From 655e5508ab5622ef7bd0cb7aa0c4e4c22863faa4 Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Sun, 18 Apr 2021 23:48:52 +0200 Subject: [PATCH 1/3] tools: install eslint-plugin-jsdoc --- .../eslint-plugin-markdown/LICENSE | 21 - .../eslint-plugin-markdown/README.md | 362 - .../eslint-plugin-markdown/index.js | 8 - .../eslint-plugin-markdown/lib/index.js | 60 - .../eslint-plugin-markdown/lib/processor.js | 395 - .../node_modules/bail/index.js | 9 - .../node_modules/bail/license | 22 - .../node_modules/bail/package.json | 72 - .../node_modules/bail/readme.md | 84 - .../character-entities-legacy/index.json | 108 - .../character-entities-legacy/license | 22 - .../character-entities-legacy/package.json | 70 - .../character-entities-legacy/readme.md | 74 - .../character-entities/index.json | 2224 - .../node_modules/character-entities/license | 22 - .../character-entities/package.json | 71 - .../node_modules/character-entities/readme.md | 72 - .../character-reference-invalid/index.json | 30 - .../character-reference-invalid/license | 22 - .../character-reference-invalid/package.json | 74 - .../character-reference-invalid/readme.md | 74 - .../collapse-white-space/index.js | 8 - .../node_modules/collapse-white-space/license | 22 - .../collapse-white-space/package.json | 70 - .../collapse-white-space/readme.md | 58 - .../node_modules/extend/.jscs.json | 175 - .../node_modules/extend/LICENSE | 23 - .../node_modules/extend/README.md | 81 - .../node_modules/extend/index.js | 117 - .../node_modules/extend/package.json | 42 - .../node_modules/inherits/LICENSE | 16 - .../node_modules/inherits/README.md | 42 - .../node_modules/inherits/inherits.js | 9 - .../node_modules/inherits/inherits_browser.js | 27 - .../node_modules/inherits/package.json | 29 - .../node_modules/is-alphabetical/index.js | 14 - .../node_modules/is-alphabetical/license | 22 - .../node_modules/is-alphabetical/package.json | 75 - .../node_modules/is-alphabetical/readme.md | 70 - .../node_modules/is-alphanumerical/index.js | 12 - .../node_modules/is-alphanumerical/license | 22 - .../is-alphanumerical/package.json | 77 - .../node_modules/is-alphanumerical/readme.md | 71 - .../node_modules/is-buffer/LICENSE | 21 - .../node_modules/is-buffer/README.md | 53 - .../node_modules/is-buffer/index.js | 21 - .../node_modules/is-buffer/package.json | 51 - .../node_modules/is-decimal/index.js | 11 - .../node_modules/is-decimal/license | 22 - .../node_modules/is-decimal/package.json | 72 - .../node_modules/is-decimal/readme.md | 69 - .../node_modules/is-hexadecimal/index.js | 15 - .../node_modules/is-hexadecimal/license | 22 - .../node_modules/is-hexadecimal/package.json | 72 - .../node_modules/is-hexadecimal/readme.md | 70 - .../node_modules/is-plain-obj/index.js | 7 - .../node_modules/is-plain-obj/license | 21 - .../node_modules/is-plain-obj/package.json | 36 - .../node_modules/is-plain-obj/readme.md | 35 - .../is-whitespace-character/index.js | 14 - .../is-whitespace-character/license | 22 - .../is-whitespace-character/package.json | 74 - .../is-whitespace-character/readme.md | 74 - .../node_modules/is-word-character/index.js | 14 - .../node_modules/is-word-character/license | 22 - .../is-word-character/package.json | 72 - .../node_modules/is-word-character/readme.md | 72 - .../node_modules/markdown-escapes/index.js | 57 - .../node_modules/markdown-escapes/license | 22 - .../markdown-escapes/package.json | 72 - .../node_modules/markdown-escapes/readme.md | 80 - .../parse-entities/decode-entity.browser.js | 30 - .../parse-entities/decode-entity.js | 13 - .../node_modules/parse-entities/index.js | 450 - .../node_modules/parse-entities/license | 22 - .../node_modules/parse-entities/package.json | 91 - .../node_modules/parse-entities/readme.md | 217 - .../node_modules/remark-parse/index.js | 14 - .../remark-parse/lib/block-elements.json | 68 - .../node_modules/remark-parse/lib/decode.js | 64 - .../node_modules/remark-parse/lib/defaults.js | 10 - .../remark-parse/lib/locate/break.js | 17 - .../remark-parse/lib/locate/code-inline.js | 7 - .../remark-parse/lib/locate/delete.js | 7 - .../remark-parse/lib/locate/emphasis.js | 18 - .../remark-parse/lib/locate/escape.js | 7 - .../remark-parse/lib/locate/link.js | 16 - .../remark-parse/lib/locate/strong.js | 18 - .../remark-parse/lib/locate/tag.js | 7 - .../remark-parse/lib/locate/url.js | 26 - .../node_modules/remark-parse/lib/parse.js | 45 - .../node_modules/remark-parse/lib/parser.js | 152 - .../remark-parse/lib/set-options.js | 47 - .../remark-parse/lib/tokenize/auto-link.js | 145 - .../remark-parse/lib/tokenize/blockquote.js | 129 - .../remark-parse/lib/tokenize/break.js | 40 - .../remark-parse/lib/tokenize/code-fenced.js | 236 - .../lib/tokenize/code-indented.js | 98 - .../remark-parse/lib/tokenize/code-inline.js | 112 - .../remark-parse/lib/tokenize/definition.js | 278 - .../remark-parse/lib/tokenize/delete.js | 60 - .../remark-parse/lib/tokenize/emphasis.js | 85 - .../remark-parse/lib/tokenize/escape.js | 34 - .../lib/tokenize/footnote-definition.js | 185 - .../remark-parse/lib/tokenize/heading-atx.js | 141 - .../lib/tokenize/heading-setext.js | 107 - .../remark-parse/lib/tokenize/html-block.js | 94 - .../remark-parse/lib/tokenize/html-inline.js | 54 - .../remark-parse/lib/tokenize/link.js | 392 - .../remark-parse/lib/tokenize/list.js | 474 - .../remark-parse/lib/tokenize/newline.js | 47 - .../remark-parse/lib/tokenize/paragraph.js | 122 - .../remark-parse/lib/tokenize/reference.js | 206 - .../remark-parse/lib/tokenize/strong.js | 84 - .../remark-parse/lib/tokenize/table.js | 266 - .../remark-parse/lib/tokenize/text.js | 58 - .../lib/tokenize/thematic-break.js | 70 - .../remark-parse/lib/tokenize/url.js | 144 - .../remark-parse/lib/tokenizer.js | 331 - .../node_modules/remark-parse/lib/unescape.js | 37 - .../remark-parse/lib/util/get-indentation.js | 32 - .../remark-parse/lib/util/html.js | 25 - .../remark-parse/lib/util/interrupt.js | 43 - .../remark-parse/lib/util/normalize.js | 11 - .../lib/util/remove-indentation.js | 78 - .../node_modules/remark-parse/package.json | 44 - .../node_modules/remark-parse/readme.md | 453 - .../node_modules/repeat-string/LICENSE | 21 - .../node_modules/repeat-string/README.md | 136 - .../node_modules/repeat-string/index.js | 70 - .../node_modules/repeat-string/package.json | 77 - .../node_modules/replace-ext/LICENSE | 21 - .../node_modules/replace-ext/README.md | 50 - .../node_modules/replace-ext/index.js | 18 - .../node_modules/replace-ext/package.json | 44 - .../node_modules/state-toggle/index.js | 23 - .../node_modules/state-toggle/license | 22 - .../node_modules/state-toggle/package.json | 70 - .../node_modules/state-toggle/readme.md | 95 - .../node_modules/trim-trailing-lines/index.js | 8 - .../node_modules/trim-trailing-lines/license | 22 - .../trim-trailing-lines/package.json | 72 - .../trim-trailing-lines/readme.md | 68 - .../node_modules/trim/Makefile | 7 - .../node_modules/trim/Readme.md | 69 - .../node_modules/trim/index.js | 14 - .../node_modules/trim/package.json | 18 - .../node_modules/trough/index.js | 74 - .../node_modules/trough/license | 21 - .../node_modules/trough/package.json | 75 - .../node_modules/trough/readme.md | 330 - .../node_modules/trough/wrap.js | 64 - .../node_modules/unherit/index.js | 45 - .../node_modules/unherit/license | 21 - .../node_modules/unherit/package.json | 72 - .../node_modules/unherit/readme.md | 79 - .../node_modules/unified/LICENSE | 21 - .../node_modules/unified/index.js | 466 - .../node_modules/unified/package.json | 86 - .../node_modules/unified/readme.md | 993 - .../node_modules/unist-util-is/convert.js | 87 - .../node_modules/unist-util-is/index.js | 37 - .../node_modules/unist-util-is/license | 22 - .../node_modules/unist-util-is/package.json | 75 - .../node_modules/unist-util-is/readme.md | 202 - .../unist-util-remove-position/index.js | 18 - .../unist-util-remove-position/license | 22 - .../unist-util-remove-position/package.json | 76 - .../unist-util-remove-position/readme.md | 131 - .../unist-util-stringify-position/LICENSE | 22 - .../unist-util-stringify-position/index.js | 50 - .../package.json | 77 - .../unist-util-stringify-position/readme.md | 100 - .../unist-util-visit-parents/index.js | 78 - .../unist-util-visit-parents/license | 22 - .../unist-util-visit-parents/package.json | 70 - .../unist-util-visit-parents/readme.md | 218 - .../node_modules/unist-util-visit/index.js | 29 - .../node_modules/unist-util-visit/license | 22 - .../unist-util-visit/package.json | 79 - .../node_modules/unist-util-visit/readme.md | 121 - .../node_modules/vfile-location/index.js | 74 - .../node_modules/vfile-location/license | 22 - .../node_modules/vfile-location/package.json | 73 - .../node_modules/vfile-location/readme.md | 115 - .../node_modules/vfile-message/index.js | 94 - .../node_modules/vfile-message/license | 22 - .../node_modules/vfile-message/package.json | 73 - .../node_modules/vfile-message/readme.md | 194 - .../node_modules/vfile/LICENSE | 21 - .../node_modules/vfile/core.js | 169 - .../node_modules/vfile/index.js | 53 - .../node_modules/vfile/package.json | 78 - .../node_modules/vfile/readme.md | 285 - .../node_modules/x-is-string/LICENCE | 19 - .../node_modules/x-is-string/README.md | 46 - .../node_modules/x-is-string/index.js | 7 - .../node_modules/x-is-string/package.json | 55 - .../node_modules/xtend/LICENSE | 20 - .../node_modules/xtend/README.md | 32 - .../node_modules/xtend/immutable.js | 19 - .../node_modules/xtend/mutable.js | 17 - .../node_modules/xtend/package.json | 55 - .../eslint-plugin-markdown/package.json | 59 - .../node_modules/eslint-plugin-jsdoc/index.js | 105541 +++++++++++++++ .../eslint-plugin-markdown/index.js | 11965 ++ .../eslint/node_modules/table/README.md | 52 + .../node_modules/table/dist/createStream.js | 20 +- .../table/dist/createStream.js.flow | 20 +- .../node_modules/table/dist/drawBorder.js | 108 +- .../table/dist/drawBorder.js.flow | 98 +- .../table/dist/drawHorizontalContent.js | 41 + .../table/dist/drawHorizontalContent.js.flow | 31 + .../eslint/node_modules/table/dist/drawRow.js | 24 +- .../node_modules/table/dist/drawRow.js.flow | 22 +- .../node_modules/table/dist/drawTable.js | 20 +- .../node_modules/table/dist/drawTable.js.flow | 37 +- .../node_modules/table/dist/makeConfig.js | 13 +- .../table/dist/makeConfig.js.flow | 13 +- .../table/dist/makeStreamConfig.js | 10 + .../table/dist/makeStreamConfig.js.flow | 9 + .../table/dist/schemas/config.json | 3 + .../table/dist/schemas/streamConfig.json | 3 + .../eslint/node_modules/table/dist/table.js | 14 +- .../node_modules/table/dist/table.js.flow | 14 +- .../node_modules/table/dist/validators.js | 68 +- .../ajv/dist/compile/validate/keyword.js | 5 +- .../table/node_modules/ajv/dist/core.js | 3 +- .../applicator/additionalProperties.js | 2 +- .../applicator/patternProperties.js | 2 +- .../ajv/dist/vocabularies/code.js | 7 +- .../dist/vocabularies/validation/pattern.js | 6 +- .../table/node_modules/ajv/package.json | 2 +- .../eslint/node_modules/table/package.json | 2 +- tools/update-eslint.sh | 14 +- 235 files changed, 117979 insertions(+), 18854 deletions(-) delete mode 100644 tools/node_modules/eslint-plugin-markdown/LICENSE delete mode 100644 tools/node_modules/eslint-plugin-markdown/README.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/lib/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/lib/processor.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/bail/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/bail/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/bail/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/bail/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/character-entities-legacy/index.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/character-entities-legacy/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/character-entities-legacy/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/character-entities-legacy/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/character-entities/index.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/character-entities/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/character-entities/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/character-entities/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/character-reference-invalid/index.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/character-reference-invalid/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/character-reference-invalid/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/character-reference-invalid/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/collapse-white-space/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/collapse-white-space/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/collapse-white-space/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/collapse-white-space/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/extend/.jscs.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/extend/LICENSE delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/extend/README.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/extend/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/extend/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/inherits/LICENSE delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/inherits/README.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/inherits/inherits.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/inherits/inherits_browser.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/inherits/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-alphabetical/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-alphabetical/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-alphabetical/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-alphabetical/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-alphanumerical/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-alphanumerical/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-alphanumerical/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-alphanumerical/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-buffer/LICENSE delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-buffer/README.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-buffer/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-buffer/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-decimal/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-decimal/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-decimal/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-decimal/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-hexadecimal/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-hexadecimal/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-hexadecimal/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-hexadecimal/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-plain-obj/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-plain-obj/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-plain-obj/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-plain-obj/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-whitespace-character/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-whitespace-character/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-whitespace-character/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-whitespace-character/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-word-character/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-word-character/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-word-character/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/is-word-character/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/markdown-escapes/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/markdown-escapes/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/markdown-escapes/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/markdown-escapes/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/decode-entity.browser.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/decode-entity.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/block-elements.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/decode.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/defaults.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/break.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/code-inline.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/delete.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/emphasis.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/escape.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/link.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/strong.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/tag.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/url.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/parse.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/parser.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/set-options.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/auto-link.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/blockquote.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/break.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/code-fenced.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/code-indented.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/code-inline.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/definition.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/delete.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/emphasis.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/escape.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/footnote-definition.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/heading-atx.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/heading-setext.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/html-block.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/html-inline.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/link.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/list.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/newline.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/paragraph.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/reference.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/strong.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/table.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/text.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/thematic-break.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/url.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenizer.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/unescape.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/util/get-indentation.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/util/html.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/util/interrupt.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/util/normalize.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/util/remove-indentation.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/repeat-string/LICENSE delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/repeat-string/README.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/repeat-string/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/repeat-string/package.json delete mode 100755 tools/node_modules/eslint-plugin-markdown/node_modules/replace-ext/LICENSE delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/replace-ext/README.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/replace-ext/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/replace-ext/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/state-toggle/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/state-toggle/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/state-toggle/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/state-toggle/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/trim-trailing-lines/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/trim-trailing-lines/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/trim-trailing-lines/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/trim-trailing-lines/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/trim/Makefile delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/trim/Readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/trim/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/trim/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/trough/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/trough/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/trough/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/trough/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/trough/wrap.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unherit/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unherit/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unherit/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unherit/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unified/LICENSE delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unified/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unified/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unified/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-is/convert.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-is/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-is/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-is/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-is/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-remove-position/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-remove-position/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-remove-position/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-remove-position/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-stringify-position/LICENSE delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-stringify-position/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-stringify-position/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-stringify-position/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit-parents/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit-parents/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit-parents/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit-parents/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/vfile-location/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/vfile-location/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/vfile-location/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/vfile-location/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/vfile-message/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/vfile-message/license delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/vfile-message/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/vfile-message/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/vfile/LICENSE delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/vfile/core.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/vfile/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/vfile/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/vfile/readme.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/x-is-string/LICENCE delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/x-is-string/README.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/x-is-string/index.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/x-is-string/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/xtend/LICENSE delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/xtend/README.md delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/xtend/immutable.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/xtend/mutable.js delete mode 100644 tools/node_modules/eslint-plugin-markdown/node_modules/xtend/package.json delete mode 100644 tools/node_modules/eslint-plugin-markdown/package.json create mode 100644 tools/node_modules/eslint/node_modules/eslint-plugin-jsdoc/index.js create mode 100644 tools/node_modules/eslint/node_modules/eslint-plugin-markdown/index.js create mode 100644 tools/node_modules/eslint/node_modules/table/dist/drawHorizontalContent.js create mode 100644 tools/node_modules/eslint/node_modules/table/dist/drawHorizontalContent.js.flow diff --git a/tools/node_modules/eslint-plugin-markdown/LICENSE b/tools/node_modules/eslint-plugin-markdown/LICENSE deleted file mode 100644 index cf5a5995af4cd5..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright JS Foundation and other contributors, https://js.foundation - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/README.md b/tools/node_modules/eslint-plugin-markdown/README.md deleted file mode 100644 index fd8767b753596c..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/README.md +++ /dev/null @@ -1,362 +0,0 @@ -# eslint-plugin-markdown - -[![npm Version](https://img.shields.io/npm/v/eslint-plugin-markdown.svg)](https://www.npmjs.com/package/eslint-plugin-markdown) -[![Build Status](https://img.shields.io/github/workflow/status/eslint/eslint-plugin-markdown/CI/main.svg)](https://github.com/eslint/eslint-plugin-markdown/actions) - -Lint JS, JSX, TypeScript, and more inside Markdown. - -A JS code snippet in a Markdown editor has red squiggly underlines. A tooltip explains the problem. - -## Usage - -### Installing - -Install the plugin alongside ESLint v6 or greater: - -```sh -npm install --save-dev eslint eslint-plugin-markdown -``` - -### Configuring - -Extending the `plugin:markdown/recommended` config will enable the Markdown processor on all `.md` files: - -```js -// .eslintrc.js -module.exports = { - extends: "plugin:markdown/recommended" -}; -``` - -#### Advanced Configuration - -Add the plugin to your `.eslintrc` and use the `processor` option in an `overrides` entry to enable the plugin's `markdown/markdown` processor on Markdown files. -Each fenced code block inside a Markdown document has a virtual filename appended to the Markdown file's path. -The virtual filename's extension will match the fenced code block's syntax tag, so for example, ```js code blocks in README.md would match README.md/*.js. -[`overrides` glob patterns](https://eslint.org/docs/user-guide/configuring#configuration-based-on-glob-patterns) for these virtual filenames can customize configuration for code blocks without affecting regular code. -For more information on configuring processors, refer to the [ESLint documentation](https://eslint.org/docs/user-guide/configuring#specifying-processor). - -```js -// .eslintrc.js -module.exports = { - // 1. Add the plugin. - plugins: ["markdown"], - overrides: [ - { - // 2. Enable the Markdown processor for all .md files. - files: ["**/*.md"], - processor: "markdown/markdown" - }, - { - // 3. Optionally, customize the configuration ESLint uses for ```js - // fenced code blocks inside .md files. - files: ["**/*.md/*.js"], - // ... - rules: { - // ... - } - } - ] -}; -``` - -#### Frequently-Disabled Rules - -Some rules that catch mistakes in regular code are less helpful in documentation. -For example, `no-undef` would flag variables that are declared outside of a code snippet because they aren't relevant to the example. -The `plugin:markdown/recommended` config disables these rules in Markdown files: - -- [`no-undef`](https://eslint.org/docs/rules/no-undef) -- [`no-unused-expressions`](https://eslint.org/docs/rules/no-unused-expressions) -- [`no-unused-vars`](https://eslint.org/docs/rules/no-unused-vars) -- [`padded-blocks`](https://eslint.org/docs/rules/padded-blocks) - -Use [`overrides` glob patterns](https://eslint.org/docs/user-guide/configuring#configuration-based-on-glob-patterns) to disable more rules just for Markdown code blocks: - -```js -module.exports = { - // ... - overrides: [ - // ... - { - // 1. Target ```js code blocks in .md files. - files: ["**/*.md/*.js"], - rules: { - // 2. Disable other rules. - "no-console": "off", - "import/no-unresolved": "off" - } - } - ] -}; -``` - -#### Strict Mode - -`"use strict"` directives in every code block would be annoying. -The `plugin:markdown/recommended` config enables the [`impliedStrict` parser option](https://eslint.org/docs/user-guide/configuring#specifying-parser-options) and disables the [`strict` rule](https://eslint.org/docs/rules/strict) in Markdown files. -This opts into strict mode parsing without repeated `"use strict"` directives. - -#### Unsatisfiable Rules - -Markdown code blocks are not real files, so ESLint's file-format rules do not apply. -The `plugin:markdown/recommended` config disables these rules in Markdown files: - -- [`eol-last`](https://eslint.org/docs/rules/eol-last): The Markdown parser trims trailing newlines from code blocks. -- [`unicode-bom`](https://eslint.org/docs/rules/unicode-bom): Markdown code blocks do not have Unicode Byte Order Marks. - -#### Migrating from `eslint-plugin-markdown` v1 - -`eslint-plugin-markdown` v1 used an older version of ESLint's processor API. -The Markdown processor automatically ran on `.md`, `.mkdn`, `.mdown`, and `.markdown` files, and it only extracted fenced code blocks marked with `js`, `javascript`, `jsx`, or `node` syntax. -Configuration specifically for fenced code blocks went inside an `overrides` entry with a `files` pattern matching the containing Markdown document's filename that applied to all fenced code blocks inside the file. - -```js -// .eslintrc.js for eslint-plugin-markdown v1 -module.exports = { - plugins: ["markdown"], - overrides: [ - { - files: ["**/*.md"], - // In v1, configuration for fenced code blocks went inside an - // `overrides` entry with a .md pattern, for example: - parserOptions: { - ecmaFeatures: { - impliedStrict: true - } - }, - rules: { - "no-console": "off" - } - } - ] -}; -``` - -[RFC3](https://github.com/eslint/rfcs/blob/master/designs/2018-processors-improvements/README.md) designed a new processor API to remove these limitations, and the new API was [implemented](https://github.com/eslint/eslint/pull/11552) as part of ESLint v6. -`eslint-plugin-markdown` v2 uses this new API. - -```bash -$ npm install --save-dev eslint@latest eslint-plugin-markdown@latest -``` - -All of the Markdown file extensions that were previously hard-coded are now fully configurable in `.eslintrc.js`. -Use the new `processor` option to apply the `markdown/markdown` processor on any Markdown documents matching a `files` pattern. -Each fenced code block inside a Markdown document has a virtual filename appended to the Markdown file's path. -The virtual filename's extension will match the fenced code block's syntax tag, so for example, ```js code blocks in README.md would match README.md/*.js. - -```js -// eslintrc.js for eslint-plugin-markdown v2 -module.exports = { - plugins: ["markdown"], - overrides: [ - { - // In v2, explicitly apply eslint-plugin-markdown's `markdown` - // processor on any Markdown files you want to lint. - files: ["**/*.md"], - processor: "markdown/markdown" - }, - { - // In v2, configuration for fenced code blocks is separate from the - // containing Markdown file. Each code block has a virtual filename - // appended to the Markdown file's path. - files: ["**/*.md/*.js"], - // Configuration for fenced code blocks goes with the override for - // the code block's virtual filename, for example: - parserOptions: { - ecmaFeatures: { - impliedStrict: true - } - }, - rules: { - "no-console": "off" - } - } - ] -}; -``` - -If you need to precisely mimic the behavior of v1 with the hard-coded Markdown extensions and fenced code block syntaxes, you can use those as glob patterns in `overrides[].files`: - -```js -// eslintrc.js for v2 mimicking v1 behavior -module.exports = { - plugins: ["markdown"], - overrides: [ - { - files: ["**/*.{md,mkdn,mdown,markdown}"], - processor: "markdown/markdown" - }, - { - files: ["**/*.{md,mkdn,mdown,markdown}/*.{js,javascript,jsx,node}"] - // ... - } - ] -}; -``` - -### Running - -#### ESLint v7 - -You can run ESLint as usual and do not need to use the `--ext` option. -ESLint v7 [automatically lints file extensions specified in `overrides[].files` patterns in config files](https://github.com/eslint/rfcs/blob/0253e3a95511c65d622eaa387eb73f824249b467/designs/2019-additional-lint-targets/README.md). - -#### ESLint v6 - -Use the [`--ext` option](https://eslint.org/docs/user-guide/command-line-interface#ext) to include `.js` and `.md` extensions in ESLint's file search: - -```sh -eslint --ext js,md . -``` - -### Autofixing - -With this plugin, [ESLint's `--fix` option](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some issues in your Markdown fenced code blocks. -To enable this, pass the `--fix` flag when you run ESLint: - -```bash -eslint --fix . -``` - -## What Gets Linted? - -With this plugin, ESLint will lint [fenced code blocks](https://help.github.com/articles/github-flavored-markdown/#fenced-code-blocks) in your Markdown documents: - -````markdown -```js -// This gets linted -var answer = 6 * 7; -console.log(answer); -``` - -Here is some regular Markdown text that will be ignored. - -```js -// This also gets linted - -/* eslint quotes: [2, "double"] */ - -function hello() { - console.log("Hello, world!"); -} -hello(); -``` - -```jsx -// This can be linted too if you add `.jsx` files to `overrides` in ESLint v7 -// or pass `--ext jsx` in ESLint v6. -var div =
; -``` -```` - -Blocks that don't specify a syntax are ignored: - -````markdown -``` -This is plain text and doesn't get linted. -``` -```` - -Unless a fenced code block's syntax appears as a file extension in `overrides[].files` in ESLint v7, it will be ignored. -If using ESLint v6, you must also include the extension with the `--ext` option. - -````markdown -```python -print("This doesn't get linted either.") -``` -```` - -## Configuration Comments - -The processor will convert HTML comments immediately preceding a code block into JavaScript block comments and insert them at the beginning of the source code that it passes to ESLint. -This permits configuring ESLint via configuration comments while keeping the configuration comments themselves hidden when the markdown is rendered. -Comment bodies are passed through unmodified, so the plugin supports any [configuration comments](http://eslint.org/docs/user-guide/configuring) supported by ESLint itself. - -This example enables the `browser` environment, disables the `no-alert` rule, and configures the `quotes` rule to prefer single quotes: - -````markdown - - - - -```js -alert('Hello, world!'); -``` -```` - -Each code block in a file is linted separately, so configuration comments apply only to the code block that immediately follows. - -````markdown -Assuming `no-alert` is enabled in `.eslintrc`, the first code block will have no error from `no-alert`: - - - - -```js -alert("Hello, world!"); -``` - -But the next code block will have an error from `no-alert`: - - - -```js -alert("Hello, world!"); -``` -```` - -### Skipping Blocks - -Sometimes it can be useful to have code blocks marked with `js` even though they don't contain valid JavaScript syntax, such as commented JSON blobs that need `js` syntax highlighting. -Standard `eslint-disable` comments only silence rule reporting, but ESLint still reports any syntax errors it finds. -In cases where a code block should not even be parsed, insert a non-standard `` comment before the block, and this plugin will hide the following block from ESLint. -Neither rule nor syntax errors will be reported. - -````markdown -There are comments in this JSON, so we use `js` syntax for better -highlighting. Skip the block to prevent warnings about invalid syntax. - - - -```js -{ - // This code block is hidden from ESLint. - "hello": "world" -} -``` - -```js -console.log("This code block is linted normally."); -``` -```` - -## Editor Integrations - -### VSCode - -[`vscode-eslint`](https://github.com/microsoft/vscode-eslint) has built-in support for the Markdown processor. - -### Atom - -The [`linter-eslint`](https://atom.io/packages/linter-eslint) package allows for linting within the [Atom IDE](https://atom.io/). - -In order to see `eslint-plugin-markdown` work its magic within Markdown code blocks in your Atom editor, you can go to `linter-eslint`'s settings and within "List of scopes to run ESLint on...", add the cursor scope "source.gfm". - -However, this reports a problem when viewing Markdown which does not have configuration, so you may wish to use the cursor scope "source.embedded.js", but note that `eslint-plugin-markdown` configuration comments and skip directives won't work in this context. - -## Contributing - -```sh -$ git clone https://github.com/eslint/eslint-plugin-markdown.git -$ cd eslint-plugin-markdown -$ npm install -$ npm test -``` - -This project follows the [ESLint contribution guidelines](http://eslint.org/docs/developer-guide/contributing/). diff --git a/tools/node_modules/eslint-plugin-markdown/index.js b/tools/node_modules/eslint-plugin-markdown/index.js deleted file mode 100644 index 1638f11ee3c12b..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/index.js +++ /dev/null @@ -1,8 +0,0 @@ -/** - * @fileoverview Exports the processor. - * @author Brandon Mills - */ - -"use strict"; - -module.exports = require("./lib"); diff --git a/tools/node_modules/eslint-plugin-markdown/lib/index.js b/tools/node_modules/eslint-plugin-markdown/lib/index.js deleted file mode 100644 index d66a7ddda6f6c2..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/lib/index.js +++ /dev/null @@ -1,60 +0,0 @@ -/** - * @fileoverview Enables the processor for Markdown file extensions. - * @author Brandon Mills - */ - -"use strict"; - -const processor = require("./processor"); - -module.exports = { - configs: { - recommended: { - plugins: ["markdown"], - overrides: [ - { - files: ["*.md"], - processor: "markdown/markdown" - }, - { - files: ["**/*.md/**"], - parserOptions: { - ecmaFeatures: { - - // Adding a "use strict" directive at the top of - // every code block is tedious and distracting, so - // opt into strict mode parsing without the - // directive. - impliedStrict: true - } - }, - rules: { - - // The Markdown parser automatically trims trailing - // newlines from code blocks. - "eol-last": "off", - - // In code snippets and examples, these rules are often - // counterproductive to clarity and brevity. - "no-undef": "off", - "no-unused-expressions": "off", - "no-unused-vars": "off", - "padded-blocks": "off", - - // Adding a "use strict" directive at the top of every - // code block is tedious and distracting. The config - // opts into strict mode parsing without the directive. - strict: "off", - - // The processor will not receive a Unicode Byte Order - // Mark from the Markdown parser. - "unicode-bom": "off" - } - } - ] - } - }, - processors: { - markdown: processor - } -}; diff --git a/tools/node_modules/eslint-plugin-markdown/lib/processor.js b/tools/node_modules/eslint-plugin-markdown/lib/processor.js deleted file mode 100644 index 94cf816dc913d9..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/lib/processor.js +++ /dev/null @@ -1,395 +0,0 @@ -/** - * @fileoverview Processes Markdown files for consumption by ESLint. - * @author Brandon Mills - */ - -/** - * @typedef {import('eslint/lib/shared/types').LintMessage} Message - * - * @typedef {Object} ASTNode - * @property {string} type - * @property {string} [lang] - * - * @typedef {Object} RangeMap - * @property {number} js - * @property {number} md - * - * @typedef {Object} BlockBase - * @property {string} baseIndentText - * @property {string[]} comments - * @property {RangeMap[]} rangeMap - * - * @typedef {ASTNode & BlockBase} Block - */ - -"use strict"; - -const unified = require("unified"); -const remarkParse = require("remark-parse"); - -const UNSATISFIABLE_RULES = [ - "eol-last", // The Markdown parser strips trailing newlines in code fences - "unicode-bom" // Code blocks will begin in the middle of Markdown files -]; -const SUPPORTS_AUTOFIX = true; - -const markdown = unified().use(remarkParse); - -/** - * @type {Map} - */ -const blocksCache = new Map(); - -/** - * Performs a depth-first traversal of the Markdown AST. - * @param {ASTNode} node A Markdown AST node. - * @param {{[key: string]: (node: ASTNode) => void}} callbacks A map of node types to callbacks. - * @returns {void} - */ -function traverse(node, callbacks) { - if (callbacks[node.type]) { - callbacks[node.type](node); - } else { - callbacks["*"](); - } - - if (typeof node.children !== "undefined") { - for (let i = 0; i < node.children.length; i++) { - traverse(node.children[i], callbacks); - } - } -} - -/** - * Extracts `eslint-*` or `global` comments from HTML comments if present. - * @param {string} html The text content of an HTML AST node. - * @returns {string} The comment's text without the opening and closing tags or - * an empty string if the text is not an ESLint HTML comment. - */ -function getComment(html) { - const commentStart = ""; - const regex = /^(eslint\b|global\s)/u; - - if ( - html.slice(0, commentStart.length) !== commentStart || - html.slice(-commentEnd.length) !== commentEnd - ) { - return ""; - } - - const comment = html.slice(commentStart.length, -commentEnd.length); - - if (!regex.test(comment.trim())) { - return ""; - } - - return comment; -} - -// Before a code block, blockquote characters (`>`) are also considered -// "whitespace". -const leadingWhitespaceRegex = /^[>\s]*/u; - -/** - * Gets the offset for the first column of the node's first line in the - * original source text. - * @param {ASTNode} node A Markdown code block AST node. - * @returns {number} The offset for the first column of the node's first line. - */ -function getBeginningOfLineOffset(node) { - return node.position.start.offset - node.position.start.column + 1; -} - -/** - * Gets the leading text, typically whitespace with possible blockquote chars, - * used to indent a code block. - * @param {string} text The text of the file. - * @param {ASTNode} node A Markdown code block AST node. - * @returns {string} The text from the start of the first line to the opening - * fence of the code block. - */ -function getIndentText(text, node) { - return leadingWhitespaceRegex.exec( - text.slice(getBeginningOfLineOffset(node)) - )[0]; -} - -/** - * When applying fixes, the postprocess step needs to know how to map fix ranges - * from their location in the linted JS to the original offset in the Markdown. - * Configuration comments and indentation trimming both complicate this process. - * - * Configuration comments appear in the linted JS but not in the Markdown code - * block. Fixes to configuration comments would cause undefined behavior and - * should be ignored during postprocessing. Fixes to actual code after - * configuration comments need to be mapped back to the code block after - * removing any offset due to configuration comments. - * - * Fenced code blocks can be indented by up to three spaces at the opening - * fence. Inside of a list, for example, this indent can be in addition to the - * indent already required for list item children. Leading whitespace inside - * indented code blocks is trimmed up to the level of the opening fence and does - * not appear in the linted code. Further, lines can have less leading - * whitespace than the opening fence, so not all lines are guaranteed to have - * the same column offset as the opening fence. - * - * The source code of a non-configuration-comment line in the linted JS is a - * suffix of the corresponding line in the Markdown code block. There are no - * differences within the line, so the mapping need only provide the offset - * delta at the beginning of each line. - * @param {string} text The text of the file. - * @param {ASTNode} node A Markdown code block AST node. - * @param {string[]} comments List of configuration comment strings that will be - * inserted at the beginning of the code block. - * @returns {RangeMap[]} A list of offset-based adjustments, where lookups are - * done based on the `js` key, which represents the range in the linted JS, - * and the `md` key is the offset delta that, when added to the JS range, - * returns the corresponding location in the original Markdown source. - */ -function getBlockRangeMap(text, node, comments) { - - /* - * The parser sets the fenced code block's start offset to wherever content - * should normally begin (typically the first column of the line, but more - * inside a list item, for example). The code block's opening fance may be - * further indented by up to three characters. If the code block has - * additional indenting, the opening fence's first backtick may be up to - * three whitespace characters after the start offset. - */ - const startOffset = getBeginningOfLineOffset(node); - - /* - * Extract the Markdown source to determine the leading whitespace for each - * line. - */ - const code = text.slice(startOffset, node.position.end.offset); - const lines = code.split("\n"); - - /* - * The parser trims leading whitespace from each line of code within the - * fenced code block up to the opening fence's first backtick. The first - * backtick's column is the AST node's starting column plus any additional - * indentation. - */ - const baseIndent = getIndentText(text, node).length; - - /* - * Track the length of any inserted configuration comments at the beginning - * of the linted JS and start the JS offset lookup keys at this index. - */ - const commentLength = comments.reduce((len, comment) => len + comment.length + 1, 0); - - /* - * In case there are configuration comments, initialize the map so that the - * first lookup index is always 0. If there are no configuration comments, - * the lookup index will also be 0, and the lookup should always go to the - * last range that matches, skipping this initialization entry. - */ - const rangeMap = [{ - js: 0, - md: 0 - }]; - - // Start the JS offset after any configuration comments. - let jsOffset = commentLength; - - /* - * Start the Markdown offset at the beginning of the block's first line of - * actual code. The first line of the block is always the opening fence, so - * the code begins on the second line. - */ - let mdOffset = startOffset + lines[0].length + 1; - - /* - * For each line, determine how much leading whitespace was trimmed due to - * indentation. Increase the JS lookup offset by the length of the line - * post-trimming and the Markdown offset by the total line length. - */ - for (let i = 0; i + 1 < lines.length; i++) { - const line = lines[i + 1]; - const leadingWhitespaceLength = leadingWhitespaceRegex.exec(line)[0].length; - - // The parser trims leading whitespace up to the level of the opening - // fence, so keep any additional indentation beyond that. - const trimLength = Math.min(baseIndent, leadingWhitespaceLength); - - rangeMap.push({ - js: jsOffset, - - // Advance `trimLength` character from the beginning of the Markdown - // line to the beginning of the equivalent JS line, then compute the - // delta. - md: mdOffset + trimLength - jsOffset - }); - - // Accumulate the current line in the offsets, and don't forget the - // newline. - mdOffset += line.length + 1; - jsOffset += line.length - trimLength + 1; - } - - return rangeMap; -} - -/** - * Extracts lintable code blocks from Markdown text. - * @param {string} text The text of the file. - * @param {string} filename The filename of the file - * @returns {Array<{ filename: string, text: string }>} Source code blocks to lint. - */ -function preprocess(text, filename) { - const ast = markdown.parse(text); - const blocks = []; - - blocksCache.set(filename, blocks); - - /** - * During the depth-first traversal, keep track of any sequences of HTML - * comment nodes containing `eslint-*` or `global` comments. If a code - * block immediately follows such a sequence, insert the comments at the - * top of the code block. Any non-ESLint comment or other node type breaks - * and empties the sequence. - * @type {string[]} - */ - let htmlComments = []; - - traverse(ast, { - "*"() { - htmlComments = []; - }, - code(node) { - if (node.lang) { - const comments = []; - - for (const comment of htmlComments) { - if (comment.trim() === "eslint-skip") { - htmlComments = []; - return; - } - - comments.push(`/*${comment}*/`); - } - - htmlComments = []; - - blocks.push({ - ...node, - baseIndentText: getIndentText(text, node), - comments, - rangeMap: getBlockRangeMap(text, node, comments) - }); - } - }, - html(node) { - const comment = getComment(node.value); - - if (comment) { - htmlComments.push(comment); - } else { - htmlComments = []; - } - } - }); - - return blocks.map((block, index) => ({ - filename: `${index}.${block.lang.trim().split(" ")[0]}`, - text: [ - ...block.comments, - block.value, - "" - ].join("\n") - })); -} - -/** - * Creates a map function that adjusts messages in a code block. - * @param {Block} block A code block. - * @returns {(message: Message) => Message} A function that adjusts messages in a code block. - */ -function adjustBlock(block) { - const leadingCommentLines = block.comments.reduce((count, comment) => count + comment.split("\n").length, 0); - - const blockStart = block.position.start.line; - - /** - * Adjusts ESLint messages to point to the correct location in the Markdown. - * @param {Message} message A message from ESLint. - * @returns {Message} The same message, but adjusted to the correct location. - */ - return function adjustMessage(message) { - - const lineInCode = message.line - leadingCommentLines; - - if (lineInCode < 1) { - return null; - } - - const out = { - line: lineInCode + blockStart, - column: message.column + block.position.indent[lineInCode - 1] - 1 - }; - - if (Number.isInteger(message.endLine)) { - out.endLine = message.endLine - leadingCommentLines + blockStart; - } - - const adjustedFix = {}; - - if (message.fix) { - adjustedFix.fix = { - range: message.fix.range.map(range => { - - // Advance through the block's range map to find the last - // matching range by finding the first range too far and - // then going back one. - let i = 1; - - while (i < block.rangeMap.length && block.rangeMap[i].js <= range) { - i++; - } - - // Apply the mapping delta for this range. - return range + block.rangeMap[i - 1].md; - }), - text: message.fix.text.replace(/\n/gu, `\n${block.baseIndentText}`) - }; - } - - return { ...message, ...out, ...adjustedFix }; - }; -} - -/** - * Excludes unsatisfiable rules from the list of messages. - * @param {Message} message A message from the linter. - * @returns {boolean} True if the message should be included in output. - */ -function excludeUnsatisfiableRules(message) { - return message && UNSATISFIABLE_RULES.indexOf(message.ruleId) < 0; -} - -/** - * Transforms generated messages for output. - * @param {Array} messages An array containing one array of messages - * for each code block returned from `preprocess`. - * @param {string} filename The filename of the file - * @returns {Message[]} A flattened array of messages with mapped locations. - */ -function postprocess(messages, filename) { - const blocks = blocksCache.get(filename); - - blocksCache.delete(filename); - - return [].concat(...messages.map((group, i) => { - const adjust = adjustBlock(blocks[i]); - - return group.map(adjust).filter(excludeUnsatisfiableRules); - })); -} - -module.exports = { - preprocess, - postprocess, - supportsAutofix: SUPPORTS_AUTOFIX -}; diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/bail/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/bail/index.js deleted file mode 100644 index ef5e8807adf193..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/bail/index.js +++ /dev/null @@ -1,9 +0,0 @@ -'use strict' - -module.exports = bail - -function bail(err) { - if (err) { - throw err - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/bail/license b/tools/node_modules/eslint-plugin-markdown/node_modules/bail/license deleted file mode 100644 index 32e7a3d93ca5a2..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/bail/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2015 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/bail/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/bail/package.json deleted file mode 100644 index 8f8539d32b89b6..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/bail/package.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "name": "bail", - "version": "1.0.5", - "description": "Throw a given error", - "license": "MIT", - "keywords": [ - "fail", - "bail", - "throw", - "callback", - "error" - ], - "repository": "wooorm/bail", - "bugs": "https://github.com/wooorm/bail/issues", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - }, - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "files": [ - "index.js" - ], - "dependencies": {}, - "devDependencies": { - "browserify": "^16.0.0", - "nyc": "^15.0.0", - "prettier": "^1.0.0", - "remark-cli": "^7.0.0", - "remark-preset-wooorm": "^6.0.0", - "tape": "^4.0.0", - "tinyify": "^2.0.0", - "xo": "^0.25.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify index.js -s bail -o bail.js", - "build-mangle": "browserify index.js -s bail -p tinyify -o bail.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "ignores": [ - "bail.js" - ] - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/bail/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/bail/readme.md deleted file mode 100644 index 8e7b0863c01d2b..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/bail/readme.md +++ /dev/null @@ -1,84 +0,0 @@ -# bail - -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] - -:warning: Throw a given error. - -## Install - -[npm][]: - -```sh -npm install bail -``` - -## Use - -```js -var bail = require('bail') - -bail() - -bail(new Error('failure')) -// Error: failure -// at repl:1:6 -// at REPLServer.defaultEval (repl.js:154:27) -// … -``` - -## API - -### `bail([err])` - -Throw a given error. - -###### Parameters - -* `err` (`Error?`) — Optional error. - -###### Throws - -* `Error` — Given error, if any. - -## Related - -* [`noop`][noop] -* [`noop2`][noop2] -* [`noop3`][noop3] - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/wooorm/bail.svg - -[build]: https://travis-ci.org/wooorm/bail - -[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/bail.svg - -[coverage]: https://codecov.io/github/wooorm/bail - -[downloads-badge]: https://img.shields.io/npm/dm/bail.svg - -[downloads]: https://www.npmjs.com/package/bail - -[size-badge]: https://img.shields.io/bundlephobia/minzip/bail.svg - -[size]: https://bundlephobia.com/result?p=bail - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com - -[noop]: https://www.npmjs.com/package/noop - -[noop2]: https://www.npmjs.com/package/noop2 - -[noop3]: https://www.npmjs.com/package/noop3 diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities-legacy/index.json b/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities-legacy/index.json deleted file mode 100644 index d83b75251b7928..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities-legacy/index.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "AElig": "Æ", - "AMP": "&", - "Aacute": "Á", - "Acirc": "Â", - "Agrave": "À", - "Aring": "Å", - "Atilde": "Ã", - "Auml": "Ä", - "COPY": "©", - "Ccedil": "Ç", - "ETH": "Ð", - "Eacute": "É", - "Ecirc": "Ê", - "Egrave": "È", - "Euml": "Ë", - "GT": ">", - "Iacute": "Í", - "Icirc": "Î", - "Igrave": "Ì", - "Iuml": "Ï", - "LT": "<", - "Ntilde": "Ñ", - "Oacute": "Ó", - "Ocirc": "Ô", - "Ograve": "Ò", - "Oslash": "Ø", - "Otilde": "Õ", - "Ouml": "Ö", - "QUOT": "\"", - "REG": "®", - "THORN": "Þ", - "Uacute": "Ú", - "Ucirc": "Û", - "Ugrave": "Ù", - "Uuml": "Ü", - "Yacute": "Ý", - "aacute": "á", - "acirc": "â", - "acute": "´", - "aelig": "æ", - "agrave": "à", - "amp": "&", - "aring": "å", - "atilde": "ã", - "auml": "ä", - "brvbar": "¦", - "ccedil": "ç", - "cedil": "¸", - "cent": "¢", - "copy": "©", - "curren": "¤", - "deg": "°", - "divide": "÷", - "eacute": "é", - "ecirc": "ê", - "egrave": "è", - "eth": "ð", - "euml": "ë", - "frac12": "½", - "frac14": "¼", - "frac34": "¾", - "gt": ">", - "iacute": "í", - "icirc": "î", - "iexcl": "¡", - "igrave": "ì", - "iquest": "¿", - "iuml": "ï", - "laquo": "«", - "lt": "<", - "macr": "¯", - "micro": "µ", - "middot": "·", - "nbsp": " ", - "not": "¬", - "ntilde": "ñ", - "oacute": "ó", - "ocirc": "ô", - "ograve": "ò", - "ordf": "ª", - "ordm": "º", - "oslash": "ø", - "otilde": "õ", - "ouml": "ö", - "para": "¶", - "plusmn": "±", - "pound": "£", - "quot": "\"", - "raquo": "»", - "reg": "®", - "sect": "§", - "shy": "­", - "sup1": "¹", - "sup2": "²", - "sup3": "³", - "szlig": "ß", - "thorn": "þ", - "times": "×", - "uacute": "ú", - "ucirc": "û", - "ugrave": "ù", - "uml": "¨", - "uuml": "ü", - "yacute": "ý", - "yen": "¥", - "yuml": "ÿ" -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities-legacy/license b/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities-legacy/license deleted file mode 100644 index 32e7a3d93ca5a2..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities-legacy/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2015 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities-legacy/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities-legacy/package.json deleted file mode 100644 index e532b8714df3e8..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities-legacy/package.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "name": "character-entities-legacy", - "version": "1.1.4", - "description": "HTML legacy character entity information", - "license": "MIT", - "keywords": [ - "html", - "entity", - "entities", - "character", - "reference", - "name", - "replacement" - ], - "repository": "wooorm/character-entities-legacy", - "bugs": "https://github.com/wooorm/character-entities-legacy/issues", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - }, - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "main": "index.json", - "files": [ - "index.json" - ], - "dependencies": {}, - "devDependencies": { - "bail": "^1.0.0", - "browserify": "^16.0.0", - "concat-stream": "^2.0.0", - "prettier": "^1.0.0", - "remark-cli": "^7.0.0", - "remark-preset-wooorm": "^6.0.0", - "tape": "^4.0.0", - "tinyify": "^2.0.0", - "xo": "^0.25.0" - }, - "scripts": { - "generate": "node build", - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify index.json -s characterEntitiesLegacy -o character-entities-legacy.js", - "build-mangle": "browserify index.json -s characterEntitiesLegacy -p tinyify -o character-entities-legacy.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test": "npm run generate && npm run format && npm run build && npm run test-api" - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "ignores": [ - "character-entities-legacy.js" - ] - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities-legacy/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities-legacy/readme.md deleted file mode 100644 index 711a090a7d205f..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities-legacy/readme.md +++ /dev/null @@ -1,74 +0,0 @@ -# character-entities-legacy - -[![Build][build-badge]][build] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] - -HTML legacy character entity information: for legacy reasons some character -entities are not required to have a trailing semicolon: `©` is perfectly -okay for `©`. - -## Install - -[npm][]: - -```sh -npm install character-entities-legacy -``` - -## Use - -```js -var characterEntitiesLegacy = require('character-entities-legacy') - -console.log(characterEntitiesLegacy.copy) // => '©' -console.log(characterEntitiesLegacy.frac34) // => '¾' -console.log(characterEntitiesLegacy.sup1) // => '¹' -``` - -## API - -### `characterEntitiesLegacy` - -Mapping between (case-sensitive) legacy character entity names to replacements. - -## Support - -See [`whatwg/html`][html]. - -## Related - -* [`character-entities`](https://github.com/wooorm/character-entities) - — HTML character entity info -* [`character-entities-html4`](https://github.com/wooorm/character-entities-html4) - — HTML 4 character entity info -* [`parse-entities`](https://github.com/wooorm/parse-entities) - — Parse HTML character references -* [`stringify-entities`](https://github.com/wooorm/stringify-entities) - — Serialize HTML character references - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/wooorm/character-entities-legacy.svg - -[build]: https://travis-ci.org/wooorm/character-entities-legacy - -[downloads-badge]: https://img.shields.io/npm/dm/character-entities-legacy.svg - -[downloads]: https://www.npmjs.com/package/character-entities-legacy - -[size-badge]: https://img.shields.io/bundlephobia/minzip/character-entities-legacy.svg - -[size]: https://bundlephobia.com/result?p=character-entities-legacy - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com - -[html]: https://raw.githubusercontent.com/whatwg/html/master/json-entities-legacy.inc diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities/index.json b/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities/index.json deleted file mode 100644 index a63babe093521d..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities/index.json +++ /dev/null @@ -1,2224 +0,0 @@ -{ - "AEli": "Æ", - "AElig": "Æ", - "AM": "&", - "AMP": "&", - "Aacut": "Á", - "Aacute": "Á", - "Abreve": "Ă", - "Acir": "Â", - "Acirc": "Â", - "Acy": "А", - "Afr": "𝔄", - "Agrav": "À", - "Agrave": "À", - "Alpha": "Α", - "Amacr": "Ā", - "And": "⩓", - "Aogon": "Ą", - "Aopf": "𝔸", - "ApplyFunction": "⁡", - "Arin": "Å", - "Aring": "Å", - "Ascr": "𝒜", - "Assign": "≔", - "Atild": "Ã", - "Atilde": "Ã", - "Aum": "Ä", - "Auml": "Ä", - "Backslash": "∖", - "Barv": "⫧", - "Barwed": "⌆", - "Bcy": "Б", - "Because": "∵", - "Bernoullis": "ℬ", - "Beta": "Β", - "Bfr": "𝔅", - "Bopf": "𝔹", - "Breve": "˘", - "Bscr": "ℬ", - "Bumpeq": "≎", - "CHcy": "Ч", - "COP": "©", - "COPY": "©", - "Cacute": "Ć", - "Cap": "⋒", - "CapitalDifferentialD": "ⅅ", - "Cayleys": "ℭ", - "Ccaron": "Č", - "Ccedi": "Ç", - "Ccedil": "Ç", - "Ccirc": "Ĉ", - "Cconint": "∰", - "Cdot": "Ċ", - "Cedilla": "¸", - "CenterDot": "·", - "Cfr": "ℭ", - "Chi": "Χ", - "CircleDot": "⊙", - "CircleMinus": "⊖", - "CirclePlus": "⊕", - "CircleTimes": "⊗", - "ClockwiseContourIntegral": "∲", - "CloseCurlyDoubleQuote": "”", - "CloseCurlyQuote": "’", - "Colon": "∷", - "Colone": "⩴", - "Congruent": "≡", - "Conint": "∯", - "ContourIntegral": "∮", - "Copf": "ℂ", - "Coproduct": "∐", - "CounterClockwiseContourIntegral": "∳", - "Cross": "⨯", - "Cscr": "𝒞", - "Cup": "⋓", - "CupCap": "≍", - "DD": "ⅅ", - "DDotrahd": "⤑", - "DJcy": "Ђ", - "DScy": "Ѕ", - "DZcy": "Џ", - "Dagger": "‡", - "Darr": "↡", - "Dashv": "⫤", - "Dcaron": "Ď", - "Dcy": "Д", - "Del": "∇", - "Delta": "Δ", - "Dfr": "𝔇", - "DiacriticalAcute": "´", - "DiacriticalDot": "˙", - "DiacriticalDoubleAcute": "˝", - "DiacriticalGrave": "`", - "DiacriticalTilde": "˜", - "Diamond": "⋄", - "DifferentialD": "ⅆ", - "Dopf": "𝔻", - "Dot": "¨", - "DotDot": "⃜", - "DotEqual": "≐", - "DoubleContourIntegral": "∯", - "DoubleDot": "¨", - "DoubleDownArrow": "⇓", - "DoubleLeftArrow": "⇐", - "DoubleLeftRightArrow": "⇔", - "DoubleLeftTee": "⫤", - "DoubleLongLeftArrow": "⟸", - "DoubleLongLeftRightArrow": "⟺", - "DoubleLongRightArrow": "⟹", - "DoubleRightArrow": "⇒", - "DoubleRightTee": "⊨", - "DoubleUpArrow": "⇑", - "DoubleUpDownArrow": "⇕", - "DoubleVerticalBar": "∥", - "DownArrow": "↓", - "DownArrowBar": "⤓", - "DownArrowUpArrow": "⇵", - "DownBreve": "̑", - "DownLeftRightVector": "⥐", - "DownLeftTeeVector": "⥞", - "DownLeftVector": "↽", - "DownLeftVectorBar": "⥖", - "DownRightTeeVector": "⥟", - "DownRightVector": "⇁", - "DownRightVectorBar": "⥗", - "DownTee": "⊤", - "DownTeeArrow": "↧", - "Downarrow": "⇓", - "Dscr": "𝒟", - "Dstrok": "Đ", - "ENG": "Ŋ", - "ET": "Ð", - "ETH": "Ð", - "Eacut": "É", - "Eacute": "É", - "Ecaron": "Ě", - "Ecir": "Ê", - "Ecirc": "Ê", - "Ecy": "Э", - "Edot": "Ė", - "Efr": "𝔈", - "Egrav": "È", - "Egrave": "È", - "Element": "∈", - "Emacr": "Ē", - "EmptySmallSquare": "◻", - "EmptyVerySmallSquare": "▫", - "Eogon": "Ę", - "Eopf": "𝔼", - "Epsilon": "Ε", - "Equal": "⩵", - "EqualTilde": "≂", - "Equilibrium": "⇌", - "Escr": "ℰ", - "Esim": "⩳", - "Eta": "Η", - "Eum": "Ë", - "Euml": "Ë", - "Exists": "∃", - "ExponentialE": "ⅇ", - "Fcy": "Ф", - "Ffr": "𝔉", - "FilledSmallSquare": "◼", - "FilledVerySmallSquare": "▪", - "Fopf": "𝔽", - "ForAll": "∀", - "Fouriertrf": "ℱ", - "Fscr": "ℱ", - "GJcy": "Ѓ", - "G": ">", - "GT": ">", - "Gamma": "Γ", - "Gammad": "Ϝ", - "Gbreve": "Ğ", - "Gcedil": "Ģ", - "Gcirc": "Ĝ", - "Gcy": "Г", - "Gdot": "Ġ", - "Gfr": "𝔊", - "Gg": "⋙", - "Gopf": "𝔾", - "GreaterEqual": "≥", - "GreaterEqualLess": "⋛", - "GreaterFullEqual": "≧", - "GreaterGreater": "⪢", - "GreaterLess": "≷", - "GreaterSlantEqual": "⩾", - "GreaterTilde": "≳", - "Gscr": "𝒢", - "Gt": "≫", - "HARDcy": "Ъ", - "Hacek": "ˇ", - "Hat": "^", - "Hcirc": "Ĥ", - "Hfr": "ℌ", - "HilbertSpace": "ℋ", - "Hopf": "ℍ", - "HorizontalLine": "─", - "Hscr": "ℋ", - "Hstrok": "Ħ", - "HumpDownHump": "≎", - "HumpEqual": "≏", - "IEcy": "Е", - "IJlig": "IJ", - "IOcy": "Ё", - "Iacut": "Í", - "Iacute": "Í", - "Icir": "Î", - "Icirc": "Î", - "Icy": "И", - "Idot": "İ", - "Ifr": "ℑ", - "Igrav": "Ì", - "Igrave": "Ì", - "Im": "ℑ", - "Imacr": "Ī", - "ImaginaryI": "ⅈ", - "Implies": "⇒", - "Int": "∬", - "Integral": "∫", - "Intersection": "⋂", - "InvisibleComma": "⁣", - "InvisibleTimes": "⁢", - "Iogon": "Į", - "Iopf": "𝕀", - "Iota": "Ι", - "Iscr": "ℐ", - "Itilde": "Ĩ", - "Iukcy": "І", - "Ium": "Ï", - "Iuml": "Ï", - "Jcirc": "Ĵ", - "Jcy": "Й", - "Jfr": "𝔍", - "Jopf": "𝕁", - "Jscr": "𝒥", - "Jsercy": "Ј", - "Jukcy": "Є", - "KHcy": "Х", - "KJcy": "Ќ", - "Kappa": "Κ", - "Kcedil": "Ķ", - "Kcy": "К", - "Kfr": "𝔎", - "Kopf": "𝕂", - "Kscr": "𝒦", - "LJcy": "Љ", - "L": "<", - "LT": "<", - "Lacute": "Ĺ", - "Lambda": "Λ", - "Lang": "⟪", - "Laplacetrf": "ℒ", - "Larr": "↞", - "Lcaron": "Ľ", - "Lcedil": "Ļ", - "Lcy": "Л", - "LeftAngleBracket": "⟨", - "LeftArrow": "←", - "LeftArrowBar": "⇤", - "LeftArrowRightArrow": "⇆", - "LeftCeiling": "⌈", - "LeftDoubleBracket": "⟦", - "LeftDownTeeVector": "⥡", - "LeftDownVector": "⇃", - "LeftDownVectorBar": "⥙", - "LeftFloor": "⌊", - "LeftRightArrow": "↔", - "LeftRightVector": "⥎", - "LeftTee": "⊣", - "LeftTeeArrow": "↤", - "LeftTeeVector": "⥚", - "LeftTriangle": "⊲", - "LeftTriangleBar": "⧏", - "LeftTriangleEqual": "⊴", - "LeftUpDownVector": "⥑", - "LeftUpTeeVector": "⥠", - "LeftUpVector": "↿", - "LeftUpVectorBar": "⥘", - "LeftVector": "↼", - "LeftVectorBar": "⥒", - "Leftarrow": "⇐", - "Leftrightarrow": "⇔", - "LessEqualGreater": "⋚", - "LessFullEqual": "≦", - "LessGreater": "≶", - "LessLess": "⪡", - "LessSlantEqual": "⩽", - "LessTilde": "≲", - "Lfr": "𝔏", - "Ll": "⋘", - "Lleftarrow": "⇚", - "Lmidot": "Ŀ", - "LongLeftArrow": "⟵", - "LongLeftRightArrow": "⟷", - "LongRightArrow": "⟶", - "Longleftarrow": "⟸", - "Longleftrightarrow": "⟺", - "Longrightarrow": "⟹", - "Lopf": "𝕃", - "LowerLeftArrow": "↙", - "LowerRightArrow": "↘", - "Lscr": "ℒ", - "Lsh": "↰", - "Lstrok": "Ł", - "Lt": "≪", - "Map": "⤅", - "Mcy": "М", - "MediumSpace": " ", - "Mellintrf": "ℳ", - "Mfr": "𝔐", - "MinusPlus": "∓", - "Mopf": "𝕄", - "Mscr": "ℳ", - "Mu": "Μ", - "NJcy": "Њ", - "Nacute": "Ń", - "Ncaron": "Ň", - "Ncedil": "Ņ", - "Ncy": "Н", - "NegativeMediumSpace": "​", - "NegativeThickSpace": "​", - "NegativeThinSpace": "​", - "NegativeVeryThinSpace": "​", - "NestedGreaterGreater": "≫", - "NestedLessLess": "≪", - "NewLine": "\n", - "Nfr": "𝔑", - "NoBreak": "⁠", - "NonBreakingSpace": " ", - "Nopf": "ℕ", - "Not": "⫬", - "NotCongruent": "≢", - "NotCupCap": "≭", - "NotDoubleVerticalBar": "∦", - "NotElement": "∉", - "NotEqual": "≠", - "NotEqualTilde": "≂̸", - "NotExists": "∄", - "NotGreater": "≯", - "NotGreaterEqual": "≱", - "NotGreaterFullEqual": "≧̸", - "NotGreaterGreater": "≫̸", - "NotGreaterLess": "≹", - "NotGreaterSlantEqual": "⩾̸", - "NotGreaterTilde": "≵", - "NotHumpDownHump": "≎̸", - "NotHumpEqual": "≏̸", - "NotLeftTriangle": "⋪", - "NotLeftTriangleBar": "⧏̸", - "NotLeftTriangleEqual": "⋬", - "NotLess": "≮", - "NotLessEqual": "≰", - "NotLessGreater": "≸", - "NotLessLess": "≪̸", - "NotLessSlantEqual": "⩽̸", - "NotLessTilde": "≴", - "NotNestedGreaterGreater": "⪢̸", - "NotNestedLessLess": "⪡̸", - "NotPrecedes": "⊀", - "NotPrecedesEqual": "⪯̸", - "NotPrecedesSlantEqual": "⋠", - "NotReverseElement": "∌", - "NotRightTriangle": "⋫", - "NotRightTriangleBar": "⧐̸", - "NotRightTriangleEqual": "⋭", - "NotSquareSubset": "⊏̸", - "NotSquareSubsetEqual": "⋢", - "NotSquareSuperset": "⊐̸", - "NotSquareSupersetEqual": "⋣", - "NotSubset": "⊂⃒", - "NotSubsetEqual": "⊈", - "NotSucceeds": "⊁", - "NotSucceedsEqual": "⪰̸", - "NotSucceedsSlantEqual": "⋡", - "NotSucceedsTilde": "≿̸", - "NotSuperset": "⊃⃒", - "NotSupersetEqual": "⊉", - "NotTilde": "≁", - "NotTildeEqual": "≄", - "NotTildeFullEqual": "≇", - "NotTildeTilde": "≉", - "NotVerticalBar": "∤", - "Nscr": "𝒩", - "Ntild": "Ñ", - "Ntilde": "Ñ", - "Nu": "Ν", - "OElig": "Œ", - "Oacut": "Ó", - "Oacute": "Ó", - "Ocir": "Ô", - "Ocirc": "Ô", - "Ocy": "О", - "Odblac": "Ő", - "Ofr": "𝔒", - "Ograv": "Ò", - "Ograve": "Ò", - "Omacr": "Ō", - "Omega": "Ω", - "Omicron": "Ο", - "Oopf": "𝕆", - "OpenCurlyDoubleQuote": "“", - "OpenCurlyQuote": "‘", - "Or": "⩔", - "Oscr": "𝒪", - "Oslas": "Ø", - "Oslash": "Ø", - "Otild": "Õ", - "Otilde": "Õ", - "Otimes": "⨷", - "Oum": "Ö", - "Ouml": "Ö", - "OverBar": "‾", - "OverBrace": "⏞", - "OverBracket": "⎴", - "OverParenthesis": "⏜", - "PartialD": "∂", - "Pcy": "П", - "Pfr": "𝔓", - "Phi": "Φ", - "Pi": "Π", - "PlusMinus": "±", - "Poincareplane": "ℌ", - "Popf": "ℙ", - "Pr": "⪻", - "Precedes": "≺", - "PrecedesEqual": "⪯", - "PrecedesSlantEqual": "≼", - "PrecedesTilde": "≾", - "Prime": "″", - "Product": "∏", - "Proportion": "∷", - "Proportional": "∝", - "Pscr": "𝒫", - "Psi": "Ψ", - "QUO": "\"", - "QUOT": "\"", - "Qfr": "𝔔", - "Qopf": "ℚ", - "Qscr": "𝒬", - "RBarr": "⤐", - "RE": "®", - "REG": "®", - "Racute": "Ŕ", - "Rang": "⟫", - "Rarr": "↠", - "Rarrtl": "⤖", - "Rcaron": "Ř", - "Rcedil": "Ŗ", - "Rcy": "Р", - "Re": "ℜ", - "ReverseElement": "∋", - "ReverseEquilibrium": "⇋", - "ReverseUpEquilibrium": "⥯", - "Rfr": "ℜ", - "Rho": "Ρ", - "RightAngleBracket": "⟩", - "RightArrow": "→", - "RightArrowBar": "⇥", - "RightArrowLeftArrow": "⇄", - "RightCeiling": "⌉", - "RightDoubleBracket": "⟧", - "RightDownTeeVector": "⥝", - "RightDownVector": "⇂", - "RightDownVectorBar": "⥕", - "RightFloor": "⌋", - "RightTee": "⊢", - "RightTeeArrow": "↦", - "RightTeeVector": "⥛", - "RightTriangle": "⊳", - "RightTriangleBar": "⧐", - "RightTriangleEqual": "⊵", - "RightUpDownVector": "⥏", - "RightUpTeeVector": "⥜", - "RightUpVector": "↾", - "RightUpVectorBar": "⥔", - "RightVector": "⇀", - "RightVectorBar": "⥓", - "Rightarrow": "⇒", - "Ropf": "ℝ", - "RoundImplies": "⥰", - "Rrightarrow": "⇛", - "Rscr": "ℛ", - "Rsh": "↱", - "RuleDelayed": "⧴", - "SHCHcy": "Щ", - "SHcy": "Ш", - "SOFTcy": "Ь", - "Sacute": "Ś", - "Sc": "⪼", - "Scaron": "Š", - "Scedil": "Ş", - "Scirc": "Ŝ", - "Scy": "С", - "Sfr": "𝔖", - "ShortDownArrow": "↓", - "ShortLeftArrow": "←", - "ShortRightArrow": "→", - "ShortUpArrow": "↑", - "Sigma": "Σ", - "SmallCircle": "∘", - "Sopf": "𝕊", - "Sqrt": "√", - "Square": "□", - "SquareIntersection": "⊓", - "SquareSubset": "⊏", - "SquareSubsetEqual": "⊑", - "SquareSuperset": "⊐", - "SquareSupersetEqual": "⊒", - "SquareUnion": "⊔", - "Sscr": "𝒮", - "Star": "⋆", - "Sub": "⋐", - "Subset": "⋐", - "SubsetEqual": "⊆", - "Succeeds": "≻", - "SucceedsEqual": "⪰", - "SucceedsSlantEqual": "≽", - "SucceedsTilde": "≿", - "SuchThat": "∋", - "Sum": "∑", - "Sup": "⋑", - "Superset": "⊃", - "SupersetEqual": "⊇", - "Supset": "⋑", - "THOR": "Þ", - "THORN": "Þ", - "TRADE": "™", - "TSHcy": "Ћ", - "TScy": "Ц", - "Tab": "\t", - "Tau": "Τ", - "Tcaron": "Ť", - "Tcedil": "Ţ", - "Tcy": "Т", - "Tfr": "𝔗", - "Therefore": "∴", - "Theta": "Θ", - "ThickSpace": "  ", - "ThinSpace": " ", - "Tilde": "∼", - "TildeEqual": "≃", - "TildeFullEqual": "≅", - "TildeTilde": "≈", - "Topf": "𝕋", - "TripleDot": "⃛", - "Tscr": "𝒯", - "Tstrok": "Ŧ", - "Uacut": "Ú", - "Uacute": "Ú", - "Uarr": "↟", - "Uarrocir": "⥉", - "Ubrcy": "Ў", - "Ubreve": "Ŭ", - "Ucir": "Û", - "Ucirc": "Û", - "Ucy": "У", - "Udblac": "Ű", - "Ufr": "𝔘", - "Ugrav": "Ù", - "Ugrave": "Ù", - "Umacr": "Ū", - "UnderBar": "_", - "UnderBrace": "⏟", - "UnderBracket": "⎵", - "UnderParenthesis": "⏝", - "Union": "⋃", - "UnionPlus": "⊎", - "Uogon": "Ų", - "Uopf": "𝕌", - "UpArrow": "↑", - "UpArrowBar": "⤒", - "UpArrowDownArrow": "⇅", - "UpDownArrow": "↕", - "UpEquilibrium": "⥮", - "UpTee": "⊥", - "UpTeeArrow": "↥", - "Uparrow": "⇑", - "Updownarrow": "⇕", - "UpperLeftArrow": "↖", - "UpperRightArrow": "↗", - "Upsi": "ϒ", - "Upsilon": "Υ", - "Uring": "Ů", - "Uscr": "𝒰", - "Utilde": "Ũ", - "Uum": "Ü", - "Uuml": "Ü", - "VDash": "⊫", - "Vbar": "⫫", - "Vcy": "В", - "Vdash": "⊩", - "Vdashl": "⫦", - "Vee": "⋁", - "Verbar": "‖", - "Vert": "‖", - "VerticalBar": "∣", - "VerticalLine": "|", - "VerticalSeparator": "❘", - "VerticalTilde": "≀", - "VeryThinSpace": " ", - "Vfr": "𝔙", - "Vopf": "𝕍", - "Vscr": "𝒱", - "Vvdash": "⊪", - "Wcirc": "Ŵ", - "Wedge": "⋀", - "Wfr": "𝔚", - "Wopf": "𝕎", - "Wscr": "𝒲", - "Xfr": "𝔛", - "Xi": "Ξ", - "Xopf": "𝕏", - "Xscr": "𝒳", - "YAcy": "Я", - "YIcy": "Ї", - "YUcy": "Ю", - "Yacut": "Ý", - "Yacute": "Ý", - "Ycirc": "Ŷ", - "Ycy": "Ы", - "Yfr": "𝔜", - "Yopf": "𝕐", - "Yscr": "𝒴", - "Yuml": "Ÿ", - "ZHcy": "Ж", - "Zacute": "Ź", - "Zcaron": "Ž", - "Zcy": "З", - "Zdot": "Ż", - "ZeroWidthSpace": "​", - "Zeta": "Ζ", - "Zfr": "ℨ", - "Zopf": "ℤ", - "Zscr": "𝒵", - "aacut": "á", - "aacute": "á", - "abreve": "ă", - "ac": "∾", - "acE": "∾̳", - "acd": "∿", - "acir": "â", - "acirc": "â", - "acut": "´", - "acute": "´", - "acy": "а", - "aeli": "æ", - "aelig": "æ", - "af": "⁡", - "afr": "𝔞", - "agrav": "à", - "agrave": "à", - "alefsym": "ℵ", - "aleph": "ℵ", - "alpha": "α", - "amacr": "ā", - "amalg": "⨿", - "am": "&", - "amp": "&", - "and": "∧", - "andand": "⩕", - "andd": "⩜", - "andslope": "⩘", - "andv": "⩚", - "ang": "∠", - "ange": "⦤", - "angle": "∠", - "angmsd": "∡", - "angmsdaa": "⦨", - "angmsdab": "⦩", - "angmsdac": "⦪", - "angmsdad": "⦫", - "angmsdae": "⦬", - "angmsdaf": "⦭", - "angmsdag": "⦮", - "angmsdah": "⦯", - "angrt": "∟", - "angrtvb": "⊾", - "angrtvbd": "⦝", - "angsph": "∢", - "angst": "Å", - "angzarr": "⍼", - "aogon": "ą", - "aopf": "𝕒", - "ap": "≈", - "apE": "⩰", - "apacir": "⩯", - "ape": "≊", - "apid": "≋", - "apos": "'", - "approx": "≈", - "approxeq": "≊", - "arin": "å", - "aring": "å", - "ascr": "𝒶", - "ast": "*", - "asymp": "≈", - "asympeq": "≍", - "atild": "ã", - "atilde": "ã", - "aum": "ä", - "auml": "ä", - "awconint": "∳", - "awint": "⨑", - "bNot": "⫭", - "backcong": "≌", - "backepsilon": "϶", - "backprime": "‵", - "backsim": "∽", - "backsimeq": "⋍", - "barvee": "⊽", - "barwed": "⌅", - "barwedge": "⌅", - "bbrk": "⎵", - "bbrktbrk": "⎶", - "bcong": "≌", - "bcy": "б", - "bdquo": "„", - "becaus": "∵", - "because": "∵", - "bemptyv": "⦰", - "bepsi": "϶", - "bernou": "ℬ", - "beta": "β", - "beth": "ℶ", - "between": "≬", - "bfr": "𝔟", - "bigcap": "⋂", - "bigcirc": "◯", - "bigcup": "⋃", - "bigodot": "⨀", - "bigoplus": "⨁", - "bigotimes": "⨂", - "bigsqcup": "⨆", - "bigstar": "★", - "bigtriangledown": "▽", - "bigtriangleup": "△", - "biguplus": "⨄", - "bigvee": "⋁", - "bigwedge": "⋀", - "bkarow": "⤍", - "blacklozenge": "⧫", - "blacksquare": "▪", - "blacktriangle": "▴", - "blacktriangledown": "▾", - "blacktriangleleft": "◂", - "blacktriangleright": "▸", - "blank": "␣", - "blk12": "▒", - "blk14": "░", - "blk34": "▓", - "block": "█", - "bne": "=⃥", - "bnequiv": "≡⃥", - "bnot": "⌐", - "bopf": "𝕓", - "bot": "⊥", - "bottom": "⊥", - "bowtie": "⋈", - "boxDL": "╗", - "boxDR": "╔", - "boxDl": "╖", - "boxDr": "╓", - "boxH": "═", - "boxHD": "╦", - "boxHU": "╩", - "boxHd": "╤", - "boxHu": "╧", - "boxUL": "╝", - "boxUR": "╚", - "boxUl": "╜", - "boxUr": "╙", - "boxV": "║", - "boxVH": "╬", - "boxVL": "╣", - "boxVR": "╠", - "boxVh": "╫", - "boxVl": "╢", - "boxVr": "╟", - "boxbox": "⧉", - "boxdL": "╕", - "boxdR": "╒", - "boxdl": "┐", - "boxdr": "┌", - "boxh": "─", - "boxhD": "╥", - "boxhU": "╨", - "boxhd": "┬", - "boxhu": "┴", - "boxminus": "⊟", - "boxplus": "⊞", - "boxtimes": "⊠", - "boxuL": "╛", - "boxuR": "╘", - "boxul": "┘", - "boxur": "└", - "boxv": "│", - "boxvH": "╪", - "boxvL": "╡", - "boxvR": "╞", - "boxvh": "┼", - "boxvl": "┤", - "boxvr": "├", - "bprime": "‵", - "breve": "˘", - "brvba": "¦", - "brvbar": "¦", - "bscr": "𝒷", - "bsemi": "⁏", - "bsim": "∽", - "bsime": "⋍", - "bsol": "\\", - "bsolb": "⧅", - "bsolhsub": "⟈", - "bull": "•", - "bullet": "•", - "bump": "≎", - "bumpE": "⪮", - "bumpe": "≏", - "bumpeq": "≏", - "cacute": "ć", - "cap": "∩", - "capand": "⩄", - "capbrcup": "⩉", - "capcap": "⩋", - "capcup": "⩇", - "capdot": "⩀", - "caps": "∩︀", - "caret": "⁁", - "caron": "ˇ", - "ccaps": "⩍", - "ccaron": "č", - "ccedi": "ç", - "ccedil": "ç", - "ccirc": "ĉ", - "ccups": "⩌", - "ccupssm": "⩐", - "cdot": "ċ", - "cedi": "¸", - "cedil": "¸", - "cemptyv": "⦲", - "cen": "¢", - "cent": "¢", - "centerdot": "·", - "cfr": "𝔠", - "chcy": "ч", - "check": "✓", - "checkmark": "✓", - "chi": "χ", - "cir": "○", - "cirE": "⧃", - "circ": "ˆ", - "circeq": "≗", - "circlearrowleft": "↺", - "circlearrowright": "↻", - "circledR": "®", - "circledS": "Ⓢ", - "circledast": "⊛", - "circledcirc": "⊚", - "circleddash": "⊝", - "cire": "≗", - "cirfnint": "⨐", - "cirmid": "⫯", - "cirscir": "⧂", - "clubs": "♣", - "clubsuit": "♣", - "colon": ":", - "colone": "≔", - "coloneq": "≔", - "comma": ",", - "commat": "@", - "comp": "∁", - "compfn": "∘", - "complement": "∁", - "complexes": "ℂ", - "cong": "≅", - "congdot": "⩭", - "conint": "∮", - "copf": "𝕔", - "coprod": "∐", - "cop": "©", - "copy": "©", - "copysr": "℗", - "crarr": "↵", - "cross": "✗", - "cscr": "𝒸", - "csub": "⫏", - "csube": "⫑", - "csup": "⫐", - "csupe": "⫒", - "ctdot": "⋯", - "cudarrl": "⤸", - "cudarrr": "⤵", - "cuepr": "⋞", - "cuesc": "⋟", - "cularr": "↶", - "cularrp": "⤽", - "cup": "∪", - "cupbrcap": "⩈", - "cupcap": "⩆", - "cupcup": "⩊", - "cupdot": "⊍", - "cupor": "⩅", - "cups": "∪︀", - "curarr": "↷", - "curarrm": "⤼", - "curlyeqprec": "⋞", - "curlyeqsucc": "⋟", - "curlyvee": "⋎", - "curlywedge": "⋏", - "curre": "¤", - "curren": "¤", - "curvearrowleft": "↶", - "curvearrowright": "↷", - "cuvee": "⋎", - "cuwed": "⋏", - "cwconint": "∲", - "cwint": "∱", - "cylcty": "⌭", - "dArr": "⇓", - "dHar": "⥥", - "dagger": "†", - "daleth": "ℸ", - "darr": "↓", - "dash": "‐", - "dashv": "⊣", - "dbkarow": "⤏", - "dblac": "˝", - "dcaron": "ď", - "dcy": "д", - "dd": "ⅆ", - "ddagger": "‡", - "ddarr": "⇊", - "ddotseq": "⩷", - "de": "°", - "deg": "°", - "delta": "δ", - "demptyv": "⦱", - "dfisht": "⥿", - "dfr": "𝔡", - "dharl": "⇃", - "dharr": "⇂", - "diam": "⋄", - "diamond": "⋄", - "diamondsuit": "♦", - "diams": "♦", - "die": "¨", - "digamma": "ϝ", - "disin": "⋲", - "div": "÷", - "divid": "÷", - "divide": "÷", - "divideontimes": "⋇", - "divonx": "⋇", - "djcy": "ђ", - "dlcorn": "⌞", - "dlcrop": "⌍", - "dollar": "$", - "dopf": "𝕕", - "dot": "˙", - "doteq": "≐", - "doteqdot": "≑", - "dotminus": "∸", - "dotplus": "∔", - "dotsquare": "⊡", - "doublebarwedge": "⌆", - "downarrow": "↓", - "downdownarrows": "⇊", - "downharpoonleft": "⇃", - "downharpoonright": "⇂", - "drbkarow": "⤐", - "drcorn": "⌟", - "drcrop": "⌌", - "dscr": "𝒹", - "dscy": "ѕ", - "dsol": "⧶", - "dstrok": "đ", - "dtdot": "⋱", - "dtri": "▿", - "dtrif": "▾", - "duarr": "⇵", - "duhar": "⥯", - "dwangle": "⦦", - "dzcy": "џ", - "dzigrarr": "⟿", - "eDDot": "⩷", - "eDot": "≑", - "eacut": "é", - "eacute": "é", - "easter": "⩮", - "ecaron": "ě", - "ecir": "ê", - "ecirc": "ê", - "ecolon": "≕", - "ecy": "э", - "edot": "ė", - "ee": "ⅇ", - "efDot": "≒", - "efr": "𝔢", - "eg": "⪚", - "egrav": "è", - "egrave": "è", - "egs": "⪖", - "egsdot": "⪘", - "el": "⪙", - "elinters": "⏧", - "ell": "ℓ", - "els": "⪕", - "elsdot": "⪗", - "emacr": "ē", - "empty": "∅", - "emptyset": "∅", - "emptyv": "∅", - "emsp13": " ", - "emsp14": " ", - "emsp": " ", - "eng": "ŋ", - "ensp": " ", - "eogon": "ę", - "eopf": "𝕖", - "epar": "⋕", - "eparsl": "⧣", - "eplus": "⩱", - "epsi": "ε", - "epsilon": "ε", - "epsiv": "ϵ", - "eqcirc": "≖", - "eqcolon": "≕", - "eqsim": "≂", - "eqslantgtr": "⪖", - "eqslantless": "⪕", - "equals": "=", - "equest": "≟", - "equiv": "≡", - "equivDD": "⩸", - "eqvparsl": "⧥", - "erDot": "≓", - "erarr": "⥱", - "escr": "ℯ", - "esdot": "≐", - "esim": "≂", - "eta": "η", - "et": "ð", - "eth": "ð", - "eum": "ë", - "euml": "ë", - "euro": "€", - "excl": "!", - "exist": "∃", - "expectation": "ℰ", - "exponentiale": "ⅇ", - "fallingdotseq": "≒", - "fcy": "ф", - "female": "♀", - "ffilig": "ffi", - "fflig": "ff", - "ffllig": "ffl", - "ffr": "𝔣", - "filig": "fi", - "fjlig": "fj", - "flat": "♭", - "fllig": "fl", - "fltns": "▱", - "fnof": "ƒ", - "fopf": "𝕗", - "forall": "∀", - "fork": "⋔", - "forkv": "⫙", - "fpartint": "⨍", - "frac1": "¼", - "frac12": "½", - "frac13": "⅓", - "frac14": "¼", - "frac15": "⅕", - "frac16": "⅙", - "frac18": "⅛", - "frac23": "⅔", - "frac25": "⅖", - "frac3": "¾", - "frac34": "¾", - "frac35": "⅗", - "frac38": "⅜", - "frac45": "⅘", - "frac56": "⅚", - "frac58": "⅝", - "frac78": "⅞", - "frasl": "⁄", - "frown": "⌢", - "fscr": "𝒻", - "gE": "≧", - "gEl": "⪌", - "gacute": "ǵ", - "gamma": "γ", - "gammad": "ϝ", - "gap": "⪆", - "gbreve": "ğ", - "gcirc": "ĝ", - "gcy": "г", - "gdot": "ġ", - "ge": "≥", - "gel": "⋛", - "geq": "≥", - "geqq": "≧", - "geqslant": "⩾", - "ges": "⩾", - "gescc": "⪩", - "gesdot": "⪀", - "gesdoto": "⪂", - "gesdotol": "⪄", - "gesl": "⋛︀", - "gesles": "⪔", - "gfr": "𝔤", - "gg": "≫", - "ggg": "⋙", - "gimel": "ℷ", - "gjcy": "ѓ", - "gl": "≷", - "glE": "⪒", - "gla": "⪥", - "glj": "⪤", - "gnE": "≩", - "gnap": "⪊", - "gnapprox": "⪊", - "gne": "⪈", - "gneq": "⪈", - "gneqq": "≩", - "gnsim": "⋧", - "gopf": "𝕘", - "grave": "`", - "gscr": "ℊ", - "gsim": "≳", - "gsime": "⪎", - "gsiml": "⪐", - "g": ">", - "gt": ">", - "gtcc": "⪧", - "gtcir": "⩺", - "gtdot": "⋗", - "gtlPar": "⦕", - "gtquest": "⩼", - "gtrapprox": "⪆", - "gtrarr": "⥸", - "gtrdot": "⋗", - "gtreqless": "⋛", - "gtreqqless": "⪌", - "gtrless": "≷", - "gtrsim": "≳", - "gvertneqq": "≩︀", - "gvnE": "≩︀", - "hArr": "⇔", - "hairsp": " ", - "half": "½", - "hamilt": "ℋ", - "hardcy": "ъ", - "harr": "↔", - "harrcir": "⥈", - "harrw": "↭", - "hbar": "ℏ", - "hcirc": "ĥ", - "hearts": "♥", - "heartsuit": "♥", - "hellip": "…", - "hercon": "⊹", - "hfr": "𝔥", - "hksearow": "⤥", - "hkswarow": "⤦", - "hoarr": "⇿", - "homtht": "∻", - "hookleftarrow": "↩", - "hookrightarrow": "↪", - "hopf": "𝕙", - "horbar": "―", - "hscr": "𝒽", - "hslash": "ℏ", - "hstrok": "ħ", - "hybull": "⁃", - "hyphen": "‐", - "iacut": "í", - "iacute": "í", - "ic": "⁣", - "icir": "î", - "icirc": "î", - "icy": "и", - "iecy": "е", - "iexc": "¡", - "iexcl": "¡", - "iff": "⇔", - "ifr": "𝔦", - "igrav": "ì", - "igrave": "ì", - "ii": "ⅈ", - "iiiint": "⨌", - "iiint": "∭", - "iinfin": "⧜", - "iiota": "℩", - "ijlig": "ij", - "imacr": "ī", - "image": "ℑ", - "imagline": "ℐ", - "imagpart": "ℑ", - "imath": "ı", - "imof": "⊷", - "imped": "Ƶ", - "in": "∈", - "incare": "℅", - "infin": "∞", - "infintie": "⧝", - "inodot": "ı", - "int": "∫", - "intcal": "⊺", - "integers": "ℤ", - "intercal": "⊺", - "intlarhk": "⨗", - "intprod": "⨼", - "iocy": "ё", - "iogon": "į", - "iopf": "𝕚", - "iota": "ι", - "iprod": "⨼", - "iques": "¿", - "iquest": "¿", - "iscr": "𝒾", - "isin": "∈", - "isinE": "⋹", - "isindot": "⋵", - "isins": "⋴", - "isinsv": "⋳", - "isinv": "∈", - "it": "⁢", - "itilde": "ĩ", - "iukcy": "і", - "ium": "ï", - "iuml": "ï", - "jcirc": "ĵ", - "jcy": "й", - "jfr": "𝔧", - "jmath": "ȷ", - "jopf": "𝕛", - "jscr": "𝒿", - "jsercy": "ј", - "jukcy": "є", - "kappa": "κ", - "kappav": "ϰ", - "kcedil": "ķ", - "kcy": "к", - "kfr": "𝔨", - "kgreen": "ĸ", - "khcy": "х", - "kjcy": "ќ", - "kopf": "𝕜", - "kscr": "𝓀", - "lAarr": "⇚", - "lArr": "⇐", - "lAtail": "⤛", - "lBarr": "⤎", - "lE": "≦", - "lEg": "⪋", - "lHar": "⥢", - "lacute": "ĺ", - "laemptyv": "⦴", - "lagran": "ℒ", - "lambda": "λ", - "lang": "⟨", - "langd": "⦑", - "langle": "⟨", - "lap": "⪅", - "laqu": "«", - "laquo": "«", - "larr": "←", - "larrb": "⇤", - "larrbfs": "⤟", - "larrfs": "⤝", - "larrhk": "↩", - "larrlp": "↫", - "larrpl": "⤹", - "larrsim": "⥳", - "larrtl": "↢", - "lat": "⪫", - "latail": "⤙", - "late": "⪭", - "lates": "⪭︀", - "lbarr": "⤌", - "lbbrk": "❲", - "lbrace": "{", - "lbrack": "[", - "lbrke": "⦋", - "lbrksld": "⦏", - "lbrkslu": "⦍", - "lcaron": "ľ", - "lcedil": "ļ", - "lceil": "⌈", - "lcub": "{", - "lcy": "л", - "ldca": "⤶", - "ldquo": "“", - "ldquor": "„", - "ldrdhar": "⥧", - "ldrushar": "⥋", - "ldsh": "↲", - "le": "≤", - "leftarrow": "←", - "leftarrowtail": "↢", - "leftharpoondown": "↽", - "leftharpoonup": "↼", - "leftleftarrows": "⇇", - "leftrightarrow": "↔", - "leftrightarrows": "⇆", - "leftrightharpoons": "⇋", - "leftrightsquigarrow": "↭", - "leftthreetimes": "⋋", - "leg": "⋚", - "leq": "≤", - "leqq": "≦", - "leqslant": "⩽", - "les": "⩽", - "lescc": "⪨", - "lesdot": "⩿", - "lesdoto": "⪁", - "lesdotor": "⪃", - "lesg": "⋚︀", - "lesges": "⪓", - "lessapprox": "⪅", - "lessdot": "⋖", - "lesseqgtr": "⋚", - "lesseqqgtr": "⪋", - "lessgtr": "≶", - "lesssim": "≲", - "lfisht": "⥼", - "lfloor": "⌊", - "lfr": "𝔩", - "lg": "≶", - "lgE": "⪑", - "lhard": "↽", - "lharu": "↼", - "lharul": "⥪", - "lhblk": "▄", - "ljcy": "љ", - "ll": "≪", - "llarr": "⇇", - "llcorner": "⌞", - "llhard": "⥫", - "lltri": "◺", - "lmidot": "ŀ", - "lmoust": "⎰", - "lmoustache": "⎰", - "lnE": "≨", - "lnap": "⪉", - "lnapprox": "⪉", - "lne": "⪇", - "lneq": "⪇", - "lneqq": "≨", - "lnsim": "⋦", - "loang": "⟬", - "loarr": "⇽", - "lobrk": "⟦", - "longleftarrow": "⟵", - "longleftrightarrow": "⟷", - "longmapsto": "⟼", - "longrightarrow": "⟶", - "looparrowleft": "↫", - "looparrowright": "↬", - "lopar": "⦅", - "lopf": "𝕝", - "loplus": "⨭", - "lotimes": "⨴", - "lowast": "∗", - "lowbar": "_", - "loz": "◊", - "lozenge": "◊", - "lozf": "⧫", - "lpar": "(", - "lparlt": "⦓", - "lrarr": "⇆", - "lrcorner": "⌟", - "lrhar": "⇋", - "lrhard": "⥭", - "lrm": "‎", - "lrtri": "⊿", - "lsaquo": "‹", - "lscr": "𝓁", - "lsh": "↰", - "lsim": "≲", - "lsime": "⪍", - "lsimg": "⪏", - "lsqb": "[", - "lsquo": "‘", - "lsquor": "‚", - "lstrok": "ł", - "l": "<", - "lt": "<", - "ltcc": "⪦", - "ltcir": "⩹", - "ltdot": "⋖", - "lthree": "⋋", - "ltimes": "⋉", - "ltlarr": "⥶", - "ltquest": "⩻", - "ltrPar": "⦖", - "ltri": "◃", - "ltrie": "⊴", - "ltrif": "◂", - "lurdshar": "⥊", - "luruhar": "⥦", - "lvertneqq": "≨︀", - "lvnE": "≨︀", - "mDDot": "∺", - "mac": "¯", - "macr": "¯", - "male": "♂", - "malt": "✠", - "maltese": "✠", - "map": "↦", - "mapsto": "↦", - "mapstodown": "↧", - "mapstoleft": "↤", - "mapstoup": "↥", - "marker": "▮", - "mcomma": "⨩", - "mcy": "м", - "mdash": "—", - "measuredangle": "∡", - "mfr": "𝔪", - "mho": "℧", - "micr": "µ", - "micro": "µ", - "mid": "∣", - "midast": "*", - "midcir": "⫰", - "middo": "·", - "middot": "·", - "minus": "−", - "minusb": "⊟", - "minusd": "∸", - "minusdu": "⨪", - "mlcp": "⫛", - "mldr": "…", - "mnplus": "∓", - "models": "⊧", - "mopf": "𝕞", - "mp": "∓", - "mscr": "𝓂", - "mstpos": "∾", - "mu": "μ", - "multimap": "⊸", - "mumap": "⊸", - "nGg": "⋙̸", - "nGt": "≫⃒", - "nGtv": "≫̸", - "nLeftarrow": "⇍", - "nLeftrightarrow": "⇎", - "nLl": "⋘̸", - "nLt": "≪⃒", - "nLtv": "≪̸", - "nRightarrow": "⇏", - "nVDash": "⊯", - "nVdash": "⊮", - "nabla": "∇", - "nacute": "ń", - "nang": "∠⃒", - "nap": "≉", - "napE": "⩰̸", - "napid": "≋̸", - "napos": "ʼn", - "napprox": "≉", - "natur": "♮", - "natural": "♮", - "naturals": "ℕ", - "nbs": " ", - "nbsp": " ", - "nbump": "≎̸", - "nbumpe": "≏̸", - "ncap": "⩃", - "ncaron": "ň", - "ncedil": "ņ", - "ncong": "≇", - "ncongdot": "⩭̸", - "ncup": "⩂", - "ncy": "н", - "ndash": "–", - "ne": "≠", - "neArr": "⇗", - "nearhk": "⤤", - "nearr": "↗", - "nearrow": "↗", - "nedot": "≐̸", - "nequiv": "≢", - "nesear": "⤨", - "nesim": "≂̸", - "nexist": "∄", - "nexists": "∄", - "nfr": "𝔫", - "ngE": "≧̸", - "nge": "≱", - "ngeq": "≱", - "ngeqq": "≧̸", - "ngeqslant": "⩾̸", - "nges": "⩾̸", - "ngsim": "≵", - "ngt": "≯", - "ngtr": "≯", - "nhArr": "⇎", - "nharr": "↮", - "nhpar": "⫲", - "ni": "∋", - "nis": "⋼", - "nisd": "⋺", - "niv": "∋", - "njcy": "њ", - "nlArr": "⇍", - "nlE": "≦̸", - "nlarr": "↚", - "nldr": "‥", - "nle": "≰", - "nleftarrow": "↚", - "nleftrightarrow": "↮", - "nleq": "≰", - "nleqq": "≦̸", - "nleqslant": "⩽̸", - "nles": "⩽̸", - "nless": "≮", - "nlsim": "≴", - "nlt": "≮", - "nltri": "⋪", - "nltrie": "⋬", - "nmid": "∤", - "nopf": "𝕟", - "no": "¬", - "not": "¬", - "notin": "∉", - "notinE": "⋹̸", - "notindot": "⋵̸", - "notinva": "∉", - "notinvb": "⋷", - "notinvc": "⋶", - "notni": "∌", - "notniva": "∌", - "notnivb": "⋾", - "notnivc": "⋽", - "npar": "∦", - "nparallel": "∦", - "nparsl": "⫽⃥", - "npart": "∂̸", - "npolint": "⨔", - "npr": "⊀", - "nprcue": "⋠", - "npre": "⪯̸", - "nprec": "⊀", - "npreceq": "⪯̸", - "nrArr": "⇏", - "nrarr": "↛", - "nrarrc": "⤳̸", - "nrarrw": "↝̸", - "nrightarrow": "↛", - "nrtri": "⋫", - "nrtrie": "⋭", - "nsc": "⊁", - "nsccue": "⋡", - "nsce": "⪰̸", - "nscr": "𝓃", - "nshortmid": "∤", - "nshortparallel": "∦", - "nsim": "≁", - "nsime": "≄", - "nsimeq": "≄", - "nsmid": "∤", - "nspar": "∦", - "nsqsube": "⋢", - "nsqsupe": "⋣", - "nsub": "⊄", - "nsubE": "⫅̸", - "nsube": "⊈", - "nsubset": "⊂⃒", - "nsubseteq": "⊈", - "nsubseteqq": "⫅̸", - "nsucc": "⊁", - "nsucceq": "⪰̸", - "nsup": "⊅", - "nsupE": "⫆̸", - "nsupe": "⊉", - "nsupset": "⊃⃒", - "nsupseteq": "⊉", - "nsupseteqq": "⫆̸", - "ntgl": "≹", - "ntild": "ñ", - "ntilde": "ñ", - "ntlg": "≸", - "ntriangleleft": "⋪", - "ntrianglelefteq": "⋬", - "ntriangleright": "⋫", - "ntrianglerighteq": "⋭", - "nu": "ν", - "num": "#", - "numero": "№", - "numsp": " ", - "nvDash": "⊭", - "nvHarr": "⤄", - "nvap": "≍⃒", - "nvdash": "⊬", - "nvge": "≥⃒", - "nvgt": ">⃒", - "nvinfin": "⧞", - "nvlArr": "⤂", - "nvle": "≤⃒", - "nvlt": "<⃒", - "nvltrie": "⊴⃒", - "nvrArr": "⤃", - "nvrtrie": "⊵⃒", - "nvsim": "∼⃒", - "nwArr": "⇖", - "nwarhk": "⤣", - "nwarr": "↖", - "nwarrow": "↖", - "nwnear": "⤧", - "oS": "Ⓢ", - "oacut": "ó", - "oacute": "ó", - "oast": "⊛", - "ocir": "ô", - "ocirc": "ô", - "ocy": "о", - "odash": "⊝", - "odblac": "ő", - "odiv": "⨸", - "odot": "⊙", - "odsold": "⦼", - "oelig": "œ", - "ofcir": "⦿", - "ofr": "𝔬", - "ogon": "˛", - "ograv": "ò", - "ograve": "ò", - "ogt": "⧁", - "ohbar": "⦵", - "ohm": "Ω", - "oint": "∮", - "olarr": "↺", - "olcir": "⦾", - "olcross": "⦻", - "oline": "‾", - "olt": "⧀", - "omacr": "ō", - "omega": "ω", - "omicron": "ο", - "omid": "⦶", - "ominus": "⊖", - "oopf": "𝕠", - "opar": "⦷", - "operp": "⦹", - "oplus": "⊕", - "or": "∨", - "orarr": "↻", - "ord": "º", - "order": "ℴ", - "orderof": "ℴ", - "ordf": "ª", - "ordm": "º", - "origof": "⊶", - "oror": "⩖", - "orslope": "⩗", - "orv": "⩛", - "oscr": "ℴ", - "oslas": "ø", - "oslash": "ø", - "osol": "⊘", - "otild": "õ", - "otilde": "õ", - "otimes": "⊗", - "otimesas": "⨶", - "oum": "ö", - "ouml": "ö", - "ovbar": "⌽", - "par": "¶", - "para": "¶", - "parallel": "∥", - "parsim": "⫳", - "parsl": "⫽", - "part": "∂", - "pcy": "п", - "percnt": "%", - "period": ".", - "permil": "‰", - "perp": "⊥", - "pertenk": "‱", - "pfr": "𝔭", - "phi": "φ", - "phiv": "ϕ", - "phmmat": "ℳ", - "phone": "☎", - "pi": "π", - "pitchfork": "⋔", - "piv": "ϖ", - "planck": "ℏ", - "planckh": "ℎ", - "plankv": "ℏ", - "plus": "+", - "plusacir": "⨣", - "plusb": "⊞", - "pluscir": "⨢", - "plusdo": "∔", - "plusdu": "⨥", - "pluse": "⩲", - "plusm": "±", - "plusmn": "±", - "plussim": "⨦", - "plustwo": "⨧", - "pm": "±", - "pointint": "⨕", - "popf": "𝕡", - "poun": "£", - "pound": "£", - "pr": "≺", - "prE": "⪳", - "prap": "⪷", - "prcue": "≼", - "pre": "⪯", - "prec": "≺", - "precapprox": "⪷", - "preccurlyeq": "≼", - "preceq": "⪯", - "precnapprox": "⪹", - "precneqq": "⪵", - "precnsim": "⋨", - "precsim": "≾", - "prime": "′", - "primes": "ℙ", - "prnE": "⪵", - "prnap": "⪹", - "prnsim": "⋨", - "prod": "∏", - "profalar": "⌮", - "profline": "⌒", - "profsurf": "⌓", - "prop": "∝", - "propto": "∝", - "prsim": "≾", - "prurel": "⊰", - "pscr": "𝓅", - "psi": "ψ", - "puncsp": " ", - "qfr": "𝔮", - "qint": "⨌", - "qopf": "𝕢", - "qprime": "⁗", - "qscr": "𝓆", - "quaternions": "ℍ", - "quatint": "⨖", - "quest": "?", - "questeq": "≟", - "quo": "\"", - "quot": "\"", - "rAarr": "⇛", - "rArr": "⇒", - "rAtail": "⤜", - "rBarr": "⤏", - "rHar": "⥤", - "race": "∽̱", - "racute": "ŕ", - "radic": "√", - "raemptyv": "⦳", - "rang": "⟩", - "rangd": "⦒", - "range": "⦥", - "rangle": "⟩", - "raqu": "»", - "raquo": "»", - "rarr": "→", - "rarrap": "⥵", - "rarrb": "⇥", - "rarrbfs": "⤠", - "rarrc": "⤳", - "rarrfs": "⤞", - "rarrhk": "↪", - "rarrlp": "↬", - "rarrpl": "⥅", - "rarrsim": "⥴", - "rarrtl": "↣", - "rarrw": "↝", - "ratail": "⤚", - "ratio": "∶", - "rationals": "ℚ", - "rbarr": "⤍", - "rbbrk": "❳", - "rbrace": "}", - "rbrack": "]", - "rbrke": "⦌", - "rbrksld": "⦎", - "rbrkslu": "⦐", - "rcaron": "ř", - "rcedil": "ŗ", - "rceil": "⌉", - "rcub": "}", - "rcy": "р", - "rdca": "⤷", - "rdldhar": "⥩", - "rdquo": "”", - "rdquor": "”", - "rdsh": "↳", - "real": "ℜ", - "realine": "ℛ", - "realpart": "ℜ", - "reals": "ℝ", - "rect": "▭", - "re": "®", - "reg": "®", - "rfisht": "⥽", - "rfloor": "⌋", - "rfr": "𝔯", - "rhard": "⇁", - "rharu": "⇀", - "rharul": "⥬", - "rho": "ρ", - "rhov": "ϱ", - "rightarrow": "→", - "rightarrowtail": "↣", - "rightharpoondown": "⇁", - "rightharpoonup": "⇀", - "rightleftarrows": "⇄", - "rightleftharpoons": "⇌", - "rightrightarrows": "⇉", - "rightsquigarrow": "↝", - "rightthreetimes": "⋌", - "ring": "˚", - "risingdotseq": "≓", - "rlarr": "⇄", - "rlhar": "⇌", - "rlm": "‏", - "rmoust": "⎱", - "rmoustache": "⎱", - "rnmid": "⫮", - "roang": "⟭", - "roarr": "⇾", - "robrk": "⟧", - "ropar": "⦆", - "ropf": "𝕣", - "roplus": "⨮", - "rotimes": "⨵", - "rpar": ")", - "rpargt": "⦔", - "rppolint": "⨒", - "rrarr": "⇉", - "rsaquo": "›", - "rscr": "𝓇", - "rsh": "↱", - "rsqb": "]", - "rsquo": "’", - "rsquor": "’", - "rthree": "⋌", - "rtimes": "⋊", - "rtri": "▹", - "rtrie": "⊵", - "rtrif": "▸", - "rtriltri": "⧎", - "ruluhar": "⥨", - "rx": "℞", - "sacute": "ś", - "sbquo": "‚", - "sc": "≻", - "scE": "⪴", - "scap": "⪸", - "scaron": "š", - "sccue": "≽", - "sce": "⪰", - "scedil": "ş", - "scirc": "ŝ", - "scnE": "⪶", - "scnap": "⪺", - "scnsim": "⋩", - "scpolint": "⨓", - "scsim": "≿", - "scy": "с", - "sdot": "⋅", - "sdotb": "⊡", - "sdote": "⩦", - "seArr": "⇘", - "searhk": "⤥", - "searr": "↘", - "searrow": "↘", - "sec": "§", - "sect": "§", - "semi": ";", - "seswar": "⤩", - "setminus": "∖", - "setmn": "∖", - "sext": "✶", - "sfr": "𝔰", - "sfrown": "⌢", - "sharp": "♯", - "shchcy": "щ", - "shcy": "ш", - "shortmid": "∣", - "shortparallel": "∥", - "sh": "­", - "shy": "­", - "sigma": "σ", - "sigmaf": "ς", - "sigmav": "ς", - "sim": "∼", - "simdot": "⩪", - "sime": "≃", - "simeq": "≃", - "simg": "⪞", - "simgE": "⪠", - "siml": "⪝", - "simlE": "⪟", - "simne": "≆", - "simplus": "⨤", - "simrarr": "⥲", - "slarr": "←", - "smallsetminus": "∖", - "smashp": "⨳", - "smeparsl": "⧤", - "smid": "∣", - "smile": "⌣", - "smt": "⪪", - "smte": "⪬", - "smtes": "⪬︀", - "softcy": "ь", - "sol": "/", - "solb": "⧄", - "solbar": "⌿", - "sopf": "𝕤", - "spades": "♠", - "spadesuit": "♠", - "spar": "∥", - "sqcap": "⊓", - "sqcaps": "⊓︀", - "sqcup": "⊔", - "sqcups": "⊔︀", - "sqsub": "⊏", - "sqsube": "⊑", - "sqsubset": "⊏", - "sqsubseteq": "⊑", - "sqsup": "⊐", - "sqsupe": "⊒", - "sqsupset": "⊐", - "sqsupseteq": "⊒", - "squ": "□", - "square": "□", - "squarf": "▪", - "squf": "▪", - "srarr": "→", - "sscr": "𝓈", - "ssetmn": "∖", - "ssmile": "⌣", - "sstarf": "⋆", - "star": "☆", - "starf": "★", - "straightepsilon": "ϵ", - "straightphi": "ϕ", - "strns": "¯", - "sub": "⊂", - "subE": "⫅", - "subdot": "⪽", - "sube": "⊆", - "subedot": "⫃", - "submult": "⫁", - "subnE": "⫋", - "subne": "⊊", - "subplus": "⪿", - "subrarr": "⥹", - "subset": "⊂", - "subseteq": "⊆", - "subseteqq": "⫅", - "subsetneq": "⊊", - "subsetneqq": "⫋", - "subsim": "⫇", - "subsub": "⫕", - "subsup": "⫓", - "succ": "≻", - "succapprox": "⪸", - "succcurlyeq": "≽", - "succeq": "⪰", - "succnapprox": "⪺", - "succneqq": "⪶", - "succnsim": "⋩", - "succsim": "≿", - "sum": "∑", - "sung": "♪", - "sup": "⊃", - "sup1": "¹", - "sup2": "²", - "sup3": "³", - "supE": "⫆", - "supdot": "⪾", - "supdsub": "⫘", - "supe": "⊇", - "supedot": "⫄", - "suphsol": "⟉", - "suphsub": "⫗", - "suplarr": "⥻", - "supmult": "⫂", - "supnE": "⫌", - "supne": "⊋", - "supplus": "⫀", - "supset": "⊃", - "supseteq": "⊇", - "supseteqq": "⫆", - "supsetneq": "⊋", - "supsetneqq": "⫌", - "supsim": "⫈", - "supsub": "⫔", - "supsup": "⫖", - "swArr": "⇙", - "swarhk": "⤦", - "swarr": "↙", - "swarrow": "↙", - "swnwar": "⤪", - "szli": "ß", - "szlig": "ß", - "target": "⌖", - "tau": "τ", - "tbrk": "⎴", - "tcaron": "ť", - "tcedil": "ţ", - "tcy": "т", - "tdot": "⃛", - "telrec": "⌕", - "tfr": "𝔱", - "there4": "∴", - "therefore": "∴", - "theta": "θ", - "thetasym": "ϑ", - "thetav": "ϑ", - "thickapprox": "≈", - "thicksim": "∼", - "thinsp": " ", - "thkap": "≈", - "thksim": "∼", - "thor": "þ", - "thorn": "þ", - "tilde": "˜", - "time": "×", - "times": "×", - "timesb": "⊠", - "timesbar": "⨱", - "timesd": "⨰", - "tint": "∭", - "toea": "⤨", - "top": "⊤", - "topbot": "⌶", - "topcir": "⫱", - "topf": "𝕥", - "topfork": "⫚", - "tosa": "⤩", - "tprime": "‴", - "trade": "™", - "triangle": "▵", - "triangledown": "▿", - "triangleleft": "◃", - "trianglelefteq": "⊴", - "triangleq": "≜", - "triangleright": "▹", - "trianglerighteq": "⊵", - "tridot": "◬", - "trie": "≜", - "triminus": "⨺", - "triplus": "⨹", - "trisb": "⧍", - "tritime": "⨻", - "trpezium": "⏢", - "tscr": "𝓉", - "tscy": "ц", - "tshcy": "ћ", - "tstrok": "ŧ", - "twixt": "≬", - "twoheadleftarrow": "↞", - "twoheadrightarrow": "↠", - "uArr": "⇑", - "uHar": "⥣", - "uacut": "ú", - "uacute": "ú", - "uarr": "↑", - "ubrcy": "ў", - "ubreve": "ŭ", - "ucir": "û", - "ucirc": "û", - "ucy": "у", - "udarr": "⇅", - "udblac": "ű", - "udhar": "⥮", - "ufisht": "⥾", - "ufr": "𝔲", - "ugrav": "ù", - "ugrave": "ù", - "uharl": "↿", - "uharr": "↾", - "uhblk": "▀", - "ulcorn": "⌜", - "ulcorner": "⌜", - "ulcrop": "⌏", - "ultri": "◸", - "umacr": "ū", - "um": "¨", - "uml": "¨", - "uogon": "ų", - "uopf": "𝕦", - "uparrow": "↑", - "updownarrow": "↕", - "upharpoonleft": "↿", - "upharpoonright": "↾", - "uplus": "⊎", - "upsi": "υ", - "upsih": "ϒ", - "upsilon": "υ", - "upuparrows": "⇈", - "urcorn": "⌝", - "urcorner": "⌝", - "urcrop": "⌎", - "uring": "ů", - "urtri": "◹", - "uscr": "𝓊", - "utdot": "⋰", - "utilde": "ũ", - "utri": "▵", - "utrif": "▴", - "uuarr": "⇈", - "uum": "ü", - "uuml": "ü", - "uwangle": "⦧", - "vArr": "⇕", - "vBar": "⫨", - "vBarv": "⫩", - "vDash": "⊨", - "vangrt": "⦜", - "varepsilon": "ϵ", - "varkappa": "ϰ", - "varnothing": "∅", - "varphi": "ϕ", - "varpi": "ϖ", - "varpropto": "∝", - "varr": "↕", - "varrho": "ϱ", - "varsigma": "ς", - "varsubsetneq": "⊊︀", - "varsubsetneqq": "⫋︀", - "varsupsetneq": "⊋︀", - "varsupsetneqq": "⫌︀", - "vartheta": "ϑ", - "vartriangleleft": "⊲", - "vartriangleright": "⊳", - "vcy": "в", - "vdash": "⊢", - "vee": "∨", - "veebar": "⊻", - "veeeq": "≚", - "vellip": "⋮", - "verbar": "|", - "vert": "|", - "vfr": "𝔳", - "vltri": "⊲", - "vnsub": "⊂⃒", - "vnsup": "⊃⃒", - "vopf": "𝕧", - "vprop": "∝", - "vrtri": "⊳", - "vscr": "𝓋", - "vsubnE": "⫋︀", - "vsubne": "⊊︀", - "vsupnE": "⫌︀", - "vsupne": "⊋︀", - "vzigzag": "⦚", - "wcirc": "ŵ", - "wedbar": "⩟", - "wedge": "∧", - "wedgeq": "≙", - "weierp": "℘", - "wfr": "𝔴", - "wopf": "𝕨", - "wp": "℘", - "wr": "≀", - "wreath": "≀", - "wscr": "𝓌", - "xcap": "⋂", - "xcirc": "◯", - "xcup": "⋃", - "xdtri": "▽", - "xfr": "𝔵", - "xhArr": "⟺", - "xharr": "⟷", - "xi": "ξ", - "xlArr": "⟸", - "xlarr": "⟵", - "xmap": "⟼", - "xnis": "⋻", - "xodot": "⨀", - "xopf": "𝕩", - "xoplus": "⨁", - "xotime": "⨂", - "xrArr": "⟹", - "xrarr": "⟶", - "xscr": "𝓍", - "xsqcup": "⨆", - "xuplus": "⨄", - "xutri": "△", - "xvee": "⋁", - "xwedge": "⋀", - "yacut": "ý", - "yacute": "ý", - "yacy": "я", - "ycirc": "ŷ", - "ycy": "ы", - "ye": "¥", - "yen": "¥", - "yfr": "𝔶", - "yicy": "ї", - "yopf": "𝕪", - "yscr": "𝓎", - "yucy": "ю", - "yum": "ÿ", - "yuml": "ÿ", - "zacute": "ź", - "zcaron": "ž", - "zcy": "з", - "zdot": "ż", - "zeetrf": "ℨ", - "zeta": "ζ", - "zfr": "𝔷", - "zhcy": "ж", - "zigrarr": "⇝", - "zopf": "𝕫", - "zscr": "𝓏", - "zwj": "‍", - "zwnj": "‌" -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities/license b/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities/license deleted file mode 100644 index 32e7a3d93ca5a2..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2015 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities/package.json deleted file mode 100644 index e1151d249e23dd..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities/package.json +++ /dev/null @@ -1,71 +0,0 @@ -{ - "name": "character-entities", - "version": "1.2.4", - "description": "HTML character entity information", - "license": "MIT", - "keywords": [ - "html", - "entity", - "entities", - "character", - "reference", - "name", - "replacement" - ], - "repository": "wooorm/character-entities", - "bugs": "https://github.com/wooorm/character-entities/issues", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - }, - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "main": "index.json", - "files": [ - "index.json" - ], - "dependencies": {}, - "devDependencies": { - "bail": "^1.0.0", - "browserify": "^16.0.0", - "concat-stream": "^2.0.0", - "prettier": "^1.0.0", - "remark-cli": "^7.0.0", - "remark-preset-wooorm": "^6.0.0", - "tape": "^4.0.0", - "tinyify": "^2.0.0", - "xo": "^0.25.0" - }, - "scripts": { - "generate": "node build", - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify index.json -s characterEntities -o character-entities.js", - "build-mangle": "browserify index.json -s characterEntities -p tinyify -o character-entities.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "lint": "xo", - "test-api": "node test", - "test": "npm run generate && npm run format && npm run build && npm run test-api" - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "ignores": [ - "character-entities.js" - ] - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities/readme.md deleted file mode 100644 index b890e2aec3c4c7..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/character-entities/readme.md +++ /dev/null @@ -1,72 +0,0 @@ -# character-entities - -[![Build][build-badge]][build] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] - -HTML character entity information. - -## Install - -[npm][]: - -```sh -npm install character-entities -``` - -## Use - -```js -var characterEntities = require('character-entities') - -console.log(characterEntities.AElig) // => 'Æ' -console.log(characterEntities.aelig) // => 'æ' -console.log(characterEntities.amp) // => '&' -``` - -## API - -### characterEntities - -Mapping between (case-sensitive) character entity names to replacements. - -## Support - -See [`html.spec.whatwg.org`][html]. - -## Related - -* [`character-entities-html4`](https://github.com/wooorm/character-entities-html4) - — HTML 4 character entity info -* [`character-entities-legacy`](https://github.com/wooorm/character-entities-legacy) - — Legacy character entity info -* [`parse-entities`](https://github.com/wooorm/parse-entities) - — Parse HTML character references -* [`stringify-entities`](https://github.com/wooorm/stringify-entities) - — Stringify HTML character references - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/wooorm/character-entities.svg - -[build]: https://travis-ci.org/wooorm/character-entities - -[downloads-badge]: https://img.shields.io/npm/dm/character-entities.svg - -[downloads]: https://www.npmjs.com/package/character-entities - -[size-badge]: https://img.shields.io/bundlephobia/minzip/character-entities.svg - -[size]: https://bundlephobia.com/result?p=character-entities - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com - -[html]: https://html.spec.whatwg.org/multipage/syntax.html#named-character-references diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/character-reference-invalid/index.json b/tools/node_modules/eslint-plugin-markdown/node_modules/character-reference-invalid/index.json deleted file mode 100644 index 9337a854e40194..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/character-reference-invalid/index.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "0": "�", - "128": "€", - "130": "‚", - "131": "ƒ", - "132": "„", - "133": "…", - "134": "†", - "135": "‡", - "136": "ˆ", - "137": "‰", - "138": "Š", - "139": "‹", - "140": "Œ", - "142": "Ž", - "145": "‘", - "146": "’", - "147": "“", - "148": "”", - "149": "•", - "150": "–", - "151": "—", - "152": "˜", - "153": "™", - "154": "š", - "155": "›", - "156": "œ", - "158": "ž", - "159": "Ÿ" -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/character-reference-invalid/license b/tools/node_modules/eslint-plugin-markdown/node_modules/character-reference-invalid/license deleted file mode 100644 index 32e7a3d93ca5a2..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/character-reference-invalid/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2015 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/character-reference-invalid/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/character-reference-invalid/package.json deleted file mode 100644 index 069dc4b2b53901..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/character-reference-invalid/package.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "name": "character-reference-invalid", - "version": "1.1.4", - "description": "HTML invalid numeric character reference information", - "license": "MIT", - "keywords": [ - "html", - "entity", - "numeric", - "character", - "reference", - "replacement", - "invalid", - "name" - ], - "repository": "wooorm/character-reference-invalid", - "bugs": "https://github.com/wooorm/character-reference-invalid/issues", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - }, - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "main": "index.json", - "files": [ - "index.json" - ], - "dependencies": {}, - "devDependencies": { - "bail": "^1.0.0", - "browserify": "^16.0.0", - "concat-stream": "^2.0.0", - "hast-util-select": "^3.0.0", - "hast-util-to-string": "^1.0.0", - "rehype-parse": "^6.0.0", - "remark-cli": "^7.0.0", - "remark-preset-wooorm": "^6.0.0", - "tape": "^4.0.0", - "tinyify": "^2.0.0", - "unified": "^8.0.0", - "xo": "^0.25.0" - }, - "scripts": { - "generate": "node build", - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify index.json -s characterReferenceInvalid -o character-reference-invalid.js", - "build-mangle": "browserify index.json -s characterReferenceInvalid -p tinyify -o character-reference-invalid.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test": "npm run generate && npm run format && npm run build && npm run test-api" - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "ignores": [ - "character-reference-invalid.js" - ] - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/character-reference-invalid/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/character-reference-invalid/readme.md deleted file mode 100644 index e2e8f7a5177708..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/character-reference-invalid/readme.md +++ /dev/null @@ -1,74 +0,0 @@ -# character-reference-invalid - -[![Build][build-badge]][build] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] - -HTML invalid numeric character reference information. - -## Install - -[npm][]: - -```sh -npm install character-reference-invalid -``` - -## Use - -```js -var characterReferenceInvalid = require('character-reference-invalid') - -console.log(characterReferenceInvalid[0x80]) // => '€' -console.log(characterReferenceInvalid[0x89]) // => '‰' -console.log(characterReferenceInvalid[0x99]) // => '™' -``` - -## API - -### `characterReferenceInvalid` - -Mapping between invalid numeric character reference to replacements. - -## Support - -See [`html.spec.whatwg.org`][html]. - -## Related - -* [`character-entities`](https://github.com/wooorm/character-entities) - — HTML character entity info -* [`character-entities-html4`](https://github.com/wooorm/character-entities-html4) - — HTML 4 character entity info -* [`character-entities-legacy`](https://github.com/wooorm/character-entities-legacy) - — Legacy character entity info -* [`parse-entities`](https://github.com/wooorm/parse-entities) - — Parse HTML character references -* [`stringify-entities`](https://github.com/wooorm/stringify-entities) - — Serialize HTML character references - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/wooorm/character-reference-invalid.svg - -[build]: https://travis-ci.org/wooorm/character-reference-invalid - -[downloads-badge]: https://img.shields.io/npm/dm/character-reference-invalid.svg - -[downloads]: https://www.npmjs.com/package/character-reference-invalid - -[size-badge]: https://img.shields.io/bundlephobia/minzip/character-reference-invalid.svg - -[size]: https://bundlephobia.com/result?p=character-reference-invalid - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com - -[html]: https://html.spec.whatwg.org/multipage/syntax.html#table-charref-overrides diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/collapse-white-space/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/collapse-white-space/index.js deleted file mode 100644 index 93d546695c7ae7..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/collapse-white-space/index.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict' - -module.exports = collapse - -// `collapse(' \t\nbar \nbaz\t') // ' bar baz '` -function collapse(value) { - return String(value).replace(/\s+/g, ' ') -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/collapse-white-space/license b/tools/node_modules/eslint-plugin-markdown/node_modules/collapse-white-space/license deleted file mode 100644 index 32e7a3d93ca5a2..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/collapse-white-space/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2015 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/collapse-white-space/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/collapse-white-space/package.json deleted file mode 100644 index 6c9e8f348f4bc1..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/collapse-white-space/package.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "name": "collapse-white-space", - "version": "1.0.6", - "description": "Replace multiple white-space characters with a single space", - "license": "MIT", - "keywords": [ - "collapse", - "white", - "space" - ], - "repository": "wooorm/collapse-white-space", - "bugs": "https://github.com/wooorm/collapse-white-space/issues", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - }, - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "files": [ - "index.js" - ], - "dependencies": {}, - "devDependencies": { - "browserify": "^16.0.0", - "nyc": "^15.0.0", - "prettier": "^1.0.0", - "remark-cli": "^7.0.0", - "remark-preset-wooorm": "^6.0.0", - "tape": "^4.0.0", - "tinyify": "^2.0.0", - "xo": "^0.25.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify . -s collapseWhiteSpace -o collapse-white-space.js", - "build-mangle": "browserify . -s collapseWhiteSpace -p tinyify -o collapse-white-space.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "ignores": [ - "collapse-white-space.js" - ] - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/collapse-white-space/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/collapse-white-space/readme.md deleted file mode 100644 index 5154c9fedc3024..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/collapse-white-space/readme.md +++ /dev/null @@ -1,58 +0,0 @@ -# collapse-white-space - -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] - -Replace multiple whitespace characters with a single space. - -## Install - -[npm][]: - -```sh -npm install collapse-white-space -``` - -## Use - -```js -var collapse = require('collapse-white-space') - -collapse('\tfoo \n\tbar \t\r\nbaz') //=> ' foo bar baz' -``` - -## API - -### `collapse(value)` - -Replace multiple whitespace characters in value with a single space. - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/wooorm/collapse-white-space.svg - -[build]: https://travis-ci.org/wooorm/collapse-white-space - -[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/collapse-white-space.svg - -[coverage]: https://codecov.io/github/wooorm/collapse-white-space - -[downloads-badge]: https://img.shields.io/npm/dm/collapse-white-space.svg - -[downloads]: https://www.npmjs.com/package/collapse-white-space - -[size-badge]: https://img.shields.io/bundlephobia/minzip/collapse-white-space.svg - -[size]: https://bundlephobia.com/result?p=collapse-white-space - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/extend/.jscs.json b/tools/node_modules/eslint-plugin-markdown/node_modules/extend/.jscs.json deleted file mode 100644 index 3cce01d7832943..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/extend/.jscs.json +++ /dev/null @@ -1,175 +0,0 @@ -{ - "es3": true, - - "additionalRules": [], - - "requireSemicolons": true, - - "disallowMultipleSpaces": true, - - "disallowIdentifierNames": [], - - "requireCurlyBraces": { - "allExcept": [], - "keywords": ["if", "else", "for", "while", "do", "try", "catch"] - }, - - "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch", "function"], - - "disallowSpaceAfterKeywords": [], - - "disallowSpaceBeforeComma": true, - "disallowSpaceAfterComma": false, - "disallowSpaceBeforeSemicolon": true, - - "disallowNodeTypes": [ - "DebuggerStatement", - "LabeledStatement", - "SwitchCase", - "SwitchStatement", - "WithStatement" - ], - - "requireObjectKeysOnNewLine": { "allExcept": ["sameLine"] }, - - "requireSpacesInAnonymousFunctionExpression": { "beforeOpeningRoundBrace": true, "beforeOpeningCurlyBrace": true }, - "requireSpacesInNamedFunctionExpression": { "beforeOpeningCurlyBrace": true }, - "disallowSpacesInNamedFunctionExpression": { "beforeOpeningRoundBrace": true }, - "requireSpacesInFunctionDeclaration": { "beforeOpeningCurlyBrace": true }, - "disallowSpacesInFunctionDeclaration": { "beforeOpeningRoundBrace": true }, - - "requireSpaceBetweenArguments": true, - - "disallowSpacesInsideParentheses": true, - - "disallowSpacesInsideArrayBrackets": true, - - "disallowQuotedKeysInObjects": { "allExcept": ["reserved"] }, - - "disallowSpaceAfterObjectKeys": true, - - "requireCommaBeforeLineBreak": true, - - "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"], - "requireSpaceAfterPrefixUnaryOperators": [], - - "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"], - "requireSpaceBeforePostfixUnaryOperators": [], - - "disallowSpaceBeforeBinaryOperators": [], - "requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="], - - "requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="], - "disallowSpaceAfterBinaryOperators": [], - - "disallowImplicitTypeConversion": ["binary", "string"], - - "disallowKeywords": ["with", "eval"], - - "requireKeywordsOnNewLine": [], - "disallowKeywordsOnNewLine": ["else"], - - "requireLineFeedAtFileEnd": true, - - "disallowTrailingWhitespace": true, - - "disallowTrailingComma": true, - - "excludeFiles": ["node_modules/**", "vendor/**"], - - "disallowMultipleLineStrings": true, - - "requireDotNotation": { "allExcept": ["keywords"] }, - - "requireParenthesesAroundIIFE": true, - - "validateLineBreaks": "LF", - - "validateQuoteMarks": { - "escape": true, - "mark": "'" - }, - - "disallowOperatorBeforeLineBreak": [], - - "requireSpaceBeforeKeywords": [ - "do", - "for", - "if", - "else", - "switch", - "case", - "try", - "catch", - "finally", - "while", - "with", - "return" - ], - - "validateAlignedFunctionParameters": { - "lineBreakAfterOpeningBraces": true, - "lineBreakBeforeClosingBraces": true - }, - - "requirePaddingNewLinesBeforeExport": true, - - "validateNewlineAfterArrayElements": { - "maximum": 6 - }, - - "requirePaddingNewLinesAfterUseStrict": true, - - "disallowArrowFunctions": true, - - "disallowMultiLineTernary": true, - - "validateOrderInObjectKeys": false, - - "disallowIdenticalDestructuringNames": true, - - "disallowNestedTernaries": { "maxLevel": 1 }, - - "requireSpaceAfterComma": { "allExcept": ["trailing"] }, - "requireAlignedMultilineParams": false, - - "requireSpacesInGenerator": { - "afterStar": true - }, - - "disallowSpacesInGenerator": { - "beforeStar": true - }, - - "disallowVar": false, - - "requireArrayDestructuring": false, - - "requireEnhancedObjectLiterals": false, - - "requireObjectDestructuring": false, - - "requireEarlyReturn": false, - - "requireCapitalizedConstructorsNew": { - "allExcept": ["Function", "String", "Object", "Symbol", "Number", "Date", "RegExp", "Error", "Boolean", "Array"] - }, - - "requireImportAlphabetized": false, - - "requireSpaceBeforeObjectValues": true, - "requireSpaceBeforeDestructuredValues": true, - - "disallowSpacesInsideTemplateStringPlaceholders": true, - - "disallowArrayDestructuringReturn": false, - - "requireNewlineBeforeSingleStatementsInIf": false, - - "disallowUnusedVariables": true, - - "requireSpacesInsideImportedObjectBraces": true, - - "requireUseStrict": true -} - diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/extend/LICENSE b/tools/node_modules/eslint-plugin-markdown/node_modules/extend/LICENSE deleted file mode 100644 index e16d6a56ca64e2..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/extend/LICENSE +++ /dev/null @@ -1,23 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Stefan Thomas - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/extend/README.md b/tools/node_modules/eslint-plugin-markdown/node_modules/extend/README.md deleted file mode 100644 index 5b8249aa95e5d3..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/extend/README.md +++ /dev/null @@ -1,81 +0,0 @@ -[![Build Status][travis-svg]][travis-url] -[![dependency status][deps-svg]][deps-url] -[![dev dependency status][dev-deps-svg]][dev-deps-url] - -# extend() for Node.js [![Version Badge][npm-version-png]][npm-url] - -`node-extend` is a port of the classic extend() method from jQuery. It behaves as you expect. It is simple, tried and true. - -Notes: - -* Since Node.js >= 4, - [`Object.assign`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) - now offers the same functionality natively (but without the "deep copy" option). - See [ECMAScript 2015 (ES6) in Node.js](https://nodejs.org/en/docs/es6). -* Some native implementations of `Object.assign` in both Node.js and many - browsers (since NPM modules are for the browser too) may not be fully - spec-compliant. - Check [`object.assign`](https://www.npmjs.com/package/object.assign) module for - a compliant candidate. - -## Installation - -This package is available on [npm][npm-url] as: `extend` - -``` sh -npm install extend -``` - -## Usage - -**Syntax:** extend **(** [`deep`], `target`, `object1`, [`objectN`] **)** - -*Extend one object with one or more others, returning the modified object.* - -**Example:** - -``` js -var extend = require('extend'); -extend(targetObject, object1, object2); -``` - -Keep in mind that the target object will be modified, and will be returned from extend(). - -If a boolean true is specified as the first argument, extend performs a deep copy, recursively copying any objects it finds. Otherwise, the copy will share structure with the original object(s). -Undefined properties are not copied. However, properties inherited from the object's prototype will be copied over. -Warning: passing `false` as the first argument is not supported. - -### Arguments - -* `deep` *Boolean* (optional) -If set, the merge becomes recursive (i.e. deep copy). -* `target` *Object* -The object to extend. -* `object1` *Object* -The object that will be merged into the first. -* `objectN` *Object* (Optional) -More objects to merge into the first. - -## License - -`node-extend` is licensed under the [MIT License][mit-license-url]. - -## Acknowledgements - -All credit to the jQuery authors for perfecting this amazing utility. - -Ported to Node.js by [Stefan Thomas][github-justmoon] with contributions by [Jonathan Buchanan][github-insin] and [Jordan Harband][github-ljharb]. - -[travis-svg]: https://travis-ci.org/justmoon/node-extend.svg -[travis-url]: https://travis-ci.org/justmoon/node-extend -[npm-url]: https://npmjs.org/package/extend -[mit-license-url]: http://opensource.org/licenses/MIT -[github-justmoon]: https://github.com/justmoon -[github-insin]: https://github.com/insin -[github-ljharb]: https://github.com/ljharb -[npm-version-png]: http://versionbadg.es/justmoon/node-extend.svg -[deps-svg]: https://david-dm.org/justmoon/node-extend.svg -[deps-url]: https://david-dm.org/justmoon/node-extend -[dev-deps-svg]: https://david-dm.org/justmoon/node-extend/dev-status.svg -[dev-deps-url]: https://david-dm.org/justmoon/node-extend#info=devDependencies - diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/extend/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/extend/index.js deleted file mode 100644 index 2aa3faae68c43e..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/extend/index.js +++ /dev/null @@ -1,117 +0,0 @@ -'use strict'; - -var hasOwn = Object.prototype.hasOwnProperty; -var toStr = Object.prototype.toString; -var defineProperty = Object.defineProperty; -var gOPD = Object.getOwnPropertyDescriptor; - -var isArray = function isArray(arr) { - if (typeof Array.isArray === 'function') { - return Array.isArray(arr); - } - - return toStr.call(arr) === '[object Array]'; -}; - -var isPlainObject = function isPlainObject(obj) { - if (!obj || toStr.call(obj) !== '[object Object]') { - return false; - } - - var hasOwnConstructor = hasOwn.call(obj, 'constructor'); - var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); - // Not own constructor property must be Object - if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { - return false; - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - var key; - for (key in obj) { /**/ } - - return typeof key === 'undefined' || hasOwn.call(obj, key); -}; - -// If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target -var setProperty = function setProperty(target, options) { - if (defineProperty && options.name === '__proto__') { - defineProperty(target, options.name, { - enumerable: true, - configurable: true, - value: options.newValue, - writable: true - }); - } else { - target[options.name] = options.newValue; - } -}; - -// Return undefined instead of __proto__ if '__proto__' is not an own property -var getProperty = function getProperty(obj, name) { - if (name === '__proto__') { - if (!hasOwn.call(obj, name)) { - return void 0; - } else if (gOPD) { - // In early versions of node, obj['__proto__'] is buggy when obj has - // __proto__ as an own property. Object.getOwnPropertyDescriptor() works. - return gOPD(obj, name).value; - } - } - - return obj[name]; -}; - -module.exports = function extend() { - var options, name, src, copy, copyIsArray, clone; - var target = arguments[0]; - var i = 1; - var length = arguments.length; - var deep = false; - - // Handle a deep copy situation - if (typeof target === 'boolean') { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - if (target == null || (typeof target !== 'object' && typeof target !== 'function')) { - target = {}; - } - - for (; i < length; ++i) { - options = arguments[i]; - // Only deal with non-null/undefined values - if (options != null) { - // Extend the base object - for (name in options) { - src = getProperty(target, name); - copy = getProperty(options, name); - - // Prevent never-ending loop - if (target !== copy) { - // Recurse if we're merging plain objects or arrays - if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) { - if (copyIsArray) { - copyIsArray = false; - clone = src && isArray(src) ? src : []; - } else { - clone = src && isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - setProperty(target, { name: name, newValue: extend(deep, clone, copy) }); - - // Don't bring in undefined values - } else if (typeof copy !== 'undefined') { - setProperty(target, { name: name, newValue: copy }); - } - } - } - } - } - - // Return the modified object - return target; -}; diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/extend/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/extend/package.json deleted file mode 100644 index 85279f78054e5c..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/extend/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "extend", - "author": "Stefan Thomas (http://www.justmoon.net)", - "version": "3.0.2", - "description": "Port of jQuery.extend for node.js and the browser", - "main": "index", - "scripts": { - "pretest": "npm run lint", - "test": "npm run tests-only", - "posttest": "npm run coverage-quiet", - "tests-only": "node test", - "coverage": "covert test/index.js", - "coverage-quiet": "covert test/index.js --quiet", - "lint": "npm run jscs && npm run eslint", - "jscs": "jscs *.js */*.js", - "eslint": "eslint *.js */*.js" - }, - "contributors": [ - { - "name": "Jordan Harband", - "url": "https://github.com/ljharb" - } - ], - "keywords": [ - "extend", - "clone", - "merge" - ], - "repository": { - "type": "git", - "url": "https://github.com/justmoon/node-extend.git" - }, - "dependencies": {}, - "devDependencies": { - "@ljharb/eslint-config": "^12.2.1", - "covert": "^1.1.0", - "eslint": "^4.19.1", - "jscs": "^3.0.7", - "tape": "^4.9.1" - }, - "license": "MIT" -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/inherits/LICENSE b/tools/node_modules/eslint-plugin-markdown/node_modules/inherits/LICENSE deleted file mode 100644 index dea3013d6710ee..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/inherits/LICENSE +++ /dev/null @@ -1,16 +0,0 @@ -The ISC License - -Copyright (c) Isaac Z. Schlueter - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted, provided that the above -copyright notice and this permission notice appear in all copies. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND -FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. - diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/inherits/README.md b/tools/node_modules/eslint-plugin-markdown/node_modules/inherits/README.md deleted file mode 100644 index b1c56658557b81..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/inherits/README.md +++ /dev/null @@ -1,42 +0,0 @@ -Browser-friendly inheritance fully compatible with standard node.js -[inherits](http://nodejs.org/api/util.html#util_util_inherits_constructor_superconstructor). - -This package exports standard `inherits` from node.js `util` module in -node environment, but also provides alternative browser-friendly -implementation through [browser -field](https://gist.github.com/shtylman/4339901). Alternative -implementation is a literal copy of standard one located in standalone -module to avoid requiring of `util`. It also has a shim for old -browsers with no `Object.create` support. - -While keeping you sure you are using standard `inherits` -implementation in node.js environment, it allows bundlers such as -[browserify](https://github.com/substack/node-browserify) to not -include full `util` package to your client code if all you need is -just `inherits` function. It worth, because browser shim for `util` -package is large and `inherits` is often the single function you need -from it. - -It's recommended to use this package instead of -`require('util').inherits` for any code that has chances to be used -not only in node.js but in browser too. - -## usage - -```js -var inherits = require('inherits'); -// then use exactly as the standard one -``` - -## note on version ~1.0 - -Version ~1.0 had completely different motivation and is not compatible -neither with 2.0 nor with standard node.js `inherits`. - -If you are using version ~1.0 and planning to switch to ~2.0, be -careful: - -* new version uses `super_` instead of `super` for referencing - superclass -* new version overwrites current prototype while old one preserves any - existing fields on it diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/inherits/inherits.js b/tools/node_modules/eslint-plugin-markdown/node_modules/inherits/inherits.js deleted file mode 100644 index f71f2d93294a67..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/inherits/inherits.js +++ /dev/null @@ -1,9 +0,0 @@ -try { - var util = require('util'); - /* istanbul ignore next */ - if (typeof util.inherits !== 'function') throw ''; - module.exports = util.inherits; -} catch (e) { - /* istanbul ignore next */ - module.exports = require('./inherits_browser.js'); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/inherits/inherits_browser.js b/tools/node_modules/eslint-plugin-markdown/node_modules/inherits/inherits_browser.js deleted file mode 100644 index 86bbb3dc29e484..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/inherits/inherits_browser.js +++ /dev/null @@ -1,27 +0,0 @@ -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - if (superCtor) { - ctor.super_ = superCtor - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }) - } - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - if (superCtor) { - ctor.super_ = superCtor - var TempCtor = function () {} - TempCtor.prototype = superCtor.prototype - ctor.prototype = new TempCtor() - ctor.prototype.constructor = ctor - } - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/inherits/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/inherits/package.json deleted file mode 100644 index 37b4366b83e63e..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/inherits/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "inherits", - "description": "Browser-friendly inheritance fully compatible with standard node.js inherits()", - "version": "2.0.4", - "keywords": [ - "inheritance", - "class", - "klass", - "oop", - "object-oriented", - "inherits", - "browser", - "browserify" - ], - "main": "./inherits.js", - "browser": "./inherits_browser.js", - "repository": "git://github.com/isaacs/inherits", - "license": "ISC", - "scripts": { - "test": "tap" - }, - "devDependencies": { - "tap": "^14.2.4" - }, - "files": [ - "inherits.js", - "inherits_browser.js" - ] -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphabetical/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphabetical/index.js deleted file mode 100644 index 26d3650ef060cd..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphabetical/index.js +++ /dev/null @@ -1,14 +0,0 @@ -'use strict' - -module.exports = alphabetical - -// Check if the given character code, or the character code at the first -// character, is alphabetical. -function alphabetical(character) { - var code = typeof character === 'string' ? character.charCodeAt(0) : character - - return ( - (code >= 97 && code <= 122) /* a-z */ || - (code >= 65 && code <= 90) /* A-Z */ - ) -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphabetical/license b/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphabetical/license deleted file mode 100644 index 8d8660d36ef2ec..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphabetical/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2016 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphabetical/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphabetical/package.json deleted file mode 100644 index c7764f2a09e8c8..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphabetical/package.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "name": "is-alphabetical", - "version": "1.0.4", - "description": "Check if a character is alphabetical", - "license": "MIT", - "keywords": [ - "string", - "character", - "char", - "code", - "alphabetical" - ], - "repository": "wooorm/is-alphabetical", - "bugs": "https://github.com/wooorm/is-alphabetical/issues", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - }, - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "files": [ - "index.js" - ], - "dependencies": {}, - "devDependencies": { - "browserify": "^16.0.0", - "nyc": "^15.0.0", - "prettier": "^1.0.0", - "remark-cli": "^7.0.0", - "remark-preset-wooorm": "^6.0.0", - "tape": "^4.0.0", - "tinyify": "^2.0.0", - "xo": "^0.25.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify -s isAlphabetical -o is-alphabetical.js", - "build-mangle": "browserify -s isAlphabetical -p tinyify -o is-alphabetical.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "rules": { - "capitalized-comments": "off" - }, - "ignores": [ - "is-alphabetical.js" - ] - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphabetical/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphabetical/readme.md deleted file mode 100644 index 2a6064b6865ffb..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphabetical/readme.md +++ /dev/null @@ -1,70 +0,0 @@ -# is-alphabetical - -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] - -Check if a character is alphabetical. - -## Install - -[npm][]: - -```sh -npm install is-alphabetical -``` - -## Use - -```js -var alphabetical = require('is-alphabetical') - -alphabetical('a') // => true -alphabetical('B') // => true -alphabetical('0') // => false -alphabetical('💩') // => false -``` - -## API - -### `alphabetical(character|code)` - -Check whether the given character code (`number`), or the character code at the -first position (`string`), is alphabetical. - -## Related - -* [`is-decimal`](https://github.com/wooorm/is-decimal) -* [`is-hexadecimal`](https://github.com/wooorm/is-hexadecimal) -* [`is-alphanumerical`](https://github.com/wooorm/is-alphanumerical) -* [`is-whitespace-character`](https://github.com/wooorm/is-whitespace-character) -* [`is-word-character`](https://github.com/wooorm/is-word-character) - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/wooorm/is-alphabetical.svg - -[build]: https://travis-ci.org/wooorm/is-alphabetical - -[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/is-alphabetical.svg - -[coverage]: https://codecov.io/github/wooorm/is-alphabetical - -[downloads-badge]: https://img.shields.io/npm/dm/is-alphabetical.svg - -[downloads]: https://www.npmjs.com/package/is-alphabetical - -[size-badge]: https://img.shields.io/bundlephobia/minzip/is-alphabetical.svg - -[size]: https://bundlephobia.com/result?p=is-alphabetical - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphanumerical/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphanumerical/index.js deleted file mode 100644 index cd5edef3dbf03c..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphanumerical/index.js +++ /dev/null @@ -1,12 +0,0 @@ -'use strict' - -var alphabetical = require('is-alphabetical') -var decimal = require('is-decimal') - -module.exports = alphanumerical - -// Check if the given character code, or the character code at the first -// character, is alphanumerical. -function alphanumerical(character) { - return alphabetical(character) || decimal(character) -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphanumerical/license b/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphanumerical/license deleted file mode 100644 index 8d8660d36ef2ec..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphanumerical/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2016 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphanumerical/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphanumerical/package.json deleted file mode 100644 index edaa31e66f0ea1..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphanumerical/package.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "name": "is-alphanumerical", - "version": "1.0.4", - "description": "Check if a character is alphanumerical", - "license": "MIT", - "keywords": [ - "string", - "character", - "char", - "code", - "alphabetical", - "numerical", - "alphanumerical" - ], - "repository": "wooorm/is-alphanumerical", - "bugs": "https://github.com/wooorm/is-alphanumerical/issues", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - }, - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "files": [ - "index.js" - ], - "dependencies": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" - }, - "devDependencies": { - "browserify": "^16.0.0", - "nyc": "^15.0.0", - "prettier": "^1.0.0", - "remark-cli": "^7.0.0", - "remark-preset-wooorm": "^6.0.0", - "tape": "^4.0.0", - "tinyify": "^2.0.0", - "xo": "^0.25.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify . -s isAlphanumerical -o is-alphanumerical.js", - "build-mangle": "browserify . -s isAlphanumerical -p tinyify -o is-alphanumerical.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "ignores": [ - "is-alphanumerical.js" - ] - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphanumerical/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphanumerical/readme.md deleted file mode 100644 index 8496cad64e66ba..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-alphanumerical/readme.md +++ /dev/null @@ -1,71 +0,0 @@ -# is-alphanumerical - -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] - -Check if a character is alphanumerical (`[a-zA-Z0-9]`). - -## Install - -[npm][]: - -```sh -npm install is-alphanumerical -``` - -## Use - -```js -var alphanumerical = require('is-alphanumerical') - -alphanumerical('a') // => true -alphanumerical('Z') // => true -alphanumerical('0') // => true -alphanumerical(' ') // => false -alphanumerical('💩') // => false -``` - -## API - -### `alphanumerical(character)` - -Check whether the given character code (`number`), or the character code at the -first position (`string`), is alphanumerical. - -## Related - -* [`is-alphabetical`](https://github.com/wooorm/is-alphabetical) -* [`is-decimal`](https://github.com/wooorm/is-decimal) -* [`is-hexadecimal`](https://github.com/wooorm/is-hexadecimal) -* [`is-whitespace-character`](https://github.com/wooorm/is-whitespace-character) -* [`is-word-character`](https://github.com/wooorm/is-word-character) - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/wooorm/is-alphanumerical.svg - -[build]: https://travis-ci.org/wooorm/is-alphanumerical - -[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/is-alphanumerical.svg - -[coverage]: https://codecov.io/github/wooorm/is-alphanumerical - -[downloads-badge]: https://img.shields.io/npm/dm/is-alphanumerical.svg - -[downloads]: https://www.npmjs.com/package/is-alphanumerical - -[size-badge]: https://img.shields.io/bundlephobia/minzip/is-alphanumerical.svg - -[size]: https://bundlephobia.com/result?p=is-alphanumerical - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-buffer/LICENSE b/tools/node_modules/eslint-plugin-markdown/node_modules/is-buffer/LICENSE deleted file mode 100644 index 0c068ceecbd48f..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-buffer/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) Feross Aboukhadijeh - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-buffer/README.md b/tools/node_modules/eslint-plugin-markdown/node_modules/is-buffer/README.md deleted file mode 100644 index cce0a8cf924d8c..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-buffer/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# is-buffer [![travis][travis-image]][travis-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url] - -[travis-image]: https://img.shields.io/travis/feross/is-buffer/master.svg -[travis-url]: https://travis-ci.org/feross/is-buffer -[npm-image]: https://img.shields.io/npm/v/is-buffer.svg -[npm-url]: https://npmjs.org/package/is-buffer -[downloads-image]: https://img.shields.io/npm/dm/is-buffer.svg -[downloads-url]: https://npmjs.org/package/is-buffer -[standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg -[standard-url]: https://standardjs.com - -#### Determine if an object is a [`Buffer`](http://nodejs.org/api/buffer.html) (including the [browserify Buffer](https://github.com/feross/buffer)) - -[![saucelabs][saucelabs-image]][saucelabs-url] - -[saucelabs-image]: https://saucelabs.com/browser-matrix/is-buffer.svg -[saucelabs-url]: https://saucelabs.com/u/is-buffer - -## Why not use `Buffer.isBuffer`? - -This module lets you check if an object is a `Buffer` without using `Buffer.isBuffer` (which includes the whole [buffer](https://github.com/feross/buffer) module in [browserify](http://browserify.org/)). - -It's future-proof and works in node too! - -## install - -```bash -npm install is-buffer -``` - -## usage - -```js -var isBuffer = require('is-buffer') - -isBuffer(new Buffer(4)) // true - -isBuffer(undefined) // false -isBuffer(null) // false -isBuffer('') // false -isBuffer(true) // false -isBuffer(false) // false -isBuffer(0) // false -isBuffer(1) // false -isBuffer(1.0) // false -isBuffer('string') // false -isBuffer({}) // false -isBuffer(function foo () {}) // false -``` - -## license - -MIT. Copyright (C) [Feross Aboukhadijeh](http://feross.org). diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-buffer/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/is-buffer/index.js deleted file mode 100644 index 9cce396594f605..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-buffer/index.js +++ /dev/null @@ -1,21 +0,0 @@ -/*! - * Determine if an object is a Buffer - * - * @author Feross Aboukhadijeh - * @license MIT - */ - -// The _isBuffer check is for Safari 5-7 support, because it's missing -// Object.prototype.constructor. Remove this eventually -module.exports = function (obj) { - return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer) -} - -function isBuffer (obj) { - return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) -} - -// For Node v0.10 support. Remove this eventually. -function isSlowBuffer (obj) { - return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0)) -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-buffer/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/is-buffer/package.json deleted file mode 100644 index ea12137a63cf0f..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-buffer/package.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "name": "is-buffer", - "description": "Determine if an object is a Buffer", - "version": "1.1.6", - "author": { - "name": "Feross Aboukhadijeh", - "email": "feross@feross.org", - "url": "http://feross.org/" - }, - "bugs": { - "url": "https://github.com/feross/is-buffer/issues" - }, - "dependencies": {}, - "devDependencies": { - "standard": "*", - "tape": "^4.0.0", - "zuul": "^3.0.0" - }, - "keywords": [ - "buffer", - "buffers", - "type", - "core buffer", - "browser buffer", - "browserify", - "typed array", - "uint32array", - "int16array", - "int32array", - "float32array", - "float64array", - "browser", - "arraybuffer", - "dataview" - ], - "license": "MIT", - "main": "index.js", - "repository": { - "type": "git", - "url": "git://github.com/feross/is-buffer.git" - }, - "scripts": { - "test": "standard && npm run test-node && npm run test-browser", - "test-browser": "zuul -- test/*.js", - "test-browser-local": "zuul --local -- test/*.js", - "test-node": "tape test/*.js" - }, - "testling": { - "files": "test/*.js" - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-decimal/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/is-decimal/index.js deleted file mode 100644 index a522104e5cf970..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-decimal/index.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict' - -module.exports = decimal - -// Check if the given character code, or the character code at the first -// character, is decimal. -function decimal(character) { - var code = typeof character === 'string' ? character.charCodeAt(0) : character - - return code >= 48 && code <= 57 /* 0-9 */ -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-decimal/license b/tools/node_modules/eslint-plugin-markdown/node_modules/is-decimal/license deleted file mode 100644 index 8d8660d36ef2ec..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-decimal/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2016 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-decimal/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/is-decimal/package.json deleted file mode 100644 index 5589c2a4f1f1b7..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-decimal/package.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "name": "is-decimal", - "version": "1.0.4", - "description": "Check if a character is decimal", - "license": "MIT", - "keywords": [ - "string", - "character", - "char", - "code", - "decimal" - ], - "repository": "wooorm/is-decimal", - "bugs": "https://github.com/wooorm/is-decimal/issues", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - }, - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "files": [ - "index.js" - ], - "dependencies": {}, - "devDependencies": { - "browserify": "^16.0.0", - "nyc": "^15.0.0", - "prettier": "^1.0.0", - "remark-cli": "^7.0.0", - "remark-preset-wooorm": "^6.0.0", - "tape": "^4.0.0", - "tinyify": "^2.0.0", - "xo": "^0.25.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify . -s isDecimal -o is-decimal.js", - "build-mangle": "browserify . -s isDecimal -p tinyify -o is-decimal.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "ignores": [ - "is-decimal.js" - ] - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-decimal/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/is-decimal/readme.md deleted file mode 100644 index d24a3d28c0a32d..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-decimal/readme.md +++ /dev/null @@ -1,69 +0,0 @@ -# is-decimal - -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] - -Check if a character is decimal. - -## Install - -[npm][]: - -```sh -npm install is-decimal -``` - -## Use - -```js -var decimal = require('is-decimal') - -decimal('0') // => true -decimal('9') // => true -decimal('a') // => false -decimal('💩') // => false -``` - -## API - -### `decimal(character|code)` - -Check whether the given character code (`number`), or the character code at the -first position (`string`), is decimal. - -## Related - -* [`is-alphabetical`](https://github.com/wooorm/is-alphabetical) -* [`is-hexadecimal`](https://github.com/wooorm/is-hexadecimal) -* [`is-whitespace-character`](https://github.com/wooorm/is-whitespace-character) -* [`is-word-character`](https://github.com/wooorm/is-word-character) - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/wooorm/is-decimal.svg - -[build]: https://travis-ci.org/wooorm/is-decimal - -[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/is-decimal.svg - -[coverage]: https://codecov.io/github/wooorm/is-decimal - -[downloads-badge]: https://img.shields.io/npm/dm/is-decimal.svg - -[downloads]: https://www.npmjs.com/package/is-decimal - -[size-badge]: https://img.shields.io/bundlephobia/minzip/is-decimal.svg - -[size]: https://bundlephobia.com/result?p=is-decimal - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-hexadecimal/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/is-hexadecimal/index.js deleted file mode 100644 index 567c9d1c077737..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-hexadecimal/index.js +++ /dev/null @@ -1,15 +0,0 @@ -'use strict' - -module.exports = hexadecimal - -// Check if the given character code, or the character code at the first -// character, is hexadecimal. -function hexadecimal(character) { - var code = typeof character === 'string' ? character.charCodeAt(0) : character - - return ( - (code >= 97 /* a */ && code <= 102) /* z */ || - (code >= 65 /* A */ && code <= 70) /* Z */ || - (code >= 48 /* A */ && code <= 57) /* Z */ - ) -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-hexadecimal/license b/tools/node_modules/eslint-plugin-markdown/node_modules/is-hexadecimal/license deleted file mode 100644 index 8d8660d36ef2ec..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-hexadecimal/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2016 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-hexadecimal/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/is-hexadecimal/package.json deleted file mode 100644 index b8741fe102945a..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-hexadecimal/package.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "name": "is-hexadecimal", - "version": "1.0.4", - "description": "Check if a character is hexadecimal", - "license": "MIT", - "keywords": [ - "string", - "character", - "char", - "code", - "hexadecimal" - ], - "repository": "wooorm/is-hexadecimal", - "bugs": "https://github.com/wooorm/is-hexadecimal/issues", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - }, - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "files": [ - "index.js" - ], - "dependencies": {}, - "devDependencies": { - "browserify": "^16.0.0", - "nyc": "^15.0.0", - "prettier": "^1.0.0", - "remark-cli": "^7.0.0", - "remark-preset-wooorm": "^6.0.0", - "tape": "^4.0.0", - "tinyify": "^2.0.0", - "xo": "^0.25.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify . -s isHexadecimal -o is-hexadecimal.js", - "build-mangle": "browserify . -s isHexadecimal -p tinyify -o is-hexadecimal.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "ignores": [ - "is-hexadecimal.js" - ] - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-hexadecimal/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/is-hexadecimal/readme.md deleted file mode 100644 index 7c82b1b8d462f8..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-hexadecimal/readme.md +++ /dev/null @@ -1,70 +0,0 @@ -# is-hexadecimal - -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] - -Check if a character is hexadecimal. - -## Install - -[npm][]: - -```sh -npm install is-hexadecimal -``` - -## Use - -```js -var hexadecimal = require('is-hexadecimal') - -hexadecimal('a') // => true -hexadecimal('0') // => true -hexadecimal('G') // => false -hexadecimal('💩') // => false -``` - -## API - -### `hexadecimal(character|code)` - -Check whether the given character code (`number`), or the character code at the -first position (`string`), is hexadecimal. - -## Related - -* [`is-alphabetical`](https://github.com/wooorm/is-alphabetical) -* [`is-alphanumerical`](https://github.com/wooorm/is-alphabetical) -* [`is-decimal`](https://github.com/wooorm/is-decimal) -* [`is-whitespace-character`](https://github.com/wooorm/is-whitespace-character) -* [`is-word-character`](https://github.com/wooorm/is-word-character) - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/wooorm/is-hexadecimal.svg - -[build]: https://travis-ci.org/wooorm/is-hexadecimal - -[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/is-hexadecimal.svg - -[coverage]: https://codecov.io/github/wooorm/is-hexadecimal - -[downloads-badge]: https://img.shields.io/npm/dm/is-hexadecimal.svg - -[downloads]: https://www.npmjs.com/package/is-hexadecimal - -[size-badge]: https://img.shields.io/bundlephobia/minzip/is-hexadecimal.svg - -[size]: https://bundlephobia.com/result?p=is-hexadecimal - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-plain-obj/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/is-plain-obj/index.js deleted file mode 100644 index 0d1ba9eeb89723..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-plain-obj/index.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict'; -var toString = Object.prototype.toString; - -module.exports = function (x) { - var prototype; - return toString.call(x) === '[object Object]' && (prototype = Object.getPrototypeOf(x), prototype === null || prototype === Object.getPrototypeOf({})); -}; diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-plain-obj/license b/tools/node_modules/eslint-plugin-markdown/node_modules/is-plain-obj/license deleted file mode 100644 index 654d0bfe943437..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-plain-obj/license +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) Sindre Sorhus (sindresorhus.com) - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-plain-obj/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/is-plain-obj/package.json deleted file mode 100644 index d331f6e8169900..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-plain-obj/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "is-plain-obj", - "version": "1.1.0", - "description": "Check if a value is a plain object", - "license": "MIT", - "repository": "sindresorhus/is-plain-obj", - "author": { - "name": "Sindre Sorhus", - "email": "sindresorhus@gmail.com", - "url": "sindresorhus.com" - }, - "engines": { - "node": ">=0.10.0" - }, - "scripts": { - "test": "node test.js" - }, - "files": [ - "index.js" - ], - "keywords": [ - "obj", - "object", - "is", - "check", - "test", - "type", - "plain", - "vanilla", - "pure", - "simple" - ], - "devDependencies": { - "ava": "0.0.4" - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-plain-obj/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/is-plain-obj/readme.md deleted file mode 100644 index 269e56aeff0646..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-plain-obj/readme.md +++ /dev/null @@ -1,35 +0,0 @@ -# is-plain-obj [![Build Status](https://travis-ci.org/sindresorhus/is-plain-obj.svg?branch=master)](https://travis-ci.org/sindresorhus/is-plain-obj) - -> Check if a value is a plain object - -An object is plain if it's created by either `{}`, `new Object()` or `Object.create(null)`. - - -## Install - -``` -$ npm install --save is-plain-obj -``` - - -## Usage - -```js -var isPlainObj = require('is-plain-obj'); - -isPlainObj({foo: 'bar'}); -//=> true - -isPlainObj([1, 2, 3]); -//=> false -``` - - -## Related - -- [is-obj](https://github.com/sindresorhus/is-obj) - Check if a value is an object - - -## License - -MIT © [Sindre Sorhus](http://sindresorhus.com) diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-whitespace-character/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/is-whitespace-character/index.js deleted file mode 100644 index 801c19f0d8df82..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-whitespace-character/index.js +++ /dev/null @@ -1,14 +0,0 @@ -'use strict' - -module.exports = whitespace - -var fromCode = String.fromCharCode -var re = /\s/ - -// Check if the given character code, or the character code at the first -// character, is a whitespace character. -function whitespace(character) { - return re.test( - typeof character === 'number' ? fromCode(character) : character.charAt(0) - ) -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-whitespace-character/license b/tools/node_modules/eslint-plugin-markdown/node_modules/is-whitespace-character/license deleted file mode 100644 index 8d8660d36ef2ec..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-whitespace-character/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2016 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-whitespace-character/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/is-whitespace-character/package.json deleted file mode 100644 index d6b35d9a0b5df4..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-whitespace-character/package.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "name": "is-whitespace-character", - "version": "1.0.4", - "description": "Check if a character is a whitespace character", - "license": "MIT", - "keywords": [ - "string", - "character", - "char", - "code", - "whitespace", - "white", - "space" - ], - "repository": "wooorm/is-whitespace-character", - "bugs": "https://github.com/wooorm/is-whitespace-character/issues", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - }, - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "files": [ - "index.js" - ], - "dependencies": {}, - "devDependencies": { - "browserify": "^16.0.0", - "nyc": "^15.0.0", - "prettier": "^1.0.0", - "remark-cli": "^7.0.0", - "remark-preset-wooorm": "^6.0.0", - "tape": "^4.0.0", - "tinyify": "^2.0.0", - "xo": "^0.25.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify . -s isWhitespaceCharacter -o is-whitespace-character.js", - "build-mangle": "browserify . -s isWhitespaceCharacter -p tinyify -o is-whitespace-character.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "ignores": [ - "is-whitespace-character.js" - ] - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-whitespace-character/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/is-whitespace-character/readme.md deleted file mode 100644 index 34d4f343c86adf..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-whitespace-character/readme.md +++ /dev/null @@ -1,74 +0,0 @@ -# is-whitespace-character - -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] - -Check if a character is a whitespace character: `\s`, which equals all Unicode -Space Separators (including `[ \t\v\f]`), the BOM (`\uFEFF`), and line -terminator (`[\n\r\u2028\u2029]`). - -## Install - -[npm][]: - -```sh -npm install is-whitespace-character -``` - -## Use - -```js -var whitespace = require('is-whitespace-character') - -whitespace(' ') // => true -whitespace('\n') // => true -whitespace('\uFEFF') // => true -whitespace('_') // => false -whitespace('a') // => false -whitespace('💩') // => false -``` - -## API - -### `whitespaceCharacter(character|code)` - -Check whether the given character code (`number`), or the character code at the -first position (`string`), is a whitespace character. - -## Related - -* [`is-alphabetical`](https://github.com/wooorm/is-alphabetical) -* [`is-alphanumerical`](https://github.com/wooorm/is-alphanumerical) -* [`is-decimal`](https://github.com/wooorm/is-decimal) -* [`is-hexadecimal`](https://github.com/wooorm/is-hexadecimal) -* [`is-word-character`](https://github.com/wooorm/is-word-character) - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/wooorm/is-whitespace-character.svg - -[build]: https://travis-ci.org/wooorm/is-whitespace-character - -[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/is-whitespace-character.svg - -[coverage]: https://codecov.io/github/wooorm/is-whitespace-character - -[downloads-badge]: https://img.shields.io/npm/dm/is-whitespace-character.svg - -[downloads]: https://www.npmjs.com/package/is-whitespace-character - -[size-badge]: https://img.shields.io/bundlephobia/minzip/is-whitespace-character.svg - -[size]: https://bundlephobia.com/result?p=is-whitespace-character - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-word-character/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/is-word-character/index.js deleted file mode 100644 index 8c3537f99568c3..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-word-character/index.js +++ /dev/null @@ -1,14 +0,0 @@ -'use strict' - -module.exports = wordCharacter - -var fromCode = String.fromCharCode -var re = /\w/ - -// Check if the given character code, or the character code at the first -// character, is a word character. -function wordCharacter(character) { - return re.test( - typeof character === 'number' ? fromCode(character) : character.charAt(0) - ) -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-word-character/license b/tools/node_modules/eslint-plugin-markdown/node_modules/is-word-character/license deleted file mode 100644 index 8d8660d36ef2ec..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-word-character/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2016 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-word-character/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/is-word-character/package.json deleted file mode 100644 index 42c262cf64fa63..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-word-character/package.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "name": "is-word-character", - "version": "1.0.4", - "description": "Check if a character is a word character", - "license": "MIT", - "keywords": [ - "string", - "character", - "char", - "code", - "word" - ], - "repository": "wooorm/is-word-character", - "bugs": "https://github.com/wooorm/is-word-character/issues", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - }, - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "files": [ - "index.js" - ], - "dependencies": {}, - "devDependencies": { - "browserify": "^16.0.0", - "nyc": "^15.0.0", - "prettier": "^1.0.0", - "remark-cli": "^7.0.0", - "remark-preset-wooorm": "^6.0.0", - "tape": "^4.0.0", - "tinyify": "^2.0.0", - "xo": "^0.25.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify . -s isWordCharacter -o is-word-character.js", - "build-mangle": "browserify . -s isWordCharacter -p tinyify -o is-word-character.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "ignores": [ - "is-word-character.js" - ] - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/is-word-character/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/is-word-character/readme.md deleted file mode 100644 index 3c88ce976e3da2..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/is-word-character/readme.md +++ /dev/null @@ -1,72 +0,0 @@ -# is-word-character - -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] - -Check if a character is a word character (`\w`, which equals `[a-zA-Z0-9_]`). - -## Install - -[npm][]: - -```sh -npm install is-word-character -``` - -## Use - -```js -var wordCharacter = require('is-word-character') - -wordCharacter('a') // => true -wordCharacter('Z') // => true -wordCharacter('0') // => true -wordCharacter('_') // => true -wordCharacter(' ') // => false -wordCharacter('💩') // => false -``` - -## API - -### `wordCharacter(character|code)` - -Check whether the given character code (`number`), or the character code at the -first position (`string`), is a word character. - -## Related - -* [`is-alphabetical`](https://github.com/wooorm/is-alphabetical) -* [`is-alphanumerical`](https://github.com/wooorm/is-alphanumerical) -* [`is-decimal`](https://github.com/wooorm/is-decimal) -* [`is-hexadecimal`](https://github.com/wooorm/is-hexadecimal) -* [`is-whitespace-character`](https://github.com/wooorm/is-whitespace-character) - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/wooorm/is-word-character.svg - -[build]: https://travis-ci.org/wooorm/is-word-character - -[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/is-word-character.svg - -[coverage]: https://codecov.io/github/wooorm/is-word-character - -[downloads-badge]: https://img.shields.io/npm/dm/is-word-character.svg - -[downloads]: https://www.npmjs.com/package/is-word-character - -[size-badge]: https://img.shields.io/bundlephobia/minzip/is-word-character.svg - -[size]: https://bundlephobia.com/result?p=is-word-character - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/markdown-escapes/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/markdown-escapes/index.js deleted file mode 100644 index f8bea48eacca65..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/markdown-escapes/index.js +++ /dev/null @@ -1,57 +0,0 @@ -'use strict' - -module.exports = escapes - -var defaults = [ - '\\', - '`', - '*', - '{', - '}', - '[', - ']', - '(', - ')', - '#', - '+', - '-', - '.', - '!', - '_', - '>' -] - -var gfm = defaults.concat(['~', '|']) - -var commonmark = gfm.concat([ - '\n', - '"', - '$', - '%', - '&', - "'", - ',', - '/', - ':', - ';', - '<', - '=', - '?', - '@', - '^' -]) - -escapes.default = defaults -escapes.gfm = gfm -escapes.commonmark = commonmark - -// Get markdown escapes. -function escapes(options) { - var settings = options || {} - - if (settings.commonmark) { - return commonmark - } - - return settings.gfm ? gfm : defaults -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/markdown-escapes/license b/tools/node_modules/eslint-plugin-markdown/node_modules/markdown-escapes/license deleted file mode 100644 index 8d8660d36ef2ec..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/markdown-escapes/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2016 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/markdown-escapes/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/markdown-escapes/package.json deleted file mode 100644 index 7f94d86ad7acc9..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/markdown-escapes/package.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "name": "markdown-escapes", - "version": "1.0.4", - "description": "List of escapable characters in markdown", - "license": "MIT", - "keywords": [ - "markdown", - "escape", - "pedantic", - "gfm", - "commonmark" - ], - "repository": "wooorm/markdown-escapes", - "bugs": "https://github.com/wooorm/markdown-escapes/issues", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - }, - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "files": [ - "index.js" - ], - "dependencies": {}, - "devDependencies": { - "browserify": "^16.0.0", - "nyc": "^14.0.0", - "prettier": "^1.0.0", - "remark-cli": "^7.0.0", - "remark-preset-wooorm": "^6.0.0", - "tape": "^4.0.0", - "tinyify": "^2.0.0", - "xo": "^0.25.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify . -s markdownEscapes -o markdown-escapes.js", - "build-mangle": "browserify . -s markdownEscapes -p tinyify -o markdown-escapes.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "ignores": [ - "markdown-escapes.js" - ] - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/markdown-escapes/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/markdown-escapes/readme.md deleted file mode 100644 index a7404526114d3d..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/markdown-escapes/readme.md +++ /dev/null @@ -1,80 +0,0 @@ -# markdown-escapes - -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] - -List of escapable characters in markdown. - -## Install - -[npm][]: - -```sh -npm install markdown-escapes -``` - -## Use - -```js -var escapes = require('markdown-escapes'); - -// Access by property: -escapes.commonmark; //=> ['\\', '`', ..., '@', '^'] - -// Access by options object: -escapes({gfm: true}); //=> ['\\', '`', ..., '~', '|'] -``` - -## API - -### `escapes([options])` - -Get escapes. -Supports `options.commonmark` and `options.gfm`, which when `true` returns the -extra escape characters supported by those flavors. - -###### Returns - -`Array.`. - -### `escapes.default` - -List of default escapable characters. - -### `escapes.gfm` - -List of escapable characters in GFM (which includes all `default`s). - -### `escapes.commonmark` - -List of escapable characters in CommonMark (which includes all `gfm`s). - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/wooorm/markdown-escapes.svg - -[build]: https://travis-ci.org/wooorm/markdown-escapes - -[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/markdown-escapes.svg - -[coverage]: https://codecov.io/github/wooorm/markdown-escapes - -[downloads-badge]: https://img.shields.io/npm/dm/markdown-escapes.svg - -[downloads]: https://www.npmjs.com/package/markdown-escapes - -[size-badge]: https://img.shields.io/bundlephobia/minzip/markdown-escapes.svg - -[size]: https://bundlephobia.com/result?p=markdown-escapes - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/decode-entity.browser.js b/tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/decode-entity.browser.js deleted file mode 100644 index feb32664202d16..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/decode-entity.browser.js +++ /dev/null @@ -1,30 +0,0 @@ -'use strict' - -/* eslint-env browser */ - -var el - -var semicolon = 59 // ';' - -module.exports = decodeEntity - -function decodeEntity(characters) { - var entity = '&' + characters + ';' - var char - - el = el || document.createElement('i') - el.innerHTML = entity - char = el.textContent - - // Some entities do not require the closing semicolon (`¬` - for instance), - // which leads to situations where parsing the assumed entity of ¬it; will - // result in the string `¬it;`. When we encounter a trailing semicolon after - // parsing and the entity to decode was not a semicolon (`;`), we can - // assume that the matching was incomplete - if (char.charCodeAt(char.length - 1) === semicolon && characters !== 'semi') { - return false - } - - // If the decoded string is equal to the input, the entity was not valid - return char === entity ? false : char -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/decode-entity.js b/tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/decode-entity.js deleted file mode 100644 index 87c3b1e0bc2657..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/decode-entity.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict' - -var characterEntities = require('character-entities') - -module.exports = decodeEntity - -var own = {}.hasOwnProperty - -function decodeEntity(characters) { - return own.call(characterEntities, characters) - ? characterEntities[characters] - : false -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/index.js deleted file mode 100644 index 1606d02f6590c5..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/index.js +++ /dev/null @@ -1,450 +0,0 @@ -'use strict' - -var legacy = require('character-entities-legacy') -var invalid = require('character-reference-invalid') -var decimal = require('is-decimal') -var hexadecimal = require('is-hexadecimal') -var alphanumerical = require('is-alphanumerical') -var decodeEntity = require('./decode-entity') - -module.exports = parseEntities - -var own = {}.hasOwnProperty -var fromCharCode = String.fromCharCode -var noop = Function.prototype - -// Default settings. -var defaults = { - warning: null, - reference: null, - text: null, - warningContext: null, - referenceContext: null, - textContext: null, - position: {}, - additional: null, - attribute: false, - nonTerminated: true -} - -// Characters. -var tab = 9 // '\t' -var lineFeed = 10 // '\n' -var formFeed = 12 // '\f' -var space = 32 // ' ' -var ampersand = 38 // '&' -var semicolon = 59 // ';' -var lessThan = 60 // '<' -var equalsTo = 61 // '=' -var numberSign = 35 // '#' -var uppercaseX = 88 // 'X' -var lowercaseX = 120 // 'x' -var replacementCharacter = 65533 // '�' - -// Reference types. -var name = 'named' -var hexa = 'hexadecimal' -var deci = 'decimal' - -// Map of bases. -var bases = {} - -bases[hexa] = 16 -bases[deci] = 10 - -// Map of types to tests. -// Each type of character reference accepts different characters. -// This test is used to detect whether a reference has ended (as the semicolon -// is not strictly needed). -var tests = {} - -tests[name] = alphanumerical -tests[deci] = decimal -tests[hexa] = hexadecimal - -// Warning types. -var namedNotTerminated = 1 -var numericNotTerminated = 2 -var namedEmpty = 3 -var numericEmpty = 4 -var namedUnknown = 5 -var numericDisallowed = 6 -var numericProhibited = 7 - -// Warning messages. -var messages = {} - -messages[namedNotTerminated] = - 'Named character references must be terminated by a semicolon' -messages[numericNotTerminated] = - 'Numeric character references must be terminated by a semicolon' -messages[namedEmpty] = 'Named character references cannot be empty' -messages[numericEmpty] = 'Numeric character references cannot be empty' -messages[namedUnknown] = 'Named character references must be known' -messages[numericDisallowed] = - 'Numeric character references cannot be disallowed' -messages[numericProhibited] = - 'Numeric character references cannot be outside the permissible Unicode range' - -// Wrap to ensure clean parameters are given to `parse`. -function parseEntities(value, options) { - var settings = {} - var option - var key - - if (!options) { - options = {} - } - - for (key in defaults) { - option = options[key] - settings[key] = - option === null || option === undefined ? defaults[key] : option - } - - if (settings.position.indent || settings.position.start) { - settings.indent = settings.position.indent || [] - settings.position = settings.position.start - } - - return parse(value, settings) -} - -// Parse entities. -// eslint-disable-next-line complexity -function parse(value, settings) { - var additional = settings.additional - var nonTerminated = settings.nonTerminated - var handleText = settings.text - var handleReference = settings.reference - var handleWarning = settings.warning - var textContext = settings.textContext - var referenceContext = settings.referenceContext - var warningContext = settings.warningContext - var pos = settings.position - var indent = settings.indent || [] - var length = value.length - var index = 0 - var lines = -1 - var column = pos.column || 1 - var line = pos.line || 1 - var queue = '' - var result = [] - var entityCharacters - var namedEntity - var terminated - var characters - var character - var reference - var following - var warning - var reason - var output - var entity - var begin - var start - var type - var test - var prev - var next - var diff - var end - - if (typeof additional === 'string') { - additional = additional.charCodeAt(0) - } - - // Cache the current point. - prev = now() - - // Wrap `handleWarning`. - warning = handleWarning ? parseError : noop - - // Ensure the algorithm walks over the first character and the end (inclusive). - index-- - length++ - - while (++index < length) { - // If the previous character was a newline. - if (character === lineFeed) { - column = indent[lines] || 1 - } - - character = value.charCodeAt(index) - - if (character === ampersand) { - following = value.charCodeAt(index + 1) - - // The behaviour depends on the identity of the next character. - if ( - following === tab || - following === lineFeed || - following === formFeed || - following === space || - following === ampersand || - following === lessThan || - following !== following || - (additional && following === additional) - ) { - // Not a character reference. - // No characters are consumed, and nothing is returned. - // This is not an error, either. - queue += fromCharCode(character) - column++ - - continue - } - - start = index + 1 - begin = start - end = start - - if (following === numberSign) { - // Numerical entity. - end = ++begin - - // The behaviour further depends on the next character. - following = value.charCodeAt(end) - - if (following === uppercaseX || following === lowercaseX) { - // ASCII hex digits. - type = hexa - end = ++begin - } else { - // ASCII digits. - type = deci - } - } else { - // Named entity. - type = name - } - - entityCharacters = '' - entity = '' - characters = '' - test = tests[type] - end-- - - while (++end < length) { - following = value.charCodeAt(end) - - if (!test(following)) { - break - } - - characters += fromCharCode(following) - - // Check if we can match a legacy named reference. - // If so, we cache that as the last viable named reference. - // This ensures we do not need to walk backwards later. - if (type === name && own.call(legacy, characters)) { - entityCharacters = characters - entity = legacy[characters] - } - } - - terminated = value.charCodeAt(end) === semicolon - - if (terminated) { - end++ - - namedEntity = type === name ? decodeEntity(characters) : false - - if (namedEntity) { - entityCharacters = characters - entity = namedEntity - } - } - - diff = 1 + end - start - - if (!terminated && !nonTerminated) { - // Empty. - } else if (!characters) { - // An empty (possible) entity is valid, unless it’s numeric (thus an - // ampersand followed by an octothorp). - if (type !== name) { - warning(numericEmpty, diff) - } - } else if (type === name) { - // An ampersand followed by anything unknown, and not terminated, is - // invalid. - if (terminated && !entity) { - warning(namedUnknown, 1) - } else { - // If theres something after an entity name which is not known, cap - // the reference. - if (entityCharacters !== characters) { - end = begin + entityCharacters.length - diff = 1 + end - begin - terminated = false - } - - // If the reference is not terminated, warn. - if (!terminated) { - reason = entityCharacters ? namedNotTerminated : namedEmpty - - if (settings.attribute) { - following = value.charCodeAt(end) - - if (following === equalsTo) { - warning(reason, diff) - entity = null - } else if (alphanumerical(following)) { - entity = null - } else { - warning(reason, diff) - } - } else { - warning(reason, diff) - } - } - } - - reference = entity - } else { - if (!terminated) { - // All non-terminated numeric entities are not rendered, and trigger a - // warning. - warning(numericNotTerminated, diff) - } - - // When terminated and number, parse as either hexadecimal or decimal. - reference = parseInt(characters, bases[type]) - - // Trigger a warning when the parsed number is prohibited, and replace - // with replacement character. - if (prohibited(reference)) { - warning(numericProhibited, diff) - reference = fromCharCode(replacementCharacter) - } else if (reference in invalid) { - // Trigger a warning when the parsed number is disallowed, and replace - // by an alternative. - warning(numericDisallowed, diff) - reference = invalid[reference] - } else { - // Parse the number. - output = '' - - // Trigger a warning when the parsed number should not be used. - if (disallowed(reference)) { - warning(numericDisallowed, diff) - } - - // Stringify the number. - if (reference > 0xffff) { - reference -= 0x10000 - output += fromCharCode((reference >>> (10 & 0x3ff)) | 0xd800) - reference = 0xdc00 | (reference & 0x3ff) - } - - reference = output + fromCharCode(reference) - } - } - - // Found it! - // First eat the queued characters as normal text, then eat an entity. - if (reference) { - flush() - - prev = now() - index = end - 1 - column += end - start + 1 - result.push(reference) - next = now() - next.offset++ - - if (handleReference) { - handleReference.call( - referenceContext, - reference, - {start: prev, end: next}, - value.slice(start - 1, end) - ) - } - - prev = next - } else { - // If we could not find a reference, queue the checked characters (as - // normal characters), and move the pointer to their end. - // This is possible because we can be certain neither newlines nor - // ampersands are included. - characters = value.slice(start - 1, end) - queue += characters - column += characters.length - index = end - 1 - } - } else { - // Handle anything other than an ampersand, including newlines and EOF. - if ( - character === 10 // Line feed - ) { - line++ - lines++ - column = 0 - } - - if (character === character) { - queue += fromCharCode(character) - column++ - } else { - flush() - } - } - } - - // Return the reduced nodes, and any possible warnings. - return result.join('') - - // Get current position. - function now() { - return { - line: line, - column: column, - offset: index + (pos.offset || 0) - } - } - - // “Throw” a parse-error: a warning. - function parseError(code, offset) { - var position = now() - - position.column += offset - position.offset += offset - - handleWarning.call(warningContext, messages[code], position, code) - } - - // Flush `queue` (normal text). - // Macro invoked before each entity and at the end of `value`. - // Does nothing when `queue` is empty. - function flush() { - if (queue) { - result.push(queue) - - if (handleText) { - handleText.call(textContext, queue, {start: prev, end: now()}) - } - - queue = '' - } - } -} - -// Check if `character` is outside the permissible unicode range. -function prohibited(code) { - return (code >= 0xd800 && code <= 0xdfff) || code > 0x10ffff -} - -// Check if `character` is disallowed. -function disallowed(code) { - return ( - (code >= 0x0001 && code <= 0x0008) || - code === 0x000b || - (code >= 0x000d && code <= 0x001f) || - (code >= 0x007f && code <= 0x009f) || - (code >= 0xfdd0 && code <= 0xfdef) || - (code & 0xffff) === 0xffff || - (code & 0xffff) === 0xfffe - ) -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/license b/tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/license deleted file mode 100644 index 611b67581bb8e2..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2015 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/package.json deleted file mode 100644 index a5e1bc46f6a9ba..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/package.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "name": "parse-entities", - "version": "1.2.2", - "description": "Parse HTML character references: fast, spec-compliant, positional information", - "license": "MIT", - "keywords": [ - "parse", - "html", - "character", - "reference", - "entity", - "entities" - ], - "repository": "wooorm/parse-entities", - "bugs": "https://github.com/wooorm/parse-entities/issues", - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "browser": { - "./decode-entity.js": "./decode-entity.browser.js" - }, - "react-native": { - "./decode-entity.js": "./decode-entity.js" - }, - "files": [ - "index.js", - "decode-entity.js", - "decode-entity.browser.js" - ], - "dependencies": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - }, - "devDependencies": { - "browserify": "^16.0.0", - "nyc": "^14.0.0", - "prettier": "^1.12.1", - "remark-cli": "^6.0.0", - "remark-preset-wooorm": "^4.0.0", - "tape": "^4.2.0", - "tape-run": "^6.0.0", - "tinyify": "^2.4.3", - "xo": "^0.24.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify . -s parseEntities > parse-entities.js", - "build-mangle": "browserify . -s parseEntities -p tinyify > parse-entities.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test-browser": "browserify test.js | tape-run", - "test": "npm run format && npm run build && npm run test-coverage && npm run test-browser" - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "rules": { - "no-self-compare": "off", - "guard-for-in": "off", - "max-depth": "off" - }, - "ignores": [ - "parse-entities.js" - ] - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/readme.md deleted file mode 100644 index e9cc0f037ff16f..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/parse-entities/readme.md +++ /dev/null @@ -1,217 +0,0 @@ -# parse-entities - -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] - -Parse HTML character references: fast, spec-compliant, positional -information. - -## Installation - -[npm][]: - -```bash -npm install parse-entities -``` - -## Usage - -```js -var decode = require('parse-entities') - -decode('alpha & bravo') -// => alpha & bravo - -decode('charlie ©cat; delta') -// => charlie ©cat; delta - -decode('echo © foxtrot ≠ golf 𝌆 hotel') -// => echo © foxtrot ≠ golf 𝌆 hotel -``` - -## API - -## `parseEntities(value[, options])` - -##### `options` - -###### `options.additional` - -Additional character to accept (`string?`, default: `''`). -This allows other characters, without error, when following an ampersand. - -###### `options.attribute` - -Whether to parse `value` as an attribute value (`boolean?`, default: -`false`). - -###### `options.nonTerminated` - -Whether to allow non-terminated entities (`boolean`, default: `true`). -For example, `©cat` for `©cat`. This behaviour is spec-compliant but -can lead to unexpected results. - -###### `options.warning` - -Error handler ([`Function?`][warning]). - -###### `options.text` - -Text handler ([`Function?`][text]). - -###### `options.reference` - -Reference handler ([`Function?`][reference]). - -###### `options.warningContext` - -Context used when invoking `warning` (`'*'`, optional). - -###### `options.textContext` - -Context used when invoking `text` (`'*'`, optional). - -###### `options.referenceContext` - -Context used when invoking `reference` (`'*'`, optional) - -###### `options.position` - -Starting `position` of `value` (`Location` or `Position`, optional). Useful -when dealing with values nested in some sort of syntax tree. The default is: - -```js -{ - start: {line: 1, column: 1, offset: 0}, - indent: [] -} -``` - -##### Returns - -`string` — Decoded `value`. - -### `function warning(reason, position, code)` - -Error handler. - -##### Context - -`this` refers to `warningContext` when given to `parseEntities`. - -##### Parameters - -###### `reason` - -Human-readable reason for triggering a parse error (`string`). - -###### `position` - -Place at which the parse error occurred (`Position`). - -###### `code` - -Identifier of reason for triggering a parse error (`number`). - -The following codes are used: - -| Code | Example | Note | -| ---- | ------------------ | --------------------------------------------- | -| `1` | `foo & bar` | Missing semicolon (named) | -| `2` | `foo { bar` | Missing semicolon (numeric) | -| `3` | `Foo &bar baz` | Ampersand did not start a reference | -| `4` | `Foo &#` | Empty reference | -| `5` | `Foo &bar; baz` | Unknown entity | -| `6` | `Foo € baz` | [Disallowed reference][invalid] | -| `7` | `Foo � baz` | Prohibited: outside permissible unicode range | - -### `function text(value, location)` - -Text handler. - -##### Context - -`this` refers to `textContext` when given to `parseEntities`. - -##### Parameters - -###### `value` - -String of content (`string`). - -###### `location` - -Location at which `value` starts and ends (`Location`). - -### `function reference(value, location, source)` - -Character reference handler. - -##### Context - -`this` refers to `referenceContext` when given to `parseEntities`. - -##### Parameters - -###### `value` - -Encoded character reference (`string`). - -###### `location` - -Location at which `value` starts and ends (`Location`). - -###### `source` - -Source of character reference (`Location`). - -## Related - -* [`stringify-entities`](https://github.com/wooorm/stringify-entities) - — Encode HTML character references -* [`character-entities`](https://github.com/wooorm/character-entities) - — Info on character entities -* [`character-entities-html4`](https://github.com/wooorm/character-entities-html4) - — Info on HTML4 character entities -* [`character-entities-legacy`](https://github.com/wooorm/character-entities-legacy) - — Info on legacy character entities -* [`character-reference-invalid`](https://github.com/wooorm/character-reference-invalid) - — Info on invalid numeric character references - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/wooorm/parse-entities.svg - -[build]: https://travis-ci.org/wooorm/parse-entities - -[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/parse-entities.svg - -[coverage]: https://codecov.io/github/wooorm/parse-entities - -[downloads-badge]: https://img.shields.io/npm/dm/parse-entities.svg - -[downloads]: https://www.npmjs.com/package/parse-entities - -[size-badge]: https://img.shields.io/bundlephobia/minzip/parse-entities.svg - -[size]: https://bundlephobia.com/result?p=parse-entities - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com - -[warning]: #function-warningreason-position-code - -[text]: #function-textvalue-location - -[reference]: #function-referencevalue-location-source - -[invalid]: https://github.com/wooorm/character-reference-invalid diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/index.js deleted file mode 100644 index 1579e35518c582..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/index.js +++ /dev/null @@ -1,14 +0,0 @@ -'use strict'; - -var unherit = require('unherit'); -var xtend = require('xtend'); -var Parser = require('./lib/parser.js'); - -module.exports = parse; -parse.Parser = Parser; - -function parse(options) { - var Local = unherit(Parser); - Local.prototype.options = xtend(Local.prototype.options, this.data('settings'), options); - this.Parser = Local; -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/block-elements.json b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/block-elements.json deleted file mode 100644 index 2d13b561792d65..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/block-elements.json +++ /dev/null @@ -1,68 +0,0 @@ -[ - "address", - "article", - "aside", - "base", - "basefont", - "blockquote", - "body", - "caption", - "center", - "col", - "colgroup", - "dd", - "details", - "dialog", - "dir", - "div", - "dl", - "dt", - "fieldset", - "figcaption", - "figure", - "footer", - "form", - "frame", - "frameset", - "h1", - "h2", - "h3", - "h4", - "h5", - "h6", - "head", - "header", - "hgroup", - "hr", - "html", - "iframe", - "legend", - "li", - "link", - "main", - "menu", - "menuitem", - "meta", - "nav", - "noframes", - "ol", - "optgroup", - "option", - "p", - "param", - "pre", - "section", - "source", - "title", - "summary", - "table", - "tbody", - "td", - "tfoot", - "th", - "thead", - "title", - "tr", - "track", - "ul" -] diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/decode.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/decode.js deleted file mode 100644 index fd45b729d069e1..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/decode.js +++ /dev/null @@ -1,64 +0,0 @@ -'use strict'; - -var xtend = require('xtend'); -var entities = require('parse-entities'); - -module.exports = factory; - -/* Factory to create an entity decoder. */ -function factory(ctx) { - decoder.raw = decodeRaw; - - return decoder; - - /* Normalize `position` to add an `indent`. */ - function normalize(position) { - var offsets = ctx.offset; - var line = position.line; - var result = []; - - while (++line) { - if (!(line in offsets)) { - break; - } - - result.push((offsets[line] || 0) + 1); - } - - return { - start: position, - indent: result - }; - } - - /* Handle a warning. - * See https://github.com/wooorm/parse-entities - * for the warnings. */ - function handleWarning(reason, position, code) { - if (code === 3) { - return; - } - - ctx.file.message(reason, position); - } - - /* Decode `value` (at `position`) into text-nodes. */ - function decoder(value, position, handler) { - entities(value, { - position: normalize(position), - warning: handleWarning, - text: handler, - reference: handler, - textContext: ctx, - referenceContext: ctx - }); - } - - /* Decode `value` (at `position`) into a string. */ - function decodeRaw(value, position, options) { - return entities(value, xtend(options, { - position: normalize(position), - warning: handleWarning - })); - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/defaults.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/defaults.js deleted file mode 100644 index 37846f3930a35a..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/defaults.js +++ /dev/null @@ -1,10 +0,0 @@ -'use strict'; - -module.exports = { - position: true, - gfm: true, - commonmark: false, - footnotes: false, - pedantic: false, - blocks: require('./block-elements.json') -}; diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/break.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/break.js deleted file mode 100644 index 295bdc9855126e..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/break.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict'; - -module.exports = locate; - -function locate(value, fromIndex) { - var index = value.indexOf('\n', fromIndex); - - while (index > fromIndex) { - if (value.charAt(index - 1) !== ' ') { - break; - } - - index--; - } - - return index; -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/code-inline.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/code-inline.js deleted file mode 100644 index 981c81698254fe..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/code-inline.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict'; - -module.exports = locate; - -function locate(value, fromIndex) { - return value.indexOf('`', fromIndex); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/delete.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/delete.js deleted file mode 100644 index d208aef2fff386..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/delete.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict'; - -module.exports = locate; - -function locate(value, fromIndex) { - return value.indexOf('~~', fromIndex); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/emphasis.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/emphasis.js deleted file mode 100644 index 6a1f24227d05bb..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/emphasis.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict'; - -module.exports = locate; - -function locate(value, fromIndex) { - var asterisk = value.indexOf('*', fromIndex); - var underscore = value.indexOf('_', fromIndex); - - if (underscore === -1) { - return asterisk; - } - - if (asterisk === -1) { - return underscore; - } - - return underscore < asterisk ? underscore : asterisk; -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/escape.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/escape.js deleted file mode 100644 index f6c63715827ef3..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/escape.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict'; - -module.exports = locate; - -function locate(value, fromIndex) { - return value.indexOf('\\', fromIndex); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/link.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/link.js deleted file mode 100644 index 0f16fd8016bd36..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/link.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict'; - -module.exports = locate; - -function locate(value, fromIndex) { - var link = value.indexOf('[', fromIndex); - var image = value.indexOf('![', fromIndex); - - if (image === -1) { - return link; - } - - /* Link can never be `-1` if an image is found, so we don’t need - * to check for that :) */ - return link < image ? link : image; -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/strong.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/strong.js deleted file mode 100644 index da1cac0a499f2e..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/strong.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict'; - -module.exports = locate; - -function locate(value, fromIndex) { - var asterisk = value.indexOf('**', fromIndex); - var underscore = value.indexOf('__', fromIndex); - - if (underscore === -1) { - return asterisk; - } - - if (asterisk === -1) { - return underscore; - } - - return underscore < asterisk ? underscore : asterisk; -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/tag.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/tag.js deleted file mode 100644 index 3c5534268abe1d..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/tag.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict'; - -module.exports = locate; - -function locate(value, fromIndex) { - return value.indexOf('<', fromIndex); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/url.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/url.js deleted file mode 100644 index 59b63e2563693e..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/locate/url.js +++ /dev/null @@ -1,26 +0,0 @@ -'use strict'; - -module.exports = locate; - -var PROTOCOLS = ['https://', 'http://', 'mailto:']; - -function locate(value, fromIndex) { - var length = PROTOCOLS.length; - var index = -1; - var min = -1; - var position; - - if (!this.options.gfm) { - return -1; - } - - while (++index < length) { - position = value.indexOf(PROTOCOLS[index], fromIndex); - - if (position !== -1 && (position < min || min === -1)) { - min = position; - } - } - - return min; -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/parse.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/parse.js deleted file mode 100644 index 5a8d8119556792..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/parse.js +++ /dev/null @@ -1,45 +0,0 @@ -'use strict'; - -var xtend = require('xtend'); -var removePosition = require('unist-util-remove-position'); - -module.exports = parse; - -var C_NEWLINE = '\n'; -var EXPRESSION_LINE_BREAKS = /\r\n|\r/g; - -/* Parse the bound file. */ -function parse() { - var self = this; - var value = String(self.file); - var start = {line: 1, column: 1, offset: 0}; - var content = xtend(start); - var node; - - /* Clean non-unix newlines: `\r\n` and `\r` are all - * changed to `\n`. This should not affect positional - * information. */ - value = value.replace(EXPRESSION_LINE_BREAKS, C_NEWLINE); - - if (value.charCodeAt(0) === 0xFEFF) { - value = value.slice(1); - - content.column++; - content.offset++; - } - - node = { - type: 'root', - children: self.tokenizeBlock(value, content), - position: { - start: start, - end: self.eof || xtend(start) - } - }; - - if (!self.options.position) { - removePosition(node, true); - } - - return node; -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/parser.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/parser.js deleted file mode 100644 index 9291109f16f3ec..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/parser.js +++ /dev/null @@ -1,152 +0,0 @@ -'use strict'; - -var xtend = require('xtend'); -var toggle = require('state-toggle'); -var vfileLocation = require('vfile-location'); -var unescape = require('./unescape'); -var decode = require('./decode'); -var tokenizer = require('./tokenizer'); - -module.exports = Parser; - -function Parser(doc, file) { - this.file = file; - this.offset = {}; - this.options = xtend(this.options); - this.setOptions({}); - - this.inList = false; - this.inBlock = false; - this.inLink = false; - this.atStart = true; - - this.toOffset = vfileLocation(file).toOffset; - this.unescape = unescape(this, 'escape'); - this.decode = decode(this); -} - -var proto = Parser.prototype; - -/* Expose core. */ -proto.setOptions = require('./set-options'); -proto.parse = require('./parse'); - -/* Expose `defaults`. */ -proto.options = require('./defaults'); - -/* Enter and exit helpers. */ -proto.exitStart = toggle('atStart', true); -proto.enterList = toggle('inList', false); -proto.enterLink = toggle('inLink', false); -proto.enterBlock = toggle('inBlock', false); - -/* Nodes that can interupt a paragraph: - * - * ```markdown - * A paragraph, followed by a thematic break. - * ___ - * ``` - * - * In the above example, the thematic break “interupts” - * the paragraph. */ -proto.interruptParagraph = [ - ['thematicBreak'], - ['atxHeading'], - ['fencedCode'], - ['blockquote'], - ['html'], - ['setextHeading', {commonmark: false}], - ['definition', {commonmark: false}], - ['footnote', {commonmark: false}] -]; - -/* Nodes that can interupt a list: - * - * ```markdown - * - One - * ___ - * ``` - * - * In the above example, the thematic break “interupts” - * the list. */ -proto.interruptList = [ - ['atxHeading', {pedantic: false}], - ['fencedCode', {pedantic: false}], - ['thematicBreak', {pedantic: false}], - ['definition', {commonmark: false}], - ['footnote', {commonmark: false}] -]; - -/* Nodes that can interupt a blockquote: - * - * ```markdown - * > A paragraph. - * ___ - * ``` - * - * In the above example, the thematic break “interupts” - * the blockquote. */ -proto.interruptBlockquote = [ - ['indentedCode', {commonmark: true}], - ['fencedCode', {commonmark: true}], - ['atxHeading', {commonmark: true}], - ['setextHeading', {commonmark: true}], - ['thematicBreak', {commonmark: true}], - ['html', {commonmark: true}], - ['list', {commonmark: true}], - ['definition', {commonmark: false}], - ['footnote', {commonmark: false}] -]; - -/* Handlers. */ -proto.blockTokenizers = { - newline: require('./tokenize/newline'), - indentedCode: require('./tokenize/code-indented'), - fencedCode: require('./tokenize/code-fenced'), - blockquote: require('./tokenize/blockquote'), - atxHeading: require('./tokenize/heading-atx'), - thematicBreak: require('./tokenize/thematic-break'), - list: require('./tokenize/list'), - setextHeading: require('./tokenize/heading-setext'), - html: require('./tokenize/html-block'), - footnote: require('./tokenize/footnote-definition'), - definition: require('./tokenize/definition'), - table: require('./tokenize/table'), - paragraph: require('./tokenize/paragraph') -}; - -proto.inlineTokenizers = { - escape: require('./tokenize/escape'), - autoLink: require('./tokenize/auto-link'), - url: require('./tokenize/url'), - html: require('./tokenize/html-inline'), - link: require('./tokenize/link'), - reference: require('./tokenize/reference'), - strong: require('./tokenize/strong'), - emphasis: require('./tokenize/emphasis'), - deletion: require('./tokenize/delete'), - code: require('./tokenize/code-inline'), - break: require('./tokenize/break'), - text: require('./tokenize/text') -}; - -/* Expose precedence. */ -proto.blockMethods = keys(proto.blockTokenizers); -proto.inlineMethods = keys(proto.inlineTokenizers); - -/* Tokenizers. */ -proto.tokenizeBlock = tokenizer('block'); -proto.tokenizeInline = tokenizer('inline'); -proto.tokenizeFactory = tokenizer; - -/* Get all keys in `value`. */ -function keys(value) { - var result = []; - var key; - - for (key in value) { - result.push(key); - } - - return result; -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/set-options.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/set-options.js deleted file mode 100644 index c55f7f32f31def..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/set-options.js +++ /dev/null @@ -1,47 +0,0 @@ -'use strict'; - -var xtend = require('xtend'); -var escapes = require('markdown-escapes'); -var defaults = require('./defaults'); - -module.exports = setOptions; - -function setOptions(options) { - var self = this; - var current = self.options; - var key; - var value; - - if (options == null) { - options = {}; - } else if (typeof options === 'object') { - options = xtend(options); - } else { - throw new Error( - 'Invalid value `' + options + '` ' + - 'for setting `options`' - ); - } - - for (key in defaults) { - value = options[key]; - - if (value == null) { - value = current[key]; - } - - if ( - (key !== 'blocks' && typeof value !== 'boolean') || - (key === 'blocks' && typeof value !== 'object') - ) { - throw new Error('Invalid value `' + value + '` for setting `options.' + key + '`'); - } - - options[key] = value; - } - - self.options = options; - self.escape = escapes(options); - - return self; -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/auto-link.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/auto-link.js deleted file mode 100644 index c945a2c1f88f58..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/auto-link.js +++ /dev/null @@ -1,145 +0,0 @@ -'use strict'; - -var whitespace = require('is-whitespace-character'); -var decode = require('parse-entities'); -var locate = require('../locate/tag'); - -module.exports = autoLink; -autoLink.locator = locate; -autoLink.notInLink = true; - -var C_LT = '<'; -var C_GT = '>'; -var C_AT_SIGN = '@'; -var C_SLASH = '/'; -var MAILTO = 'mailto:'; -var MAILTO_LENGTH = MAILTO.length; - -/* Tokenise a link. */ -function autoLink(eat, value, silent) { - var self; - var subvalue; - var length; - var index; - var queue; - var character; - var hasAtCharacter; - var link; - var now; - var content; - var tokenizers; - var exit; - - if (value.charAt(0) !== C_LT) { - return; - } - - self = this; - subvalue = ''; - length = value.length; - index = 0; - queue = ''; - hasAtCharacter = false; - link = ''; - - index++; - subvalue = C_LT; - - while (index < length) { - character = value.charAt(index); - - if ( - whitespace(character) || - character === C_GT || - character === C_AT_SIGN || - (character === ':' && value.charAt(index + 1) === C_SLASH) - ) { - break; - } - - queue += character; - index++; - } - - if (!queue) { - return; - } - - link += queue; - queue = ''; - - character = value.charAt(index); - link += character; - index++; - - if (character === C_AT_SIGN) { - hasAtCharacter = true; - } else { - if ( - character !== ':' || - value.charAt(index + 1) !== C_SLASH - ) { - return; - } - - link += C_SLASH; - index++; - } - - while (index < length) { - character = value.charAt(index); - - if (whitespace(character) || character === C_GT) { - break; - } - - queue += character; - index++; - } - - character = value.charAt(index); - - if (!queue || character !== C_GT) { - return; - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - link += queue; - content = link; - subvalue += link + character; - now = eat.now(); - now.column++; - now.offset++; - - if (hasAtCharacter) { - if (link.slice(0, MAILTO_LENGTH).toLowerCase() === MAILTO) { - content = content.substr(MAILTO_LENGTH); - now.column += MAILTO_LENGTH; - now.offset += MAILTO_LENGTH; - } else { - link = MAILTO + link; - } - } - - /* Temporarily remove all tokenizers except text in autolinks. */ - tokenizers = self.inlineTokenizers; - self.inlineTokenizers = {text: tokenizers.text}; - - exit = self.enterLink(); - - content = self.tokenizeInline(content, now); - - self.inlineTokenizers = tokenizers; - exit(); - - return eat(subvalue)({ - type: 'link', - title: null, - url: decode(link, {nonTerminated: false}), - children: content - }); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/blockquote.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/blockquote.js deleted file mode 100644 index bd700d6a6c8276..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/blockquote.js +++ /dev/null @@ -1,129 +0,0 @@ -'use strict'; - -var trim = require('trim'); -var interrupt = require('../util/interrupt'); - -module.exports = blockquote; - -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_SPACE = ' '; -var C_GT = '>'; - -/* Tokenise a blockquote. */ -function blockquote(eat, value, silent) { - var self = this; - var offsets = self.offset; - var tokenizers = self.blockTokenizers; - var interruptors = self.interruptBlockquote; - var now = eat.now(); - var currentLine = now.line; - var length = value.length; - var values = []; - var contents = []; - var indents = []; - var add; - var index = 0; - var character; - var rest; - var nextIndex; - var content; - var line; - var startIndex; - var prefixed; - var exit; - - while (index < length) { - character = value.charAt(index); - - if (character !== C_SPACE && character !== C_TAB) { - break; - } - - index++; - } - - if (value.charAt(index) !== C_GT) { - return; - } - - if (silent) { - return true; - } - - index = 0; - - while (index < length) { - nextIndex = value.indexOf(C_NEWLINE, index); - startIndex = index; - prefixed = false; - - if (nextIndex === -1) { - nextIndex = length; - } - - while (index < length) { - character = value.charAt(index); - - if (character !== C_SPACE && character !== C_TAB) { - break; - } - - index++; - } - - if (value.charAt(index) === C_GT) { - index++; - prefixed = true; - - if (value.charAt(index) === C_SPACE) { - index++; - } - } else { - index = startIndex; - } - - content = value.slice(index, nextIndex); - - if (!prefixed && !trim(content)) { - index = startIndex; - break; - } - - if (!prefixed) { - rest = value.slice(index); - - /* Check if the following code contains a possible - * block. */ - if (interrupt(interruptors, tokenizers, self, [eat, rest, true])) { - break; - } - } - - line = startIndex === index ? content : value.slice(startIndex, nextIndex); - - indents.push(index - startIndex); - values.push(line); - contents.push(content); - - index = nextIndex + 1; - } - - index = -1; - length = indents.length; - add = eat(values.join(C_NEWLINE)); - - while (++index < length) { - offsets[currentLine] = (offsets[currentLine] || 0) + indents[index]; - currentLine++; - } - - exit = self.enterBlock(); - contents = self.tokenizeBlock(contents.join(C_NEWLINE), now); - exit(); - - return add({ - type: 'blockquote', - children: contents - }); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/break.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/break.js deleted file mode 100644 index eb531342bfebcb..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/break.js +++ /dev/null @@ -1,40 +0,0 @@ -'use strict'; - -var locate = require('../locate/break'); - -module.exports = hardBreak; -hardBreak.locator = locate; - -var MIN_BREAK_LENGTH = 2; - -function hardBreak(eat, value, silent) { - var length = value.length; - var index = -1; - var queue = ''; - var character; - - while (++index < length) { - character = value.charAt(index); - - if (character === '\n') { - if (index < MIN_BREAK_LENGTH) { - return; - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - queue += character; - - return eat(queue)({type: 'break'}); - } - - if (character !== ' ') { - return; - } - - queue += character; - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/code-fenced.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/code-fenced.js deleted file mode 100644 index 65f2bc73273ab3..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/code-fenced.js +++ /dev/null @@ -1,236 +0,0 @@ -'use strict'; - -var trim = require('trim-trailing-lines'); - -module.exports = fencedCode; - -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_SPACE = ' '; -var C_TILDE = '~'; -var C_TICK = '`'; - -var MIN_FENCE_COUNT = 3; -var CODE_INDENT_COUNT = 4; - -function fencedCode(eat, value, silent) { - var self = this; - var settings = self.options; - var length = value.length + 1; - var index = 0; - var subvalue = ''; - var fenceCount; - var marker; - var character; - var flag; - var queue; - var content; - var exdentedContent; - var closing; - var exdentedClosing; - var indent; - var now; - - if (!settings.gfm) { - return; - } - - /* Eat initial spacing. */ - while (index < length) { - character = value.charAt(index); - - if (character !== C_SPACE && character !== C_TAB) { - break; - } - - subvalue += character; - index++; - } - - indent = index; - - /* Eat the fence. */ - character = value.charAt(index); - - if (character !== C_TILDE && character !== C_TICK) { - return; - } - - index++; - marker = character; - fenceCount = 1; - subvalue += character; - - while (index < length) { - character = value.charAt(index); - - if (character !== marker) { - break; - } - - subvalue += character; - fenceCount++; - index++; - } - - if (fenceCount < MIN_FENCE_COUNT) { - return; - } - - /* Eat spacing before flag. */ - while (index < length) { - character = value.charAt(index); - - if (character !== C_SPACE && character !== C_TAB) { - break; - } - - subvalue += character; - index++; - } - - /* Eat flag. */ - flag = ''; - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if ( - character === C_NEWLINE || - character === C_TILDE || - character === C_TICK - ) { - break; - } - - if (character === C_SPACE || character === C_TAB) { - queue += character; - } else { - flag += queue + character; - queue = ''; - } - - index++; - } - - character = value.charAt(index); - - if (character && character !== C_NEWLINE) { - return; - } - - if (silent) { - return true; - } - - now = eat.now(); - now.column += subvalue.length; - now.offset += subvalue.length; - - subvalue += flag; - flag = self.decode.raw(self.unescape(flag), now); - - if (queue) { - subvalue += queue; - } - - queue = ''; - closing = ''; - exdentedClosing = ''; - content = ''; - exdentedContent = ''; - - /* Eat content. */ - while (index < length) { - character = value.charAt(index); - content += closing; - exdentedContent += exdentedClosing; - closing = ''; - exdentedClosing = ''; - - if (character !== C_NEWLINE) { - content += character; - exdentedClosing += character; - index++; - continue; - } - - /* Add the newline to `subvalue` if its the first - * character. Otherwise, add it to the `closing` - * queue. */ - if (content) { - closing += character; - exdentedClosing += character; - } else { - subvalue += character; - } - - queue = ''; - index++; - - while (index < length) { - character = value.charAt(index); - - if (character !== C_SPACE) { - break; - } - - queue += character; - index++; - } - - closing += queue; - exdentedClosing += queue.slice(indent); - - if (queue.length >= CODE_INDENT_COUNT) { - continue; - } - - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if (character !== marker) { - break; - } - - queue += character; - index++; - } - - closing += queue; - exdentedClosing += queue; - - if (queue.length < fenceCount) { - continue; - } - - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if (character !== C_SPACE && character !== C_TAB) { - break; - } - - closing += character; - exdentedClosing += character; - index++; - } - - if (!character || character === C_NEWLINE) { - break; - } - } - - subvalue += content + closing; - - return eat(subvalue)({ - type: 'code', - lang: flag || null, - value: trim(exdentedContent) - }); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/code-indented.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/code-indented.js deleted file mode 100644 index c73849d9ad8bf2..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/code-indented.js +++ /dev/null @@ -1,98 +0,0 @@ -'use strict'; - -var repeat = require('repeat-string'); -var trim = require('trim-trailing-lines'); - -module.exports = indentedCode; - -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_SPACE = ' '; - -var CODE_INDENT_COUNT = 4; -var CODE_INDENT = repeat(C_SPACE, CODE_INDENT_COUNT); - -/* Tokenise indented code. */ -function indentedCode(eat, value, silent) { - var index = -1; - var length = value.length; - var subvalue = ''; - var content = ''; - var subvalueQueue = ''; - var contentQueue = ''; - var character; - var blankQueue; - var indent; - - while (++index < length) { - character = value.charAt(index); - - if (indent) { - indent = false; - - subvalue += subvalueQueue; - content += contentQueue; - subvalueQueue = ''; - contentQueue = ''; - - if (character === C_NEWLINE) { - subvalueQueue = character; - contentQueue = character; - } else { - subvalue += character; - content += character; - - while (++index < length) { - character = value.charAt(index); - - if (!character || character === C_NEWLINE) { - contentQueue = character; - subvalueQueue = character; - break; - } - - subvalue += character; - content += character; - } - } - } else if ( - character === C_SPACE && - value.charAt(index + 1) === character && - value.charAt(index + 2) === character && - value.charAt(index + 3) === character - ) { - subvalueQueue += CODE_INDENT; - index += 3; - indent = true; - } else if (character === C_TAB) { - subvalueQueue += character; - indent = true; - } else { - blankQueue = ''; - - while (character === C_TAB || character === C_SPACE) { - blankQueue += character; - character = value.charAt(++index); - } - - if (character !== C_NEWLINE) { - break; - } - - subvalueQueue += blankQueue + character; - contentQueue += character; - } - } - - if (content) { - if (silent) { - return true; - } - - return eat(subvalue)({ - type: 'code', - lang: null, - value: trim(content) - }); - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/code-inline.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/code-inline.js deleted file mode 100644 index c0a496b49255ba..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/code-inline.js +++ /dev/null @@ -1,112 +0,0 @@ -'use strict'; - -var whitespace = require('is-whitespace-character'); -var locate = require('../locate/code-inline'); - -module.exports = inlineCode; -inlineCode.locator = locate; - -var C_TICK = '`'; - -/* Tokenise inline code. */ -function inlineCode(eat, value, silent) { - var length = value.length; - var index = 0; - var queue = ''; - var tickQueue = ''; - var contentQueue; - var subqueue; - var count; - var openingCount; - var subvalue; - var character; - var found; - var next; - - while (index < length) { - if (value.charAt(index) !== C_TICK) { - break; - } - - queue += C_TICK; - index++; - } - - if (!queue) { - return; - } - - subvalue = queue; - openingCount = index; - queue = ''; - next = value.charAt(index); - count = 0; - - while (index < length) { - character = next; - next = value.charAt(index + 1); - - if (character === C_TICK) { - count++; - tickQueue += character; - } else { - count = 0; - queue += character; - } - - if (count && next !== C_TICK) { - if (count === openingCount) { - subvalue += queue + tickQueue; - found = true; - break; - } - - queue += tickQueue; - tickQueue = ''; - } - - index++; - } - - if (!found) { - if (openingCount % 2 !== 0) { - return; - } - - queue = ''; - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - contentQueue = ''; - subqueue = ''; - length = queue.length; - index = -1; - - while (++index < length) { - character = queue.charAt(index); - - if (whitespace(character)) { - subqueue += character; - continue; - } - - if (subqueue) { - if (contentQueue) { - contentQueue += subqueue; - } - - subqueue = ''; - } - - contentQueue += character; - } - - return eat(subvalue)({ - type: 'inlineCode', - value: contentQueue - }); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/definition.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/definition.js deleted file mode 100644 index 1cce274cfbdd71..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/definition.js +++ /dev/null @@ -1,278 +0,0 @@ -'use strict'; - -var whitespace = require('is-whitespace-character'); -var normalize = require('../util/normalize'); - -module.exports = definition; -definition.notInList = true; -definition.notInBlock = true; - -var C_DOUBLE_QUOTE = '"'; -var C_SINGLE_QUOTE = '\''; -var C_BACKSLASH = '\\'; -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_SPACE = ' '; -var C_BRACKET_OPEN = '['; -var C_BRACKET_CLOSE = ']'; -var C_PAREN_OPEN = '('; -var C_PAREN_CLOSE = ')'; -var C_COLON = ':'; -var C_LT = '<'; -var C_GT = '>'; - -function definition(eat, value, silent) { - var self = this; - var commonmark = self.options.commonmark; - var index = 0; - var length = value.length; - var subvalue = ''; - var beforeURL; - var beforeTitle; - var queue; - var character; - var test; - var identifier; - var url; - var title; - - while (index < length) { - character = value.charAt(index); - - if (character !== C_SPACE && character !== C_TAB) { - break; - } - - subvalue += character; - index++; - } - - character = value.charAt(index); - - if (character !== C_BRACKET_OPEN) { - return; - } - - index++; - subvalue += character; - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if (character === C_BRACKET_CLOSE) { - break; - } else if (character === C_BACKSLASH) { - queue += character; - index++; - character = value.charAt(index); - } - - queue += character; - index++; - } - - if ( - !queue || - value.charAt(index) !== C_BRACKET_CLOSE || - value.charAt(index + 1) !== C_COLON - ) { - return; - } - - identifier = queue; - subvalue += queue + C_BRACKET_CLOSE + C_COLON; - index = subvalue.length; - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if ( - character !== C_TAB && - character !== C_SPACE && - character !== C_NEWLINE - ) { - break; - } - - subvalue += character; - index++; - } - - character = value.charAt(index); - queue = ''; - beforeURL = subvalue; - - if (character === C_LT) { - index++; - - while (index < length) { - character = value.charAt(index); - - if (!isEnclosedURLCharacter(character)) { - break; - } - - queue += character; - index++; - } - - character = value.charAt(index); - - if (character === isEnclosedURLCharacter.delimiter) { - subvalue += C_LT + queue + character; - index++; - } else { - if (commonmark) { - return; - } - - index -= queue.length + 1; - queue = ''; - } - } - - if (!queue) { - while (index < length) { - character = value.charAt(index); - - if (!isUnclosedURLCharacter(character)) { - break; - } - - queue += character; - index++; - } - - subvalue += queue; - } - - if (!queue) { - return; - } - - url = queue; - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if ( - character !== C_TAB && - character !== C_SPACE && - character !== C_NEWLINE - ) { - break; - } - - queue += character; - index++; - } - - character = value.charAt(index); - test = null; - - if (character === C_DOUBLE_QUOTE) { - test = C_DOUBLE_QUOTE; - } else if (character === C_SINGLE_QUOTE) { - test = C_SINGLE_QUOTE; - } else if (character === C_PAREN_OPEN) { - test = C_PAREN_CLOSE; - } - - if (!test) { - queue = ''; - index = subvalue.length; - } else if (queue) { - subvalue += queue + character; - index = subvalue.length; - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if (character === test) { - break; - } - - if (character === C_NEWLINE) { - index++; - character = value.charAt(index); - - if (character === C_NEWLINE || character === test) { - return; - } - - queue += C_NEWLINE; - } - - queue += character; - index++; - } - - character = value.charAt(index); - - if (character !== test) { - return; - } - - beforeTitle = subvalue; - subvalue += queue + character; - index++; - title = queue; - queue = ''; - } else { - return; - } - - while (index < length) { - character = value.charAt(index); - - if (character !== C_TAB && character !== C_SPACE) { - break; - } - - subvalue += character; - index++; - } - - character = value.charAt(index); - - if (!character || character === C_NEWLINE) { - if (silent) { - return true; - } - - beforeURL = eat(beforeURL).test().end; - url = self.decode.raw(self.unescape(url), beforeURL, {nonTerminated: false}); - - if (title) { - beforeTitle = eat(beforeTitle).test().end; - title = self.decode.raw(self.unescape(title), beforeTitle); - } - - return eat(subvalue)({ - type: 'definition', - identifier: normalize(identifier), - title: title || null, - url: url - }); - } -} - -/* Check if `character` can be inside an enclosed URI. */ -function isEnclosedURLCharacter(character) { - return character !== C_GT && - character !== C_BRACKET_OPEN && - character !== C_BRACKET_CLOSE; -} - -isEnclosedURLCharacter.delimiter = C_GT; - -/* Check if `character` can be inside an unclosed URI. */ -function isUnclosedURLCharacter(character) { - return character !== C_BRACKET_OPEN && - character !== C_BRACKET_CLOSE && - !whitespace(character); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/delete.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/delete.js deleted file mode 100644 index ca7c68a8c5c1be..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/delete.js +++ /dev/null @@ -1,60 +0,0 @@ -'use strict'; - -var whitespace = require('is-whitespace-character'); -var locate = require('../locate/delete'); - -module.exports = strikethrough; -strikethrough.locator = locate; - -var C_TILDE = '~'; -var DOUBLE = '~~'; - -function strikethrough(eat, value, silent) { - var self = this; - var character = ''; - var previous = ''; - var preceding = ''; - var subvalue = ''; - var index; - var length; - var now; - - if ( - !self.options.gfm || - value.charAt(0) !== C_TILDE || - value.charAt(1) !== C_TILDE || - whitespace(value.charAt(2)) - ) { - return; - } - - index = 1; - length = value.length; - now = eat.now(); - now.column += 2; - now.offset += 2; - - while (++index < length) { - character = value.charAt(index); - - if ( - character === C_TILDE && - previous === C_TILDE && - (!preceding || !whitespace(preceding)) - ) { - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - return eat(DOUBLE + subvalue + DOUBLE)({ - type: 'delete', - children: self.tokenizeInline(subvalue, now) - }); - } - - subvalue += previous; - preceding = previous; - previous = character; - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/emphasis.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/emphasis.js deleted file mode 100644 index b2c87b4497de38..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/emphasis.js +++ /dev/null @@ -1,85 +0,0 @@ -'use strict'; - -var trim = require('trim'); -var word = require('is-word-character'); -var whitespace = require('is-whitespace-character'); -var locate = require('../locate/emphasis'); - -module.exports = emphasis; -emphasis.locator = locate; - -var C_ASTERISK = '*'; -var C_UNDERSCORE = '_'; - -function emphasis(eat, value, silent) { - var self = this; - var index = 0; - var character = value.charAt(index); - var now; - var pedantic; - var marker; - var queue; - var subvalue; - var length; - var prev; - - if (character !== C_ASTERISK && character !== C_UNDERSCORE) { - return; - } - - pedantic = self.options.pedantic; - subvalue = character; - marker = character; - length = value.length; - index++; - queue = ''; - character = ''; - - if (pedantic && whitespace(value.charAt(index))) { - return; - } - - while (index < length) { - prev = character; - character = value.charAt(index); - - if (character === marker && (!pedantic || !whitespace(prev))) { - character = value.charAt(++index); - - if (character !== marker) { - if (!trim(queue) || prev === marker) { - return; - } - - if (!pedantic && marker === C_UNDERSCORE && word(character)) { - queue += marker; - continue; - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - now = eat.now(); - now.column++; - now.offset++; - - return eat(subvalue + queue + marker)({ - type: 'emphasis', - children: self.tokenizeInline(queue, now) - }); - } - - queue += marker; - } - - if (!pedantic && character === '\\') { - queue += character; - character = value.charAt(++index); - } - - queue += character; - index++; - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/escape.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/escape.js deleted file mode 100644 index d6f99bcc10381d..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/escape.js +++ /dev/null @@ -1,34 +0,0 @@ -'use strict'; - -var locate = require('../locate/escape'); - -module.exports = escape; -escape.locator = locate; - -function escape(eat, value, silent) { - var self = this; - var character; - var node; - - if (value.charAt(0) === '\\') { - character = value.charAt(1); - - if (self.escape.indexOf(character) !== -1) { - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - if (character === '\n') { - node = {type: 'break'}; - } else { - node = { - type: 'text', - value: character - }; - } - - return eat('\\' + character)(node); - } - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/footnote-definition.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/footnote-definition.js deleted file mode 100644 index f48ff9bb7eb187..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/footnote-definition.js +++ /dev/null @@ -1,185 +0,0 @@ -'use strict'; - -var whitespace = require('is-whitespace-character'); -var normalize = require('../util/normalize'); - -module.exports = footnoteDefinition; -footnoteDefinition.notInList = true; -footnoteDefinition.notInBlock = true; - -var C_BACKSLASH = '\\'; -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_SPACE = ' '; -var C_BRACKET_OPEN = '['; -var C_BRACKET_CLOSE = ']'; -var C_CARET = '^'; -var C_COLON = ':'; - -var EXPRESSION_INITIAL_TAB = /^( {4}|\t)?/gm; - -function footnoteDefinition(eat, value, silent) { - var self = this; - var offsets = self.offset; - var index; - var length; - var subvalue; - var now; - var currentLine; - var content; - var queue; - var subqueue; - var character; - var identifier; - var add; - var exit; - - if (!self.options.footnotes) { - return; - } - - index = 0; - length = value.length; - subvalue = ''; - now = eat.now(); - currentLine = now.line; - - while (index < length) { - character = value.charAt(index); - - if (!whitespace(character)) { - break; - } - - subvalue += character; - index++; - } - - if ( - value.charAt(index) !== C_BRACKET_OPEN || - value.charAt(index + 1) !== C_CARET - ) { - return; - } - - subvalue += C_BRACKET_OPEN + C_CARET; - index = subvalue.length; - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if (character === C_BRACKET_CLOSE) { - break; - } else if (character === C_BACKSLASH) { - queue += character; - index++; - character = value.charAt(index); - } - - queue += character; - index++; - } - - if ( - !queue || - value.charAt(index) !== C_BRACKET_CLOSE || - value.charAt(index + 1) !== C_COLON - ) { - return; - } - - if (silent) { - return true; - } - - identifier = normalize(queue); - subvalue += queue + C_BRACKET_CLOSE + C_COLON; - index = subvalue.length; - - while (index < length) { - character = value.charAt(index); - - if (character !== C_TAB && character !== C_SPACE) { - break; - } - - subvalue += character; - index++; - } - - now.column += subvalue.length; - now.offset += subvalue.length; - queue = ''; - content = ''; - subqueue = ''; - - while (index < length) { - character = value.charAt(index); - - if (character === C_NEWLINE) { - subqueue = character; - index++; - - while (index < length) { - character = value.charAt(index); - - if (character !== C_NEWLINE) { - break; - } - - subqueue += character; - index++; - } - - queue += subqueue; - subqueue = ''; - - while (index < length) { - character = value.charAt(index); - - if (character !== C_SPACE) { - break; - } - - subqueue += character; - index++; - } - - if (subqueue.length === 0) { - break; - } - - queue += subqueue; - } - - if (queue) { - content += queue; - queue = ''; - } - - content += character; - index++; - } - - subvalue += content; - - content = content.replace(EXPRESSION_INITIAL_TAB, function (line) { - offsets[currentLine] = (offsets[currentLine] || 0) + line.length; - currentLine++; - - return ''; - }); - - add = eat(subvalue); - - exit = self.enterBlock(); - content = self.tokenizeBlock(content, now); - exit(); - - return add({ - type: 'footnoteDefinition', - identifier: identifier, - children: content - }); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/heading-atx.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/heading-atx.js deleted file mode 100644 index aafeabb54910f6..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/heading-atx.js +++ /dev/null @@ -1,141 +0,0 @@ -'use strict'; - -module.exports = atxHeading; - -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_SPACE = ' '; -var C_HASH = '#'; - -var MAX_ATX_COUNT = 6; - -function atxHeading(eat, value, silent) { - var self = this; - var settings = self.options; - var length = value.length + 1; - var index = -1; - var now = eat.now(); - var subvalue = ''; - var content = ''; - var character; - var queue; - var depth; - - /* Eat initial spacing. */ - while (++index < length) { - character = value.charAt(index); - - if (character !== C_SPACE && character !== C_TAB) { - index--; - break; - } - - subvalue += character; - } - - /* Eat hashes. */ - depth = 0; - - while (++index <= length) { - character = value.charAt(index); - - if (character !== C_HASH) { - index--; - break; - } - - subvalue += character; - depth++; - } - - if (depth > MAX_ATX_COUNT) { - return; - } - - if ( - !depth || - (!settings.pedantic && value.charAt(index + 1) === C_HASH) - ) { - return; - } - - length = value.length + 1; - - /* Eat intermediate white-space. */ - queue = ''; - - while (++index < length) { - character = value.charAt(index); - - if (character !== C_SPACE && character !== C_TAB) { - index--; - break; - } - - queue += character; - } - - /* Exit when not in pedantic mode without spacing. */ - if ( - !settings.pedantic && - queue.length === 0 && - character && - character !== C_NEWLINE - ) { - return; - } - - if (silent) { - return true; - } - - /* Eat content. */ - subvalue += queue; - queue = ''; - content = ''; - - while (++index < length) { - character = value.charAt(index); - - if (!character || character === C_NEWLINE) { - break; - } - - if ( - character !== C_SPACE && - character !== C_TAB && - character !== C_HASH - ) { - content += queue + character; - queue = ''; - continue; - } - - while (character === C_SPACE || character === C_TAB) { - queue += character; - character = value.charAt(++index); - } - - while (character === C_HASH) { - queue += character; - character = value.charAt(++index); - } - - while (character === C_SPACE || character === C_TAB) { - queue += character; - character = value.charAt(++index); - } - - index--; - } - - now.column += subvalue.length; - now.offset += subvalue.length; - subvalue += content + queue; - - return eat(subvalue)({ - type: 'heading', - depth: depth, - children: self.tokenizeInline(content, now) - }); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/heading-setext.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/heading-setext.js deleted file mode 100644 index 96c6130da744e1..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/heading-setext.js +++ /dev/null @@ -1,107 +0,0 @@ -'use strict'; - -module.exports = setextHeading; - -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_SPACE = ' '; -var C_EQUALS = '='; -var C_DASH = '-'; - -var MAX_HEADING_INDENT = 3; - -/* Map of characters which can be used to mark setext - * headers, mapping to their corresponding depth. */ -var SETEXT_MARKERS = {}; - -SETEXT_MARKERS[C_EQUALS] = 1; -SETEXT_MARKERS[C_DASH] = 2; - -function setextHeading(eat, value, silent) { - var self = this; - var now = eat.now(); - var length = value.length; - var index = -1; - var subvalue = ''; - var content; - var queue; - var character; - var marker; - var depth; - - /* Eat initial indentation. */ - while (++index < length) { - character = value.charAt(index); - - if (character !== C_SPACE || index >= MAX_HEADING_INDENT) { - index--; - break; - } - - subvalue += character; - } - - /* Eat content. */ - content = ''; - queue = ''; - - while (++index < length) { - character = value.charAt(index); - - if (character === C_NEWLINE) { - index--; - break; - } - - if (character === C_SPACE || character === C_TAB) { - queue += character; - } else { - content += queue + character; - queue = ''; - } - } - - now.column += subvalue.length; - now.offset += subvalue.length; - subvalue += content + queue; - - /* Ensure the content is followed by a newline and a - * valid marker. */ - character = value.charAt(++index); - marker = value.charAt(++index); - - if (character !== C_NEWLINE || !SETEXT_MARKERS[marker]) { - return; - } - - subvalue += character; - - /* Eat Setext-line. */ - queue = marker; - depth = SETEXT_MARKERS[marker]; - - while (++index < length) { - character = value.charAt(index); - - if (character !== marker) { - if (character !== C_NEWLINE) { - return; - } - - index--; - break; - } - - queue += character; - } - - if (silent) { - return true; - } - - return eat(subvalue + queue)({ - type: 'heading', - depth: depth, - children: self.tokenizeInline(content, now) - }); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/html-block.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/html-block.js deleted file mode 100644 index 6e81eb290a3993..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/html-block.js +++ /dev/null @@ -1,94 +0,0 @@ -'use strict'; - -var openCloseTag = require('../util/html').openCloseTag; - -module.exports = blockHTML; - -var C_TAB = '\t'; -var C_SPACE = ' '; -var C_NEWLINE = '\n'; -var C_LT = '<'; - -function blockHTML(eat, value, silent) { - var self = this; - var blocks = self.options.blocks; - var length = value.length; - var index = 0; - var next; - var line; - var offset; - var character; - var count; - var sequence; - var subvalue; - - var sequences = [ - [/^<(script|pre|style)(?=(\s|>|$))/i, /<\/(script|pre|style)>/i, true], - [/^/, true], - [/^<\?/, /\?>/, true], - [/^/, true], - [/^/, true], - [new RegExp('^|$))', 'i'), /^$/, true], - [new RegExp(openCloseTag.source + '\\s*$'), /^$/, false] - ]; - - /* Eat initial spacing. */ - while (index < length) { - character = value.charAt(index); - - if (character !== C_TAB && character !== C_SPACE) { - break; - } - - index++; - } - - if (value.charAt(index) !== C_LT) { - return; - } - - next = value.indexOf(C_NEWLINE, index + 1); - next = next === -1 ? length : next; - line = value.slice(index, next); - offset = -1; - count = sequences.length; - - while (++offset < count) { - if (sequences[offset][0].test(line)) { - sequence = sequences[offset]; - break; - } - } - - if (!sequence) { - return; - } - - if (silent) { - return sequence[2]; - } - - index = next; - - if (!sequence[1].test(line)) { - while (index < length) { - next = value.indexOf(C_NEWLINE, index + 1); - next = next === -1 ? length : next; - line = value.slice(index + 1, next); - - if (sequence[1].test(line)) { - if (line) { - index = next; - } - - break; - } - - index = next; - } - } - - subvalue = value.slice(0, index); - - return eat(subvalue)({type: 'html', value: subvalue}); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/html-inline.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/html-inline.js deleted file mode 100644 index c204e962b15ae8..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/html-inline.js +++ /dev/null @@ -1,54 +0,0 @@ -'use strict'; - -var alphabetical = require('is-alphabetical'); -var locate = require('../locate/tag'); -var tag = require('../util/html').tag; - -module.exports = inlineHTML; -inlineHTML.locator = locate; - -var EXPRESSION_HTML_LINK_OPEN = /^/i; - -function inlineHTML(eat, value, silent) { - var self = this; - var length = value.length; - var character; - var subvalue; - - if (value.charAt(0) !== '<' || length < 3) { - return; - } - - character = value.charAt(1); - - if ( - !alphabetical(character) && - character !== '?' && - character !== '!' && - character !== '/' - ) { - return; - } - - subvalue = value.match(tag); - - if (!subvalue) { - return; - } - - /* istanbul ignore if - not used yet. */ - if (silent) { - return true; - } - - subvalue = subvalue[0]; - - if (!self.inLink && EXPRESSION_HTML_LINK_OPEN.test(subvalue)) { - self.inLink = true; - } else if (self.inLink && EXPRESSION_HTML_LINK_CLOSE.test(subvalue)) { - self.inLink = false; - } - - return eat(subvalue)({type: 'html', value: subvalue}); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/link.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/link.js deleted file mode 100644 index 3ef5e1ba312d75..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/link.js +++ /dev/null @@ -1,392 +0,0 @@ -'use strict'; - -var whitespace = require('is-whitespace-character'); -var locate = require('../locate/link'); - -module.exports = link; -link.locator = locate; - -var own = {}.hasOwnProperty; - -var C_BACKSLASH = '\\'; -var C_BRACKET_OPEN = '['; -var C_BRACKET_CLOSE = ']'; -var C_PAREN_OPEN = '('; -var C_PAREN_CLOSE = ')'; -var C_LT = '<'; -var C_GT = '>'; -var C_TICK = '`'; -var C_DOUBLE_QUOTE = '"'; -var C_SINGLE_QUOTE = '\''; - -/* Map of characters, which can be used to mark link - * and image titles. */ -var LINK_MARKERS = {}; - -LINK_MARKERS[C_DOUBLE_QUOTE] = C_DOUBLE_QUOTE; -LINK_MARKERS[C_SINGLE_QUOTE] = C_SINGLE_QUOTE; - -/* Map of characters, which can be used to mark link - * and image titles in commonmark-mode. */ -var COMMONMARK_LINK_MARKERS = {}; - -COMMONMARK_LINK_MARKERS[C_DOUBLE_QUOTE] = C_DOUBLE_QUOTE; -COMMONMARK_LINK_MARKERS[C_SINGLE_QUOTE] = C_SINGLE_QUOTE; -COMMONMARK_LINK_MARKERS[C_PAREN_OPEN] = C_PAREN_CLOSE; - -function link(eat, value, silent) { - var self = this; - var subvalue = ''; - var index = 0; - var character = value.charAt(0); - var pedantic = self.options.pedantic; - var commonmark = self.options.commonmark; - var gfm = self.options.gfm; - var closed; - var count; - var opening; - var beforeURL; - var beforeTitle; - var subqueue; - var hasMarker; - var markers; - var isImage; - var content; - var marker; - var length; - var title; - var depth; - var queue; - var url; - var now; - var exit; - var node; - - /* Detect whether this is an image. */ - if (character === '!') { - isImage = true; - subvalue = character; - character = value.charAt(++index); - } - - /* Eat the opening. */ - if (character !== C_BRACKET_OPEN) { - return; - } - - /* Exit when this is a link and we’re already inside - * a link. */ - if (!isImage && self.inLink) { - return; - } - - subvalue += character; - queue = ''; - index++; - - /* Eat the content. */ - length = value.length; - now = eat.now(); - depth = 0; - - now.column += index; - now.offset += index; - - while (index < length) { - character = value.charAt(index); - subqueue = character; - - if (character === C_TICK) { - /* Inline-code in link content. */ - count = 1; - - while (value.charAt(index + 1) === C_TICK) { - subqueue += character; - index++; - count++; - } - - if (!opening) { - opening = count; - } else if (count >= opening) { - opening = 0; - } - } else if (character === C_BACKSLASH) { - /* Allow brackets to be escaped. */ - index++; - subqueue += value.charAt(index); - /* In GFM mode, brackets in code still count. - * In all other modes, they don’t. This empty - * block prevents the next statements are - * entered. */ - } else if ((!opening || gfm) && character === C_BRACKET_OPEN) { - depth++; - } else if ((!opening || gfm) && character === C_BRACKET_CLOSE) { - if (depth) { - depth--; - } else { - /* Allow white-space between content and - * url in GFM mode. */ - if (!pedantic) { - while (index < length) { - character = value.charAt(index + 1); - - if (!whitespace(character)) { - break; - } - - subqueue += character; - index++; - } - } - - if (value.charAt(index + 1) !== C_PAREN_OPEN) { - return; - } - - subqueue += C_PAREN_OPEN; - closed = true; - index++; - - break; - } - } - - queue += subqueue; - subqueue = ''; - index++; - } - - /* Eat the content closing. */ - if (!closed) { - return; - } - - content = queue; - subvalue += queue + subqueue; - index++; - - /* Eat white-space. */ - while (index < length) { - character = value.charAt(index); - - if (!whitespace(character)) { - break; - } - - subvalue += character; - index++; - } - - /* Eat the URL. */ - character = value.charAt(index); - markers = commonmark ? COMMONMARK_LINK_MARKERS : LINK_MARKERS; - queue = ''; - beforeURL = subvalue; - - if (character === C_LT) { - index++; - beforeURL += C_LT; - - while (index < length) { - character = value.charAt(index); - - if (character === C_GT) { - break; - } - - if (commonmark && character === '\n') { - return; - } - - queue += character; - index++; - } - - if (value.charAt(index) !== C_GT) { - return; - } - - subvalue += C_LT + queue + C_GT; - url = queue; - index++; - } else { - character = null; - subqueue = ''; - - while (index < length) { - character = value.charAt(index); - - if (subqueue && own.call(markers, character)) { - break; - } - - if (whitespace(character)) { - if (!pedantic) { - break; - } - - subqueue += character; - } else { - if (character === C_PAREN_OPEN) { - depth++; - } else if (character === C_PAREN_CLOSE) { - if (depth === 0) { - break; - } - - depth--; - } - - queue += subqueue; - subqueue = ''; - - if (character === C_BACKSLASH) { - queue += C_BACKSLASH; - character = value.charAt(++index); - } - - queue += character; - } - - index++; - } - - subvalue += queue; - url = queue; - index = subvalue.length; - } - - /* Eat white-space. */ - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if (!whitespace(character)) { - break; - } - - queue += character; - index++; - } - - character = value.charAt(index); - subvalue += queue; - - /* Eat the title. */ - if (queue && own.call(markers, character)) { - index++; - subvalue += character; - queue = ''; - marker = markers[character]; - beforeTitle = subvalue; - - /* In commonmark-mode, things are pretty easy: the - * marker cannot occur inside the title. - * - * Non-commonmark does, however, support nested - * delimiters. */ - if (commonmark) { - while (index < length) { - character = value.charAt(index); - - if (character === marker) { - break; - } - - if (character === C_BACKSLASH) { - queue += C_BACKSLASH; - character = value.charAt(++index); - } - - index++; - queue += character; - } - - character = value.charAt(index); - - if (character !== marker) { - return; - } - - title = queue; - subvalue += queue + character; - index++; - - while (index < length) { - character = value.charAt(index); - - if (!whitespace(character)) { - break; - } - - subvalue += character; - index++; - } - } else { - subqueue = ''; - - while (index < length) { - character = value.charAt(index); - - if (character === marker) { - if (hasMarker) { - queue += marker + subqueue; - subqueue = ''; - } - - hasMarker = true; - } else if (!hasMarker) { - queue += character; - } else if (character === C_PAREN_CLOSE) { - subvalue += queue + marker + subqueue; - title = queue; - break; - } else if (whitespace(character)) { - subqueue += character; - } else { - queue += marker + subqueue + character; - subqueue = ''; - hasMarker = false; - } - - index++; - } - } - } - - if (value.charAt(index) !== C_PAREN_CLOSE) { - return; - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - subvalue += C_PAREN_CLOSE; - - url = self.decode.raw(self.unescape(url), eat(beforeURL).test().end, {nonTerminated: false}); - - if (title) { - beforeTitle = eat(beforeTitle).test().end; - title = self.decode.raw(self.unescape(title), beforeTitle); - } - - node = { - type: isImage ? 'image' : 'link', - title: title || null, - url: url - }; - - if (isImage) { - node.alt = self.decode.raw(self.unescape(content), now) || null; - } else { - exit = self.enterLink(); - node.children = self.tokenizeInline(content, now); - exit(); - } - - return eat(subvalue)(node); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/list.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/list.js deleted file mode 100644 index 9164c8167f8dc1..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/list.js +++ /dev/null @@ -1,474 +0,0 @@ -'use strict'; - -/* eslint-disable max-params */ - -var trim = require('trim'); -var repeat = require('repeat-string'); -var decimal = require('is-decimal'); -var getIndent = require('../util/get-indentation'); -var removeIndent = require('../util/remove-indentation'); -var interrupt = require('../util/interrupt'); - -module.exports = list; - -var C_ASTERISK = '*'; -var C_UNDERSCORE = '_'; -var C_PLUS = '+'; -var C_DASH = '-'; -var C_DOT = '.'; -var C_SPACE = ' '; -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_PAREN_CLOSE = ')'; -var C_X_LOWER = 'x'; - -var TAB_SIZE = 4; -var EXPRESSION_LOOSE_LIST_ITEM = /\n\n(?!\s*$)/; -var EXPRESSION_TASK_ITEM = /^\[([ \t]|x|X)][ \t]/; -var EXPRESSION_BULLET = /^([ \t]*)([*+-]|\d+[.)])( {1,4}(?! )| |\t|$|(?=\n))([^\n]*)/; -var EXPRESSION_PEDANTIC_BULLET = /^([ \t]*)([*+-]|\d+[.)])([ \t]+)/; -var EXPRESSION_INITIAL_INDENT = /^( {1,4}|\t)?/gm; - -/* Map of characters which can be used to mark - * list-items. */ -var LIST_UNORDERED_MARKERS = {}; - -LIST_UNORDERED_MARKERS[C_ASTERISK] = true; -LIST_UNORDERED_MARKERS[C_PLUS] = true; -LIST_UNORDERED_MARKERS[C_DASH] = true; - -/* Map of characters which can be used to mark - * list-items after a digit. */ -var LIST_ORDERED_MARKERS = {}; - -LIST_ORDERED_MARKERS[C_DOT] = true; - -/* Map of characters which can be used to mark - * list-items after a digit. */ -var LIST_ORDERED_COMMONMARK_MARKERS = {}; - -LIST_ORDERED_COMMONMARK_MARKERS[C_DOT] = true; -LIST_ORDERED_COMMONMARK_MARKERS[C_PAREN_CLOSE] = true; - -function list(eat, value, silent) { - var self = this; - var commonmark = self.options.commonmark; - var pedantic = self.options.pedantic; - var tokenizers = self.blockTokenizers; - var interuptors = self.interruptList; - var markers; - var index = 0; - var length = value.length; - var start = null; - var size = 0; - var queue; - var ordered; - var character; - var marker; - var nextIndex; - var startIndex; - var prefixed; - var currentMarker; - var content; - var line; - var prevEmpty; - var empty; - var items; - var allLines; - var emptyLines; - var item; - var enterTop; - var exitBlockquote; - var isLoose; - var node; - var now; - var end; - var indented; - - while (index < length) { - character = value.charAt(index); - - if (character === C_TAB) { - size += TAB_SIZE - (size % TAB_SIZE); - } else if (character === C_SPACE) { - size++; - } else { - break; - } - - index++; - } - - if (size >= TAB_SIZE) { - return; - } - - character = value.charAt(index); - - markers = commonmark ? - LIST_ORDERED_COMMONMARK_MARKERS : - LIST_ORDERED_MARKERS; - - if (LIST_UNORDERED_MARKERS[character] === true) { - marker = character; - ordered = false; - } else { - ordered = true; - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if (!decimal(character)) { - break; - } - - queue += character; - index++; - } - - character = value.charAt(index); - - if (!queue || markers[character] !== true) { - return; - } - - start = parseInt(queue, 10); - marker = character; - } - - character = value.charAt(++index); - - if (character !== C_SPACE && character !== C_TAB) { - return; - } - - if (silent) { - return true; - } - - index = 0; - items = []; - allLines = []; - emptyLines = []; - - while (index < length) { - nextIndex = value.indexOf(C_NEWLINE, index); - startIndex = index; - prefixed = false; - indented = false; - - if (nextIndex === -1) { - nextIndex = length; - } - - end = index + TAB_SIZE; - size = 0; - - while (index < length) { - character = value.charAt(index); - - if (character === C_TAB) { - size += TAB_SIZE - (size % TAB_SIZE); - } else if (character === C_SPACE) { - size++; - } else { - break; - } - - index++; - } - - if (size >= TAB_SIZE) { - indented = true; - } - - if (item && size >= item.indent) { - indented = true; - } - - character = value.charAt(index); - currentMarker = null; - - if (!indented) { - if (LIST_UNORDERED_MARKERS[character] === true) { - currentMarker = character; - index++; - size++; - } else { - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if (!decimal(character)) { - break; - } - - queue += character; - index++; - } - - character = value.charAt(index); - index++; - - if (queue && markers[character] === true) { - currentMarker = character; - size += queue.length + 1; - } - } - - if (currentMarker) { - character = value.charAt(index); - - if (character === C_TAB) { - size += TAB_SIZE - (size % TAB_SIZE); - index++; - } else if (character === C_SPACE) { - end = index + TAB_SIZE; - - while (index < end) { - if (value.charAt(index) !== C_SPACE) { - break; - } - - index++; - size++; - } - - if (index === end && value.charAt(index) === C_SPACE) { - index -= TAB_SIZE - 1; - size -= TAB_SIZE - 1; - } - } else if (character !== C_NEWLINE && character !== '') { - currentMarker = null; - } - } - } - - if (currentMarker) { - if (!pedantic && marker !== currentMarker) { - break; - } - - prefixed = true; - } else { - if (!commonmark && !indented && value.charAt(startIndex) === C_SPACE) { - indented = true; - } else if (commonmark && item) { - indented = size >= item.indent || size > TAB_SIZE; - } - - prefixed = false; - index = startIndex; - } - - line = value.slice(startIndex, nextIndex); - content = startIndex === index ? line : value.slice(index, nextIndex); - - if ( - currentMarker === C_ASTERISK || - currentMarker === C_UNDERSCORE || - currentMarker === C_DASH - ) { - if (tokenizers.thematicBreak.call(self, eat, line, true)) { - break; - } - } - - prevEmpty = empty; - empty = !trim(content).length; - - if (indented && item) { - item.value = item.value.concat(emptyLines, line); - allLines = allLines.concat(emptyLines, line); - emptyLines = []; - } else if (prefixed) { - if (emptyLines.length !== 0) { - item.value.push(''); - item.trail = emptyLines.concat(); - } - - item = { - value: [line], - indent: size, - trail: [] - }; - - items.push(item); - allLines = allLines.concat(emptyLines, line); - emptyLines = []; - } else if (empty) { - if (prevEmpty) { - break; - } - - emptyLines.push(line); - } else { - if (prevEmpty) { - break; - } - - if (interrupt(interuptors, tokenizers, self, [eat, line, true])) { - break; - } - - item.value = item.value.concat(emptyLines, line); - allLines = allLines.concat(emptyLines, line); - emptyLines = []; - } - - index = nextIndex + 1; - } - - node = eat(allLines.join(C_NEWLINE)).reset({ - type: 'list', - ordered: ordered, - start: start, - loose: null, - children: [] - }); - - enterTop = self.enterList(); - exitBlockquote = self.enterBlock(); - isLoose = false; - index = -1; - length = items.length; - - while (++index < length) { - item = items[index].value.join(C_NEWLINE); - now = eat.now(); - - item = eat(item)(listItem(self, item, now), node); - - if (item.loose) { - isLoose = true; - } - - item = items[index].trail.join(C_NEWLINE); - - if (index !== length - 1) { - item += C_NEWLINE; - } - - eat(item); - } - - enterTop(); - exitBlockquote(); - - node.loose = isLoose; - - return node; -} - -function listItem(ctx, value, position) { - var offsets = ctx.offset; - var fn = ctx.options.pedantic ? pedanticListItem : normalListItem; - var checked = null; - var task; - var indent; - - value = fn.apply(null, arguments); - - if (ctx.options.gfm) { - task = value.match(EXPRESSION_TASK_ITEM); - - if (task) { - indent = task[0].length; - checked = task[1].toLowerCase() === C_X_LOWER; - offsets[position.line] += indent; - value = value.slice(indent); - } - } - - return { - type: 'listItem', - loose: EXPRESSION_LOOSE_LIST_ITEM.test(value) || - value.charAt(value.length - 1) === C_NEWLINE, - checked: checked, - children: ctx.tokenizeBlock(value, position) - }; -} - -/* Create a list-item using overly simple mechanics. */ -function pedanticListItem(ctx, value, position) { - var offsets = ctx.offset; - var line = position.line; - - /* Remove the list-item’s bullet. */ - value = value.replace(EXPRESSION_PEDANTIC_BULLET, replacer); - - /* The initial line was also matched by the below, so - * we reset the `line`. */ - line = position.line; - - return value.replace(EXPRESSION_INITIAL_INDENT, replacer); - - /* A simple replacer which removed all matches, - * and adds their length to `offset`. */ - function replacer($0) { - offsets[line] = (offsets[line] || 0) + $0.length; - line++; - - return ''; - } -} - -/* Create a list-item using sane mechanics. */ -function normalListItem(ctx, value, position) { - var offsets = ctx.offset; - var line = position.line; - var max; - var bullet; - var rest; - var lines; - var trimmedLines; - var index; - var length; - - /* Remove the list-item’s bullet. */ - value = value.replace(EXPRESSION_BULLET, replacer); - - lines = value.split(C_NEWLINE); - - trimmedLines = removeIndent(value, getIndent(max).indent).split(C_NEWLINE); - - /* We replaced the initial bullet with something - * else above, which was used to trick - * `removeIndentation` into removing some more - * characters when possible. However, that could - * result in the initial line to be stripped more - * than it should be. */ - trimmedLines[0] = rest; - - offsets[line] = (offsets[line] || 0) + bullet.length; - line++; - - index = 0; - length = lines.length; - - while (++index < length) { - offsets[line] = (offsets[line] || 0) + - lines[index].length - trimmedLines[index].length; - line++; - } - - return trimmedLines.join(C_NEWLINE); - - function replacer($0, $1, $2, $3, $4) { - bullet = $1 + $2 + $3; - rest = $4; - - /* Make sure that the first nine numbered list items - * can indent with an extra space. That is, when - * the bullet did not receive an extra final space. */ - if (Number($2) < 10 && bullet.length % 2 === 1) { - $2 = C_SPACE + $2; - } - - max = $1 + repeat(C_SPACE, $2.length) + $3; - - return max + rest; - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/newline.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/newline.js deleted file mode 100644 index 6008670cc5e742..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/newline.js +++ /dev/null @@ -1,47 +0,0 @@ -'use strict'; - -var whitespace = require('is-whitespace-character'); - -module.exports = newline; - -/* Tokenise newline. */ -function newline(eat, value, silent) { - var character = value.charAt(0); - var length; - var subvalue; - var queue; - var index; - - if (character !== '\n') { - return; - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - index = 1; - length = value.length; - subvalue = character; - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if (!whitespace(character)) { - break; - } - - queue += character; - - if (character === '\n') { - subvalue += queue; - queue = ''; - } - - index++; - } - - eat(subvalue); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/paragraph.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/paragraph.js deleted file mode 100644 index 1492a027e78237..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/paragraph.js +++ /dev/null @@ -1,122 +0,0 @@ -'use strict'; - -var trim = require('trim'); -var decimal = require('is-decimal'); -var trimTrailingLines = require('trim-trailing-lines'); -var interrupt = require('../util/interrupt'); - -module.exports = paragraph; - -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_SPACE = ' '; - -var TAB_SIZE = 4; - -/* Tokenise paragraph. */ -function paragraph(eat, value, silent) { - var self = this; - var settings = self.options; - var commonmark = settings.commonmark; - var gfm = settings.gfm; - var tokenizers = self.blockTokenizers; - var interruptors = self.interruptParagraph; - var index = value.indexOf(C_NEWLINE); - var length = value.length; - var position; - var subvalue; - var character; - var size; - var now; - - while (index < length) { - /* Eat everything if there’s no following newline. */ - if (index === -1) { - index = length; - break; - } - - /* Stop if the next character is NEWLINE. */ - if (value.charAt(index + 1) === C_NEWLINE) { - break; - } - - /* In commonmark-mode, following indented lines - * are part of the paragraph. */ - if (commonmark) { - size = 0; - position = index + 1; - - while (position < length) { - character = value.charAt(position); - - if (character === C_TAB) { - size = TAB_SIZE; - break; - } else if (character === C_SPACE) { - size++; - } else { - break; - } - - position++; - } - - if (size >= TAB_SIZE) { - index = value.indexOf(C_NEWLINE, index + 1); - continue; - } - } - - subvalue = value.slice(index + 1); - - /* Check if the following code contains a possible - * block. */ - if (interrupt(interruptors, tokenizers, self, [eat, subvalue, true])) { - break; - } - - /* Break if the following line starts a list, when - * already in a list, or when in commonmark, or when - * in gfm mode and the bullet is *not* numeric. */ - if ( - tokenizers.list.call(self, eat, subvalue, true) && - ( - self.inList || - commonmark || - (gfm && !decimal(trim.left(subvalue).charAt(0))) - ) - ) { - break; - } - - position = index; - index = value.indexOf(C_NEWLINE, index + 1); - - if (index !== -1 && trim(value.slice(position, index)) === '') { - index = position; - break; - } - } - - subvalue = value.slice(0, index); - - if (trim(subvalue) === '') { - eat(subvalue); - - return null; - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - now = eat.now(); - subvalue = trimTrailingLines(subvalue); - - return eat(subvalue)({ - type: 'paragraph', - children: self.tokenizeInline(subvalue, now) - }); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/reference.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/reference.js deleted file mode 100644 index 50713f1ccfc8fa..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/reference.js +++ /dev/null @@ -1,206 +0,0 @@ -'use strict'; - -var whitespace = require('is-whitespace-character'); -var locate = require('../locate/link'); -var normalize = require('../util/normalize'); - -module.exports = reference; -reference.locator = locate; - -var T_LINK = 'link'; -var T_IMAGE = 'image'; -var T_FOOTNOTE = 'footnote'; -var REFERENCE_TYPE_SHORTCUT = 'shortcut'; -var REFERENCE_TYPE_COLLAPSED = 'collapsed'; -var REFERENCE_TYPE_FULL = 'full'; -var C_CARET = '^'; -var C_BACKSLASH = '\\'; -var C_BRACKET_OPEN = '['; -var C_BRACKET_CLOSE = ']'; - -function reference(eat, value, silent) { - var self = this; - var character = value.charAt(0); - var index = 0; - var length = value.length; - var subvalue = ''; - var intro = ''; - var type = T_LINK; - var referenceType = REFERENCE_TYPE_SHORTCUT; - var content; - var identifier; - var now; - var node; - var exit; - var queue; - var bracketed; - var depth; - - /* Check whether we’re eating an image. */ - if (character === '!') { - type = T_IMAGE; - intro = character; - character = value.charAt(++index); - } - - if (character !== C_BRACKET_OPEN) { - return; - } - - index++; - intro += character; - queue = ''; - - /* Check whether we’re eating a footnote. */ - if (self.options.footnotes && value.charAt(index) === C_CARET) { - /* Exit if `![^` is found, so the `!` will be seen as text after this, - * and we’ll enter this function again when `[^` is found. */ - if (type === T_IMAGE) { - return; - } - - intro += C_CARET; - index++; - type = T_FOOTNOTE; - } - - /* Eat the text. */ - depth = 0; - - while (index < length) { - character = value.charAt(index); - - if (character === C_BRACKET_OPEN) { - bracketed = true; - depth++; - } else if (character === C_BRACKET_CLOSE) { - if (!depth) { - break; - } - - depth--; - } - - if (character === C_BACKSLASH) { - queue += C_BACKSLASH; - character = value.charAt(++index); - } - - queue += character; - index++; - } - - subvalue = queue; - content = queue; - character = value.charAt(index); - - if (character !== C_BRACKET_CLOSE) { - return; - } - - index++; - subvalue += character; - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if (!whitespace(character)) { - break; - } - - queue += character; - index++; - } - - character = value.charAt(index); - - /* Inline footnotes cannot have an identifier. */ - if (type !== T_FOOTNOTE && character === C_BRACKET_OPEN) { - identifier = ''; - queue += character; - index++; - - while (index < length) { - character = value.charAt(index); - - if (character === C_BRACKET_OPEN || character === C_BRACKET_CLOSE) { - break; - } - - if (character === C_BACKSLASH) { - identifier += C_BACKSLASH; - character = value.charAt(++index); - } - - identifier += character; - index++; - } - - character = value.charAt(index); - - if (character === C_BRACKET_CLOSE) { - referenceType = identifier ? REFERENCE_TYPE_FULL : REFERENCE_TYPE_COLLAPSED; - queue += identifier + character; - index++; - } else { - identifier = ''; - } - - subvalue += queue; - queue = ''; - } else { - if (!content) { - return; - } - - identifier = content; - } - - /* Brackets cannot be inside the identifier. */ - if (referenceType !== REFERENCE_TYPE_FULL && bracketed) { - return; - } - - subvalue = intro + subvalue; - - if (type === T_LINK && self.inLink) { - return null; - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - if (type === T_FOOTNOTE && content.indexOf(' ') !== -1) { - return eat(subvalue)({ - type: 'footnote', - children: this.tokenizeInline(content, eat.now()) - }); - } - - now = eat.now(); - now.column += intro.length; - now.offset += intro.length; - identifier = referenceType === REFERENCE_TYPE_FULL ? identifier : content; - - node = { - type: type + 'Reference', - identifier: normalize(identifier) - }; - - if (type === T_LINK || type === T_IMAGE) { - node.referenceType = referenceType; - } - - if (type === T_LINK) { - exit = self.enterLink(); - node.children = self.tokenizeInline(content, now); - exit(); - } else if (type === T_IMAGE) { - node.alt = self.decode.raw(self.unescape(content), now) || null; - } - - return eat(subvalue)(node); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/strong.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/strong.js deleted file mode 100644 index 12d5785bc64a74..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/strong.js +++ /dev/null @@ -1,84 +0,0 @@ -'use strict'; - -var trim = require('trim'); -var whitespace = require('is-whitespace-character'); -var locate = require('../locate/strong'); - -module.exports = strong; -strong.locator = locate; - -var C_ASTERISK = '*'; -var C_UNDERSCORE = '_'; - -function strong(eat, value, silent) { - var self = this; - var index = 0; - var character = value.charAt(index); - var now; - var pedantic; - var marker; - var queue; - var subvalue; - var length; - var prev; - - if ( - (character !== C_ASTERISK && character !== C_UNDERSCORE) || - value.charAt(++index) !== character - ) { - return; - } - - pedantic = self.options.pedantic; - marker = character; - subvalue = marker + marker; - length = value.length; - index++; - queue = ''; - character = ''; - - if (pedantic && whitespace(value.charAt(index))) { - return; - } - - while (index < length) { - prev = character; - character = value.charAt(index); - - if ( - character === marker && - value.charAt(index + 1) === marker && - (!pedantic || !whitespace(prev)) - ) { - character = value.charAt(index + 2); - - if (character !== marker) { - if (!trim(queue)) { - return; - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - now = eat.now(); - now.column += 2; - now.offset += 2; - - return eat(subvalue + queue + subvalue)({ - type: 'strong', - children: self.tokenizeInline(queue, now) - }); - } - } - - if (!pedantic && character === '\\') { - queue += character; - character = value.charAt(++index); - } - - queue += character; - index++; - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/table.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/table.js deleted file mode 100644 index ce93b1d22f0f31..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/table.js +++ /dev/null @@ -1,266 +0,0 @@ -'use strict'; - -var whitespace = require('is-whitespace-character'); - -module.exports = table; - -var C_BACKSLASH = '\\'; -var C_TICK = '`'; -var C_DASH = '-'; -var C_PIPE = '|'; -var C_COLON = ':'; -var C_SPACE = ' '; -var C_NEWLINE = '\n'; -var C_TAB = '\t'; - -var MIN_TABLE_COLUMNS = 1; -var MIN_TABLE_ROWS = 2; - -var TABLE_ALIGN_LEFT = 'left'; -var TABLE_ALIGN_CENTER = 'center'; -var TABLE_ALIGN_RIGHT = 'right'; -var TABLE_ALIGN_NONE = null; - -function table(eat, value, silent) { - var self = this; - var index; - var alignments; - var alignment; - var subvalue; - var row; - var length; - var lines; - var queue; - var character; - var hasDash; - var align; - var cell; - var preamble; - var count; - var opening; - var now; - var position; - var lineCount; - var line; - var rows; - var table; - var lineIndex; - var pipeIndex; - var first; - - /* Exit when not in gfm-mode. */ - if (!self.options.gfm) { - return; - } - - /* Get the rows. - * Detecting tables soon is hard, so there are some - * checks for performance here, such as the minimum - * number of rows, and allowed characters in the - * alignment row. */ - index = 0; - lineCount = 0; - length = value.length + 1; - lines = []; - - while (index < length) { - lineIndex = value.indexOf(C_NEWLINE, index); - pipeIndex = value.indexOf(C_PIPE, index + 1); - - if (lineIndex === -1) { - lineIndex = value.length; - } - - if (pipeIndex === -1 || pipeIndex > lineIndex) { - if (lineCount < MIN_TABLE_ROWS) { - return; - } - - break; - } - - lines.push(value.slice(index, lineIndex)); - lineCount++; - index = lineIndex + 1; - } - - /* Parse the alignment row. */ - subvalue = lines.join(C_NEWLINE); - alignments = lines.splice(1, 1)[0] || []; - index = 0; - length = alignments.length; - lineCount--; - alignment = false; - align = []; - - while (index < length) { - character = alignments.charAt(index); - - if (character === C_PIPE) { - hasDash = null; - - if (alignment === false) { - if (first === false) { - return; - } - } else { - align.push(alignment); - alignment = false; - } - - first = false; - } else if (character === C_DASH) { - hasDash = true; - alignment = alignment || TABLE_ALIGN_NONE; - } else if (character === C_COLON) { - if (alignment === TABLE_ALIGN_LEFT) { - alignment = TABLE_ALIGN_CENTER; - } else if (hasDash && alignment === TABLE_ALIGN_NONE) { - alignment = TABLE_ALIGN_RIGHT; - } else { - alignment = TABLE_ALIGN_LEFT; - } - } else if (!whitespace(character)) { - return; - } - - index++; - } - - if (alignment !== false) { - align.push(alignment); - } - - /* Exit when without enough columns. */ - if (align.length < MIN_TABLE_COLUMNS) { - return; - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - /* Parse the rows. */ - position = -1; - rows = []; - - table = eat(subvalue).reset({ - type: 'table', - align: align, - children: rows - }); - - while (++position < lineCount) { - line = lines[position]; - row = {type: 'tableRow', children: []}; - - /* Eat a newline character when this is not the - * first row. */ - if (position) { - eat(C_NEWLINE); - } - - /* Eat the row. */ - eat(line).reset(row, table); - - length = line.length + 1; - index = 0; - queue = ''; - cell = ''; - preamble = true; - count = null; - opening = null; - - while (index < length) { - character = line.charAt(index); - - if (character === C_TAB || character === C_SPACE) { - if (cell) { - queue += character; - } else { - eat(character); - } - - index++; - continue; - } - - if (character === '' || character === C_PIPE) { - if (preamble) { - eat(character); - } else { - if (character && opening) { - queue += character; - index++; - continue; - } - - if ((cell || character) && !preamble) { - subvalue = cell; - - if (queue.length > 1) { - if (character) { - subvalue += queue.slice(0, queue.length - 1); - queue = queue.charAt(queue.length - 1); - } else { - subvalue += queue; - queue = ''; - } - } - - now = eat.now(); - - eat(subvalue)({ - type: 'tableCell', - children: self.tokenizeInline(cell, now) - }, row); - } - - eat(queue + character); - - queue = ''; - cell = ''; - } - } else { - if (queue) { - cell += queue; - queue = ''; - } - - cell += character; - - if (character === C_BACKSLASH && index !== length - 2) { - cell += line.charAt(index + 1); - index++; - } - - if (character === C_TICK) { - count = 1; - - while (line.charAt(index + 1) === character) { - cell += character; - index++; - count++; - } - - if (!opening) { - opening = count; - } else if (count >= opening) { - opening = 0; - } - } - } - - preamble = false; - index++; - } - - /* Eat the alignment row. */ - if (!position) { - eat(C_NEWLINE + alignments); - } - } - - return table; -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/text.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/text.js deleted file mode 100644 index 4aedfa90d5d9b8..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/text.js +++ /dev/null @@ -1,58 +0,0 @@ -'use strict'; - -module.exports = text; - -function text(eat, value, silent) { - var self = this; - var methods; - var tokenizers; - var index; - var length; - var subvalue; - var position; - var tokenizer; - var name; - var min; - var now; - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - methods = self.inlineMethods; - length = methods.length; - tokenizers = self.inlineTokenizers; - index = -1; - min = value.length; - - while (++index < length) { - name = methods[index]; - - if (name === 'text' || !tokenizers[name]) { - continue; - } - - tokenizer = tokenizers[name].locator; - - if (!tokenizer) { - eat.file.fail('Missing locator: `' + name + '`'); - } - - position = tokenizer.call(self, value, 1); - - if (position !== -1 && position < min) { - min = position; - } - } - - subvalue = value.slice(0, min); - now = eat.now(); - - self.decode(subvalue, now, function (content, position, source) { - eat(source || content)({ - type: 'text', - value: content - }); - }); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/thematic-break.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/thematic-break.js deleted file mode 100644 index 2391e3f592cb25..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/thematic-break.js +++ /dev/null @@ -1,70 +0,0 @@ -'use strict'; - -module.exports = thematicBreak; - -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_SPACE = ' '; -var C_ASTERISK = '*'; -var C_UNDERSCORE = '_'; -var C_DASH = '-'; - -var THEMATIC_BREAK_MARKER_COUNT = 3; - -function thematicBreak(eat, value, silent) { - var index = -1; - var length = value.length + 1; - var subvalue = ''; - var character; - var marker; - var markerCount; - var queue; - - while (++index < length) { - character = value.charAt(index); - - if (character !== C_TAB && character !== C_SPACE) { - break; - } - - subvalue += character; - } - - if ( - character !== C_ASTERISK && - character !== C_DASH && - character !== C_UNDERSCORE - ) { - return; - } - - marker = character; - subvalue += character; - markerCount = 1; - queue = ''; - - while (++index < length) { - character = value.charAt(index); - - if (character === marker) { - markerCount++; - subvalue += queue + marker; - queue = ''; - } else if (character === C_SPACE) { - queue += character; - } else if ( - markerCount >= THEMATIC_BREAK_MARKER_COUNT && - (!character || character === C_NEWLINE) - ) { - subvalue += queue; - - if (silent) { - return true; - } - - return eat(subvalue)({type: 'thematicBreak'}); - } else { - return; - } - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/url.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/url.js deleted file mode 100644 index 297940bf4ab922..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenize/url.js +++ /dev/null @@ -1,144 +0,0 @@ -'use strict'; - -var decode = require('parse-entities'); -var whitespace = require('is-whitespace-character'); -var locate = require('../locate/url'); - -module.exports = url; -url.locator = locate; -url.notInLink = true; - -var C_BRACKET_OPEN = '['; -var C_BRACKET_CLOSE = ']'; -var C_PAREN_OPEN = '('; -var C_PAREN_CLOSE = ')'; -var C_LT = '<'; -var C_AT_SIGN = '@'; - -var HTTP_PROTOCOL = 'http://'; -var HTTPS_PROTOCOL = 'https://'; -var MAILTO_PROTOCOL = 'mailto:'; - -var PROTOCOLS = [ - HTTP_PROTOCOL, - HTTPS_PROTOCOL, - MAILTO_PROTOCOL -]; - -var PROTOCOLS_LENGTH = PROTOCOLS.length; - -function url(eat, value, silent) { - var self = this; - var subvalue; - var content; - var character; - var index; - var position; - var protocol; - var match; - var length; - var queue; - var parenCount; - var nextCharacter; - var exit; - - if (!self.options.gfm) { - return; - } - - subvalue = ''; - index = -1; - length = PROTOCOLS_LENGTH; - - while (++index < length) { - protocol = PROTOCOLS[index]; - match = value.slice(0, protocol.length); - - if (match.toLowerCase() === protocol) { - subvalue = match; - break; - } - } - - if (!subvalue) { - return; - } - - index = subvalue.length; - length = value.length; - queue = ''; - parenCount = 0; - - while (index < length) { - character = value.charAt(index); - - if (whitespace(character) || character === C_LT) { - break; - } - - if ( - character === '.' || - character === ',' || - character === ':' || - character === ';' || - character === '"' || - character === '\'' || - character === ')' || - character === ']' - ) { - nextCharacter = value.charAt(index + 1); - - if (!nextCharacter || whitespace(nextCharacter)) { - break; - } - } - - if (character === C_PAREN_OPEN || character === C_BRACKET_OPEN) { - parenCount++; - } - - if (character === C_PAREN_CLOSE || character === C_BRACKET_CLOSE) { - parenCount--; - - if (parenCount < 0) { - break; - } - } - - queue += character; - index++; - } - - if (!queue) { - return; - } - - subvalue += queue; - content = subvalue; - - if (protocol === MAILTO_PROTOCOL) { - position = queue.indexOf(C_AT_SIGN); - - if (position === -1 || position === length - 1) { - return; - } - - content = content.substr(MAILTO_PROTOCOL.length); - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - exit = self.enterLink(); - content = self.tokenizeInline(content, eat.now()); - exit(); - - return eat(subvalue)({ - type: 'link', - title: null, - url: decode(subvalue, {nonTerminated: false}), - children: content - }); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenizer.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenizer.js deleted file mode 100644 index 498ef22ad949af..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/tokenizer.js +++ /dev/null @@ -1,331 +0,0 @@ -'use strict'; - -module.exports = factory; - -var MERGEABLE_NODES = { - text: mergeText, - blockquote: mergeBlockquote -}; - -/* Check whether a node is mergeable with adjacent nodes. */ -function mergeable(node) { - var start; - var end; - - if (node.type !== 'text' || !node.position) { - return true; - } - - start = node.position.start; - end = node.position.end; - - /* Only merge nodes which occupy the same size as their - * `value`. */ - return start.line !== end.line || - end.column - start.column === node.value.length; -} - -/* Merge two text nodes: `node` into `prev`. */ -function mergeText(prev, node) { - prev.value += node.value; - - return prev; -} - -/* Merge two blockquotes: `node` into `prev`, unless in - * CommonMark mode. */ -function mergeBlockquote(prev, node) { - if (this.options.commonmark) { - return node; - } - - prev.children = prev.children.concat(node.children); - - return prev; -} - -/* Construct a tokenizer. This creates both - * `tokenizeInline` and `tokenizeBlock`. */ -function factory(type) { - return tokenize; - - /* Tokenizer for a bound `type`. */ - function tokenize(value, location) { - var self = this; - var offset = self.offset; - var tokens = []; - var methods = self[type + 'Methods']; - var tokenizers = self[type + 'Tokenizers']; - var line = location.line; - var column = location.column; - var index; - var length; - var method; - var name; - var matched; - var valueLength; - - /* Trim white space only lines. */ - if (!value) { - return tokens; - } - - /* Expose on `eat`. */ - eat.now = now; - eat.file = self.file; - - /* Sync initial offset. */ - updatePosition(''); - - /* Iterate over `value`, and iterate over all - * tokenizers. When one eats something, re-iterate - * with the remaining value. If no tokenizer eats, - * something failed (should not happen) and an - * exception is thrown. */ - while (value) { - index = -1; - length = methods.length; - matched = false; - - while (++index < length) { - name = methods[index]; - method = tokenizers[name]; - - if ( - method && - /* istanbul ignore next */ (!method.onlyAtStart || self.atStart) && - (!method.notInList || !self.inList) && - (!method.notInBlock || !self.inBlock) && - (!method.notInLink || !self.inLink) - ) { - valueLength = value.length; - - method.apply(self, [eat, value]); - - matched = valueLength !== value.length; - - if (matched) { - break; - } - } - } - - /* istanbul ignore if */ - if (!matched) { - self.file.fail(new Error('Infinite loop'), eat.now()); - } - } - - self.eof = now(); - - return tokens; - - /* Update line, column, and offset based on - * `value`. */ - function updatePosition(subvalue) { - var lastIndex = -1; - var index = subvalue.indexOf('\n'); - - while (index !== -1) { - line++; - lastIndex = index; - index = subvalue.indexOf('\n', index + 1); - } - - if (lastIndex === -1) { - column += subvalue.length; - } else { - column = subvalue.length - lastIndex; - } - - if (line in offset) { - if (lastIndex !== -1) { - column += offset[line]; - } else if (column <= offset[line]) { - column = offset[line] + 1; - } - } - } - - /* Get offset. Called before the first character is - * eaten to retrieve the range's offsets. */ - function getOffset() { - var indentation = []; - var pos = line + 1; - - /* Done. Called when the last character is - * eaten to retrieve the range’s offsets. */ - return function () { - var last = line + 1; - - while (pos < last) { - indentation.push((offset[pos] || 0) + 1); - - pos++; - } - - return indentation; - }; - } - - /* Get the current position. */ - function now() { - var pos = {line: line, column: column}; - - pos.offset = self.toOffset(pos); - - return pos; - } - - /* Store position information for a node. */ - function Position(start) { - this.start = start; - this.end = now(); - } - - /* Throw when a value is incorrectly eaten. - * This shouldn’t happen but will throw on new, - * incorrect rules. */ - function validateEat(subvalue) { - /* istanbul ignore if */ - if (value.substring(0, subvalue.length) !== subvalue) { - /* Capture stack-trace. */ - self.file.fail( - new Error( - 'Incorrectly eaten value: please report this ' + - 'warning on http://git.io/vg5Ft' - ), - now() - ); - } - } - - /* Mark position and patch `node.position`. */ - function position() { - var before = now(); - - return update; - - /* Add the position to a node. */ - function update(node, indent) { - var prev = node.position; - var start = prev ? prev.start : before; - var combined = []; - var n = prev && prev.end.line; - var l = before.line; - - node.position = new Position(start); - - /* If there was already a `position`, this - * node was merged. Fixing `start` wasn’t - * hard, but the indent is different. - * Especially because some information, the - * indent between `n` and `l` wasn’t - * tracked. Luckily, that space is - * (should be?) empty, so we can safely - * check for it now. */ - if (prev && indent && prev.indent) { - combined = prev.indent; - - if (n < l) { - while (++n < l) { - combined.push((offset[n] || 0) + 1); - } - - combined.push(before.column); - } - - indent = combined.concat(indent); - } - - node.position.indent = indent || []; - - return node; - } - } - - /* Add `node` to `parent`s children or to `tokens`. - * Performs merges where possible. */ - function add(node, parent) { - var children = parent ? parent.children : tokens; - var prev = children[children.length - 1]; - - if ( - prev && - node.type === prev.type && - node.type in MERGEABLE_NODES && - mergeable(prev) && - mergeable(node) - ) { - node = MERGEABLE_NODES[node.type].call(self, prev, node); - } - - if (node !== prev) { - children.push(node); - } - - if (self.atStart && tokens.length !== 0) { - self.exitStart(); - } - - return node; - } - - /* Remove `subvalue` from `value`. - * `subvalue` must be at the start of `value`. */ - function eat(subvalue) { - var indent = getOffset(); - var pos = position(); - var current = now(); - - validateEat(subvalue); - - apply.reset = reset; - reset.test = test; - apply.test = test; - - value = value.substring(subvalue.length); - - updatePosition(subvalue); - - indent = indent(); - - return apply; - - /* Add the given arguments, add `position` to - * the returned node, and return the node. */ - function apply(node, parent) { - return pos(add(pos(node), parent), indent); - } - - /* Functions just like apply, but resets the - * content: the line and column are reversed, - * and the eaten value is re-added. - * This is useful for nodes with a single - * type of content, such as lists and tables. - * See `apply` above for what parameters are - * expected. */ - function reset() { - var node = apply.apply(null, arguments); - - line = current.line; - column = current.column; - value = subvalue + value; - - return node; - } - - /* Test the position, after eating, and reverse - * to a not-eaten state. */ - function test() { - var result = pos({}); - - line = current.line; - column = current.column; - value = subvalue + value; - - return result.position; - } - } - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/unescape.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/unescape.js deleted file mode 100644 index 321900e7eacd73..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/unescape.js +++ /dev/null @@ -1,37 +0,0 @@ -'use strict'; - -module.exports = factory; - -/* Factory to de-escape a value, based on a list at `key` - * in `ctx`. */ -function factory(ctx, key) { - return unescape; - - /* De-escape a string using the expression at `key` - * in `ctx`. */ - function unescape(value) { - var prev = 0; - var index = value.indexOf('\\'); - var escape = ctx[key]; - var queue = []; - var character; - - while (index !== -1) { - queue.push(value.slice(prev, index)); - prev = index + 1; - character = value.charAt(prev); - - /* If the following character is not a valid escape, - * add the slash. */ - if (!character || escape.indexOf(character) === -1) { - queue.push('\\'); - } - - index = value.indexOf('\\', prev); - } - - queue.push(value.slice(prev)); - - return queue.join(''); - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/util/get-indentation.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/util/get-indentation.js deleted file mode 100644 index 3e09e1411ed67c..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/util/get-indentation.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict'; - -module.exports = indentation; - -/* Map of characters, and their column length, - * which can be used as indentation. */ -var characters = {' ': 1, '\t': 4}; - -/* Gets indentation information for a line. */ -function indentation(value) { - var index = 0; - var indent = 0; - var character = value.charAt(index); - var stops = {}; - var size; - - while (character in characters) { - size = characters[character]; - - indent += size; - - if (size > 1) { - indent = Math.floor(indent / size) * size; - } - - stops[indent] = index; - - character = value.charAt(++index); - } - - return {indent: indent, stops: stops}; -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/util/html.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/util/html.js deleted file mode 100644 index 5f211f13f8f534..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/util/html.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict'; - -var attributeName = '[a-zA-Z_:][a-zA-Z0-9:._-]*'; -var unquoted = '[^"\'=<>`\\u0000-\\u0020]+'; -var singleQuoted = '\'[^\']*\''; -var doubleQuoted = '"[^"]*"'; -var attributeValue = '(?:' + unquoted + '|' + singleQuoted + '|' + doubleQuoted + ')'; -var attribute = '(?:\\s+' + attributeName + '(?:\\s*=\\s*' + attributeValue + ')?)'; -var openTag = '<[A-Za-z][A-Za-z0-9\\-]*' + attribute + '*\\s*\\/?>'; -var closeTag = '<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>'; -var comment = '|'; -var processing = '<[?].*?[?]>'; -var declaration = ']*>'; -var cdata = ''; - -exports.openCloseTag = new RegExp('^(?:' + openTag + '|' + closeTag + ')'); - -exports.tag = new RegExp('^(?:' + - openTag + '|' + - closeTag + '|' + - comment + '|' + - processing + '|' + - declaration + '|' + - cdata + -')'); diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/util/interrupt.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/util/interrupt.js deleted file mode 100644 index e3178ab45c60df..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/util/interrupt.js +++ /dev/null @@ -1,43 +0,0 @@ -'use strict'; - -module.exports = interrupt; - -function interrupt(interruptors, tokenizers, ctx, params) { - var bools = ['pedantic', 'commonmark']; - var count = bools.length; - var length = interruptors.length; - var index = -1; - var interruptor; - var config; - var fn; - var offset; - var bool; - var ignore; - - while (++index < length) { - interruptor = interruptors[index]; - config = interruptor[1] || {}; - fn = interruptor[0]; - offset = -1; - ignore = false; - - while (++offset < count) { - bool = bools[offset]; - - if (config[bool] !== undefined && config[bool] !== ctx.options[bool]) { - ignore = true; - break; - } - } - - if (ignore) { - continue; - } - - if (tokenizers[fn].apply(ctx, params)) { - return true; - } - } - - return false; -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/util/normalize.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/util/normalize.js deleted file mode 100644 index 846ceeecac5ade..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/util/normalize.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; - -var collapseWhiteSpace = require('collapse-white-space'); - -module.exports = normalize; - -/* Normalize an identifier. Collapses multiple white space - * characters into a single space, and removes casing. */ -function normalize(value) { - return collapseWhiteSpace(value).toLowerCase(); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/util/remove-indentation.js b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/util/remove-indentation.js deleted file mode 100644 index 20f18be74087eb..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/lib/util/remove-indentation.js +++ /dev/null @@ -1,78 +0,0 @@ -'use strict'; - -var trim = require('trim'); -var repeat = require('repeat-string'); -var getIndent = require('./get-indentation'); - -module.exports = indentation; - -var C_SPACE = ' '; -var C_NEWLINE = '\n'; -var C_TAB = '\t'; - -/* Remove the minimum indent from every line in `value`. - * Supports both tab, spaced, and mixed indentation (as - * well as possible). */ -function indentation(value, maximum) { - var values = value.split(C_NEWLINE); - var position = values.length + 1; - var minIndent = Infinity; - var matrix = []; - var index; - var indentation; - var stops; - var padding; - - values.unshift(repeat(C_SPACE, maximum) + '!'); - - while (position--) { - indentation = getIndent(values[position]); - - matrix[position] = indentation.stops; - - if (trim(values[position]).length === 0) { - continue; - } - - if (indentation.indent) { - if (indentation.indent > 0 && indentation.indent < minIndent) { - minIndent = indentation.indent; - } - } else { - minIndent = Infinity; - - break; - } - } - - if (minIndent !== Infinity) { - position = values.length; - - while (position--) { - stops = matrix[position]; - index = minIndent; - - while (index && !(index in stops)) { - index--; - } - - if ( - trim(values[position]).length !== 0 && - minIndent && - index !== minIndent - ) { - padding = C_TAB; - } else { - padding = ''; - } - - values[position] = padding + values[position].slice( - index in stops ? stops[index] + 1 : 0 - ); - } - } - - values.shift(); - - return values.join(C_NEWLINE); -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/package.json deleted file mode 100644 index 822420cb25200a..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/package.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "remark-parse", - "version": "5.0.0", - "description": "Markdown parser for remark", - "license": "MIT", - "keywords": [ - "markdown", - "abstract", - "syntax", - "tree", - "ast", - "parse" - ], - "homepage": "http://remark.js.org", - "repository": "https://github.com/remarkjs/remark/tree/master/packages/remark-parse", - "bugs": "https://github.com/remarkjs/remark/issues", - "author": "Titus Wormer (http://wooorm.com)", - "contributors": [ - "Titus Wormer (http://wooorm.com)", - "Eugene Sharygin " - ], - "files": [ - "index.js", - "lib" - ], - "dependencies": { - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^1.1.0", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^1.0.0", - "vfile-location": "^2.0.0", - "xtend": "^4.0.1" - }, - "xo": false -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/readme.md deleted file mode 100644 index ecaa6c093c0ab2..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/remark-parse/readme.md +++ /dev/null @@ -1,453 +0,0 @@ -# remark-parse [![Build Status][build-badge]][build-status] [![Coverage Status][coverage-badge]][coverage-status] [![Chat][chat-badge]][chat] - -[Parser][] for [**unified**][unified]. Parses markdown to an -[**MDAST**][mdast] syntax tree. Used in the [**remark** -processor][processor]. Can be [extended][extend] to change how -markdown is parsed. - -## Installation - -[npm][]: - -```sh -npm install remark-parse -``` - -## Usage - -```js -var unified = require('unified'); -var createStream = require('unified-stream'); -var markdown = require('remark-parse'); -var html = require('remark-html'); - -var processor = unified() - .use(markdown, {commonmark: true}) - .use(html) - -process.stdin - .pipe(createStream(processor)) - .pipe(process.stdout); -``` - -## Table of Contents - -* [API](#api) - * [processor.use(parse\[, options\])](#processoruseparse-options) - * [parse.Parser](#parseparser) -* [Extending the Parser](#extending-the-parser) - * [Parser#blockTokenizers](#parserblocktokenizers) - * [Parser#blockMethods](#parserblockmethods) - * [Parser#inlineTokenizers](#parserinlinetokenizers) - * [Parser#inlineMethods](#parserinlinemethods) - * [function tokenizer(eat, value, silent)](#function-tokenizereat-value-silent) - * [tokenizer.locator(value, fromIndex)](#tokenizerlocatorvalue-fromindex) - * [eat(subvalue)](#eatsubvalue) - * [add(node\[, parent\])](#addnode-parent) - * [add.test()](#addtest) - * [add.reset(node\[, parent\])](#addresetnode-parent) - * [Turning off a tokenizer](#turning-off-a-tokenizer) -* [License](#license) - -## API - -### `processor.use(parse[, options])` - -Configure the `processor` to read markdown as input and process an -[**MDAST**][mdast] syntax tree. - -##### `options` - -Options are passed directly, or passed later through [`processor.data()`][data]. - -##### `options.gfm` - -```md -hello ~~hi~~ world -``` - -GFM mode (`boolean`, default: `true`) turns on: - -* [Fenced code blocks](https://help.github.com/articles/github-flavored-markdown/#fenced-code-blocks) -* [Autolinking of URLs](https://help.github.com/articles/github-flavored-markdown/#url-autolinking) -* [Deletions (strikethrough)](https://help.github.com/articles/github-flavored-markdown/#strikethrough) -* [Task lists](https://help.github.com/articles/writing-on-github/#task-lists) -* [Tables](https://help.github.com/articles/github-flavored-markdown/#tables) - -##### `options.commonmark` - -```md -This is a paragraph - and this is also part of the preceding paragraph. -``` - -CommonMark mode (`boolean`, default: `false`) allows: - -* Empty lines to split blockquotes -* Parentheses (`(` and `)`) around for link and image titles -* Any escaped [ASCII-punctuation][escapes] character -* Closing parenthesis (`)`) as an ordered list marker -* URL definitions (and footnotes, when enabled) in blockquotes - -CommonMark mode disallows: - -* Code directly following a paragraph -* ATX-headings (`# Hash headings`) without spacing after opening hashes - or and before closing hashes -* Setext headings (`Underline headings\n---`) when following a paragraph -* Newlines in link and image titles -* White space in link and image URLs in auto-links (links in brackets, - `<` and `>`) -* Lazy blockquote continuation, lines not preceded by a closing angle - bracket (`>`), for lists, code, and thematicBreak - -##### `options.footnotes` - -```md -Something something[^or something?]. - -And something else[^1]. - -[^1]: This reference footnote contains a paragraph... - - * ...and a list -``` - -Footnotes mode (`boolean`, default: `false`) enables reference footnotes and -inline footnotes. Both are wrapped in square brackets and preceded by a caret -(`^`), and can be referenced from inside other footnotes. - -##### `options.blocks` - -```md -foo - -``` - -Blocks (`Array.`, default: list of [block HTML elements][blocks]) -exposes let’s users define block-level HTML elements. - -##### `options.pedantic` - -```md -Check out some_file_name.txt -``` - -Pedantic mode (`boolean`, default: `false`) turns on: - -* Emphasis (`_alpha_`) and importance (`__bravo__`) with underscores - in words -* Unordered lists with different markers (`*`, `-`, `+`) -* If `commonmark` is also turned on, ordered lists with different - markers (`.`, `)`) -* And pedantic mode removes less spaces in list-items (at most four, - instead of the whole indent) - -### `parse.Parser` - -Access to the [parser][], if you need it. - -## Extending the Parser - -Most often, using transformers to manipulate a syntax tree produces -the desired output. Sometimes, mainly when introducing new syntactic -entities with a certain level of precedence, interfacing with the parser -is necessary. - -If the `remark-parse` plugin is used, it adds a [`Parser`][parser] constructor -to the `processor`. Other plugins can add tokenizers to the parser’s prototype -to change how markdown is parsed. - -The below plugin adds a [tokenizer][] for at-mentions. - -```js -module.exports = mentions; - -function mentions() { - var Parser = this.Parser; - var tokenizers = Parser.prototype.inlineTokenizers; - var methods = Parser.prototype.inlineMethods; - - /* Add an inline tokenizer (defined in the following example). */ - tokenizers.mention = tokenizeMention; - - /* Run it just before `text`. */ - methods.splice(methods.indexOf('text'), 0, 'mention'); -} -``` - -### `Parser#blockTokenizers` - -An object mapping tokenizer names to [tokenizer][]s. These -tokenizers (for example: `fencedCode`, `table`, and `paragraph`) eat -from the start of a value to a line ending. - -See `#blockMethods` below for a list of methods that are included by -default. - -### `Parser#blockMethods` - -Array of `blockTokenizers` names (`string`) specifying the order in -which they run. - - - -* `newline` -* `indentedCode` -* `fencedCode` -* `blockquote` -* `atxHeading` -* `thematicBreak` -* `list` -* `setextHeading` -* `html` -* `footnote` -* `definition` -* `table` -* `paragraph` - - - -### `Parser#inlineTokenizers` - -An object mapping tokenizer names to [tokenizer][]s. These tokenizers -(for example: `url`, `reference`, and `emphasis`) eat from the start -of a value. To increase performance, they depend on [locator][]s. - -See `#inlineMethods` below for a list of methods that are included by -default. - -### `Parser#inlineMethods` - -Array of `inlineTokenizers` names (`string`) specifying the order in -which they run. - - - -* `escape` -* `autoLink` -* `url` -* `html` -* `link` -* `reference` -* `strong` -* `emphasis` -* `deletion` -* `code` -* `break` -* `text` - - - -### `function tokenizer(eat, value, silent)` - -```js -tokenizeMention.notInLink = true; -tokenizeMention.locator = locateMention; - -function tokenizeMention(eat, value, silent) { - var match = /^@(\w+)/.exec(value); - - if (match) { - if (silent) { - return true; - } - - return eat(match[0])({ - type: 'link', - url: 'https://social-network/' + match[1], - children: [{type: 'text', value: match[0]}] - }); - } -} -``` - -The parser knows two types of tokenizers: block level and inline level. -Block level tokenizers are the same as inline level tokenizers, with -the exception that the latter must have a [locator][]. - -Tokenizers _test_ whether a document starts with a certain syntactic -entity. In _silent_ mode, they return whether that test passes. -In _normal_ mode, they consume that token, a process which is called -“eating”. Locators enable tokenizers to function faster by providing -information on where the next entity may occur. - -###### Signatures - -* `Node? = tokenizer(eat, value)` -* `boolean? = tokenizer(eat, value, silent)` - -###### Parameters - -* `eat` ([`Function`][eat]) — Eat, when applicable, an entity -* `value` (`string`) — Value which may start an entity -* `silent` (`boolean`, optional) — Whether to detect or consume - -###### Properties - -* `locator` ([`Function`][locator]) - — Required for inline tokenizers -* `onlyAtStart` (`boolean`) - — Whether nodes can only be found at the beginning of the document -* `notInBlock` (`boolean`) - — Whether nodes cannot be in blockquotes, lists, or footnote - definitions -* `notInList` (`boolean`) - — Whether nodes cannot be in lists -* `notInLink` (`boolean`) - — Whether nodes cannot be in links - -###### Returns - -* In _silent_ mode, whether a node can be found at the start of `value` -* In _normal_ mode, a node if it can be found at the start of `value` - -### `tokenizer.locator(value, fromIndex)` - -```js -function locateMention(value, fromIndex) { - return value.indexOf('@', fromIndex); -} -``` - -Locators are required for inline tokenization to keep the process -performant. Locators enable inline tokenizers to function faster by -providing information on the where the next entity occurs. Locators -may be wrong, it’s OK if there actually isn’t a node to be found at -the index they return, but they must skip any nodes. - -###### Parameters - -* `value` (`string`) — Value which may contain an entity -* `fromIndex` (`number`) — Position to start searching at - -###### Returns - -Index at which an entity may start, and `-1` otherwise. - -### `eat(subvalue)` - -```js -var add = eat('foo'); -``` - -Eat `subvalue`, which is a string at the start of the -[tokenize][tokenizer]d `value` (it’s tracked to ensure the correct -value is eaten). - -###### Parameters - -* `subvalue` (`string`) - Value to eat. - -###### Returns - -[`add`][add]. - -### `add(node[, parent])` - -```js -var add = eat('foo'); -add({type: 'text', value: 'foo'}); -``` - -Add [positional information][location] to `node` and add it to `parent`. - -###### Parameters - -* `node` ([`Node`][node]) - Node to patch position on and insert -* `parent` ([`Node`][node], optional) - Place to add `node` to in - the syntax tree. Defaults to the currently processed node - -###### Returns - -The given `node`. - -### `add.test()` - -Get the [positional information][location] which would be patched on -`node` by `add`. - -###### Returns - -[`Location`][location]. - -### `add.reset(node[, parent])` - -`add`, but resets the internal location. Useful for example in -lists, where the same content is first eaten for a list, and later -for list items - -###### Parameters - -* `node` ([`Node`][node]) - Node to patch position on and insert -* `parent` ([`Node`][node], optional) - Place to add `node` to in - the syntax tree. Defaults to the currently processed node - -###### Returns - -The given `node`. - -### Turning off a tokenizer - -In rare situations, you may want to turn off a tokenizer to avoid parsing -that syntactic feature. This can be done by deleting the tokenizer from -your Parser’s `blockTokenizers` (or `blockMethods`) or `inlineTokenizers` -(or `inlineMethods`). - -The following example turns off indented code blocks: - -```js -delete remarkParse.Parser.prototype.blockTokenizers.indentedCode; -``` - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/remarkjs/remark.svg - -[build-status]: https://travis-ci.org/remarkjs/remark - -[coverage-badge]: https://img.shields.io/codecov/c/github/remarkjs/remark.svg - -[coverage-status]: https://codecov.io/github/remarkjs/remark - -[chat-badge]: https://img.shields.io/gitter/room/remarkjs/Lobby.svg - -[chat]: https://gitter.im/remarkjs/Lobby - -[license]: https://github.com/remarkjs/remark/blob/master/LICENSE - -[author]: http://wooorm.com - -[npm]: https://docs.npmjs.com/cli/install - -[unified]: https://github.com/unifiedjs/unified - -[data]: https://github.com/unifiedjs/unified#processordatakey-value - -[processor]: https://github.com/unifiedjs/remark/blob/master/packages/remark - -[mdast]: https://github.com/syntax-tree/mdast - -[escapes]: http://spec.commonmark.org/0.25/#backslash-escapes - -[node]: https://github.com/syntax-tree/unist#node - -[location]: https://github.com/syntax-tree/unist#location - -[parser]: https://github.com/unifiedjs/unified#processorparser - -[extend]: #extending-the-parser - -[tokenizer]: #function-tokenizereat-value-silent - -[locator]: #tokenizerlocatorvalue-fromindex - -[eat]: #eatsubvalue - -[add]: #addnode-parent - -[blocks]: https://github.com/remarkjs/remark/blob/master/packages/remark-parse/lib/block-elements.json diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/repeat-string/LICENSE b/tools/node_modules/eslint-plugin-markdown/node_modules/repeat-string/LICENSE deleted file mode 100644 index 39245ac1c60613..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/repeat-string/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014-2016, Jon Schlinkert. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/repeat-string/README.md b/tools/node_modules/eslint-plugin-markdown/node_modules/repeat-string/README.md deleted file mode 100644 index aaa5e91c7a7f91..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/repeat-string/README.md +++ /dev/null @@ -1,136 +0,0 @@ -# repeat-string [![NPM version](https://img.shields.io/npm/v/repeat-string.svg?style=flat)](https://www.npmjs.com/package/repeat-string) [![NPM monthly downloads](https://img.shields.io/npm/dm/repeat-string.svg?style=flat)](https://npmjs.org/package/repeat-string) [![NPM total downloads](https://img.shields.io/npm/dt/repeat-string.svg?style=flat)](https://npmjs.org/package/repeat-string) [![Linux Build Status](https://img.shields.io/travis/jonschlinkert/repeat-string.svg?style=flat&label=Travis)](https://travis-ci.org/jonschlinkert/repeat-string) - -> Repeat the given string n times. Fastest implementation for repeating a string. - -## Install - -Install with [npm](https://www.npmjs.com/): - -```sh -$ npm install --save repeat-string -``` - -## Usage - -### [repeat](index.js#L41) - -Repeat the given `string` the specified `number` of times. - -**Example:** - -**Example** - -```js -var repeat = require('repeat-string'); -repeat('A', 5); -//=> AAAAA -``` - -**Params** - -* `string` **{String}**: The string to repeat -* `number` **{Number}**: The number of times to repeat the string -* `returns` **{String}**: Repeated string - -## Benchmarks - -Repeat string is significantly faster than the native method (which is itself faster than [repeating](https://github.com/sindresorhus/repeating)): - -```sh -# 2x -repeat-string █████████████████████████ (26,953,977 ops/sec) -repeating █████████ (9,855,695 ops/sec) -native ██████████████████ (19,453,895 ops/sec) - -# 3x -repeat-string █████████████████████████ (19,445,252 ops/sec) -repeating ███████████ (8,661,565 ops/sec) -native ████████████████████ (16,020,598 ops/sec) - -# 10x -repeat-string █████████████████████████ (23,792,521 ops/sec) -repeating █████████ (8,571,332 ops/sec) -native ███████████████ (14,582,955 ops/sec) - -# 50x -repeat-string █████████████████████████ (23,640,179 ops/sec) -repeating █████ (5,505,509 ops/sec) -native ██████████ (10,085,557 ops/sec) - -# 250x -repeat-string █████████████████████████ (23,489,618 ops/sec) -repeating ████ (3,962,937 ops/sec) -native ████████ (7,724,892 ops/sec) - -# 2000x -repeat-string █████████████████████████ (20,315,172 ops/sec) -repeating ████ (3,297,079 ops/sec) -native ███████ (6,203,331 ops/sec) - -# 20000x -repeat-string █████████████████████████ (23,382,915 ops/sec) -repeating ███ (2,980,058 ops/sec) -native █████ (5,578,808 ops/sec) -``` - -**Run the benchmarks** - -Install dev dependencies: - -```sh -npm i -d && node benchmark -``` - -## About - -### Related projects - -[repeat-element](https://www.npmjs.com/package/repeat-element): Create an array by repeating the given value n times. | [homepage](https://github.com/jonschlinkert/repeat-element "Create an array by repeating the given value n times.") - -### Contributing - -Pull requests and stars are always welcome. For bugs and feature requests, [please create an issue](../../issues/new). - -### Contributors - -| **Commits** | **Contributor**
| -| --- | --- | -| 51 | [jonschlinkert](https://github.com/jonschlinkert) | -| 2 | [LinusU](https://github.com/LinusU) | -| 2 | [tbusser](https://github.com/tbusser) | -| 1 | [doowb](https://github.com/doowb) | -| 1 | [wooorm](https://github.com/wooorm) | - -### Building docs - -_(This document was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme) (a [verb](https://github.com/verbose/verb) generator), please don't edit the readme directly. Any changes to the readme must be made in [.verb.md](.verb.md).)_ - -To generate the readme and API documentation with [verb](https://github.com/verbose/verb): - -```sh -$ npm install -g verb verb-generate-readme && verb -``` - -### Running tests - -Install dev dependencies: - -```sh -$ npm install -d && npm test -``` - -### Author - -**Jon Schlinkert** - -* [github/jonschlinkert](https://github.com/jonschlinkert) -* [twitter/jonschlinkert](http://twitter.com/jonschlinkert) - -### License - -Copyright © 2016, [Jon Schlinkert](http://github.com/jonschlinkert). -Released under the [MIT license](https://github.com/jonschlinkert/repeat-string/blob/master/LICENSE). - -*** - -_This file was generated by [verb-generate-readme](https://github.com/verbose/verb-generate-readme), v0.2.0, on October 23, 2016._ \ No newline at end of file diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/repeat-string/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/repeat-string/index.js deleted file mode 100644 index 4459afd8016e31..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/repeat-string/index.js +++ /dev/null @@ -1,70 +0,0 @@ -/*! - * repeat-string - * - * Copyright (c) 2014-2015, Jon Schlinkert. - * Licensed under the MIT License. - */ - -'use strict'; - -/** - * Results cache - */ - -var res = ''; -var cache; - -/** - * Expose `repeat` - */ - -module.exports = repeat; - -/** - * Repeat the given `string` the specified `number` - * of times. - * - * **Example:** - * - * ```js - * var repeat = require('repeat-string'); - * repeat('A', 5); - * //=> AAAAA - * ``` - * - * @param {String} `string` The string to repeat - * @param {Number} `number` The number of times to repeat the string - * @return {String} Repeated string - * @api public - */ - -function repeat(str, num) { - if (typeof str !== 'string') { - throw new TypeError('expected a string'); - } - - // cover common, quick use cases - if (num === 1) return str; - if (num === 2) return str + str; - - var max = str.length * num; - if (cache !== str || typeof cache === 'undefined') { - cache = str; - res = ''; - } else if (res.length >= max) { - return res.substr(0, max); - } - - while (max > res.length && num > 1) { - if (num & 1) { - res += str; - } - - num >>= 1; - str += str; - } - - res += str; - res = res.substr(0, max); - return res; -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/repeat-string/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/repeat-string/package.json deleted file mode 100644 index 09f889299b6683..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/repeat-string/package.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "name": "repeat-string", - "description": "Repeat the given string n times. Fastest implementation for repeating a string.", - "version": "1.6.1", - "homepage": "https://github.com/jonschlinkert/repeat-string", - "author": "Jon Schlinkert (http://github.com/jonschlinkert)", - "contributors": [ - "Brian Woodward (https://github.com/doowb)", - "Jon Schlinkert (http://twitter.com/jonschlinkert)", - "Linus Unnebäck (http://linus.unnebäck.se)", - "Thijs Busser (http://tbusser.net)", - "Titus (wooorm.com)" - ], - "repository": "jonschlinkert/repeat-string", - "bugs": { - "url": "https://github.com/jonschlinkert/repeat-string/issues" - }, - "license": "MIT", - "files": [ - "index.js" - ], - "main": "index.js", - "engines": { - "node": ">=0.10" - }, - "scripts": { - "test": "mocha" - }, - "devDependencies": { - "ansi-cyan": "^0.1.1", - "benchmarked": "^0.2.5", - "gulp-format-md": "^0.1.11", - "isobject": "^2.1.0", - "mocha": "^3.1.2", - "repeating": "^3.0.0", - "text-table": "^0.2.0", - "yargs-parser": "^4.0.2" - }, - "keywords": [ - "fast", - "fastest", - "fill", - "left", - "left-pad", - "multiple", - "pad", - "padding", - "repeat", - "repeating", - "repetition", - "right", - "right-pad", - "string", - "times" - ], - "verb": { - "toc": false, - "layout": "default", - "tasks": [ - "readme" - ], - "plugins": [ - "gulp-format-md" - ], - "related": { - "list": [ - "repeat-element" - ] - }, - "helpers": [ - "./benchmark/helper.js" - ], - "reflinks": [ - "verb" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/replace-ext/LICENSE b/tools/node_modules/eslint-plugin-markdown/node_modules/replace-ext/LICENSE deleted file mode 100755 index fd38d69351565d..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/replace-ext/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Blaine Bublitz , Eric Schoffstall and other contributors - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/replace-ext/README.md b/tools/node_modules/eslint-plugin-markdown/node_modules/replace-ext/README.md deleted file mode 100644 index 8775983b7834d5..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/replace-ext/README.md +++ /dev/null @@ -1,50 +0,0 @@ -

- - - -

- -# replace-ext - -[![NPM version][npm-image]][npm-url] [![Downloads][downloads-image]][npm-url] [![Build Status][travis-image]][travis-url] [![AppVeyor Build Status][appveyor-image]][appveyor-url] [![Coveralls Status][coveralls-image]][coveralls-url] [![Gitter chat][gitter-image]][gitter-url] - -Replaces a file extension with another one. - -## Usage - -```js -var replaceExt = require('replace-ext'); - -var path = '/some/dir/file.js'; -var newPath = replaceExt(path, '.coffee'); - -console.log(newPath); // /some/dir/file.coffee -``` - -## API - -### `replaceExt(path, extension)` - -Replaces the extension from `path` with `extension` and returns the updated path string. - -Does not replace the extension if `path` is not a string or is empty. - -## License - -MIT - -[downloads-image]: http://img.shields.io/npm/dm/replace-ext.svg -[npm-url]: https://www.npmjs.com/package/replace-ext -[npm-image]: http://img.shields.io/npm/v/replace-ext.svg - -[travis-url]: https://travis-ci.org/gulpjs/replace-ext -[travis-image]: http://img.shields.io/travis/gulpjs/replace-ext.svg?label=travis-ci - -[appveyor-url]: https://ci.appveyor.com/project/gulpjs/replace-ext -[appveyor-image]: https://img.shields.io/appveyor/ci/gulpjs/replace-ext.svg?label=appveyor - -[coveralls-url]: https://coveralls.io/r/gulpjs/replace-ext -[coveralls-image]: http://img.shields.io/coveralls/gulpjs/replace-ext/master.svg - -[gitter-url]: https://gitter.im/gulpjs/gulp -[gitter-image]: https://badges.gitter.im/gulpjs/gulp.svg diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/replace-ext/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/replace-ext/index.js deleted file mode 100644 index 7cb7789e280723..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/replace-ext/index.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict'; - -var path = require('path'); - -function replaceExt(npath, ext) { - if (typeof npath !== 'string') { - return npath; - } - - if (npath.length === 0) { - return npath; - } - - var nFileName = path.basename(npath, path.extname(npath)) + ext; - return path.join(path.dirname(npath), nFileName); -} - -module.exports = replaceExt; diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/replace-ext/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/replace-ext/package.json deleted file mode 100644 index 27dbe31042d0ff..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/replace-ext/package.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "replace-ext", - "version": "1.0.0", - "description": "Replaces a file extension with another one", - "author": "Gulp Team (http://gulpjs.com/)", - "contributors": [ - "Eric Schoffstall ", - "Blaine Bublitz " - ], - "repository": "gulpjs/replace-ext", - "license": "MIT", - "engines": { - "node": ">= 0.10" - }, - "main": "index.js", - "files": [ - "LICENSE", - "index.js" - ], - "scripts": { - "lint": "eslint . && jscs index.js test/", - "pretest": "npm run lint", - "test": "mocha --async-only", - "cover": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly", - "coveralls": "npm run cover && istanbul-coveralls" - }, - "dependencies": {}, - "devDependencies": { - "eslint": "^1.10.3", - "eslint-config-gulp": "^2.0.0", - "expect": "^1.16.0", - "istanbul": "^0.4.3", - "istanbul-coveralls": "^1.0.3", - "jscs": "^2.3.5", - "jscs-preset-gulp": "^1.0.0", - "mocha": "^2.4.5" - }, - "keywords": [ - "gulp", - "extensions", - "filepath", - "basename" - ] -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/state-toggle/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/state-toggle/index.js deleted file mode 100644 index aceee00d1db789..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/state-toggle/index.js +++ /dev/null @@ -1,23 +0,0 @@ -'use strict' - -module.exports = factory - -// Construct a state `toggler`: a function which inverses `property` in context -// based on its current value. -// The by `toggler` returned function restores that value. -function factory(key, state, ctx) { - return enter - - function enter() { - var context = ctx || this - var current = context[key] - - context[key] = !state - - return exit - - function exit() { - context[key] = current - } - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/state-toggle/license b/tools/node_modules/eslint-plugin-markdown/node_modules/state-toggle/license deleted file mode 100644 index 8d8660d36ef2ec..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/state-toggle/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2016 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/state-toggle/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/state-toggle/package.json deleted file mode 100644 index 1111db063669a9..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/state-toggle/package.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "name": "state-toggle", - "version": "1.0.3", - "description": "Enter/exit a state", - "license": "MIT", - "keywords": [ - "enter", - "exit", - "state" - ], - "repository": "wooorm/state-toggle", - "bugs": "https://github.com/wooorm/state-toggle/issues", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - }, - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "files": [ - "index.js" - ], - "dependencies": {}, - "devDependencies": { - "browserify": "^16.0.0", - "nyc": "^15.0.0", - "prettier": "^1.0.0", - "remark-cli": "^7.0.0", - "remark-preset-wooorm": "^6.0.0", - "tape": "^4.0.0", - "tinyify": "^2.0.0", - "xo": "^0.25.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify . -s stateToggle -o state-toggle.js", - "build-mangle": "browserify . -s stateToggle -p tinyify -o state-toggle.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "ignores": [ - "state-toggle.js" - ] - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/state-toggle/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/state-toggle/readme.md deleted file mode 100644 index 9fcca1e5ef6ddb..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/state-toggle/readme.md +++ /dev/null @@ -1,95 +0,0 @@ -# state-toggle - -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] - -Enter/exit a state. - -## Install - -[npm][]: - -```sh -npm install state-toggle -``` - -## Use - -```js -var toggle = require('state-toggle') - -var ctx = {on: false} -var enter = toggle('on', ctx.on, ctx) -var exit - -// Entering: -exit = enter() -console.log(ctx.on) // => true - -// Exiting: -exit() -console.log(ctx.on) // => false -``` - -## API - -### `toggle(key, initial[, ctx])` - -Create a toggle, which when entering toggles `key` on `ctx` (or `this`, if `ctx` -is not given) to `!initial`, and when exiting, sets `key` on the context back to -the value it had before entering. - -###### Returns - -`Function` — [`enter`][enter]. - -### `enter()` - -Enter the state. - -###### Context - -If no `ctx` was given to `toggle`, the context object (`this`) of `enter()` is -used to toggle. - -###### Returns - -`Function` — [`exit`][exit]. - -### `exit()` - -Exit the state, reverting `key` to the value it had before entering. - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/wooorm/state-toggle.svg - -[build]: https://travis-ci.org/wooorm/state-toggle - -[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/state-toggle.svg - -[coverage]: https://codecov.io/github/wooorm/state-toggle - -[downloads-badge]: https://img.shields.io/npm/dm/state-toggle.svg - -[downloads]: https://www.npmjs.com/package/state-toggle - -[size-badge]: https://img.shields.io/bundlephobia/minzip/state-toggle.svg - -[size]: https://bundlephobia.com/result?p=state-toggle - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com - -[enter]: #enter - -[exit]: #exit diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/trim-trailing-lines/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/trim-trailing-lines/index.js deleted file mode 100644 index eff85c6baedffb..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/trim-trailing-lines/index.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict' - -module.exports = trimTrailingLines - -// Remove final newline characters from `value`. -function trimTrailingLines(value) { - return String(value).replace(/\n+$/, '') -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/trim-trailing-lines/license b/tools/node_modules/eslint-plugin-markdown/node_modules/trim-trailing-lines/license deleted file mode 100644 index 611b67581bb8e2..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/trim-trailing-lines/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2015 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/trim-trailing-lines/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/trim-trailing-lines/package.json deleted file mode 100644 index 861198394c3220..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/trim-trailing-lines/package.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "name": "trim-trailing-lines", - "version": "1.1.4", - "description": "Remove final line feeds from a string", - "license": "MIT", - "keywords": [ - "trim", - "final", - "line", - "newline", - "characters" - ], - "repository": "wooorm/trim-trailing-lines", - "bugs": "https://github.com/wooorm/trim-trailing-lines/issues", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - }, - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "files": [ - "index.js" - ], - "dependencies": {}, - "devDependencies": { - "browserify": "^17.0.0", - "nyc": "^15.0.0", - "prettier": "^2.0.0", - "remark-cli": "^9.0.0", - "remark-preset-wooorm": "^8.0.0", - "tape": "^5.0.0", - "tinyify": "^3.0.0", - "xo": "^0.34.0" - }, - "scripts": { - "format": "remark . -qfo && prettier . -w --loglevel warn && xo --fix", - "build-bundle": "browserify . -s trimTrailingLines -o trim-trailing-lines.js", - "build-mangle": "browserify . -s trimTrailingLines -p tinyify -o trim-trailing-lines.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "ignores": [ - "trim-trailing-lines.js" - ] - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/trim-trailing-lines/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/trim-trailing-lines/readme.md deleted file mode 100644 index a9c1f441b84262..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/trim-trailing-lines/readme.md +++ /dev/null @@ -1,68 +0,0 @@ -# trim-trailing-lines - -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] - -Remove final line feeds from a string. - -## Install - -[npm][]: - -```sh -npm install trim-trailing-lines -``` - -## Use - -```js -var trimTrailingLines = require('trim-trailing-lines') - -trimTrailingLines('foo\nbar') // => 'foo\nbar' -trimTrailingLines('foo\nbar\n') // => 'foo\nbar' -trimTrailingLines('foo\nbar\n\n') // => 'foo\nbar' -``` - -## API - -### `trimTrailingLines(value)` - -Remove final line feed characters from `value`. - -###### Parameters - -* `value` (`string`) — Value with trailing line feeds, coerced to string. - -###### Returns - -`string` — Value without trailing newlines. - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/wooorm/trim-trailing-lines.svg - -[build]: https://travis-ci.org/wooorm/trim-trailing-lines - -[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/trim-trailing-lines.svg - -[coverage]: https://codecov.io/github/wooorm/trim-trailing-lines - -[downloads-badge]: https://img.shields.io/npm/dm/trim-trailing-lines.svg - -[downloads]: https://www.npmjs.com/package/trim-trailing-lines - -[size-badge]: https://img.shields.io/bundlephobia/minzip/trim-trailing-lines.svg - -[size]: https://bundlephobia.com/result?p=trim-trailing-lines - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/trim/Makefile b/tools/node_modules/eslint-plugin-markdown/node_modules/trim/Makefile deleted file mode 100644 index 4e9c8d36ebcd2f..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/trim/Makefile +++ /dev/null @@ -1,7 +0,0 @@ - -test: - @./node_modules/.bin/mocha \ - --require should \ - --reporter spec - -.PHONY: test \ No newline at end of file diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/trim/Readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/trim/Readme.md deleted file mode 100644 index 3460f523fbe8ac..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/trim/Readme.md +++ /dev/null @@ -1,69 +0,0 @@ - -# trim - - Trims string whitespace. - -## Installation - -``` -$ npm install trim -$ component install component/trim -``` - -## API - - - [trim(str)](#trimstr) - - [.left(str)](#leftstr) - - [.right(str)](#rightstr) - - - -### trim(str) -should trim leading / trailing whitespace. - -```js -trim(' foo bar ').should.equal('foo bar'); -trim('\n\n\nfoo bar\n\r\n\n').should.equal('foo bar'); -``` - - -### .left(str) -should trim leading whitespace. - -```js -trim.left(' foo bar ').should.equal('foo bar '); -``` - - -### .right(str) -should trim trailing whitespace. - -```js -trim.right(' foo bar ').should.equal(' foo bar'); -``` - - -## License - -(The MIT License) - -Copyright (c) 2012 TJ Holowaychuk <tj@vision-media.ca> - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/trim/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/trim/index.js deleted file mode 100644 index 640c24cf302e60..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/trim/index.js +++ /dev/null @@ -1,14 +0,0 @@ - -exports = module.exports = trim; - -function trim(str){ - return str.replace(/^\s*|\s*$/g, ''); -} - -exports.left = function(str){ - return str.replace(/^\s*/, ''); -}; - -exports.right = function(str){ - return str.replace(/\s*$/, ''); -}; diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/trim/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/trim/package.json deleted file mode 100644 index 64ee5c69d84c32..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/trim/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "trim", - "version": "0.0.1", - "description": "Trim string whitespace", - "keywords": ["string", "trim"], - "author": "TJ Holowaychuk ", - "dependencies": {}, - "devDependencies": { - "mocha": "*", - "should": "*" - }, - "main": "index", - "component": { - "scripts": { - "trim/index.js": "index.js" - } - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/trough/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/trough/index.js deleted file mode 100644 index 2b73d868056525..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/trough/index.js +++ /dev/null @@ -1,74 +0,0 @@ -'use strict' - -var wrap = require('./wrap.js') - -module.exports = trough - -trough.wrap = wrap - -var slice = [].slice - -// Create new middleware. -function trough() { - var fns = [] - var middleware = {} - - middleware.run = run - middleware.use = use - - return middleware - - // Run `fns`. Last argument must be a completion handler. - function run() { - var index = -1 - var input = slice.call(arguments, 0, -1) - var done = arguments[arguments.length - 1] - - if (typeof done !== 'function') { - throw new Error('Expected function as last argument, not ' + done) - } - - next.apply(null, [null].concat(input)) - - // Run the next `fn`, if any. - function next(err) { - var fn = fns[++index] - var params = slice.call(arguments, 0) - var values = params.slice(1) - var length = input.length - var pos = -1 - - if (err) { - done(err) - return - } - - // Copy non-nully input into values. - while (++pos < length) { - if (values[pos] === null || values[pos] === undefined) { - values[pos] = input[pos] - } - } - - input = values - - // Next or done. - if (fn) { - wrap(fn, next).apply(null, input) - } else { - done.apply(null, [null].concat(input)) - } - } - } - - // Add `fn` to the list. - function use(fn) { - if (typeof fn !== 'function') { - throw new Error('Expected `fn` to be a function, not ' + fn) - } - - fns.push(fn) - - return middleware - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/trough/license b/tools/node_modules/eslint-plugin-markdown/node_modules/trough/license deleted file mode 100644 index 3f0166f62b10c0..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/trough/license +++ /dev/null @@ -1,21 +0,0 @@ -(The MIT License) - -Copyright (c) 2016 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/trough/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/trough/package.json deleted file mode 100644 index cbf7782f89a445..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/trough/package.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "name": "trough", - "version": "1.0.5", - "description": "Middleware: a channel used to convey a liquid", - "license": "MIT", - "keywords": [ - "middleware", - "ware" - ], - "repository": "wooorm/trough", - "bugs": "https://github.com/wooorm/trough/issues", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - }, - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "files": [ - "index.js", - "wrap.js" - ], - "dependencies": {}, - "devDependencies": { - "browserify": "^16.0.0", - "nyc": "^15.0.0", - "prettier": "^1.0.0", - "remark-cli": "^7.0.0", - "remark-preset-wooorm": "^6.0.0", - "tape": "^4.0.0", - "tinyify": "^2.0.0", - "xo": "^0.25.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify index.js -s trough > trough.js", - "build-mangle": "browserify index.js -s trough -p tinyify > trough.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "rules": { - "unicorn/prefer-reflect-apply": "off", - "unicorn/prefer-type-error": "off", - "guard-for-in": "off" - }, - "ignores": [ - "trough.js" - ] - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/trough/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/trough/readme.md deleted file mode 100644 index ce3d38bca9a2bf..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/trough/readme.md +++ /dev/null @@ -1,330 +0,0 @@ -# trough - -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] - -> **trough** /trôf/ — a channel used to convey a liquid. - -`trough` is like [`ware`][ware] with less sugar, and middleware functions can -change the input of the next. - -## Install - -[npm][]: - -```sh -npm install trough -``` - -## Use - -```js -var fs = require('fs') -var path = require('path') -var trough = require('trough') - -var pipeline = trough() - .use(function(fileName) { - console.log('Checking… ' + fileName) - }) - .use(function(fileName) { - return path.join(process.cwd(), fileName) - }) - .use(function(filePath, next) { - fs.stat(filePath, function(err, stats) { - next(err, {filePath, stats}) - }) - }) - .use(function(ctx, next) { - if (ctx.stats.isFile()) { - fs.readFile(ctx.filePath, next) - } else { - next(new Error('Expected file')) - } - }) - -pipeline.run('readme.md', console.log) -pipeline.run('node_modules', console.log) -``` - -Yields: - -```txt -Checking… readme.md -Checking… node_modules -Error: Expected file - at ~/example.js:21:12 - at wrapped (~/node_modules/trough/index.js:93:19) - at next (~/node_modules/trough/index.js:56:24) - at done (~/node_modules/trough/index.js:124:12) - at ~/node_modules/example.js:14:7 - at FSReqWrap.oncomplete (fs.js:153:5) -null -``` - -## API - -### `trough()` - -Create a new [`Trough`][trough]. - -#### `trough.wrap(middleware, callback[, …input])` - -Call `middleware` with all input. -If `middleware` accepts more arguments than given in input, and extra `done` -function is passed in after the input when calling it. -It must be called. - -The first value in `input` is called the main input value. -All other input values are called the rest input values. -The values given to `callback` are the input values, merged with every non-nully -output value. - -* If `middleware` throws an error, returns a promise that is rejected, or - calls the given `done` function with an error, `callback` is invoked with - that error -* If `middleware` returns a value or returns a promise that is resolved, that - value is the main output value -* If `middleware` calls `done`, all non-nully values except for the first one - (the error) overwrite the output values - -### `Trough` - -A pipeline. - -#### `Trough#run([input…, ]done)` - -Run the pipeline (all [`use()`][use]d middleware). -Invokes [`done`][done] on completion with either an error or the output of the -last middleware. - -> Note! -> as the length of input defines whether [async][] functions get a `next` -> function, it’s recommended to keep `input` at one value normally. - -##### `function done(err?, [output…])` - -The final handler passed to [`run()`][run], invoked with an error if a -[middleware function][fn] rejected, passed, or threw one, or the output of the -last middleware function. - -#### `Trough#use(fn)` - -Add `fn`, a [middleware function][fn], to the pipeline. - -##### `function fn([input…, ][next])` - -A middleware function invoked with the output of its predecessor. - -###### Synchronous - -If `fn` returns or throws an error, the pipeline fails and `done` is invoked -with that error. - -If `fn` returns a value (neither `null` nor `undefined`), the first `input` of -the next function is set to that value (all other `input` is passed through). - -The following example shows how returning an error stops the pipeline: - -```js -var trough = require('trough') - -trough() - .use(function(val) { - return new Error('Got: ' + val) - }) - .run('some value', console.log) -``` - -Yields: - -```txt -Error: Got: some value - at ~/example.js:5:12 - … -``` - -The following example shows how throwing an error stops the pipeline: - -```js -var trough = require('trough') - -trough() - .use(function(val) { - throw new Error('Got: ' + val) - }) - .run('more value', console.log) -``` - -Yields: - -```txt -Error: Got: more value - at ~/example.js:5:11 - … -``` - -The following example shows how the first output can be modified: - -```js -var trough = require('trough') - -trough() - .use(function(val) { - return 'even ' + val - }) - .run('more value', 'untouched', console.log) -``` - -Yields: - -```txt -null 'even more value' 'untouched' -``` - -###### Promise - -If `fn` returns a promise, and that promise rejects, the pipeline fails and -`done` is invoked with the rejected value. - -If `fn` returns a promise, and that promise resolves with a value (neither -`null` nor `undefined`), the first `input` of the next function is set to that -value (all other `input` is passed through). - -The following example shows how rejecting a promise stops the pipeline: - -```js -var trough = require('trough') - -trough() - .use(function(val) { - return new Promise(function(resolve, reject) { - reject('Got: ' + val) - }) - }) - .run('val', console.log) -``` - -Yields: - -```txt -Got: val -``` - -The following example shows how the input isn’t touched by resolving to `null`. - -```js -var trough = require('trough') - -trough() - .use(function() { - return new Promise(function(resolve) { - setTimeout(function() { - resolve(null) - }, 100) - }) - }) - .run('Input', console.log) -``` - -Yields: - -```txt -null 'Input' -``` - -###### Asynchronous - -If `fn` accepts one more argument than the given `input`, a `next` function is -given (after the input). `next` must be called, but doesn’t have to be called -async. - -If `next` is given a value (neither `null` nor `undefined`) as its first -argument, the pipeline fails and `done` is invoked with that value. - -If `next` is given no value (either `null` or `undefined`) as the first -argument, all following non-nully values change the input of the following -function, and all nully values default to the `input`. - -The following example shows how passing a first argument stops the pipeline: - -```js -var trough = require('trough') - -trough() - .use(function(val, next) { - next(new Error('Got: ' + val)) - }) - .run('val', console.log) -``` - -Yields: - -```txt -Error: Got: val - at ~/example.js:5:10 -``` - -The following example shows how more values than the input are passed. - -```js -var trough = require('trough') - -trough() - .use(function(val, next) { - setTimeout(function() { - next(null, null, 'values') - }, 100) - }) - .run('some', console.log) -``` - -Yields: - -```txt -null 'some' 'values' -``` - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/wooorm/trough.svg - -[build]: https://travis-ci.org/wooorm/trough - -[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/trough.svg - -[coverage]: https://codecov.io/github/wooorm/trough - -[downloads-badge]: https://img.shields.io/npm/dm/trough.svg - -[downloads]: https://www.npmjs.com/package/trough - -[size-badge]: https://img.shields.io/bundlephobia/minzip/trough.svg - -[size]: https://bundlephobia.com/result?p=trough - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com - -[ware]: https://github.com/segmentio/ware - -[trough]: #trough-1 - -[use]: #troughusefn - -[run]: #troughruninput-done - -[fn]: #function-fninput-next - -[done]: #function-doneerr-output - -[async]: #asynchronous diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/trough/wrap.js b/tools/node_modules/eslint-plugin-markdown/node_modules/trough/wrap.js deleted file mode 100644 index cf568c07adfa34..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/trough/wrap.js +++ /dev/null @@ -1,64 +0,0 @@ -'use strict' - -var slice = [].slice - -module.exports = wrap - -// Wrap `fn`. -// Can be sync or async; return a promise, receive a completion handler, return -// new values and errors. -function wrap(fn, callback) { - var invoked - - return wrapped - - function wrapped() { - var params = slice.call(arguments, 0) - var callback = fn.length > params.length - var result - - if (callback) { - params.push(done) - } - - try { - result = fn.apply(null, params) - } catch (error) { - // Well, this is quite the pickle. - // `fn` received a callback and invoked it (thus continuing the pipeline), - // but later also threw an error. - // We’re not about to restart the pipeline again, so the only thing left - // to do is to throw the thing instead. - if (callback && invoked) { - throw error - } - - return done(error) - } - - if (!callback) { - if (result && typeof result.then === 'function') { - result.then(then, done) - } else if (result instanceof Error) { - done(result) - } else { - then(result) - } - } - } - - // Invoke `next`, only once. - function done() { - if (!invoked) { - invoked = true - - callback.apply(null, arguments) - } - } - - // Invoke `done` with one value. - // Tracks if an error is passed, too. - function then(value) { - done(null, value) - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unherit/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/unherit/index.js deleted file mode 100644 index 32ead7770fa2c9..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unherit/index.js +++ /dev/null @@ -1,45 +0,0 @@ -'use strict' - -var xtend = require('xtend') -var inherits = require('inherits') - -module.exports = unherit - -// Create a custom constructor which can be modified without affecting the -// original class. -function unherit(Super) { - var result - var key - var value - - inherits(Of, Super) - inherits(From, Of) - - // Clone values. - result = Of.prototype - - for (key in result) { - value = result[key] - - if (value && typeof value === 'object') { - result[key] = 'concat' in value ? value.concat() : xtend(value) - } - } - - return Of - - // Constructor accepting a single argument, which itself is an `arguments` - // object. - function From(parameters) { - return Super.apply(this, parameters) - } - - // Constructor accepting variadic arguments. - function Of() { - if (!(this instanceof Of)) { - return new From(arguments) - } - - return Super.apply(this, arguments) - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unherit/license b/tools/node_modules/eslint-plugin-markdown/node_modules/unherit/license deleted file mode 100644 index f3722d94b38121..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unherit/license +++ /dev/null @@ -1,21 +0,0 @@ -(The MIT License) - -Copyright (c) 2015 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unherit/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/unherit/package.json deleted file mode 100644 index 445a500650255e..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unherit/package.json +++ /dev/null @@ -1,72 +0,0 @@ -{ - "name": "unherit", - "version": "1.1.3", - "description": "Clone a constructor without affecting the super-class", - "license": "MIT", - "keywords": [ - "clone", - "super", - "class", - "constructor" - ], - "repository": "wooorm/unherit", - "bugs": "https://github.com/wooorm/unherit/issues", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - }, - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "files": [ - "index.js" - ], - "dependencies": { - "inherits": "^2.0.0", - "xtend": "^4.0.0" - }, - "devDependencies": { - "browserify": "^16.0.0", - "nyc": "^15.0.0", - "prettier": "^1.0.0", - "remark-cli": "^7.0.0", - "remark-preset-wooorm": "^6.0.0", - "tape": "^4.0.0", - "tinyify": "^2.0.0", - "xo": "^0.25.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify . -s unherit -o unherit.js", - "build-mangle": "browserify . -s unherit -p tinyify -o unherit.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "rules": { - "unicorn/prefer-reflect-apply": "off", - "guard-for-in": "off" - }, - "ignores": [ - "unherit.js" - ] - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unherit/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/unherit/readme.md deleted file mode 100644 index bf679597d89d50..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unherit/readme.md +++ /dev/null @@ -1,79 +0,0 @@ -# unherit - -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] - -Create a custom constructor which can be modified without affecting the original -class. - -## Install - -[npm][]: - -```sh -npm install unherit -``` - -## Use - -```js -var EventEmitter = require('events').EventEmitter -var unherit = require('unherit') - -// Create a private class which acts just like `EventEmitter`. -var Emitter = unherit(EventEmitter) - -Emitter.prototype.defaultMaxListeners = 0 -// Now, all instances of `Emitter` have no maximum listeners, without affecting -// other `EventEmitter`s. - -new Emitter().defaultMaxListeners === 0 // => true -new EventEmitter().defaultMaxListeners === undefined // => true -new Emitter() instanceof EventEmitter // => true -``` - -## API - -### `unherit(Super)` - -Create a custom constructor which can be modified without affecting the original -class. - -###### Parameters - -* `Super` (`Function`) — Super-class - -###### Returns - -`Function` — Constructor acting like `Super`, which can be modified without -affecting the original class. - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/wooorm/unherit.svg - -[build]: https://travis-ci.org/wooorm/unherit - -[coverage-badge]: https://img.shields.io/codecov/c/github/wooorm/unherit.svg - -[coverage]: https://codecov.io/github/wooorm/unherit - -[downloads-badge]: https://img.shields.io/npm/dm/unherit.svg - -[downloads]: https://www.npmjs.com/package/unherit - -[size-badge]: https://img.shields.io/bundlephobia/minzip/unherit.svg - -[size]: https://bundlephobia.com/result?p=unherit - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unified/LICENSE b/tools/node_modules/eslint-plugin-markdown/node_modules/unified/LICENSE deleted file mode 100644 index f3722d94b38121..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unified/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -(The MIT License) - -Copyright (c) 2015 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unified/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/unified/index.js deleted file mode 100644 index b8f9011d1701b9..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unified/index.js +++ /dev/null @@ -1,466 +0,0 @@ -'use strict' - -/* Dependencies. */ -var extend = require('extend') -var bail = require('bail') -var vfile = require('vfile') -var trough = require('trough') -var string = require('x-is-string') -var plain = require('is-plain-obj') - -/* Expose a frozen processor. */ -module.exports = unified().freeze() - -var slice = [].slice -var own = {}.hasOwnProperty - -/* Process pipeline. */ -var pipeline = trough() - .use(pipelineParse) - .use(pipelineRun) - .use(pipelineStringify) - -function pipelineParse(p, ctx) { - ctx.tree = p.parse(ctx.file) -} - -function pipelineRun(p, ctx, next) { - p.run(ctx.tree, ctx.file, done) - - function done(err, tree, file) { - if (err) { - next(err) - } else { - ctx.tree = tree - ctx.file = file - next() - } - } -} - -function pipelineStringify(p, ctx) { - ctx.file.contents = p.stringify(ctx.tree, ctx.file) -} - -/* Function to create the first processor. */ -function unified() { - var attachers = [] - var transformers = trough() - var namespace = {} - var frozen = false - var freezeIndex = -1 - - /* Data management. */ - processor.data = data - - /* Lock. */ - processor.freeze = freeze - - /* Plug-ins. */ - processor.attachers = attachers - processor.use = use - - /* API. */ - processor.parse = parse - processor.stringify = stringify - processor.run = run - processor.runSync = runSync - processor.process = process - processor.processSync = processSync - - /* Expose. */ - return processor - - /* Create a new processor based on the processor - * in the current scope. */ - function processor() { - var destination = unified() - var length = attachers.length - var index = -1 - - while (++index < length) { - destination.use.apply(null, attachers[index]) - } - - destination.data(extend(true, {}, namespace)) - - return destination - } - - /* Freeze: used to signal a processor that has finished - * configuration. - * - * For example, take unified itself. It’s frozen. - * Plug-ins should not be added to it. Rather, it should - * be extended, by invoking it, before modifying it. - * - * In essence, always invoke this when exporting a - * processor. */ - function freeze() { - var values - var plugin - var options - var transformer - - if (frozen) { - return processor - } - - while (++freezeIndex < attachers.length) { - values = attachers[freezeIndex] - plugin = values[0] - options = values[1] - transformer = null - - if (options === false) { - continue - } - - if (options === true) { - values[1] = undefined - } - - transformer = plugin.apply(processor, values.slice(1)) - - if (typeof transformer === 'function') { - transformers.use(transformer) - } - } - - frozen = true - freezeIndex = Infinity - - return processor - } - - /* Data management. - * Getter / setter for processor-specific informtion. */ - function data(key, value) { - if (string(key)) { - /* Set `key`. */ - if (arguments.length === 2) { - assertUnfrozen('data', frozen) - - namespace[key] = value - - return processor - } - - /* Get `key`. */ - return (own.call(namespace, key) && namespace[key]) || null - } - - /* Set space. */ - if (key) { - assertUnfrozen('data', frozen) - namespace = key - return processor - } - - /* Get space. */ - return namespace - } - - /* Plug-in management. - * - * Pass it: - * * an attacher and options, - * * a preset, - * * a list of presets, attachers, and arguments (list - * of attachers and options). */ - function use(value) { - var settings - - assertUnfrozen('use', frozen) - - if (value === null || value === undefined) { - /* Empty */ - } else if (typeof value === 'function') { - addPlugin.apply(null, arguments) - } else if (typeof value === 'object') { - if ('length' in value) { - addList(value) - } else { - addPreset(value) - } - } else { - throw new Error('Expected usable value, not `' + value + '`') - } - - if (settings) { - namespace.settings = extend(namespace.settings || {}, settings) - } - - return processor - - function addPreset(result) { - addList(result.plugins) - - if (result.settings) { - settings = extend(settings || {}, result.settings) - } - } - - function add(value) { - if (typeof value === 'function') { - addPlugin(value) - } else if (typeof value === 'object') { - if ('length' in value) { - addPlugin.apply(null, value) - } else { - addPreset(value) - } - } else { - throw new Error('Expected usable value, not `' + value + '`') - } - } - - function addList(plugins) { - var length - var index - - if (plugins === null || plugins === undefined) { - /* Empty */ - } else if (typeof plugins === 'object' && 'length' in plugins) { - length = plugins.length - index = -1 - - while (++index < length) { - add(plugins[index]) - } - } else { - throw new Error('Expected a list of plugins, not `' + plugins + '`') - } - } - - function addPlugin(plugin, value) { - var entry = find(plugin) - - if (entry) { - if (plain(entry[1]) && plain(value)) { - value = extend(entry[1], value) - } - - entry[1] = value - } else { - attachers.push(slice.call(arguments)) - } - } - } - - function find(plugin) { - var length = attachers.length - var index = -1 - var entry - - while (++index < length) { - entry = attachers[index] - - if (entry[0] === plugin) { - return entry - } - } - } - - /* Parse a file (in string or VFile representation) - * into a Unist node using the `Parser` on the - * processor. */ - function parse(doc) { - var file = vfile(doc) - var Parser - - freeze() - Parser = processor.Parser - assertParser('parse', Parser) - - if (newable(Parser)) { - return new Parser(String(file), file).parse() - } - - return Parser(String(file), file) // eslint-disable-line new-cap - } - - /* Run transforms on a Unist node representation of a file - * (in string or VFile representation), async. */ - function run(node, file, cb) { - assertNode(node) - freeze() - - if (!cb && typeof file === 'function') { - cb = file - file = null - } - - if (!cb) { - return new Promise(executor) - } - - executor(null, cb) - - function executor(resolve, reject) { - transformers.run(node, vfile(file), done) - - function done(err, tree, file) { - tree = tree || node - if (err) { - reject(err) - } else if (resolve) { - resolve(tree) - } else { - cb(null, tree, file) - } - } - } - } - - /* Run transforms on a Unist node representation of a file - * (in string or VFile representation), sync. */ - function runSync(node, file) { - var complete = false - var result - - run(node, file, done) - - assertDone('runSync', 'run', complete) - - return result - - function done(err, tree) { - complete = true - bail(err) - result = tree - } - } - - /* Stringify a Unist node representation of a file - * (in string or VFile representation) into a string - * using the `Compiler` on the processor. */ - function stringify(node, doc) { - var file = vfile(doc) - var Compiler - - freeze() - Compiler = processor.Compiler - assertCompiler('stringify', Compiler) - assertNode(node) - - if (newable(Compiler)) { - return new Compiler(node, file).compile() - } - - return Compiler(node, file) // eslint-disable-line new-cap - } - - /* Parse a file (in string or VFile representation) - * into a Unist node using the `Parser` on the processor, - * then run transforms on that node, and compile the - * resulting node using the `Compiler` on the processor, - * and store that result on the VFile. */ - function process(doc, cb) { - freeze() - assertParser('process', processor.Parser) - assertCompiler('process', processor.Compiler) - - if (!cb) { - return new Promise(executor) - } - - executor(null, cb) - - function executor(resolve, reject) { - var file = vfile(doc) - - pipeline.run(processor, {file: file}, done) - - function done(err) { - if (err) { - reject(err) - } else if (resolve) { - resolve(file) - } else { - cb(null, file) - } - } - } - } - - /* Process the given document (in string or VFile - * representation), sync. */ - function processSync(doc) { - var complete = false - var file - - freeze() - assertParser('processSync', processor.Parser) - assertCompiler('processSync', processor.Compiler) - file = vfile(doc) - - process(file, done) - - assertDone('processSync', 'process', complete) - - return file - - function done(err) { - complete = true - bail(err) - } - } -} - -/* Check if `func` is a constructor. */ -function newable(value) { - return typeof value === 'function' && keys(value.prototype) -} - -/* Check if `value` is an object with keys. */ -function keys(value) { - var key - for (key in value) { - return true - } - return false -} - -/* Assert a parser is available. */ -function assertParser(name, Parser) { - if (typeof Parser !== 'function') { - throw new Error('Cannot `' + name + '` without `Parser`') - } -} - -/* Assert a compiler is available. */ -function assertCompiler(name, Compiler) { - if (typeof Compiler !== 'function') { - throw new Error('Cannot `' + name + '` without `Compiler`') - } -} - -/* Assert the processor is not frozen. */ -function assertUnfrozen(name, frozen) { - if (frozen) { - throw new Error( - [ - 'Cannot invoke `' + name + '` on a frozen processor.\nCreate a new ', - 'processor first, by invoking it: use `processor()` instead of ', - '`processor`.' - ].join('') - ) - } -} - -/* Assert `node` is a Unist node. */ -function assertNode(node) { - if (!node || !string(node.type)) { - throw new Error('Expected node, got `' + node + '`') - } -} - -/* Assert that `complete` is `true`. */ -function assertDone(name, asyncName, complete) { - if (!complete) { - throw new Error( - '`' + name + '` finished async. Use `' + asyncName + '` instead' - ) - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unified/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/unified/package.json deleted file mode 100644 index 21777216934520..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unified/package.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "name": "unified", - "version": "6.2.0", - "description": "Pluggable text processing interface", - "license": "MIT", - "keywords": [ - "process", - "parse", - "transform", - "compile", - "stringify", - "rehype", - "retext", - "remark" - ], - "repository": "unifiedjs/unified", - "bugs": "https://github.com/unifiedjs/unified/issues", - "author": "Titus Wormer (http://wooorm.com)", - "contributors": [ - "Titus Wormer (http://wooorm.com)" - ], - "files": [ - "index.js", - "lib" - ], - "dependencies": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^1.1.0", - "trough": "^1.0.0", - "vfile": "^2.0.0", - "x-is-string": "^0.1.0" - }, - "devDependencies": { - "browserify": "^16.0.0", - "esmangle": "^1.0.0", - "nyc": "^11.0.0", - "prettier": "^1.12.1", - "remark-cli": "^5.0.0", - "remark-preset-wooorm": "^4.0.0", - "tape": "^4.4.0", - "xo": "^0.20.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write '**/*.js' && xo --fix", - "build-bundle": "browserify index.js -s unified > unified.js", - "build-mangle": "esmangle unified.js > unified.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "rules": { - "guard-for-in": "off", - "no-var": "off", - "object-shorthand": "off", - "prefer-arrow-callback": "off", - "unicorn/prefer-type-error": "off" - }, - "ignores": [ - "unified.js" - ] - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unified/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/unified/readme.md deleted file mode 100644 index e979e0b3629447..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unified/readme.md +++ /dev/null @@ -1,993 +0,0 @@ -# ![unified][logo] - -[![Build Status][travis-badge]][travis] -[![Coverage Status][codecov-badge]][codecov] -[![Chat][chat-badge]][chat] - -**unified** is an interface for processing text using syntax trees. It’s what -powers [**remark**][remark], [**retext**][retext], and [**rehype**][rehype], -but it also allows for processing between multiple syntaxes. - -The website for **unified**, [`unifiedjs.github.io`][site], provides a less -technical and more practical introduction to unified. Make sure to visit it -and try its introductory [Guides][]. - -## Installation - -[npm][]: - -```bash -npm install unified -``` - -## Usage - -```js -var unified = require('unified') -var markdown = require('remark-parse') -var remark2rehype = require('remark-rehype') -var doc = require('rehype-document') -var format = require('rehype-format') -var html = require('rehype-stringify') -var report = require('vfile-reporter') - -unified() - .use(markdown) - .use(remark2rehype) - .use(doc) - .use(format) - .use(html) - .process('# Hello world!', function(err, file) { - console.error(report(err || file)) - console.log(String(file)) - }) -``` - -Yields: - -```html -no issues found - - - - - - - -

Hello world!

- - -``` - -## Table of Contents - -* [Description](#description) -* [API](#api) - * [processor()](#processor) - * [processor.use(plugin\[, options\])](#processoruseplugin-options) - * [processor.parse(file|value)](#processorparsefilevalue) - * [processor.stringify(node\[, file\])](#processorstringifynode-file) - * [processor.run(node\[, file\]\[, done\])](#processorrunnode-file-done) - * [processor.runSync(node\[, file\])](#processorrunsyncnode-file) - * [processor.process(file|value\[, done\])](#processorprocessfilevalue-done) - * [processor.processSync(file|value)](#processorprocesssyncfilevalue) - * [processor.data(key\[, value\])](#processordatakey-value) - * [processor.freeze()](#processorfreeze) -* [Plugin](#plugin) - * [function attacher(\[options\])](#function-attacheroptions) - * [function transformer(node, file\[, next\])](#function-transformernode-file-next) -* [Preset](#preset) -* [Contribute](#contribute) -* [Acknowledgments](#acknowledgments) -* [License](#license) - -## Description - -**unified** is an interface for processing text using syntax trees. Syntax -trees are a representation understandable to programs. Those programs, called -[**plugin**][plugin]s, take these trees and modify them, amongst other things. -To get to the syntax tree from input text there’s a [**parser**][parser]. To -get from that back to text there’s a [**compiler**][compiler]. This is the -[**process**][process] of a **processor**. - -```ascii -| ....................... process() ......................... | -| ......... parse() ..... | run() | ..... stringify() ....... | - - +--------+ +----------+ -Input ->- | Parser | ->- Syntax Tree ->- | Compiler | ->- Output - +--------+ | +----------+ - X - | - +--------------+ - | Transformers | - +--------------+ -``` - -###### Processors - -Every processor implements another processor. To create a new processor invoke -another processor. This creates a processor that is configured to function the -same as its ancestor. But when the descendant processor is configured in the -future it does not affect the ancestral processor. - -When processors are exposed from a module (for example, unified itself) they -should not be configured directly, as that would change their behaviour for all -module users. Those processors are [**frozen**][freeze] and they should be -invoked to create a new processor before they are used. - -###### Node - -The syntax trees used in **unified** are [**Unist**][unist] nodes: plain -JavaScript objects with a `type` property. The semantics of those `type`s are -defined by other projects. - -There are several [utilities][unist-utilities] for working with these nodes. - -###### List of Processors - -The following projects process different syntax trees. They parse text to -their respective syntax tree and they compile their syntax trees back to text. -These processors can be used as-is, or their parsers and compilers can be mixed -and matched with **unified** and other plugins to process between different -syntaxes. - -* [**rehype**][rehype] ([**HAST**][hast]) — HTML -* [**remark**][remark] ([**MDAST**][mdast]) — Markdown -* [**retext**][retext] ([**NLCST**][nlcst]) — Natural language - -###### List of Plugins - -The below plugins work with **unified**, unrelated to what flavour the syntax -tree is in: - -* [`unified-diff`](https://github.com/unifiedjs/unified-diff) - — Ignore messages for unchanged lines in Travis - -See [**remark**][remark-plugins], [**rehype**][rehype-plugins], and -[**retext**][retext-plugins] for lists of their plugins. - -###### File - -When processing documents metadata is often gathered about that document. -[**VFile**][vfile] is a virtual file format which stores data and handles -metadata and messages for **unified** and its plugins. - -There are several [utilities][vfile-utilities] for working with these files. - -###### Configuration - -To configure a processor invoke its [`use`][use] method, supply it a -[**plugin**][plugin], and optionally settings. - -###### Integrations - -**unified** can integrate with the file-system through -[`unified-engine`][engine]. On top of that, CLI apps can be created with -[`unified-args`][args], Gulp plugins with [`unified-engine-gulp`][gulp], and -Atom Linters with [`unified-engine-atom`][atom]. - -A streaming interface is provided through [`unified-stream`][stream]. - -###### Programming interface - -The API gives access to processing metadata (such as lint messages) and -supports multiple passed through files: - -```js -var unified = require('unified') -var markdown = require('remark-parse') -var styleGuide = require('remark-preset-lint-markdown-style-guide') -var remark2retext = require('remark-retext') -var english = require('retext-english') -var equality = require('retext-equality') -var remark2rehype = require('remark-rehype') -var html = require('rehype-stringify') -var report = require('vfile-reporter') - -unified() - .use(markdown) - .use(styleGuide) - .use( - remark2retext, - unified() - .use(english) - .use(equality) - ) - .use(remark2rehype) - .use(html) - .process('*Emphasis* and _importance_, you guys!', function(err, file) { - console.error(report(err || file)) - console.log(String(file)) - }) -``` - -Yields: - -```txt - 1:16-1:28 warning Emphasis should use `*` as a marker emphasis-marker remark-lint - 1:34-1:38 warning `guys` may be insensitive, use `people`, `persons`, `folks` instead gals-men retext-equality - -⚠ 2 warnings -

Emphasis and importance, you guys!

-``` - -###### Processing between syntaxes - -The processors can be combined in two modes. - -**Bridge** mode transforms the syntax tree from one flavour (the origin) to -another (the destination). Then, transformations are applied on that tree. -Finally, the origin processor continues transforming the original syntax tree. - -**Mutate** mode also transforms the syntax tree from one flavour to another. -But then the origin processor continues transforming the destination syntax -tree. - -In the previous example (“Programming interface”), `remark-retext` is used in -bridge mode: the origin syntax tree is kept after retext is done; whereas -`remark-rehype` is used in mutate mode: it sets a new syntax tree and discards -the original. - -* [`remark-retext`][remark-retext] -* [`remark-rehype`][remark-rehype] -* [`rehype-retext`][rehype-retext] -* [`rehype-remark`][rehype-remark] - -## API - -### `processor()` - -Object describing how to process text. - -###### Returns - -`Function` — New [**unfrozen**][freeze] processor which is configured to -function the same as its ancestor. But when the descendant processor is -configured in the future it does not affect the ancestral processor. - -###### Example - -The following example shows how a new processor can be created (from the remark -processor) and linked to **stdin**(4) and **stdout**(4). - -```js -var remark = require('remark') -var concat = require('concat-stream') - -process.stdin.pipe(concat(onconcat)) - -function onconcat(buf) { - var doc = remark() - .processSync(buf) - .toString() - - process.stdout.write(doc) -} -``` - -### `processor.use(plugin[, options])` - -Configure the processor to use a [**plugin**][plugin] and optionally configure -that plugin with options. - -###### Signatures - -* `processor.use(plugin[, options])` -* `processor.use(preset)` -* `processor.use(list)` - -###### Parameters - -* `plugin` ([`Plugin`][plugin]) -* `options` (`*`, optional) — Configuration for `plugin` -* `preset` (`Object`) — Object with an optional `plugins` (set to `list`), - and/or an optional `settings` object -* `list` (`Array`) — List of plugins, presets, and pairs (`plugin` and - `options` in an array) - -###### Returns - -`processor` — The processor on which `use` is invoked. - -###### Note - -`use` cannot be called on [frozen][freeze] processors. Invoke the processor -first to create a new unfrozen processor. - -###### Example - -There are many ways to pass plugins to `.use()`. The below example gives an -overview. - -```js -var unified = require('unified') - -unified() - // Plugin with options: - .use(plugin, {}) - // Plugins: - .use([plugin, pluginB]) - // Two plugins, the second with options: - .use([plugin, [pluginB, {}]]) - // Preset with plugins and settings: - .use({plugins: [plugin, [pluginB, {}]], settings: {position: false}}) - // Settings only: - .use({settings: {position: false}}) - -function plugin() {} -function pluginB() {} -``` - -### `processor.parse(file|value)` - -Parse text to a syntax tree. - -###### Parameters - -* `file` ([`VFile`][file]) - — Or anything which can be given to `vfile()` - -###### Returns - -[`Node`][node] — Syntax tree representation of input. - -###### Note - -`parse` [freezes][freeze] the processor if not already frozen. - -#### `processor.Parser` - -Function handling the parsing of text to a syntax tree. Used in the -[**parse**][parse] phase in the process and invoked with a `string` and -[`VFile`][file] representation of the document to parse. - -`Parser` can be a normal function in which case it must return a -[`Node`][node]: the syntax tree representation of the given file. - -`Parser` can also be a constructor function (a function with keys in its -`prototype`) in which case it’s invoked with `new`. Instances must have a -`parse` method which is invoked without arguments and must return a -[`Node`][node]. - -### `processor.stringify(node[, file])` - -Compile a syntax tree to text. - -###### Parameters - -* `node` ([`Node`][node]) -* `file` ([`VFile`][file], optional); - — Or anything which can be given to `vfile()` - -###### Returns - -`string` — String representation of the syntax tree file. - -###### Note - -`stringify` [freezes][freeze] the processor if not already frozen. - -#### `processor.Compiler` - -Function handling the compilation of syntax tree to a text. Used in the -[**stringify**][stringify] phase in the process and invoked with a -[`Node`][node] and [`VFile`][file] representation of the document to stringify. - -`Compiler` can be a normal function in which case it must return a `string`: -the text representation of the given syntax tree. - -`Compiler` can also be a constructor function (a function with keys in its -`prototype`) in which case it’s invoked with `new`. Instances must have a -`compile` method which is invoked without arguments and must return a `string`. - -### `processor.run(node[, file][, done])` - -Transform a syntax tree by applying [**plugin**][plugin]s to it. - -###### Parameters - -* `node` ([`Node`][node]) -* `file` ([`VFile`][file], optional) - — Or anything which can be given to `vfile()` -* `done` ([`Function`][run-done], optional) - -###### Returns - -[`Promise`][promise] if `done` is not given. Rejected with an error, or -resolved with the resulting syntax tree. - -###### Note - -`run` [freezes][freeze] the processor if not already frozen. - -##### `function done(err[, node, file])` - -Invoked when transformation is complete. Either invoked with an error or a -syntax tree and a file. - -###### Parameters - -* `err` (`Error`) — Fatal error -* `node` ([`Node`][node]) -* `file` ([`VFile`][file]) - -### `processor.runSync(node[, file])` - -Transform a syntax tree by applying [**plugin**][plugin]s to it. - -If asynchronous [**plugin**][plugin]s are configured an error is thrown. - -###### Parameters - -* `node` ([`Node`][node]) -* `file` ([`VFile`][file], optional) - — Or anything which can be given to `vfile()` - -###### Returns - -[`Node`][node] — The given syntax tree. - -###### Note - -`runSync` [freezes][freeze] the processor if not already frozen. - -### `processor.process(file|value[, done])` - -Process the given representation of a file as configured on the processor. The -process invokes `parse`, `run`, and `stringify` internally. - -###### Parameters - -* `file` ([`VFile`][file]) -* `value` (`string`) — String representation of a file -* `done` ([`Function`][process-done], optional) - -###### Returns - -[`Promise`][promise] if `done` is not given. Rejected with an error or -resolved with the resulting file. - -###### Note - -`process` [freezes][freeze] the processor if not already frozen. - -#### `function done(err, file)` - -Invoked when the process is complete. Invoked with a fatal error, if any, and -the [`VFile`][file]. - -###### Parameters - -* `err` (`Error`, optional) — Fatal error -* `file` ([`VFile`][file]) - -###### Example - -```js -var unified = require('unified') -var markdown = require('remark-parse') -var remark2rehype = require('remark-rehype') -var doc = require('rehype-document') -var format = require('rehype-format') -var html = require('rehype-stringify') - -unified() - .use(markdown) - .use(remark2rehype) - .use(doc) - .use(format) - .use(html) - .process('# Hello world!') - .then( - function(file) { - console.log(String(file)) - }, - function(err) { - console.error(String(err)) - } - ) -``` - -Yields: - -```html - - - - - - - -

Hello world!

- - -``` - -### `processor.processSync(file|value)` - -Process the given representation of a file as configured on the processor. The -process invokes `parse`, `run`, and `stringify` internally. - -If asynchronous [**plugin**][plugin]s are configured an error is thrown. - -###### Parameters - -* `file` ([`VFile`][file]) -* `value` (`string`) — String representation of a file - -###### Returns - -[`VFile`][file] — Virtual file with modified [`contents`][vfile-contents]. - -###### Note - -`processSync` [freezes][freeze] the processor if not already frozen. - -###### Example - -```js -var unified = require('unified') -var markdown = require('remark-parse') -var remark2rehype = require('remark-rehype') -var doc = require('rehype-document') -var format = require('rehype-format') -var html = require('rehype-stringify') - -var processor = unified() - .use(markdown) - .use(remark2rehype) - .use(doc) - .use(format) - .use(html) - -console.log(processor.processSync('# Hello world!').toString()) -``` - -Yields: - -```html - - - - - - - -

Hello world!

- - -``` - -### `processor.data(key[, value])` - -Get or set information in an in-memory key-value store accessible to all phases -of the process. An example is a list of HTML elements which are self-closing, -which is needed when parsing, transforming, and compiling HTML. - -###### Parameters - -* `key` (`string`) — Identifier -* `value` (`*`, optional) — Value to set. Omit if getting `key` - -###### Returns - -* `processor` — If setting, the processor on which `data` is invoked -* `*` — If getting, the value at `key` - -###### Note - -Setting information with `data` cannot occur on [frozen][freeze] processors. -Invoke the processor first to create a new unfrozen processor. - -###### Example - -The following example show how to get and set information: - -```js -var unified = require('unified') - -console.log( - unified() - .data('alpha', 'bravo') - .data('alpha') -) -``` - -Yields: - -```txt -bravo -``` - -### `processor.freeze()` - -Freeze a processor. Frozen processors are meant to be extended and not to be -configured or processed directly. - -Once a processor is frozen it cannot be unfrozen. New processors functioning -just like it can be created by invoking the processor. - -It’s possible to freeze processors explicitly, by calling `.freeze()`, but -[`.parse()`][parse], [`.run()`][run], [`.stringify()`][stringify], and -[`.process()`][process] call `.freeze()` to freeze a processor too. - -###### Returns - -`Processor` — The processor on which `freeze` is invoked. - -###### Example - -The following example, `index.js`, shows how [**rehype**][rehype] prevents -extensions to itself: - -```js -var unified = require('unified') -var parse = require('rehype-parse') -var stringify = require('rehype-stringify') - -module.exports = unified() - .use(parse) - .use(stringify) - .freeze() -``` - -The below example, `a.js`, shows how that processor can be used and configured. - -```js -var rehype = require('rehype') -var format = require('rehype-format') -// ... - -rehype() - .use(format) - // ... -``` - -The below example, `b.js`, shows a similar looking example which operates on -the frozen [**rehype**][rehype] interface. If this behaviour was allowed it -would result in unexpected behaviour so an error is thrown. **This is -invalid**: - -```js -var rehype = require('rehype') -var format = require('rehype-format') -// ... - -rehype - .use(format) - // ... -``` - -Yields: - -```txt -~/node_modules/unified/index.js:440 - throw new Error( - ^ - -Error: Cannot invoke `use` on a frozen processor. -Create a new processor first, by invoking it: use `processor()` instead of `processor`. - at assertUnfrozen (~/node_modules/unified/index.js:440:11) - at Function.use (~/node_modules/unified/index.js:172:5) - at Object. (~/b.js:6:4) -``` - -## `Plugin` - -**unified** plugins change the way the applied-on processor works in the -following ways: - -* They modify the [**processor**][processor]: such as changing the parser, - the compiler, or linking it to other processors -* They transform [**syntax tree**][node] representation of files -* They modify metadata of files - -Plugins are a concept. They materialise as [`attacher`][attacher]s. - -###### Example - -`move.js`: - -```js -module.exports = move - -function move(options) { - var expected = (options || {}).extname - - if (!expected) { - throw new Error('Missing `extname` in options') - } - - return transformer - - function transformer(tree, file) { - if (file.extname && file.extname !== expected) { - file.extname = expected - } - } -} -``` - -`index.js`: - -```js -var unified = require('unified') -var parse = require('remark-parse') -var remark2rehype = require('remark-rehype') -var stringify = require('rehype-stringify') -var vfile = require('to-vfile') -var report = require('vfile-reporter') -var move = require('./move') - -unified() - .use(parse) - .use(remark2rehype) - .use(move, {extname: '.html'}) - .use(stringify) - .process(vfile.readSync('index.md'), function(err, file) { - console.error(report(err || file)) - if (file) { - vfile.writeSync(file) // Written to `index.html`. - } - }) -``` - -### `function attacher([options])` - -An attacher is the thing passed to [`use`][use]. It configures the processor -and in turn can receive options. - -Attachers can configure processors, such as by interacting with parsers and -compilers, linking them to other processors, or by specifying how the syntax -tree is handled. - -###### Context - -The context object is set to the invoked on [`processor`][processor]. - -###### Parameters - -* `options` (`*`, optional) — Configuration - -###### Returns - -[`transformer`][transformer] — Optional. - -###### Note - -Attachers are invoked when the processor is [frozen][freeze]: either when -`.freeze()` is called explicitly, or when [`.parse()`][parse], [`.run()`][run], -[`.stringify()`][stringify], or [`.process()`][process] is called for the first -time. - -### `function transformer(node, file[, next])` - -Transformers modify the syntax tree or metadata of a file. A transformer is a -function which is invoked each time a file is passed through the transform -phase. If an error occurs (either because it’s thrown, returned, rejected, or -passed to [`next`][next]), the process stops. - -The transformation process in **unified** is handled by [`trough`][trough], see -it’s documentation for the exact semantics of transformers. - -###### Parameters - -* `node` ([`Node`][node]) -* `file` ([`VFile`][file]) -* `next` ([`Function`][next], optional) - -###### Returns - -* `Error` — Can be returned to stop the process -* [`Node`][node] — Can be returned and results in further transformations - and `stringify`s to be performed on the new tree -* `Promise` — If a promise is returned, the function is asynchronous, and - **must** be resolved (optionally with a [`Node`][node]) or rejected - (optionally with an `Error`) - -#### `function next(err[, tree[, file]])` - -If the signature of a transformer includes `next` (third argument), the -function **may** finish asynchronous, and **must** invoke `next()`. - -###### Parameters - -* `err` (`Error`, optional) — Stop the process -* `node` ([`Node`][node], optional) — New syntax tree -* `file` ([`VFile`][file], optional) — New virtual file - -## `Preset` - -Presets provide a potentially sharable way to configure processors. They can -contain multiple plugins and optionally settings as well. - -###### Example - -`preset.js`: - -```js -exports.settings = {bullet: '*', fences: true} - -exports.plugins = [ - require('remark-preset-lint-recommended'), - require('remark-comment-config'), - require('remark-preset-lint-markdown-style-guide'), - [require('remark-toc'), {maxDepth: 3, tight: true}], - require('remark-github') -] -``` - -`index.js`: - -```js -var remark = require('remark') -var vfile = require('to-vfile') -var report = require('vfile-reporter') -var preset = require('./preset') - -remark() - .use(preset) - .process(vfile.readSync('index.md'), function(err, file) { - console.error(report(err || file)) - - if (file) { - vfile.writeSync(file) - } - }) -``` - -## Contribute - -**unified** is built by people just like you! Check out -[`contributing.md`][contributing] for ways to get started. - -This project has a [Code of Conduct][coc]. By interacting with this repository, -organisation, or community you agree to abide by its terms. - -Want to chat with the community and contributors? Join us in [Gitter][chat]! - -Have an idea for a cool new utility or tool? That’s great! If you want -feedback, help, or just to share it with the world you can do so by creating -an issue in the [`unifiedjs/ideas`][ideas] repository! - -## Acknowledgments - -Preliminary work for unified was done [in 2014][preliminary] for -[**retext**][retext] and inspired by [`ware`][ware]. Further incubation -happened in [**remark**][remark]. The project was finally [externalised][] -in 2015 and [published][] as `unified`. The project was authored by -[**@wooorm**](https://github.com/wooorm). - -Although `unified` since moved it’s plugin architecture to [`trough`][trough], -thanks to [**@calvinfo**](https://github.com/calvinfo), -[**@ianstormtaylor**](https://github.com/ianstormtaylor), and others for their -work on [`ware`][ware], which was a huge initial inspiration. - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[logo]: https://cdn.rawgit.com/unifiedjs/unified/0cd3a41/logo.svg - -[travis-badge]: https://img.shields.io/travis/unifiedjs/unified.svg - -[travis]: https://travis-ci.org/unifiedjs/unified - -[codecov-badge]: https://img.shields.io/codecov/c/github/unifiedjs/unified.svg - -[codecov]: https://codecov.io/github/unifiedjs/unified - -[chat-badge]: https://img.shields.io/gitter/room/unifiedjs/Lobby.svg - -[chat]: https://gitter.im/unifiedjs/Lobby - -[npm]: https://docs.npmjs.com/cli/install - -[license]: LICENSE - -[author]: http://wooorm.com - -[site]: https://unifiedjs.github.io - -[guides]: https://unifiedjs.github.io/#guides - -[rehype]: https://github.com/rehypejs/rehype - -[remark]: https://github.com/remarkjs/remark - -[retext]: https://github.com/retextjs/retext - -[hast]: https://github.com/syntax-tree/hast - -[mdast]: https://github.com/syntax-tree/mdast - -[nlcst]: https://github.com/syntax-tree/nlcst - -[unist]: https://github.com/syntax-tree/unist - -[engine]: https://github.com/unifiedjs/unified-engine - -[args]: https://github.com/unifiedjs/unified-args - -[gulp]: https://github.com/unifiedjs/unified-engine-gulp - -[atom]: https://github.com/unifiedjs/unified-engine-atom - -[remark-rehype]: https://github.com/remarkjs/remark-rehype - -[remark-retext]: https://github.com/remarkjs/remark-retext - -[rehype-retext]: https://github.com/rehypejs/rehype-retext - -[rehype-remark]: https://github.com/rehypejs/rehype-remark - -[unist-utilities]: https://github.com/syntax-tree/unist#list-of-utilities - -[vfile]: https://github.com/vfile/vfile - -[vfile-contents]: https://github.com/vfile/vfile#vfilecontents - -[vfile-utilities]: https://github.com/vfile/vfile#related-tools - -[file]: #file - -[node]: #node - -[processor]: #processor - -[process]: #processorprocessfilevalue-done - -[parse]: #processorparsefilevalue - -[parser]: #processorparser - -[stringify]: #processorstringifynode-file - -[run]: #processorrunnode-file-done - -[compiler]: #processorcompiler - -[use]: #processoruseplugin-options - -[attacher]: #function-attacheroptions - -[transformer]: #function-transformernode-file-next - -[next]: #function-nexterr-tree-file - -[freeze]: #processorfreeze - -[plugin]: #plugin - -[run-done]: #function-doneerr-node-file - -[process-done]: #function-doneerr-file - -[trough]: https://github.com/wooorm/trough#function-fninput-next - -[promise]: https://developer.mozilla.org/Web/JavaScript/Reference/Global_Objects/Promise - -[remark-plugins]: https://github.com/remarkjs/remark/blob/master/doc/plugins.md#list-of-plugins - -[rehype-plugins]: https://github.com/rehypejs/rehype/blob/master/doc/plugins.md#list-of-plugins - -[retext-plugins]: https://github.com/retextjs/retext/blob/master/doc/plugins.md#list-of-plugins - -[stream]: https://github.com/unifiedjs/unified-stream - -[contributing]: contributing.md - -[coc]: code-of-conduct.md - -[ideas]: https://github.com/unifiedjs/ideas - -[preliminary]: https://github.com/retextjs/retext/commit/8fcb1f#diff-168726dbe96b3ce427e7fedce31bb0bc - -[externalised]: https://github.com/remarkjs/remark/commit/9892ec#diff-168726dbe96b3ce427e7fedce31bb0bc - -[published]: https://github.com/unifiedjs/unified/commit/2ba1cf - -[ware]: https://github.com/segmentio/ware diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-is/convert.js b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-is/convert.js deleted file mode 100644 index f92f34f1051b25..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-is/convert.js +++ /dev/null @@ -1,87 +0,0 @@ -'use strict' - -module.exports = convert - -function convert(test) { - if (typeof test === 'string') { - return typeFactory(test) - } - - if (test === null || test === undefined) { - return ok - } - - if (typeof test === 'object') { - return ('length' in test ? anyFactory : matchesFactory)(test) - } - - if (typeof test === 'function') { - return test - } - - throw new Error('Expected function, string, or object as test') -} - -function convertAll(tests) { - var results = [] - var length = tests.length - var index = -1 - - while (++index < length) { - results[index] = convert(tests[index]) - } - - return results -} - -// Utility assert each property in `test` is represented in `node`, and each -// values are strictly equal. -function matchesFactory(test) { - return matches - - function matches(node) { - var key - - for (key in test) { - if (node[key] !== test[key]) { - return false - } - } - - return true - } -} - -function anyFactory(tests) { - var checks = convertAll(tests) - var length = checks.length - - return matches - - function matches() { - var index = -1 - - while (++index < length) { - if (checks[index].apply(this, arguments)) { - return true - } - } - - return false - } -} - -// Utility to convert a string into a function which checks a given node’s type -// for said string. -function typeFactory(test) { - return type - - function type(node) { - return Boolean(node && node.type === test) - } -} - -// Utility to return true. -function ok() { - return true -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-is/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-is/index.js deleted file mode 100644 index f18d416e08d214..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-is/index.js +++ /dev/null @@ -1,37 +0,0 @@ -'use strict' - -var convert = require('./convert') - -module.exports = is - -is.convert = convert - -// Assert if `test` passes for `node`. -// When a `parent` node is known the `index` of node should also be given. -// eslint-disable-next-line max-params -function is(node, test, index, parent, context) { - var hasParent = parent !== null && parent !== undefined - var hasIndex = index !== null && index !== undefined - var check = convert(test) - - if ( - hasIndex && - (typeof index !== 'number' || index < 0 || index === Infinity) - ) { - throw new Error('Expected positive finite index or child node') - } - - if (hasParent && (!is(parent) || !parent.children)) { - throw new Error('Expected parent node') - } - - if (!node || !node.type || typeof node.type !== 'string') { - return false - } - - if (hasParent !== hasIndex) { - throw new Error('Expected both parent and index') - } - - return Boolean(check.call(context, node, index, parent)) -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-is/license b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-is/license deleted file mode 100644 index cfa79e66cfc072..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-is/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT license) - -Copyright (c) 2015 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-is/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-is/package.json deleted file mode 100644 index 25193acddd8a0d..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-is/package.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "name": "unist-util-is", - "version": "3.0.0", - "description": "Utility to check if a node passes a test", - "license": "MIT", - "keywords": [ - "unist", - "node", - "is", - "equal", - "test", - "type", - "util", - "utility" - ], - "repository": "syntax-tree/unist-util-is", - "bugs": "https://github.com/syntax-tree/unist-util-is/issues", - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "files": [ - "index.js", - "convert.js" - ], - "dependencies": {}, - "devDependencies": { - "browserify": "^16.0.0", - "nyc": "^14.0.0", - "prettier": "^1.0.0", - "remark-cli": "^6.0.0", - "remark-preset-wooorm": "^5.0.0", - "tape": "^4.0.0", - "tinyify": "^2.0.0", - "xo": "^0.24.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify . -s unistUtilIs > unist-util-is.js", - "build-mangle": "browserify . -s unistUtilIs -p tinyify > unist-util-is.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "rules": { - "unicorn/prefer-type-error": "off" - }, - "ignore": [ - "unist-util-is.js" - ] - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-is/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-is/readme.md deleted file mode 100644 index 7d53629aba87db..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-is/readme.md +++ /dev/null @@ -1,202 +0,0 @@ -# unist-util-is - -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] -[![Sponsors][sponsors-badge]][collective] -[![Backers][backers-badge]][collective] -[![Chat][chat-badge]][chat] - -[**unist**][unist] utility to check if a node passes a test. - -## Install - -[npm][]: - -```sh -npm install unist-util-is -``` - -## Usage - -```js -var is = require('unist-util-is') - -var node = {type: 'strong'} -var parent = {type: 'paragraph', children: [node]} - -function test(node, n) { - return n === 5 -} - -is() // => false -is({children: []}) // => false -is(node) // => true -is(node, 'strong') // => true -is(node, 'emphasis') // => false - -is(node, node) // => true -is(parent, {type: 'paragraph'}) // => true -is(parent, {type: 'strong'}) // => false - -is(node, test) // => false -is(node, test, 4, parent) // => false -is(node, test, 5, parent) // => true -``` - -## API - -### `is(node[, test[, index, parent[, context]]])` - -###### Parameters - -* `node` ([`Node`][node]) — Node to check. -* `test` ([`Function`][test], `string`, `Object`, or `Array.`, optional) - — When not given, checks if `node` is a [`Node`][node]. - When `string`, works like passing `node => node.type === test`. - When `array`, checks if any one of the subtests pass. - When `object`, checks that all keys in `test` are in `node`, - and that they have strictly equal values -* `index` (`number`, optional) — [Index][] of `node` in `parent` -* `parent` ([`Node`][node], optional) — [Parent][] of `node` -* `context` (`*`, optional) — Context object to invoke `test` with - -###### Returns - -`boolean` — Whether `test` passed *and* `node` is a [`Node`][node] (object with -`type` set to a non-empty `string`). - -#### `function test(node[, index, parent])` - -###### Parameters - -* `node` ([`Node`][node]) — Node to check -* `index` (`number?`) — [Index][] of `node` in `parent` -* `parent` ([`Node?`][node]) — [Parent][] of `node` - -###### Context - -`*` — The to `is` given `context`. - -###### Returns - -`boolean?` — Whether `node` matches. - -### `is.convert(test)` - -Create a test function from `test`, that can later be called with a `node`, -`index`, and `parent`. -Useful if you’re going to test many nodes, for example when creating a utility -where something else passes an is-compatible test. - -Can also be accessed with `require('unist-util-is/convert')`. - -For example: - -```js -var u = require('unist-builder') -var convert = require('unist-util-is/convert') - -var test = convert('leaf') - -var tree = u('tree', [ - u('node', [u('leaf', '1')]), - u('leaf', '2'), - u('node', [u('leaf', '3'), u('leaf', '4')]), - u('leaf', '5') -]) - -var leafs = tree.children.filter((child, index) => test(child, index, tree)) - -console.log(leafs) -``` - -Yields: - -```js -[({type: 'leaf', value: '2'}, {type: 'leaf', value: '5'})] -``` - -## Related - -* [`unist-util-find-after`](https://github.com/syntax-tree/unist-util-find-after) - — Find a node after another node -* [`unist-util-find-before`](https://github.com/syntax-tree/unist-util-find-before) - — Find a node before another node -* [`unist-util-find-all-after`](https://github.com/syntax-tree/unist-util-find-all-after) - — Find all nodes after another node -* [`unist-util-find-all-before`](https://github.com/syntax-tree/unist-util-find-all-before) - — Find all nodes before another node -* [`unist-util-find-all-between`](https://github.com/mrzmmr/unist-util-find-all-between) - — Find all nodes between two nodes -* [`unist-util-find`](https://github.com/blahah/unist-util-find) - — Find nodes matching a predicate -* [`unist-util-filter`](https://github.com/eush77/unist-util-filter) - — Create a new tree with nodes that pass a check -* [`unist-util-remove`](https://github.com/eush77/unist-util-remove) - — Remove nodes from tree - -## Contribute - -See [`contributing.md` in `syntax-tree/.github`][contributing] for ways to get -started. -See [`support.md`][support] for ways to get help. - -This project has a [Code of Conduct][coc]. -By interacting with this repository, organisation, or community you agree to -abide by its terms. - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/syntax-tree/unist-util-is.svg - -[build]: https://travis-ci.org/syntax-tree/unist-util-is - -[coverage-badge]: https://img.shields.io/codecov/c/github/syntax-tree/unist-util-is.svg - -[coverage]: https://codecov.io/github/syntax-tree/unist-util-is - -[downloads-badge]: https://img.shields.io/npm/dm/unist-util-is.svg - -[downloads]: https://www.npmjs.com/package/unist-util-is - -[size-badge]: https://img.shields.io/bundlephobia/minzip/unist-util-is.svg - -[size]: https://bundlephobia.com/result?p=unist-util-is - -[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg - -[backers-badge]: https://opencollective.com/unified/backers/badge.svg - -[collective]: https://opencollective.com/unified - -[chat-badge]: https://img.shields.io/badge/join%20the%20community-on%20spectrum-7b16ff.svg - -[chat]: https://spectrum.chat/unified/syntax-tree - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com - -[contributing]: https://github.com/syntax-tree/.github/blob/master/contributing.md - -[support]: https://github.com/syntax-tree/.github/blob/master/support.md - -[coc]: https://github.com/syntax-tree/.github/blob/master/code-of-conduct.md - -[unist]: https://github.com/syntax-tree/unist - -[node]: https://github.com/syntax-tree/unist#node - -[parent]: https://github.com/syntax-tree/unist#parent-1 - -[index]: https://github.com/syntax-tree/unist#index - -[test]: #function-testnode-index-parent diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-remove-position/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-remove-position/index.js deleted file mode 100644 index 096395981793d9..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-remove-position/index.js +++ /dev/null @@ -1,18 +0,0 @@ -'use strict' - -var visit = require('unist-util-visit') - -module.exports = removePosition - -function removePosition(node, force) { - visit(node, force ? hard : soft) - return node -} - -function hard(node) { - delete node.position -} - -function soft(node) { - node.position = undefined -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-remove-position/license b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-remove-position/license deleted file mode 100644 index 8d8660d36ef2ec..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-remove-position/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2016 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-remove-position/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-remove-position/package.json deleted file mode 100644 index e1166471c37d6e..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-remove-position/package.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "name": "unist-util-remove-position", - "version": "1.1.4", - "description": "Remove `position`s from a unist tree", - "license": "MIT", - "keywords": [ - "unist", - "utility", - "remove", - "position", - "location" - ], - "repository": "syntax-tree/unist-util-remove-position", - "bugs": "https://github.com/syntax-tree/unist-util-remove-position/issues", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "files": [ - "index.js" - ], - "dependencies": { - "unist-util-visit": "^1.1.0" - }, - "devDependencies": { - "browserify": "^16.0.0", - "nyc": "^14.0.0", - "prettier": "^1.0.0", - "remark": "^11.0.0", - "remark-cli": "^7.0.0", - "remark-preset-wooorm": "^6.0.0", - "tape": "^4.0.0", - "tinyify": "^2.0.0", - "unist-builder": "^2.0.0", - "xo": "^0.25.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify . -s unistUtilRemovePosition > unist-util-remove-position.js", - "build-mangle": "browserify . -s unistUtilRemovePosition -p tinyify > unist-util-remove-position.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "ignores": [ - "unist-util-remove-position.js" - ] - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-remove-position/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-remove-position/readme.md deleted file mode 100644 index e79ed14b35084f..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-remove-position/readme.md +++ /dev/null @@ -1,131 +0,0 @@ -# unist-util-remove-position - -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] -[![Sponsors][sponsors-badge]][collective] -[![Backers][backers-badge]][collective] -[![Chat][chat-badge]][chat] - -[**unist**][unist] utility to remove [`position`][position]s from tree. - -## Install - -[npm][]: - -```sh -npm install unist-util-remove-position -``` - -## Usage - -```js -var remark = require('remark') -var removePosition = require('unist-util-remove-position') - -var tree = remark().parse('Some _emphasis_, **importance**, and `code`.') - -removePosition(tree, true) - -console.dir(tree, {depth: null}) -``` - -Yields: - -```js -{ - type: 'root', - children: [ - { - type: 'paragraph', - children: [ - { type: 'text', value: 'Some ' }, - { - type: 'emphasis', - children: [ { type: 'text', value: 'emphasis' } ] - }, - { type: 'text', value: ', ' }, - { - type: 'strong', - children: [ { type: 'text', value: 'importance' } ] - }, - { type: 'text', value: ', and ' }, - { type: 'inlineCode', value: 'code' }, - { type: 'text', value: '.' } - ] - } - ] -} -``` - -## API - -### `removePosition(node[, force])` - -Remove [`position`][position]s from [`node`][node]. -If `force` is given, uses `delete`, otherwise, sets `position`s to `undefined`. - -###### Returns - -The given `node`. - -## Contribute - -See [`contributing.md` in `syntax-tree/.github`][contributing] for ways to get -started. -See [`support.md`][support] for ways to get help. - -This project has a [Code of Conduct][coc]. -By interacting with this repository, organisation, or community you agree to -abide by its terms. - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/syntax-tree/unist-util-remove-position.svg - -[build]: https://travis-ci.org/syntax-tree/unist-util-remove-position - -[coverage-badge]: https://img.shields.io/codecov/c/github/syntax-tree/unist-util-remove-position.svg - -[coverage]: https://codecov.io/github/syntax-tree/unist-util-remove-position - -[downloads-badge]: https://img.shields.io/npm/dm/unist-util-remove-position.svg - -[downloads]: https://www.npmjs.com/package/unist-util-remove-position - -[size-badge]: https://img.shields.io/bundlephobia/minzip/unist-util-remove-position.svg - -[size]: https://bundlephobia.com/result?p=unist-util-remove-position - -[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg - -[backers-badge]: https://opencollective.com/unified/backers/badge.svg - -[collective]: https://opencollective.com/unified - -[chat-badge]: https://img.shields.io/badge/join%20the%20community-on%20spectrum-7b16ff.svg - -[chat]: https://spectrum.chat/unified/syntax-tree - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com - -[contributing]: https://github.com/syntax-tree/.github/blob/master/contributing.md - -[support]: https://github.com/syntax-tree/.github/blob/master/support.md - -[coc]: https://github.com/syntax-tree/.github/blob/master/code-of-conduct.md - -[unist]: https://github.com/syntax-tree/unist - -[position]: https://github.com/syntax-tree/unist#position - -[node]: https://github.com/syntax-tree/unist#node diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-stringify-position/LICENSE b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-stringify-position/LICENSE deleted file mode 100644 index 8d8660d36ef2ec..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-stringify-position/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2016 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-stringify-position/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-stringify-position/index.js deleted file mode 100644 index 3be1e14276cf79..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-stringify-position/index.js +++ /dev/null @@ -1,50 +0,0 @@ -'use strict' - -var own = {}.hasOwnProperty - -module.exports = stringify - -function stringify(value) { - /* Nothing. */ - if (!value || typeof value !== 'object') { - return null - } - - /* Node. */ - if (own.call(value, 'position') || own.call(value, 'type')) { - return position(value.position) - } - - /* Position. */ - if (own.call(value, 'start') || own.call(value, 'end')) { - return position(value) - } - - /* Point. */ - if (own.call(value, 'line') || own.call(value, 'column')) { - return point(value) - } - - /* ? */ - return null -} - -function point(point) { - if (!point || typeof point !== 'object') { - point = {} - } - - return index(point.line) + ':' + index(point.column) -} - -function position(pos) { - if (!pos || typeof pos !== 'object') { - pos = {} - } - - return point(pos.start) + '-' + point(pos.end) -} - -function index(value) { - return value && typeof value === 'number' ? value : 1 -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-stringify-position/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-stringify-position/package.json deleted file mode 100644 index 2e20b672051031..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-stringify-position/package.json +++ /dev/null @@ -1,77 +0,0 @@ -{ - "name": "unist-util-stringify-position", - "version": "1.1.2", - "description": "Stringify a Unist node, position, or point", - "license": "MIT", - "keywords": [ - "unist", - "position", - "location", - "point", - "node", - "stringify", - "tostring", - "util", - "utility" - ], - "repository": "syntax-tree/unist-util-stringify-position", - "bugs": "https://github.com/syntax-tree/unist-util-stringify-position/issues", - "author": "Titus Wormer (http://wooorm.com)", - "contributors": [ - "Titus Wormer (http://wooorm.com)" - ], - "files": [ - "index.js" - ], - "dependencies": {}, - "devDependencies": { - "browserify": "^16.0.0", - "esmangle": "^1.0.0", - "nyc": "^11.0.0", - "prettier": "^1.12.1", - "remark-cli": "^5.0.0", - "remark-preset-wooorm": "^4.0.0", - "tape": "^4.5.1", - "xo": "^0.20.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write '**/*.js' && xo --fix", - "build-bundle": "browserify index.js --no-builtins -s unistUtilStringifyPosition > unist-util-stringify-position.js", - "build-mangle": "esmangle unist-util-stringify-position.js > unist-util-stringify-position.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "rules": { - "guard-for-in": "off", - "no-var": "off", - "prefer-arrow-callback": "off" - }, - "ignores": [ - "unist-util-stringify-position.js" - ] - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-stringify-position/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-stringify-position/readme.md deleted file mode 100644 index 85c753b5e1b47d..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-stringify-position/readme.md +++ /dev/null @@ -1,100 +0,0 @@ -# unist-util-stringify-position [![Build Status][build-badge]][build-page] [![Coverage Status][coverage-badge]][coverage-page] - -Stringify a [**Unist**][unist] [`Position`][position] or [`Point`][point]. - -## Installation - -[npm][]: - -```bash -npm install unist-util-stringify-position -``` - -## Usage - -```javascript -var stringify = require('unist-util-stringify-position') - -// Point -stringify({line: 2, column: 3}) // => '2:3' - -// Position -stringify({ - start: {line: 2}, - end: {line: 3} -}) // => '2:1-3:1' - -// Node -stringify({ - type: 'text', - value: '!', - position: { - start: {line: 5, column: 11}, - end: {line: 5, column: 12} - } -}) // => '5:11-5:12' -``` - -## API - -### `stringifyPosition(node|position|point)` - -Stringify one point, a position (start and end points), or -a node’s position. - -###### Parameters - -* `node` ([`Node`][node]) - — Node whose `'position'` property to stringify -* `position` ([`Position`][position]) - — Position whose `'start'` and `'end'` points to stringify -* `point` ([`Point`][point]) - — Point whose `'line'` and `'column'` to stringify - -###### Returns - -`string?` — A range `ls:cs-le:ce` (when given `node` or -`position`) or a point `l:c` (when given `point`), where `l` stands -for line, `c` for column, `s` for `start`, and `e` for -end. `null` is returned if the given value is neither `node`, -`position`, nor `point`. - -## Contribute - -See [`contributing.md` in `syntax-tree/unist`][contributing] for ways to get -started. - -This organisation has a [Code of Conduct][coc]. By interacting with this -repository, organisation, or community you agree to abide by its terms. - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/syntax-tree/unist-util-stringify-position.svg - -[build-page]: https://travis-ci.org/syntax-tree/unist-util-stringify-position - -[coverage-badge]: https://img.shields.io/codecov/c/github/syntax-tree/unist-util-stringify-position.svg - -[coverage-page]: https://codecov.io/github/syntax-tree/unist-util-stringify-position?branch=master - -[npm]: https://docs.npmjs.com/cli/install - -[license]: LICENSE - -[author]: http://wooorm.com - -[unist]: https://github.com/syntax-tree/unist - -[node]: https://github.com/syntax-tree/unist#node - -[position]: https://github.com/syntax-tree/unist#position - -[point]: https://github.com/syntax-tree/unist#point - -[contributing]: https://github.com/syntax-tree/unist/blob/master/contributing.md - -[coc]: https://github.com/syntax-tree/unist/blob/master/code-of-conduct.md diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit-parents/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit-parents/index.js deleted file mode 100644 index c72635924f86d1..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit-parents/index.js +++ /dev/null @@ -1,78 +0,0 @@ -'use strict' - -module.exports = visitParents - -var convert = require('unist-util-is/convert') - -var CONTINUE = true -var SKIP = 'skip' -var EXIT = false - -visitParents.CONTINUE = CONTINUE -visitParents.SKIP = SKIP -visitParents.EXIT = EXIT - -function visitParents(tree, test, visitor, reverse) { - var is - - if (typeof test === 'function' && typeof visitor !== 'function') { - reverse = visitor - visitor = test - test = null - } - - is = convert(test) - - one(tree, null, []) - - // Visit a single node. - function one(node, index, parents) { - var result = [] - var subresult - - if (!test || is(node, index, parents[parents.length - 1] || null)) { - result = toResult(visitor(node, parents)) - - if (result[0] === EXIT) { - return result - } - } - - if (node.children && result[0] !== SKIP) { - subresult = toResult(all(node.children, parents.concat(node))) - return subresult[0] === EXIT ? subresult : result - } - - return result - } - - // Visit children in `parent`. - function all(children, parents) { - var min = -1 - var step = reverse ? -1 : 1 - var index = (reverse ? children.length : min) + step - var result - - while (index > min && index < children.length) { - result = one(children[index], index, parents) - - if (result[0] === EXIT) { - return result - } - - index = typeof result[1] === 'number' ? result[1] : index + step - } - } -} - -function toResult(value) { - if (value !== null && typeof value === 'object' && 'length' in value) { - return value - } - - if (typeof value === 'number') { - return [CONTINUE, value] - } - - return [value] -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit-parents/license b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit-parents/license deleted file mode 100644 index 8d8660d36ef2ec..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit-parents/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2016 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit-parents/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit-parents/package.json deleted file mode 100644 index 26e187202d145b..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit-parents/package.json +++ /dev/null @@ -1,70 +0,0 @@ -{ - "name": "unist-util-visit-parents", - "version": "2.1.2", - "description": "Recursively walk over unist nodes, with ancestral information", - "license": "MIT", - "keywords": [ - "unist", - "walk", - "util", - "utility" - ], - "repository": "syntax-tree/unist-util-visit-parents", - "bugs": "https://github.com/syntax-tree/unist-util-visit-parents/issues", - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "files": [ - "index.js" - ], - "dependencies": { - "unist-util-is": "^3.0.0" - }, - "devDependencies": { - "browserify": "^16.0.0", - "nyc": "^14.0.0", - "prettier": "^1.0.0", - "remark": "^10.0.0", - "remark-cli": "^6.0.0", - "remark-preset-wooorm": "^5.0.0", - "tape": "^4.0.0", - "tinyify": "^2.0.0", - "xo": "^0.24.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify index.js -s unistUtilVisitParents > unist-util-visit-parents.js", - "build-mangle": "browserify index.js -s unistUtilVisitParents -p tinyify > unist-util-visit-parents.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "ignores": [ - "unist-util-visit-parents.js" - ] - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit-parents/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit-parents/readme.md deleted file mode 100644 index ec7efc7bd03402..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit-parents/readme.md +++ /dev/null @@ -1,218 +0,0 @@ -# unist-util-visit-parents - -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] -[![Sponsors][sponsors-badge]][collective] -[![Backers][backers-badge]][collective] -[![Chat][chat-badge]][chat] - -[**unist**][unist] utility to visit nodes, with ancestral information. - -## Install - -[npm][]: - -```sh -npm install unist-util-visit-parents -``` - -## Usage - -```js -var remark = require('remark') -var visit = require('unist-util-visit-parents') - -var tree = remark.parse('Some _emphasis_, **importance**, and `code`.') - -visit(tree, 'strong', visitor) - -function visitor(node, ancestors) { - console.log(ancestors) -} -``` - -Yields: - -```js -[ { type: 'root', children: [ [Object] ] }, - { type: 'paragraph', - children: - [ [Object], - [Object], - [Object], - [Object], - [Object], - [Object], - [Object] ] } ] -``` - -## API - -### `visit(tree[, test], visitor[, reverse])` - -Visit nodes ([**inclusive descendants**][descendant] of [`tree`][tree]), with -ancestral information. Optionally filtering nodes. Optionally in reverse. - -###### Parameters - -* `tree` ([`Node`][node]) — [Tree][] to traverse -* `test` ([`Test`][is], optional) — [`is`][is]-compatible test (such as a - [type][]) -* `visitor` ([Function][visitor]) — Function invoked when a node is found - that passes `test` -* `reverse` (`boolean`, default: `false`) — The tree is walked in [preorder][] - (NLR), visiting the node itself, then its [head][], etc. - When `reverse` is passed, the tree is stilled walked in preorder, but now - in NRL (the node itself, then its [tail][], etc.) - -#### `next? = visitor(node, ancestors)` - -Invoked when a node (matching `test`, if given) is found. - -Visitors are free to transform `node`. -They can also transform the [parent][] of node (the last of `ancestors`). -Replacing `node` itself, if `visit.SKIP` is not returned, still causes its -[descendant][]s to be visited. -If adding or removing previous [sibling][]s (or next siblings, in case of -`reverse`) of `node`, `visitor` should return a new [`index`][index] (`number`) -to specify the sibling to traverse after `node` is traversed. -Adding or removing next siblings of `node` (or previous siblings, in case of -reverse) is handled as expected without needing to return a new `index`. -Removing the `children` property of parent still results in them being -traversed. - -###### Parameters - -* `node` ([`Node`][node]) — Found node -* `ancestors` (`Array.`) — [Ancestor][]s of `node` - -##### Returns - -The return value can have the following forms: - -* [`index`][index] (`number`) — Treated as a tuple of `[CONTINUE, index]` -* `action` (`*`) — Treated as a tuple of `[action]` -* `tuple` (`Array.<*>`) — List with one or two values, the first an `action`, - the second and `index`. - Note that passing a tuple only makes sense if the `action` is `SKIP`. - If the `action` is `EXIT`, that action can be returned. - If the `action` is `CONTINUE`, `index` can be returned. - -###### `action` - -An action can have the following values: - -* `visit.EXIT` (`false`) — Stop traversing immediately -* `visit.CONTINUE` (`true`) — Continue traversing as normal (same behaviour - as not returning anything) -* `visit.SKIP` (`'skip'`) — Do not traverse this node’s children; continue - with the specified index - -###### `index` - -[`index`][index] (`number`) — Move to the sibling at `index` next (after `node` -itself is completely traversed). -Useful if mutating the tree, such as removing the node the visitor is currently -on, or any of its previous siblings (or next siblings, in case of `reverse`) -Results less than `0` or greater than or equal to `children.length` stop -traversing the parent - -## Related - -* [`unist-util-visit`](https://github.com/syntax-tree/unist-util-visit) - — Like `visit-parents`, but with one parent -* [`unist-util-filter`](https://github.com/eush77/unist-util-filter) - — Create a new tree with all nodes that pass a test -* [`unist-util-map`](https://github.com/syntax-tree/unist-util-map) - — Create a new tree with all nodes mapped by a given function -* [`unist-util-flatmap`](https://gitlab.com/staltz/unist-util-flatmap) - — Create a new tree by mapping (to an array) with the provided function and - then flattening -* [`unist-util-remove`](https://github.com/eush77/unist-util-remove) - — Remove nodes from a tree that pass a test -* [`unist-util-select`](https://github.com/eush77/unist-util-select) - — Select nodes with CSS-like selectors - -## Contribute - -See [`contributing.md` in `syntax-tree/.github`][contributing] for ways to get -started. -See [`support.md`][support] for ways to get help. - -This project has a [Code of Conduct][coc]. -By interacting with this repository, organisation, or community you agree to -abide by its terms. - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/syntax-tree/unist-util-visit-parents.svg - -[build]: https://travis-ci.org/syntax-tree/unist-util-visit-parents - -[coverage-badge]: https://img.shields.io/codecov/c/github/syntax-tree/unist-util-visit-parents.svg - -[coverage]: https://codecov.io/github/syntax-tree/unist-util-visit-parents - -[downloads-badge]: https://img.shields.io/npm/dm/unist-util-visit-parents.svg - -[downloads]: https://www.npmjs.com/package/unist-util-visit-parents - -[size-badge]: https://img.shields.io/bundlephobia/minzip/unist-util-visit-parents.svg - -[size]: https://bundlephobia.com/result?p=unist-util-visit-parents - -[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg - -[backers-badge]: https://opencollective.com/unified/backers/badge.svg - -[collective]: https://opencollective.com/unified - -[chat-badge]: https://img.shields.io/badge/join%20the%20community-on%20spectrum-7b16ff.svg - -[chat]: https://spectrum.chat/unified/syntax-tree - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com - -[unist]: https://github.com/syntax-tree/unist - -[node]: https://github.com/syntax-tree/unist#node - -[visitor]: #next--visitornode-ancestors - -[contributing]: https://github.com/syntax-tree/.github/blob/master/contributing.md - -[support]: https://github.com/syntax-tree/.github/blob/master/support.md - -[coc]: https://github.com/syntax-tree/.github/blob/master/code-of-conduct.md - -[is]: https://github.com/syntax-tree/unist-util-is - -[preorder]: https://www.geeksforgeeks.org/tree-traversals-inorder-preorder-and-postorder/ - -[descendant]: https://github.com/syntax-tree/unist#descendant - -[head]: https://github.com/syntax-tree/unist#head - -[tail]: https://github.com/syntax-tree/unist#tail - -[parent]: https://github.com/syntax-tree/unist#parent-1 - -[sibling]: https://github.com/syntax-tree/unist#sibling - -[index]: https://github.com/syntax-tree/unist#index - -[ancestor]: https://github.com/syntax-tree/unist#ancestor - -[tree]: https://github.com/syntax-tree/unist#tree - -[type]: https://github.com/syntax-tree/unist#type diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit/index.js deleted file mode 100644 index 39970e7debaa49..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit/index.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict' - -module.exports = visit - -var visitParents = require('unist-util-visit-parents') - -var CONTINUE = visitParents.CONTINUE -var SKIP = visitParents.SKIP -var EXIT = visitParents.EXIT - -visit.CONTINUE = CONTINUE -visit.SKIP = SKIP -visit.EXIT = EXIT - -function visit(tree, test, visitor, reverse) { - if (typeof test === 'function' && typeof visitor !== 'function') { - reverse = visitor - visitor = test - test = null - } - - visitParents(tree, test, overload, reverse) - - function overload(node, parents) { - var parent = parents[parents.length - 1] - var index = parent ? parent.children.indexOf(node) : null - return visitor(node, index, parent) - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit/license b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit/license deleted file mode 100644 index 32e7a3d93ca5a2..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2015 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit/package.json deleted file mode 100644 index 44b8bd4897b398..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit/package.json +++ /dev/null @@ -1,79 +0,0 @@ -{ - "name": "unist-util-visit", - "version": "1.4.1", - "description": "Recursively walk over unist nodes", - "license": "MIT", - "keywords": [ - "unist", - "remark", - "markdown", - "retext", - "natural", - "language", - "node", - "visit", - "walk", - "util", - "utility" - ], - "repository": "syntax-tree/unist-util-visit", - "bugs": "https://github.com/syntax-tree/unist-util-visit/issues", - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)", - "Eugene Sharygin ", - "Richard Gibson " - ], - "files": [ - "index.js" - ], - "dependencies": { - "unist-util-visit-parents": "^2.0.0" - }, - "devDependencies": { - "browserify": "^16.0.0", - "nyc": "^14.0.0", - "prettier": "^1.0.0", - "remark": "^10.0.0", - "remark-cli": "^6.0.0", - "remark-preset-wooorm": "^5.0.0", - "tape": "^4.0.0", - "tinyify": "^2.0.0", - "xo": "^0.24.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify . -s unistUtilVisit > unist-util-visit.js", - "build-mangle": "browserify . -s unistUtilVisit -p tinyify > unist-util-visit.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "ignores": [ - "unist-util-visit.js" - ] - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit/readme.md deleted file mode 100644 index 25808a27a543e5..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/unist-util-visit/readme.md +++ /dev/null @@ -1,121 +0,0 @@ -# unist-util-visit - -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] - -[**unist**][unist] utility to visit nodes. - -## Install - -[npm][]: - -```bash -npm install unist-util-visit -``` - -## Usage - -```javascript -var u = require('unist-builder') -var visit = require('unist-util-visit') - -var tree = u('tree', [ - u('leaf', '1'), - u('node', [u('leaf', '2')]), - u('void'), - u('leaf', '3') -]) - -visit(tree, 'leaf', function(node) { - console.log(node) -}) -``` - -Yields: - -```js -{ type: 'leaf', value: '1' } -{ type: 'leaf', value: '2' } -{ type: 'leaf', value: '3' } -``` - -## API - -### `visit(tree[, test], visitor[, reverse])` - -This function works exactly the same as [`unist-util-visit-parents`][vp], -but `visitor` has a different signature. - -#### `next? = visitor(node, index, parent)` - -Instead of being passed an array of ancestors, `visitor` is invoked with the -node’s [`index`][index] and its [`parent`][parent]. - -Otherwise the same as [`unist-util-visit-parents`][vp]. - -## Related - -* [`unist-util-visit-parents`][vp] - — Like `visit`, but with a stack of parents -* [`unist-util-filter`](https://github.com/eush77/unist-util-filter) - — Create a new tree with all nodes that pass a test -* [`unist-util-map`](https://github.com/syntax-tree/unist-util-map) - — Create a new tree with all nodes mapped by a given function -* [`unist-util-remove`](https://github.com/eush77/unist-util-remove) - — Remove nodes from a tree that pass a test -* [`unist-util-select`](https://github.com/eush77/unist-util-select) - — Select nodes with CSS-like selectors - -## Contribute - -See [`contributing.md` in `syntax-tree/.github`][contributing] for ways to get -started. -See [`support.md`][support] for ways to get help. - -This project has a [Code of Conduct][coc]. -By interacting with this repository, organisation, or community you agree to -abide by its terms. - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/syntax-tree/unist-util-visit.svg - -[build]: https://travis-ci.org/syntax-tree/unist-util-visit - -[coverage-badge]: https://img.shields.io/codecov/c/github/syntax-tree/unist-util-visit.svg - -[coverage]: https://codecov.io/github/syntax-tree/unist-util-visit - -[downloads-badge]: https://img.shields.io/npm/dm/unist-util-visit.svg - -[downloads]: https://www.npmjs.com/package/unist-util-visit - -[size-badge]: https://img.shields.io/bundlephobia/minzip/unist-util-visit.svg - -[size]: https://bundlephobia.com/result?p=unist-util-visit - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com - -[contributing]: https://github.com/syntax-tree/.github/blob/master/contributing.md - -[support]: https://github.com/syntax-tree/.github/blob/master/support.md - -[coc]: https://github.com/syntax-tree/.github/blob/master/code-of-conduct.md - -[unist]: https://github.com/syntax-tree/unist - -[vp]: https://github.com/syntax-tree/unist-util-visit-parents - -[index]: https://github.com/syntax-tree/unist#index - -[parent]: https://github.com/syntax-tree/unist#parent-1 diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-location/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-location/index.js deleted file mode 100644 index 2d7c21c1808b7f..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-location/index.js +++ /dev/null @@ -1,74 +0,0 @@ -'use strict' - -module.exports = factory - -function factory(file) { - var contents = indices(String(file)) - - return { - toPosition: offsetToPositionFactory(contents), - toOffset: positionToOffsetFactory(contents) - } -} - -// Factory to get the line and column-based `position` for `offset` in the bound -// indices. -function offsetToPositionFactory(indices) { - return offsetToPosition - - // Get the line and column-based `position` for `offset` in the bound indices. - function offsetToPosition(offset) { - var index = -1 - var length = indices.length - - if (offset < 0) { - return {} - } - - while (++index < length) { - if (indices[index] > offset) { - return { - line: index + 1, - column: offset - (indices[index - 1] || 0) + 1, - offset: offset - } - } - } - - return {} - } -} - -// Factory to get the `offset` for a line and column-based `position` in the -// bound indices. -function positionToOffsetFactory(indices) { - return positionToOffset - - // Get the `offset` for a line and column-based `position` in the bound - // indices. - function positionToOffset(position) { - var line = position && position.line - var column = position && position.column - - if (!isNaN(line) && !isNaN(column) && line - 1 in indices) { - return (indices[line - 2] || 0) + column - 1 || 0 - } - - return -1 - } -} - -// Get indices of line-breaks in `value`. -function indices(value) { - var result = [] - var index = value.indexOf('\n') - - while (index !== -1) { - result.push(index + 1) - index = value.indexOf('\n', index + 1) - } - - result.push(value.length + 1) - - return result -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-location/license b/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-location/license deleted file mode 100644 index 8d8660d36ef2ec..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-location/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2016 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-location/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-location/package.json deleted file mode 100644 index f66857cf1c9cec..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-location/package.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "name": "vfile-location", - "version": "2.0.6", - "description": "Convert between positions (line and column-based) and offsets (range-based) locations in a virtual file", - "license": "MIT", - "keywords": [ - "remark", - "comment", - "message", - "marker", - "control" - ], - "repository": "vfile/vfile-location", - "bugs": "https://github.com/vfile/vfile-location/issues", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "files": [ - "index.js" - ], - "dependencies": {}, - "devDependencies": { - "browserify": "^16.0.0", - "nyc": "^14.0.0", - "prettier": "^1.0.0", - "remark-cli": "^7.0.0", - "remark-preset-wooorm": "^6.0.0", - "tape": "^4.0.0", - "tinyify": "^2.0.0", - "vfile": "^4.0.0", - "xo": "^0.25.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write \"**/*.js\" && xo --fix", - "build-bundle": "browserify . -s vfileLocation > vfile-location.js", - "build-mangle": "browserify . -s vfileLocation -p tinyify > vfile-location.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "ignores": [ - "vfile-location.js" - ] - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-location/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-location/readme.md deleted file mode 100644 index aa126a3fe3978d..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-location/readme.md +++ /dev/null @@ -1,115 +0,0 @@ -# vfile-location - -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Size][size-badge]][size] -[![Sponsors][sponsors-badge]][collective] -[![Backers][backers-badge]][collective] -[![Chat][chat-badge]][chat] - -Convert between positions (line and column-based) and offsets (range-based) -locations in a [virtual file][vfile]. - -## Install - -[npm][]: - -```sh -npm install vfile-location -``` - -## Usage - -```js -var vfile = require('vfile') -var vfileLocation = require('vfile-location') - -var location = vfileLocation(vfile('foo\nbar\nbaz')) - -var offset = location.toOffset({line: 3, column: 3}) // => 10 -location.toPosition(offset) // => {line: 3, column: 3, offset: 10} -``` - -## API - -### `location = vfileLocation(doc)` - -Get transform functions for the given `doc` (`string`) or [`file`][vfile]. - -Returns an object with [`toOffset`][to-offset] and [`toPosition`][to-position]. - -### `location.toOffset(position)` - -Get the `offset` (`number`) for a line and column-based [`position`][position] -in the bound file. -Returns `-1` when given invalid or out of bounds input. - -### `location.toPosition(offset)` - -Get the line and column-based [`position`][position] for `offset` in the bound -file. - -## Contribute - -See [`contributing.md`][contributing] in [`vfile/.github`][health] for ways to -get started. -See [`support.md`][support] for ways to get help. - -This project has a [Code of Conduct][coc]. -By interacting with this repository, organisation, or community you agree to -abide by its terms. - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/vfile/vfile-location.svg - -[build]: https://travis-ci.org/vfile/vfile-location - -[coverage-badge]: https://img.shields.io/codecov/c/github/vfile/vfile-location.svg - -[coverage]: https://codecov.io/github/vfile/vfile-location - -[downloads-badge]: https://img.shields.io/npm/dm/vfile-location.svg - -[downloads]: https://www.npmjs.com/package/vfile-location - -[size-badge]: https://img.shields.io/bundlephobia/minzip/vfile-location.svg - -[size]: https://bundlephobia.com/result?p=vfile-location - -[sponsors-badge]: https://opencollective.com/unified/sponsors/badge.svg - -[backers-badge]: https://opencollective.com/unified/backers/badge.svg - -[collective]: https://opencollective.com/unified - -[chat-badge]: https://img.shields.io/badge/join%20the%20community-on%20spectrum-7b16ff.svg - -[chat]: https://spectrum.chat/unified/vfile - -[npm]: https://docs.npmjs.com/cli/install - -[contributing]: https://github.com/vfile/.github/blob/master/contributing.md - -[support]: https://github.com/vfile/.github/blob/master/support.md - -[health]: https://github.com/vfile/.github - -[coc]: https://github.com/vfile/.github/blob/master/code-of-conduct.md - -[license]: license - -[author]: https://wooorm.com - -[vfile]: https://github.com/vfile/vfile - -[to-offset]: #locationtooffsetposition - -[to-position]: #locationtopositionoffset - -[position]: https://github.com/syntax-tree/unist#position diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-message/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-message/index.js deleted file mode 100644 index c913753249edad..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-message/index.js +++ /dev/null @@ -1,94 +0,0 @@ -'use strict' - -var stringify = require('unist-util-stringify-position') - -module.exports = VMessage - -// Inherit from `Error#`. -function VMessagePrototype() {} -VMessagePrototype.prototype = Error.prototype -VMessage.prototype = new VMessagePrototype() - -// Message properties. -var proto = VMessage.prototype - -proto.file = '' -proto.name = '' -proto.reason = '' -proto.message = '' -proto.stack = '' -proto.fatal = null -proto.column = null -proto.line = null - -// Construct a new VMessage. -// -// Note: We cannot invoke `Error` on the created context, as that adds readonly -// `line` and `column` attributes on Safari 9, thus throwing and failing the -// data. -function VMessage(reason, position, origin) { - var parts - var range - var location - - if (typeof position === 'string') { - origin = position - position = null - } - - parts = parseOrigin(origin) - range = stringify(position) || '1:1' - - location = { - start: {line: null, column: null}, - end: {line: null, column: null} - } - - // Node. - if (position && position.position) { - position = position.position - } - - if (position) { - // Position. - if (position.start) { - location = position - position = position.start - } else { - // Point. - location.start = position - } - } - - if (reason.stack) { - this.stack = reason.stack - reason = reason.message - } - - this.message = reason - this.name = range - this.reason = reason - this.line = position ? position.line : null - this.column = position ? position.column : null - this.location = location - this.source = parts[0] - this.ruleId = parts[1] -} - -function parseOrigin(origin) { - var result = [null, null] - var index - - if (typeof origin === 'string') { - index = origin.indexOf(':') - - if (index === -1) { - result[1] = origin - } else { - result[0] = origin.slice(0, index) - result[1] = origin.slice(index + 1) - } - } - - return result -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-message/license b/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-message/license deleted file mode 100644 index 045ffe0e075da4..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-message/license +++ /dev/null @@ -1,22 +0,0 @@ -(The MIT License) - -Copyright (c) 2017 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-message/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-message/package.json deleted file mode 100644 index 7396bb68e54f70..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-message/package.json +++ /dev/null @@ -1,73 +0,0 @@ -{ - "name": "vfile-message", - "version": "1.1.1", - "description": "Create a virtual message", - "license": "MIT", - "keywords": [ - "vfile", - "virtual", - "message" - ], - "repository": "vfile/vfile-message", - "bugs": "https://github.com/vfile/vfile-message/issues", - "author": "Titus Wormer (https://wooorm.com)", - "contributors": [ - "Titus Wormer (https://wooorm.com)" - ], - "files": [ - "index.js" - ], - "dependencies": { - "unist-util-stringify-position": "^1.1.1" - }, - "devDependencies": { - "browserify": "^16.0.0", - "nyc": "^13.0.0", - "prettier": "^1.12.1", - "remark-cli": "^6.0.0", - "remark-preset-wooorm": "^4.0.0", - "tape": "^4.0.0", - "tinyify": "^2.4.3", - "xo": "^0.23.0" - }, - "scripts": { - "format": "remark . -qfo && prettier --write '**/*.js' && xo --fix", - "build-bundle": "browserify . -s vfileMessage > vfile-message.js", - "build-mangle": "browserify . -s vfileMessage -p tinyify > vfile-message.min.js", - "build": "npm run build-bundle && npm run build-mangle", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run format && npm run build && npm run test-coverage" - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - }, - "prettier": { - "tabWidth": 2, - "useTabs": false, - "singleQuote": true, - "bracketSpacing": false, - "semi": false, - "trailingComma": "none" - }, - "xo": { - "prettier": true, - "esnext": false, - "rules": { - "no-var": "off", - "prefer-arrow-callback": "off", - "object-shorthand": "off" - }, - "ignores": [ - "vfile-message.js" - ] - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-message/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-message/readme.md deleted file mode 100644 index 0c88353a53c9cf..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile-message/readme.md +++ /dev/null @@ -1,194 +0,0 @@ -# vfile-message - -[![Build][build-badge]][build] -[![Coverage][coverage-badge]][coverage] -[![Downloads][downloads-badge]][downloads] -[![Chat][chat-badge]][chat] - -Create [vfile][] messages. - -## Installation - -[npm][]: - -```bash -npm install vfile-message -``` - -## Usage - -```js -var VMessage = require('vfile-message') - -var message = new VMessage( - '`braavo` is misspelt; did you mean `bravo`?', - {line: 1, column: 8}, - 'spell:typo' -) - -console.log(message) -``` - -Yields: - -```js -{ [1:8: `braavo` is misspelt; did you mean `bravo`?] - reason: '`braavo` is misspelt; did you mean `bravo`?', - fatal: null, - line: 1, - column: 8, - location: - { start: { line: 1, column: 8 }, - end: { line: null, column: null } }, - source: 'spell', - ruleId: 'typo' } -``` - -## API - -### `VMessage(reason[, position][, origin])` - -Constructor of a message for `reason` at `position` from `origin`. When -an error is passed in as `reason`, copies the stack. - -##### Parameters - -###### `reason` - -Reason for message (`string` or `Error`). Uses the stack and message of the -error if given. - -###### `position` - -Place at which the message occurred in a file ([`Node`][node], -[`Position`][position], or [`Point`][point], optional). - -###### `origin` - -Place in code the message originates from (`string`, optional). - -Can either be the [`ruleId`][ruleid] (`'rule'`), or a string with both a -[`source`][source] and a [`ruleId`][ruleid] delimited with a colon -(`'source:rule'`). - -##### Extends - -[`Error`][error]. - -##### Returns - -An instance of itself. - -##### Properties - -###### `reason` - -Reason for message (`string`). - -###### `fatal` - -If `true`, marks associated file as no longer processable (`boolean?`). If -`false`, necessitates a (potential) change. The value can also be `null` or -`undefined`. - -###### `line` - -Starting line of error (`number?`). - -###### `column` - -Starting column of error (`number?`). - -###### `location` - -Full range information, when available ([`Position`][position]). Has `start` -and `end` properties, both set to an object with `line` and `column`, set to -`number?`. - -###### `source` - -Namespace of warning (`string?`). - -###### `ruleId` - -Category of message (`string?`). - -###### `stack` - -Stack of message (`string?`). - -##### Custom properties - -It’s OK to store custom data directly on the `VMessage`, some of those are -handled by [utilities][util]. - -###### `file` - -You may add a `file` property with a path of a file (used throughout the -[**VFile**][vfile] ecosystem). - -###### `note` - -You may add a `note` property with a long form description of the message -(supported by [`vfile-reporter`][reporter]). - -###### `url` - -You may add a `url` property with a link to documentation for the message. - -## Contribute - -See [`contributing.md` in `vfile/vfile`][contributing] for ways to get started. - -This organisation has a [Code of Conduct][coc]. By interacting with this -repository, organisation, or community you agree to abide by its terms. - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/vfile/vfile-message.svg - -[build]: https://travis-ci.org/vfile/vfile-message - -[coverage-badge]: https://img.shields.io/codecov/c/github/vfile/vfile-message.svg - -[coverage]: https://codecov.io/github/vfile/vfile-message - -[downloads-badge]: https://img.shields.io/npm/dm/vfile-message.svg - -[downloads]: https://www.npmjs.com/package/vfile-message - -[chat-badge]: https://img.shields.io/badge/join%20the%20community-on%20spectrum-7b16ff.svg - -[chat]: https://spectrum.chat/unified/vfile - -[npm]: https://docs.npmjs.com/cli/install - -[license]: license - -[author]: https://wooorm.com - -[error]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error - -[node]: https://github.com/syntax-tree/unist#node - -[position]: https://github.com/syntax-tree/unist#position - -[point]: https://github.com/syntax-tree/unist#point - -[vfile]: https://github.com/vfile/vfile - -[contributing]: https://github.com/vfile/vfile/blob/master/contributing.md - -[coc]: https://github.com/vfile/vfile/blob/master/code-of-conduct.md - -[util]: https://github.com/vfile/vfile#utilities - -[reporter]: https://github.com/vfile/vfile-reporter - -[ruleid]: #ruleid - -[source]: #source diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile/LICENSE b/tools/node_modules/eslint-plugin-markdown/node_modules/vfile/LICENSE deleted file mode 100644 index f3722d94b38121..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -(The MIT License) - -Copyright (c) 2015 Titus Wormer - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile/core.js b/tools/node_modules/eslint-plugin-markdown/node_modules/vfile/core.js deleted file mode 100644 index 2d88a333993a08..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile/core.js +++ /dev/null @@ -1,169 +0,0 @@ -'use strict'; - -var path = require('path'); -var replace = require('replace-ext'); -var buffer = require('is-buffer'); - -module.exports = VFile; - -var own = {}.hasOwnProperty; -var proto = VFile.prototype; - -proto.toString = toString; - -/* Order of setting (least specific to most), we need this because - * otherwise `{stem: 'a', path: '~/b.js'}` would throw, as a path - * is needed before a stem can be set. */ -var order = [ - 'history', - 'path', - 'basename', - 'stem', - 'extname', - 'dirname' -]; - -/* Construct a new file. */ -function VFile(options) { - var prop; - var index; - var length; - - if (!options) { - options = {}; - } else if (typeof options === 'string' || buffer(options)) { - options = {contents: options}; - } else if ('message' in options && 'messages' in options) { - return options; - } - - if (!(this instanceof VFile)) { - return new VFile(options); - } - - this.data = {}; - this.messages = []; - this.history = []; - this.cwd = process.cwd(); - - /* Set path related properties in the correct order. */ - index = -1; - length = order.length; - - while (++index < length) { - prop = order[index]; - - if (own.call(options, prop)) { - this[prop] = options[prop]; - } - } - - /* Set non-path related properties. */ - for (prop in options) { - if (order.indexOf(prop) === -1) { - this[prop] = options[prop]; - } - } -} - -/* Access full path (`~/index.min.js`). */ -Object.defineProperty(proto, 'path', { - get: function () { - return this.history[this.history.length - 1]; - }, - set: function (path) { - assertNonEmpty(path, 'path'); - - if (path !== this.path) { - this.history.push(path); - } - } -}); - -/* Access parent path (`~`). */ -Object.defineProperty(proto, 'dirname', { - get: function () { - return typeof this.path === 'string' ? path.dirname(this.path) : undefined; - }, - set: function (dirname) { - assertPath(this.path, 'dirname'); - this.path = path.join(dirname || '', this.basename); - } -}); - -/* Access basename (`index.min.js`). */ -Object.defineProperty(proto, 'basename', { - get: function () { - return typeof this.path === 'string' ? path.basename(this.path) : undefined; - }, - set: function (basename) { - assertNonEmpty(basename, 'basename'); - assertPart(basename, 'basename'); - this.path = path.join(this.dirname || '', basename); - } -}); - -/* Access extname (`.js`). */ -Object.defineProperty(proto, 'extname', { - get: function () { - return typeof this.path === 'string' ? path.extname(this.path) : undefined; - }, - set: function (extname) { - var ext = extname || ''; - - assertPart(ext, 'extname'); - assertPath(this.path, 'extname'); - - if (ext) { - if (ext.charAt(0) !== '.') { - throw new Error('`extname` must start with `.`'); - } - - if (ext.indexOf('.', 1) !== -1) { - throw new Error('`extname` cannot contain multiple dots'); - } - } - - this.path = replace(this.path, ext); - } -}); - -/* Access stem (`index.min`). */ -Object.defineProperty(proto, 'stem', { - get: function () { - return typeof this.path === 'string' ? path.basename(this.path, this.extname) : undefined; - }, - set: function (stem) { - assertNonEmpty(stem, 'stem'); - assertPart(stem, 'stem'); - this.path = path.join(this.dirname || '', stem + (this.extname || '')); - } -}); - -/* Get the value of the file. */ -function toString(encoding) { - var value = this.contents || ''; - return buffer(value) ? value.toString(encoding) : String(value); -} - -/* Assert that `part` is not a path (i.e., does - * not contain `path.sep`). */ -function assertPart(part, name) { - if (part.indexOf(path.sep) !== -1) { - throw new Error('`' + name + '` cannot be a path: did not expect `' + path.sep + '`'); - } -} - -/* Assert that `part` is not empty. */ -function assertNonEmpty(part, name) { - if (!part) { - throw new Error('`' + name + '` cannot be empty'); - } -} - -/* Assert `path` exists. */ -function assertPath(path, name) { - if (!path) { - throw new Error('Setting `' + name + '` requires `path` to be set too'); - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/vfile/index.js deleted file mode 100644 index 9b3c7e0d10e109..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile/index.js +++ /dev/null @@ -1,53 +0,0 @@ -'use strict'; - -var VMessage = require('vfile-message'); -var VFile = require('./core.js'); - -module.exports = VFile; - -var proto = VFile.prototype; - -proto.message = message; -proto.info = info; -proto.fail = fail; - -/* Slight backwards compatibility. Remove in the future. */ -proto.warn = message; - -/* Create a message with `reason` at `position`. - * When an error is passed in as `reason`, copies the stack. */ -function message(reason, position, origin) { - var filePath = this.path; - var message = new VMessage(reason, position, origin); - - if (filePath) { - message.name = filePath + ':' + message.name; - message.file = filePath; - } - - message.fatal = false; - - this.messages.push(message); - - return message; -} - -/* Fail. Creates a vmessage, associates it with the file, - * and throws it. */ -function fail() { - var message = this.message.apply(this, arguments); - - message.fatal = true; - - throw message; -} - -/* Info. Creates a vmessage, associates it with the file, - * and marks the fatality as null. */ -function info() { - var message = this.message.apply(this, arguments); - - message.fatal = null; - - return message; -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/vfile/package.json deleted file mode 100644 index aba5f34dd9d5ab..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile/package.json +++ /dev/null @@ -1,78 +0,0 @@ -{ - "name": "vfile", - "version": "2.3.0", - "description": "Virtual file format for text processing", - "license": "MIT", - "keywords": [ - "virtual", - "file", - "text", - "processing", - "message", - "warning", - "error", - "remark", - "retext" - ], - "repository": "vfile/vfile", - "bugs": "https://github.com/vfile/vfile/issues", - "author": "Titus Wormer (http://wooorm.com)", - "contributors": [ - "Titus Wormer (http://wooorm.com)", - "Brendan Abbott ", - "Denys Dovhan ", - "Kyle Mathews ", - "Shinnosuke Watanabe ", - "Sindre Sorhus " - ], - "files": [ - "core.js", - "index.js" - ], - "dependencies": { - "is-buffer": "^1.1.4", - "replace-ext": "1.0.0", - "unist-util-stringify-position": "^1.0.0", - "vfile-message": "^1.0.0" - }, - "devDependencies": { - "browserify": "^14.0.0", - "esmangle": "^1.0.0", - "nyc": "^11.0.0", - "remark-cli": "^4.0.0", - "remark-preset-wooorm": "^3.0.0", - "tape": "^4.4.0", - "xo": "^0.18.0" - }, - "scripts": { - "build-md": "remark . -qfo", - "build-bundle": "browserify index.js -s VFile > vfile.js", - "build-mangle": "esmangle vfile.js > vfile.min.js", - "build": "npm run build-md && npm run build-bundle && npm run build-mangle", - "lint": "xo", - "test-api": "node test", - "test-coverage": "nyc --reporter lcov tape test.js", - "test": "npm run build && npm run lint && npm run test-coverage" - }, - "nyc": { - "check-coverage": true, - "lines": 100, - "functions": 100, - "branches": 100 - }, - "xo": { - "space": true, - "esnext": false, - "rules": { - "unicorn/no-new-buffer": "off" - }, - "ignores": [ - "vfile.js" - ] - }, - "remarkConfig": { - "plugins": [ - "preset-wooorm" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile/readme.md b/tools/node_modules/eslint-plugin-markdown/node_modules/vfile/readme.md deleted file mode 100644 index 1488031d7edd0a..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/vfile/readme.md +++ /dev/null @@ -1,285 +0,0 @@ -# ![vfile][] - -[![Build Status][build-badge]][build-status] -[![Coverage Status][coverage-badge]][coverage-status] - -**VFile** is a virtual file format used by [**unified**][unified], -a text processing umbrella (it powers [**retext**][retext] for -natural language, [**remark**][remark] for markdown, and -[**rehype**][rehype] for HTML). Each processors that parse, transform, -and compile text, and need a virtual representation of files and a -place to store [messages][] about them. Plus, they work in the browser. -**VFile** provides these requirements at a small size, in IE 9 and up. - -> **VFile** is different from the excellent [**vinyl**][vinyl] -> in that it has a smaller API, a smaller size, and focuses on -> [messages][]. - -VFile can be used anywhere where files need a lightweight representation. -For example, it’s used in: - -* [`documentation`](https://github.com/documentationjs/documentation) - — The documentation system for modern JavaScript -* [`weh`](https://github.com/wehjs/weh) - — Declarative small site generator -* [`geojsonhint`](https://github.com/mapbox/geojsonhint) - — Complete, fast, standards-based validation for geojson - -## Installation - -[npm][]: - -```bash -npm install vfile -``` - -## Table of Contents - -* [Usage](#usage) -* [Utilities](#utilities) -* [Reporters](#reporters) -* [API](#api) - * [VFile(\[options\])](#vfileoptions) - * [vfile.contents](#vfilecontents) - * [vfile.cwd](#vfilecwd) - * [vfile.path](#vfilepath) - * [vfile.basename](#vfilebasename) - * [vfile.stem](#vfilestem) - * [vfile.extname](#vfileextname) - * [vfile.dirname](#vfiledirname) - * [vfile.history](#vfilehistory) - * [vfile.messages](#vfilemessages) - * [vfile.data](#vfiledata) - * [VFile#toString(\[encoding\])](#vfiletostringencoding) - * [VFile#message(reason\[, position\]\[, origin\])](#vfilemessagereason-position-origin) - * [VFile#info(reason\[, position\]\[, origin\])](#vfileinforeason-position-origin) - * [VFile#fail(reason\[, position\]\[, origin\])](#vfilefailreason-position-origin) -* [License](#license) - -## Usage - -```js -var vfile = require('vfile'); - -var file = vfile({path: '~/example.txt', contents: 'Alpha *braavo* charlie.'}); - -file.path; //=> '~/example.txt' -file.dirname; //=> '~' - -file.extname = '.md'; - -file.basename; //=> 'example.md' - -file.basename = 'index.text'; - -file.history; //=> ['~/example.txt', '~/example.md', '~/index.text'] - -file.message('`braavo` is misspelt; did you mean `bravo`?', {line: 1, column: 8}); - -console.log(file.messages); -``` - -Yields: - -```js -[ { [~/index.text:1:8: `braavo` is misspelt; did you mean `bravo`?] - message: '`braavo` is misspelt; did you mean `bravo`?', - name: '~/index.text:1:8', - file: '~/index.text', - reason: '`braavo` is misspelt; did you mean `bravo`?', - line: 1, - column: 8, - location: { start: [Object], end: [Object] }, - ruleId: null, - source: null, - fatal: false } ] -``` - -## Utilities - -The following list of projects includes tools for working with virtual -files. See [**Unist**][unist] for projects working with nodes. - -* [`convert-vinyl-to-vfile`](https://github.com/dustinspecker/convert-vinyl-to-vfile) - — Convert from [Vinyl][] -* [`is-vfile-message`](https://github.com/shinnn/is-vfile-message) - — Check if a value is a `VMessage` object -* [`to-vfile`](https://github.com/vfile/to-vfile) - — Create a virtual file from a file-path (and optionally read it) -* [`vfile-find-down`](https://github.com/vfile/vfile-find-down) - — Find files by searching the file system downwards -* [`vfile-find-up`](https://github.com/vfile/vfile-find-up) - — Find files by searching the file system upwards -* [`vfile-location`](https://github.com/vfile/vfile-location) - — Convert between line/column- and range-based locations -* [`vfile-statistics`](https://github.com/vfile/vfile-statistics) - — Count messages per category -* [`vfile-messages-to-vscode-diagnostics`](https://github.com/shinnn/vfile-messages-to-vscode-diagnostics) - — Convert to VS Code diagnostics -* [`vfile-sort`](https://github.com/vfile/vfile-sort) - — Sort messages by line/column -* [`vfile-to-eslint`](https://github.com/vfile/vfile-to-eslint) - — Convert VFiles to ESLint formatter compatible output - -## Reporters - -The following list of projects show linting results for given virtual files. -Reporters _must_ accept `Array.` as their first argument, and return -`string`. Reporters _may_ accept other values too, in which case it’s suggested -to stick to `vfile-reporter`s interface. - -* [`vfile-reporter`][reporter] - — Stylish reporter -* [`vfile-reporter-json`](https://github.com/vfile/vfile-reporter-json) - — JSON reporter -* [`vfile-reporter-pretty`](https://github.com/vfile/vfile-reporter-pretty) - — Pretty reporter - -## API - -### `VFile([options])` - -Create a new virtual file. If `options` is `string` or `Buffer`, treats -it as `{contents: options}`. If `options` is a `VFile`, returns it. -All other options are set on the newly created `vfile`. - -Path related properties are set in the following order (least specific -to most specific): `history`, `path`, `basename`, `stem`, `extname`, -`dirname`. - -It’s not possible to set either `dirname` or `extname` without setting -either `history`, `path`, `basename`, or `stem` as well. - -###### Example - -```js -vfile(); -vfile('console.log("alpha");'); -vfile(Buffer.from('exit 1')); -vfile({path: path.join(__dirname, 'readme.md')}); -vfile({stem: 'readme', extname: '.md', dirname: __dirname}); -vfile({other: 'properties', are: 'copied', ov: {e: 'r'}}); -``` - -### `vfile.contents` - -`Buffer`, `string`, `null` — Raw value. - -### `vfile.cwd` - -`string` — Base of `path`. Defaults to `process.cwd()`. - -### `vfile.path` - -`string?` — Path of `vfile`. Cannot be nullified. - -### `vfile.basename` - -`string?` — Current name (including extension) of `vfile`. Cannot -contain path separators. Cannot be nullified either (use -`file.path = file.dirname` instead). - -### `vfile.stem` - -`string?` — Name (without extension) of `vfile`. Cannot be nullified, -and cannot contain path separators. - -### `vfile.extname` - -`string?` — Extension (with dot) of `vfile`. Cannot be set if -there’s no `path` yet and cannot contain path separators. - -### `vfile.dirname` - -`string?` — Path to parent directory of `vfile`. Cannot be set if -there’s no `path` yet. - -### `vfile.history` - -`Array.` — List of file-paths the file moved between. - -### `vfile.messages` - -[`Array.`][message] — List of messages associated with the file. - -### `vfile.data` - -`Object` — Place to store custom information. It’s OK to store custom -data directly on the `vfile`, moving it to `data` gives a _little_ more -privacy. - -### `VFile#toString([encoding])` - -Convert contents of `vfile` to string. If `contents` is a buffer, -`encoding` is used to stringify buffers (default: `'utf8'`). - -### `VFile#message(reason[, position][, origin])` - -Associates a message with the file, where `fatal` is set to `false`. -Constructs a new [`VMessage`][vmessage] and adds it to -[`vfile.messages`][messages]. - -##### Returns - -[`VMessage`][vmessage]. - -### `VFile#info(reason[, position][, origin])` - -Associates an informational message with the file, where `fatal` is set to -`null`. Calls [`#message()`][message] internally. - -##### Returns - -[`VMessage`][vmessage]. - -### `VFile#fail(reason[, position][, origin])` - -Associates a fatal message with the file, then immediately throws it. -Note: fatal errors mean a file is no longer processable. -Calls [`#message()`][message] internally. - -##### Throws - -[`VMessage`][vmessage]. - -## License - -[MIT][license] © [Titus Wormer][author] - - - -[build-badge]: https://img.shields.io/travis/vfile/vfile.svg - -[build-status]: https://travis-ci.org/vfile/vfile - -[coverage-badge]: https://img.shields.io/codecov/c/github/vfile/vfile.svg - -[coverage-status]: https://codecov.io/github/vfile/vfile - -[npm]: https://docs.npmjs.com/cli/install - -[license]: LICENSE - -[author]: http://wooorm.com - -[vfile]: https://cdn.rawgit.com/vfile/vfile/f65510e/logo.svg - -[unified]: https://github.com/unifiedjs/unified - -[retext]: https://github.com/wooorm/retext - -[remark]: https://github.com/wooorm/remark - -[rehype]: https://github.com/wooorm/rehype - -[vinyl]: https://github.com/gulpjs/vinyl - -[unist]: https://github.com/syntax-tree/unist#list-of-utilities - -[reporter]: https://github.com/vfile/vfile-reporter - -[vmessage]: https://github.com/vfile/vfile-message - -[messages]: #vfilemessages - -[message]: #vfilemessagereason-position-origin diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/x-is-string/LICENCE b/tools/node_modules/eslint-plugin-markdown/node_modules/x-is-string/LICENCE deleted file mode 100644 index 0d0834052f3c54..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/x-is-string/LICENCE +++ /dev/null @@ -1,19 +0,0 @@ -Copyright (c) 2014 Matt-Esch. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/x-is-string/README.md b/tools/node_modules/eslint-plugin-markdown/node_modules/x-is-string/README.md deleted file mode 100644 index 99977d475ac91e..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/x-is-string/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# x-is-string - -Simple string test - -## Example - -```js -var isString = require("x-is-string") - -isString("hello") -// -> true - -isString("") -// -> true - -isString(new String("things")) -// -> true - -isString(1) -// -> false - -isString(true) -// -> false - -isString(new Date()) -// -> false - -isString({}) -// -> false - -isString(null) -// -> false - -isString(undefined) -// -> false -``` - -## Installation - -`npm install x-is-string` - -## Contributors - - - Matt-Esch - -## MIT Licenced \ No newline at end of file diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/x-is-string/index.js b/tools/node_modules/eslint-plugin-markdown/node_modules/x-is-string/index.js deleted file mode 100644 index 090130d4ce4026..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/x-is-string/index.js +++ /dev/null @@ -1,7 +0,0 @@ -var toString = Object.prototype.toString - -module.exports = isString - -function isString(obj) { - return toString.call(obj) === "[object String]" -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/x-is-string/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/x-is-string/package.json deleted file mode 100644 index ea267ce35112e1..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/x-is-string/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "x-is-string", - "version": "0.1.0", - "description": "Simple string test", - "keywords": [], - "author": "Matt-Esch ", - "repository": "git://github.com/Matt-Esch/x-is-string.git", - "main": "index", - "homepage": "https://github.com/Matt-Esch/x-is-string", - "contributors": [ - { - "name": "Matt-Esch" - } - ], - "bugs": { - "url": "https://github.com/Matt-Esch/x-is-string/issues", - "email": "matt@mattesch.info" - }, - "dependencies": {}, - "devDependencies": { - "tape": "^2.12.2" - }, - "licenses": [ - { - "type": "MIT", - "url": "http://github.com/Matt-Esch/x-is-string/raw/master/LICENSE" - } - ], - "scripts": { - "test": "node ./test/index.js", - "start": "node ./index.js", - "watch": "nodemon -w ./index.js index.js", - "travis-test": "istanbul cover ./test/index.js && ((cat coverage/lcov.info | coveralls) || exit 0)", - "cover": "istanbul cover --report none --print detail ./test/index.js", - "view-cover": "istanbul report html && google-chrome ./coverage/index.html", - "test-browser": "testem-browser ./test/browser/index.js", - "testem": "testem-both -b=./test/browser/index.js" - }, - "testling": { - "files": "test/index.js", - "browsers": [ - "ie/8..latest", - "firefox/16..latest", - "firefox/nightly", - "chrome/22..latest", - "chrome/canary", - "opera/12..latest", - "opera/next", - "safari/5.1..latest", - "ipad/6.0..latest", - "iphone/6.0..latest", - "android-browser/4.2..latest" - ] - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/xtend/LICENSE b/tools/node_modules/eslint-plugin-markdown/node_modules/xtend/LICENSE deleted file mode 100644 index 0099f4f6c77f40..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/xtend/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) -Copyright (c) 2012-2014 Raynos. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/xtend/README.md b/tools/node_modules/eslint-plugin-markdown/node_modules/xtend/README.md deleted file mode 100644 index 4a2703cff276b1..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/xtend/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# xtend - -[![browser support][3]][4] - -[![locked](http://badges.github.io/stability-badges/dist/locked.svg)](http://github.com/badges/stability-badges) - -Extend like a boss - -xtend is a basic utility library which allows you to extend an object by appending all of the properties from each object in a list. When there are identical properties, the right-most property takes precedence. - -## Examples - -```js -var extend = require("xtend") - -// extend returns a new object. Does not mutate arguments -var combination = extend({ - a: "a", - b: "c" -}, { - b: "b" -}) -// { a: "a", b: "b" } -``` - -## Stability status: Locked - -## MIT Licensed - - - [3]: http://ci.testling.com/Raynos/xtend.png - [4]: http://ci.testling.com/Raynos/xtend diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/xtend/immutable.js b/tools/node_modules/eslint-plugin-markdown/node_modules/xtend/immutable.js deleted file mode 100644 index 94889c9de11a18..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/xtend/immutable.js +++ /dev/null @@ -1,19 +0,0 @@ -module.exports = extend - -var hasOwnProperty = Object.prototype.hasOwnProperty; - -function extend() { - var target = {} - - for (var i = 0; i < arguments.length; i++) { - var source = arguments[i] - - for (var key in source) { - if (hasOwnProperty.call(source, key)) { - target[key] = source[key] - } - } - } - - return target -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/xtend/mutable.js b/tools/node_modules/eslint-plugin-markdown/node_modules/xtend/mutable.js deleted file mode 100644 index 72debede6ca585..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/xtend/mutable.js +++ /dev/null @@ -1,17 +0,0 @@ -module.exports = extend - -var hasOwnProperty = Object.prototype.hasOwnProperty; - -function extend(target) { - for (var i = 1; i < arguments.length; i++) { - var source = arguments[i] - - for (var key in source) { - if (hasOwnProperty.call(source, key)) { - target[key] = source[key] - } - } - } - - return target -} diff --git a/tools/node_modules/eslint-plugin-markdown/node_modules/xtend/package.json b/tools/node_modules/eslint-plugin-markdown/node_modules/xtend/package.json deleted file mode 100644 index f7a39d10af5f5e..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/node_modules/xtend/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "xtend", - "version": "4.0.2", - "description": "extend like a boss", - "keywords": [ - "extend", - "merge", - "options", - "opts", - "object", - "array" - ], - "author": "Raynos ", - "repository": "git://github.com/Raynos/xtend.git", - "main": "immutable", - "scripts": { - "test": "node test" - }, - "dependencies": {}, - "devDependencies": { - "tape": "~1.1.0" - }, - "homepage": "https://github.com/Raynos/xtend", - "contributors": [ - { - "name": "Jake Verbaten" - }, - { - "name": "Matt Esch" - } - ], - "bugs": { - "url": "https://github.com/Raynos/xtend/issues", - "email": "raynos2@gmail.com" - }, - "license": "MIT", - "testling": { - "files": "test.js", - "browsers": [ - "ie/7..latest", - "firefox/16..latest", - "firefox/nightly", - "chrome/22..latest", - "chrome/canary", - "opera/12..latest", - "opera/next", - "safari/5.1..latest", - "ipad/6.0..latest", - "iphone/6.0..latest" - ] - }, - "engines": { - "node": ">=0.4" - } -} diff --git a/tools/node_modules/eslint-plugin-markdown/package.json b/tools/node_modules/eslint-plugin-markdown/package.json deleted file mode 100644 index f371a4610eea62..00000000000000 --- a/tools/node_modules/eslint-plugin-markdown/package.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "name": "eslint-plugin-markdown", - "version": "2.0.1", - "description": "An ESLint plugin to lint JavaScript in Markdown code fences.", - "license": "MIT", - "author": { - "name": "Brandon Mills", - "url": "https://github.com/btmills" - }, - "repository": "eslint/eslint-plugin-markdown", - "bugs": { - "url": "https://github.com/eslint/eslint-plugin-markdown/issues" - }, - "homepage": "https://github.com/eslint/eslint-plugin-markdown#readme", - "keywords": [ - "eslint", - "eslintplugin", - "markdown", - "lint", - "linter" - ], - "scripts": { - "lint": "eslint --ext js,md .", - "prepare": "node ./npm-prepare.js", - "test": "npm run lint && npm run test-cov", - "test-cov": "nyc _mocha -- -c tests/{examples,lib}/**/*.js", - "generate-release": "eslint-generate-release", - "generate-alpharelease": "eslint-generate-prerelease alpha", - "generate-betarelease": "eslint-generate-prerelease beta", - "generate-rcrelease": "eslint-generate-prerelease rc", - "publish-release": "eslint-publish-release" - }, - "main": "index.js", - "files": [ - "index.js", - "lib/index.js", - "lib/processor.js" - ], - "devDependencies": { - "chai": "^4.2.0", - "eslint": "^6.8.0", - "eslint-config-eslint": "^6.0.0", - "eslint-plugin-jsdoc": "^15.9.5", - "eslint-plugin-node": "^9.0.0", - "eslint-release": "^3.1.2", - "mocha": "^6.2.2", - "nyc": "^14.1.1" - }, - "dependencies": { - "remark-parse": "^5.0.0", - "unified": "^6.1.2" - }, - "peerDependencies": { - "eslint": ">=6.0.0" - }, - "engines": { - "node": "^8.10.0 || ^10.12.0 || >= 12.0.0" - } -} diff --git a/tools/node_modules/eslint/node_modules/eslint-plugin-jsdoc/index.js b/tools/node_modules/eslint/node_modules/eslint-plugin-jsdoc/index.js new file mode 100644 index 00000000000000..08bb390e5066c5 --- /dev/null +++ b/tools/node_modules/eslint/node_modules/eslint-plugin-jsdoc/index.js @@ -0,0 +1,105541 @@ +'use strict'; + +var lodash = require('lodash'); +var fs = require('fs'); +var path = require('path'); +var require$$2 = require('@eslint/eslintrc'); +var Module = require('module'); +var getGlobParent = require('glob-parent'); +var isGlob = require('is-glob'); +var require$$1$1 = require('minimatch'); +var require$$0$1 = require('debug'); +var eslintScope = require('eslint-scope'); +var vk = require('eslint-visitor-keys'); +var espree = require('espree'); +var globals = require('globals'); +var util$1 = require('util'); +var Ajv = require('ajv'); +var require$$0$2 = require('eslint-utils'); +var assert = require('assert'); +var levn = require('levn'); +var esquery = require('esquery'); +var esutils = require('esutils'); +var createTree = require('functional-red-black-tree'); +var regexpp = require('regexpp'); +var ignore = require('ignore'); +var naturalCompare = require('natural-compare'); +var doctrine = require('doctrine'); +var murmur = require('imurmurhash'); +var fileEntryCache = require('file-entry-cache'); +var stringify = require('json-stable-stringify-without-jsonify'); +var require$$0$3 = require('semver'); + +function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } + +var lodash__default = /*#__PURE__*/_interopDefaultLegacy(lodash); +var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs); +var path__default = /*#__PURE__*/_interopDefaultLegacy(path); +var require$$2__default = /*#__PURE__*/_interopDefaultLegacy(require$$2); +var Module__default = /*#__PURE__*/_interopDefaultLegacy(Module); +var getGlobParent__default = /*#__PURE__*/_interopDefaultLegacy(getGlobParent); +var isGlob__default = /*#__PURE__*/_interopDefaultLegacy(isGlob); +var require$$1__default = /*#__PURE__*/_interopDefaultLegacy(require$$1$1); +var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0$1); +var eslintScope__default = /*#__PURE__*/_interopDefaultLegacy(eslintScope); +var vk__default = /*#__PURE__*/_interopDefaultLegacy(vk); +var espree__default = /*#__PURE__*/_interopDefaultLegacy(espree); +var globals__default = /*#__PURE__*/_interopDefaultLegacy(globals); +var util__default = /*#__PURE__*/_interopDefaultLegacy(util$1); +var Ajv__default = /*#__PURE__*/_interopDefaultLegacy(Ajv); +var require$$0__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$0$2); +var assert__default = /*#__PURE__*/_interopDefaultLegacy(assert); +var levn__default = /*#__PURE__*/_interopDefaultLegacy(levn); +var esquery__default = /*#__PURE__*/_interopDefaultLegacy(esquery); +var esutils__default = /*#__PURE__*/_interopDefaultLegacy(esutils); +var createTree__default = /*#__PURE__*/_interopDefaultLegacy(createTree); +var regexpp__default = /*#__PURE__*/_interopDefaultLegacy(regexpp); +var ignore__default = /*#__PURE__*/_interopDefaultLegacy(ignore); +var naturalCompare__default = /*#__PURE__*/_interopDefaultLegacy(naturalCompare); +var doctrine__default = /*#__PURE__*/_interopDefaultLegacy(doctrine); +var murmur__default = /*#__PURE__*/_interopDefaultLegacy(murmur); +var fileEntryCache__default = /*#__PURE__*/_interopDefaultLegacy(fileEntryCache); +var stringify__default = /*#__PURE__*/_interopDefaultLegacy(stringify); +var require$$0__default$2 = /*#__PURE__*/_interopDefaultLegacy(require$$0$3); + +var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; + +function getDefaultExportFromCjs (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; +} + +function createCommonjsModule(fn) { + var module = { exports: {} }; + return fn(module, module.exports), module.exports; +} + +function commonjsRequire (path) { + throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.'); +} + +var util = createCommonjsModule(function (module, exports) { +Object.defineProperty(exports, "__esModule", { value: true }); +exports.rewireSpecs = exports.rewireSource = exports.seedTokens = exports.seedSpec = exports.seedBlock = exports.splitLines = exports.splitSpace = exports.isSpace = void 0; +function isSpace(source) { + return /^\s+$/.test(source); +} +exports.isSpace = isSpace; +function splitSpace(source) { + const matches = source.match(/^\s+/); + return matches == null + ? ['', source] + : [source.slice(0, matches[0].length), source.slice(matches[0].length)]; +} +exports.splitSpace = splitSpace; +function splitLines(source) { + return source.split(/\r?\n/); +} +exports.splitLines = splitLines; +function seedBlock(block = {}) { + return Object.assign({ description: '', tags: [], source: [], problems: [] }, block); +} +exports.seedBlock = seedBlock; +function seedSpec(spec = {}) { + return Object.assign({ tag: '', name: '', type: '', optional: false, description: '', problems: [], source: [] }, spec); +} +exports.seedSpec = seedSpec; +function seedTokens(tokens = {}) { + return Object.assign({ start: '', delimiter: '', postDelimiter: '', tag: '', postTag: '', name: '', postName: '', type: '', postType: '', description: '', end: '' }, tokens); +} +exports.seedTokens = seedTokens; +/** + * Assures Block.tags[].source contains references to the Block.source items, + * using Block.source as a source of truth. This is a counterpart of rewireSpecs + * @param block parsed coments block + */ +function rewireSource(block) { + const source = block.source.reduce((acc, line) => acc.set(line.number, line), new Map()); + for (const spec of block.tags) { + spec.source = spec.source.map((line) => source.get(line.number)); + } + return block; +} +exports.rewireSource = rewireSource; +/** + * Assures Block.source contains references to the Block.tags[].source items, + * using Block.tags[].source as a source of truth. This is a counterpart of rewireSource + * @param block parsed coments block + */ +function rewireSpecs(block) { + const source = block.tags.reduce((acc, spec) => spec.source.reduce((acc, line) => acc.set(line.number, line), acc), new Map()); + block.source = block.source.map((line) => source.get(line.number) || line); + return block; +} +exports.rewireSpecs = rewireSpecs; +}); + +const reTag = /^@\S+/; +/** + * Creates configured `Parser` + * @param {Partial} options + */ +function getParser$3({ fence = '```', } = {}) { + const fencer = getFencer(fence); + const toggleFence = (source, isFenced) => fencer(source) ? !isFenced : isFenced; + return function parseBlock(source) { + // start with description section + const sections = [[]]; + let isFenced = false; + for (const line of source) { + if (reTag.test(line.tokens.description) && !isFenced) { + sections.push([line]); + } + else { + sections[sections.length - 1].push(line); + } + isFenced = toggleFence(line.tokens.description, isFenced); + } + return sections; + }; +} +var _default$a = getParser$3; +function getFencer(fence) { + if (typeof fence === 'string') + return (source) => source.split(fence).length % 2 === 0; + return fence; +} + +var blockParser = /*#__PURE__*/Object.defineProperty({ + default: _default$a +}, '__esModule', {value: true}); + +var primitives = createCommonjsModule(function (module, exports) { +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Markers = void 0; +(function (Markers) { + Markers["start"] = "/**"; + Markers["nostart"] = "/***"; + Markers["delim"] = "*"; + Markers["end"] = "*/"; +})(exports.Markers || (exports.Markers = {})); +}); + +function getParser$2({ startLine = 0, } = {}) { + let block = null; + let num = startLine; + return function parseSource(source) { + let rest = source; + const tokens = util.seedTokens(); + [tokens.start, rest] = util.splitSpace(rest); + if (block === null && + rest.startsWith(primitives.Markers.start) && + !rest.startsWith(primitives.Markers.nostart)) { + block = []; + tokens.delimiter = rest.slice(0, primitives.Markers.start.length); + rest = rest.slice(primitives.Markers.start.length); + [tokens.postDelimiter, rest] = util.splitSpace(rest); + } + if (block === null) { + num++; + return null; + } + const isClosed = rest.trimRight().endsWith(primitives.Markers.end); + if (tokens.delimiter === '' && + rest.startsWith(primitives.Markers.delim) && + !rest.startsWith(primitives.Markers.end)) { + tokens.delimiter = primitives.Markers.delim; + rest = rest.slice(primitives.Markers.delim.length); + [tokens.postDelimiter, rest] = util.splitSpace(rest); + } + if (isClosed) { + const trimmed = rest.trimRight(); + tokens.end = rest.slice(trimmed.length - primitives.Markers.end.length); + rest = trimmed.slice(0, -primitives.Markers.end.length); + } + tokens.description = rest; + block.push({ number: num, source, tokens }); + num++; + if (isClosed) { + const result = block.slice(); + block = null; + return result; + } + return null; + }; +} +var _default$9 = getParser$2; + +var sourceParser = /*#__PURE__*/Object.defineProperty({ + default: _default$9 +}, '__esModule', {value: true}); + +function getParser$1({ tokenizers }) { + return function parseSpec(source) { + var _a; + let spec = util.seedSpec({ source }); + for (const tokenize of tokenizers) { + spec = tokenize(spec); + if ((_a = spec.problems[spec.problems.length - 1]) === null || _a === void 0 ? void 0 : _a.critical) + break; + } + return spec; + }; +} +var _default$8 = getParser$1; + +var specParser = /*#__PURE__*/Object.defineProperty({ + default: _default$8 +}, '__esModule', {value: true}); + +/** + * Splits the `@prefix` from remaining `Spec.lines[].token.descrioption` into the `tag` token, + * and populates `spec.tag` + */ +function tagTokenizer() { + return (spec) => { + const { tokens } = spec.source[0]; + const match = tokens.description.match(/\s*(@(\S+))(\s*)/); + if (match === null) { + spec.problems.push({ + code: 'spec:tag:prefix', + message: 'tag should start with "@" symbol', + line: spec.source[0].number, + critical: true, + }); + return spec; + } + tokens.tag = match[1]; + tokens.postTag = match[3]; + tokens.description = tokens.description.slice(match[0].length); + spec.tag = match[2]; + return spec; + }; +} +var _default$7 = tagTokenizer; + +var tag = /*#__PURE__*/Object.defineProperty({ + default: _default$7 +}, '__esModule', {value: true}); + +/** + * Sets splits remaining `Spec.lines[].tokes.description` into `type` and `description` + * tokens and populates Spec.type` + * + * @param {Spacing} spacing tells how to deal with a whitespace + * for type values going over multiple lines + */ +function typeTokenizer(spacing = 'compact') { + const join = getJoiner(spacing); + return (spec) => { + let curlies = 0; + let lines = []; + for (const [i, { tokens }] of spec.source.entries()) { + let type = ''; + if (i === 0 && tokens.description[0] !== '{') + return spec; + for (const ch of tokens.description) { + if (ch === '{') + curlies++; + if (ch === '}') + curlies--; + type += ch; + if (curlies === 0) + break; + } + lines.push([tokens, type]); + if (curlies === 0) + break; + } + if (curlies !== 0) { + spec.problems.push({ + code: 'spec:type:unpaired-curlies', + message: 'unpaired curlies', + line: spec.source[0].number, + critical: true, + }); + return spec; + } + const parts = []; + const offset = lines[0][0].postDelimiter.length; + for (const [i, [tokens, type]] of lines.entries()) { + if (type === '') + continue; + tokens.type = type; + if (i > 0) { + tokens.type = tokens.postDelimiter.slice(offset) + type; + tokens.postDelimiter = tokens.postDelimiter.slice(0, offset); + } + [tokens.postType, tokens.description] = util.splitSpace(tokens.description.slice(type.length)); + parts.push(tokens.type); + } + parts[0] = parts[0].slice(1); + parts[parts.length - 1] = parts[parts.length - 1].slice(0, -1); + spec.type = join(parts); + return spec; + }; +} +var _default$6 = typeTokenizer; +const trim = (x) => x.trim(); +function getJoiner(spacing) { + if (spacing === 'compact') + return (t) => t.map(trim).join(''); + else if (spacing === 'preserve') + return (t) => t.join('\n'); + else + return spacing; +} + +var type_1 = /*#__PURE__*/Object.defineProperty({ + default: _default$6 +}, '__esModule', {value: true}); + +const isQuoted = (s) => s && s.startsWith('"') && s.endsWith('"'); +/** + * Splits remaining `spec.lines[].tokens.description` into `name` and `descriptions` tokens, + * and populates the `spec.name` + */ +function nameTokenizer() { + const typeEnd = (num, { tokens }, i) => tokens.type === '' ? num : i; + return (spec) => { + // look for the name in the line where {type} ends + const { tokens } = spec.source[spec.source.reduce(typeEnd, 0)]; + const source = tokens.description.trimLeft(); + const quotedGroups = source.split('"'); + // if it starts with quoted group, assume it is a literal + if (quotedGroups.length > 1 && + quotedGroups[0] === '' && + quotedGroups.length % 2 === 1) { + spec.name = quotedGroups[1]; + tokens.name = `"${quotedGroups[1]}"`; + [tokens.postName, tokens.description] = util.splitSpace(source.slice(tokens.name.length)); + return spec; + } + let brackets = 0; + let name = ''; + let optional = false; + let defaultValue; + // assume name is non-space string or anything wrapped into brackets + for (const ch of source) { + if (brackets === 0 && util.isSpace(ch)) + break; + if (ch === '[') + brackets++; + if (ch === ']') + brackets--; + name += ch; + } + if (brackets !== 0) { + spec.problems.push({ + code: 'spec:name:unpaired-brackets', + message: 'unpaired brackets', + line: spec.source[0].number, + critical: true, + }); + return spec; + } + const nameToken = name; + if (name[0] === '[' && name[name.length - 1] === ']') { + optional = true; + name = name.slice(1, -1); + const parts = name.split('='); + name = parts[0].trim(); + if (parts[1] !== undefined) + defaultValue = parts.slice(1).join('=').trim(); + if (name === '') { + spec.problems.push({ + code: 'spec:name:empty-name', + message: 'empty name', + line: spec.source[0].number, + critical: true, + }); + return spec; + } + if (defaultValue === '') { + spec.problems.push({ + code: 'spec:name:empty-default', + message: 'empty default value', + line: spec.source[0].number, + critical: true, + }); + return spec; + } + // has "=" and is not a string, except for "=>" + if (!isQuoted(defaultValue) && /=(?!>)/.test(defaultValue)) { + spec.problems.push({ + code: 'spec:name:invalid-default', + message: 'invalid default value syntax', + line: spec.source[0].number, + critical: true, + }); + return spec; + } + } + spec.optional = optional; + spec.name = name; + tokens.name = nameToken; + if (defaultValue !== undefined) + spec.default = defaultValue; + [tokens.postName, tokens.description] = util.splitSpace(source.slice(tokens.name.length)); + return spec; + }; +} +var _default$5 = nameTokenizer; + +var name$1 = /*#__PURE__*/Object.defineProperty({ + default: _default$5 +}, '__esModule', {value: true}); + +var description$2 = createCommonjsModule(function (module, exports) { +Object.defineProperty(exports, "__esModule", { value: true }); +exports.getJoiner = void 0; + +/** + * Makes no changes to `spec.lines[].tokens` but joins them into `spec.description` + * following given spacing srtategy + * @param {Spacing} spacing tells how to handle the whitespace + */ +function descriptionTokenizer(spacing = 'compact') { + const join = getJoiner(spacing); + return (spec) => { + spec.description = join(spec.source); + return spec; + }; +} +exports.default = descriptionTokenizer; +function getJoiner(spacing) { + if (spacing === 'compact') + return compactJoiner; + if (spacing === 'preserve') + return preserveJoiner; + return spacing; +} +exports.getJoiner = getJoiner; +function compactJoiner(lines) { + return lines + .map(({ tokens: { description } }) => description.trim()) + .filter((description) => description !== '') + .join(' '); +} +const lineNo = (num, { tokens }, i) => tokens.type === '' ? num : i; +const getDescription = ({ tokens }) => (tokens.delimiter === '' ? tokens.start : tokens.postDelimiter.slice(1)) + + tokens.description; +function preserveJoiner(lines) { + if (lines.length === 0) + return ''; + // skip the opening line with no description + if (lines[0].tokens.description === '' && + lines[0].tokens.delimiter === primitives.Markers.start) + lines = lines.slice(1); + // skip the closing line with no description + const lastLine = lines[lines.length - 1]; + if (lastLine !== undefined && + lastLine.tokens.description === '' && + lastLine.tokens.end.endsWith(primitives.Markers.end)) + lines = lines.slice(0, -1); + // description starts at the last line of type definition + lines = lines.slice(lines.reduce(lineNo, 0)); + return lines.map(getDescription).join('\n'); +} +}); + +function getParser({ startLine = 0, fence = '```', spacing = 'compact', tokenizers = [ + tag.default(), + type_1.default(spacing), + name$1.default(), + description$2.default(spacing), +], } = {}) { + if (startLine < 0 || startLine % 1 > 0) + throw new Error('Invalid startLine'); + const parseSource = sourceParser.default({ startLine }); + const parseBlock = blockParser.default({ fence }); + const parseSpec = specParser.default({ tokenizers }); + const joinDescription = description$2.getJoiner(spacing); + const notEmpty = (line) => line.tokens.description.trim() != ''; + return function (source) { + const blocks = []; + for (const line of util.splitLines(source)) { + const lines = parseSource(line); + if (lines === null) + continue; + if (lines.find(notEmpty) === undefined) + continue; + const sections = parseBlock(lines); + const specs = sections.slice(1).map(parseSpec); + blocks.push({ + description: joinDescription(sections[0]), + tags: specs, + source: lines, + problems: specs.reduce((acc, spec) => acc.concat(spec.problems), []), + }); + } + return blocks; + }; +} +var _default$4 = getParser; + +var parser$2 = /*#__PURE__*/Object.defineProperty({ + default: _default$4 +}, '__esModule', {value: true}); + +function join(tokens) { + return (tokens.start + + tokens.delimiter + + tokens.postDelimiter + + tokens.tag + + tokens.postTag + + tokens.type + + tokens.postType + + tokens.name + + tokens.postName + + tokens.description + + tokens.end); +} +function getStringifier() { + return (block) => block.source.map(({ tokens }) => join(tokens)).join('\n'); +} +var _default$3 = getStringifier; + +var stringifier = /*#__PURE__*/Object.defineProperty({ + default: _default$3 +}, '__esModule', {value: true}); + +var __rest$1 = (commonjsGlobal && commonjsGlobal.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; +}; + + + +const zeroWidth$1 = { + start: 0, + tag: 0, + type: 0, + name: 0, +}; +const getWidth = (w, { tokens: t }) => ({ + start: t.delimiter === primitives.Markers.start ? t.start.length : w.start, + tag: Math.max(w.tag, t.tag.length), + type: Math.max(w.type, t.type.length), + name: Math.max(w.name, t.name.length), +}); +const space = (len) => ''.padStart(len, ' '); +function align$1() { + let intoTags = false; + let w; + function update(line) { + const tokens = Object.assign({}, line.tokens); + if (tokens.tag !== '') + intoTags = true; + const isEmpty = tokens.tag === '' && + tokens.name === '' && + tokens.type === '' && + tokens.description === ''; + // dangling '*/' + if (tokens.end === primitives.Markers.end && isEmpty) { + tokens.start = space(w.start + 1); + return Object.assign(Object.assign({}, line), { tokens }); + } + switch (tokens.delimiter) { + case primitives.Markers.start: + tokens.start = space(w.start); + break; + case primitives.Markers.delim: + tokens.start = space(w.start + 1); + break; + default: + tokens.delimiter = ''; + tokens.start = space(w.start + 2); // compensate delimiter + } + if (!intoTags) { + tokens.postDelimiter = tokens.description === '' ? '' : ' '; + return Object.assign(Object.assign({}, line), { tokens }); + } + const nothingAfter = { + delim: false, + tag: false, + type: false, + name: false, + }; + if (tokens.description === '') { + nothingAfter.name = true; + tokens.postName = ''; + if (tokens.name === '') { + nothingAfter.type = true; + tokens.postType = ''; + if (tokens.type === '') { + nothingAfter.tag = true; + tokens.postTag = ''; + if (tokens.tag === '') { + nothingAfter.delim = true; + } + } + } + } + tokens.postDelimiter = nothingAfter.delim ? '' : ' '; + if (!nothingAfter.tag) + tokens.postTag = space(w.tag - tokens.tag.length + 1); + if (!nothingAfter.type) + tokens.postType = space(w.type - tokens.type.length + 1); + if (!nothingAfter.name) + tokens.postName = space(w.name - tokens.name.length + 1); + return Object.assign(Object.assign({}, line), { tokens }); + } + return (_a) => { + var { source } = _a, fields = __rest$1(_a, ["source"]); + w = source.reduce(getWidth, Object.assign({}, zeroWidth$1)); + return util.rewireSource(Object.assign(Object.assign({}, fields), { source: source.map(update) })); + }; +} +var _default$2 = align$1; + +var align_1 = /*#__PURE__*/Object.defineProperty({ + default: _default$2 +}, '__esModule', {value: true}); + +var __rest = (commonjsGlobal && commonjsGlobal.__rest) || function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { + if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) + t[p[i]] = s[p[i]]; + } + return t; +}; + + +const pull = (offset) => (str) => str.slice(offset); +const push = (offset) => { + const space = ''.padStart(offset, ' '); + return (str) => str + space; +}; +function indent$1(pos) { + let shift; + const pad = (start) => { + if (shift === undefined) { + const offset = pos - start.length; + shift = offset > 0 ? push(offset) : pull(-offset); + } + return shift(start); + }; + const update = (line) => (Object.assign(Object.assign({}, line), { tokens: Object.assign(Object.assign({}, line.tokens), { start: pad(line.tokens.start) }) })); + return (_a) => { + var { source } = _a, fields = __rest(_a, ["source"]); + return util.rewireSource(Object.assign(Object.assign({}, fields), { source: source.map(update) })); + }; +} +var _default$1 = indent$1; + +var indent_1 = /*#__PURE__*/Object.defineProperty({ + default: _default$1 +}, '__esModule', {value: true}); + +var transforms = createCommonjsModule(function (module, exports) { +Object.defineProperty(exports, "__esModule", { value: true }); +exports.flow = void 0; +function flow(...transforms) { + return (block) => transforms.reduce((block, t) => t(block), block); +} +exports.flow = flow; +}); + +const zeroWidth = { + line: 0, + start: 0, + delimiter: 0, + postDelimiter: 0, + tag: 0, + postTag: 0, + name: 0, + postName: 0, + type: 0, + postType: 0, + description: 0, + end: 0, +}; +const fields = Object.keys(zeroWidth); +const repr = (x) => (util.isSpace(x) ? `{${x.length}}` : x); +const frame = (line) => '|' + line.join('|') + '|'; +const align = (width, tokens) => Object.keys(tokens).map((k) => repr(tokens[k]).padEnd(width[k])); +function inspect$1({ source }) { + if (source.length === 0) + return ''; + const width = Object.assign({}, zeroWidth); + for (const f of fields) + width[f] = f.length; + for (const { number, tokens } of source) { + width.line = Math.max(width.line, number.toString().length); + for (const k in tokens) + width[k] = Math.max(width[k], repr(tokens[k]).length); + } + const lines = [[], []]; + for (const f of fields) + lines[0].push(f.padEnd(width[f])); + for (const f of fields) + lines[1].push('-'.padEnd(width[f], '-')); + for (const { number, tokens } of source) { + const line = number.toString().padStart(width.line); + lines.push([line, ...align(width, tokens)]); + } + return lines.map(frame).join('\n'); +} +var _default = inspect$1; + +var inspect_1 = /*#__PURE__*/Object.defineProperty({ + default: _default +}, '__esModule', {value: true}); + +var lib = createCommonjsModule(function (module, exports) { +Object.defineProperty(exports, "__esModule", { value: true }); +exports.tokenizers = exports.transforms = exports.inspect = exports.stringify = exports.parse = void 0; + + + + + + + + + +function parse(source, options = {}) { + return parser$2.default(options)(source); +} +exports.parse = parse; +exports.stringify = stringifier.default(); + +Object.defineProperty(exports, "inspect", { enumerable: true, get: function () { return inspect_1.default; } }); +exports.transforms = { + flow: transforms.flow, + align: align_1.default, + indent: indent_1.default, +}; +exports.tokenizers = { + tag: tag.default, + type: type_1.default, + name: name$1.default, + description: description$2.default, +}; +}); + +var getJSDocComment_1 = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = exports.findJSDocComment = exports.getDecorator = exports.getJSDocComment = exports.getReducedASTNode = void 0; + +/** + * Obtained originally from {@link https://github.com/eslint/eslint/blob/master/lib/util/source-code.js#L313} + * + * @license MIT + */ + +/** + * Checks if the given token is a comment token or not. + * + * @param {Token} token - The token to check. + * @returns {boolean} `true` if the token is a comment token. + */ +const isCommentToken = token => { + return token.type === 'Line' || token.type === 'Block' || token.type === 'Shebang'; +}; + +const getDecorator = node => { + var _node$declaration, _node$declaration$dec, _node$decorators, _node$parent, _node$parent$decorato; + + return (node === null || node === void 0 ? void 0 : (_node$declaration = node.declaration) === null || _node$declaration === void 0 ? void 0 : (_node$declaration$dec = _node$declaration.decorators) === null || _node$declaration$dec === void 0 ? void 0 : _node$declaration$dec[0]) || (node === null || node === void 0 ? void 0 : (_node$decorators = node.decorators) === null || _node$decorators === void 0 ? void 0 : _node$decorators[0]) || (node === null || node === void 0 ? void 0 : (_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : (_node$parent$decorato = _node$parent.decorators) === null || _node$parent$decorato === void 0 ? void 0 : _node$parent$decorato[0]); +}; +/** + * Check to see if its a ES6 export declaration. + * + * @param {ASTNode} astNode An AST node. + * @returns {boolean} whether the given node represents an export declaration. + * @private + */ + + +exports.getDecorator = getDecorator; + +const looksLikeExport = function (astNode) { + return astNode.type === 'ExportDefaultDeclaration' || astNode.type === 'ExportNamedDeclaration' || astNode.type === 'ExportAllDeclaration' || astNode.type === 'ExportSpecifier'; +}; + +const getTSFunctionComment = function (astNode) { + const { + parent + } = astNode; + const grandparent = parent.parent; + const greatGrandparent = grandparent.parent; + const greatGreatGrandparent = greatGrandparent && greatGrandparent.parent; // istanbul ignore if + + if (parent.type !== 'TSTypeAnnotation') { + return astNode; + } + + switch (grandparent.type) { + case 'ClassProperty': + case 'TSDeclareFunction': + case 'TSMethodSignature': + case 'TSPropertySignature': + return grandparent; + + case 'ArrowFunctionExpression': + // istanbul ignore else + if (greatGrandparent.type === 'VariableDeclarator' // && greatGreatGrandparent.parent.type === 'VariableDeclaration' + ) { + return greatGreatGrandparent.parent; + } // istanbul ignore next + + + return astNode; + + case 'FunctionExpression': + // istanbul ignore else + if (greatGrandparent.type === 'MethodDefinition') { + return greatGrandparent; + } + + // Fallthrough + + default: + // istanbul ignore if + if (grandparent.type !== 'Identifier') { + // istanbul ignore next + return astNode; + } + + } // istanbul ignore next + + + switch (greatGrandparent.type) { + case 'ArrowFunctionExpression': + // istanbul ignore else + if (greatGreatGrandparent.type === 'VariableDeclarator' && greatGreatGrandparent.parent.type === 'VariableDeclaration') { + return greatGreatGrandparent.parent; + } // istanbul ignore next + + + return astNode; + + case 'FunctionDeclaration': + return greatGrandparent; + + case 'VariableDeclarator': + // istanbul ignore else + if (greatGreatGrandparent.type === 'VariableDeclaration') { + return greatGreatGrandparent; + } + + // Fallthrough + + default: + // istanbul ignore next + return astNode; + } +}; + +const invokedExpression = new Set(['CallExpression', 'OptionalCallExpression', 'NewExpression']); +const allowableCommentNode = new Set(['VariableDeclaration', 'ExpressionStatement', 'MethodDefinition', 'Property', 'ObjectProperty', 'ClassProperty']); +/* eslint-disable complexity */ + +/** + * Reduces the provided node to the appropriate node for evaluating JSDoc comment status. + * + * @param {ASTNode} node An AST node. + * @param {SourceCode} sourceCode The ESLint SourceCode. + * @returns {ASTNode} The AST node that can be evaluated for appropriate JSDoc comments. + * @private + */ + +const getReducedASTNode = function (node, sourceCode) { + /* eslint-enable complexity */ + let { + parent + } = node; + + switch (node.type) { + case 'TSFunctionType': + return getTSFunctionComment(node); + + case 'TSInterfaceDeclaration': + case 'TSTypeAliasDeclaration': + case 'TSEnumDeclaration': + case 'ClassDeclaration': + case 'FunctionDeclaration': + return looksLikeExport(parent) ? parent : node; + + case 'TSDeclareFunction': + case 'ClassExpression': + case 'ObjectExpression': + case 'ArrowFunctionExpression': + case 'TSEmptyBodyFunctionExpression': + case 'FunctionExpression': + if (!invokedExpression.has(parent.type)) { + while (!sourceCode.getCommentsBefore(parent).length && !/Function/u.test(parent.type) && !allowableCommentNode.has(parent.type)) { + parent = parent.parent; + + if (!parent) { + break; + } + } + + if (parent && parent.type !== 'FunctionDeclaration' && parent.type !== 'Program') { + if (parent.parent && parent.parent.type === 'ExportNamedDeclaration') { + return parent.parent; + } + + return parent; + } + } + + return node; + + default: + return node; + } +}; +/** + * Checks for the presence of a JSDoc comment for the given node and returns it. + * + * @param {ASTNode} astNode The AST node to get the comment for. + * @returns {Token|null} The Block comment token containing the JSDoc comment + * for the given node or null if not found. + * @private + */ + + +exports.getReducedASTNode = getReducedASTNode; + +const findJSDocComment = (astNode, sourceCode, settings) => { + const { + minLines, + maxLines + } = settings; + let currentNode = astNode; + let tokenBefore = null; + + while (currentNode) { + const decorator = getDecorator(currentNode); + + if (decorator) { + currentNode = decorator; + } + + tokenBefore = sourceCode.getTokenBefore(currentNode, { + includeComments: true + }); + + if (!tokenBefore || !isCommentToken(tokenBefore)) { + return null; + } + + if (tokenBefore.type === 'Line') { + currentNode = tokenBefore; + continue; + } + + break; + } + + if (tokenBefore.type === 'Block' && tokenBefore.value.charAt(0) === '*' && currentNode.loc.start.line - tokenBefore.loc.end.line >= minLines && currentNode.loc.start.line - tokenBefore.loc.end.line <= maxLines) { + return tokenBefore; + } + + return null; +}; +/** + * Retrieves the JSDoc comment for a given node. + * + * @param {SourceCode} sourceCode The ESLint SourceCode + * @param {ASTNode} node The AST node to get the comment for. + * @param {object} settings The settings in context + * @returns {Token|null} The Block comment token containing the JSDoc comment + * for the given node or null if not found. + * @public + */ + + +exports.findJSDocComment = findJSDocComment; + +const getJSDocComment = function (sourceCode, node, settings) { + const reducedNode = getReducedASTNode(node, sourceCode); + return findJSDocComment(reducedNode, sourceCode, settings); +}; + +exports.getJSDocComment = getJSDocComment; +var _default = getJSDocComment; +exports.default = _default; +//# sourceMappingURL=getJSDocComment.js.map +}); + +var WarnSettings_1 = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +const WarnSettings = function () { + /** @type {WeakMap>} */ + const warnedSettings = new WeakMap(); + return { + /** + * Warn only once for each context and setting + * + * @param {object} context + * @param {string} setting + */ + hasBeenWarned(context, setting) { + return warnedSettings.has(context) && warnedSettings.get(context).has(setting); + }, + + markSettingAsWarned(context, setting) { + // istanbul ignore else + if (!warnedSettings.has(context)) { + warnedSettings.set(context, new Set()); + } + + warnedSettings.get(context).add(setting); + } + + }; +}; + +var _default = WarnSettings; +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=WarnSettings.js.map +}); + +var getDefaultTagStructureForMode_1 = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +const getDefaultTagStructureForMode = mode => { + const isJsdoc = mode === 'jsdoc'; + const isClosure = mode === 'closure'; + const isTypescript = mode === 'typescript'; + const isPermissive = mode === 'permissive'; + const isJsdocOrTypescript = isJsdoc || isTypescript; + const isTypescriptOrClosure = isTypescript || isClosure; + const isClosureOrPermissive = isClosure || isPermissive; + const isJsdocTypescriptOrPermissive = isJsdocOrTypescript || isPermissive; // Properties: + // `nameContents` - 'namepath-referencing'|'namepath-defining'|'text'|false + // `typeAllowed` - boolean + // `nameRequired` - boolean + // `typeRequired` - boolean + // `typeOrNameRequired` - boolean + // All of `typeAllowed` have a signature with "type" except for + // `augments`/`extends` ("namepath") + // `param`/`arg`/`argument` (no signature) + // `property`/`prop` (no signature) + // `modifies` (undocumented) + // None of the `nameContents: 'namepath-defining'` show as having curly + // brackets for their name/namepath + // Among `namepath-defining` and `namepath-referencing`, these do not seem + // to allow curly brackets in their doc signature or examples (`modifies` + // references namepaths within its type brackets and `param` is + // name-defining but not namepath-defining, so not part of these groups) + // Todo: Should support special processing for "name" as distinct from + // "namepath" (e.g., param can't define a namepath) + // Once checking inline tags: + // Todo: Re: `typeOrNameRequired`, `@link` (or @linkcode/@linkplain) seems + // to require a namepath OR URL and might be checked as such. + // Todo: Should support a `tutorialID` type (for `@tutorial` block and + // inline) + + return new Map([['alias', new Map([// Signature seems to require a "namepath" (and no counter-examples) + ['nameContents', 'namepath-referencing'], // "namepath" + ['typeOrNameRequired', true]])], ['arg', new Map([['nameContents', 'namepath-defining'], // See `param` + ['nameRequired', true], // Has no formal signature in the docs but shows curly brackets + // in the examples + ['typeAllowed', true]])], ['argument', new Map([['nameContents', 'namepath-defining'], // See `param` + ['nameRequired', true], // Has no formal signature in the docs but shows curly brackets + // in the examples + ['typeAllowed', true]])], ['augments', new Map([// Signature seems to require a "namepath" (and no counter-examples) + ['nameContents', 'namepath-referencing'], // Does not show curly brackets in either the signature or examples + ['typeAllowed', true], // "namepath" + ['typeOrNameRequired', true]])], ['borrows', new Map([// `borrows` has a different format, however, so needs special parsing; + // seems to require both, and as "namepath"'s + ['nameContents', 'namepath-referencing'], // "namepath" + ['typeOrNameRequired', true]])], ['callback', new Map([// Seems to require a "namepath" in the signature (with no + // counter-examples) + ['nameContents', 'namepath-defining'], // "namepath" + ['nameRequired', true]])], ['class', new Map([// Allows for "name"'s in signature, but indicated as optional + ['nameContents', 'namepath-defining'], ['typeAllowed', true]])], ['const', new Map([// Allows for "name"'s in signature, but indicated as optional + ['nameContents', 'namepath-defining'], ['typeAllowed', true]])], ['constant', new Map([// Allows for "name"'s in signature, but indicated as optional + ['nameContents', 'namepath-defining'], ['typeAllowed', true]])], ['constructor', new Map([// Allows for "name"'s in signature, but indicated as optional + ['nameContents', 'namepath-defining'], ['typeAllowed', true]])], ['define', new Map([['typeRequired', isClosure]])], ['emits', new Map([// Signature seems to require a "name" (of an event) and no counter-examples + ['nameContents', 'namepath-referencing']])], ['enum', new Map([// Has example showing curly brackets but not in doc signature + ['typeAllowed', true]])], ['event', new Map([// The doc signature of `event` seems to require a "name" + ['nameRequired', true], // Appears to require a "name" in its signature, albeit somewhat + // different from other "name"'s (including as described + // at https://jsdoc.app/about-namepaths.html ) + ['nameContents', 'namepath-defining']])], ['exception', new Map([// Shows curly brackets in the signature and in the examples + ['typeAllowed', true]])], ['export', new Map([['typeAllowed', isClosureOrPermissive]])], ['extends', new Map([// Signature seems to require a "namepath" (and no counter-examples) + ['nameContents', 'namepath-referencing'], // Does not show curly brackets in either the signature or examples + ['typeAllowed', isClosureOrPermissive], ['nameRequired', isJsdocOrTypescript], // "namepath" + ['typeOrNameRequired', isClosureOrPermissive]])], ['external', new Map([// Appears to require a "name" in its signature, albeit somewhat + // different from other "name"'s (including as described + // at https://jsdoc.app/about-namepaths.html ) + ['nameContents', 'namepath-defining'], // "name" (and a special syntax for the `external` name) + ['nameRequired', true]])], ['fires', new Map([// Signature seems to require a "name" (of an event) and no + // counter-examples + ['nameContents', 'namepath-referencing']])], ['function', new Map([// Allows for "name"'s in signature, but indicated as optional + ['nameContents', 'namepath-defining']])], ['func', new Map([// Allows for "name"'s in signature, but indicated as optional + ['nameContents', 'namepath-defining']])], ['host', new Map([// Appears to require a "name" in its signature, albeit somewhat + // different from other "name"'s (including as described + // at https://jsdoc.app/about-namepaths.html ) + ['nameContents', 'namepath-defining'], // See `external` + ['nameRequired', true], // "namepath" + ['typeOrNameRequired', true]])], ['interface', new Map([// Allows for "name" in signature, but indicates as optional + ['nameContents', isJsdocTypescriptOrPermissive ? 'namepath-defining' : false]])], ['implements', new Map([// Shows curly brackets in the doc signature and examples + // "typeExpression" + ['typeRequired', true]])], ['lends', new Map([// Signature seems to require a "namepath" (and no counter-examples) + ['nameContents', 'namepath-referencing'], // "namepath" + ['typeOrNameRequired', true]])], ['listens', new Map([// Signature seems to require a "name" (of an event) and no + // counter-examples + ['nameContents', 'namepath-referencing']])], ['member', new Map([// Allows for "name"'s in signature, but indicated as optional + ['nameContents', 'namepath-defining'], // Has example showing curly brackets but not in doc signature + ['typeAllowed', true]])], ['memberof', new Map([// Signature seems to require a "namepath" (and no counter-examples), + // though it allows an incomplete namepath ending with connecting symbol + ['nameContents', 'namepath-referencing'], // "namepath" + ['typeOrNameRequired', true]])], ['memberof!', new Map([// Signature seems to require a "namepath" (and no counter-examples), + // though it allows an incomplete namepath ending with connecting symbol + ['nameContents', 'namepath-referencing'], // "namepath" + ['typeOrNameRequired', true]])], ['method', new Map([// Allows for "name"'s in signature, but indicated as optional + ['nameContents', 'namepath-defining']])], ['mixes', new Map([// Signature seems to require a "OtherObjectPath" with no + // counter-examples + ['nameContents', 'namepath-referencing'], // "OtherObjectPath" + ['typeOrNameRequired', true]])], ['mixin', new Map([// Allows for "name"'s in signature, but indicated as optional + ['nameContents', 'namepath-defining']])], ['modifies', new Map([// Has no documentation, but test example has curly brackets, and + // "name" would be suggested rather than "namepath" based on example; + // not sure if name is required + ['typeAllowed', true]])], ['module', new Map([// Optional "name" and no curly brackets + // this block impacts `no-undefined-types` and `valid-types` (search for + // "isNamepathDefiningTag|tagMightHaveNamepath|tagMightHaveEitherTypeOrNamePosition") + ['nameContents', isJsdoc ? 'namepath-defining' : 'text'], // Shows the signature with curly brackets but not in the example + ['typeAllowed', true]])], ['name', new Map([// Seems to require a "namepath" in the signature (with no + // counter-examples) + ['nameContents', 'namepath-defining'], // "namepath" + ['nameRequired', true], // "namepath" + ['typeOrNameRequired', true]])], ['namespace', new Map([// Allows for "name"'s in signature, but indicated as optional + ['nameContents', 'namepath-defining'], // Shows the signature with curly brackets but not in the example + ['typeAllowed', true]])], ['package', new Map([// Shows the signature with curly brackets but not in the example + // "typeExpression" + ['typeAllowed', isClosureOrPermissive]])], ['param', new Map([['nameContents', 'namepath-defining'], // Though no signature provided requiring, per + // https://jsdoc.app/tags-param.html: + // "The @param tag requires you to specify the name of the parameter you + // are documenting." + ['nameRequired', true], // Has no formal signature in the docs but shows curly brackets + // in the examples + ['typeAllowed', true]])], ['private', new Map([// Shows the signature with curly brackets but not in the example + // "typeExpression" + ['typeAllowed', isClosureOrPermissive]])], ['prop', new Map([['nameContents', 'namepath-defining'], // See `property` + ['nameRequired', true], // Has no formal signature in the docs but shows curly brackets + // in the examples + ['typeAllowed', true]])], ['property', new Map([['nameContents', 'namepath-defining'], // No docs indicate required, but since parallel to `param`, we treat as + // such: + ['nameRequired', true], // Has no formal signature in the docs but shows curly brackets + // in the examples + ['typeAllowed', true]])], ['protected', new Map([// Shows the signature with curly brackets but not in the example + // "typeExpression" + ['typeAllowed', isClosureOrPermissive]])], ['public', new Map([// Does not show a signature nor show curly brackets in the example + ['typeAllowed', isClosureOrPermissive]])], ['returns', new Map([// Shows curly brackets in the signature and in the examples + ['typeAllowed', true]])], ['return', new Map([// Shows curly brackets in the signature and in the examples + ['typeAllowed', true]])], ['see', new Map([// Signature allows for "namepath" or text, so user must configure to + // 'namepath-referencing' to enforce checks + ['nameContents', 'text']])], ['static', new Map([// Does not show a signature nor show curly brackets in the example + ['typeAllowed', isClosureOrPermissive]])], ['template', new Map([['nameContents', isJsdoc ? 'text' : 'namepath-referencing'], // Though defines `nameContents: 'namepath-defining'` in a sense, it is + // not parseable in the same way for template (e.g., allowing commas), + // so not adding + ['typeAllowed', isTypescriptOrClosure || isPermissive]])], ['this', new Map([// Signature seems to require a "namepath" (and no counter-examples) + // Not used with namepath in Closure/TypeScript, however + ['nameContents', isJsdoc ? 'namepath-referencing' : false], ['typeRequired', isTypescriptOrClosure], // namepath + ['typeOrNameRequired', isJsdoc]])], ['throws', new Map([// Shows curly brackets in the signature and in the examples + ['typeAllowed', true]])], ['type', new Map([// Shows curly brackets in the doc signature and examples + // "typeName" + ['typeRequired', true]])], ['typedef', new Map([// Seems to require a "namepath" in the signature (with no + // counter-examples) + ['nameContents', 'namepath-defining'], // "namepath" + ['nameRequired', isJsdocTypescriptOrPermissive], // Has example showing curly brackets but not in doc signature + ['typeAllowed', true], // "namepath" + ['typeOrNameRequired', true]])], ['var', new Map([// Allows for "name"'s in signature, but indicated as optional + ['nameContents', 'namepath-defining'], // Has example showing curly brackets but not in doc signature + ['typeAllowed', true]])], ['yields', new Map([// Shows curly brackets in the signature and in the examples + ['typeAllowed', true]])], ['yield', new Map([// Shows curly brackets in the signature and in the examples + ['typeAllowed', true]])]]); +}; + +var _default = getDefaultTagStructureForMode; +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=getDefaultTagStructureForMode.js.map +}); + +var tagNames = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.typeScriptTags = exports.closureTags = exports.jsdocTags = void 0; +const jsdocTagsUndocumented = { + // Undocumented but present; see + // https://github.com/jsdoc/jsdoc/issues/1283#issuecomment-516816802 + // https://github.com/jsdoc/jsdoc/blob/master/packages/jsdoc/lib/jsdoc/tag/dictionary/definitions.js#L594 + modifies: [] +}; +const jsdocTags = { ...jsdocTagsUndocumented, + abstract: ['virtual'], + access: [], + alias: [], + async: [], + augments: ['extends'], + author: [], + borrows: [], + callback: [], + class: ['constructor'], + classdesc: [], + constant: ['const'], + constructs: [], + copyright: [], + default: ['defaultvalue'], + deprecated: [], + description: ['desc'], + enum: [], + event: [], + example: [], + exports: [], + external: ['host'], + file: ['fileoverview', 'overview'], + fires: ['emits'], + function: ['func', 'method'], + generator: [], + global: [], + hideconstructor: [], + ignore: [], + implements: [], + inheritdoc: [], + // Allowing casing distinct from jsdoc `definitions.js` (required in Closure) + inheritDoc: [], + inner: [], + instance: [], + interface: [], + kind: [], + lends: [], + license: [], + listens: [], + member: ['var'], + memberof: [], + 'memberof!': [], + mixes: [], + mixin: [], + module: [], + name: [], + namespace: [], + override: [], + package: [], + param: ['arg', 'argument'], + private: [], + property: ['prop'], + protected: [], + public: [], + readonly: [], + requires: [], + returns: ['return'], + see: [], + since: [], + static: [], + summary: [], + this: [], + throws: ['exception'], + todo: [], + tutorial: [], + type: [], + typedef: [], + variation: [], + version: [], + yields: ['yield'] +}; +exports.jsdocTags = jsdocTags; +const typeScriptTags = { ...jsdocTags, + // `@template` is also in TypeScript per: + // https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html#supported-jsdoc + template: [] +}; +exports.typeScriptTags = typeScriptTags; +const undocumentedClosureTags = { + // These are in Closure source but not in jsdoc source nor in the Closure + // docs: https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/parsing/Annotation.java + closurePrimitive: [], + customElement: [], + expose: [], + hidden: [], + idGenerator: [], + meaning: [], + mixinClass: [], + mixinFunction: [], + ngInject: [], + owner: [], + typeSummary: [], + wizaction: [] +}; +const { + /* eslint-disable no-unused-vars */ + inheritdoc, + // Will be inverted to prefer `return` + returns, + + /* eslint-enable no-unused-vars */ + ...typeScriptTagsInClosure +} = typeScriptTags; +const closureTags = { ...typeScriptTagsInClosure, + ...undocumentedClosureTags, + // From https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler + // These are all recognized in https://github.com/jsdoc/jsdoc/blob/master/packages/jsdoc/lib/jsdoc/tag/dictionary/definitions.js + // except for the experimental `noinline` and the casing differences noted below + // Defined as a synonym of `const` in jsdoc `definitions.js` + define: [], + dict: [], + export: [], + externs: [], + final: [], + // With casing distinct from jsdoc `definitions.js` + implicitCast: [], + noalias: [], + nocollapse: [], + nocompile: [], + noinline: [], + nosideeffects: [], + polymer: [], + polymerBehavior: [], + preserve: [], + // Defined as a synonym of `interface` in jsdoc `definitions.js` + record: [], + return: ['returns'], + struct: [], + suppress: [], + unrestricted: [] +}; +exports.closureTags = closureTags; +//# sourceMappingURL=tagNames.js.map +}); + +var jsdocUtils = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _lodash = _interopRequireDefault(lodash__default['default']); + +var _WarnSettings = _interopRequireDefault(WarnSettings_1); + +var _getDefaultTagStructureForMode = _interopRequireDefault(getDefaultTagStructureForMode_1); + + + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +let tagStructure; + +const setTagStructure = mode => { + tagStructure = (0, _getDefaultTagStructureForMode.default)(mode); +}; // Given a nested array of property names, reduce them to a single array, +// appending the name of the root element along the way if present. + + +const flattenRoots = (params, root = '') => { + let hasRestElement = false; + let hasPropertyRest = false; + const rests = []; + const names = params.reduce((acc, cur) => { + if (Array.isArray(cur)) { + let nms; + + if (Array.isArray(cur[1])) { + nms = cur[1]; + } else { + if (cur[1].hasRestElement) { + hasRestElement = true; + } + + if (cur[1].hasPropertyRest) { + hasPropertyRest = true; + } + + nms = cur[1].names; + } + + const flattened = flattenRoots(nms, root ? `${root}.${cur[0]}` : cur[0]); + + if (flattened.hasRestElement) { + hasRestElement = true; + } + + if (flattened.hasPropertyRest) { + hasPropertyRest = true; + } + + const inner = [root ? `${root}.${cur[0]}` : cur[0], ...flattened.names].filter(Boolean); + rests.push(false, ...flattened.rests); + return acc.concat(inner); + } + + if (typeof cur === 'object') { + if (cur.isRestProperty) { + hasPropertyRest = true; + rests.push(true); + } else { + rests.push(false); + } + + if (cur.restElement) { + hasRestElement = true; + } + + acc.push(root ? `${root}.${cur.name}` : cur.name); + } else if (typeof cur !== 'undefined') { + rests.push(false); + acc.push(root ? `${root}.${cur}` : cur); + } + + return acc; + }, []); + return { + hasPropertyRest, + hasRestElement, + names, + rests + }; +}; + +const getPropertiesFromPropertySignature = propSignature => { + if (propSignature.type === 'TSIndexSignature' || propSignature.type === 'TSConstructSignatureDeclaration' || propSignature.type === 'TSCallSignatureDeclaration') { + return undefined; + } + + if (propSignature.typeAnnotation && propSignature.typeAnnotation.typeAnnotation.type === 'TSTypeLiteral') { + return [propSignature.key.name, propSignature.typeAnnotation.typeAnnotation.members.map(member => { + return getPropertiesFromPropertySignature(member); + })]; + } + + return propSignature.key.name; +}; + +const getFunctionParameterNames = (functionNode, checkDefaultObjects) => { + // eslint-disable-next-line complexity + const getParamName = (param, isProperty) => { + var _param$left, _param$left3; + + if (_lodash.default.has(param, 'typeAnnotation') || _lodash.default.has(param, 'left.typeAnnotation')) { + const typeAnnotation = _lodash.default.has(param, 'left.typeAnnotation') ? param.left.typeAnnotation : param.typeAnnotation; + + if (typeAnnotation.typeAnnotation.type === 'TSTypeLiteral') { + const propertyNames = typeAnnotation.typeAnnotation.members.map(member => { + return getPropertiesFromPropertySignature(member); + }); + const flattened = { ...flattenRoots(propertyNames), + annotationParamName: param.name + }; + + if (_lodash.default.has(param, 'name') || _lodash.default.has(param, 'left.name')) { + return [_lodash.default.has(param, 'left.name') ? param.left.name : param.name, flattened]; + } + + return [undefined, flattened]; + } + } + + if (_lodash.default.has(param, 'name')) { + return param.name; + } + + if (_lodash.default.has(param, 'left.name')) { + return param.left.name; + } + + if (param.type === 'ObjectPattern' || ((_param$left = param.left) === null || _param$left === void 0 ? void 0 : _param$left.type) === 'ObjectPattern') { + var _param$left2; + + const properties = param.properties || ((_param$left2 = param.left) === null || _param$left2 === void 0 ? void 0 : _param$left2.properties); + const roots = properties.map(prop => { + return getParamName(prop, true); + }); + return [undefined, flattenRoots(roots)]; + } + + if (param.type === 'Property') { + switch (param.value.type) { + case 'ArrayPattern': + return [param.key.name, param.value.elements.map((prop, idx) => { + return { + name: idx, + restElement: prop.type === 'RestElement' + }; + })]; + + case 'ObjectPattern': + return [param.key.name, param.value.properties.map(prop => { + return getParamName(prop, isProperty); + })]; + + case 'AssignmentPattern': + { + switch (param.value.left.type) { + case 'Identifier': + // Default parameter + if (checkDefaultObjects && param.value.right.type === 'ObjectExpression') { + return [param.key.name, param.value.right.properties.map(prop => { + return getParamName(prop, isProperty); + })]; + } + + break; + + case 'ObjectPattern': + return [param.key.name, param.value.left.properties.map(prop => { + return getParamName(prop, isProperty); + })]; + + case 'ArrayPattern': + return [param.key.name, param.value.left.elements.map((prop, idx) => { + return { + name: idx, + restElement: prop.type === 'RestElement' + }; + })]; + } + } + } + + switch (param.key.type) { + case 'Identifier': + return param.key.name; + // The key of an object could also be a string or number + + case 'Literal': + return param.key.raw || // istanbul ignore next -- `raw` may not be present in all parsers + param.key.value; + // case 'MemberExpression': + + default: + // Todo: We should really create a structure (and a corresponding + // option analogous to `checkRestProperty`) which allows for + // (and optionally requires) dynamic properties to have a single + // line of documentation + return undefined; + } + } + + if (param.type === 'ArrayPattern' || ((_param$left3 = param.left) === null || _param$left3 === void 0 ? void 0 : _param$left3.type) === 'ArrayPattern') { + var _param$left4; + + const elements = param.elements || ((_param$left4 = param.left) === null || _param$left4 === void 0 ? void 0 : _param$left4.elements); + const roots = elements.map((prop, idx) => { + return { + name: idx, + restElement: prop.type === 'RestElement' + }; + }); + return [undefined, flattenRoots(roots)]; + } + + if (['RestElement', 'ExperimentalRestProperty'].includes(param.type)) { + return { + isRestProperty: isProperty, + name: param.argument.name, + restElement: true + }; + } + + if (param.type === 'TSParameterProperty') { + return getParamName(param.parameter, true); + } + + throw new Error(`Unsupported function signature format: \`${param.type}\`.`); + }; + + return (functionNode.params || functionNode.value.params).map(param => { + return getParamName(param); + }); +}; + +const hasParams = functionNode => { + // Should also check `functionNode.value.params` if supporting `MethodDefinition` + return functionNode.params.length; +}; +/** + * Gets all names of the target type, including those that refer to a path, e.g. + * "@param foo; @param foo.bar". + */ + + +const getJsdocTagsDeep = (jsdoc, targetTagName) => { + const ret = []; + jsdoc.tags.forEach(({ + name, + tag, + type + }, idx) => { + if (tag !== targetTagName) { + return; + } + + ret.push({ + idx, + name, + type + }); + }); + return ret; +}; + +const modeWarnSettings = (0, _WarnSettings.default)(); + +const getTagNamesForMode = (mode, context) => { + switch (mode) { + case 'jsdoc': + return tagNames.jsdocTags; + + case 'typescript': + return tagNames.typeScriptTags; + + case 'closure': + case 'permissive': + return tagNames.closureTags; + + default: + if (!modeWarnSettings.hasBeenWarned(context, 'mode')) { + context.report({ + loc: { + start: { + column: 1, + line: 1 + } + }, + message: `Unrecognized value \`${mode}\` for \`settings.jsdoc.mode\`.` + }); + modeWarnSettings.markSettingAsWarned(context, 'mode'); + } // We'll avoid breaking too many other rules + + + return tagNames.jsdocTags; + } +}; + +const getPreferredTagName = (context, mode, name, tagPreference = {}) => { + var _Object$entries$find; + + const prefValues = Object.values(tagPreference); + + if (prefValues.includes(name) || prefValues.some(prefVal => { + return prefVal && typeof prefVal === 'object' && prefVal.replacement === name; + })) { + return name; + } // Allow keys to have a 'tag ' prefix to avoid upstream bug in ESLint + // that disallows keys that conflict with Object.prototype, + // e.g. 'tag constructor' for 'constructor': + // https://github.com/eslint/eslint/issues/13289 + // https://github.com/gajus/eslint-plugin-jsdoc/issues/537 + + + const tagPreferenceFixed = _lodash.default.mapKeys(tagPreference, (_value, key) => { + return key.replace('tag ', ''); + }); + + if (_lodash.default.has(tagPreferenceFixed, name)) { + return tagPreferenceFixed[name]; + } + + const tagNames = getTagNamesForMode(mode, context); + const preferredTagName = (_Object$entries$find = Object.entries(tagNames).find(([, aliases]) => { + return aliases.includes(name); + })) === null || _Object$entries$find === void 0 ? void 0 : _Object$entries$find[0]; + + if (preferredTagName) { + return preferredTagName; + } + + return name; +}; + +const isValidTag = (context, mode, name, definedTags) => { + const tagNames = getTagNamesForMode(mode, context); + const validTagNames = Object.keys(tagNames).concat(_lodash.default.flatten(Object.values(tagNames))); + const additionalTags = definedTags; + const allTags = validTagNames.concat(additionalTags); + return allTags.includes(name); +}; + +const hasTag = (jsdoc, targetTagName) => { + const targetTagLower = targetTagName.toLowerCase(); + return _lodash.default.some(jsdoc.tags, doc => { + return doc.tag.toLowerCase() === targetTagLower; + }); +}; + +const hasATag = (jsdoc, targetTagNames) => { + return targetTagNames.some(targetTagName => { + return hasTag(jsdoc, targetTagName); + }); +}; +/** + * Checks if the JSDoc comment declares a defined type. + * + * @param {JsDocTag} tag + * the tag which should be checked. + * @returns {boolean} + * true in case a defined type is declared; otherwise false. + */ + + +const hasDefinedTypeTag = tag => { + // The function should not continue in the event the type is not defined... + if (typeof tag === 'undefined' || tag === null) { + return false; + } // .. same applies if it declares an `{undefined}` or `{void}` type + + + const tagType = tag.type.trim(); + + if (tagType === 'undefined' || tagType === 'void') { + return false; + } // In any other case, a type is present + + + return true; +}; + +const ensureMap = (map, tag) => { + if (!map.has(tag)) { + map.set(tag, new Map()); + } + + return map.get(tag); +}; + +const overrideTagStructure = (structuredTags, tagMap = tagStructure) => { + Object.entries(structuredTags).forEach(([tag, { + name, + type, + required = [] + }]) => { + const tagStruct = ensureMap(tagMap, tag); + tagStruct.set('nameContents', name); + tagStruct.set('typeAllowed', type); + const requiredName = required.includes('name'); + + if (requiredName && name === false) { + throw new Error('Cannot add "name" to `require` with the tag\'s `name` set to `false`'); + } + + tagStruct.set('nameRequired', requiredName); + const requiredType = required.includes('type'); + + if (requiredType && type === false) { + throw new Error('Cannot add "type" to `require` with the tag\'s `type` set to `false`'); + } + + tagStruct.set('typeRequired', requiredType); + const typeOrNameRequired = required.includes('typeOrNameRequired'); + + if (typeOrNameRequired && name === false) { + throw new Error('Cannot add "typeOrNameRequired" to `require` with the tag\'s `name` set to `false`'); + } + + if (typeOrNameRequired && type === false) { + throw new Error('Cannot add "typeOrNameRequired" to `require` with the tag\'s `type` set to `false`'); + } + + tagStruct.set('typeOrNameRequired', typeOrNameRequired); + }); +}; + +const getTagStructureForMode = (mode, structuredTags) => { + const tagStruct = (0, _getDefaultTagStructureForMode.default)(mode); + + try { + overrideTagStructure(structuredTags, tagStruct); + } catch {// + } + + return tagStruct; +}; + +const isNamepathDefiningTag = (tag, tagMap = tagStructure) => { + const tagStruct = ensureMap(tagMap, tag); + return tagStruct.get('nameContents') === 'namepath-defining'; +}; + +const tagMustHaveTypePosition = (tag, tagMap = tagStructure) => { + const tagStruct = ensureMap(tagMap, tag); + return tagStruct.get('typeRequired'); +}; + +const tagMightHaveTypePosition = (tag, tagMap = tagStructure) => { + if (tagMustHaveTypePosition(tag, tagMap)) { + return true; + } + + const tagStruct = ensureMap(tagMap, tag); + const ret = tagStruct.get('typeAllowed'); + return ret === undefined ? true : ret; +}; + +const namepathTypes = new Set(['namepath-defining', 'namepath-referencing']); + +const tagMightHaveNamePosition = (tag, tagMap = tagStructure) => { + const tagStruct = ensureMap(tagMap, tag); + const ret = tagStruct.get('nameContents'); + return ret === undefined ? true : Boolean(ret); +}; + +const tagMightHaveNamepath = (tag, tagMap = tagStructure) => { + const tagStruct = ensureMap(tagMap, tag); + return namepathTypes.has(tagStruct.get('nameContents')); +}; + +const tagMustHaveNamePosition = (tag, tagMap = tagStructure) => { + const tagStruct = ensureMap(tagMap, tag); + return tagStruct.get('nameRequired'); +}; + +const tagMightHaveEitherTypeOrNamePosition = (tag, tagMap) => { + return tagMightHaveTypePosition(tag, tagMap) || tagMightHaveNamepath(tag, tagMap); +}; + +const tagMustHaveEitherTypeOrNamePosition = (tag, tagMap) => { + const tagStruct = ensureMap(tagMap, tag); + return tagStruct.get('typeOrNameRequired'); +}; + +const tagMissingRequiredTypeOrNamepath = (tag, tagMap = tagStructure) => { + const mustHaveTypePosition = tagMustHaveTypePosition(tag.tag, tagMap); + const mightHaveTypePosition = tagMightHaveTypePosition(tag.tag, tagMap); + const hasTypePosition = mightHaveTypePosition && Boolean(tag.type); + const hasNameOrNamepathPosition = (tagMustHaveNamePosition(tag.tag, tagMap) || tagMightHaveNamepath(tag.tag, tagMap)) && Boolean(tag.name); + const mustHaveEither = tagMustHaveEitherTypeOrNamePosition(tag.tag, tagMap); + const hasEither = tagMightHaveEitherTypeOrNamePosition(tag.tag, tagMap) && (hasTypePosition || hasNameOrNamepathPosition); + return mustHaveEither && !hasEither && !mustHaveTypePosition; +}; +/** + * Checks if a node is a promise but has no resolve value or an empty value. + * An `undefined` resolve does not count. + * + * @param {object} node + * @returns {boolean} + */ + + +const isNewPromiseExpression = node => { + return node.type === 'NewExpression' && node.callee.type === 'Identifier' && node.callee.name === 'Promise'; +}; +/** + * Checks if a node has a return statement. Void return does not count. + * + * @param {object} node + * @returns {boolean|Node} + */ +// eslint-disable-next-line complexity + + +const hasReturnValue = (node, promFilter) => { + if (!node) { + return false; + } + + switch (node.type) { + case 'FunctionExpression': + case 'FunctionDeclaration': + case 'ArrowFunctionExpression': + { + return node.expression || hasReturnValue(node.body, promFilter); + } + + case 'BlockStatement': + { + return node.body.some(bodyNode => { + return bodyNode.type !== 'FunctionDeclaration' && hasReturnValue(bodyNode, promFilter); + }); + } + + case 'LabeledStatement': + case 'WhileStatement': + case 'DoWhileStatement': + case 'ForStatement': + case 'ForInStatement': + case 'ForOfStatement': + case 'WithStatement': + { + return hasReturnValue(node.body, promFilter); + } + + case 'IfStatement': + { + return hasReturnValue(node.consequent, promFilter) || hasReturnValue(node.alternate, promFilter); + } + + case 'TryStatement': + { + return hasReturnValue(node.block, promFilter) || hasReturnValue(node.handler && node.handler.body, promFilter) || hasReturnValue(node.finalizer, promFilter); + } + + case 'SwitchStatement': + { + return node.cases.some(someCase => { + return someCase.consequent.some(nde => { + return hasReturnValue(nde, promFilter); + }); + }); + } + + case 'ReturnStatement': + { + // void return does not count. + if (node.argument === null) { + return false; + } + + if (promFilter && isNewPromiseExpression(node.argument)) { + // Let caller decide how to filter, but this is, at the least, + // a return of sorts and truthy + return promFilter(node.argument); + } + + return true; + } + + default: + { + return false; + } + } +}; +/** + * Avoids further checking child nodes if a nested function shadows the + * resolver, but otherwise, if name is used (by call or passed in as an + * argument to another function), will be considered as non-empty. + * + * This could check for redeclaration of the resolver, but as such is + * unlikely, we avoid the performance cost of checking everywhere for + * (re)declarations or assignments. + * + * @param {AST} node + * @param {string} resolverName + * @returns {boolean} + */ +// eslint-disable-next-line complexity + + +const hasNonEmptyResolverCall = (node, resolverName) => { + if (!node) { + return false; + } // Arrow function without block + + + switch (node.type) { + // istanbul ignore next -- In Babel? + case 'OptionalCallExpression': + case 'CallExpression': + return node.callee.name === resolverName && ( // Implicit or expliit undefined + node.arguments.length > 1 || node.arguments[0] !== undefined) || node.arguments.some(nde => { + // Being passed in to another function (which might invoke it) + return nde.type === 'Identifier' && nde.name === resolverName || // Handle nested items + hasNonEmptyResolverCall(nde, resolverName); + }); + + case 'ChainExpression': + case 'Decorator': + case 'ExpressionStatement': + return hasNonEmptyResolverCall(node.expression, resolverName); + + case 'ClassBody': + case 'BlockStatement': + return node.body.some(bodyNode => { + return hasNonEmptyResolverCall(bodyNode, resolverName); + }); + + case 'FunctionExpression': + case 'FunctionDeclaration': + case 'ArrowFunctionExpression': + { + var _node$params$; + + // Shadowing + if (((_node$params$ = node.params[0]) === null || _node$params$ === void 0 ? void 0 : _node$params$.name) === resolverName) { + return false; + } + + return hasNonEmptyResolverCall(node.body, resolverName); + } + + case 'LabeledStatement': + case 'WhileStatement': + case 'DoWhileStatement': + case 'ForStatement': + case 'ForInStatement': + case 'ForOfStatement': + case 'WithStatement': + { + return hasNonEmptyResolverCall(node.body, resolverName); + } + + case 'ConditionalExpression': + case 'IfStatement': + { + return hasNonEmptyResolverCall(node.test, resolverName) || hasNonEmptyResolverCall(node.consequent, resolverName) || hasNonEmptyResolverCall(node.alternate, resolverName); + } + + case 'TryStatement': + { + return hasNonEmptyResolverCall(node.block, resolverName) || hasNonEmptyResolverCall(node.handler && node.handler.body, resolverName) || hasNonEmptyResolverCall(node.finalizer, resolverName); + } + + case 'SwitchStatement': + { + return node.cases.some(someCase => { + return someCase.consequent.some(nde => { + return hasNonEmptyResolverCall(nde, resolverName); + }); + }); + } + + case 'ArrayPattern': + case 'ArrayExpression': + return node.elements.some(element => { + return hasNonEmptyResolverCall(element, resolverName); + }); + + case 'AssignmentPattern': + return hasNonEmptyResolverCall(node.right, resolverName); + + case 'AssignmentExpression': + case 'BinaryExpression': + case 'LogicalExpression': + { + return hasNonEmptyResolverCall(node.left, resolverName) || hasNonEmptyResolverCall(node.right, resolverName); + } + // Comma + + case 'SequenceExpression': + case 'TemplateLiteral': + return node.expressions.some(subExpression => { + return hasNonEmptyResolverCall(subExpression, resolverName); + }); + + case 'ObjectPattern': + case 'ObjectExpression': + return node.properties.some(property => { + return hasNonEmptyResolverCall(property, resolverName); + }); + // istanbul ignore next -- In Babel? + + case 'ClassMethod': + case 'MethodDefinition': + return node.decorators && node.decorators.some(decorator => { + return hasNonEmptyResolverCall(decorator, resolverName); + }) || node.computed && hasNonEmptyResolverCall(node.key, resolverName) || hasNonEmptyResolverCall(node.value, resolverName); + // istanbul ignore next -- In Babel? + + case 'ObjectProperty': + /* eslint-disable no-fallthrough */ + // istanbul ignore next -- In Babel? + + case 'ClassProperty': + /* eslint-enable no-fallthrough */ + + case 'Property': + return node.computed && hasNonEmptyResolverCall(node.key, resolverName) || hasNonEmptyResolverCall(node.value, resolverName); + // istanbul ignore next -- In Babel? + + case 'ObjectMethod': + // istanbul ignore next -- In Babel? + return node.computed && hasNonEmptyResolverCall(node.key, resolverName) || node.arguments.some(nde => { + return hasNonEmptyResolverCall(nde, resolverName); + }); + + case 'ClassExpression': + case 'ClassDeclaration': + return hasNonEmptyResolverCall(node.body, resolverName); + + case 'AwaitExpression': + case 'SpreadElement': + case 'UnaryExpression': + case 'YieldExpression': + return hasNonEmptyResolverCall(node.argument, resolverName); + + case 'VariableDeclaration': + { + return node.declarations.some(nde => { + return hasNonEmptyResolverCall(nde, resolverName); + }); + } + + case 'VariableDeclarator': + { + return hasNonEmptyResolverCall(node.id, resolverName) || hasNonEmptyResolverCall(node.init, resolverName); + } + + case 'TaggedTemplateExpression': + return hasNonEmptyResolverCall(node.quasi, resolverName); + // ?. + // istanbul ignore next -- In Babel? + + case 'OptionalMemberExpression': + case 'MemberExpression': + return hasNonEmptyResolverCall(node.object, resolverName) || hasNonEmptyResolverCall(node.property, resolverName); + // istanbul ignore next -- In Babel? + + case 'Import': + case 'ImportExpression': + return hasNonEmptyResolverCall(node.source, resolverName); + + case 'ReturnStatement': + { + if (node.argument === null) { + return false; + } + + return hasNonEmptyResolverCall(node.argument, resolverName); + } + + /* + // Shouldn't need to parse literals/literal components, etc. + case 'Identifier': + case 'TemplateElement': + case 'Super': + // Exports not relevant in this context + */ + + default: + return false; + } +}; +/** + * Checks if a Promise executor has no resolve value or an empty value. + * An `undefined` resolve does not count. + * + * @param {object} node + * @param {boolean} anyPromiseAsReturn + * @returns {boolean} + */ + + +const hasValueOrExecutorHasNonEmptyResolveValue = (node, anyPromiseAsReturn) => { + return hasReturnValue(node, prom => { + if (anyPromiseAsReturn) { + return true; + } + + const [{ + params, + body + } = {}] = prom.arguments; + + if (!(params !== null && params !== void 0 && params.length)) { + return false; + } + + const [{ + name: resolverName + }] = params; + return hasNonEmptyResolverCall(body, resolverName); + }); +}; // eslint-disable-next-line complexity + + +const hasNonFunctionYield = (node, checkYieldReturnValue) => { + if (!node) { + return false; + } + + switch (node.type) { + case 'BlockStatement': + { + return node.body.some(bodyNode => { + return !['ArrowFunctionExpression', 'FunctionDeclaration', 'FunctionExpression'].includes(bodyNode.type) && hasNonFunctionYield(bodyNode, checkYieldReturnValue); + }); + } + // istanbul ignore next -- In Babel? + + case 'OptionalCallExpression': + case 'CallExpression': + return node.arguments.some(element => { + return hasNonFunctionYield(element, checkYieldReturnValue); + }); + + case 'ChainExpression': + case 'ExpressionStatement': + { + return hasNonFunctionYield(node.expression, checkYieldReturnValue); + } + + case 'LabeledStatement': + case 'WhileStatement': + case 'DoWhileStatement': + case 'ForStatement': + case 'ForInStatement': + case 'ForOfStatement': + case 'WithStatement': + { + return hasNonFunctionYield(node.body, checkYieldReturnValue); + } + + case 'ConditionalExpression': + case 'IfStatement': + { + return hasNonFunctionYield(node.test, checkYieldReturnValue) || hasNonFunctionYield(node.consequent, checkYieldReturnValue) || hasNonFunctionYield(node.alternate, checkYieldReturnValue); + } + + case 'TryStatement': + { + return hasNonFunctionYield(node.block, checkYieldReturnValue) || hasNonFunctionYield(node.handler && node.handler.body, checkYieldReturnValue) || hasNonFunctionYield(node.finalizer, checkYieldReturnValue); + } + + case 'SwitchStatement': + { + return node.cases.some(someCase => { + return someCase.consequent.some(nde => { + return hasNonFunctionYield(nde, checkYieldReturnValue); + }); + }); + } + + case 'ArrayPattern': + case 'ArrayExpression': + return node.elements.some(element => { + return hasNonFunctionYield(element, checkYieldReturnValue); + }); + + case 'AssignmentPattern': + return hasNonFunctionYield(node.right, checkYieldReturnValue); + + case 'VariableDeclaration': + { + return node.declarations.some(nde => { + return hasNonFunctionYield(nde, checkYieldReturnValue); + }); + } + + case 'VariableDeclarator': + { + return hasNonFunctionYield(node.id, checkYieldReturnValue) || hasNonFunctionYield(node.init, checkYieldReturnValue); + } + + case 'AssignmentExpression': + case 'BinaryExpression': + case 'LogicalExpression': + { + return hasNonFunctionYield(node.left, checkYieldReturnValue) || hasNonFunctionYield(node.right, checkYieldReturnValue); + } + // Comma + + case 'SequenceExpression': + case 'TemplateLiteral': + return node.expressions.some(subExpression => { + return hasNonFunctionYield(subExpression, checkYieldReturnValue); + }); + + case 'ObjectPattern': + case 'ObjectExpression': + return node.properties.some(property => { + return hasNonFunctionYield(property, checkYieldReturnValue); + }); + // istanbul ignore next -- In Babel? + + case 'ObjectProperty': + /* eslint-disable no-fallthrough */ + // istanbul ignore next -- In Babel? + + case 'ClassProperty': + /* eslint-enable no-fallthrough */ + + case 'Property': + return node.computed && hasNonFunctionYield(node.key, checkYieldReturnValue) || hasNonFunctionYield(node.value, checkYieldReturnValue); + // istanbul ignore next -- In Babel? + + case 'ObjectMethod': + // istanbul ignore next -- In Babel? + return node.computed && hasNonFunctionYield(node.key, checkYieldReturnValue) || node.arguments.some(nde => { + return hasNonFunctionYield(nde, checkYieldReturnValue); + }); + + case 'SpreadElement': + case 'UnaryExpression': + return hasNonFunctionYield(node.argument, checkYieldReturnValue); + + case 'TaggedTemplateExpression': + return hasNonFunctionYield(node.quasi, checkYieldReturnValue); + // ?. + // istanbul ignore next -- In Babel? + + case 'OptionalMemberExpression': + case 'MemberExpression': + return hasNonFunctionYield(node.object, checkYieldReturnValue) || hasNonFunctionYield(node.property, checkYieldReturnValue); + // istanbul ignore next -- In Babel? + + case 'Import': + case 'ImportExpression': + return hasNonFunctionYield(node.source, checkYieldReturnValue); + + case 'ReturnStatement': + { + if (node.argument === null) { + return false; + } + + return hasNonFunctionYield(node.argument, checkYieldReturnValue); + } + + case 'YieldExpression': + { + if (checkYieldReturnValue) { + if (node.parent.type === 'VariableDeclarator') { + return true; + } + + return false; + } // void return does not count. + + + if (node.argument === null) { + return false; + } + + return true; + } + + default: + { + return false; + } + } +}; +/** + * Checks if a node has a return statement. Void return does not count. + * + * @param {object} node + * @returns {boolean} + */ + + +const hasYieldValue = (node, checkYieldReturnValue) => { + return node.generator && (node.expression || hasNonFunctionYield(node.body, checkYieldReturnValue)); +}; +/** + * Checks if a node has a throws statement. + * + * @param {object} node + * @param {boolean} innerFunction + * @returns {boolean} + */ +// eslint-disable-next-line complexity + + +const hasThrowValue = (node, innerFunction) => { + if (!node) { + return false; + } // There are cases where a function may execute its inner function which + // throws, but we're treating functions atomically rather than trying to + // follow them + + + switch (node.type) { + case 'FunctionExpression': + case 'FunctionDeclaration': + case 'ArrowFunctionExpression': + { + return !innerFunction && hasThrowValue(node.body, true); + } + + case 'BlockStatement': + { + return node.body.some(bodyNode => { + return bodyNode.type !== 'FunctionDeclaration' && hasThrowValue(bodyNode); + }); + } + + case 'LabeledStatement': + case 'WhileStatement': + case 'DoWhileStatement': + case 'ForStatement': + case 'ForInStatement': + case 'ForOfStatement': + case 'WithStatement': + { + return hasThrowValue(node.body); + } + + case 'IfStatement': + { + return hasThrowValue(node.consequent) || hasThrowValue(node.alternate); + } + // We only consider it to throw an error if the catch or finally blocks throw an error. + + case 'TryStatement': + { + return hasThrowValue(node.handler && node.handler.body) || hasThrowValue(node.finalizer); + } + + case 'SwitchStatement': + { + return node.cases.some(someCase => { + return someCase.consequent.some(nde => { + return hasThrowValue(nde); + }); + }); + } + + case 'ThrowStatement': + { + return true; + } + + default: + { + return false; + } + } +}; +/** @param {string} tag */ + +/* +const isInlineTag = (tag) => { + return /^(@link|@linkcode|@linkplain|@tutorial) /u.test(tag); +}; +*/ + +/** + * Parses GCC Generic/Template types + * + * @see {https://github.com/google/closure-compiler/wiki/Generic-Types} + * @see {https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#template} + * @param {JsDocTag} tag + * @returns {Array} + */ + + +const parseClosureTemplateTag = tag => { + return tag.name.split(',').map(type => { + return type.trim(); + }); +}; +/** + * Checks user option for `contexts` array, defaulting to + * contexts designated by the rule. Returns an array of + * ESTree AST types, indicating allowable contexts. + * + * @param {*} context + * @param {true|string[]} defaultContexts + * @returns {string[]} + */ + + +const enforcedContexts = (context, defaultContexts) => { + const { + contexts = defaultContexts === true ? ['ArrowFunctionExpression', 'FunctionDeclaration', 'FunctionExpression'] : defaultContexts + } = context.options[0] || {}; + return contexts; +}; +/** + * @param {string[]} contexts + * @param {Function} checkJsdoc + */ + + +const getContextObject = (contexts, checkJsdoc) => { + const properties = {}; + contexts.forEach(prop => { + if (typeof prop === 'object') { + properties[prop.context] = checkJsdoc; + } else { + properties[prop] = checkJsdoc; + } + }); + return properties; +}; + +const filterTags = (tags, filter) => { + return tags.filter(filter); +}; + +const tagsWithNamesAndDescriptions = new Set(['param', 'arg', 'argument', 'property', 'prop', 'template', // These two are parsed by our custom parser as though having a `name` +'returns', 'return']); + +const getTagsByType = (context, mode, tags, tagPreference) => { + const descName = getPreferredTagName(context, mode, 'description', tagPreference); + const tagsWithoutNames = []; + const tagsWithNames = filterTags(tags, tag => { + const { + tag: tagName + } = tag; + const tagWithName = tagsWithNamesAndDescriptions.has(tagName); + + if (!tagWithName && tagName !== descName) { + tagsWithoutNames.push(tag); + } + + return tagWithName; + }); + return { + tagsWithNames, + tagsWithoutNames + }; +}; + +const getIndent = sourceCode => { + var _sourceCode$text$matc, _sourceCode$text$matc2; + + return ((_sourceCode$text$matc = (_sourceCode$text$matc2 = sourceCode.text.match(/^\n*([ \t]+)/u)) === null || _sourceCode$text$matc2 === void 0 ? void 0 : _sourceCode$text$matc2[1]) !== null && _sourceCode$text$matc !== void 0 ? _sourceCode$text$matc : '') + ' '; +}; + +const isConstructor = node => { + var _node$parent; + + return (node === null || node === void 0 ? void 0 : node.type) === 'MethodDefinition' && node.kind === 'constructor' || (node === null || node === void 0 ? void 0 : (_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : _node$parent.kind) === 'constructor'; +}; + +const isGetter = node => { + return node && node.parent.kind === 'get'; +}; + +const isSetter = node => { + return node && node.parent.kind === 'set'; +}; + +const hasAccessorPair = node => { + const { + type, + kind: sourceKind, + key: { + name: sourceName + } + } = node; + const oppositeKind = sourceKind === 'get' ? 'set' : 'get'; + const children = type === 'MethodDefinition' ? 'body' : 'properties'; + return node.parent[children].some(({ + kind, + key: { + name + } + }) => { + return kind === oppositeKind && name === sourceName; + }); +}; + +const exemptSpeciaMethods = (jsdoc, node, context, schema) => { + const hasSchemaOption = prop => { + var _context$options$0$pr, _context$options$; + + const schemaProperties = schema[0].properties; + return (_context$options$0$pr = (_context$options$ = context.options[0]) === null || _context$options$ === void 0 ? void 0 : _context$options$[prop]) !== null && _context$options$0$pr !== void 0 ? _context$options$0$pr : schemaProperties[prop] && schemaProperties[prop].default; + }; + + const checkGetters = hasSchemaOption('checkGetters'); + const checkSetters = hasSchemaOption('checkSetters'); + return !hasSchemaOption('checkConstructors') && (isConstructor(node) || hasATag(jsdoc, ['class', 'constructor'])) || isGetter(node) && (!checkGetters || checkGetters === 'no-setter' && hasAccessorPair(node.parent)) || isSetter(node) && (!checkSetters || checkSetters === 'no-getter' && hasAccessorPair(node.parent)); +}; +/** + * Since path segments may be unquoted (if matching a reserved word, + * identifier or numeric literal) or single or double quoted, in either + * the `@param` or in source, we need to strip the quotes to give a fair + * comparison. + * + * @param {string} str + * @returns {string} + */ + + +const dropPathSegmentQuotes = str => { + return str.replace(/\.(['"])(.*)\1/gu, '.$2'); +}; + +const comparePaths = name => { + return otherPathName => { + return otherPathName === name || dropPathSegmentQuotes(otherPathName) === dropPathSegmentQuotes(name); + }; +}; + +const getRegexFromString = (regexString, requiredFlags) => { + const match = regexString.match(/^\/(.*)\/([gimyus]*)$/us); + let flags = 'u'; + let regex = regexString; + + if (match) { + [, regex, flags] = match; + + if (!flags) { + flags = 'u'; + } + } + + const uniqueFlags = [...new Set(flags + (requiredFlags || ''))]; + flags = uniqueFlags.join(''); + return new RegExp(regex, flags); +}; + +var _default = { + comparePaths, + dropPathSegmentQuotes, + enforcedContexts, + exemptSpeciaMethods, + filterTags, + flattenRoots, + getContextObject, + getFunctionParameterNames, + getIndent, + getJsdocTagsDeep, + getPreferredTagName, + getRegexFromString, + getTagsByType, + getTagStructureForMode, + hasATag, + hasDefinedTypeTag, + hasParams, + hasReturnValue, + hasTag, + hasThrowValue, + hasValueOrExecutorHasNonEmptyResolveValue, + hasYieldValue, + isConstructor, + isGetter, + isNamepathDefiningTag, + isSetter, + isValidTag, + overrideTagStructure, + parseClosureTemplateTag, + setTagStructure, + tagMightHaveNamepath, + tagMightHaveNamePosition, + tagMightHaveTypePosition, + tagMissingRequiredTypeOrNamepath, + tagMustHaveNamePosition, + tagMustHaveTypePosition +}; +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=jsdocUtils.js.map +}); + +var iterateJsdoc_1 = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = iterateJsdoc; +exports.parseComment = exports.getSettings = void 0; + + + +var _description = _interopRequireWildcard(description$2); + +var _name = _interopRequireDefault(name$1); + +var _tag = _interopRequireDefault(tag); + +var _type = _interopRequireDefault(type_1); + + + +var _lodash = _interopRequireDefault(lodash__default['default']); + + + +var _jsdocUtils = _interopRequireDefault(jsdocUtils); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +/* +const { + align as commentAlign, + flow: commentFlow, + indent: commentIndent, +} = transforms; +*/ +const globalState = new Map(); + +const hasSeeWithLink = spec => { + return spec.tag === 'see' && /\{@link.+?\}/u.test(spec.source[0].source); +}; + +const getTokenizers = () => { + // trim + return [// Tag + (0, _tag.default)(), // Type + spec => { + if (['default', 'defaultvalue', 'see'].includes(spec.tag)) { + return spec; + } + + return (0, _type.default)()(spec); + }, // Name + spec => { + if (spec.tag === 'template') { + // const preWS = spec.postTag; + const remainder = spec.source[0].tokens.description; + const pos = remainder.search(/(? { + return (0, _description.default)((0, _description.getJoiner)('preserve'))(spec); + }]; +}; +/** + * + * @param {object} commentNode + * @param {string} indent Whitespace + * @returns {object} + */ + + +const parseComment = (commentNode, indent) => { + // Preserve JSDoc block start/end indentation. + return (0, lib.parse)(`/*${commentNode.value}*/`, { + // @see https://github.com/yavorskiy/comment-parser/issues/21 + tokenizers: getTokenizers() + })[0] || (0, util.seedBlock)({ + source: [{ + number: 0, + tokens: (0, util.seedTokens)({ + delimiter: '/**', + description: '', + end: '', + postDelimiter: '', + start: '' + }) + }, { + number: 1, + tokens: (0, util.seedTokens)({ + delimiter: '', + description: '', + end: '*/', + postDelimiter: '', + start: indent + ' ' + }) + }] + }); +}; + +exports.parseComment = parseComment; + +const getBasicUtils = (context, { + tagNamePreference, + mode +}) => { + const utils = {}; + + utils.reportSettings = message => { + context.report({ + loc: { + start: { + column: 1, + line: 1 + } + }, + message + }); + }; + + utils.parseClosureTemplateTag = tag => { + return _jsdocUtils.default.parseClosureTemplateTag(tag); + }; + + utils.getPreferredTagNameObject = ({ + tagName + }) => { + const ret = _jsdocUtils.default.getPreferredTagName(context, mode, tagName, tagNamePreference); + + const isObject = ret && typeof ret === 'object'; + + if (ret === false || isObject && !ret.replacement) { + return { + blocked: true, + tagName + }; + } + + return ret; + }; + + return utils; +}; + +const getUtils = (node, jsdoc, jsdocNode, settings, report, context, iteratingAll, ruleConfig, indent) => { + const ancestors = context.getAncestors(); + const sourceCode = context.getSourceCode(); + const utils = getBasicUtils(context, settings); + const { + tagNamePreference, + overrideReplacesDocs, + implementsReplacesDocs, + augmentsExtendsReplacesDocs, + maxLines, + minLines, + mode + } = settings; + + utils.isIteratingFunction = () => { + return !iteratingAll || ['MethodDefinition', 'ArrowFunctionExpression', 'FunctionDeclaration', 'FunctionExpression'].includes(node && node.type); + }; + + utils.isVirtualFunction = () => { + return iteratingAll && utils.hasATag(['callback', 'function', 'func', 'method']); + }; + + utils.stringify = (tagBlock, specRewire) => { + return (0, lib.stringify)(specRewire ? (0, util.rewireSpecs)(tagBlock) : tagBlock); + }; + + utils.reportJSDoc = (msg, tag, handler, specRewire) => { + report(msg, handler ? fixer => { + handler(); + const replacement = utils.stringify(jsdoc, specRewire); + return fixer.replaceText(jsdocNode, replacement); + } : null, tag); + }; + + utils.getRegexFromString = (str, requiredFlags) => { + return _jsdocUtils.default.getRegexFromString(str, requiredFlags); + }; + + utils.getDescription = () => { + const descriptions = []; + let lastDescriptionLine; + + if (jsdoc.source[0].tokens.description) { + descriptions.push(jsdoc.source[0].tokens.description); + } + + jsdoc.source.slice(1).some(({ + tokens: { + description, + tag, + end + } + }, idx) => { + if (tag || end) { + lastDescriptionLine = idx; + return true; + } + + descriptions.push(description); + return false; + }); + return { + description: descriptions.join('\n'), + lastDescriptionLine + }; + }; + + utils.changeTag = (tag, ...tokens) => { + tag.source.forEach((src, idx) => { + src.tokens = { ...src.tokens, + ...tokens[idx] + }; + }); + }; + + utils.setTag = (tag, tokens) => { + tag.source = [{ + // Or tag.source[0].number? + number: tag.line, + tokens: (0, util.seedTokens)({ + delimiter: '*', + postDelimiter: ' ', + start: indent + ' ', + tag: '@' + tag.tag, + ...tokens + }) + }]; + }; + + utils.removeTag = tagIndex => { + const { + source + } = jsdoc.tags[tagIndex]; + let lastIndex; + const firstNumber = jsdoc.source[0].number; + source.forEach(({ + number + }) => { + const sourceIndex = jsdoc.source.findIndex(({ + number: srcNumber, + tokens: { + end + } + }) => { + return number === srcNumber && !end; + }); + + if (sourceIndex > -1) { + jsdoc.source.splice(sourceIndex, 1); + lastIndex = sourceIndex; + } + }); + jsdoc.source.slice(lastIndex).forEach((src, idx) => { + src.number = firstNumber + lastIndex + idx; + }); + }; + + utils.addTag = targetTagName => { + var _jsdoc$tags$source$0$, _jsdoc$tags, _jsdoc$tags$source$; + + const number = ((_jsdoc$tags$source$0$ = (_jsdoc$tags = jsdoc.tags[jsdoc.tags.length - 1]) === null || _jsdoc$tags === void 0 ? void 0 : (_jsdoc$tags$source$ = _jsdoc$tags.source[0]) === null || _jsdoc$tags$source$ === void 0 ? void 0 : _jsdoc$tags$source$.number) !== null && _jsdoc$tags$source$0$ !== void 0 ? _jsdoc$tags$source$0$ : 0) + 1; + jsdoc.source.splice(number, 0, { + number, + source: '', + tokens: (0, util.seedTokens)({ + delimiter: '*', + postDelimiter: ' ', + start: indent + ' ', + tag: `@${targetTagName}` + }) + }); + jsdoc.source.slice(number + 1).forEach(src => { + src.number++; + }); + }; + + utils.flattenRoots = params => { + return _jsdocUtils.default.flattenRoots(params); + }; + + utils.getFunctionParameterNames = useDefaultObjectProperties => { + return _jsdocUtils.default.getFunctionParameterNames(node, useDefaultObjectProperties); + }; + + utils.hasParams = () => { + return _jsdocUtils.default.hasParams(node); + }; + + utils.isGenerator = () => { + return node && (node.generator || node.type === 'MethodDefinition' && node.value.generator || ['ExportNamedDeclaration', 'ExportDefaultDeclaration'].includes(node.type) && node.declaration.generator); + }; + + utils.isConstructor = () => { + return _jsdocUtils.default.isConstructor(node); + }; + + utils.getJsdocTagsDeep = tagName => { + const name = utils.getPreferredTagName({ + tagName + }); + + if (!name) { + return false; + } + + return _jsdocUtils.default.getJsdocTagsDeep(jsdoc, name); + }; + + utils.getPreferredTagName = ({ + tagName, + skipReportingBlockedTag = false, + allowObjectReturn = false, + defaultMessage = `Unexpected tag \`@${tagName}\`` + }) => { + const ret = _jsdocUtils.default.getPreferredTagName(context, mode, tagName, tagNamePreference); + + const isObject = ret && typeof ret === 'object'; + + if (utils.hasTag(tagName) && (ret === false || isObject && !ret.replacement)) { + if (skipReportingBlockedTag) { + return { + blocked: true, + tagName + }; + } + + const message = isObject && ret.message || defaultMessage; + report(message, null, utils.getTags(tagName)[0]); + return false; + } + + return isObject && !allowObjectReturn ? ret.replacement : ret; + }; + + utils.isValidTag = (name, definedTags) => { + return _jsdocUtils.default.isValidTag(context, mode, name, definedTags); + }; + + utils.hasATag = name => { + return _jsdocUtils.default.hasATag(jsdoc, name); + }; + + utils.hasTag = name => { + return _jsdocUtils.default.hasTag(jsdoc, name); + }; + + utils.comparePaths = name => { + return _jsdocUtils.default.comparePaths(name); + }; + + utils.dropPathSegmentQuotes = name => { + return _jsdocUtils.default.dropPathSegmentQuotes(name); + }; + + utils.avoidDocs = () => { + var _context$options$0$ex, _context$options$; + + if (overrideReplacesDocs !== false && (utils.hasTag('override') || utils.classHasTag('override')) || implementsReplacesDocs !== false && (utils.hasTag('implements') || utils.classHasTag('implements')) || augmentsExtendsReplacesDocs && (utils.hasATag(['augments', 'extends']) || utils.classHasTag('augments') || utils.classHasTag('extends'))) { + return true; + } + + if (_jsdocUtils.default.exemptSpeciaMethods(jsdoc, node, context, ruleConfig.meta.schema)) { + return true; + } + + const exemptedBy = (_context$options$0$ex = (_context$options$ = context.options[0]) === null || _context$options$ === void 0 ? void 0 : _context$options$.exemptedBy) !== null && _context$options$0$ex !== void 0 ? _context$options$0$ex : ['inheritDoc', ...(mode === 'closure' ? [] : ['inheritdoc'])]; + + if (exemptedBy.length && utils.getPresentTags(exemptedBy).length) { + return true; + } + + return false; + }; + + ['tagMightHaveNamePosition', 'tagMightHaveTypePosition'].forEach(method => { + utils[method] = (tagName, otherModeMaps) => { + const result = _jsdocUtils.default[method](tagName); + + if (result) { + return true; + } + + if (!otherModeMaps) { + return false; + } + + const otherResult = otherModeMaps.some(otherModeMap => { + return _jsdocUtils.default[method](tagName, otherModeMap); + }); + return otherResult ? { + otherMode: true + } : false; + }; + }); + ['tagMustHaveNamePosition', 'tagMustHaveTypePosition', 'tagMissingRequiredTypeOrNamepath'].forEach(method => { + utils[method] = (tagName, otherModeMaps) => { + const result = _jsdocUtils.default[method](tagName); + + if (!result) { + return false; + } // if (!otherModeMaps) { return true; } + + + const otherResult = otherModeMaps.every(otherModeMap => { + return _jsdocUtils.default[method](tagName, otherModeMap); + }); + return otherResult ? true : { + otherMode: false + }; + }; + }); + ['isNamepathDefiningTag', 'tagMightHaveNamepath'].forEach(method => { + utils[method] = tagName => { + return _jsdocUtils.default[method](tagName); + }; + }); + + utils.getTagStructureForMode = mde => { + return _jsdocUtils.default.getTagStructureForMode(mde, settings.structuredTags); + }; + + utils.hasDefinedTypeTag = tag => { + return _jsdocUtils.default.hasDefinedTypeTag(tag); + }; + + utils.hasValueOrExecutorHasNonEmptyResolveValue = anyPromiseAsReturn => { + return _jsdocUtils.default.hasValueOrExecutorHasNonEmptyResolveValue(node, anyPromiseAsReturn); + }; + + utils.hasYieldValue = () => { + if (['ExportNamedDeclaration', 'ExportDefaultDeclaration'].includes(node.type)) { + return _jsdocUtils.default.hasYieldValue(node.declaration); + } + + return _jsdocUtils.default.hasYieldValue(node); + }; + + utils.hasYieldReturnValue = () => { + return _jsdocUtils.default.hasYieldValue(node, true); + }; + + utils.hasThrowValue = () => { + return _jsdocUtils.default.hasThrowValue(node); + }; + + utils.isAsync = () => { + return node.async; + }; + + utils.getTags = tagName => { + return utils.filterTags(item => { + return item.tag === tagName; + }); + }; + + utils.getPresentTags = tagList => { + return utils.filterTags(tag => { + return tagList.includes(tag.tag); + }); + }; + + utils.filterTags = filter => { + return _jsdocUtils.default.filterTags(jsdoc.tags, filter); + }; + + utils.getTagsByType = tags => { + return _jsdocUtils.default.getTagsByType(context, mode, tags, tagNamePreference); + }; + + utils.hasOptionTag = tagName => { + var _context$options$2; + + const { + tags + } = (_context$options$2 = context.options[0]) !== null && _context$options$2 !== void 0 ? _context$options$2 : {}; + return Boolean(tags && tags.includes(tagName)); + }; + + utils.getClassNode = () => { + return [...ancestors, node].reverse().find(parent => { + return parent && ['ClassDeclaration', 'ClassExpression'].includes(parent.type); + }) || null; + }; + + utils.getClassJsdoc = () => { + const classNode = utils.getClassNode(); + + if (!classNode) { + return null; + } + + const classJsdocNode = (0, getJSDocComment_1.getJSDocComment)(sourceCode, classNode, { + maxLines, + minLines + }); + + if (classJsdocNode) { + const indnt = ' '.repeat(classJsdocNode.loc.start.column); + return parseComment(classJsdocNode, indnt); + } + + return null; + }; + + utils.classHasTag = tagName => { + const classJsdoc = utils.getClassJsdoc(); + return Boolean(classJsdoc) && _jsdocUtils.default.hasTag(classJsdoc, tagName); + }; + + utils.forEachPreferredTag = (tagName, arrayHandler, skipReportingBlockedTag = false) => { + const targetTagName = utils.getPreferredTagName({ + skipReportingBlockedTag, + tagName + }); + + if (!targetTagName || skipReportingBlockedTag && targetTagName && typeof targetTagName === 'object') { + return; + } + + const matchingJsdocTags = _lodash.default.filter(jsdoc.tags, { + tag: targetTagName + }); + + matchingJsdocTags.forEach(matchingJsdocTag => { + arrayHandler(matchingJsdocTag, targetTagName); + }); + }; + + return utils; +}; + +const getSettings = context => { + var _context$settings$jsd, _context$settings$jsd2, _context$settings$jsd3, _context$settings$jsd4, _context$settings$jsd5, _context$settings$jsd6, _context$settings$jsd7, _context$settings$jsd8, _context$settings$jsd9, _context$settings$jsd10, _context$settings$jsd11, _context$settings$jsd12, _context$settings$jsd13, _context$settings$jsd14, _context$settings$jsd15, _context$settings$jsd16, _context$settings$jsd17; + + /* eslint-disable sort-keys-fix/sort-keys-fix */ + const settings = { + // All rules + ignorePrivate: Boolean((_context$settings$jsd = context.settings.jsdoc) === null || _context$settings$jsd === void 0 ? void 0 : _context$settings$jsd.ignorePrivate), + ignoreInternal: Boolean((_context$settings$jsd2 = context.settings.jsdoc) === null || _context$settings$jsd2 === void 0 ? void 0 : _context$settings$jsd2.ignoreInternal), + maxLines: Number((_context$settings$jsd3 = (_context$settings$jsd4 = context.settings.jsdoc) === null || _context$settings$jsd4 === void 0 ? void 0 : _context$settings$jsd4.maxLines) !== null && _context$settings$jsd3 !== void 0 ? _context$settings$jsd3 : 1), + minLines: Number((_context$settings$jsd5 = (_context$settings$jsd6 = context.settings.jsdoc) === null || _context$settings$jsd6 === void 0 ? void 0 : _context$settings$jsd6.minLines) !== null && _context$settings$jsd5 !== void 0 ? _context$settings$jsd5 : 0), + // `check-tag-names` and many returns/param rules + tagNamePreference: (_context$settings$jsd7 = (_context$settings$jsd8 = context.settings.jsdoc) === null || _context$settings$jsd8 === void 0 ? void 0 : _context$settings$jsd8.tagNamePreference) !== null && _context$settings$jsd7 !== void 0 ? _context$settings$jsd7 : {}, + // `check-types` and `no-undefined-types` + preferredTypes: (_context$settings$jsd9 = (_context$settings$jsd10 = context.settings.jsdoc) === null || _context$settings$jsd10 === void 0 ? void 0 : _context$settings$jsd10.preferredTypes) !== null && _context$settings$jsd9 !== void 0 ? _context$settings$jsd9 : {}, + // `check-types`, `no-undefined-types`, `valid-types` + structuredTags: (_context$settings$jsd11 = (_context$settings$jsd12 = context.settings.jsdoc) === null || _context$settings$jsd12 === void 0 ? void 0 : _context$settings$jsd12.structuredTags) !== null && _context$settings$jsd11 !== void 0 ? _context$settings$jsd11 : {}, + // `require-param`, `require-description`, `require-example`, `require-returns` + overrideReplacesDocs: (_context$settings$jsd13 = context.settings.jsdoc) === null || _context$settings$jsd13 === void 0 ? void 0 : _context$settings$jsd13.overrideReplacesDocs, + implementsReplacesDocs: (_context$settings$jsd14 = context.settings.jsdoc) === null || _context$settings$jsd14 === void 0 ? void 0 : _context$settings$jsd14.implementsReplacesDocs, + augmentsExtendsReplacesDocs: (_context$settings$jsd15 = context.settings.jsdoc) === null || _context$settings$jsd15 === void 0 ? void 0 : _context$settings$jsd15.augmentsExtendsReplacesDocs, + // Many rules, e.g., `check-tag-names` + mode: (_context$settings$jsd16 = (_context$settings$jsd17 = context.settings.jsdoc) === null || _context$settings$jsd17 === void 0 ? void 0 : _context$settings$jsd17.mode) !== null && _context$settings$jsd16 !== void 0 ? _context$settings$jsd16 : context.parserPath.includes('@typescript-eslint') ? 'typescript' : 'jsdoc' + }; + /* eslint-enable sort-keys-fix/sort-keys-fix */ + + _jsdocUtils.default.setTagStructure(settings.mode); + + try { + _jsdocUtils.default.overrideTagStructure(settings.structuredTags); + } catch (error) { + context.report({ + loc: { + start: { + column: 1, + line: 1 + } + }, + message: error.message + }); + return false; + } + + return settings; +}; +/** + * Create the report function + * + * @param {object} context + * @param {object} commentNode + */ + + +exports.getSettings = getSettings; + +const makeReport = (context, commentNode) => { + const report = (message, fix = null, jsdocLoc = null, data = null) => { + let loc; + + if (jsdocLoc) { + if (!('line' in jsdocLoc)) { + jsdocLoc.line = jsdocLoc.source[0].number; + } + + const lineNumber = commentNode.loc.start.line + jsdocLoc.line; + loc = { + end: { + line: lineNumber + }, + start: { + line: lineNumber + } + }; + + if (jsdocLoc.column) { + const colNumber = commentNode.loc.start.column + jsdocLoc.column; + loc.end.column = colNumber; + loc.start.column = colNumber; + } + } + + context.report({ + data, + fix, + loc, + message, + node: commentNode + }); + }; + + return report; +}; +/** + * @typedef {ReturnType} Utils + * @typedef {ReturnType} Settings + * @typedef {( + * arg: { + * context: object, + * sourceCode: object, + * indent: string, + * jsdoc: object, + * jsdocNode: object, + * node: object | null, + * report: ReturnType, + * settings: Settings, + * utils: Utils, + * } + * ) => any } JsdocVisitor + */ + + +const iterate = (ruleConfig, context, lines, jsdocNode, node, settings, sourceCode, iterator, state, iteratingAll) => { + const sourceLine = lines[jsdocNode.loc.start.line - 1]; + const indent = sourceLine.charAt(0).repeat(jsdocNode.loc.start.column); + const jsdoc = parseComment(jsdocNode, indent); + const report = makeReport(context, jsdocNode); + const utils = getUtils(node, jsdoc, jsdocNode, settings, report, context, iteratingAll, ruleConfig, indent); + + if (!ruleConfig.checkInternal && settings.ignoreInternal && utils.hasTag('internal')) { + return; + } + + if (!ruleConfig.checkPrivate && settings.ignorePrivate && (utils.hasTag('private') || _lodash.default.filter(jsdoc.tags, { + tag: 'access' + }).some(({ + description + }) => { + return description === 'private'; + }))) { + return; + } + + iterator({ + context, + globalState, + indent, + iteratingAll, + jsdoc, + jsdocNode, + node, + report, + settings, + sourceCode, + state, + utils + }); +}; +/** + * Create an eslint rule that iterates over all JSDocs, regardless of whether + * they are attached to a function-like node. + * + * @param {JsdocVisitor} iterator + * @param {{meta: any}} ruleConfig + */ + + +const iterateAllJsdocs = (iterator, ruleConfig) => { + const trackedJsdocs = []; + let settings; + + const callIterator = (context, node, jsdocNodes, state, lastCall) => { + const sourceCode = context.getSourceCode(); + const { + lines + } = sourceCode; + const utils = getBasicUtils(context, settings); + jsdocNodes.forEach(jsdocNode => { + if (!/^\/\*\*\s/.test(sourceCode.getText(jsdocNode))) { + return; + } + + iterate(ruleConfig, context, lines, jsdocNode, node, settings, sourceCode, iterator, state, true); + }); + + if (lastCall && ruleConfig.exit) { + ruleConfig.exit({ + context, + state, + utils + }); + } + }; + + return { + create(context) { + const sourceCode = context.getSourceCode(); + settings = getSettings(context); + + if (!settings) { + return {}; + } + + const state = {}; + return { + '*:not(Program)'(node) { + const reducedNode = (0, getJSDocComment_1.getReducedASTNode)(node, sourceCode); + + if (node !== reducedNode) { + return; + } + + const comment = (0, getJSDocComment_1.getJSDocComment)(sourceCode, node, settings); + + if (trackedJsdocs.includes(comment)) { + return; + } + + if (!comment) { + if (ruleConfig.nonComment) { + ruleConfig.nonComment({ + node, + state + }); + } + + return; + } + + trackedJsdocs.push(comment); + callIterator(context, node, [comment], state); + }, + + 'Program:exit'() { + const allComments = sourceCode.getAllComments(); + const untrackedJSdoc = allComments.filter(node => { + return !trackedJsdocs.includes(node); + }); + callIterator(context, null, untrackedJSdoc, state, true); + } + + }; + }, + + meta: ruleConfig.meta + }; +}; +/** + * Create an eslint rule that iterates over all JSDocs, regardless of whether + * they are attached to a function-like node. + * + * @param {JsdocVisitor} iterator + * @param {{meta: any}} ruleConfig + */ + + +const checkFile = (iterator, ruleConfig) => { + return { + create(context) { + const sourceCode = context.getSourceCode(); + const settings = getSettings(context); + + if (!settings) { + return {}; + } + + return { + 'Program:exit'() { + const allComments = sourceCode.getAllComments(); + const { + lines + } = sourceCode; + const utils = getBasicUtils(context, settings); + iterator({ + allComments, + context, + lines, + makeReport, + settings, + sourceCode, + utils + }); + } + + }; + }, + + meta: ruleConfig.meta + }; +}; + +/** + * @param {JsdocVisitor} iterator + * @param {{ + * meta: any, + * contextDefaults?: true | string[], + * iterateAllJsdocs?: true, + * }} ruleConfig + */ +function iterateJsdoc(iterator, ruleConfig) { + var _ruleConfig$meta; + + const metaType = ruleConfig === null || ruleConfig === void 0 ? void 0 : (_ruleConfig$meta = ruleConfig.meta) === null || _ruleConfig$meta === void 0 ? void 0 : _ruleConfig$meta.type; + + if (!metaType || !['problem', 'suggestion', 'layout'].includes(metaType)) { + throw new TypeError('Rule must include `meta.type` option (with value "problem", "suggestion", or "layout")'); + } + + if (typeof iterator !== 'function') { + throw new TypeError('The iterator argument must be a function.'); + } + + if (ruleConfig.checkFile) { + return checkFile(iterator, ruleConfig); + } + + if (ruleConfig.iterateAllJsdocs) { + return iterateAllJsdocs(iterator, ruleConfig); + } + + return { + /** + * The entrypoint for the JSDoc rule. + * + * @param {*} context + * a reference to the context which hold all important information + * like settings and the sourcecode to check. + * @returns {object} + * a list with parser callback function. + */ + create(context) { + let contexts; + + if (ruleConfig.contextDefaults) { + contexts = _jsdocUtils.default.enforcedContexts(context, ruleConfig.contextDefaults); + + if (contexts.includes('any')) { + return iterateAllJsdocs(iterator, ruleConfig).create(context); + } + } + + const sourceCode = context.getSourceCode(); + const settings = getSettings(context); + + if (!settings) { + return {}; + } + + const { + lines + } = sourceCode; + + const checkJsdoc = node => { + const jsdocNode = (0, getJSDocComment_1.getJSDocComment)(sourceCode, node, settings); + + if (!jsdocNode) { + return; + } + + iterate(ruleConfig, context, lines, jsdocNode, node, settings, sourceCode, iterator); + }; + + if (ruleConfig.contextDefaults) { + return _jsdocUtils.default.getContextObject(contexts, checkJsdoc); + } + + return { + ArrowFunctionExpression: checkJsdoc, + FunctionDeclaration: checkJsdoc, + FunctionExpression: checkJsdoc + }; + }, + + meta: ruleConfig.meta + }; +} +//# sourceMappingURL=iterateJsdoc.js.map +}); + +var checkAccess = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const accessLevels = ['package', 'private', 'protected', 'public']; + +var _default = (0, _iterateJsdoc.default)(({ + report, + utils +}) => { + utils.forEachPreferredTag('access', (jsdocParameter, targetTagName) => { + const desc = targetTagName === 'access' ? jsdocParameter.description : jsdocParameter.name + ' ' + jsdocParameter.description; + + if (!accessLevels.includes(desc.trim())) { + report(`Missing valid JSDoc @${targetTagName} level.`, null, jsdocParameter); + } + }); + const accessLength = utils.getTags('access').length; + const individualTagLength = utils.getPresentTags(accessLevels).length; + + if (accessLength && individualTagLength) { + report('The @access tag may not be used with specific access-control tags (@package, @private, @protected, or @public).'); + } + + if (accessLength > 1 || individualTagLength > 1) { + report('At most one access-control tag may be present on a jsdoc block.'); + } +}, { + checkPrivate: true, + iterateAllJsdocs: true, + meta: { + docs: { + description: 'Checks that `@access` tags have a valid value.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-access' + }, + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=checkAccess.js.map +}); + +var checkAlignment = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const trimStart = string => { + return string.replace(/^\s+/u, ''); +}; + +var _default = (0, _iterateJsdoc.default)(({ + sourceCode, + jsdocNode, + report, + indent +}) => { + // `indent` is whitespace from line 1 (`/**`), so slice and account for "/". + const indentLevel = indent.length + 1; + const sourceLines = sourceCode.getText(jsdocNode).split('\n').slice(1).map(line => { + return line.split('*')[0]; + }).filter(line => { + return !trimStart(line).length; + }); + + const fix = fixer => { + const replacement = sourceCode.getText(jsdocNode).split('\n').map((line, index) => { + // Ignore the first line and all lines not starting with `*` + const ignored = !index || trimStart(line.split('*')[0]).length; + return ignored ? line : `${indent} ${trimStart(line)}`; + }).join('\n'); + return fixer.replaceText(jsdocNode, replacement); + }; + + sourceLines.some((line, lineNum) => { + if (line.length !== indentLevel) { + report('Expected JSDoc block to be aligned.', fix, { + line: lineNum + 1 + }); + return true; + } + + return false; + }); +}, { + iterateAllJsdocs: true, + meta: { + docs: { + description: 'Reports invalid alignment of JSDoc block asterisks.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-alignment' + }, + fixable: 'code', + type: 'layout' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=checkAlignment.js.map +}); + +/** + * @fileoverview Default CLIEngineOptions. + * @author Ian VanSchooten + */ + +var defaultCliOptions = { + configFile: null, + baseConfig: false, + rulePaths: [], + useEslintrc: true, + envs: [], + globals: [], + extensions: null, + ignore: true, + ignorePath: void 0, + cache: false, + + /* + * in order to honor the cacheFile option if specified + * this option should not have a default value otherwise + * it will always be used + */ + cacheLocation: "", + cacheFile: ".eslintcache", + cacheStrategy: "metadata", + fix: false, + allowInlineConfig: true, + reportUnusedDisableDirectives: void 0, + globInputPaths: true +}; + +var name = "eslint"; +var version$1 = "7.24.0"; +var author = "Nicholas C. Zakas "; +var description$1 = "An AST-based pattern checker for JavaScript."; +var bin = { + eslint: "./bin/eslint.js" +}; +var main = "./lib/api.js"; +var scripts = { + test: "node Makefile.js test", + "test:cli": "mocha", + lint: "node Makefile.js lint", + fix: "node Makefile.js lint -- fix", + fuzz: "node Makefile.js fuzz", + "generate-release": "node Makefile.js generateRelease", + "generate-alpharelease": "node Makefile.js generatePrerelease -- alpha", + "generate-betarelease": "node Makefile.js generatePrerelease -- beta", + "generate-rcrelease": "node Makefile.js generatePrerelease -- rc", + "publish-release": "node Makefile.js publishRelease", + docs: "node Makefile.js docs", + gensite: "node Makefile.js gensite", + webpack: "node Makefile.js webpack", + perf: "node Makefile.js perf" +}; +var gitHooks = { + "pre-commit": "lint-staged" +}; +var files = [ + "LICENSE", + "README.md", + "bin", + "conf", + "lib", + "messages" +]; +var repository = "eslint/eslint"; +var funding = "https://opencollective.com/eslint"; +var homepage = "https://eslint.org"; +var bugs = "https://github.com/eslint/eslint/issues/"; +var dependencies$1 = { + "@babel/code-frame": "7.12.11", + "@eslint/eslintrc": "^0.4.0", + ajv: "^6.10.0", + chalk: "^4.0.0", + "cross-spawn": "^7.0.2", + debug: "^4.0.1", + doctrine: "^3.0.0", + enquirer: "^2.3.5", + "eslint-scope": "^5.1.1", + "eslint-utils": "^2.1.0", + "eslint-visitor-keys": "^2.0.0", + espree: "^7.3.1", + esquery: "^1.4.0", + esutils: "^2.0.2", + "file-entry-cache": "^6.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + globals: "^13.6.0", + ignore: "^4.0.6", + "import-fresh": "^3.0.0", + imurmurhash: "^0.1.4", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + levn: "^0.4.1", + lodash: "^4.17.21", + minimatch: "^3.0.4", + "natural-compare": "^1.4.0", + optionator: "^0.9.1", + progress: "^2.0.0", + regexpp: "^3.1.0", + semver: "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", + table: "^6.0.4", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" +}; +var devDependencies = { + "@babel/core": "^7.4.3", + "@babel/preset-env": "^7.4.3", + acorn: "^7.2.0", + "babel-loader": "^8.0.5", + chai: "^4.0.1", + cheerio: "^0.22.0", + "common-tags": "^1.8.0", + "core-js": "^3.1.3", + dateformat: "^3.0.3", + ejs: "^3.0.2", + "escape-string-regexp": "^3.0.0", + eslint: "file:.", + "eslint-config-eslint": "file:packages/eslint-config-eslint", + "eslint-plugin-eslint-plugin": "^2.2.1", + "eslint-plugin-internal-rules": "file:tools/internal-rules", + "eslint-plugin-jsdoc": "^25.4.3", + "eslint-plugin-node": "^11.1.0", + "eslint-release": "^2.0.0", + eslump: "^2.0.0", + esprima: "^4.0.1", + "fs-teardown": "^0.1.0", + glob: "^7.1.6", + jsdoc: "^3.5.5", + karma: "^6.1.1", + "karma-chrome-launcher": "^3.1.0", + "karma-mocha": "^2.0.1", + "karma-mocha-reporter": "^2.2.5", + "karma-webpack": "^5.0.0", + "lint-staged": "^10.1.2", + "load-perf": "^0.2.0", + markdownlint: "^0.19.0", + "markdownlint-cli": "^0.22.0", + memfs: "^3.0.1", + mocha: "^8.3.2", + "mocha-junit-reporter": "^2.0.0", + "node-polyfill-webpack-plugin": "^1.0.3", + "npm-license": "^0.3.3", + nyc: "^15.0.1", + proxyquire: "^2.0.1", + puppeteer: "^7.1.0", + recast: "^0.19.0", + "regenerator-runtime": "^0.13.2", + shelljs: "^0.8.2", + sinon: "^9.0.1", + temp: "^0.9.0", + webpack: "^5.23.0", + "webpack-cli": "^4.5.0", + yorkie: "^2.0.0" +}; +var keywords$1 = [ + "ast", + "lint", + "javascript", + "ecmascript", + "espree" +]; +var license = "MIT"; +var engines = { + node: "^10.12.0 || >=12.0.0" +}; +var require$$3 = { + name: name, + version: version$1, + author: author, + description: description$1, + bin: bin, + main: main, + scripts: scripts, + gitHooks: gitHooks, + "lint-staged": { + "*.js": [ + "eslint --fix", + "git add" + ], + "*.md": "markdownlint" +}, + files: files, + repository: repository, + funding: funding, + homepage: homepage, + bugs: bugs, + dependencies: dependencies$1, + devDependencies: devDependencies, + keywords: keywords$1, + license: license, + engines: engines +}; + +/** + * Utility for resolving a module relative to another module + * @author Teddy Katz + */ + + + +/* + * `Module.createRequire` is added in v12.2.0. It supports URL as well. + * We only support the case where the argument is a filepath, not a URL. + */ +// eslint-disable-next-line node/no-unsupported-features/node-builtins, node/no-deprecated-api +const createRequire = Module__default['default'].createRequire || Module__default['default'].createRequireFromPath; + +var relativeModuleResolver = { + + /** + * Resolves a Node module relative to another module + * @param {string} moduleName The name of a Node module, or a path to a Node module. + * @param {string} relativeToPath An absolute path indicating the module that `moduleName` should be resolved relative to. This must be + * a file rather than a directory, but the file need not actually exist. + * @returns {string} The absolute path that would result from calling `require.resolve(moduleName)` in a file located at `relativeToPath` + */ + resolve(moduleName, relativeToPath) { + try { + return createRequire(relativeToPath).resolve(moduleName); + } catch (error) { + + // This `if` block is for older Node.js than 12.0.0. We can remove this block in the future. + if ( + typeof error === "object" && + error !== null && + error.code === "MODULE_NOT_FOUND" && + !error.requireStack && + error.message.includes(moduleName) + ) { + error.message += `\nRequire stack:\n- ${relativeToPath}`; + } + throw error; + } + } +}; + +/** + * @fileoverview `FileEnumerator` class. + * + * `FileEnumerator` class has two responsibilities: + * + * 1. Find target files by processing glob patterns. + * 2. Tie each target file and appropriate configuration. + * + * It provides a method: + * + * - `iterateFiles(patterns)` + * Iterate files which are matched by given patterns together with the + * corresponded configuration. This is for `CLIEngine#executeOnFiles()`. + * While iterating files, it loads the configuration file of each directory + * before iterate files on the directory, so we can use the configuration + * files to determine target files. + * + * @example + * const enumerator = new FileEnumerator(); + * const linter = new Linter(); + * + * for (const { config, filePath } of enumerator.iterateFiles(["*.js"])) { + * const code = fs.readFileSync(filePath, "utf8"); + * const messages = linter.verify(code, config, filePath); + * + * console.log(messages); + * } + * + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + + +const { escapeRegExp: escapeRegExp$1 } = lodash__default['default']; +const { Minimatch } = require$$1__default['default']; + +const { + Legacy: { + IgnorePattern: IgnorePattern$1, + CascadingConfigArrayFactory: CascadingConfigArrayFactory$1 + } +} = require$$2__default['default']; +const debug$8 = require$$0__default['default']("eslint:file-enumerator"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const minimatchOpts = { dot: true, matchBase: true }; +const dotfilesPattern = /(?:(?:^\.)|(?:[/\\]\.))[^/\\.].*/u; +const NONE = 0; +const IGNORED_SILENTLY = 1; +const IGNORED = 2; + +// For VSCode intellisense +/** @typedef {ReturnType} ConfigArray */ + +/** + * @typedef {Object} FileEnumeratorOptions + * @property {CascadingConfigArrayFactory} [configArrayFactory] The factory for config arrays. + * @property {string} [cwd] The base directory to start lookup. + * @property {string[]} [extensions] The extensions to match files for directory patterns. + * @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file. + * @property {boolean} [ignore] The flag to check ignored files. + * @property {string[]} [rulePaths] The value of `--rulesdir` option. + */ + +/** + * @typedef {Object} FileAndConfig + * @property {string} filePath The path to a target file. + * @property {ConfigArray} config The config entries of that file. + * @property {boolean} ignored If `true` then this file should be ignored and warned because it was directly specified. + */ + +/** + * @typedef {Object} FileEntry + * @property {string} filePath The path to a target file. + * @property {ConfigArray} config The config entries of that file. + * @property {NONE|IGNORED_SILENTLY|IGNORED} flag The flag. + * - `NONE` means the file is a target file. + * - `IGNORED_SILENTLY` means the file should be ignored silently. + * - `IGNORED` means the file should be ignored and warned because it was directly specified. + */ + +/** + * @typedef {Object} FileEnumeratorInternalSlots + * @property {CascadingConfigArrayFactory} configArrayFactory The factory for config arrays. + * @property {string} cwd The base directory to start lookup. + * @property {RegExp|null} extensionRegExp The RegExp to test if a string ends with specific file extensions. + * @property {boolean} globInputPaths Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file. + * @property {boolean} ignoreFlag The flag to check ignored files. + * @property {(filePath:string, dot:boolean) => boolean} defaultIgnores The default predicate function to ignore files. + */ + +/** @type {WeakMap} */ +const internalSlotsMap$2 = new WeakMap(); + +/** + * Check if a string is a glob pattern or not. + * @param {string} pattern A glob pattern. + * @returns {boolean} `true` if the string is a glob pattern. + */ +function isGlobPattern(pattern) { + return isGlob__default['default'](path__default['default'].sep === "\\" ? pattern.replace(/\\/gu, "/") : pattern); +} + +/** + * Get stats of a given path. + * @param {string} filePath The path to target file. + * @returns {fs.Stats|null} The stats. + * @private + */ +function statSafeSync(filePath) { + try { + return fs__default['default'].statSync(filePath); + } catch (error) { + /* istanbul ignore next */ + if (error.code !== "ENOENT") { + throw error; + } + return null; + } +} + +/** + * Get filenames in a given path to a directory. + * @param {string} directoryPath The path to target directory. + * @returns {import("fs").Dirent[]} The filenames. + * @private + */ +function readdirSafeSync(directoryPath) { + try { + return fs__default['default'].readdirSync(directoryPath, { withFileTypes: true }); + } catch (error) { + /* istanbul ignore next */ + if (error.code !== "ENOENT") { + throw error; + } + return []; + } +} + +/** + * Create a `RegExp` object to detect extensions. + * @param {string[] | null} extensions The extensions to create. + * @returns {RegExp | null} The created `RegExp` object or null. + */ +function createExtensionRegExp(extensions) { + if (extensions) { + const normalizedExts = extensions.map(ext => escapeRegExp$1( + ext.startsWith(".") + ? ext.slice(1) + : ext + )); + + return new RegExp( + `.\\.(?:${normalizedExts.join("|")})$`, + "u" + ); + } + return null; +} + +/** + * The error type when no files match a glob. + */ +class NoFilesFoundError extends Error { + + // eslint-disable-next-line jsdoc/require-description + /** + * @param {string} pattern The glob pattern which was not found. + * @param {boolean} globDisabled If `true` then the pattern was a glob pattern, but glob was disabled. + */ + constructor(pattern, globDisabled) { + super(`No files matching '${pattern}' were found${globDisabled ? " (glob was disabled)" : ""}.`); + this.messageTemplate = "file-not-found"; + this.messageData = { pattern, globDisabled }; + } +} + +/** + * The error type when there are files matched by a glob, but all of them have been ignored. + */ +class AllFilesIgnoredError extends Error { + + // eslint-disable-next-line jsdoc/require-description + /** + * @param {string} pattern The glob pattern which was not found. + */ + constructor(pattern) { + super(`All files matched by '${pattern}' are ignored.`); + this.messageTemplate = "all-files-ignored"; + this.messageData = { pattern }; + } +} + +/** + * This class provides the functionality that enumerates every file which is + * matched by given glob patterns and that configuration. + */ +class FileEnumerator$1 { + + /** + * Initialize this enumerator. + * @param {FileEnumeratorOptions} options The options. + */ + constructor({ + cwd = process.cwd(), + configArrayFactory = new CascadingConfigArrayFactory$1({ + cwd, + eslintRecommendedPath: path__default['default'].resolve(__dirname, "../../conf/eslint-recommended.js"), + eslintAllPath: path__default['default'].resolve(__dirname, "../../conf/eslint-all.js") + }), + extensions = null, + globInputPaths = true, + errorOnUnmatchedPattern = true, + ignore = true + } = {}) { + internalSlotsMap$2.set(this, { + configArrayFactory, + cwd, + defaultIgnores: IgnorePattern$1.createDefaultIgnore(cwd), + extensionRegExp: createExtensionRegExp(extensions), + globInputPaths, + errorOnUnmatchedPattern, + ignoreFlag: ignore + }); + } + + /** + * Check if a given file is target or not. + * @param {string} filePath The path to a candidate file. + * @param {ConfigArray} [providedConfig] Optional. The configuration for the file. + * @returns {boolean} `true` if the file is a target. + */ + isTargetPath(filePath, providedConfig) { + const { + configArrayFactory, + extensionRegExp + } = internalSlotsMap$2.get(this); + + // If `--ext` option is present, use it. + if (extensionRegExp) { + return extensionRegExp.test(filePath); + } + + // `.js` file is target by default. + if (filePath.endsWith(".js")) { + return true; + } + + // use `overrides[].files` to check additional targets. + const config = + providedConfig || + configArrayFactory.getConfigArrayForFile( + filePath, + { ignoreNotFoundError: true } + ); + + return config.isAdditionalTargetPath(filePath); + } + + /** + * Iterate files which are matched by given glob patterns. + * @param {string|string[]} patternOrPatterns The glob patterns to iterate files. + * @returns {IterableIterator} The found files. + */ + *iterateFiles(patternOrPatterns) { + const { globInputPaths, errorOnUnmatchedPattern } = internalSlotsMap$2.get(this); + const patterns = Array.isArray(patternOrPatterns) + ? patternOrPatterns + : [patternOrPatterns]; + + debug$8("Start to iterate files: %o", patterns); + + // The set of paths to remove duplicate. + const set = new Set(); + + for (const pattern of patterns) { + let foundRegardlessOfIgnored = false; + let found = false; + + // Skip empty string. + if (!pattern) { + continue; + } + + // Iterate files of this pattern. + for (const { config, filePath, flag } of this._iterateFiles(pattern)) { + foundRegardlessOfIgnored = true; + if (flag === IGNORED_SILENTLY) { + continue; + } + found = true; + + // Remove duplicate paths while yielding paths. + if (!set.has(filePath)) { + set.add(filePath); + yield { + config, + filePath, + ignored: flag === IGNORED + }; + } + } + + // Raise an error if any files were not found. + if (errorOnUnmatchedPattern) { + if (!foundRegardlessOfIgnored) { + throw new NoFilesFoundError( + pattern, + !globInputPaths && isGlob__default['default'](pattern) + ); + } + if (!found) { + throw new AllFilesIgnoredError(pattern); + } + } + } + + debug$8(`Complete iterating files: ${JSON.stringify(patterns)}`); + } + + /** + * Iterate files which are matched by a given glob pattern. + * @param {string} pattern The glob pattern to iterate files. + * @returns {IterableIterator} The found files. + */ + _iterateFiles(pattern) { + const { cwd, globInputPaths } = internalSlotsMap$2.get(this); + const absolutePath = path__default['default'].resolve(cwd, pattern); + const isDot = dotfilesPattern.test(pattern); + const stat = statSafeSync(absolutePath); + + if (stat && stat.isDirectory()) { + return this._iterateFilesWithDirectory(absolutePath, isDot); + } + if (stat && stat.isFile()) { + return this._iterateFilesWithFile(absolutePath); + } + if (globInputPaths && isGlobPattern(pattern)) { + return this._iterateFilesWithGlob(absolutePath, isDot); + } + + return []; + } + + /** + * Iterate a file which is matched by a given path. + * @param {string} filePath The path to the target file. + * @returns {IterableIterator} The found files. + * @private + */ + _iterateFilesWithFile(filePath) { + debug$8(`File: ${filePath}`); + + const { configArrayFactory } = internalSlotsMap$2.get(this); + const config = configArrayFactory.getConfigArrayForFile(filePath); + const ignored = this._isIgnoredFile(filePath, { config, direct: true }); + const flag = ignored ? IGNORED : NONE; + + return [{ config, filePath, flag }]; + } + + /** + * Iterate files in a given path. + * @param {string} directoryPath The path to the target directory. + * @param {boolean} dotfiles If `true` then it doesn't skip dot files by default. + * @returns {IterableIterator} The found files. + * @private + */ + _iterateFilesWithDirectory(directoryPath, dotfiles) { + debug$8(`Directory: ${directoryPath}`); + + return this._iterateFilesRecursive( + directoryPath, + { dotfiles, recursive: true, selector: null } + ); + } + + /** + * Iterate files which are matched by a given glob pattern. + * @param {string} pattern The glob pattern to iterate files. + * @param {boolean} dotfiles If `true` then it doesn't skip dot files by default. + * @returns {IterableIterator} The found files. + * @private + */ + _iterateFilesWithGlob(pattern, dotfiles) { + debug$8(`Glob: ${pattern}`); + + const directoryPath = path__default['default'].resolve(getGlobParent__default['default'](pattern)); + const globPart = pattern.slice(directoryPath.length + 1); + + /* + * recursive if there are `**` or path separators in the glob part. + * Otherwise, patterns such as `src/*.js`, it doesn't need recursive. + */ + const recursive = /\*\*|\/|\\/u.test(globPart); + const selector = new Minimatch(pattern, minimatchOpts); + + debug$8(`recursive? ${recursive}`); + + return this._iterateFilesRecursive( + directoryPath, + { dotfiles, recursive, selector } + ); + } + + /** + * Iterate files in a given path. + * @param {string} directoryPath The path to the target directory. + * @param {Object} options The options to iterate files. + * @param {boolean} [options.dotfiles] If `true` then it doesn't skip dot files by default. + * @param {boolean} [options.recursive] If `true` then it dives into sub directories. + * @param {InstanceType} [options.selector] The matcher to choose files. + * @returns {IterableIterator} The found files. + * @private + */ + *_iterateFilesRecursive(directoryPath, options) { + debug$8(`Enter the directory: ${directoryPath}`); + const { configArrayFactory } = internalSlotsMap$2.get(this); + + /** @type {ConfigArray|null} */ + let config = null; + + // Enumerate the files of this directory. + for (const entry of readdirSafeSync(directoryPath)) { + const filePath = path__default['default'].join(directoryPath, entry.name); + const fileInfo = entry.isSymbolicLink() ? statSafeSync(filePath) : entry; + + if (!fileInfo) { + continue; + } + + // Check if the file is matched. + if (fileInfo.isFile()) { + if (!config) { + config = configArrayFactory.getConfigArrayForFile( + filePath, + + /* + * We must ignore `ConfigurationNotFoundError` at this + * point because we don't know if target files exist in + * this directory. + */ + { ignoreNotFoundError: true } + ); + } + const matched = options.selector + + // Started with a glob pattern; choose by the pattern. + ? options.selector.match(filePath) + + // Started with a directory path; choose by file extensions. + : this.isTargetPath(filePath, config); + + if (matched) { + const ignored = this._isIgnoredFile(filePath, { ...options, config }); + const flag = ignored ? IGNORED_SILENTLY : NONE; + + debug$8(`Yield: ${entry.name}${ignored ? " but ignored" : ""}`); + yield { + config: configArrayFactory.getConfigArrayForFile(filePath), + filePath, + flag + }; + } else { + debug$8(`Didn't match: ${entry.name}`); + } + + // Dive into the sub directory. + } else if (options.recursive && fileInfo.isDirectory()) { + if (!config) { + config = configArrayFactory.getConfigArrayForFile( + filePath, + { ignoreNotFoundError: true } + ); + } + const ignored = this._isIgnoredFile( + filePath + path__default['default'].sep, + { ...options, config } + ); + + if (!ignored) { + yield* this._iterateFilesRecursive(filePath, options); + } + } + } + + debug$8(`Leave the directory: ${directoryPath}`); + } + + /** + * Check if a given file should be ignored. + * @param {string} filePath The path to a file to check. + * @param {Object} options Options + * @param {ConfigArray} [options.config] The config for this file. + * @param {boolean} [options.dotfiles] If `true` then this is not ignore dot files by default. + * @param {boolean} [options.direct] If `true` then this is a direct specified file. + * @returns {boolean} `true` if the file should be ignored. + * @private + */ + _isIgnoredFile(filePath, { + config: providedConfig, + dotfiles = false, + direct = false + }) { + const { + configArrayFactory, + defaultIgnores, + ignoreFlag + } = internalSlotsMap$2.get(this); + + if (ignoreFlag) { + const config = + providedConfig || + configArrayFactory.getConfigArrayForFile( + filePath, + { ignoreNotFoundError: true } + ); + const ignores = + config.extractConfig(filePath).ignores || defaultIgnores; + + return ignores(filePath, dotfiles); + } + + return !direct && defaultIgnores(filePath, dotfiles); + } +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +var fileEnumerator = { FileEnumerator: FileEnumerator$1 }; + +/** + * @fileoverview Defines environment settings and globals. + * @author Elan Shanker + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Get the object that has difference. + * @param {Record} current The newer object. + * @param {Record} prev The older object. + * @returns {Record} The difference object. + */ +function getDiff(current, prev) { + const retv = {}; + + for (const [key, value] of Object.entries(current)) { + if (!Object.hasOwnProperty.call(prev, key)) { + retv[key] = value; + } + } + + return retv; +} + +const newGlobals2015 = getDiff(globals__default['default'].es2015, globals__default['default'].es5); // 19 variables such as Promise, Map, ... +const newGlobals2017 = { + Atomics: false, + SharedArrayBuffer: false +}; +const newGlobals2020 = { + BigInt: false, + BigInt64Array: false, + BigUint64Array: false, + globalThis: false +}; + +const newGlobals2021 = { + AggregateError: false, + FinalizationRegistry: false, + WeakRef: false +}; + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** @type {Map} */ +var environments = new Map(Object.entries({ + + // Language + builtin: { + globals: globals__default['default'].es5 + }, + es6: { + globals: newGlobals2015, + parserOptions: { + ecmaVersion: 6 + } + }, + es2015: { + globals: newGlobals2015, + parserOptions: { + ecmaVersion: 6 + } + }, + es2017: { + globals: { ...newGlobals2015, ...newGlobals2017 }, + parserOptions: { + ecmaVersion: 8 + } + }, + es2020: { + globals: { ...newGlobals2015, ...newGlobals2017, ...newGlobals2020 }, + parserOptions: { + ecmaVersion: 11 + } + }, + es2021: { + globals: { ...newGlobals2015, ...newGlobals2017, ...newGlobals2020, ...newGlobals2021 }, + parserOptions: { + ecmaVersion: 12 + } + }, + + // Platforms + browser: { + globals: globals__default['default'].browser + }, + node: { + globals: globals__default['default'].node, + parserOptions: { + ecmaFeatures: { + globalReturn: true + } + } + }, + "shared-node-browser": { + globals: globals__default['default']["shared-node-browser"] + }, + worker: { + globals: globals__default['default'].worker + }, + serviceworker: { + globals: globals__default['default'].serviceworker + }, + + // Frameworks + commonjs: { + globals: globals__default['default'].commonjs, + parserOptions: { + ecmaFeatures: { + globalReturn: true + } + } + }, + amd: { + globals: globals__default['default'].amd + }, + mocha: { + globals: globals__default['default'].mocha + }, + jasmine: { + globals: globals__default['default'].jasmine + }, + jest: { + globals: globals__default['default'].jest + }, + phantomjs: { + globals: globals__default['default'].phantomjs + }, + jquery: { + globals: globals__default['default'].jquery + }, + qunit: { + globals: globals__default['default'].qunit + }, + prototypejs: { + globals: globals__default['default'].prototypejs + }, + shelljs: { + globals: globals__default['default'].shelljs + }, + meteor: { + globals: globals__default['default'].meteor + }, + mongo: { + globals: globals__default['default'].mongo + }, + protractor: { + globals: globals__default['default'].protractor + }, + applescript: { + globals: globals__default['default'].applescript + }, + nashorn: { + globals: globals__default['default'].nashorn + }, + atomtest: { + globals: globals__default['default'].atomtest + }, + embertest: { + globals: globals__default['default'].embertest + }, + webextensions: { + globals: globals__default['default'].webextensions + }, + greasemonkey: { + globals: globals__default['default'].greasemonkey + } +})); + +/** + * @fileoverview Common utils for AST. + * + * This file contains only shared items for core and rules. + * If you make a utility for rules, please see `../rules/utils/ast-utils.js`. + * + * @author Toru Nagashima + */ + +const breakableTypePattern$1 = /^(?:(?:Do)?While|For(?:In|Of)?|Switch)Statement$/u; +const lineBreakPattern = /\r\n|[\r\n\u2028\u2029]/u; +const shebangPattern = /^#!([^\r\n]+)/u; + +/** + * Creates a version of the `lineBreakPattern` regex with the global flag. + * Global regexes are mutable, so this needs to be a function instead of a constant. + * @returns {RegExp} A global regular expression that matches line terminators + */ +function createGlobalLinebreakMatcher() { + return new RegExp(lineBreakPattern.source, "gu"); +} + +var astUtils$1 = { + breakableTypePattern: breakableTypePattern$1, + lineBreakPattern, + createGlobalLinebreakMatcher, + shebangPattern +}; + +/** + * @fileoverview Config file operations. This file must be usable in the browser, + * so no Node-specific code can be here. + * @author Nicholas C. Zakas + */ + +var configOps = createCommonjsModule(function (module) { + +//------------------------------------------------------------------------------ +// Private +//------------------------------------------------------------------------------ + +const RULE_SEVERITY_STRINGS = ["off", "warn", "error"], + RULE_SEVERITY = RULE_SEVERITY_STRINGS.reduce((map, value, index) => { + map[value] = index; + return map; + }, {}), + VALID_SEVERITIES = [0, 1, 2, "off", "warn", "error"]; + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = { + + /** + * Normalizes the severity value of a rule's configuration to a number + * @param {(number|string|[number, ...*]|[string, ...*])} ruleConfig A rule's configuration value, generally + * received from the user. A valid config value is either 0, 1, 2, the string "off" (treated the same as 0), + * the string "warn" (treated the same as 1), the string "error" (treated the same as 2), or an array + * whose first element is one of the above values. Strings are matched case-insensitively. + * @returns {(0|1|2)} The numeric severity value if the config value was valid, otherwise 0. + */ + getRuleSeverity(ruleConfig) { + const severityValue = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig; + + if (severityValue === 0 || severityValue === 1 || severityValue === 2) { + return severityValue; + } + + if (typeof severityValue === "string") { + return RULE_SEVERITY[severityValue.toLowerCase()] || 0; + } + + return 0; + }, + + /** + * Converts old-style severity settings (0, 1, 2) into new-style + * severity settings (off, warn, error) for all rules. Assumption is that severity + * values have already been validated as correct. + * @param {Object} config The config object to normalize. + * @returns {void} + */ + normalizeToStrings(config) { + + if (config.rules) { + Object.keys(config.rules).forEach(ruleId => { + const ruleConfig = config.rules[ruleId]; + + if (typeof ruleConfig === "number") { + config.rules[ruleId] = RULE_SEVERITY_STRINGS[ruleConfig] || RULE_SEVERITY_STRINGS[0]; + } else if (Array.isArray(ruleConfig) && typeof ruleConfig[0] === "number") { + ruleConfig[0] = RULE_SEVERITY_STRINGS[ruleConfig[0]] || RULE_SEVERITY_STRINGS[0]; + } + }); + } + }, + + /** + * Determines if the severity for the given rule configuration represents an error. + * @param {int|string|Array} ruleConfig The configuration for an individual rule. + * @returns {boolean} True if the rule represents an error, false if not. + */ + isErrorSeverity(ruleConfig) { + return module.exports.getRuleSeverity(ruleConfig) === 2; + }, + + /** + * Checks whether a given config has valid severity or not. + * @param {number|string|Array} ruleConfig The configuration for an individual rule. + * @returns {boolean} `true` if the configuration has valid severity. + */ + isValidSeverity(ruleConfig) { + let severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig; + + if (typeof severity === "string") { + severity = severity.toLowerCase(); + } + return VALID_SEVERITIES.indexOf(severity) !== -1; + }, + + /** + * Checks whether every rule of a given config has valid severity or not. + * @param {Object} config The configuration for rules. + * @returns {boolean} `true` if the configuration has valid severity. + */ + isEverySeverityValid(config) { + return Object.keys(config).every(ruleId => this.isValidSeverity(config[ruleId])); + }, + + /** + * Normalizes a value for a global in a config + * @param {(boolean|string|null)} configuredValue The value given for a global in configuration or in + * a global directive comment + * @returns {("readable"|"writeable"|"off")} The value normalized as a string + * @throws Error if global value is invalid + */ + normalizeConfigGlobal(configuredValue) { + switch (configuredValue) { + case "off": + return "off"; + + case true: + case "true": + case "writeable": + case "writable": + return "writable"; + + case null: + case false: + case "false": + case "readable": + case "readonly": + return "readonly"; + + default: + throw new Error(`'${configuredValue}' is not a valid configuration for a global (use 'readonly', 'writable', or 'off')`); + } + } +}; +}); + +/** + * @fileoverview Defines a schema for configs. + * @author Sylvan Mably + */ + +const baseConfigProperties$1 = { + $schema: { type: "string" }, + env: { type: "object" }, + extends: { $ref: "#/definitions/stringOrStrings" }, + globals: { type: "object" }, + overrides: { + type: "array", + items: { $ref: "#/definitions/overrideConfig" }, + additionalItems: false + }, + parser: { type: ["string", "null"] }, + parserOptions: { type: "object" }, + plugins: { type: "array" }, + processor: { type: "string" }, + rules: { type: "object" }, + settings: { type: "object" }, + noInlineConfig: { type: "boolean" }, + reportUnusedDisableDirectives: { type: "boolean" }, + + ecmaFeatures: { type: "object" } // deprecated; logs a warning when used +}; + +const configSchema$1 = { + definitions: { + stringOrStrings: { + oneOf: [ + { type: "string" }, + { + type: "array", + items: { type: "string" }, + additionalItems: false + } + ] + }, + stringOrStringsRequired: { + oneOf: [ + { type: "string" }, + { + type: "array", + items: { type: "string" }, + additionalItems: false, + minItems: 1 + } + ] + }, + + // Config at top-level. + objectConfig: { + type: "object", + properties: { + root: { type: "boolean" }, + ignorePatterns: { $ref: "#/definitions/stringOrStrings" }, + ...baseConfigProperties$1 + }, + additionalProperties: false + }, + + // Config in `overrides`. + overrideConfig: { + type: "object", + properties: { + excludedFiles: { $ref: "#/definitions/stringOrStrings" }, + files: { $ref: "#/definitions/stringOrStringsRequired" }, + ...baseConfigProperties$1 + }, + required: ["files"], + additionalProperties: false + } + }, + + $ref: "#/definitions/objectConfig" +}; + +var configSchema_1$1 = configSchema$1; + +/** + * @fileoverview Provide the function that emits deprecation warnings. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Private +//------------------------------------------------------------------------------ + +// Defitions for deprecation warnings. +const deprecationWarningMessages$1 = { + ESLINT_LEGACY_ECMAFEATURES: + "The 'ecmaFeatures' config file property is deprecated and has no effect.", + ESLINT_PERSONAL_CONFIG_LOAD: + "'~/.eslintrc.*' config files have been deprecated. " + + "Please use a config file per project or the '--config' option.", + ESLINT_PERSONAL_CONFIG_SUPPRESS: + "'~/.eslintrc.*' config files have been deprecated. " + + "Please remove it or add 'root:true' to the config files in your " + + "projects in order to avoid loading '~/.eslintrc.*' accidentally." +}; + +const sourceFileErrorCache = new Set(); + +/** + * Emits a deprecation warning containing a given filepath. A new deprecation warning is emitted + * for each unique file path, but repeated invocations with the same file path have no effect. + * No warnings are emitted if the `--no-deprecation` or `--no-warnings` Node runtime flags are active. + * @param {string} source The name of the configuration source to report the warning for. + * @param {string} errorCode The warning message to show. + * @returns {void} + */ +function emitDeprecationWarning$3(source, errorCode) { + const cacheKey = JSON.stringify({ source, errorCode }); + + if (sourceFileErrorCache.has(cacheKey)) { + return; + } + sourceFileErrorCache.add(cacheKey); + + const rel = path__default['default'].relative(process.cwd(), source); + const message = deprecationWarningMessages$1[errorCode]; + + process.emitWarning( + `${message} (found in "${rel}")`, + "DeprecationWarning", + errorCode + ); +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +var deprecationWarnings$1 = { + emitDeprecationWarning: emitDeprecationWarning$3 +}; + +var id = "http://json-schema.org/draft-04/schema#"; +var $schema = "http://json-schema.org/draft-04/schema#"; +var description = "Core schema meta-schema"; +var definitions = { + schemaArray: { + type: "array", + minItems: 1, + items: { + $ref: "#" + } + }, + positiveInteger: { + type: "integer", + minimum: 0 + }, + positiveIntegerDefault0: { + allOf: [ + { + $ref: "#/definitions/positiveInteger" + }, + { + "default": 0 + } + ] + }, + simpleTypes: { + "enum": [ + "array", + "boolean", + "integer", + "null", + "number", + "object", + "string" + ] + }, + stringArray: { + type: "array", + items: { + type: "string" + }, + minItems: 1, + uniqueItems: true + } +}; +var type = "object"; +var properties = { + id: { + type: "string" + }, + $schema: { + type: "string" + }, + title: { + type: "string" + }, + description: { + type: "string" + }, + "default": { + }, + multipleOf: { + type: "number", + minimum: 0, + exclusiveMinimum: true + }, + maximum: { + type: "number" + }, + exclusiveMaximum: { + type: "boolean", + "default": false + }, + minimum: { + type: "number" + }, + exclusiveMinimum: { + type: "boolean", + "default": false + }, + maxLength: { + $ref: "#/definitions/positiveInteger" + }, + minLength: { + $ref: "#/definitions/positiveIntegerDefault0" + }, + pattern: { + type: "string", + format: "regex" + }, + additionalItems: { + anyOf: [ + { + type: "boolean" + }, + { + $ref: "#" + } + ], + "default": { + } + }, + items: { + anyOf: [ + { + $ref: "#" + }, + { + $ref: "#/definitions/schemaArray" + } + ], + "default": { + } + }, + maxItems: { + $ref: "#/definitions/positiveInteger" + }, + minItems: { + $ref: "#/definitions/positiveIntegerDefault0" + }, + uniqueItems: { + type: "boolean", + "default": false + }, + maxProperties: { + $ref: "#/definitions/positiveInteger" + }, + minProperties: { + $ref: "#/definitions/positiveIntegerDefault0" + }, + required: { + $ref: "#/definitions/stringArray" + }, + additionalProperties: { + anyOf: [ + { + type: "boolean" + }, + { + $ref: "#" + } + ], + "default": { + } + }, + definitions: { + type: "object", + additionalProperties: { + $ref: "#" + }, + "default": { + } + }, + properties: { + type: "object", + additionalProperties: { + $ref: "#" + }, + "default": { + } + }, + patternProperties: { + type: "object", + additionalProperties: { + $ref: "#" + }, + "default": { + } + }, + dependencies: { + type: "object", + additionalProperties: { + anyOf: [ + { + $ref: "#" + }, + { + $ref: "#/definitions/stringArray" + } + ] + } + }, + "enum": { + type: "array", + minItems: 1, + uniqueItems: true + }, + type: { + anyOf: [ + { + $ref: "#/definitions/simpleTypes" + }, + { + type: "array", + items: { + $ref: "#/definitions/simpleTypes" + }, + minItems: 1, + uniqueItems: true + } + ] + }, + format: { + type: "string" + }, + allOf: { + $ref: "#/definitions/schemaArray" + }, + anyOf: { + $ref: "#/definitions/schemaArray" + }, + oneOf: { + $ref: "#/definitions/schemaArray" + }, + not: { + $ref: "#" + } +}; +var dependencies = { + exclusiveMaximum: [ + "maximum" + ], + exclusiveMinimum: [ + "minimum" + ] +}; +var metaSchema = { + id: id, + $schema: $schema, + description: description, + definitions: definitions, + type: type, + properties: properties, + dependencies: dependencies, + "default": { +} +}; + +/** + * @fileoverview The instance of Ajv validator. + * @author Evgeny Poberezkin + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +var ajv$4 = (additionalOptions = {}) => { + const ajv = new Ajv__default['default']({ + meta: false, + useDefaults: true, + validateSchema: false, + missingRefs: "ignore", + verbose: true, + schemaId: "auto", + ...additionalOptions + }); + + ajv.addMetaSchema(metaSchema); + // eslint-disable-next-line no-underscore-dangle + ajv._opts.defaultMeta = metaSchema.id; + + return ajv; +}; + +/** + * @fileoverview Validates configs. + * @author Brandon Mills + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const + { emitDeprecationWarning: emitDeprecationWarning$2 } = deprecationWarnings$1; + +const ajv$3 = ajv$4(); +const ruleValidators$1 = new WeakMap(); +const noop$2 = Function.prototype; + +//------------------------------------------------------------------------------ +// Private +//------------------------------------------------------------------------------ +let validateSchema$1; +const severityMap$1 = { + error: 2, + warn: 1, + off: 0 +}; + +const validated$1 = new WeakSet(); + +//----------------------------------------------------------------------------- +// Exports +//----------------------------------------------------------------------------- + +var configValidator$1 = class ConfigValidator { + constructor({ builtInRules = new Map() } = {}) { + this.builtInRules = builtInRules; + } + + /** + * Gets a complete options schema for a rule. + * @param {{create: Function, schema: (Array|null)}} rule A new-style rule object + * @returns {Object} JSON Schema for the rule's options. + */ + getRuleOptionsSchema(rule) { + if (!rule) { + return null; + } + + const schema = rule.schema || rule.meta && rule.meta.schema; + + // Given a tuple of schemas, insert warning level at the beginning + if (Array.isArray(schema)) { + if (schema.length) { + return { + type: "array", + items: schema, + minItems: 0, + maxItems: schema.length + }; + } + return { + type: "array", + minItems: 0, + maxItems: 0 + }; + + } + + // Given a full schema, leave it alone + return schema || null; + } + + /** + * Validates a rule's severity and returns the severity value. Throws an error if the severity is invalid. + * @param {options} options The given options for the rule. + * @returns {number|string} The rule's severity value + */ + validateRuleSeverity(options) { + const severity = Array.isArray(options) ? options[0] : options; + const normSeverity = typeof severity === "string" ? severityMap$1[severity.toLowerCase()] : severity; + + if (normSeverity === 0 || normSeverity === 1 || normSeverity === 2) { + return normSeverity; + } + + throw new Error(`\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '${util__default['default'].inspect(severity).replace(/'/gu, "\"").replace(/\n/gu, "")}').\n`); + + } + + /** + * Validates the non-severity options passed to a rule, based on its schema. + * @param {{create: Function}} rule The rule to validate + * @param {Array} localOptions The options for the rule, excluding severity + * @returns {void} + */ + validateRuleSchema(rule, localOptions) { + if (!ruleValidators$1.has(rule)) { + const schema = this.getRuleOptionsSchema(rule); + + if (schema) { + ruleValidators$1.set(rule, ajv$3.compile(schema)); + } + } + + const validateRule = ruleValidators$1.get(rule); + + if (validateRule) { + validateRule(localOptions); + if (validateRule.errors) { + throw new Error(validateRule.errors.map( + error => `\tValue ${JSON.stringify(error.data)} ${error.message}.\n` + ).join("")); + } + } + } + + /** + * Validates a rule's options against its schema. + * @param {{create: Function}|null} rule The rule that the config is being validated for + * @param {string} ruleId The rule's unique name. + * @param {Array|number} options The given options for the rule. + * @param {string|null} source The name of the configuration source to report in any errors. If null or undefined, + * no source is prepended to the message. + * @returns {void} + */ + validateRuleOptions(rule, ruleId, options, source = null) { + try { + const severity = this.validateRuleSeverity(options); + + if (severity !== 0) { + this.validateRuleSchema(rule, Array.isArray(options) ? options.slice(1) : []); + } + } catch (err) { + const enhancedMessage = `Configuration for rule "${ruleId}" is invalid:\n${err.message}`; + + if (typeof source === "string") { + throw new Error(`${source}:\n\t${enhancedMessage}`); + } else { + throw new Error(enhancedMessage); + } + } + } + + /** + * Validates an environment object + * @param {Object} environment The environment config object to validate. + * @param {string} source The name of the configuration source to report in any errors. + * @param {function(envId:string): Object} [getAdditionalEnv] A map from strings to loaded environments. + * @returns {void} + */ + validateEnvironment( + environment, + source, + getAdditionalEnv = noop$2 + ) { + + // not having an environment is ok + if (!environment) { + return; + } + + Object.keys(environment).forEach(id => { + const env = getAdditionalEnv(id) || environments.get(id) || null; + + if (!env) { + const message = `${source}:\n\tEnvironment key "${id}" is unknown\n`; + + throw new Error(message); + } + }); + } + + /** + * Validates a rules config object + * @param {Object} rulesConfig The rules config object to validate. + * @param {string} source The name of the configuration source to report in any errors. + * @param {function(ruleId:string): Object} getAdditionalRule A map from strings to loaded rules + * @returns {void} + */ + validateRules( + rulesConfig, + source, + getAdditionalRule = noop$2 + ) { + if (!rulesConfig) { + return; + } + + Object.keys(rulesConfig).forEach(id => { + const rule = getAdditionalRule(id) || this.builtInRules.get(id) || null; + + this.validateRuleOptions(rule, id, rulesConfig[id], source); + }); + } + + /** + * Validates a `globals` section of a config file + * @param {Object} globalsConfig The `globals` section + * @param {string|null} source The name of the configuration source to report in the event of an error. + * @returns {void} + */ + validateGlobals(globalsConfig, source = null) { + if (!globalsConfig) { + return; + } + + Object.entries(globalsConfig) + .forEach(([configuredGlobal, configuredValue]) => { + try { + configOps.normalizeConfigGlobal(configuredValue); + } catch (err) { + throw new Error(`ESLint configuration of global '${configuredGlobal}' in ${source} is invalid:\n${err.message}`); + } + }); + } + + /** + * Validate `processor` configuration. + * @param {string|undefined} processorName The processor name. + * @param {string} source The name of config file. + * @param {function(id:string): Processor} getProcessor The getter of defined processors. + * @returns {void} + */ + validateProcessor(processorName, source, getProcessor) { + if (processorName && !getProcessor(processorName)) { + throw new Error(`ESLint configuration of processor in '${source}' is invalid: '${processorName}' was not found.`); + } + } + + /** + * Formats an array of schema validation errors. + * @param {Array} errors An array of error messages to format. + * @returns {string} Formatted error message + */ + formatErrors(errors) { + return errors.map(error => { + if (error.keyword === "additionalProperties") { + const formattedPropertyPath = error.dataPath.length ? `${error.dataPath.slice(1)}.${error.params.additionalProperty}` : error.params.additionalProperty; + + return `Unexpected top-level property "${formattedPropertyPath}"`; + } + if (error.keyword === "type") { + const formattedField = error.dataPath.slice(1); + const formattedExpectedType = Array.isArray(error.schema) ? error.schema.join("/") : error.schema; + const formattedValue = JSON.stringify(error.data); + + return `Property "${formattedField}" is the wrong type (expected ${formattedExpectedType} but got \`${formattedValue}\`)`; + } + + const field = error.dataPath[0] === "." ? error.dataPath.slice(1) : error.dataPath; + + return `"${field}" ${error.message}. Value: ${JSON.stringify(error.data)}`; + }).map(message => `\t- ${message}.\n`).join(""); + } + + /** + * Validates the top level properties of the config object. + * @param {Object} config The config object to validate. + * @param {string} source The name of the configuration source to report in any errors. + * @returns {void} + */ + validateConfigSchema(config, source = null) { + validateSchema$1 = validateSchema$1 || ajv$3.compile(configSchema_1$1); + + if (!validateSchema$1(config)) { + throw new Error(`ESLint configuration in ${source} is invalid:\n${this.formatErrors(validateSchema$1.errors)}`); + } + + if (Object.hasOwnProperty.call(config, "ecmaFeatures")) { + emitDeprecationWarning$2(source, "ESLINT_LEGACY_ECMAFEATURES"); + } + } + + /** + * Validates an entire config object. + * @param {Object} config The config object to validate. + * @param {string} source The name of the configuration source to report in any errors. + * @param {function(ruleId:string): Object} [getAdditionalRule] A map from strings to loaded rules. + * @param {function(envId:string): Object} [getAdditionalEnv] A map from strings to loaded envs. + * @returns {void} + */ + validate(config, source, getAdditionalRule, getAdditionalEnv) { + this.validateConfigSchema(config, source); + this.validateRules(config.rules, source, getAdditionalRule); + this.validateEnvironment(config.env, source, getAdditionalEnv); + this.validateGlobals(config.globals, source); + + for (const override of config.overrides || []) { + this.validateRules(override.rules, source, getAdditionalRule); + this.validateEnvironment(override.env, source, getAdditionalEnv); + this.validateGlobals(config.globals, source); + } + } + + /** + * Validate config array object. + * @param {ConfigArray} configArray The config array to validate. + * @returns {void} + */ + validateConfigArray(configArray) { + const getPluginEnv = Map.prototype.get.bind(configArray.pluginEnvironments); + const getPluginProcessor = Map.prototype.get.bind(configArray.pluginProcessors); + const getPluginRule = Map.prototype.get.bind(configArray.pluginRules); + + // Validate. + for (const element of configArray) { + if (validated$1.has(element)) { + continue; + } + validated$1.add(element); + + this.validateEnvironment(element.env, element.name, getPluginEnv); + this.validateGlobals(element.globals, element.name); + this.validateProcessor(element.processor, element.name, getPluginProcessor); + this.validateRules(element.rules, element.name, getPluginRule); + } + } + +}; + +/** + * @fileoverview Traverser to traverse AST trees. + * @author Nicholas C. Zakas + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + +const debug$7 = require$$0__default['default']("eslint:traverser"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Do nothing. + * @returns {void} + */ +function noop$1() { + + // do nothing. +} + +/** + * Check whether the given value is an ASTNode or not. + * @param {any} x The value to check. + * @returns {boolean} `true` if the value is an ASTNode. + */ +function isNode(x) { + return x !== null && typeof x === "object" && typeof x.type === "string"; +} + +/** + * Get the visitor keys of a given node. + * @param {Object} visitorKeys The map of visitor keys. + * @param {ASTNode} node The node to get their visitor keys. + * @returns {string[]} The visitor keys of the node. + */ +function getVisitorKeys(visitorKeys, node) { + let keys = visitorKeys[node.type]; + + if (!keys) { + keys = vk__default['default'].getKeys(node); + debug$7("Unknown node type \"%s\": Estimated visitor keys %j", node.type, keys); + } + + return keys; +} + +/** + * The traverser class to traverse AST trees. + */ +class Traverser { + constructor() { + this._current = null; + this._parents = []; + this._skipped = false; + this._broken = false; + this._visitorKeys = null; + this._enter = null; + this._leave = null; + } + + // eslint-disable-next-line jsdoc/require-description + /** + * @returns {ASTNode} The current node. + */ + current() { + return this._current; + } + + // eslint-disable-next-line jsdoc/require-description + /** + * @returns {ASTNode[]} The ancestor nodes. + */ + parents() { + return this._parents.slice(0); + } + + /** + * Break the current traversal. + * @returns {void} + */ + break() { + this._broken = true; + } + + /** + * Skip child nodes for the current traversal. + * @returns {void} + */ + skip() { + this._skipped = true; + } + + /** + * Traverse the given AST tree. + * @param {ASTNode} node The root node to traverse. + * @param {Object} options The option object. + * @param {Object} [options.visitorKeys=DEFAULT_VISITOR_KEYS] The keys of each node types to traverse child nodes. Default is `./default-visitor-keys.json`. + * @param {Function} [options.enter=noop] The callback function which is called on entering each node. + * @param {Function} [options.leave=noop] The callback function which is called on leaving each node. + * @returns {void} + */ + traverse(node, options) { + this._current = null; + this._parents = []; + this._skipped = false; + this._broken = false; + this._visitorKeys = options.visitorKeys || vk__default['default'].KEYS; + this._enter = options.enter || noop$1; + this._leave = options.leave || noop$1; + this._traverse(node, null); + } + + /** + * Traverse the given AST tree recursively. + * @param {ASTNode} node The current node. + * @param {ASTNode|null} parent The parent node. + * @returns {void} + * @private + */ + _traverse(node, parent) { + if (!isNode(node)) { + return; + } + + this._current = node; + this._skipped = false; + this._enter(node, parent); + + if (!this._skipped && !this._broken) { + const keys = getVisitorKeys(this._visitorKeys, node); + + if (keys.length >= 1) { + this._parents.push(node); + for (let i = 0; i < keys.length && !this._broken; ++i) { + const child = node[keys[i]]; + + if (Array.isArray(child)) { + for (let j = 0; j < child.length && !this._broken; ++j) { + this._traverse(child[j], node); + } + } else { + this._traverse(child, node); + } + } + this._parents.pop(); + } + } + + if (!this._broken) { + this._leave(node, parent); + } + + this._current = parent; + } + + /** + * Calculates the keys to use for traversal. + * @param {ASTNode} node The node to read keys from. + * @returns {string[]} An array of keys to visit on the node. + * @private + */ + static getKeys(node) { + return vk__default['default'].getKeys(node); + } + + /** + * Traverse the given AST tree. + * @param {ASTNode} node The root node to traverse. + * @param {Object} options The option object. + * @param {Object} [options.visitorKeys=DEFAULT_VISITOR_KEYS] The keys of each node types to traverse child nodes. Default is `./default-visitor-keys.json`. + * @param {Function} [options.enter=noop] The callback function which is called on entering each node. + * @param {Function} [options.leave=noop] The callback function which is called on leaving each node. + * @returns {void} + */ + static traverse(node, options) { + new Traverser().traverse(node, options); + } + + /** + * The default visitor keys. + * @type {Object} + */ + static get DEFAULT_VISITOR_KEYS() { + return vk__default['default'].KEYS; + } +} + +var traverser = Traverser; + +/** + * @fileoverview Define the abstract class about cursors which iterate tokens. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Exports +//------------------------------------------------------------------------------ + +/** + * The abstract class about cursors which iterate tokens. + * + * This class has 2 abstract methods. + * + * - `current: Token | Comment | null` ... The current token. + * - `moveNext(): boolean` ... Moves this cursor to the next token. If the next token didn't exist, it returns `false`. + * + * This is similar to ES2015 Iterators. + * However, Iterators were slow (at 2017-01), so I created this class as similar to C# IEnumerable. + * + * There are the following known sub classes. + * + * - ForwardTokenCursor .......... The cursor which iterates tokens only. + * - BackwardTokenCursor ......... The cursor which iterates tokens only in reverse. + * - ForwardTokenCommentCursor ... The cursor which iterates tokens and comments. + * - BackwardTokenCommentCursor .. The cursor which iterates tokens and comments in reverse. + * - DecorativeCursor + * - FilterCursor ............ The cursor which ignores the specified tokens. + * - SkipCursor .............. The cursor which ignores the first few tokens. + * - LimitCursor ............. The cursor which limits the count of tokens. + * + */ +var cursor = class Cursor { + + /** + * Initializes this cursor. + */ + constructor() { + this.current = null; + } + + /** + * Gets the first token. + * This consumes this cursor. + * @returns {Token|Comment} The first token or null. + */ + getOneToken() { + return this.moveNext() ? this.current : null; + } + + /** + * Gets the first tokens. + * This consumes this cursor. + * @returns {(Token|Comment)[]} All tokens. + */ + getAllTokens() { + const tokens = []; + + while (this.moveNext()) { + tokens.push(this.current); + } + + return tokens; + } + + /** + * Moves this cursor to the next token. + * @returns {boolean} `true` if the next token exists. + * @abstract + */ + /* istanbul ignore next */ + moveNext() { // eslint-disable-line class-methods-use-this + throw new Error("Not implemented."); + } +}; + +/** + * @fileoverview Define utility functions for token store. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Gets `token.range[0]` from the given token. + * @param {Node|Token|Comment} token The token to get. + * @returns {number} The start location. + * @private + */ +function getStartLocation(token) { + return token.range[0]; +} + +//------------------------------------------------------------------------------ +// Exports +//------------------------------------------------------------------------------ + +/** + * Binary-searches the index of the first token which is after the given location. + * If it was not found, this returns `tokens.length`. + * @param {(Token|Comment)[]} tokens It searches the token in this list. + * @param {number} location The location to search. + * @returns {number} The found index or `tokens.length`. + */ +var search = function search(tokens, location) { + return lodash__default['default'].sortedIndexBy( + tokens, + { range: [location] }, + getStartLocation + ); +}; + +/** + * Gets the index of the `startLoc` in `tokens`. + * `startLoc` can be the value of `node.range[1]`, so this checks about `startLoc - 1` as well. + * @param {(Token|Comment)[]} tokens The tokens to find an index. + * @param {Object} indexMap The map from locations to indices. + * @param {number} startLoc The location to get an index. + * @returns {number} The index. + */ +var getFirstIndex = function getFirstIndex(tokens, indexMap, startLoc) { + if (startLoc in indexMap) { + return indexMap[startLoc]; + } + if ((startLoc - 1) in indexMap) { + const index = indexMap[startLoc - 1]; + const token = (index >= 0 && index < tokens.length) ? tokens[index] : null; + + /* + * For the map of "comment's location -> token's index", it points the next token of a comment. + * In that case, +1 is unnecessary. + */ + if (token && token.range[0] >= startLoc) { + return index; + } + return index + 1; + } + return 0; +}; + +/** + * Gets the index of the `endLoc` in `tokens`. + * The information of end locations are recorded at `endLoc - 1` in `indexMap`, so this checks about `endLoc - 1` as well. + * @param {(Token|Comment)[]} tokens The tokens to find an index. + * @param {Object} indexMap The map from locations to indices. + * @param {number} endLoc The location to get an index. + * @returns {number} The index. + */ +var getLastIndex = function getLastIndex(tokens, indexMap, endLoc) { + if (endLoc in indexMap) { + return indexMap[endLoc] - 1; + } + if ((endLoc - 1) in indexMap) { + const index = indexMap[endLoc - 1]; + const token = (index >= 0 && index < tokens.length) ? tokens[index] : null; + + /* + * For the map of "comment's location -> token's index", it points the next token of a comment. + * In that case, -1 is necessary. + */ + if (token && token.range[1] > endLoc) { + return index - 1; + } + return index; + } + return tokens.length - 1; +}; + +var utils = { + search: search, + getFirstIndex: getFirstIndex, + getLastIndex: getLastIndex +}; + +/** + * @fileoverview Define the cursor which iterates tokens and comments in reverse. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------------ +// Exports +//------------------------------------------------------------------------------ + +/** + * The cursor which iterates tokens and comments in reverse. + */ +var backwardTokenCommentCursor = class BackwardTokenCommentCursor extends cursor { + + /** + * Initializes this cursor. + * @param {Token[]} tokens The array of tokens. + * @param {Comment[]} comments The array of comments. + * @param {Object} indexMap The map from locations to indices in `tokens`. + * @param {number} startLoc The start location of the iteration range. + * @param {number} endLoc The end location of the iteration range. + */ + constructor(tokens, comments, indexMap, startLoc, endLoc) { + super(); + this.tokens = tokens; + this.comments = comments; + this.tokenIndex = utils.getLastIndex(tokens, indexMap, endLoc); + this.commentIndex = utils.search(comments, endLoc) - 1; + this.border = startLoc; + } + + /** @inheritdoc */ + moveNext() { + const token = (this.tokenIndex >= 0) ? this.tokens[this.tokenIndex] : null; + const comment = (this.commentIndex >= 0) ? this.comments[this.commentIndex] : null; + + if (token && (!comment || token.range[1] > comment.range[1])) { + this.current = token; + this.tokenIndex -= 1; + } else if (comment) { + this.current = comment; + this.commentIndex -= 1; + } else { + this.current = null; + } + + return Boolean(this.current) && (this.border === -1 || this.current.range[0] >= this.border); + } +}; + +/** + * @fileoverview Define the cursor which iterates tokens only in reverse. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------------ +// Exports +//------------------------------------------------------------------------------ + +/** + * The cursor which iterates tokens only in reverse. + */ +var backwardTokenCursor = class BackwardTokenCursor extends cursor { + + /** + * Initializes this cursor. + * @param {Token[]} tokens The array of tokens. + * @param {Comment[]} comments The array of comments. + * @param {Object} indexMap The map from locations to indices in `tokens`. + * @param {number} startLoc The start location of the iteration range. + * @param {number} endLoc The end location of the iteration range. + */ + constructor(tokens, comments, indexMap, startLoc, endLoc) { + super(); + this.tokens = tokens; + this.index = utils.getLastIndex(tokens, indexMap, endLoc); + this.indexEnd = utils.getFirstIndex(tokens, indexMap, startLoc); + } + + /** @inheritdoc */ + moveNext() { + if (this.index >= this.indexEnd) { + this.current = this.tokens[this.index]; + this.index -= 1; + return true; + } + return false; + } + + /* + * + * Shorthand for performance. + * + */ + + /** @inheritdoc */ + getOneToken() { + return (this.index >= this.indexEnd) ? this.tokens[this.index] : null; + } +}; + +/** + * @fileoverview Define the abstract class about cursors which manipulate another cursor. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Exports +//------------------------------------------------------------------------------ + +/** + * The abstract class about cursors which manipulate another cursor. + */ +var decorativeCursor = class DecorativeCursor extends cursor { + + /** + * Initializes this cursor. + * @param {Cursor} cursor The cursor to be decorated. + */ + constructor(cursor) { + super(); + this.cursor = cursor; + } + + /** @inheritdoc */ + moveNext() { + const retv = this.cursor.moveNext(); + + this.current = this.cursor.current; + + return retv; + } +}; + +/** + * @fileoverview Define the cursor which ignores specified tokens. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Exports +//------------------------------------------------------------------------------ + +/** + * The decorative cursor which ignores specified tokens. + */ +var filterCursor = class FilterCursor extends decorativeCursor { + + /** + * Initializes this cursor. + * @param {Cursor} cursor The cursor to be decorated. + * @param {Function} predicate The predicate function to decide tokens this cursor iterates. + */ + constructor(cursor, predicate) { + super(cursor); + this.predicate = predicate; + } + + /** @inheritdoc */ + moveNext() { + const predicate = this.predicate; + + while (super.moveNext()) { + if (predicate(this.current)) { + return true; + } + } + return false; + } +}; + +/** + * @fileoverview Define the cursor which iterates tokens and comments. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------------ +// Exports +//------------------------------------------------------------------------------ + +/** + * The cursor which iterates tokens and comments. + */ +var forwardTokenCommentCursor = class ForwardTokenCommentCursor extends cursor { + + /** + * Initializes this cursor. + * @param {Token[]} tokens The array of tokens. + * @param {Comment[]} comments The array of comments. + * @param {Object} indexMap The map from locations to indices in `tokens`. + * @param {number} startLoc The start location of the iteration range. + * @param {number} endLoc The end location of the iteration range. + */ + constructor(tokens, comments, indexMap, startLoc, endLoc) { + super(); + this.tokens = tokens; + this.comments = comments; + this.tokenIndex = utils.getFirstIndex(tokens, indexMap, startLoc); + this.commentIndex = utils.search(comments, startLoc); + this.border = endLoc; + } + + /** @inheritdoc */ + moveNext() { + const token = (this.tokenIndex < this.tokens.length) ? this.tokens[this.tokenIndex] : null; + const comment = (this.commentIndex < this.comments.length) ? this.comments[this.commentIndex] : null; + + if (token && (!comment || token.range[0] < comment.range[0])) { + this.current = token; + this.tokenIndex += 1; + } else if (comment) { + this.current = comment; + this.commentIndex += 1; + } else { + this.current = null; + } + + return Boolean(this.current) && (this.border === -1 || this.current.range[1] <= this.border); + } +}; + +/** + * @fileoverview Define the cursor which iterates tokens only. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------------ +// Exports +//------------------------------------------------------------------------------ + +/** + * The cursor which iterates tokens only. + */ +var forwardTokenCursor = class ForwardTokenCursor extends cursor { + + /** + * Initializes this cursor. + * @param {Token[]} tokens The array of tokens. + * @param {Comment[]} comments The array of comments. + * @param {Object} indexMap The map from locations to indices in `tokens`. + * @param {number} startLoc The start location of the iteration range. + * @param {number} endLoc The end location of the iteration range. + */ + constructor(tokens, comments, indexMap, startLoc, endLoc) { + super(); + this.tokens = tokens; + this.index = utils.getFirstIndex(tokens, indexMap, startLoc); + this.indexEnd = utils.getLastIndex(tokens, indexMap, endLoc); + } + + /** @inheritdoc */ + moveNext() { + if (this.index <= this.indexEnd) { + this.current = this.tokens[this.index]; + this.index += 1; + return true; + } + return false; + } + + /* + * + * Shorthand for performance. + * + */ + + /** @inheritdoc */ + getOneToken() { + return (this.index <= this.indexEnd) ? this.tokens[this.index] : null; + } + + /** @inheritdoc */ + getAllTokens() { + return this.tokens.slice(this.index, this.indexEnd + 1); + } +}; + +/** + * @fileoverview Define the cursor which limits the number of tokens. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Exports +//------------------------------------------------------------------------------ + +/** + * The decorative cursor which limits the number of tokens. + */ +var limitCursor = class LimitCursor extends decorativeCursor { + + /** + * Initializes this cursor. + * @param {Cursor} cursor The cursor to be decorated. + * @param {number} count The count of tokens this cursor iterates. + */ + constructor(cursor, count) { + super(cursor); + this.count = count; + } + + /** @inheritdoc */ + moveNext() { + if (this.count > 0) { + this.count -= 1; + return super.moveNext(); + } + return false; + } +}; + +/** + * @fileoverview Define the cursor which ignores the first few tokens. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Exports +//------------------------------------------------------------------------------ + +/** + * The decorative cursor which ignores the first few tokens. + */ +var skipCursor = class SkipCursor extends decorativeCursor { + + /** + * Initializes this cursor. + * @param {Cursor} cursor The cursor to be decorated. + * @param {number} count The count of tokens this cursor skips. + */ + constructor(cursor, count) { + super(cursor); + this.count = count; + } + + /** @inheritdoc */ + moveNext() { + while (this.count > 0) { + this.count -= 1; + if (!super.moveNext()) { + return false; + } + } + return super.moveNext(); + } +}; + +/** + * @fileoverview Define 2 token factories; forward and backward. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + + + + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * The cursor factory. + * @private + */ +class CursorFactory { + + /** + * Initializes this cursor. + * @param {Function} TokenCursor The class of the cursor which iterates tokens only. + * @param {Function} TokenCommentCursor The class of the cursor which iterates the mix of tokens and comments. + */ + constructor(TokenCursor, TokenCommentCursor) { + this.TokenCursor = TokenCursor; + this.TokenCommentCursor = TokenCommentCursor; + } + + /** + * Creates a base cursor instance that can be decorated by createCursor. + * @param {Token[]} tokens The array of tokens. + * @param {Comment[]} comments The array of comments. + * @param {Object} indexMap The map from locations to indices in `tokens`. + * @param {number} startLoc The start location of the iteration range. + * @param {number} endLoc The end location of the iteration range. + * @param {boolean} includeComments The flag to iterate comments as well. + * @returns {Cursor} The created base cursor. + */ + createBaseCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments) { + const Cursor = includeComments ? this.TokenCommentCursor : this.TokenCursor; + + return new Cursor(tokens, comments, indexMap, startLoc, endLoc); + } + + /** + * Creates a cursor that iterates tokens with normalized options. + * @param {Token[]} tokens The array of tokens. + * @param {Comment[]} comments The array of comments. + * @param {Object} indexMap The map from locations to indices in `tokens`. + * @param {number} startLoc The start location of the iteration range. + * @param {number} endLoc The end location of the iteration range. + * @param {boolean} includeComments The flag to iterate comments as well. + * @param {Function|null} filter The predicate function to choose tokens. + * @param {number} skip The count of tokens the cursor skips. + * @param {number} count The maximum count of tokens the cursor iterates. Zero is no iteration for backward compatibility. + * @returns {Cursor} The created cursor. + */ + createCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments, filter, skip, count) { + let cursor = this.createBaseCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments); + + if (filter) { + cursor = new filterCursor(cursor, filter); + } + if (skip >= 1) { + cursor = new skipCursor(cursor, skip); + } + if (count >= 0) { + cursor = new limitCursor(cursor, count); + } + + return cursor; + } +} + +//------------------------------------------------------------------------------ +// Exports +//------------------------------------------------------------------------------ + +var forward = new CursorFactory(forwardTokenCursor, forwardTokenCommentCursor); +var backward = new CursorFactory(backwardTokenCursor, backwardTokenCommentCursor); + +var cursors = { + forward: forward, + backward: backward +}; + +/** + * @fileoverview Define the cursor which iterates tokens only, with inflated range. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Exports +//------------------------------------------------------------------------------ + +/** + * The cursor which iterates tokens only, with inflated range. + * This is for the backward compatibility of padding options. + */ +var paddedTokenCursor = class PaddedTokenCursor extends forwardTokenCursor { + + /** + * Initializes this cursor. + * @param {Token[]} tokens The array of tokens. + * @param {Comment[]} comments The array of comments. + * @param {Object} indexMap The map from locations to indices in `tokens`. + * @param {number} startLoc The start location of the iteration range. + * @param {number} endLoc The end location of the iteration range. + * @param {number} beforeCount The number of tokens this cursor iterates before start. + * @param {number} afterCount The number of tokens this cursor iterates after end. + */ + constructor(tokens, comments, indexMap, startLoc, endLoc, beforeCount, afterCount) { + super(tokens, comments, indexMap, startLoc, endLoc); + this.index = Math.max(0, this.index - beforeCount); + this.indexEnd = Math.min(tokens.length - 1, this.indexEnd + afterCount); + } +}; + +/** + * @fileoverview Object to handle access and retrieval of tokens. + * @author Brandon Mills + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + +const { isCommentToken: isCommentToken$2 } = require$$0__default$1['default']; + + + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const TOKENS = Symbol("tokens"); +const COMMENTS = Symbol("comments"); +const INDEX_MAP = Symbol("indexMap"); + +/** + * Creates the map from locations to indices in `tokens`. + * + * The first/last location of tokens is mapped to the index of the token. + * The first/last location of comments is mapped to the index of the next token of each comment. + * @param {Token[]} tokens The array of tokens. + * @param {Comment[]} comments The array of comments. + * @returns {Object} The map from locations to indices in `tokens`. + * @private + */ +function createIndexMap(tokens, comments) { + const map = Object.create(null); + let tokenIndex = 0; + let commentIndex = 0; + let nextStart = 0; + let range = null; + + while (tokenIndex < tokens.length || commentIndex < comments.length) { + nextStart = (commentIndex < comments.length) ? comments[commentIndex].range[0] : Number.MAX_SAFE_INTEGER; + while (tokenIndex < tokens.length && (range = tokens[tokenIndex].range)[0] < nextStart) { + map[range[0]] = tokenIndex; + map[range[1] - 1] = tokenIndex; + tokenIndex += 1; + } + + nextStart = (tokenIndex < tokens.length) ? tokens[tokenIndex].range[0] : Number.MAX_SAFE_INTEGER; + while (commentIndex < comments.length && (range = comments[commentIndex].range)[0] < nextStart) { + map[range[0]] = tokenIndex; + map[range[1] - 1] = tokenIndex; + commentIndex += 1; + } + } + + return map; +} + +/** + * Creates the cursor iterates tokens with options. + * @param {CursorFactory} factory The cursor factory to initialize cursor. + * @param {Token[]} tokens The array of tokens. + * @param {Comment[]} comments The array of comments. + * @param {Object} indexMap The map from locations to indices in `tokens`. + * @param {number} startLoc The start location of the iteration range. + * @param {number} endLoc The end location of the iteration range. + * @param {number|Function|Object} [opts=0] The option object. If this is a number then it's `opts.skip`. If this is a function then it's `opts.filter`. + * @param {boolean} [opts.includeComments=false] The flag to iterate comments as well. + * @param {Function|null} [opts.filter=null] The predicate function to choose tokens. + * @param {number} [opts.skip=0] The count of tokens the cursor skips. + * @returns {Cursor} The created cursor. + * @private + */ +function createCursorWithSkip(factory, tokens, comments, indexMap, startLoc, endLoc, opts) { + let includeComments = false; + let skip = 0; + let filter = null; + + if (typeof opts === "number") { + skip = opts | 0; + } else if (typeof opts === "function") { + filter = opts; + } else if (opts) { + includeComments = !!opts.includeComments; + skip = opts.skip | 0; + filter = opts.filter || null; + } + assert__default['default'](skip >= 0, "options.skip should be zero or a positive integer."); + assert__default['default'](!filter || typeof filter === "function", "options.filter should be a function."); + + return factory.createCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments, filter, skip, -1); +} + +/** + * Creates the cursor iterates tokens with options. + * @param {CursorFactory} factory The cursor factory to initialize cursor. + * @param {Token[]} tokens The array of tokens. + * @param {Comment[]} comments The array of comments. + * @param {Object} indexMap The map from locations to indices in `tokens`. + * @param {number} startLoc The start location of the iteration range. + * @param {number} endLoc The end location of the iteration range. + * @param {number|Function|Object} [opts=0] The option object. If this is a number then it's `opts.count`. If this is a function then it's `opts.filter`. + * @param {boolean} [opts.includeComments] The flag to iterate comments as well. + * @param {Function|null} [opts.filter=null] The predicate function to choose tokens. + * @param {number} [opts.count=0] The maximum count of tokens the cursor iterates. Zero is no iteration for backward compatibility. + * @returns {Cursor} The created cursor. + * @private + */ +function createCursorWithCount(factory, tokens, comments, indexMap, startLoc, endLoc, opts) { + let includeComments = false; + let count = 0; + let countExists = false; + let filter = null; + + if (typeof opts === "number") { + count = opts | 0; + countExists = true; + } else if (typeof opts === "function") { + filter = opts; + } else if (opts) { + includeComments = !!opts.includeComments; + count = opts.count | 0; + countExists = typeof opts.count === "number"; + filter = opts.filter || null; + } + assert__default['default'](count >= 0, "options.count should be zero or a positive integer."); + assert__default['default'](!filter || typeof filter === "function", "options.filter should be a function."); + + return factory.createCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments, filter, 0, countExists ? count : -1); +} + +/** + * Creates the cursor iterates tokens with options. + * This is overload function of the below. + * @param {Token[]} tokens The array of tokens. + * @param {Comment[]} comments The array of comments. + * @param {Object} indexMap The map from locations to indices in `tokens`. + * @param {number} startLoc The start location of the iteration range. + * @param {number} endLoc The end location of the iteration range. + * @param {Function|Object} opts The option object. If this is a function then it's `opts.filter`. + * @param {boolean} [opts.includeComments] The flag to iterate comments as well. + * @param {Function|null} [opts.filter=null] The predicate function to choose tokens. + * @param {number} [opts.count=0] The maximum count of tokens the cursor iterates. Zero is no iteration for backward compatibility. + * @returns {Cursor} The created cursor. + * @private + */ +/** + * Creates the cursor iterates tokens with options. + * @param {Token[]} tokens The array of tokens. + * @param {Comment[]} comments The array of comments. + * @param {Object} indexMap The map from locations to indices in `tokens`. + * @param {number} startLoc The start location of the iteration range. + * @param {number} endLoc The end location of the iteration range. + * @param {number} [beforeCount=0] The number of tokens before the node to retrieve. + * @param {boolean} [afterCount=0] The number of tokens after the node to retrieve. + * @returns {Cursor} The created cursor. + * @private + */ +function createCursorWithPadding(tokens, comments, indexMap, startLoc, endLoc, beforeCount, afterCount) { + if (typeof beforeCount === "undefined" && typeof afterCount === "undefined") { + return new forwardTokenCursor(tokens, comments, indexMap, startLoc, endLoc); + } + if (typeof beforeCount === "number" || typeof beforeCount === "undefined") { + return new paddedTokenCursor(tokens, comments, indexMap, startLoc, endLoc, beforeCount | 0, afterCount | 0); + } + return createCursorWithCount(cursors.forward, tokens, comments, indexMap, startLoc, endLoc, beforeCount); +} + +/** + * Gets comment tokens that are adjacent to the current cursor position. + * @param {Cursor} cursor A cursor instance. + * @returns {Array} An array of comment tokens adjacent to the current cursor position. + * @private + */ +function getAdjacentCommentTokensFromCursor(cursor) { + const tokens = []; + let currentToken = cursor.getOneToken(); + + while (currentToken && isCommentToken$2(currentToken)) { + tokens.push(currentToken); + currentToken = cursor.getOneToken(); + } + + return tokens; +} + +//------------------------------------------------------------------------------ +// Exports +//------------------------------------------------------------------------------ + +/** + * The token store. + * + * This class provides methods to get tokens by locations as fast as possible. + * The methods are a part of public API, so we should be careful if it changes this class. + * + * People can get tokens in O(1) by the hash map which is mapping from the location of tokens/comments to tokens. + * Also people can get a mix of tokens and comments in O(log k), the k is the number of comments. + * Assuming that comments to be much fewer than tokens, this does not make hash map from token's locations to comments to reduce memory cost. + * This uses binary-searching instead for comments. + */ +var tokenStore = class TokenStore { + + /** + * Initializes this token store. + * @param {Token[]} tokens The array of tokens. + * @param {Comment[]} comments The array of comments. + */ + constructor(tokens, comments) { + this[TOKENS] = tokens; + this[COMMENTS] = comments; + this[INDEX_MAP] = createIndexMap(tokens, comments); + } + + //-------------------------------------------------------------------------- + // Gets single token. + //-------------------------------------------------------------------------- + + /** + * Gets the token starting at the specified index. + * @param {number} offset Index of the start of the token's range. + * @param {Object} [options=0] The option object. + * @param {boolean} [options.includeComments=false] The flag to iterate comments as well. + * @returns {Token|null} The token starting at index, or null if no such token. + */ + getTokenByRangeStart(offset, options) { + const includeComments = options && options.includeComments; + const token = cursors.forward.createBaseCursor( + this[TOKENS], + this[COMMENTS], + this[INDEX_MAP], + offset, + -1, + includeComments + ).getOneToken(); + + if (token && token.range[0] === offset) { + return token; + } + return null; + } + + /** + * Gets the first token of the given node. + * @param {ASTNode} node The AST node. + * @param {number|Function|Object} [options=0] The option object. If this is a number then it's `options.skip`. If this is a function then it's `options.filter`. + * @param {boolean} [options.includeComments=false] The flag to iterate comments as well. + * @param {Function|null} [options.filter=null] The predicate function to choose tokens. + * @param {number} [options.skip=0] The count of tokens the cursor skips. + * @returns {Token|null} An object representing the token. + */ + getFirstToken(node, options) { + return createCursorWithSkip( + cursors.forward, + this[TOKENS], + this[COMMENTS], + this[INDEX_MAP], + node.range[0], + node.range[1], + options + ).getOneToken(); + } + + /** + * Gets the last token of the given node. + * @param {ASTNode} node The AST node. + * @param {number|Function|Object} [options=0] The option object. Same options as getFirstToken() + * @returns {Token|null} An object representing the token. + */ + getLastToken(node, options) { + return createCursorWithSkip( + cursors.backward, + this[TOKENS], + this[COMMENTS], + this[INDEX_MAP], + node.range[0], + node.range[1], + options + ).getOneToken(); + } + + /** + * Gets the token that precedes a given node or token. + * @param {ASTNode|Token|Comment} node The AST node or token. + * @param {number|Function|Object} [options=0] The option object. Same options as getFirstToken() + * @returns {Token|null} An object representing the token. + */ + getTokenBefore(node, options) { + return createCursorWithSkip( + cursors.backward, + this[TOKENS], + this[COMMENTS], + this[INDEX_MAP], + -1, + node.range[0], + options + ).getOneToken(); + } + + /** + * Gets the token that follows a given node or token. + * @param {ASTNode|Token|Comment} node The AST node or token. + * @param {number|Function|Object} [options=0] The option object. Same options as getFirstToken() + * @returns {Token|null} An object representing the token. + */ + getTokenAfter(node, options) { + return createCursorWithSkip( + cursors.forward, + this[TOKENS], + this[COMMENTS], + this[INDEX_MAP], + node.range[1], + -1, + options + ).getOneToken(); + } + + /** + * Gets the first token between two non-overlapping nodes. + * @param {ASTNode|Token|Comment} left Node before the desired token range. + * @param {ASTNode|Token|Comment} right Node after the desired token range. + * @param {number|Function|Object} [options=0] The option object. Same options as getFirstToken() + * @returns {Token|null} An object representing the token. + */ + getFirstTokenBetween(left, right, options) { + return createCursorWithSkip( + cursors.forward, + this[TOKENS], + this[COMMENTS], + this[INDEX_MAP], + left.range[1], + right.range[0], + options + ).getOneToken(); + } + + /** + * Gets the last token between two non-overlapping nodes. + * @param {ASTNode|Token|Comment} left Node before the desired token range. + * @param {ASTNode|Token|Comment} right Node after the desired token range. + * @param {number|Function|Object} [options=0] The option object. Same options as getFirstToken() + * @returns {Token|null} An object representing the token. + */ + getLastTokenBetween(left, right, options) { + return createCursorWithSkip( + cursors.backward, + this[TOKENS], + this[COMMENTS], + this[INDEX_MAP], + left.range[1], + right.range[0], + options + ).getOneToken(); + } + + /** + * Gets the token that precedes a given node or token in the token stream. + * This is defined for backward compatibility. Use `includeComments` option instead. + * TODO: We have a plan to remove this in a future major version. + * @param {ASTNode|Token|Comment} node The AST node or token. + * @param {number} [skip=0] A number of tokens to skip. + * @returns {Token|null} An object representing the token. + * @deprecated + */ + getTokenOrCommentBefore(node, skip) { + return this.getTokenBefore(node, { includeComments: true, skip }); + } + + /** + * Gets the token that follows a given node or token in the token stream. + * This is defined for backward compatibility. Use `includeComments` option instead. + * TODO: We have a plan to remove this in a future major version. + * @param {ASTNode|Token|Comment} node The AST node or token. + * @param {number} [skip=0] A number of tokens to skip. + * @returns {Token|null} An object representing the token. + * @deprecated + */ + getTokenOrCommentAfter(node, skip) { + return this.getTokenAfter(node, { includeComments: true, skip }); + } + + //-------------------------------------------------------------------------- + // Gets multiple tokens. + //-------------------------------------------------------------------------- + + /** + * Gets the first `count` tokens of the given node. + * @param {ASTNode} node The AST node. + * @param {number|Function|Object} [options=0] The option object. If this is a number then it's `options.count`. If this is a function then it's `options.filter`. + * @param {boolean} [options.includeComments=false] The flag to iterate comments as well. + * @param {Function|null} [options.filter=null] The predicate function to choose tokens. + * @param {number} [options.count=0] The maximum count of tokens the cursor iterates. + * @returns {Token[]} Tokens. + */ + getFirstTokens(node, options) { + return createCursorWithCount( + cursors.forward, + this[TOKENS], + this[COMMENTS], + this[INDEX_MAP], + node.range[0], + node.range[1], + options + ).getAllTokens(); + } + + /** + * Gets the last `count` tokens of the given node. + * @param {ASTNode} node The AST node. + * @param {number|Function|Object} [options=0] The option object. Same options as getFirstTokens() + * @returns {Token[]} Tokens. + */ + getLastTokens(node, options) { + return createCursorWithCount( + cursors.backward, + this[TOKENS], + this[COMMENTS], + this[INDEX_MAP], + node.range[0], + node.range[1], + options + ).getAllTokens().reverse(); + } + + /** + * Gets the `count` tokens that precedes a given node or token. + * @param {ASTNode|Token|Comment} node The AST node or token. + * @param {number|Function|Object} [options=0] The option object. Same options as getFirstTokens() + * @returns {Token[]} Tokens. + */ + getTokensBefore(node, options) { + return createCursorWithCount( + cursors.backward, + this[TOKENS], + this[COMMENTS], + this[INDEX_MAP], + -1, + node.range[0], + options + ).getAllTokens().reverse(); + } + + /** + * Gets the `count` tokens that follows a given node or token. + * @param {ASTNode|Token|Comment} node The AST node or token. + * @param {number|Function|Object} [options=0] The option object. Same options as getFirstTokens() + * @returns {Token[]} Tokens. + */ + getTokensAfter(node, options) { + return createCursorWithCount( + cursors.forward, + this[TOKENS], + this[COMMENTS], + this[INDEX_MAP], + node.range[1], + -1, + options + ).getAllTokens(); + } + + /** + * Gets the first `count` tokens between two non-overlapping nodes. + * @param {ASTNode|Token|Comment} left Node before the desired token range. + * @param {ASTNode|Token|Comment} right Node after the desired token range. + * @param {number|Function|Object} [options=0] The option object. Same options as getFirstTokens() + * @returns {Token[]} Tokens between left and right. + */ + getFirstTokensBetween(left, right, options) { + return createCursorWithCount( + cursors.forward, + this[TOKENS], + this[COMMENTS], + this[INDEX_MAP], + left.range[1], + right.range[0], + options + ).getAllTokens(); + } + + /** + * Gets the last `count` tokens between two non-overlapping nodes. + * @param {ASTNode|Token|Comment} left Node before the desired token range. + * @param {ASTNode|Token|Comment} right Node after the desired token range. + * @param {number|Function|Object} [options=0] The option object. Same options as getFirstTokens() + * @returns {Token[]} Tokens between left and right. + */ + getLastTokensBetween(left, right, options) { + return createCursorWithCount( + cursors.backward, + this[TOKENS], + this[COMMENTS], + this[INDEX_MAP], + left.range[1], + right.range[0], + options + ).getAllTokens().reverse(); + } + + /** + * Gets all tokens that are related to the given node. + * @param {ASTNode} node The AST node. + * @param {Function|Object} options The option object. If this is a function then it's `options.filter`. + * @param {boolean} [options.includeComments=false] The flag to iterate comments as well. + * @param {Function|null} [options.filter=null] The predicate function to choose tokens. + * @param {number} [options.count=0] The maximum count of tokens the cursor iterates. + * @returns {Token[]} Array of objects representing tokens. + */ + /** + * Gets all tokens that are related to the given node. + * @param {ASTNode} node The AST node. + * @param {int} [beforeCount=0] The number of tokens before the node to retrieve. + * @param {int} [afterCount=0] The number of tokens after the node to retrieve. + * @returns {Token[]} Array of objects representing tokens. + */ + getTokens(node, beforeCount, afterCount) { + return createCursorWithPadding( + this[TOKENS], + this[COMMENTS], + this[INDEX_MAP], + node.range[0], + node.range[1], + beforeCount, + afterCount + ).getAllTokens(); + } + + /** + * Gets all of the tokens between two non-overlapping nodes. + * @param {ASTNode|Token|Comment} left Node before the desired token range. + * @param {ASTNode|Token|Comment} right Node after the desired token range. + * @param {Function|Object} options The option object. If this is a function then it's `options.filter`. + * @param {boolean} [options.includeComments=false] The flag to iterate comments as well. + * @param {Function|null} [options.filter=null] The predicate function to choose tokens. + * @param {number} [options.count=0] The maximum count of tokens the cursor iterates. + * @returns {Token[]} Tokens between left and right. + */ + /** + * Gets all of the tokens between two non-overlapping nodes. + * @param {ASTNode|Token|Comment} left Node before the desired token range. + * @param {ASTNode|Token|Comment} right Node after the desired token range. + * @param {int} [padding=0] Number of extra tokens on either side of center. + * @returns {Token[]} Tokens between left and right. + */ + getTokensBetween(left, right, padding) { + return createCursorWithPadding( + this[TOKENS], + this[COMMENTS], + this[INDEX_MAP], + left.range[1], + right.range[0], + padding, + padding + ).getAllTokens(); + } + + //-------------------------------------------------------------------------- + // Others. + //-------------------------------------------------------------------------- + + /** + * Checks whether any comments exist or not between the given 2 nodes. + * @param {ASTNode} left The node to check. + * @param {ASTNode} right The node to check. + * @returns {boolean} `true` if one or more comments exist. + */ + commentsExistBetween(left, right) { + const index = utils.search(this[COMMENTS], left.range[1]); + + return ( + index < this[COMMENTS].length && + this[COMMENTS][index].range[1] <= right.range[0] + ); + } + + /** + * Gets all comment tokens directly before the given node or token. + * @param {ASTNode|token} nodeOrToken The AST node or token to check for adjacent comment tokens. + * @returns {Array} An array of comments in occurrence order. + */ + getCommentsBefore(nodeOrToken) { + const cursor = createCursorWithCount( + cursors.backward, + this[TOKENS], + this[COMMENTS], + this[INDEX_MAP], + -1, + nodeOrToken.range[0], + { includeComments: true } + ); + + return getAdjacentCommentTokensFromCursor(cursor).reverse(); + } + + /** + * Gets all comment tokens directly after the given node or token. + * @param {ASTNode|token} nodeOrToken The AST node or token to check for adjacent comment tokens. + * @returns {Array} An array of comments in occurrence order. + */ + getCommentsAfter(nodeOrToken) { + const cursor = createCursorWithCount( + cursors.forward, + this[TOKENS], + this[COMMENTS], + this[INDEX_MAP], + nodeOrToken.range[1], + -1, + { includeComments: true } + ); + + return getAdjacentCommentTokensFromCursor(cursor); + } + + /** + * Gets all comment tokens inside the given node. + * @param {ASTNode} node The AST node to get the comments for. + * @returns {Array} An array of comments in occurrence order. + */ + getCommentsInside(node) { + return this.getTokens(node, { + includeComments: true, + filter: isCommentToken$2 + }); + } +}; + +/** + * @fileoverview Abstraction of JavaScript source code. + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const + { isCommentToken: isCommentToken$1 } = require$$0__default$1['default']; + +//------------------------------------------------------------------------------ +// Private +//------------------------------------------------------------------------------ + +/** + * Validates that the given AST has the required information. + * @param {ASTNode} ast The Program node of the AST to check. + * @throws {Error} If the AST doesn't contain the correct information. + * @returns {void} + * @private + */ +function validate$2(ast) { + if (!ast.tokens) { + throw new Error("AST is missing the tokens array."); + } + + if (!ast.comments) { + throw new Error("AST is missing the comments array."); + } + + if (!ast.loc) { + throw new Error("AST is missing location information."); + } + + if (!ast.range) { + throw new Error("AST is missing range information"); + } +} + +/** + * Check to see if its a ES6 export declaration. + * @param {ASTNode} astNode An AST node. + * @returns {boolean} whether the given node represents an export declaration. + * @private + */ +function looksLikeExport(astNode) { + return astNode.type === "ExportDefaultDeclaration" || astNode.type === "ExportNamedDeclaration" || + astNode.type === "ExportAllDeclaration" || astNode.type === "ExportSpecifier"; +} + +/** + * Merges two sorted lists into a larger sorted list in O(n) time. + * @param {Token[]} tokens The list of tokens. + * @param {Token[]} comments The list of comments. + * @returns {Token[]} A sorted list of tokens and comments. + * @private + */ +function sortedMerge(tokens, comments) { + const result = []; + let tokenIndex = 0; + let commentIndex = 0; + + while (tokenIndex < tokens.length || commentIndex < comments.length) { + if (commentIndex >= comments.length || tokenIndex < tokens.length && tokens[tokenIndex].range[0] < comments[commentIndex].range[0]) { + result.push(tokens[tokenIndex++]); + } else { + result.push(comments[commentIndex++]); + } + } + + return result; +} + +/** + * Determines if two nodes or tokens overlap. + * @param {ASTNode|Token} first The first node or token to check. + * @param {ASTNode|Token} second The second node or token to check. + * @returns {boolean} True if the two nodes or tokens overlap. + * @private + */ +function nodesOrTokensOverlap(first, second) { + return (first.range[0] <= second.range[0] && first.range[1] >= second.range[0]) || + (second.range[0] <= first.range[0] && second.range[1] >= first.range[0]); +} + +/** + * Determines if two nodes or tokens have at least one whitespace character + * between them. Order does not matter. Returns false if the given nodes or + * tokens overlap. + * @param {SourceCode} sourceCode The source code object. + * @param {ASTNode|Token} first The first node or token to check between. + * @param {ASTNode|Token} second The second node or token to check between. + * @param {boolean} checkInsideOfJSXText If `true` is present, check inside of JSXText tokens for backward compatibility. + * @returns {boolean} True if there is a whitespace character between + * any of the tokens found between the two given nodes or tokens. + * @public + */ +function isSpaceBetween(sourceCode, first, second, checkInsideOfJSXText) { + if (nodesOrTokensOverlap(first, second)) { + return false; + } + + const [startingNodeOrToken, endingNodeOrToken] = first.range[1] <= second.range[0] + ? [first, second] + : [second, first]; + const firstToken = sourceCode.getLastToken(startingNodeOrToken) || startingNodeOrToken; + const finalToken = sourceCode.getFirstToken(endingNodeOrToken) || endingNodeOrToken; + let currentToken = firstToken; + + while (currentToken !== finalToken) { + const nextToken = sourceCode.getTokenAfter(currentToken, { includeComments: true }); + + if ( + currentToken.range[1] !== nextToken.range[0] || + + /* + * For backward compatibility, check spaces in JSXText. + * https://github.com/eslint/eslint/issues/12614 + */ + ( + checkInsideOfJSXText && + nextToken !== finalToken && + nextToken.type === "JSXText" && + /\s/u.test(nextToken.value) + ) + ) { + return true; + } + + currentToken = nextToken; + } + + return false; +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +class SourceCode$1 extends tokenStore { + + /** + * Represents parsed source code. + * @param {string|Object} textOrConfig The source code text or config object. + * @param {string} textOrConfig.text The source code text. + * @param {ASTNode} textOrConfig.ast The Program node of the AST representing the code. This AST should be created from the text that BOM was stripped. + * @param {Object|null} textOrConfig.parserServices The parser services. + * @param {ScopeManager|null} textOrConfig.scopeManager The scope of this source code. + * @param {Object|null} textOrConfig.visitorKeys The visitor keys to traverse AST. + * @param {ASTNode} [astIfNoConfig] The Program node of the AST representing the code. This AST should be created from the text that BOM was stripped. + */ + constructor(textOrConfig, astIfNoConfig) { + let text, ast, parserServices, scopeManager, visitorKeys; + + // Process overloading. + if (typeof textOrConfig === "string") { + text = textOrConfig; + ast = astIfNoConfig; + } else if (typeof textOrConfig === "object" && textOrConfig !== null) { + text = textOrConfig.text; + ast = textOrConfig.ast; + parserServices = textOrConfig.parserServices; + scopeManager = textOrConfig.scopeManager; + visitorKeys = textOrConfig.visitorKeys; + } + + validate$2(ast); + super(ast.tokens, ast.comments); + + /** + * The flag to indicate that the source code has Unicode BOM. + * @type boolean + */ + this.hasBOM = (text.charCodeAt(0) === 0xFEFF); + + /** + * The original text source code. + * BOM was stripped from this text. + * @type string + */ + this.text = (this.hasBOM ? text.slice(1) : text); + + /** + * The parsed AST for the source code. + * @type ASTNode + */ + this.ast = ast; + + /** + * The parser services of this source code. + * @type {Object} + */ + this.parserServices = parserServices || {}; + + /** + * The scope of this source code. + * @type {ScopeManager|null} + */ + this.scopeManager = scopeManager || null; + + /** + * The visitor keys to traverse AST. + * @type {Object} + */ + this.visitorKeys = visitorKeys || traverser.DEFAULT_VISITOR_KEYS; + + // Check the source text for the presence of a shebang since it is parsed as a standard line comment. + const shebangMatched = this.text.match(astUtils$1.shebangPattern); + const hasShebang = shebangMatched && ast.comments.length && ast.comments[0].value === shebangMatched[1]; + + if (hasShebang) { + ast.comments[0].type = "Shebang"; + } + + this.tokensAndComments = sortedMerge(ast.tokens, ast.comments); + + /** + * The source code split into lines according to ECMA-262 specification. + * This is done to avoid each rule needing to do so separately. + * @type string[] + */ + this.lines = []; + this.lineStartIndices = [0]; + + const lineEndingPattern = astUtils$1.createGlobalLinebreakMatcher(); + let match; + + /* + * Previously, this was implemented using a regex that + * matched a sequence of non-linebreak characters followed by a + * linebreak, then adding the lengths of the matches. However, + * this caused a catastrophic backtracking issue when the end + * of a file contained a large number of non-newline characters. + * To avoid this, the current implementation just matches newlines + * and uses match.index to get the correct line start indices. + */ + while ((match = lineEndingPattern.exec(this.text))) { + this.lines.push(this.text.slice(this.lineStartIndices[this.lineStartIndices.length - 1], match.index)); + this.lineStartIndices.push(match.index + match[0].length); + } + this.lines.push(this.text.slice(this.lineStartIndices[this.lineStartIndices.length - 1])); + + // Cache for comments found using getComments(). + this._commentCache = new WeakMap(); + + // don't allow modification of this object + Object.freeze(this); + Object.freeze(this.lines); + } + + /** + * Split the source code into multiple lines based on the line delimiters. + * @param {string} text Source code as a string. + * @returns {string[]} Array of source code lines. + * @public + */ + static splitLines(text) { + return text.split(astUtils$1.createGlobalLinebreakMatcher()); + } + + /** + * Gets the source code for the given node. + * @param {ASTNode} [node] The AST node to get the text for. + * @param {int} [beforeCount] The number of characters before the node to retrieve. + * @param {int} [afterCount] The number of characters after the node to retrieve. + * @returns {string} The text representing the AST node. + * @public + */ + getText(node, beforeCount, afterCount) { + if (node) { + return this.text.slice(Math.max(node.range[0] - (beforeCount || 0), 0), + node.range[1] + (afterCount || 0)); + } + return this.text; + } + + /** + * Gets the entire source text split into an array of lines. + * @returns {Array} The source text as an array of lines. + * @public + */ + getLines() { + return this.lines; + } + + /** + * Retrieves an array containing all comments in the source code. + * @returns {ASTNode[]} An array of comment nodes. + * @public + */ + getAllComments() { + return this.ast.comments; + } + + /** + * Gets all comments for the given node. + * @param {ASTNode} node The AST node to get the comments for. + * @returns {Object} An object containing a leading and trailing array + * of comments indexed by their position. + * @public + * @deprecated replaced by getCommentsBefore(), getCommentsAfter(), and getCommentsInside(). + */ + getComments(node) { + if (this._commentCache.has(node)) { + return this._commentCache.get(node); + } + + const comments = { + leading: [], + trailing: [] + }; + + /* + * Return all comments as leading comments of the Program node when + * there is no executable code. + */ + if (node.type === "Program") { + if (node.body.length === 0) { + comments.leading = node.comments; + } + } else { + + /* + * Return comments as trailing comments of nodes that only contain + * comments (to mimic the comment attachment behavior present in Espree). + */ + if ((node.type === "BlockStatement" || node.type === "ClassBody") && node.body.length === 0 || + node.type === "ObjectExpression" && node.properties.length === 0 || + node.type === "ArrayExpression" && node.elements.length === 0 || + node.type === "SwitchStatement" && node.cases.length === 0 + ) { + comments.trailing = this.getTokens(node, { + includeComments: true, + filter: isCommentToken$1 + }); + } + + /* + * Iterate over tokens before and after node and collect comment tokens. + * Do not include comments that exist outside of the parent node + * to avoid duplication. + */ + let currentToken = this.getTokenBefore(node, { includeComments: true }); + + while (currentToken && isCommentToken$1(currentToken)) { + if (node.parent && (currentToken.start < node.parent.start)) { + break; + } + comments.leading.push(currentToken); + currentToken = this.getTokenBefore(currentToken, { includeComments: true }); + } + + comments.leading.reverse(); + + currentToken = this.getTokenAfter(node, { includeComments: true }); + + while (currentToken && isCommentToken$1(currentToken)) { + if (node.parent && (currentToken.end > node.parent.end)) { + break; + } + comments.trailing.push(currentToken); + currentToken = this.getTokenAfter(currentToken, { includeComments: true }); + } + } + + this._commentCache.set(node, comments); + return comments; + } + + /** + * Retrieves the JSDoc comment for a given node. + * @param {ASTNode} node The AST node to get the comment for. + * @returns {Token|null} The Block comment token containing the JSDoc comment + * for the given node or null if not found. + * @public + * @deprecated + */ + getJSDocComment(node) { + + /** + * Checks for the presence of a JSDoc comment for the given node and returns it. + * @param {ASTNode} astNode The AST node to get the comment for. + * @returns {Token|null} The Block comment token containing the JSDoc comment + * for the given node or null if not found. + * @private + */ + const findJSDocComment = astNode => { + const tokenBefore = this.getTokenBefore(astNode, { includeComments: true }); + + if ( + tokenBefore && + isCommentToken$1(tokenBefore) && + tokenBefore.type === "Block" && + tokenBefore.value.charAt(0) === "*" && + astNode.loc.start.line - tokenBefore.loc.end.line <= 1 + ) { + return tokenBefore; + } + + return null; + }; + let parent = node.parent; + + switch (node.type) { + case "ClassDeclaration": + case "FunctionDeclaration": + return findJSDocComment(looksLikeExport(parent) ? parent : node); + + case "ClassExpression": + return findJSDocComment(parent.parent); + + case "ArrowFunctionExpression": + case "FunctionExpression": + if (parent.type !== "CallExpression" && parent.type !== "NewExpression") { + while ( + !this.getCommentsBefore(parent).length && + !/Function/u.test(parent.type) && + parent.type !== "MethodDefinition" && + parent.type !== "Property" + ) { + parent = parent.parent; + + if (!parent) { + break; + } + } + + if (parent && parent.type !== "FunctionDeclaration" && parent.type !== "Program") { + return findJSDocComment(parent); + } + } + + return findJSDocComment(node); + + // falls through + default: + return null; + } + } + + /** + * Gets the deepest node containing a range index. + * @param {int} index Range index of the desired node. + * @returns {ASTNode} The node if found or null if not found. + * @public + */ + getNodeByRangeIndex(index) { + let result = null; + + traverser.traverse(this.ast, { + visitorKeys: this.visitorKeys, + enter(node) { + if (node.range[0] <= index && index < node.range[1]) { + result = node; + } else { + this.skip(); + } + }, + leave(node) { + if (node === result) { + this.break(); + } + } + }); + + return result; + } + + /** + * Determines if two nodes or tokens have at least one whitespace character + * between them. Order does not matter. Returns false if the given nodes or + * tokens overlap. + * @param {ASTNode|Token} first The first node or token to check between. + * @param {ASTNode|Token} second The second node or token to check between. + * @returns {boolean} True if there is a whitespace character between + * any of the tokens found between the two given nodes or tokens. + * @public + */ + isSpaceBetween(first, second) { + return isSpaceBetween(this, first, second, false); + } + + /** + * Determines if two nodes or tokens have at least one whitespace character + * between them. Order does not matter. Returns false if the given nodes or + * tokens overlap. + * For backward compatibility, this method returns true if there are + * `JSXText` tokens that contain whitespaces between the two. + * @param {ASTNode|Token} first The first node or token to check between. + * @param {ASTNode|Token} second The second node or token to check between. + * @returns {boolean} True if there is a whitespace character between + * any of the tokens found between the two given nodes or tokens. + * @deprecated in favor of isSpaceBetween(). + * @public + */ + isSpaceBetweenTokens(first, second) { + return isSpaceBetween(this, first, second, true); + } + + /** + * Converts a source text index into a (line, column) pair. + * @param {number} index The index of a character in a file + * @returns {Object} A {line, column} location object with a 0-indexed column + * @public + */ + getLocFromIndex(index) { + if (typeof index !== "number") { + throw new TypeError("Expected `index` to be a number."); + } + + if (index < 0 || index > this.text.length) { + throw new RangeError(`Index out of range (requested index ${index}, but source text has length ${this.text.length}).`); + } + + /* + * For an argument of this.text.length, return the location one "spot" past the last character + * of the file. If the last character is a linebreak, the location will be column 0 of the next + * line; otherwise, the location will be in the next column on the same line. + * + * See getIndexFromLoc for the motivation for this special case. + */ + if (index === this.text.length) { + return { line: this.lines.length, column: this.lines[this.lines.length - 1].length }; + } + + /* + * To figure out which line rangeIndex is on, determine the last index at which rangeIndex could + * be inserted into lineIndices to keep the list sorted. + */ + const lineNumber = lodash__default['default'].sortedLastIndex(this.lineStartIndices, index); + + return { line: lineNumber, column: index - this.lineStartIndices[lineNumber - 1] }; + } + + /** + * Converts a (line, column) pair into a range index. + * @param {Object} loc A line/column location + * @param {number} loc.line The line number of the location (1-indexed) + * @param {number} loc.column The column number of the location (0-indexed) + * @returns {number} The range index of the location in the file. + * @public + */ + getIndexFromLoc(loc) { + if (typeof loc !== "object" || typeof loc.line !== "number" || typeof loc.column !== "number") { + throw new TypeError("Expected `loc` to be an object with numeric `line` and `column` properties."); + } + + if (loc.line <= 0) { + throw new RangeError(`Line number out of range (line ${loc.line} requested). Line numbers should be 1-based.`); + } + + if (loc.line > this.lineStartIndices.length) { + throw new RangeError(`Line number out of range (line ${loc.line} requested, but only ${this.lineStartIndices.length} lines present).`); + } + + const lineStartIndex = this.lineStartIndices[loc.line - 1]; + const lineEndIndex = loc.line === this.lineStartIndices.length ? this.text.length : this.lineStartIndices[loc.line]; + const positionIndex = lineStartIndex + loc.column; + + /* + * By design, getIndexFromLoc({ line: lineNum, column: 0 }) should return the start index of + * the given line, provided that the line number is valid element of this.lines. Since the + * last element of this.lines is an empty string for files with trailing newlines, add a + * special case where getting the index for the first location after the end of the file + * will return the length of the file, rather than throwing an error. This allows rules to + * use getIndexFromLoc consistently without worrying about edge cases at the end of a file. + */ + if ( + loc.line === this.lineStartIndices.length && positionIndex > lineEndIndex || + loc.line < this.lineStartIndices.length && positionIndex >= lineEndIndex + ) { + throw new RangeError(`Column number out of range (column ${loc.column} requested, but the length of line ${loc.line} is ${lineEndIndex - lineStartIndex}).`); + } + + return positionIndex; + } +} + +var sourceCode$1 = SourceCode$1; + +var sourceCode = { + SourceCode: sourceCode$1 +}; + +/** + * @fileoverview Helpers to debug for code path analysis. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const debug$6 = require$$0__default['default']("eslint:code-path"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Gets id of a given segment. + * @param {CodePathSegment} segment A segment to get. + * @returns {string} Id of the segment. + */ +/* istanbul ignore next */ +function getId(segment) { // eslint-disable-line jsdoc/require-jsdoc + return segment.id + (segment.reachable ? "" : "!"); +} + +/** + * Get string for the given node and operation. + * @param {ASTNode} node The node to convert. + * @param {"enter" | "exit" | undefined} label The operation label. + * @returns {string} The string representation. + */ +function nodeToString(node, label) { + const suffix = label ? `:${label}` : ""; + + switch (node.type) { + case "Identifier": return `${node.type}${suffix} (${node.name})`; + case "Literal": return `${node.type}${suffix} (${node.value})`; + default: return `${node.type}${suffix}`; + } +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +var debugHelpers = { + + /** + * A flag that debug dumping is enabled or not. + * @type {boolean} + */ + enabled: debug$6.enabled, + + /** + * Dumps given objects. + * @param {...any} args objects to dump. + * @returns {void} + */ + dump: debug$6, + + /** + * Dumps the current analyzing state. + * @param {ASTNode} node A node to dump. + * @param {CodePathState} state A state to dump. + * @param {boolean} leaving A flag whether or not it's leaving + * @returns {void} + */ + dumpState: !debug$6.enabled ? debug$6 : /* istanbul ignore next */ function(node, state, leaving) { + for (let i = 0; i < state.currentSegments.length; ++i) { + const segInternal = state.currentSegments[i].internal; + + if (leaving) { + const last = segInternal.nodes.length - 1; + + if (last >= 0 && segInternal.nodes[last] === nodeToString(node, "enter")) { + segInternal.nodes[last] = nodeToString(node, void 0); + } else { + segInternal.nodes.push(nodeToString(node, "exit")); + } + } else { + segInternal.nodes.push(nodeToString(node, "enter")); + } + } + + debug$6([ + `${state.currentSegments.map(getId).join(",")})`, + `${node.type}${leaving ? ":exit" : ""}` + ].join(" ")); + }, + + /** + * Dumps a DOT code of a given code path. + * The DOT code can be visualized with Graphvis. + * @param {CodePath} codePath A code path to dump. + * @returns {void} + * @see http://www.graphviz.org + * @see http://www.webgraphviz.com + */ + dumpDot: !debug$6.enabled ? debug$6 : /* istanbul ignore next */ function(codePath) { + let text = + "\n" + + "digraph {\n" + + "node[shape=box,style=\"rounded,filled\",fillcolor=white];\n" + + "initial[label=\"\",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];\n"; + + if (codePath.returnedSegments.length > 0) { + text += "final[label=\"\",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];\n"; + } + if (codePath.thrownSegments.length > 0) { + text += "thrown[label=\"✘\",shape=circle,width=0.3,height=0.3,fixedsize];\n"; + } + + const traceMap = Object.create(null); + const arrows = this.makeDotArrows(codePath, traceMap); + + for (const id in traceMap) { // eslint-disable-line guard-for-in + const segment = traceMap[id]; + + text += `${id}[`; + + if (segment.reachable) { + text += "label=\""; + } else { + text += "style=\"rounded,dashed,filled\",fillcolor=\"#FF9800\",label=\"<>\\n"; + } + + if (segment.internal.nodes.length > 0) { + text += segment.internal.nodes.join("\\n"); + } else { + text += "????"; + } + + text += "\"];\n"; + } + + text += `${arrows}\n`; + text += "}"; + debug$6("DOT", text); + }, + + /** + * Makes a DOT code of a given code path. + * The DOT code can be visualized with Graphvis. + * @param {CodePath} codePath A code path to make DOT. + * @param {Object} traceMap Optional. A map to check whether or not segments had been done. + * @returns {string} A DOT code of the code path. + */ + makeDotArrows(codePath, traceMap) { + const stack = [[codePath.initialSegment, 0]]; + const done = traceMap || Object.create(null); + let lastId = codePath.initialSegment.id; + let text = `initial->${codePath.initialSegment.id}`; + + while (stack.length > 0) { + const item = stack.pop(); + const segment = item[0]; + const index = item[1]; + + if (done[segment.id] && index === 0) { + continue; + } + done[segment.id] = segment; + + const nextSegment = segment.allNextSegments[index]; + + if (!nextSegment) { + continue; + } + + if (lastId === segment.id) { + text += `->${nextSegment.id}`; + } else { + text += `;\n${segment.id}->${nextSegment.id}`; + } + lastId = nextSegment.id; + + stack.unshift([segment, 1 + index]); + stack.push([nextSegment, 0]); + } + + codePath.returnedSegments.forEach(finalSegment => { + if (lastId === finalSegment.id) { + text += "->final"; + } else { + text += `;\n${finalSegment.id}->final`; + } + lastId = null; + }); + + codePath.thrownSegments.forEach(finalSegment => { + if (lastId === finalSegment.id) { + text += "->thrown"; + } else { + text += `;\n${finalSegment.id}->thrown`; + } + lastId = null; + }); + + return `${text};`; + } +}; + +/** + * @fileoverview A class of the code path segment. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a given segment is reachable. + * @param {CodePathSegment} segment A segment to check. + * @returns {boolean} `true` if the segment is reachable. + */ +function isReachable$5(segment) { + return segment.reachable; +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * A code path segment. + */ +class CodePathSegment { + + // eslint-disable-next-line jsdoc/require-description + /** + * @param {string} id An identifier. + * @param {CodePathSegment[]} allPrevSegments An array of the previous segments. + * This array includes unreachable segments. + * @param {boolean} reachable A flag which shows this is reachable. + */ + constructor(id, allPrevSegments, reachable) { + + /** + * The identifier of this code path. + * Rules use it to store additional information of each rule. + * @type {string} + */ + this.id = id; + + /** + * An array of the next segments. + * @type {CodePathSegment[]} + */ + this.nextSegments = []; + + /** + * An array of the previous segments. + * @type {CodePathSegment[]} + */ + this.prevSegments = allPrevSegments.filter(isReachable$5); + + /** + * An array of the next segments. + * This array includes unreachable segments. + * @type {CodePathSegment[]} + */ + this.allNextSegments = []; + + /** + * An array of the previous segments. + * This array includes unreachable segments. + * @type {CodePathSegment[]} + */ + this.allPrevSegments = allPrevSegments; + + /** + * A flag which shows this is reachable. + * @type {boolean} + */ + this.reachable = reachable; + + // Internal data. + Object.defineProperty(this, "internal", { + value: { + used: false, + loopedPrevSegments: [] + } + }); + + /* istanbul ignore if */ + if (debugHelpers.enabled) { + this.internal.nodes = []; + } + } + + /** + * Checks a given previous segment is coming from the end of a loop. + * @param {CodePathSegment} segment A previous segment to check. + * @returns {boolean} `true` if the segment is coming from the end of a loop. + */ + isLoopedPrevSegment(segment) { + return this.internal.loopedPrevSegments.indexOf(segment) !== -1; + } + + /** + * Creates the root segment. + * @param {string} id An identifier. + * @returns {CodePathSegment} The created segment. + */ + static newRoot(id) { + return new CodePathSegment(id, [], true); + } + + /** + * Creates a segment that follows given segments. + * @param {string} id An identifier. + * @param {CodePathSegment[]} allPrevSegments An array of the previous segments. + * @returns {CodePathSegment} The created segment. + */ + static newNext(id, allPrevSegments) { + return new CodePathSegment( + id, + CodePathSegment.flattenUnusedSegments(allPrevSegments), + allPrevSegments.some(isReachable$5) + ); + } + + /** + * Creates an unreachable segment that follows given segments. + * @param {string} id An identifier. + * @param {CodePathSegment[]} allPrevSegments An array of the previous segments. + * @returns {CodePathSegment} The created segment. + */ + static newUnreachable(id, allPrevSegments) { + const segment = new CodePathSegment(id, CodePathSegment.flattenUnusedSegments(allPrevSegments), false); + + /* + * In `if (a) return a; foo();` case, the unreachable segment preceded by + * the return statement is not used but must not be remove. + */ + CodePathSegment.markUsed(segment); + + return segment; + } + + /** + * Creates a segment that follows given segments. + * This factory method does not connect with `allPrevSegments`. + * But this inherits `reachable` flag. + * @param {string} id An identifier. + * @param {CodePathSegment[]} allPrevSegments An array of the previous segments. + * @returns {CodePathSegment} The created segment. + */ + static newDisconnected(id, allPrevSegments) { + return new CodePathSegment(id, [], allPrevSegments.some(isReachable$5)); + } + + /** + * Makes a given segment being used. + * + * And this function registers the segment into the previous segments as a next. + * @param {CodePathSegment} segment A segment to mark. + * @returns {void} + */ + static markUsed(segment) { + if (segment.internal.used) { + return; + } + segment.internal.used = true; + + let i; + + if (segment.reachable) { + for (i = 0; i < segment.allPrevSegments.length; ++i) { + const prevSegment = segment.allPrevSegments[i]; + + prevSegment.allNextSegments.push(segment); + prevSegment.nextSegments.push(segment); + } + } else { + for (i = 0; i < segment.allPrevSegments.length; ++i) { + segment.allPrevSegments[i].allNextSegments.push(segment); + } + } + } + + /** + * Marks a previous segment as looped. + * @param {CodePathSegment} segment A segment. + * @param {CodePathSegment} prevSegment A previous segment to mark. + * @returns {void} + */ + static markPrevSegmentAsLooped(segment, prevSegment) { + segment.internal.loopedPrevSegments.push(prevSegment); + } + + /** + * Replaces unused segments with the previous segments of each unused segment. + * @param {CodePathSegment[]} segments An array of segments to replace. + * @returns {CodePathSegment[]} The replaced array. + */ + static flattenUnusedSegments(segments) { + const done = Object.create(null); + const retv = []; + + for (let i = 0; i < segments.length; ++i) { + const segment = segments[i]; + + // Ignores duplicated. + if (done[segment.id]) { + continue; + } + + // Use previous segments if unused. + if (!segment.internal.used) { + for (let j = 0; j < segment.allPrevSegments.length; ++j) { + const prevSegment = segment.allPrevSegments[j]; + + if (!done[prevSegment.id]) { + done[prevSegment.id] = true; + retv.push(prevSegment); + } + } + } else { + done[segment.id] = true; + retv.push(segment); + } + } + + return retv; + } +} + +var codePathSegment = CodePathSegment; + +/** + * @fileoverview A class to operate forking. + * + * This is state of forking. + * This has a fork list and manages it. + * + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Gets whether or not a given segment is reachable. + * @param {CodePathSegment} segment A segment to get. + * @returns {boolean} `true` if the segment is reachable. + */ +function isReachable$4(segment) { + return segment.reachable; +} + +/** + * Creates new segments from the specific range of `context.segmentsList`. + * + * When `context.segmentsList` is `[[a, b], [c, d], [e, f]]`, `begin` is `0`, and + * `end` is `-1`, this creates `[g, h]`. This `g` is from `a`, `c`, and `e`. + * This `h` is from `b`, `d`, and `f`. + * @param {ForkContext} context An instance. + * @param {number} begin The first index of the previous segments. + * @param {number} end The last index of the previous segments. + * @param {Function} create A factory function of new segments. + * @returns {CodePathSegment[]} New segments. + */ +function makeSegments(context, begin, end, create) { + const list = context.segmentsList; + + const normalizedBegin = begin >= 0 ? begin : list.length + begin; + const normalizedEnd = end >= 0 ? end : list.length + end; + + const segments = []; + + for (let i = 0; i < context.count; ++i) { + const allPrevSegments = []; + + for (let j = normalizedBegin; j <= normalizedEnd; ++j) { + allPrevSegments.push(list[j][i]); + } + + segments.push(create(context.idGenerator.next(), allPrevSegments)); + } + + return segments; +} + +/** + * `segments` becomes doubly in a `finally` block. Then if a code path exits by a + * control statement (such as `break`, `continue`) from the `finally` block, the + * destination's segments may be half of the source segments. In that case, this + * merges segments. + * @param {ForkContext} context An instance. + * @param {CodePathSegment[]} segments Segments to merge. + * @returns {CodePathSegment[]} The merged segments. + */ +function mergeExtraSegments(context, segments) { + let currentSegments = segments; + + while (currentSegments.length > context.count) { + const merged = []; + + for (let i = 0, length = currentSegments.length / 2 | 0; i < length; ++i) { + merged.push(codePathSegment.newNext( + context.idGenerator.next(), + [currentSegments[i], currentSegments[i + length]] + )); + } + currentSegments = merged; + } + return currentSegments; +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * A class to manage forking. + */ +class ForkContext { + + // eslint-disable-next-line jsdoc/require-description + /** + * @param {IdGenerator} idGenerator An identifier generator for segments. + * @param {ForkContext|null} upper An upper fork context. + * @param {number} count A number of parallel segments. + */ + constructor(idGenerator, upper, count) { + this.idGenerator = idGenerator; + this.upper = upper; + this.count = count; + this.segmentsList = []; + } + + /** + * The head segments. + * @type {CodePathSegment[]} + */ + get head() { + const list = this.segmentsList; + + return list.length === 0 ? [] : list[list.length - 1]; + } + + /** + * A flag which shows empty. + * @type {boolean} + */ + get empty() { + return this.segmentsList.length === 0; + } + + /** + * A flag which shows reachable. + * @type {boolean} + */ + get reachable() { + const segments = this.head; + + return segments.length > 0 && segments.some(isReachable$4); + } + + /** + * Creates new segments from this context. + * @param {number} begin The first index of previous segments. + * @param {number} end The last index of previous segments. + * @returns {CodePathSegment[]} New segments. + */ + makeNext(begin, end) { + return makeSegments(this, begin, end, codePathSegment.newNext); + } + + /** + * Creates new segments from this context. + * The new segments is always unreachable. + * @param {number} begin The first index of previous segments. + * @param {number} end The last index of previous segments. + * @returns {CodePathSegment[]} New segments. + */ + makeUnreachable(begin, end) { + return makeSegments(this, begin, end, codePathSegment.newUnreachable); + } + + /** + * Creates new segments from this context. + * The new segments don't have connections for previous segments. + * But these inherit the reachable flag from this context. + * @param {number} begin The first index of previous segments. + * @param {number} end The last index of previous segments. + * @returns {CodePathSegment[]} New segments. + */ + makeDisconnected(begin, end) { + return makeSegments(this, begin, end, codePathSegment.newDisconnected); + } + + /** + * Adds segments into this context. + * The added segments become the head. + * @param {CodePathSegment[]} segments Segments to add. + * @returns {void} + */ + add(segments) { + assert__default['default'](segments.length >= this.count, `${segments.length} >= ${this.count}`); + + this.segmentsList.push(mergeExtraSegments(this, segments)); + } + + /** + * Replaces the head segments with given segments. + * The current head segments are removed. + * @param {CodePathSegment[]} segments Segments to add. + * @returns {void} + */ + replaceHead(segments) { + assert__default['default'](segments.length >= this.count, `${segments.length} >= ${this.count}`); + + this.segmentsList.splice(-1, 1, mergeExtraSegments(this, segments)); + } + + /** + * Adds all segments of a given fork context into this context. + * @param {ForkContext} context A fork context to add. + * @returns {void} + */ + addAll(context) { + assert__default['default'](context.count === this.count); + + const source = context.segmentsList; + + for (let i = 0; i < source.length; ++i) { + this.segmentsList.push(source[i]); + } + } + + /** + * Clears all segments in this context. + * @returns {void} + */ + clear() { + this.segmentsList = []; + } + + /** + * Creates the root fork context. + * @param {IdGenerator} idGenerator An identifier generator for segments. + * @returns {ForkContext} New fork context. + */ + static newRoot(idGenerator) { + const context = new ForkContext(idGenerator, null, 1); + + context.add([codePathSegment.newRoot(idGenerator.next())]); + + return context; + } + + /** + * Creates an empty fork context preceded by a given context. + * @param {ForkContext} parentContext The parent fork context. + * @param {boolean} forkLeavingPath A flag which shows inside of `finally` block. + * @returns {ForkContext} New fork context. + */ + static newEmpty(parentContext, forkLeavingPath) { + return new ForkContext( + parentContext.idGenerator, + parentContext, + (forkLeavingPath ? 2 : 1) * parentContext.count + ); + } +} + +var forkContext = ForkContext; + +/** + * @fileoverview A class to manage state of generating a code path. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Adds given segments into the `dest` array. + * If the `others` array does not includes the given segments, adds to the `all` + * array as well. + * + * This adds only reachable and used segments. + * @param {CodePathSegment[]} dest A destination array (`returnedSegments` or `thrownSegments`). + * @param {CodePathSegment[]} others Another destination array (`returnedSegments` or `thrownSegments`). + * @param {CodePathSegment[]} all The unified destination array (`finalSegments`). + * @param {CodePathSegment[]} segments Segments to add. + * @returns {void} + */ +function addToReturnedOrThrown(dest, others, all, segments) { + for (let i = 0; i < segments.length; ++i) { + const segment = segments[i]; + + dest.push(segment); + if (others.indexOf(segment) === -1) { + all.push(segment); + } + } +} + +/** + * Gets a loop-context for a `continue` statement. + * @param {CodePathState} state A state to get. + * @param {string} label The label of a `continue` statement. + * @returns {LoopContext} A loop-context for a `continue` statement. + */ +function getContinueContext(state, label) { + if (!label) { + return state.loopContext; + } + + let context = state.loopContext; + + while (context) { + if (context.label === label) { + return context; + } + context = context.upper; + } + + /* istanbul ignore next: foolproof (syntax error) */ + return null; +} + +/** + * Gets a context for a `break` statement. + * @param {CodePathState} state A state to get. + * @param {string} label The label of a `break` statement. + * @returns {LoopContext|SwitchContext} A context for a `break` statement. + */ +function getBreakContext(state, label) { + let context = state.breakContext; + + while (context) { + if (label ? context.label === label : context.breakable) { + return context; + } + context = context.upper; + } + + /* istanbul ignore next: foolproof (syntax error) */ + return null; +} + +/** + * Gets a context for a `return` statement. + * @param {CodePathState} state A state to get. + * @returns {TryContext|CodePathState} A context for a `return` statement. + */ +function getReturnContext(state) { + let context = state.tryContext; + + while (context) { + if (context.hasFinalizer && context.position !== "finally") { + return context; + } + context = context.upper; + } + + return state; +} + +/** + * Gets a context for a `throw` statement. + * @param {CodePathState} state A state to get. + * @returns {TryContext|CodePathState} A context for a `throw` statement. + */ +function getThrowContext(state) { + let context = state.tryContext; + + while (context) { + if (context.position === "try" || + (context.hasFinalizer && context.position === "catch") + ) { + return context; + } + context = context.upper; + } + + return state; +} + +/** + * Removes a given element from a given array. + * @param {any[]} xs An array to remove the specific element. + * @param {any} x An element to be removed. + * @returns {void} + */ +function remove$1(xs, x) { + xs.splice(xs.indexOf(x), 1); +} + +/** + * Disconnect given segments. + * + * This is used in a process for switch statements. + * If there is the "default" chunk before other cases, the order is different + * between node's and running's. + * @param {CodePathSegment[]} prevSegments Forward segments to disconnect. + * @param {CodePathSegment[]} nextSegments Backward segments to disconnect. + * @returns {void} + */ +function removeConnection(prevSegments, nextSegments) { + for (let i = 0; i < prevSegments.length; ++i) { + const prevSegment = prevSegments[i]; + const nextSegment = nextSegments[i]; + + remove$1(prevSegment.nextSegments, nextSegment); + remove$1(prevSegment.allNextSegments, nextSegment); + remove$1(nextSegment.prevSegments, prevSegment); + remove$1(nextSegment.allPrevSegments, prevSegment); + } +} + +/** + * Creates looping path. + * @param {CodePathState} state The instance. + * @param {CodePathSegment[]} unflattenedFromSegments Segments which are source. + * @param {CodePathSegment[]} unflattenedToSegments Segments which are destination. + * @returns {void} + */ +function makeLooped(state, unflattenedFromSegments, unflattenedToSegments) { + const fromSegments = codePathSegment.flattenUnusedSegments(unflattenedFromSegments); + const toSegments = codePathSegment.flattenUnusedSegments(unflattenedToSegments); + + const end = Math.min(fromSegments.length, toSegments.length); + + for (let i = 0; i < end; ++i) { + const fromSegment = fromSegments[i]; + const toSegment = toSegments[i]; + + if (toSegment.reachable) { + fromSegment.nextSegments.push(toSegment); + } + if (fromSegment.reachable) { + toSegment.prevSegments.push(fromSegment); + } + fromSegment.allNextSegments.push(toSegment); + toSegment.allPrevSegments.push(fromSegment); + + if (toSegment.allPrevSegments.length >= 2) { + codePathSegment.markPrevSegmentAsLooped(toSegment, fromSegment); + } + + state.notifyLooped(fromSegment, toSegment); + } +} + +/** + * Finalizes segments of `test` chunk of a ForStatement. + * + * - Adds `false` paths to paths which are leaving from the loop. + * - Sets `true` paths to paths which go to the body. + * @param {LoopContext} context A loop context to modify. + * @param {ChoiceContext} choiceContext A choice context of this loop. + * @param {CodePathSegment[]} head The current head paths. + * @returns {void} + */ +function finalizeTestSegmentsOfFor(context, choiceContext, head) { + if (!choiceContext.processed) { + choiceContext.trueForkContext.add(head); + choiceContext.falseForkContext.add(head); + choiceContext.qqForkContext.add(head); + } + + if (context.test !== true) { + context.brokenForkContext.addAll(choiceContext.falseForkContext); + } + context.endOfTestSegments = choiceContext.trueForkContext.makeNext(0, -1); +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * A class which manages state to analyze code paths. + */ +class CodePathState { + + // eslint-disable-next-line jsdoc/require-description + /** + * @param {IdGenerator} idGenerator An id generator to generate id for code + * path segments. + * @param {Function} onLooped A callback function to notify looping. + */ + constructor(idGenerator, onLooped) { + this.idGenerator = idGenerator; + this.notifyLooped = onLooped; + this.forkContext = forkContext.newRoot(idGenerator); + this.choiceContext = null; + this.switchContext = null; + this.tryContext = null; + this.loopContext = null; + this.breakContext = null; + this.chainContext = null; + + this.currentSegments = []; + this.initialSegment = this.forkContext.head[0]; + + // returnedSegments and thrownSegments push elements into finalSegments also. + const final = this.finalSegments = []; + const returned = this.returnedForkContext = []; + const thrown = this.thrownForkContext = []; + + returned.add = addToReturnedOrThrown.bind(null, returned, thrown, final); + thrown.add = addToReturnedOrThrown.bind(null, thrown, returned, final); + } + + /** + * The head segments. + * @type {CodePathSegment[]} + */ + get headSegments() { + return this.forkContext.head; + } + + /** + * The parent forking context. + * This is used for the root of new forks. + * @type {ForkContext} + */ + get parentForkContext() { + const current = this.forkContext; + + return current && current.upper; + } + + /** + * Creates and stacks new forking context. + * @param {boolean} forkLeavingPath A flag which shows being in a + * "finally" block. + * @returns {ForkContext} The created context. + */ + pushForkContext(forkLeavingPath) { + this.forkContext = forkContext.newEmpty( + this.forkContext, + forkLeavingPath + ); + + return this.forkContext; + } + + /** + * Pops and merges the last forking context. + * @returns {ForkContext} The last context. + */ + popForkContext() { + const lastContext = this.forkContext; + + this.forkContext = lastContext.upper; + this.forkContext.replaceHead(lastContext.makeNext(0, -1)); + + return lastContext; + } + + /** + * Creates a new path. + * @returns {void} + */ + forkPath() { + this.forkContext.add(this.parentForkContext.makeNext(-1, -1)); + } + + /** + * Creates a bypass path. + * This is used for such as IfStatement which does not have "else" chunk. + * @returns {void} + */ + forkBypassPath() { + this.forkContext.add(this.parentForkContext.head); + } + + //-------------------------------------------------------------------------- + // ConditionalExpression, LogicalExpression, IfStatement + //-------------------------------------------------------------------------- + + /** + * Creates a context for ConditionalExpression, LogicalExpression, AssignmentExpression (logical assignments only), + * IfStatement, WhileStatement, DoWhileStatement, or ForStatement. + * + * LogicalExpressions have cases that it goes different paths between the + * `true` case and the `false` case. + * + * For Example: + * + * if (a || b) { + * foo(); + * } else { + * bar(); + * } + * + * In this case, `b` is evaluated always in the code path of the `else` + * block, but it's not so in the code path of the `if` block. + * So there are 3 paths. + * + * a -> foo(); + * a -> b -> foo(); + * a -> b -> bar(); + * @param {string} kind A kind string. + * If the new context is LogicalExpression's or AssignmentExpression's, this is `"&&"` or `"||"` or `"??"`. + * If it's IfStatement's or ConditionalExpression's, this is `"test"`. + * Otherwise, this is `"loop"`. + * @param {boolean} isForkingAsResult A flag that shows that goes different + * paths between `true` and `false`. + * @returns {void} + */ + pushChoiceContext(kind, isForkingAsResult) { + this.choiceContext = { + upper: this.choiceContext, + kind, + isForkingAsResult, + trueForkContext: forkContext.newEmpty(this.forkContext), + falseForkContext: forkContext.newEmpty(this.forkContext), + qqForkContext: forkContext.newEmpty(this.forkContext), + processed: false + }; + } + + /** + * Pops the last choice context and finalizes it. + * @returns {ChoiceContext} The popped context. + */ + popChoiceContext() { + const context = this.choiceContext; + + this.choiceContext = context.upper; + + const forkContext = this.forkContext; + const headSegments = forkContext.head; + + switch (context.kind) { + case "&&": + case "||": + case "??": + + /* + * If any result were not transferred from child contexts, + * this sets the head segments to both cases. + * The head segments are the path of the right-hand operand. + */ + if (!context.processed) { + context.trueForkContext.add(headSegments); + context.falseForkContext.add(headSegments); + context.qqForkContext.add(headSegments); + } + + /* + * Transfers results to upper context if this context is in + * test chunk. + */ + if (context.isForkingAsResult) { + const parentContext = this.choiceContext; + + parentContext.trueForkContext.addAll(context.trueForkContext); + parentContext.falseForkContext.addAll(context.falseForkContext); + parentContext.qqForkContext.addAll(context.qqForkContext); + parentContext.processed = true; + + return context; + } + + break; + + case "test": + if (!context.processed) { + + /* + * The head segments are the path of the `if` block here. + * Updates the `true` path with the end of the `if` block. + */ + context.trueForkContext.clear(); + context.trueForkContext.add(headSegments); + } else { + + /* + * The head segments are the path of the `else` block here. + * Updates the `false` path with the end of the `else` + * block. + */ + context.falseForkContext.clear(); + context.falseForkContext.add(headSegments); + } + + break; + + case "loop": + + /* + * Loops are addressed in popLoopContext(). + * This is called from popLoopContext(). + */ + return context; + + /* istanbul ignore next */ + default: + throw new Error("unreachable"); + } + + // Merges all paths. + const prevForkContext = context.trueForkContext; + + prevForkContext.addAll(context.falseForkContext); + forkContext.replaceHead(prevForkContext.makeNext(0, -1)); + + return context; + } + + /** + * Makes a code path segment of the right-hand operand of a logical + * expression. + * @returns {void} + */ + makeLogicalRight() { + const context = this.choiceContext; + const forkContext = this.forkContext; + + if (context.processed) { + + /* + * This got segments already from the child choice context. + * Creates the next path from own true/false fork context. + */ + let prevForkContext; + + switch (context.kind) { + case "&&": // if true then go to the right-hand side. + prevForkContext = context.trueForkContext; + break; + case "||": // if false then go to the right-hand side. + prevForkContext = context.falseForkContext; + break; + case "??": // Both true/false can short-circuit, so needs the third path to go to the right-hand side. That's qqForkContext. + prevForkContext = context.qqForkContext; + break; + default: + throw new Error("unreachable"); + } + + forkContext.replaceHead(prevForkContext.makeNext(0, -1)); + prevForkContext.clear(); + context.processed = false; + } else { + + /* + * This did not get segments from the child choice context. + * So addresses the head segments. + * The head segments are the path of the left-hand operand. + */ + switch (context.kind) { + case "&&": // the false path can short-circuit. + context.falseForkContext.add(forkContext.head); + break; + case "||": // the true path can short-circuit. + context.trueForkContext.add(forkContext.head); + break; + case "??": // both can short-circuit. + context.trueForkContext.add(forkContext.head); + context.falseForkContext.add(forkContext.head); + break; + default: + throw new Error("unreachable"); + } + + forkContext.replaceHead(forkContext.makeNext(-1, -1)); + } + } + + /** + * Makes a code path segment of the `if` block. + * @returns {void} + */ + makeIfConsequent() { + const context = this.choiceContext; + const forkContext = this.forkContext; + + /* + * If any result were not transferred from child contexts, + * this sets the head segments to both cases. + * The head segments are the path of the test expression. + */ + if (!context.processed) { + context.trueForkContext.add(forkContext.head); + context.falseForkContext.add(forkContext.head); + context.qqForkContext.add(forkContext.head); + } + + context.processed = false; + + // Creates new path from the `true` case. + forkContext.replaceHead( + context.trueForkContext.makeNext(0, -1) + ); + } + + /** + * Makes a code path segment of the `else` block. + * @returns {void} + */ + makeIfAlternate() { + const context = this.choiceContext; + const forkContext = this.forkContext; + + /* + * The head segments are the path of the `if` block. + * Updates the `true` path with the end of the `if` block. + */ + context.trueForkContext.clear(); + context.trueForkContext.add(forkContext.head); + context.processed = true; + + // Creates new path from the `false` case. + forkContext.replaceHead( + context.falseForkContext.makeNext(0, -1) + ); + } + + //-------------------------------------------------------------------------- + // ChainExpression + //-------------------------------------------------------------------------- + + /** + * Push a new `ChainExpression` context to the stack. + * This method is called on entering to each `ChainExpression` node. + * This context is used to count forking in the optional chain then merge them on the exiting from the `ChainExpression` node. + * @returns {void} + */ + pushChainContext() { + this.chainContext = { + upper: this.chainContext, + countChoiceContexts: 0 + }; + } + + /** + * Pop a `ChainExpression` context from the stack. + * This method is called on exiting from each `ChainExpression` node. + * This merges all forks of the last optional chaining. + * @returns {void} + */ + popChainContext() { + const context = this.chainContext; + + this.chainContext = context.upper; + + // pop all choice contexts of this. + for (let i = context.countChoiceContexts; i > 0; --i) { + this.popChoiceContext(); + } + } + + /** + * Create a choice context for optional access. + * This method is called on entering to each `(Call|Member)Expression[optional=true]` node. + * This creates a choice context as similar to `LogicalExpression[operator="??"]` node. + * @returns {void} + */ + makeOptionalNode() { + if (this.chainContext) { + this.chainContext.countChoiceContexts += 1; + this.pushChoiceContext("??", false); + } + } + + /** + * Create a fork. + * This method is called on entering to the `arguments|property` property of each `(Call|Member)Expression` node. + * @returns {void} + */ + makeOptionalRight() { + if (this.chainContext) { + this.makeLogicalRight(); + } + } + + //-------------------------------------------------------------------------- + // SwitchStatement + //-------------------------------------------------------------------------- + + /** + * Creates a context object of SwitchStatement and stacks it. + * @param {boolean} hasCase `true` if the switch statement has one or more + * case parts. + * @param {string|null} label The label text. + * @returns {void} + */ + pushSwitchContext(hasCase, label) { + this.switchContext = { + upper: this.switchContext, + hasCase, + defaultSegments: null, + defaultBodySegments: null, + foundDefault: false, + lastIsDefault: false, + countForks: 0 + }; + + this.pushBreakContext(true, label); + } + + /** + * Pops the last context of SwitchStatement and finalizes it. + * + * - Disposes all forking stack for `case` and `default`. + * - Creates the next code path segment from `context.brokenForkContext`. + * - If the last `SwitchCase` node is not a `default` part, creates a path + * to the `default` body. + * @returns {void} + */ + popSwitchContext() { + const context = this.switchContext; + + this.switchContext = context.upper; + + const forkContext = this.forkContext; + const brokenForkContext = this.popBreakContext().brokenForkContext; + + if (context.countForks === 0) { + + /* + * When there is only one `default` chunk and there is one or more + * `break` statements, even if forks are nothing, it needs to merge + * those. + */ + if (!brokenForkContext.empty) { + brokenForkContext.add(forkContext.makeNext(-1, -1)); + forkContext.replaceHead(brokenForkContext.makeNext(0, -1)); + } + + return; + } + + const lastSegments = forkContext.head; + + this.forkBypassPath(); + const lastCaseSegments = forkContext.head; + + /* + * `brokenForkContext` is used to make the next segment. + * It must add the last segment into `brokenForkContext`. + */ + brokenForkContext.add(lastSegments); + + /* + * A path which is failed in all case test should be connected to path + * of `default` chunk. + */ + if (!context.lastIsDefault) { + if (context.defaultBodySegments) { + + /* + * Remove a link from `default` label to its chunk. + * It's false route. + */ + removeConnection(context.defaultSegments, context.defaultBodySegments); + makeLooped(this, lastCaseSegments, context.defaultBodySegments); + } else { + + /* + * It handles the last case body as broken if `default` chunk + * does not exist. + */ + brokenForkContext.add(lastCaseSegments); + } + } + + // Pops the segment context stack until the entry segment. + for (let i = 0; i < context.countForks; ++i) { + this.forkContext = this.forkContext.upper; + } + + /* + * Creates a path from all brokenForkContext paths. + * This is a path after switch statement. + */ + this.forkContext.replaceHead(brokenForkContext.makeNext(0, -1)); + } + + /** + * Makes a code path segment for a `SwitchCase` node. + * @param {boolean} isEmpty `true` if the body is empty. + * @param {boolean} isDefault `true` if the body is the default case. + * @returns {void} + */ + makeSwitchCaseBody(isEmpty, isDefault) { + const context = this.switchContext; + + if (!context.hasCase) { + return; + } + + /* + * Merge forks. + * The parent fork context has two segments. + * Those are from the current case and the body of the previous case. + */ + const parentForkContext = this.forkContext; + const forkContext = this.pushForkContext(); + + forkContext.add(parentForkContext.makeNext(0, -1)); + + /* + * Save `default` chunk info. + * If the `default` label is not at the last, we must make a path from + * the last `case` to the `default` chunk. + */ + if (isDefault) { + context.defaultSegments = parentForkContext.head; + if (isEmpty) { + context.foundDefault = true; + } else { + context.defaultBodySegments = forkContext.head; + } + } else { + if (!isEmpty && context.foundDefault) { + context.foundDefault = false; + context.defaultBodySegments = forkContext.head; + } + } + + context.lastIsDefault = isDefault; + context.countForks += 1; + } + + //-------------------------------------------------------------------------- + // TryStatement + //-------------------------------------------------------------------------- + + /** + * Creates a context object of TryStatement and stacks it. + * @param {boolean} hasFinalizer `true` if the try statement has a + * `finally` block. + * @returns {void} + */ + pushTryContext(hasFinalizer) { + this.tryContext = { + upper: this.tryContext, + position: "try", + hasFinalizer, + + returnedForkContext: hasFinalizer + ? forkContext.newEmpty(this.forkContext) + : null, + + thrownForkContext: forkContext.newEmpty(this.forkContext), + lastOfTryIsReachable: false, + lastOfCatchIsReachable: false + }; + } + + /** + * Pops the last context of TryStatement and finalizes it. + * @returns {void} + */ + popTryContext() { + const context = this.tryContext; + + this.tryContext = context.upper; + + if (context.position === "catch") { + + // Merges two paths from the `try` block and `catch` block merely. + this.popForkContext(); + return; + } + + /* + * The following process is executed only when there is the `finally` + * block. + */ + + const returned = context.returnedForkContext; + const thrown = context.thrownForkContext; + + if (returned.empty && thrown.empty) { + return; + } + + // Separate head to normal paths and leaving paths. + const headSegments = this.forkContext.head; + + this.forkContext = this.forkContext.upper; + const normalSegments = headSegments.slice(0, headSegments.length / 2 | 0); + const leavingSegments = headSegments.slice(headSegments.length / 2 | 0); + + // Forwards the leaving path to upper contexts. + if (!returned.empty) { + getReturnContext(this).returnedForkContext.add(leavingSegments); + } + if (!thrown.empty) { + getThrowContext(this).thrownForkContext.add(leavingSegments); + } + + // Sets the normal path as the next. + this.forkContext.replaceHead(normalSegments); + + /* + * If both paths of the `try` block and the `catch` block are + * unreachable, the next path becomes unreachable as well. + */ + if (!context.lastOfTryIsReachable && !context.lastOfCatchIsReachable) { + this.forkContext.makeUnreachable(); + } + } + + /** + * Makes a code path segment for a `catch` block. + * @returns {void} + */ + makeCatchBlock() { + const context = this.tryContext; + const forkContext$1 = this.forkContext; + const thrown = context.thrownForkContext; + + // Update state. + context.position = "catch"; + context.thrownForkContext = forkContext.newEmpty(forkContext$1); + context.lastOfTryIsReachable = forkContext$1.reachable; + + // Merge thrown paths. + thrown.add(forkContext$1.head); + const thrownSegments = thrown.makeNext(0, -1); + + // Fork to a bypass and the merged thrown path. + this.pushForkContext(); + this.forkBypassPath(); + this.forkContext.add(thrownSegments); + } + + /** + * Makes a code path segment for a `finally` block. + * + * In the `finally` block, parallel paths are created. The parallel paths + * are used as leaving-paths. The leaving-paths are paths from `return` + * statements and `throw` statements in a `try` block or a `catch` block. + * @returns {void} + */ + makeFinallyBlock() { + const context = this.tryContext; + let forkContext = this.forkContext; + const returned = context.returnedForkContext; + const thrown = context.thrownForkContext; + const headOfLeavingSegments = forkContext.head; + + // Update state. + if (context.position === "catch") { + + // Merges two paths from the `try` block and `catch` block. + this.popForkContext(); + forkContext = this.forkContext; + + context.lastOfCatchIsReachable = forkContext.reachable; + } else { + context.lastOfTryIsReachable = forkContext.reachable; + } + context.position = "finally"; + + if (returned.empty && thrown.empty) { + + // This path does not leave. + return; + } + + /* + * Create a parallel segment from merging returned and thrown. + * This segment will leave at the end of this finally block. + */ + const segments = forkContext.makeNext(-1, -1); + + for (let i = 0; i < forkContext.count; ++i) { + const prevSegsOfLeavingSegment = [headOfLeavingSegments[i]]; + + for (let j = 0; j < returned.segmentsList.length; ++j) { + prevSegsOfLeavingSegment.push(returned.segmentsList[j][i]); + } + for (let j = 0; j < thrown.segmentsList.length; ++j) { + prevSegsOfLeavingSegment.push(thrown.segmentsList[j][i]); + } + + segments.push( + codePathSegment.newNext( + this.idGenerator.next(), + prevSegsOfLeavingSegment + ) + ); + } + + this.pushForkContext(true); + this.forkContext.add(segments); + } + + /** + * Makes a code path segment from the first throwable node to the `catch` + * block or the `finally` block. + * @returns {void} + */ + makeFirstThrowablePathInTryBlock() { + const forkContext = this.forkContext; + + if (!forkContext.reachable) { + return; + } + + const context = getThrowContext(this); + + if (context === this || + context.position !== "try" || + !context.thrownForkContext.empty + ) { + return; + } + + context.thrownForkContext.add(forkContext.head); + forkContext.replaceHead(forkContext.makeNext(-1, -1)); + } + + //-------------------------------------------------------------------------- + // Loop Statements + //-------------------------------------------------------------------------- + + /** + * Creates a context object of a loop statement and stacks it. + * @param {string} type The type of the node which was triggered. One of + * `WhileStatement`, `DoWhileStatement`, `ForStatement`, `ForInStatement`, + * and `ForStatement`. + * @param {string|null} label A label of the node which was triggered. + * @returns {void} + */ + pushLoopContext(type, label) { + const forkContext$1 = this.forkContext; + const breakContext = this.pushBreakContext(true, label); + + switch (type) { + case "WhileStatement": + this.pushChoiceContext("loop", false); + this.loopContext = { + upper: this.loopContext, + type, + label, + test: void 0, + continueDestSegments: null, + brokenForkContext: breakContext.brokenForkContext + }; + break; + + case "DoWhileStatement": + this.pushChoiceContext("loop", false); + this.loopContext = { + upper: this.loopContext, + type, + label, + test: void 0, + entrySegments: null, + continueForkContext: forkContext.newEmpty(forkContext$1), + brokenForkContext: breakContext.brokenForkContext + }; + break; + + case "ForStatement": + this.pushChoiceContext("loop", false); + this.loopContext = { + upper: this.loopContext, + type, + label, + test: void 0, + endOfInitSegments: null, + testSegments: null, + endOfTestSegments: null, + updateSegments: null, + endOfUpdateSegments: null, + continueDestSegments: null, + brokenForkContext: breakContext.brokenForkContext + }; + break; + + case "ForInStatement": + case "ForOfStatement": + this.loopContext = { + upper: this.loopContext, + type, + label, + prevSegments: null, + leftSegments: null, + endOfLeftSegments: null, + continueDestSegments: null, + brokenForkContext: breakContext.brokenForkContext + }; + break; + + /* istanbul ignore next */ + default: + throw new Error(`unknown type: "${type}"`); + } + } + + /** + * Pops the last context of a loop statement and finalizes it. + * @returns {void} + */ + popLoopContext() { + const context = this.loopContext; + + this.loopContext = context.upper; + + const forkContext = this.forkContext; + const brokenForkContext = this.popBreakContext().brokenForkContext; + + // Creates a looped path. + switch (context.type) { + case "WhileStatement": + case "ForStatement": + this.popChoiceContext(); + makeLooped( + this, + forkContext.head, + context.continueDestSegments + ); + break; + + case "DoWhileStatement": { + const choiceContext = this.popChoiceContext(); + + if (!choiceContext.processed) { + choiceContext.trueForkContext.add(forkContext.head); + choiceContext.falseForkContext.add(forkContext.head); + } + if (context.test !== true) { + brokenForkContext.addAll(choiceContext.falseForkContext); + } + + // `true` paths go to looping. + const segmentsList = choiceContext.trueForkContext.segmentsList; + + for (let i = 0; i < segmentsList.length; ++i) { + makeLooped( + this, + segmentsList[i], + context.entrySegments + ); + } + break; + } + + case "ForInStatement": + case "ForOfStatement": + brokenForkContext.add(forkContext.head); + makeLooped( + this, + forkContext.head, + context.leftSegments + ); + break; + + /* istanbul ignore next */ + default: + throw new Error("unreachable"); + } + + // Go next. + if (brokenForkContext.empty) { + forkContext.replaceHead(forkContext.makeUnreachable(-1, -1)); + } else { + forkContext.replaceHead(brokenForkContext.makeNext(0, -1)); + } + } + + /** + * Makes a code path segment for the test part of a WhileStatement. + * @param {boolean|undefined} test The test value (only when constant). + * @returns {void} + */ + makeWhileTest(test) { + const context = this.loopContext; + const forkContext = this.forkContext; + const testSegments = forkContext.makeNext(0, -1); + + // Update state. + context.test = test; + context.continueDestSegments = testSegments; + forkContext.replaceHead(testSegments); + } + + /** + * Makes a code path segment for the body part of a WhileStatement. + * @returns {void} + */ + makeWhileBody() { + const context = this.loopContext; + const choiceContext = this.choiceContext; + const forkContext = this.forkContext; + + if (!choiceContext.processed) { + choiceContext.trueForkContext.add(forkContext.head); + choiceContext.falseForkContext.add(forkContext.head); + } + + // Update state. + if (context.test !== true) { + context.brokenForkContext.addAll(choiceContext.falseForkContext); + } + forkContext.replaceHead(choiceContext.trueForkContext.makeNext(0, -1)); + } + + /** + * Makes a code path segment for the body part of a DoWhileStatement. + * @returns {void} + */ + makeDoWhileBody() { + const context = this.loopContext; + const forkContext = this.forkContext; + const bodySegments = forkContext.makeNext(-1, -1); + + // Update state. + context.entrySegments = bodySegments; + forkContext.replaceHead(bodySegments); + } + + /** + * Makes a code path segment for the test part of a DoWhileStatement. + * @param {boolean|undefined} test The test value (only when constant). + * @returns {void} + */ + makeDoWhileTest(test) { + const context = this.loopContext; + const forkContext = this.forkContext; + + context.test = test; + + // Creates paths of `continue` statements. + if (!context.continueForkContext.empty) { + context.continueForkContext.add(forkContext.head); + const testSegments = context.continueForkContext.makeNext(0, -1); + + forkContext.replaceHead(testSegments); + } + } + + /** + * Makes a code path segment for the test part of a ForStatement. + * @param {boolean|undefined} test The test value (only when constant). + * @returns {void} + */ + makeForTest(test) { + const context = this.loopContext; + const forkContext = this.forkContext; + const endOfInitSegments = forkContext.head; + const testSegments = forkContext.makeNext(-1, -1); + + // Update state. + context.test = test; + context.endOfInitSegments = endOfInitSegments; + context.continueDestSegments = context.testSegments = testSegments; + forkContext.replaceHead(testSegments); + } + + /** + * Makes a code path segment for the update part of a ForStatement. + * @returns {void} + */ + makeForUpdate() { + const context = this.loopContext; + const choiceContext = this.choiceContext; + const forkContext = this.forkContext; + + // Make the next paths of the test. + if (context.testSegments) { + finalizeTestSegmentsOfFor( + context, + choiceContext, + forkContext.head + ); + } else { + context.endOfInitSegments = forkContext.head; + } + + // Update state. + const updateSegments = forkContext.makeDisconnected(-1, -1); + + context.continueDestSegments = context.updateSegments = updateSegments; + forkContext.replaceHead(updateSegments); + } + + /** + * Makes a code path segment for the body part of a ForStatement. + * @returns {void} + */ + makeForBody() { + const context = this.loopContext; + const choiceContext = this.choiceContext; + const forkContext$1 = this.forkContext; + + // Update state. + if (context.updateSegments) { + context.endOfUpdateSegments = forkContext$1.head; + + // `update` -> `test` + if (context.testSegments) { + makeLooped( + this, + context.endOfUpdateSegments, + context.testSegments + ); + } + } else if (context.testSegments) { + finalizeTestSegmentsOfFor( + context, + choiceContext, + forkContext$1.head + ); + } else { + context.endOfInitSegments = forkContext$1.head; + } + + let bodySegments = context.endOfTestSegments; + + if (!bodySegments) { + + /* + * If there is not the `test` part, the `body` path comes from the + * `init` part and the `update` part. + */ + const prevForkContext = forkContext.newEmpty(forkContext$1); + + prevForkContext.add(context.endOfInitSegments); + if (context.endOfUpdateSegments) { + prevForkContext.add(context.endOfUpdateSegments); + } + + bodySegments = prevForkContext.makeNext(0, -1); + } + context.continueDestSegments = context.continueDestSegments || bodySegments; + forkContext$1.replaceHead(bodySegments); + } + + /** + * Makes a code path segment for the left part of a ForInStatement and a + * ForOfStatement. + * @returns {void} + */ + makeForInOfLeft() { + const context = this.loopContext; + const forkContext = this.forkContext; + const leftSegments = forkContext.makeDisconnected(-1, -1); + + // Update state. + context.prevSegments = forkContext.head; + context.leftSegments = context.continueDestSegments = leftSegments; + forkContext.replaceHead(leftSegments); + } + + /** + * Makes a code path segment for the right part of a ForInStatement and a + * ForOfStatement. + * @returns {void} + */ + makeForInOfRight() { + const context = this.loopContext; + const forkContext$1 = this.forkContext; + const temp = forkContext.newEmpty(forkContext$1); + + temp.add(context.prevSegments); + const rightSegments = temp.makeNext(-1, -1); + + // Update state. + context.endOfLeftSegments = forkContext$1.head; + forkContext$1.replaceHead(rightSegments); + } + + /** + * Makes a code path segment for the body part of a ForInStatement and a + * ForOfStatement. + * @returns {void} + */ + makeForInOfBody() { + const context = this.loopContext; + const forkContext$1 = this.forkContext; + const temp = forkContext.newEmpty(forkContext$1); + + temp.add(context.endOfLeftSegments); + const bodySegments = temp.makeNext(-1, -1); + + // Make a path: `right` -> `left`. + makeLooped(this, forkContext$1.head, context.leftSegments); + + // Update state. + context.brokenForkContext.add(forkContext$1.head); + forkContext$1.replaceHead(bodySegments); + } + + //-------------------------------------------------------------------------- + // Control Statements + //-------------------------------------------------------------------------- + + /** + * Creates new context for BreakStatement. + * @param {boolean} breakable The flag to indicate it can break by + * an unlabeled BreakStatement. + * @param {string|null} label The label of this context. + * @returns {Object} The new context. + */ + pushBreakContext(breakable, label) { + this.breakContext = { + upper: this.breakContext, + breakable, + label, + brokenForkContext: forkContext.newEmpty(this.forkContext) + }; + return this.breakContext; + } + + /** + * Removes the top item of the break context stack. + * @returns {Object} The removed context. + */ + popBreakContext() { + const context = this.breakContext; + const forkContext = this.forkContext; + + this.breakContext = context.upper; + + // Process this context here for other than switches and loops. + if (!context.breakable) { + const brokenForkContext = context.brokenForkContext; + + if (!brokenForkContext.empty) { + brokenForkContext.add(forkContext.head); + forkContext.replaceHead(brokenForkContext.makeNext(0, -1)); + } + } + + return context; + } + + /** + * Makes a path for a `break` statement. + * + * It registers the head segment to a context of `break`. + * It makes new unreachable segment, then it set the head with the segment. + * @param {string} label A label of the break statement. + * @returns {void} + */ + makeBreak(label) { + const forkContext = this.forkContext; + + if (!forkContext.reachable) { + return; + } + + const context = getBreakContext(this, label); + + /* istanbul ignore else: foolproof (syntax error) */ + if (context) { + context.brokenForkContext.add(forkContext.head); + } + + forkContext.replaceHead(forkContext.makeUnreachable(-1, -1)); + } + + /** + * Makes a path for a `continue` statement. + * + * It makes a looping path. + * It makes new unreachable segment, then it set the head with the segment. + * @param {string} label A label of the continue statement. + * @returns {void} + */ + makeContinue(label) { + const forkContext = this.forkContext; + + if (!forkContext.reachable) { + return; + } + + const context = getContinueContext(this, label); + + /* istanbul ignore else: foolproof (syntax error) */ + if (context) { + if (context.continueDestSegments) { + makeLooped(this, forkContext.head, context.continueDestSegments); + + // If the context is a for-in/of loop, this effects a break also. + if (context.type === "ForInStatement" || + context.type === "ForOfStatement" + ) { + context.brokenForkContext.add(forkContext.head); + } + } else { + context.continueForkContext.add(forkContext.head); + } + } + forkContext.replaceHead(forkContext.makeUnreachable(-1, -1)); + } + + /** + * Makes a path for a `return` statement. + * + * It registers the head segment to a context of `return`. + * It makes new unreachable segment, then it set the head with the segment. + * @returns {void} + */ + makeReturn() { + const forkContext = this.forkContext; + + if (forkContext.reachable) { + getReturnContext(this).returnedForkContext.add(forkContext.head); + forkContext.replaceHead(forkContext.makeUnreachable(-1, -1)); + } + } + + /** + * Makes a path for a `throw` statement. + * + * It registers the head segment to a context of `throw`. + * It makes new unreachable segment, then it set the head with the segment. + * @returns {void} + */ + makeThrow() { + const forkContext = this.forkContext; + + if (forkContext.reachable) { + getThrowContext(this).thrownForkContext.add(forkContext.head); + forkContext.replaceHead(forkContext.makeUnreachable(-1, -1)); + } + } + + /** + * Makes the final path. + * @returns {void} + */ + makeFinal() { + const segments = this.currentSegments; + + if (segments.length > 0 && segments[0].reachable) { + this.returnedForkContext.add(segments); + } + } +} + +var codePathState = CodePathState; + +/** + * @fileoverview A class of identifiers generator for code path segments. + * + * Each rule uses the identifier of code path segments to store additional + * information of the code path. + * + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * A generator for unique ids. + */ +class IdGenerator { + + // eslint-disable-next-line jsdoc/require-description + /** + * @param {string} prefix Optional. A prefix of generated ids. + */ + constructor(prefix) { + this.prefix = String(prefix); + this.n = 0; + } + + /** + * Generates id. + * @returns {string} A generated id. + */ + next() { + this.n = 1 + this.n | 0; + + /* istanbul ignore if */ + if (this.n < 0) { + this.n = 1; + } + + return this.prefix + this.n; + } +} + +var idGenerator = IdGenerator; + +/** + * @fileoverview A class of the code path. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * A code path. + */ +class CodePath { + + // eslint-disable-next-line jsdoc/require-description + /** + * @param {string} id An identifier. + * @param {CodePath|null} upper The code path of the upper function scope. + * @param {Function} onLooped A callback function to notify looping. + */ + constructor(id, upper, onLooped) { + + /** + * The identifier of this code path. + * Rules use it to store additional information of each rule. + * @type {string} + */ + this.id = id; + + /** + * The code path of the upper function scope. + * @type {CodePath|null} + */ + this.upper = upper; + + /** + * The code paths of nested function scopes. + * @type {CodePath[]} + */ + this.childCodePaths = []; + + // Initializes internal state. + Object.defineProperty( + this, + "internal", + { value: new codePathState(new idGenerator(`${id}_`), onLooped) } + ); + + // Adds this into `childCodePaths` of `upper`. + if (upper) { + upper.childCodePaths.push(this); + } + } + + /** + * Gets the state of a given code path. + * @param {CodePath} codePath A code path to get. + * @returns {CodePathState} The state of the code path. + */ + static getState(codePath) { + return codePath.internal; + } + + /** + * The initial code path segment. + * @type {CodePathSegment} + */ + get initialSegment() { + return this.internal.initialSegment; + } + + /** + * Final code path segments. + * This array is a mix of `returnedSegments` and `thrownSegments`. + * @type {CodePathSegment[]} + */ + get finalSegments() { + return this.internal.finalSegments; + } + + /** + * Final code path segments which is with `return` statements. + * This array contains the last path segment if it's reachable. + * Since the reachable last path returns `undefined`. + * @type {CodePathSegment[]} + */ + get returnedSegments() { + return this.internal.returnedForkContext; + } + + /** + * Final code path segments which is with `throw` statements. + * @type {CodePathSegment[]} + */ + get thrownSegments() { + return this.internal.thrownForkContext; + } + + /** + * Current code path segments. + * @type {CodePathSegment[]} + */ + get currentSegments() { + return this.internal.currentSegments; + } + + /** + * Traverses all segments in this code path. + * + * codePath.traverseSegments(function(segment, controller) { + * // do something. + * }); + * + * This method enumerates segments in order from the head. + * + * The `controller` object has two methods. + * + * - `controller.skip()` - Skip the following segments in this branch. + * - `controller.break()` - Skip all following segments. + * @param {Object} [options] Omittable. + * @param {CodePathSegment} [options.first] The first segment to traverse. + * @param {CodePathSegment} [options.last] The last segment to traverse. + * @param {Function} callback A callback function. + * @returns {void} + */ + traverseSegments(options, callback) { + let resolvedOptions; + let resolvedCallback; + + if (typeof options === "function") { + resolvedCallback = options; + resolvedOptions = {}; + } else { + resolvedOptions = options || {}; + resolvedCallback = callback; + } + + const startSegment = resolvedOptions.first || this.internal.initialSegment; + const lastSegment = resolvedOptions.last; + + let item = null; + let index = 0; + let end = 0; + let segment = null; + const visited = Object.create(null); + const stack = [[startSegment, 0]]; + let skippedSegment = null; + let broken = false; + const controller = { + skip() { + if (stack.length <= 1) { + broken = true; + } else { + skippedSegment = stack[stack.length - 2][0]; + } + }, + break() { + broken = true; + } + }; + + /** + * Checks a given previous segment has been visited. + * @param {CodePathSegment} prevSegment A previous segment to check. + * @returns {boolean} `true` if the segment has been visited. + */ + function isVisited(prevSegment) { + return ( + visited[prevSegment.id] || + segment.isLoopedPrevSegment(prevSegment) + ); + } + + while (stack.length > 0) { + item = stack[stack.length - 1]; + segment = item[0]; + index = item[1]; + + if (index === 0) { + + // Skip if this segment has been visited already. + if (visited[segment.id]) { + stack.pop(); + continue; + } + + // Skip if all previous segments have not been visited. + if (segment !== startSegment && + segment.prevSegments.length > 0 && + !segment.prevSegments.every(isVisited) + ) { + stack.pop(); + continue; + } + + // Reset the flag of skipping if all branches have been skipped. + if (skippedSegment && segment.prevSegments.indexOf(skippedSegment) !== -1) { + skippedSegment = null; + } + visited[segment.id] = true; + + // Call the callback when the first time. + if (!skippedSegment) { + resolvedCallback.call(this, segment, controller); + if (segment === lastSegment) { + controller.skip(); + } + if (broken) { + break; + } + } + } + + // Update the stack. + end = segment.nextSegments.length - 1; + if (index < end) { + item[1] += 1; + stack.push([segment.nextSegments[index], 0]); + } else if (index === end) { + item[0] = segment.nextSegments[index]; + item[1] = 0; + } else { + stack.pop(); + } + } + } +} + +var codePath = CodePath; + +/** + * @fileoverview A class of the code path analyzer. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const { breakableTypePattern } = astUtils$1; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a given node is a `case` node (not `default` node). + * @param {ASTNode} node A `SwitchCase` node to check. + * @returns {boolean} `true` if the node is a `case` node (not `default` node). + */ +function isCaseNode(node) { + return Boolean(node.test); +} + +/** + * Checks whether the given logical operator is taken into account for the code + * path analysis. + * @param {string} operator The operator found in the LogicalExpression node + * @returns {boolean} `true` if the operator is "&&" or "||" or "??" + */ +function isHandledLogicalOperator(operator) { + return operator === "&&" || operator === "||" || operator === "??"; +} + +/** + * Checks whether the given assignment operator is a logical assignment operator. + * Logical assignments are taken into account for the code path analysis + * because of their short-circuiting semantics. + * @param {string} operator The operator found in the AssignmentExpression node + * @returns {boolean} `true` if the operator is "&&=" or "||=" or "??=" + */ +function isLogicalAssignmentOperator(operator) { + return operator === "&&=" || operator === "||=" || operator === "??="; +} + +/** + * Gets the label if the parent node of a given node is a LabeledStatement. + * @param {ASTNode} node A node to get. + * @returns {string|null} The label or `null`. + */ +function getLabel(node) { + if (node.parent.type === "LabeledStatement") { + return node.parent.label.name; + } + return null; +} + +/** + * Checks whether or not a given logical expression node goes different path + * between the `true` case and the `false` case. + * @param {ASTNode} node A node to check. + * @returns {boolean} `true` if the node is a test of a choice statement. + */ +function isForkingByTrueOrFalse(node) { + const parent = node.parent; + + switch (parent.type) { + case "ConditionalExpression": + case "IfStatement": + case "WhileStatement": + case "DoWhileStatement": + case "ForStatement": + return parent.test === node; + + case "LogicalExpression": + return isHandledLogicalOperator(parent.operator); + + case "AssignmentExpression": + return isLogicalAssignmentOperator(parent.operator); + + default: + return false; + } +} + +/** + * Gets the boolean value of a given literal node. + * + * This is used to detect infinity loops (e.g. `while (true) {}`). + * Statements preceded by an infinity loop are unreachable if the loop didn't + * have any `break` statement. + * @param {ASTNode} node A node to get. + * @returns {boolean|undefined} a boolean value if the node is a Literal node, + * otherwise `undefined`. + */ +function getBooleanValueIfSimpleConstant(node) { + if (node.type === "Literal") { + return Boolean(node.value); + } + return void 0; +} + +/** + * Checks that a given identifier node is a reference or not. + * + * This is used to detect the first throwable node in a `try` block. + * @param {ASTNode} node An Identifier node to check. + * @returns {boolean} `true` if the node is a reference. + */ +function isIdentifierReference(node) { + const parent = node.parent; + + switch (parent.type) { + case "LabeledStatement": + case "BreakStatement": + case "ContinueStatement": + case "ArrayPattern": + case "RestElement": + case "ImportSpecifier": + case "ImportDefaultSpecifier": + case "ImportNamespaceSpecifier": + case "CatchClause": + return false; + + case "FunctionDeclaration": + case "FunctionExpression": + case "ArrowFunctionExpression": + case "ClassDeclaration": + case "ClassExpression": + case "VariableDeclarator": + return parent.id !== node; + + case "Property": + case "MethodDefinition": + return ( + parent.key !== node || + parent.computed || + parent.shorthand + ); + + case "AssignmentPattern": + return parent.key !== node; + + default: + return true; + } +} + +/** + * Updates the current segment with the head segment. + * This is similar to local branches and tracking branches of git. + * + * To separate the current and the head is in order to not make useless segments. + * + * In this process, both "onCodePathSegmentStart" and "onCodePathSegmentEnd" + * events are fired. + * @param {CodePathAnalyzer} analyzer The instance. + * @param {ASTNode} node The current AST node. + * @returns {void} + */ +function forwardCurrentToHead(analyzer, node) { + const codePath$1 = analyzer.codePath; + const state = codePath.getState(codePath$1); + const currentSegments = state.currentSegments; + const headSegments = state.headSegments; + const end = Math.max(currentSegments.length, headSegments.length); + let i, currentSegment, headSegment; + + // Fires leaving events. + for (i = 0; i < end; ++i) { + currentSegment = currentSegments[i]; + headSegment = headSegments[i]; + + if (currentSegment !== headSegment && currentSegment) { + debugHelpers.dump(`onCodePathSegmentEnd ${currentSegment.id}`); + + if (currentSegment.reachable) { + analyzer.emitter.emit( + "onCodePathSegmentEnd", + currentSegment, + node + ); + } + } + } + + // Update state. + state.currentSegments = headSegments; + + // Fires entering events. + for (i = 0; i < end; ++i) { + currentSegment = currentSegments[i]; + headSegment = headSegments[i]; + + if (currentSegment !== headSegment && headSegment) { + debugHelpers.dump(`onCodePathSegmentStart ${headSegment.id}`); + + codePathSegment.markUsed(headSegment); + if (headSegment.reachable) { + analyzer.emitter.emit( + "onCodePathSegmentStart", + headSegment, + node + ); + } + } + } + +} + +/** + * Updates the current segment with empty. + * This is called at the last of functions or the program. + * @param {CodePathAnalyzer} analyzer The instance. + * @param {ASTNode} node The current AST node. + * @returns {void} + */ +function leaveFromCurrentSegment(analyzer, node) { + const state = codePath.getState(analyzer.codePath); + const currentSegments = state.currentSegments; + + for (let i = 0; i < currentSegments.length; ++i) { + const currentSegment = currentSegments[i]; + + debugHelpers.dump(`onCodePathSegmentEnd ${currentSegment.id}`); + if (currentSegment.reachable) { + analyzer.emitter.emit( + "onCodePathSegmentEnd", + currentSegment, + node + ); + } + } + + state.currentSegments = []; +} + +/** + * Updates the code path due to the position of a given node in the parent node + * thereof. + * + * For example, if the node is `parent.consequent`, this creates a fork from the + * current path. + * @param {CodePathAnalyzer} analyzer The instance. + * @param {ASTNode} node The current AST node. + * @returns {void} + */ +function preprocess(analyzer, node) { + const codePath$1 = analyzer.codePath; + const state = codePath.getState(codePath$1); + const parent = node.parent; + + switch (parent.type) { + + // The `arguments.length == 0` case is in `postprocess` function. + case "CallExpression": + if (parent.optional === true && parent.arguments.length >= 1 && parent.arguments[0] === node) { + state.makeOptionalRight(); + } + break; + case "MemberExpression": + if (parent.optional === true && parent.property === node) { + state.makeOptionalRight(); + } + break; + + case "LogicalExpression": + if ( + parent.right === node && + isHandledLogicalOperator(parent.operator) + ) { + state.makeLogicalRight(); + } + break; + + case "AssignmentExpression": + if ( + parent.right === node && + isLogicalAssignmentOperator(parent.operator) + ) { + state.makeLogicalRight(); + } + break; + + case "ConditionalExpression": + case "IfStatement": + + /* + * Fork if this node is at `consequent`/`alternate`. + * `popForkContext()` exists at `IfStatement:exit` and + * `ConditionalExpression:exit`. + */ + if (parent.consequent === node) { + state.makeIfConsequent(); + } else if (parent.alternate === node) { + state.makeIfAlternate(); + } + break; + + case "SwitchCase": + if (parent.consequent[0] === node) { + state.makeSwitchCaseBody(false, !parent.test); + } + break; + + case "TryStatement": + if (parent.handler === node) { + state.makeCatchBlock(); + } else if (parent.finalizer === node) { + state.makeFinallyBlock(); + } + break; + + case "WhileStatement": + if (parent.test === node) { + state.makeWhileTest(getBooleanValueIfSimpleConstant(node)); + } else { + assert__default['default'](parent.body === node); + state.makeWhileBody(); + } + break; + + case "DoWhileStatement": + if (parent.body === node) { + state.makeDoWhileBody(); + } else { + assert__default['default'](parent.test === node); + state.makeDoWhileTest(getBooleanValueIfSimpleConstant(node)); + } + break; + + case "ForStatement": + if (parent.test === node) { + state.makeForTest(getBooleanValueIfSimpleConstant(node)); + } else if (parent.update === node) { + state.makeForUpdate(); + } else if (parent.body === node) { + state.makeForBody(); + } + break; + + case "ForInStatement": + case "ForOfStatement": + if (parent.left === node) { + state.makeForInOfLeft(); + } else if (parent.right === node) { + state.makeForInOfRight(); + } else { + assert__default['default'](parent.body === node); + state.makeForInOfBody(); + } + break; + + case "AssignmentPattern": + + /* + * Fork if this node is at `right`. + * `left` is executed always, so it uses the current path. + * `popForkContext()` exists at `AssignmentPattern:exit`. + */ + if (parent.right === node) { + state.pushForkContext(); + state.forkBypassPath(); + state.forkPath(); + } + break; + } +} + +/** + * Updates the code path due to the type of a given node in entering. + * @param {CodePathAnalyzer} analyzer The instance. + * @param {ASTNode} node The current AST node. + * @returns {void} + */ +function processCodePathToEnter(analyzer, node) { + let codePath$1 = analyzer.codePath; + let state = codePath$1 && codePath.getState(codePath$1); + const parent = node.parent; + + switch (node.type) { + case "Program": + case "FunctionDeclaration": + case "FunctionExpression": + case "ArrowFunctionExpression": + if (codePath$1) { + + // Emits onCodePathSegmentStart events if updated. + forwardCurrentToHead(analyzer, node); + debugHelpers.dumpState(node, state, false); + } + + // Create the code path of this scope. + codePath$1 = analyzer.codePath = new codePath( + analyzer.idGenerator.next(), + codePath$1, + analyzer.onLooped + ); + state = codePath.getState(codePath$1); + + // Emits onCodePathStart events. + debugHelpers.dump(`onCodePathStart ${codePath$1.id}`); + analyzer.emitter.emit("onCodePathStart", codePath$1, node); + break; + + case "ChainExpression": + state.pushChainContext(); + break; + case "CallExpression": + if (node.optional === true) { + state.makeOptionalNode(); + } + break; + case "MemberExpression": + if (node.optional === true) { + state.makeOptionalNode(); + } + break; + + case "LogicalExpression": + if (isHandledLogicalOperator(node.operator)) { + state.pushChoiceContext( + node.operator, + isForkingByTrueOrFalse(node) + ); + } + break; + + case "AssignmentExpression": + if (isLogicalAssignmentOperator(node.operator)) { + state.pushChoiceContext( + node.operator.slice(0, -1), // removes `=` from the end + isForkingByTrueOrFalse(node) + ); + } + break; + + case "ConditionalExpression": + case "IfStatement": + state.pushChoiceContext("test", false); + break; + + case "SwitchStatement": + state.pushSwitchContext( + node.cases.some(isCaseNode), + getLabel(node) + ); + break; + + case "TryStatement": + state.pushTryContext(Boolean(node.finalizer)); + break; + + case "SwitchCase": + + /* + * Fork if this node is after the 2st node in `cases`. + * It's similar to `else` blocks. + * The next `test` node is processed in this path. + */ + if (parent.discriminant !== node && parent.cases[0] !== node) { + state.forkPath(); + } + break; + + case "WhileStatement": + case "DoWhileStatement": + case "ForStatement": + case "ForInStatement": + case "ForOfStatement": + state.pushLoopContext(node.type, getLabel(node)); + break; + + case "LabeledStatement": + if (!breakableTypePattern.test(node.body.type)) { + state.pushBreakContext(false, node.label.name); + } + break; + } + + // Emits onCodePathSegmentStart events if updated. + forwardCurrentToHead(analyzer, node); + debugHelpers.dumpState(node, state, false); +} + +/** + * Updates the code path due to the type of a given node in leaving. + * @param {CodePathAnalyzer} analyzer The instance. + * @param {ASTNode} node The current AST node. + * @returns {void} + */ +function processCodePathToExit(analyzer, node) { + const codePath$1 = analyzer.codePath; + const state = codePath.getState(codePath$1); + let dontForward = false; + + switch (node.type) { + case "ChainExpression": + state.popChainContext(); + break; + + case "IfStatement": + case "ConditionalExpression": + state.popChoiceContext(); + break; + + case "LogicalExpression": + if (isHandledLogicalOperator(node.operator)) { + state.popChoiceContext(); + } + break; + + case "AssignmentExpression": + if (isLogicalAssignmentOperator(node.operator)) { + state.popChoiceContext(); + } + break; + + case "SwitchStatement": + state.popSwitchContext(); + break; + + case "SwitchCase": + + /* + * This is the same as the process at the 1st `consequent` node in + * `preprocess` function. + * Must do if this `consequent` is empty. + */ + if (node.consequent.length === 0) { + state.makeSwitchCaseBody(true, !node.test); + } + if (state.forkContext.reachable) { + dontForward = true; + } + break; + + case "TryStatement": + state.popTryContext(); + break; + + case "BreakStatement": + forwardCurrentToHead(analyzer, node); + state.makeBreak(node.label && node.label.name); + dontForward = true; + break; + + case "ContinueStatement": + forwardCurrentToHead(analyzer, node); + state.makeContinue(node.label && node.label.name); + dontForward = true; + break; + + case "ReturnStatement": + forwardCurrentToHead(analyzer, node); + state.makeReturn(); + dontForward = true; + break; + + case "ThrowStatement": + forwardCurrentToHead(analyzer, node); + state.makeThrow(); + dontForward = true; + break; + + case "Identifier": + if (isIdentifierReference(node)) { + state.makeFirstThrowablePathInTryBlock(); + dontForward = true; + } + break; + + case "CallExpression": + case "ImportExpression": + case "MemberExpression": + case "NewExpression": + case "YieldExpression": + state.makeFirstThrowablePathInTryBlock(); + break; + + case "WhileStatement": + case "DoWhileStatement": + case "ForStatement": + case "ForInStatement": + case "ForOfStatement": + state.popLoopContext(); + break; + + case "AssignmentPattern": + state.popForkContext(); + break; + + case "LabeledStatement": + if (!breakableTypePattern.test(node.body.type)) { + state.popBreakContext(); + } + break; + } + + // Emits onCodePathSegmentStart events if updated. + if (!dontForward) { + forwardCurrentToHead(analyzer, node); + } + debugHelpers.dumpState(node, state, true); +} + +/** + * Updates the code path to finalize the current code path. + * @param {CodePathAnalyzer} analyzer The instance. + * @param {ASTNode} node The current AST node. + * @returns {void} + */ +function postprocess(analyzer, node) { + switch (node.type) { + case "Program": + case "FunctionDeclaration": + case "FunctionExpression": + case "ArrowFunctionExpression": { + let codePath$1 = analyzer.codePath; + + // Mark the current path as the final node. + codePath.getState(codePath$1).makeFinal(); + + // Emits onCodePathSegmentEnd event of the current segments. + leaveFromCurrentSegment(analyzer, node); + + // Emits onCodePathEnd event of this code path. + debugHelpers.dump(`onCodePathEnd ${codePath$1.id}`); + analyzer.emitter.emit("onCodePathEnd", codePath$1, node); + debugHelpers.dumpDot(codePath$1); + + codePath$1 = analyzer.codePath = analyzer.codePath.upper; + if (codePath$1) { + debugHelpers.dumpState(node, codePath.getState(codePath$1), true); + } + break; + } + + // The `arguments.length >= 1` case is in `preprocess` function. + case "CallExpression": + if (node.optional === true && node.arguments.length === 0) { + codePath.getState(analyzer.codePath).makeOptionalRight(); + } + break; + } +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * The class to analyze code paths. + * This class implements the EventGenerator interface. + */ +class CodePathAnalyzer { + + // eslint-disable-next-line jsdoc/require-description + /** + * @param {EventGenerator} eventGenerator An event generator to wrap. + */ + constructor(eventGenerator) { + this.original = eventGenerator; + this.emitter = eventGenerator.emitter; + this.codePath = null; + this.idGenerator = new idGenerator("s"); + this.currentNode = null; + this.onLooped = this.onLooped.bind(this); + } + + /** + * Does the process to enter a given AST node. + * This updates state of analysis and calls `enterNode` of the wrapped. + * @param {ASTNode} node A node which is entering. + * @returns {void} + */ + enterNode(node) { + this.currentNode = node; + + // Updates the code path due to node's position in its parent node. + if (node.parent) { + preprocess(this, node); + } + + /* + * Updates the code path. + * And emits onCodePathStart/onCodePathSegmentStart events. + */ + processCodePathToEnter(this, node); + + // Emits node events. + this.original.enterNode(node); + + this.currentNode = null; + } + + /** + * Does the process to leave a given AST node. + * This updates state of analysis and calls `leaveNode` of the wrapped. + * @param {ASTNode} node A node which is leaving. + * @returns {void} + */ + leaveNode(node) { + this.currentNode = node; + + /* + * Updates the code path. + * And emits onCodePathStart/onCodePathSegmentStart events. + */ + processCodePathToExit(this, node); + + // Emits node events. + this.original.leaveNode(node); + + // Emits the last onCodePathStart/onCodePathSegmentStart events. + postprocess(this, node); + + this.currentNode = null; + } + + /** + * This is called on a code path looped. + * Then this raises a looped event. + * @param {CodePathSegment} fromSegment A segment of prev. + * @param {CodePathSegment} toSegment A segment of next. + * @returns {void} + */ + onLooped(fromSegment, toSegment) { + if (fromSegment.reachable && toSegment.reachable) { + debugHelpers.dump(`onCodePathSegmentLoop ${fromSegment.id} -> ${toSegment.id}`); + this.emitter.emit( + "onCodePathSegmentLoop", + fromSegment, + toSegment, + this.currentNode + ); + } + } +} + +var codePathAnalyzer = CodePathAnalyzer; + +/** + * @fileoverview A module that filters reported problems based on `eslint-disable` and `eslint-enable` comments + * @author Teddy Katz + */ + + + +/** + * Compares the locations of two objects in a source file + * @param {{line: number, column: number}} itemA The first object + * @param {{line: number, column: number}} itemB The second object + * @returns {number} A value less than 1 if itemA appears before itemB in the source file, greater than 1 if + * itemA appears after itemB in the source file, or 0 if itemA and itemB have the same location. + */ +function compareLocations(itemA, itemB) { + return itemA.line - itemB.line || itemA.column - itemB.column; +} + +/** + * This is the same as the exported function, except that it + * doesn't handle disable-line and disable-next-line directives, and it always reports unused + * disable directives. + * @param {Object} options options for applying directives. This is the same as the options + * for the exported function, except that `reportUnusedDisableDirectives` is not supported + * (this function always reports unused disable directives). + * @returns {{problems: Problem[], unusedDisableDirectives: Problem[]}} An object with a list + * of filtered problems and unused eslint-disable directives + */ +function applyDirectives(options) { + const problems = []; + let nextDirectiveIndex = 0; + let currentGlobalDisableDirective = null; + const disabledRuleMap = new Map(); + + // enabledRules is only used when there is a current global disable directive. + const enabledRules = new Set(); + const usedDisableDirectives = new Set(); + + for (const problem of options.problems) { + while ( + nextDirectiveIndex < options.directives.length && + compareLocations(options.directives[nextDirectiveIndex], problem) <= 0 + ) { + const directive = options.directives[nextDirectiveIndex++]; + + switch (directive.type) { + case "disable": + if (directive.ruleId === null) { + currentGlobalDisableDirective = directive; + disabledRuleMap.clear(); + enabledRules.clear(); + } else if (currentGlobalDisableDirective) { + enabledRules.delete(directive.ruleId); + disabledRuleMap.set(directive.ruleId, directive); + } else { + disabledRuleMap.set(directive.ruleId, directive); + } + break; + + case "enable": + if (directive.ruleId === null) { + currentGlobalDisableDirective = null; + disabledRuleMap.clear(); + } else if (currentGlobalDisableDirective) { + enabledRules.add(directive.ruleId); + disabledRuleMap.delete(directive.ruleId); + } else { + disabledRuleMap.delete(directive.ruleId); + } + break; + + // no default + } + } + + if (disabledRuleMap.has(problem.ruleId)) { + usedDisableDirectives.add(disabledRuleMap.get(problem.ruleId)); + } else if (currentGlobalDisableDirective && !enabledRules.has(problem.ruleId)) { + usedDisableDirectives.add(currentGlobalDisableDirective); + } else { + problems.push(problem); + } + } + + const unusedDisableDirectives = options.directives + .filter(directive => directive.type === "disable" && !usedDisableDirectives.has(directive)) + .map(directive => ({ + ruleId: null, + message: directive.ruleId + ? `Unused eslint-disable directive (no problems were reported from '${directive.ruleId}').` + : "Unused eslint-disable directive (no problems were reported).", + line: directive.unprocessedDirective.line, + column: directive.unprocessedDirective.column, + severity: options.reportUnusedDisableDirectives === "warn" ? 1 : 2, + nodeType: null + })); + + return { problems, unusedDisableDirectives }; +} + +/** + * Given a list of directive comments (i.e. metadata about eslint-disable and eslint-enable comments) and a list + * of reported problems, determines which problems should be reported. + * @param {Object} options Information about directives and problems + * @param {{ + * type: ("disable"|"enable"|"disable-line"|"disable-next-line"), + * ruleId: (string|null), + * line: number, + * column: number + * }} options.directives Directive comments found in the file, with one-based columns. + * Two directive comments can only have the same location if they also have the same type (e.g. a single eslint-disable + * comment for two different rules is represented as two directives). + * @param {{ruleId: (string|null), line: number, column: number}[]} options.problems + * A list of problems reported by rules, sorted by increasing location in the file, with one-based columns. + * @param {"off" | "warn" | "error"} options.reportUnusedDisableDirectives If `"warn"` or `"error"`, adds additional problems for unused directives + * @returns {{ruleId: (string|null), line: number, column: number}[]} + * A list of reported problems that were not disabled by the directive comments. + */ +var applyDisableDirectives = ({ directives, problems, reportUnusedDisableDirectives = "off" }) => { + const blockDirectives = directives + .filter(directive => directive.type === "disable" || directive.type === "enable") + .map(directive => Object.assign({}, directive, { unprocessedDirective: directive })) + .sort(compareLocations); + + const lineDirectives = lodash__default['default'].flatMap(directives, directive => { + switch (directive.type) { + case "disable": + case "enable": + return []; + + case "disable-line": + return [ + { type: "disable", line: directive.line, column: 1, ruleId: directive.ruleId, unprocessedDirective: directive }, + { type: "enable", line: directive.line + 1, column: 0, ruleId: directive.ruleId, unprocessedDirective: directive } + ]; + + case "disable-next-line": + return [ + { type: "disable", line: directive.line + 1, column: 1, ruleId: directive.ruleId, unprocessedDirective: directive }, + { type: "enable", line: directive.line + 2, column: 0, ruleId: directive.ruleId, unprocessedDirective: directive } + ]; + + default: + throw new TypeError(`Unrecognized directive type '${directive.type}'`); + } + }).sort(compareLocations); + + const blockDirectivesResult = applyDirectives({ + problems, + directives: blockDirectives, + reportUnusedDisableDirectives + }); + const lineDirectivesResult = applyDirectives({ + problems: blockDirectivesResult.problems, + directives: lineDirectives, + reportUnusedDisableDirectives + }); + + return reportUnusedDisableDirectives !== "off" + ? lineDirectivesResult.problems + .concat(blockDirectivesResult.unusedDisableDirectives) + .concat(lineDirectivesResult.unusedDisableDirectives) + .sort(compareLocations) + : lineDirectivesResult.problems; +}; + +/** + * @fileoverview Config Comment Parser + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +const debug$5 = require$$0__default['default']("eslint:config-comment-parser"); + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * Object to parse ESLint configuration comments inside JavaScript files. + * @name ConfigCommentParser + */ +var configCommentParser = class ConfigCommentParser { + + /** + * Parses a list of "name:string_value" or/and "name" options divided by comma or + * whitespace. Used for "global" and "exported" comments. + * @param {string} string The string to parse. + * @param {Comment} comment The comment node which has the string. + * @returns {Object} Result map object of names and string values, or null values if no value was provided + */ + parseStringConfig(string, comment) { + debug$5("Parsing String config"); + + const items = {}; + + // Collapse whitespace around `:` and `,` to make parsing easier + const trimmedString = string.replace(/\s*([:,])\s*/gu, "$1"); + + trimmedString.split(/\s|,+/u).forEach(name => { + if (!name) { + return; + } + + // value defaults to null (if not provided), e.g: "foo" => ["foo", null] + const [key, value = null] = name.split(":"); + + items[key] = { value, comment }; + }); + return items; + } + + /** + * Parses a JSON-like config. + * @param {string} string The string to parse. + * @param {Object} location Start line and column of comments for potential error message. + * @returns {({success: true, config: Object}|{success: false, error: Problem})} Result map object + */ + parseJsonConfig(string, location) { + debug$5("Parsing JSON config"); + + let items = {}; + + // Parses a JSON-like comment by the same way as parsing CLI option. + try { + items = levn__default['default'].parse("Object", string) || {}; + + // Some tests say that it should ignore invalid comments such as `/*eslint no-alert:abc*/`. + // Also, commaless notations have invalid severity: + // "no-alert: 2 no-console: 2" --> {"no-alert": "2 no-console: 2"} + // Should ignore that case as well. + if (configOps.isEverySeverityValid(items)) { + return { + success: true, + config: items + }; + } + } catch { + + debug$5("Levn parsing failed; falling back to manual parsing."); + + // ignore to parse the string by a fallback. + } + + /* + * Optionator cannot parse commaless notations. + * But we are supporting that. So this is a fallback for that. + */ + items = {}; + const normalizedString = string.replace(/([-a-zA-Z0-9/]+):/gu, "\"$1\":").replace(/(\]|[0-9])\s+(?=")/u, "$1,"); + + try { + items = JSON.parse(`{${normalizedString}}`); + } catch (ex) { + debug$5("Manual parsing failed."); + + return { + success: false, + error: { + ruleId: null, + fatal: true, + severity: 2, + message: `Failed to parse JSON from '${normalizedString}': ${ex.message}`, + line: location.start.line, + column: location.start.column + 1 + } + }; + + } + + return { + success: true, + config: items + }; + } + + /** + * Parses a config of values separated by comma. + * @param {string} string The string to parse. + * @returns {Object} Result map of values and true values + */ + parseListConfig(string) { + debug$5("Parsing list config"); + + const items = {}; + + // Collapse whitespace around commas + string.replace(/\s*,\s*/gu, ",").split(/,+/u).forEach(name => { + const trimmedName = name.trim(); + + if (trimmedName) { + items[trimmedName] = true; + } + }); + return items; + } + +}; + +/** + * @fileoverview The event generator for AST nodes. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------------ +// Typedefs +//------------------------------------------------------------------------------ + +/** + * An object describing an AST selector + * @typedef {Object} ASTSelector + * @property {string} rawSelector The string that was parsed into this selector + * @property {boolean} isExit `true` if this should be emitted when exiting the node rather than when entering + * @property {Object} parsedSelector An object (from esquery) describing the matching behavior of the selector + * @property {string[]|null} listenerTypes A list of node types that could possibly cause the selector to match, + * or `null` if all node types could cause a match + * @property {number} attributeCount The total number of classes, pseudo-classes, and attribute queries in this selector + * @property {number} identifierCount The total number of identifier queries in this selector + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Gets the possible types of a selector + * @param {Object} parsedSelector An object (from esquery) describing the matching behavior of the selector + * @returns {string[]|null} The node types that could possibly trigger this selector, or `null` if all node types could trigger it + */ +function getPossibleTypes(parsedSelector) { + switch (parsedSelector.type) { + case "identifier": + return [parsedSelector.value]; + + case "matches": { + const typesForComponents = parsedSelector.selectors.map(getPossibleTypes); + + if (typesForComponents.every(Boolean)) { + return lodash__default['default'].union(...typesForComponents); + } + return null; + } + + case "compound": { + const typesForComponents = parsedSelector.selectors.map(getPossibleTypes).filter(typesForComponent => typesForComponent); + + // If all of the components could match any type, then the compound could also match any type. + if (!typesForComponents.length) { + return null; + } + + /* + * If at least one of the components could only match a particular type, the compound could only match + * the intersection of those types. + */ + return lodash__default['default'].intersection(...typesForComponents); + } + + case "child": + case "descendant": + case "sibling": + case "adjacent": + return getPossibleTypes(parsedSelector.right); + + default: + return null; + + } +} + +/** + * Counts the number of class, pseudo-class, and attribute queries in this selector + * @param {Object} parsedSelector An object (from esquery) describing the selector's matching behavior + * @returns {number} The number of class, pseudo-class, and attribute queries in this selector + */ +function countClassAttributes(parsedSelector) { + switch (parsedSelector.type) { + case "child": + case "descendant": + case "sibling": + case "adjacent": + return countClassAttributes(parsedSelector.left) + countClassAttributes(parsedSelector.right); + + case "compound": + case "not": + case "matches": + return parsedSelector.selectors.reduce((sum, childSelector) => sum + countClassAttributes(childSelector), 0); + + case "attribute": + case "field": + case "nth-child": + case "nth-last-child": + return 1; + + default: + return 0; + } +} + +/** + * Counts the number of identifier queries in this selector + * @param {Object} parsedSelector An object (from esquery) describing the selector's matching behavior + * @returns {number} The number of identifier queries + */ +function countIdentifiers(parsedSelector) { + switch (parsedSelector.type) { + case "child": + case "descendant": + case "sibling": + case "adjacent": + return countIdentifiers(parsedSelector.left) + countIdentifiers(parsedSelector.right); + + case "compound": + case "not": + case "matches": + return parsedSelector.selectors.reduce((sum, childSelector) => sum + countIdentifiers(childSelector), 0); + + case "identifier": + return 1; + + default: + return 0; + } +} + +/** + * Compares the specificity of two selector objects, with CSS-like rules. + * @param {ASTSelector} selectorA An AST selector descriptor + * @param {ASTSelector} selectorB Another AST selector descriptor + * @returns {number} + * a value less than 0 if selectorA is less specific than selectorB + * a value greater than 0 if selectorA is more specific than selectorB + * a value less than 0 if selectorA and selectorB have the same specificity, and selectorA <= selectorB alphabetically + * a value greater than 0 if selectorA and selectorB have the same specificity, and selectorA > selectorB alphabetically + */ +function compareSpecificity(selectorA, selectorB) { + return selectorA.attributeCount - selectorB.attributeCount || + selectorA.identifierCount - selectorB.identifierCount || + (selectorA.rawSelector <= selectorB.rawSelector ? -1 : 1); +} + +/** + * Parses a raw selector string, and throws a useful error if parsing fails. + * @param {string} rawSelector A raw AST selector + * @returns {Object} An object (from esquery) describing the matching behavior of this selector + * @throws {Error} An error if the selector is invalid + */ +function tryParseSelector(rawSelector) { + try { + return esquery__default['default'].parse(rawSelector.replace(/:exit$/u, "")); + } catch (err) { + if (err.location && err.location.start && typeof err.location.start.offset === "number") { + throw new SyntaxError(`Syntax error in selector "${rawSelector}" at position ${err.location.start.offset}: ${err.message}`); + } + throw err; + } +} + +/** + * Parses a raw selector string, and returns the parsed selector along with specificity and type information. + * @param {string} rawSelector A raw AST selector + * @returns {ASTSelector} A selector descriptor + */ +const parseSelector = lodash__default['default'].memoize(rawSelector => { + const parsedSelector = tryParseSelector(rawSelector); + + return { + rawSelector, + isExit: rawSelector.endsWith(":exit"), + parsedSelector, + listenerTypes: getPossibleTypes(parsedSelector), + attributeCount: countClassAttributes(parsedSelector), + identifierCount: countIdentifiers(parsedSelector) + }; +}); + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * The event generator for AST nodes. + * This implements below interface. + * + * ```ts + * interface EventGenerator { + * emitter: SafeEmitter; + * enterNode(node: ASTNode): void; + * leaveNode(node: ASTNode): void; + * } + * ``` + */ +class NodeEventGenerator { + + // eslint-disable-next-line jsdoc/require-description + /** + * @param {SafeEmitter} emitter + * An SafeEmitter which is the destination of events. This emitter must already + * have registered listeners for all of the events that it needs to listen for. + * (See lib/linter/safe-emitter.js for more details on `SafeEmitter`.) + * @param {ESQueryOptions} esqueryOptions `esquery` options for traversing custom nodes. + * @returns {NodeEventGenerator} new instance + */ + constructor(emitter, esqueryOptions) { + this.emitter = emitter; + this.esqueryOptions = esqueryOptions; + this.currentAncestry = []; + this.enterSelectorsByNodeType = new Map(); + this.exitSelectorsByNodeType = new Map(); + this.anyTypeEnterSelectors = []; + this.anyTypeExitSelectors = []; + + emitter.eventNames().forEach(rawSelector => { + const selector = parseSelector(rawSelector); + + if (selector.listenerTypes) { + const typeMap = selector.isExit ? this.exitSelectorsByNodeType : this.enterSelectorsByNodeType; + + selector.listenerTypes.forEach(nodeType => { + if (!typeMap.has(nodeType)) { + typeMap.set(nodeType, []); + } + typeMap.get(nodeType).push(selector); + }); + return; + } + const selectors = selector.isExit ? this.anyTypeExitSelectors : this.anyTypeEnterSelectors; + + selectors.push(selector); + }); + + this.anyTypeEnterSelectors.sort(compareSpecificity); + this.anyTypeExitSelectors.sort(compareSpecificity); + this.enterSelectorsByNodeType.forEach(selectorList => selectorList.sort(compareSpecificity)); + this.exitSelectorsByNodeType.forEach(selectorList => selectorList.sort(compareSpecificity)); + } + + /** + * Checks a selector against a node, and emits it if it matches + * @param {ASTNode} node The node to check + * @param {ASTSelector} selector An AST selector descriptor + * @returns {void} + */ + applySelector(node, selector) { + if (esquery__default['default'].matches(node, selector.parsedSelector, this.currentAncestry, this.esqueryOptions)) { + this.emitter.emit(selector.rawSelector, node); + } + } + + /** + * Applies all appropriate selectors to a node, in specificity order + * @param {ASTNode} node The node to check + * @param {boolean} isExit `false` if the node is currently being entered, `true` if it's currently being exited + * @returns {void} + */ + applySelectors(node, isExit) { + const selectorsByNodeType = (isExit ? this.exitSelectorsByNodeType : this.enterSelectorsByNodeType).get(node.type) || []; + const anyTypeSelectors = isExit ? this.anyTypeExitSelectors : this.anyTypeEnterSelectors; + + /* + * selectorsByNodeType and anyTypeSelectors were already sorted by specificity in the constructor. + * Iterate through each of them, applying selectors in the right order. + */ + let selectorsByTypeIndex = 0; + let anyTypeSelectorsIndex = 0; + + while (selectorsByTypeIndex < selectorsByNodeType.length || anyTypeSelectorsIndex < anyTypeSelectors.length) { + if ( + selectorsByTypeIndex >= selectorsByNodeType.length || + anyTypeSelectorsIndex < anyTypeSelectors.length && + compareSpecificity(anyTypeSelectors[anyTypeSelectorsIndex], selectorsByNodeType[selectorsByTypeIndex]) < 0 + ) { + this.applySelector(node, anyTypeSelectors[anyTypeSelectorsIndex++]); + } else { + this.applySelector(node, selectorsByNodeType[selectorsByTypeIndex++]); + } + } + } + + /** + * Emits an event of entering AST node. + * @param {ASTNode} node A node which was entered. + * @returns {void} + */ + enterNode(node) { + if (node.parent) { + this.currentAncestry.unshift(node.parent); + } + this.applySelectors(node, false); + } + + /** + * Emits an event of leaving AST node. + * @param {ASTNode} node A node which was left. + * @returns {void} + */ + leaveNode(node) { + this.applySelectors(node, true); + this.currentAncestry.shift(); + } +} + +var nodeEventGenerator = NodeEventGenerator; + +/** + * @fileoverview An object that creates fix commands for rules. + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +// none! + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Creates a fix command that inserts text at the specified index in the source text. + * @param {int} index The 0-based index at which to insert the new text. + * @param {string} text The text to insert. + * @returns {Object} The fix command. + * @private + */ +function insertTextAt(index, text) { + return { + range: [index, index], + text + }; +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * Creates code fixing commands for rules. + */ + +const ruleFixer = Object.freeze({ + + /** + * Creates a fix command that inserts text after the given node or token. + * The fix is not applied until applyFixes() is called. + * @param {ASTNode|Token} nodeOrToken The node or token to insert after. + * @param {string} text The text to insert. + * @returns {Object} The fix command. + */ + insertTextAfter(nodeOrToken, text) { + return this.insertTextAfterRange(nodeOrToken.range, text); + }, + + /** + * Creates a fix command that inserts text after the specified range in the source text. + * The fix is not applied until applyFixes() is called. + * @param {int[]} range The range to replace, first item is start of range, second + * is end of range. + * @param {string} text The text to insert. + * @returns {Object} The fix command. + */ + insertTextAfterRange(range, text) { + return insertTextAt(range[1], text); + }, + + /** + * Creates a fix command that inserts text before the given node or token. + * The fix is not applied until applyFixes() is called. + * @param {ASTNode|Token} nodeOrToken The node or token to insert before. + * @param {string} text The text to insert. + * @returns {Object} The fix command. + */ + insertTextBefore(nodeOrToken, text) { + return this.insertTextBeforeRange(nodeOrToken.range, text); + }, + + /** + * Creates a fix command that inserts text before the specified range in the source text. + * The fix is not applied until applyFixes() is called. + * @param {int[]} range The range to replace, first item is start of range, second + * is end of range. + * @param {string} text The text to insert. + * @returns {Object} The fix command. + */ + insertTextBeforeRange(range, text) { + return insertTextAt(range[0], text); + }, + + /** + * Creates a fix command that replaces text at the node or token. + * The fix is not applied until applyFixes() is called. + * @param {ASTNode|Token} nodeOrToken The node or token to remove. + * @param {string} text The text to insert. + * @returns {Object} The fix command. + */ + replaceText(nodeOrToken, text) { + return this.replaceTextRange(nodeOrToken.range, text); + }, + + /** + * Creates a fix command that replaces text at the specified range in the source text. + * The fix is not applied until applyFixes() is called. + * @param {int[]} range The range to replace, first item is start of range, second + * is end of range. + * @param {string} text The text to insert. + * @returns {Object} The fix command. + */ + replaceTextRange(range, text) { + return { + range, + text + }; + }, + + /** + * Creates a fix command that removes the node or token from the source. + * The fix is not applied until applyFixes() is called. + * @param {ASTNode|Token} nodeOrToken The node or token to remove. + * @returns {Object} The fix command. + */ + remove(nodeOrToken) { + return this.removeRange(nodeOrToken.range); + }, + + /** + * Creates a fix command that removes the specified range of text from the source. + * The fix is not applied until applyFixes() is called. + * @param {int[]} range The range to remove, first item is start of range, second + * is end of range. + * @returns {Object} The fix command. + */ + removeRange(range) { + return { + range, + text: "" + }; + } + +}); + + +var ruleFixer_1 = ruleFixer; + +/** + * @fileoverview Interpolate keys from an object into a string with {{ }} markers. + * @author Jed Fox + */ + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +var interpolate$1 = (text, data) => { + if (!data) { + return text; + } + + // Substitution content for any {{ }} markers. + return text.replace(/\{\{([^{}]+?)\}\}/gu, (fullMatch, termWithWhitespace) => { + const term = termWithWhitespace.trim(); + + if (term in data) { + return data[term]; + } + + // Preserve old behavior: If parameter name not provided, don't replace it. + return fullMatch; + }); +}; + +/** + * @fileoverview A helper that translates context.report() calls from the rule API into generic problem objects + * @author Teddy Katz + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + + +//------------------------------------------------------------------------------ +// Typedefs +//------------------------------------------------------------------------------ + +/** + * An error message description + * @typedef {Object} MessageDescriptor + * @property {ASTNode} [node] The reported node + * @property {Location} loc The location of the problem. + * @property {string} message The problem message. + * @property {Object} [data] Optional data to use to fill in placeholders in the + * message. + * @property {Function} [fix] The function to call that creates a fix command. + * @property {Array<{desc?: string, messageId?: string, fix: Function}>} suggest Suggestion descriptions and functions to create a the associated fixes. + */ + +/** + * Information about the report + * @typedef {Object} ReportInfo + * @property {string} ruleId + * @property {(0|1|2)} severity + * @property {(string|undefined)} message + * @property {(string|undefined)} [messageId] + * @property {number} line + * @property {number} column + * @property {(number|undefined)} [endLine] + * @property {(number|undefined)} [endColumn] + * @property {(string|null)} nodeType + * @property {string} source + * @property {({text: string, range: (number[]|null)}|null)} [fix] + * @property {Array<{text: string, range: (number[]|null)}|null>} [suggestions] + */ + +//------------------------------------------------------------------------------ +// Module Definition +//------------------------------------------------------------------------------ + + +/** + * Translates a multi-argument context.report() call into a single object argument call + * @param {...*} args A list of arguments passed to `context.report` + * @returns {MessageDescriptor} A normalized object containing report information + */ +function normalizeMultiArgReportCall(...args) { + + // If there is one argument, it is considered to be a new-style call already. + if (args.length === 1) { + + // Shallow clone the object to avoid surprises if reusing the descriptor + return Object.assign({}, args[0]); + } + + // If the second argument is a string, the arguments are interpreted as [node, message, data, fix]. + if (typeof args[1] === "string") { + return { + node: args[0], + message: args[1], + data: args[2], + fix: args[3] + }; + } + + // Otherwise, the arguments are interpreted as [node, loc, message, data, fix]. + return { + node: args[0], + loc: args[1], + message: args[2], + data: args[3], + fix: args[4] + }; +} + +/** + * Asserts that either a loc or a node was provided, and the node is valid if it was provided. + * @param {MessageDescriptor} descriptor A descriptor to validate + * @returns {void} + * @throws AssertionError if neither a node nor a loc was provided, or if the node is not an object + */ +function assertValidNodeInfo(descriptor) { + if (descriptor.node) { + assert__default['default'](typeof descriptor.node === "object", "Node must be an object"); + } else { + assert__default['default'](descriptor.loc, "Node must be provided when reporting error if location is not provided"); + } +} + +/** + * Normalizes a MessageDescriptor to always have a `loc` with `start` and `end` properties + * @param {MessageDescriptor} descriptor A descriptor for the report from a rule. + * @returns {{start: Location, end: (Location|null)}} An updated location that infers the `start` and `end` properties + * from the `node` of the original descriptor, or infers the `start` from the `loc` of the original descriptor. + */ +function normalizeReportLoc(descriptor) { + if (descriptor.loc) { + if (descriptor.loc.start) { + return descriptor.loc; + } + return { start: descriptor.loc, end: null }; + } + return descriptor.node.loc; +} + +/** + * Check that a fix has a valid range. + * @param {Fix|null} fix The fix to validate. + * @returns {void} + */ +function assertValidFix(fix) { + if (fix) { + assert__default['default'](fix.range && typeof fix.range[0] === "number" && typeof fix.range[1] === "number", `Fix has invalid range: ${JSON.stringify(fix, null, 2)}`); + } +} + +/** + * Compares items in a fixes array by range. + * @param {Fix} a The first message. + * @param {Fix} b The second message. + * @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal. + * @private + */ +function compareFixesByRange(a, b) { + return a.range[0] - b.range[0] || a.range[1] - b.range[1]; +} + +/** + * Merges the given fixes array into one. + * @param {Fix[]} fixes The fixes to merge. + * @param {SourceCode} sourceCode The source code object to get the text between fixes. + * @returns {{text: string, range: number[]}} The merged fixes + */ +function mergeFixes(fixes, sourceCode) { + for (const fix of fixes) { + assertValidFix(fix); + } + + if (fixes.length === 0) { + return null; + } + if (fixes.length === 1) { + return fixes[0]; + } + + fixes.sort(compareFixesByRange); + + const originalText = sourceCode.text; + const start = fixes[0].range[0]; + const end = fixes[fixes.length - 1].range[1]; + let text = ""; + let lastPos = Number.MIN_SAFE_INTEGER; + + for (const fix of fixes) { + assert__default['default'](fix.range[0] >= lastPos, "Fix objects must not be overlapped in a report."); + + if (fix.range[0] >= 0) { + text += originalText.slice(Math.max(0, start, lastPos), fix.range[0]); + } + text += fix.text; + lastPos = fix.range[1]; + } + text += originalText.slice(Math.max(0, start, lastPos), end); + + return { range: [start, end], text }; +} + +/** + * Gets one fix object from the given descriptor. + * If the descriptor retrieves multiple fixes, this merges those to one. + * @param {MessageDescriptor} descriptor The report descriptor. + * @param {SourceCode} sourceCode The source code object to get text between fixes. + * @returns {({text: string, range: number[]}|null)} The fix for the descriptor + */ +function normalizeFixes(descriptor, sourceCode) { + if (typeof descriptor.fix !== "function") { + return null; + } + + // @type {null | Fix | Fix[] | IterableIterator} + const fix = descriptor.fix(ruleFixer_1); + + // Merge to one. + if (fix && Symbol.iterator in fix) { + return mergeFixes(Array.from(fix), sourceCode); + } + + assertValidFix(fix); + return fix; +} + +/** + * Gets an array of suggestion objects from the given descriptor. + * @param {MessageDescriptor} descriptor The report descriptor. + * @param {SourceCode} sourceCode The source code object to get text between fixes. + * @param {Object} messages Object of meta messages for the rule. + * @returns {Array} The suggestions for the descriptor + */ +function mapSuggestions(descriptor, sourceCode, messages) { + if (!descriptor.suggest || !Array.isArray(descriptor.suggest)) { + return []; + } + + return descriptor.suggest + .map(suggestInfo => { + const computedDesc = suggestInfo.desc || messages[suggestInfo.messageId]; + + return { + ...suggestInfo, + desc: interpolate$1(computedDesc, suggestInfo.data), + fix: normalizeFixes(suggestInfo, sourceCode) + }; + }) + + // Remove suggestions that didn't provide a fix + .filter(({ fix }) => fix); +} + +/** + * Creates information about the report from a descriptor + * @param {Object} options Information about the problem + * @param {string} options.ruleId Rule ID + * @param {(0|1|2)} options.severity Rule severity + * @param {(ASTNode|null)} options.node Node + * @param {string} options.message Error message + * @param {string} [options.messageId] The error message ID. + * @param {{start: SourceLocation, end: (SourceLocation|null)}} options.loc Start and end location + * @param {{text: string, range: (number[]|null)}} options.fix The fix object + * @param {Array<{text: string, range: (number[]|null)}>} options.suggestions The array of suggestions objects + * @returns {function(...args): ReportInfo} Function that returns information about the report + */ +function createProblem(options) { + const problem = { + ruleId: options.ruleId, + severity: options.severity, + message: options.message, + line: options.loc.start.line, + column: options.loc.start.column + 1, + nodeType: options.node && options.node.type || null + }; + + /* + * If this isn’t in the conditional, some of the tests fail + * because `messageId` is present in the problem object + */ + if (options.messageId) { + problem.messageId = options.messageId; + } + + if (options.loc.end) { + problem.endLine = options.loc.end.line; + problem.endColumn = options.loc.end.column + 1; + } + + if (options.fix) { + problem.fix = options.fix; + } + + if (options.suggestions && options.suggestions.length > 0) { + problem.suggestions = options.suggestions; + } + + return problem; +} + +/** + * Validates that suggestions are properly defined. Throws if an error is detected. + * @param {Array<{ desc?: string, messageId?: string }>} suggest The incoming suggest data. + * @param {Object} messages Object of meta messages for the rule. + * @returns {void} + */ +function validateSuggestions(suggest, messages) { + if (suggest && Array.isArray(suggest)) { + suggest.forEach(suggestion => { + if (suggestion.messageId) { + const { messageId } = suggestion; + + if (!messages) { + throw new TypeError(`context.report() called with a suggest option with a messageId '${messageId}', but no messages were present in the rule metadata.`); + } + + if (!messages[messageId]) { + throw new TypeError(`context.report() called with a suggest option with a messageId '${messageId}' which is not present in the 'messages' config: ${JSON.stringify(messages, null, 2)}`); + } + + if (suggestion.desc) { + throw new TypeError("context.report() called with a suggest option that defines both a 'messageId' and an 'desc'. Please only pass one."); + } + } else if (!suggestion.desc) { + throw new TypeError("context.report() called with a suggest option that doesn't have either a `desc` or `messageId`"); + } + + if (typeof suggestion.fix !== "function") { + throw new TypeError(`context.report() called with a suggest option without a fix function. See: ${suggestion}`); + } + }); + } +} + +/** + * Returns a function that converts the arguments of a `context.report` call from a rule into a reported + * problem for the Node.js API. + * @param {{ruleId: string, severity: number, sourceCode: SourceCode, messageIds: Object, disableFixes: boolean}} metadata Metadata for the reported problem + * @param {SourceCode} sourceCode The `SourceCode` instance for the text being linted + * @returns {function(...args): ReportInfo} Function that returns information about the report + */ + +var reportTranslator = function createReportTranslator(metadata) { + + /* + * `createReportTranslator` gets called once per enabled rule per file. It needs to be very performant. + * The report translator itself (i.e. the function that `createReportTranslator` returns) gets + * called every time a rule reports a problem, which happens much less frequently (usually, the vast + * majority of rules don't report any problems for a given file). + */ + return (...args) => { + const descriptor = normalizeMultiArgReportCall(...args); + const messages = metadata.messageIds; + + assertValidNodeInfo(descriptor); + + let computedMessage; + + if (descriptor.messageId) { + if (!messages) { + throw new TypeError("context.report() called with a messageId, but no messages were present in the rule metadata."); + } + const id = descriptor.messageId; + + if (descriptor.message) { + throw new TypeError("context.report() called with a message and a messageId. Please only pass one."); + } + if (!messages || !Object.prototype.hasOwnProperty.call(messages, id)) { + throw new TypeError(`context.report() called with a messageId of '${id}' which is not present in the 'messages' config: ${JSON.stringify(messages, null, 2)}`); + } + computedMessage = messages[id]; + } else if (descriptor.message) { + computedMessage = descriptor.message; + } else { + throw new TypeError("Missing `message` property in report() call; add a message that describes the linting problem."); + } + + validateSuggestions(descriptor.suggest, messages); + + return createProblem({ + ruleId: metadata.ruleId, + severity: metadata.severity, + node: descriptor.node, + message: interpolate$1(computedMessage, descriptor.data), + messageId: descriptor.messageId, + loc: normalizeReportLoc(descriptor), + fix: metadata.disableFixes ? null : normalizeFixes(descriptor, metadata.sourceCode), + suggestions: metadata.disableFixes ? [] : mapSuggestions(descriptor, metadata.sourceCode, messages) + }); + }; +}; + +/** + * @fileoverview `Map` to load rules lazily. + * @author Toru Nagashima + */ + +const debug$4 = require$$0__default['default']("eslint:rules"); + +/** @typedef {import("./types").Rule} Rule */ + +/** + * The `Map` object that loads each rule when it's accessed. + * @example + * const rules = new LazyLoadingRuleMap([ + * ["eqeqeq", () => require("eqeqeq")], + * ["semi", () => require("semi")], + * ["no-unused-vars", () => require("no-unused-vars")], + * ]) + * + * rules.get("semi") // call `() => require("semi")` here. + * + * @extends {Map Rule>} + */ +class LazyLoadingRuleMap$1 extends Map { + + /** + * Initialize this map. + * @param {Array<[string, function(): Rule]>} loaders The rule loaders. + */ + constructor(loaders) { + let remaining = loaders.length; + + super( + debug$4.enabled + ? loaders.map(([ruleId, load]) => { + let cache = null; + + return [ + ruleId, + () => { + if (!cache) { + debug$4("Loading rule %o (remaining=%d)", ruleId, --remaining); + cache = load(); + } + return cache; + } + ]; + }) + : loaders + ); + + // `super(...iterable)` uses `this.set()`, so disable it here. + Object.defineProperty(LazyLoadingRuleMap$1.prototype, "set", { + configurable: true, + value: void 0 + }); + } + + /** + * Get a rule. + * Each rule will be loaded on the first access. + * @param {string} ruleId The rule ID to get. + * @returns {Rule|undefined} The rule. + */ + get(ruleId) { + const load = super.get(ruleId); + + return load && load(); + } + + /** + * Iterate rules. + * @returns {IterableIterator} Rules. + */ + *values() { + for (const load of super.values()) { + yield load(); + } + } + + /** + * Iterate rules. + * @returns {IterableIterator<[string, Rule]>} Rules. + */ + *entries() { + for (const [ruleId, load] of super.entries()) { + yield [ruleId, load()]; + } + } + + /** + * Call a function with each rule. + * @param {Function} callbackFn The callback function. + * @param {any} [thisArg] The object to pass to `this` of the callback function. + * @returns {void} + */ + forEach(callbackFn, thisArg) { + for (const [ruleId, load] of super.entries()) { + callbackFn.call(thisArg, load(), ruleId, this); + } + } +} + +// Forbid mutation. +Object.defineProperties(LazyLoadingRuleMap$1.prototype, { + clear: { configurable: true, value: void 0 }, + delete: { configurable: true, value: void 0 }, + [Symbol.iterator]: { + configurable: true, + writable: true, + value: LazyLoadingRuleMap$1.prototype.entries + } +}); + +var lazyLoadingRuleMap = { LazyLoadingRuleMap: LazyLoadingRuleMap$1 }; + +/** + * @fileoverview Common utils for AST. + * @author Gyandeep Singh + */ + +var astUtils = createCommonjsModule(function (module) { + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +const { + breakableTypePattern, + createGlobalLinebreakMatcher, + lineBreakPattern, + shebangPattern +} = astUtils$1; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const anyFunctionPattern = /^(?:Function(?:Declaration|Expression)|ArrowFunctionExpression)$/u; +const anyLoopPattern = /^(?:DoWhile|For|ForIn|ForOf|While)Statement$/u; +const arrayOrTypedArrayPattern = /Array$/u; +const arrayMethodPattern = /^(?:every|filter|find|findIndex|forEach|map|some)$/u; +const bindOrCallOrApplyPattern = /^(?:bind|call|apply)$/u; +const thisTagPattern = /^[\s*]*@this/mu; + + +const COMMENTS_IGNORE_PATTERN = /^\s*(?:eslint|jshint\s+|jslint\s+|istanbul\s+|globals?\s+|exported\s+|jscs)/u; +const LINEBREAKS = new Set(["\r\n", "\r", "\n", "\u2028", "\u2029"]); + +// A set of node types that can contain a list of statements +const STATEMENT_LIST_PARENTS = new Set(["Program", "BlockStatement", "SwitchCase"]); + +const DECIMAL_INTEGER_PATTERN = /^(?:0|0[0-7]*[89]\d*|[1-9](?:_?\d)*)$/u; + +// Tests the presence of at least one LegacyOctalEscapeSequence or NonOctalDecimalEscapeSequence in a raw string +const OCTAL_OR_NON_OCTAL_DECIMAL_ESCAPE_PATTERN = /^(?:[^\\]|\\.)*\\(?:[1-9]|0[0-9])/su; + +const LOGICAL_ASSIGNMENT_OPERATORS = new Set(["&&=", "||=", "??="]); + +/** + * Checks reference if is non initializer and writable. + * @param {Reference} reference A reference to check. + * @param {int} index The index of the reference in the references. + * @param {Reference[]} references The array that the reference belongs to. + * @returns {boolean} Success/Failure + * @private + */ +function isModifyingReference(reference, index, references) { + const identifier = reference.identifier; + + /* + * Destructuring assignments can have multiple default value, so + * possibly there are multiple writeable references for the same + * identifier. + */ + const modifyingDifferentIdentifier = index === 0 || + references[index - 1].identifier !== identifier; + + return (identifier && + reference.init === false && + reference.isWrite() && + modifyingDifferentIdentifier + ); +} + +/** + * Checks whether the given string starts with uppercase or not. + * @param {string} s The string to check. + * @returns {boolean} `true` if the string starts with uppercase. + */ +function startsWithUpperCase(s) { + return s[0] !== s[0].toLocaleLowerCase(); +} + +/** + * Checks whether or not a node is a constructor. + * @param {ASTNode} node A function node to check. + * @returns {boolean} Whether or not a node is a constructor. + */ +function isES5Constructor(node) { + return (node.id && startsWithUpperCase(node.id.name)); +} + +/** + * Finds a function node from ancestors of a node. + * @param {ASTNode} node A start node to find. + * @returns {Node|null} A found function node. + */ +function getUpperFunction(node) { + for (let currentNode = node; currentNode; currentNode = currentNode.parent) { + if (anyFunctionPattern.test(currentNode.type)) { + return currentNode; + } + } + return null; +} + +/** + * Checks whether a given node is a function node or not. + * The following types are function nodes: + * + * - ArrowFunctionExpression + * - FunctionDeclaration + * - FunctionExpression + * @param {ASTNode|null} node A node to check. + * @returns {boolean} `true` if the node is a function node. + */ +function isFunction(node) { + return Boolean(node && anyFunctionPattern.test(node.type)); +} + +/** + * Checks whether a given node is a loop node or not. + * The following types are loop nodes: + * + * - DoWhileStatement + * - ForInStatement + * - ForOfStatement + * - ForStatement + * - WhileStatement + * @param {ASTNode|null} node A node to check. + * @returns {boolean} `true` if the node is a loop node. + */ +function isLoop(node) { + return Boolean(node && anyLoopPattern.test(node.type)); +} + +/** + * Checks whether the given node is in a loop or not. + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if the node is in a loop. + */ +function isInLoop(node) { + for (let currentNode = node; currentNode && !isFunction(currentNode); currentNode = currentNode.parent) { + if (isLoop(currentNode)) { + return true; + } + } + + return false; +} + +/** + * Determines whether the given node is a `null` literal. + * @param {ASTNode} node The node to check + * @returns {boolean} `true` if the node is a `null` literal + */ +function isNullLiteral(node) { + + /* + * Checking `node.value === null` does not guarantee that a literal is a null literal. + * When parsing values that cannot be represented in the current environment (e.g. unicode + * regexes in Node 4), `node.value` is set to `null` because it wouldn't be possible to + * set `node.value` to a unicode regex. To make sure a literal is actually `null`, check + * `node.regex` instead. Also see: https://github.com/eslint/eslint/issues/8020 + */ + return node.type === "Literal" && node.value === null && !node.regex && !node.bigint; +} + +/** + * Checks whether or not a node is `null` or `undefined`. + * @param {ASTNode} node A node to check. + * @returns {boolean} Whether or not the node is a `null` or `undefined`. + * @public + */ +function isNullOrUndefined(node) { + return ( + isNullLiteral(node) || + (node.type === "Identifier" && node.name === "undefined") || + (node.type === "UnaryExpression" && node.operator === "void") + ); +} + +/** + * Checks whether or not a node is callee. + * @param {ASTNode} node A node to check. + * @returns {boolean} Whether or not the node is callee. + */ +function isCallee(node) { + return node.parent.type === "CallExpression" && node.parent.callee === node; +} + +/** + * Returns the result of the string conversion applied to the evaluated value of the given expression node, + * if it can be determined statically. + * + * This function returns a `string` value for all `Literal` nodes and simple `TemplateLiteral` nodes only. + * In all other cases, this function returns `null`. + * @param {ASTNode} node Expression node. + * @returns {string|null} String value if it can be determined. Otherwise, `null`. + */ +function getStaticStringValue(node) { + switch (node.type) { + case "Literal": + if (node.value === null) { + if (isNullLiteral(node)) { + return String(node.value); // "null" + } + if (node.regex) { + return `/${node.regex.pattern}/${node.regex.flags}`; + } + if (node.bigint) { + return node.bigint; + } + + // Otherwise, this is an unknown literal. The function will return null. + + } else { + return String(node.value); + } + break; + case "TemplateLiteral": + if (node.expressions.length === 0 && node.quasis.length === 1) { + return node.quasis[0].value.cooked; + } + break; + + // no default + } + + return null; +} + +/** + * Gets the property name of a given node. + * The node can be a MemberExpression, a Property, or a MethodDefinition. + * + * If the name is dynamic, this returns `null`. + * + * For examples: + * + * a.b // => "b" + * a["b"] // => "b" + * a['b'] // => "b" + * a[`b`] // => "b" + * a[100] // => "100" + * a[b] // => null + * a["a" + "b"] // => null + * a[tag`b`] // => null + * a[`${b}`] // => null + * + * let a = {b: 1} // => "b" + * let a = {["b"]: 1} // => "b" + * let a = {['b']: 1} // => "b" + * let a = {[`b`]: 1} // => "b" + * let a = {[100]: 1} // => "100" + * let a = {[b]: 1} // => null + * let a = {["a" + "b"]: 1} // => null + * let a = {[tag`b`]: 1} // => null + * let a = {[`${b}`]: 1} // => null + * @param {ASTNode} node The node to get. + * @returns {string|null} The property name if static. Otherwise, null. + */ +function getStaticPropertyName(node) { + let prop; + + switch (node && node.type) { + case "ChainExpression": + return getStaticPropertyName(node.expression); + + case "Property": + case "MethodDefinition": + prop = node.key; + break; + + case "MemberExpression": + prop = node.property; + break; + + // no default + } + + if (prop) { + if (prop.type === "Identifier" && !node.computed) { + return prop.name; + } + + return getStaticStringValue(prop); + } + + return null; +} + +/** + * Retrieve `ChainExpression#expression` value if the given node a `ChainExpression` node. Otherwise, pass through it. + * @param {ASTNode} node The node to address. + * @returns {ASTNode} The `ChainExpression#expression` value if the node is a `ChainExpression` node. Otherwise, the node. + */ +function skipChainExpression(node) { + return node && node.type === "ChainExpression" ? node.expression : node; +} + +/** + * Check if the `actual` is an expected value. + * @param {string} actual The string value to check. + * @param {string | RegExp} expected The expected string value or pattern. + * @returns {boolean} `true` if the `actual` is an expected value. + */ +function checkText(actual, expected) { + return typeof expected === "string" + ? actual === expected + : expected.test(actual); +} + +/** + * Check if a given node is an Identifier node with a given name. + * @param {ASTNode} node The node to check. + * @param {string | RegExp} name The expected name or the expected pattern of the object name. + * @returns {boolean} `true` if the node is an Identifier node with the name. + */ +function isSpecificId(node, name) { + return node.type === "Identifier" && checkText(node.name, name); +} + +/** + * Check if a given node is member access with a given object name and property name pair. + * This is regardless of optional or not. + * @param {ASTNode} node The node to check. + * @param {string | RegExp | null} objectName The expected name or the expected pattern of the object name. If this is nullish, this method doesn't check object. + * @param {string | RegExp | null} propertyName The expected name or the expected pattern of the property name. If this is nullish, this method doesn't check property. + * @returns {boolean} `true` if the node is member access with the object name and property name pair. + * The node is a `MemberExpression` or `ChainExpression`. + */ +function isSpecificMemberAccess(node, objectName, propertyName) { + const checkNode = skipChainExpression(node); + + if (checkNode.type !== "MemberExpression") { + return false; + } + + if (objectName && !isSpecificId(checkNode.object, objectName)) { + return false; + } + + if (propertyName) { + const actualPropertyName = getStaticPropertyName(checkNode); + + if (typeof actualPropertyName !== "string" || !checkText(actualPropertyName, propertyName)) { + return false; + } + } + + return true; +} + +/** + * Check if two literal nodes are the same value. + * @param {ASTNode} left The Literal node to compare. + * @param {ASTNode} right The other Literal node to compare. + * @returns {boolean} `true` if the two literal nodes are the same value. + */ +function equalLiteralValue(left, right) { + + // RegExp literal. + if (left.regex || right.regex) { + return Boolean( + left.regex && + right.regex && + left.regex.pattern === right.regex.pattern && + left.regex.flags === right.regex.flags + ); + } + + // BigInt literal. + if (left.bigint || right.bigint) { + return left.bigint === right.bigint; + } + + return left.value === right.value; +} + +/** + * Check if two expressions reference the same value. For example: + * a = a + * a.b = a.b + * a[0] = a[0] + * a['b'] = a['b'] + * @param {ASTNode} left The left side of the comparison. + * @param {ASTNode} right The right side of the comparison. + * @param {boolean} [disableStaticComputedKey] Don't address `a.b` and `a["b"]` are the same if `true`. For backward compatibility. + * @returns {boolean} `true` if both sides match and reference the same value. + */ +function isSameReference(left, right, disableStaticComputedKey = false) { + if (left.type !== right.type) { + + // Handle `a.b` and `a?.b` are samely. + if (left.type === "ChainExpression") { + return isSameReference(left.expression, right, disableStaticComputedKey); + } + if (right.type === "ChainExpression") { + return isSameReference(left, right.expression, disableStaticComputedKey); + } + + return false; + } + + switch (left.type) { + case "Super": + case "ThisExpression": + return true; + + case "Identifier": + return left.name === right.name; + case "Literal": + return equalLiteralValue(left, right); + + case "ChainExpression": + return isSameReference(left.expression, right.expression, disableStaticComputedKey); + + case "MemberExpression": { + if (!disableStaticComputedKey) { + const nameA = getStaticPropertyName(left); + + // x.y = x["y"] + if (nameA !== null) { + return ( + isSameReference(left.object, right.object, disableStaticComputedKey) && + nameA === getStaticPropertyName(right) + ); + } + } + + /* + * x[0] = x[0] + * x[y] = x[y] + * x.y = x.y + */ + return ( + left.computed === right.computed && + isSameReference(left.object, right.object, disableStaticComputedKey) && + isSameReference(left.property, right.property, disableStaticComputedKey) + ); + } + + default: + return false; + } +} + +/** + * Checks whether or not a node is `Reflect.apply`. + * @param {ASTNode} node A node to check. + * @returns {boolean} Whether or not the node is a `Reflect.apply`. + */ +function isReflectApply(node) { + return isSpecificMemberAccess(node, "Reflect", "apply"); +} + +/** + * Checks whether or not a node is `Array.from`. + * @param {ASTNode} node A node to check. + * @returns {boolean} Whether or not the node is a `Array.from`. + */ +function isArrayFromMethod(node) { + return isSpecificMemberAccess(node, arrayOrTypedArrayPattern, "from"); +} + +/** + * Checks whether or not a node is a method which has `thisArg`. + * @param {ASTNode} node A node to check. + * @returns {boolean} Whether or not the node is a method which has `thisArg`. + */ +function isMethodWhichHasThisArg(node) { + return isSpecificMemberAccess(node, null, arrayMethodPattern); +} + +/** + * Creates the negate function of the given function. + * @param {Function} f The function to negate. + * @returns {Function} Negated function. + */ +function negate(f) { + return token => !f(token); +} + +/** + * Checks whether or not a node has a `@this` tag in its comments. + * @param {ASTNode} node A node to check. + * @param {SourceCode} sourceCode A SourceCode instance to get comments. + * @returns {boolean} Whether or not the node has a `@this` tag in its comments. + */ +function hasJSDocThisTag(node, sourceCode) { + const jsdocComment = sourceCode.getJSDocComment(node); + + if (jsdocComment && thisTagPattern.test(jsdocComment.value)) { + return true; + } + + // Checks `@this` in its leading comments for callbacks, + // because callbacks don't have its JSDoc comment. + // e.g. + // sinon.test(/* @this sinon.Sandbox */function() { this.spy(); }); + return sourceCode.getCommentsBefore(node).some(comment => thisTagPattern.test(comment.value)); +} + +/** + * Determines if a node is surrounded by parentheses. + * @param {SourceCode} sourceCode The ESLint source code object + * @param {ASTNode} node The node to be checked. + * @returns {boolean} True if the node is parenthesised. + * @private + */ +function isParenthesised(sourceCode, node) { + const previousToken = sourceCode.getTokenBefore(node), + nextToken = sourceCode.getTokenAfter(node); + + return Boolean(previousToken && nextToken) && + previousToken.value === "(" && previousToken.range[1] <= node.range[0] && + nextToken.value === ")" && nextToken.range[0] >= node.range[1]; +} + +/** + * Checks if the given token is an arrow token or not. + * @param {Token} token The token to check. + * @returns {boolean} `true` if the token is an arrow token. + */ +function isArrowToken(token) { + return token.value === "=>" && token.type === "Punctuator"; +} + +/** + * Checks if the given token is a comma token or not. + * @param {Token} token The token to check. + * @returns {boolean} `true` if the token is a comma token. + */ +function isCommaToken(token) { + return token.value === "," && token.type === "Punctuator"; +} + +/** + * Checks if the given token is a dot token or not. + * @param {Token} token The token to check. + * @returns {boolean} `true` if the token is a dot token. + */ +function isDotToken(token) { + return token.value === "." && token.type === "Punctuator"; +} + +/** + * Checks if the given token is a `?.` token or not. + * @param {Token} token The token to check. + * @returns {boolean} `true` if the token is a `?.` token. + */ +function isQuestionDotToken(token) { + return token.value === "?." && token.type === "Punctuator"; +} + +/** + * Checks if the given token is a semicolon token or not. + * @param {Token} token The token to check. + * @returns {boolean} `true` if the token is a semicolon token. + */ +function isSemicolonToken(token) { + return token.value === ";" && token.type === "Punctuator"; +} + +/** + * Checks if the given token is a colon token or not. + * @param {Token} token The token to check. + * @returns {boolean} `true` if the token is a colon token. + */ +function isColonToken(token) { + return token.value === ":" && token.type === "Punctuator"; +} + +/** + * Checks if the given token is an opening parenthesis token or not. + * @param {Token} token The token to check. + * @returns {boolean} `true` if the token is an opening parenthesis token. + */ +function isOpeningParenToken(token) { + return token.value === "(" && token.type === "Punctuator"; +} + +/** + * Checks if the given token is a closing parenthesis token or not. + * @param {Token} token The token to check. + * @returns {boolean} `true` if the token is a closing parenthesis token. + */ +function isClosingParenToken(token) { + return token.value === ")" && token.type === "Punctuator"; +} + +/** + * Checks if the given token is an opening square bracket token or not. + * @param {Token} token The token to check. + * @returns {boolean} `true` if the token is an opening square bracket token. + */ +function isOpeningBracketToken(token) { + return token.value === "[" && token.type === "Punctuator"; +} + +/** + * Checks if the given token is a closing square bracket token or not. + * @param {Token} token The token to check. + * @returns {boolean} `true` if the token is a closing square bracket token. + */ +function isClosingBracketToken(token) { + return token.value === "]" && token.type === "Punctuator"; +} + +/** + * Checks if the given token is an opening brace token or not. + * @param {Token} token The token to check. + * @returns {boolean} `true` if the token is an opening brace token. + */ +function isOpeningBraceToken(token) { + return token.value === "{" && token.type === "Punctuator"; +} + +/** + * Checks if the given token is a closing brace token or not. + * @param {Token} token The token to check. + * @returns {boolean} `true` if the token is a closing brace token. + */ +function isClosingBraceToken(token) { + return token.value === "}" && token.type === "Punctuator"; +} + +/** + * Checks if the given token is a comment token or not. + * @param {Token} token The token to check. + * @returns {boolean} `true` if the token is a comment token. + */ +function isCommentToken(token) { + return token.type === "Line" || token.type === "Block" || token.type === "Shebang"; +} + +/** + * Checks if the given token is a keyword token or not. + * @param {Token} token The token to check. + * @returns {boolean} `true` if the token is a keyword token. + */ +function isKeywordToken(token) { + return token.type === "Keyword"; +} + +/** + * Gets the `(` token of the given function node. + * @param {ASTNode} node The function node to get. + * @param {SourceCode} sourceCode The source code object to get tokens. + * @returns {Token} `(` token. + */ +function getOpeningParenOfParams(node, sourceCode) { + return node.id + ? sourceCode.getTokenAfter(node.id, isOpeningParenToken) + : sourceCode.getFirstToken(node, isOpeningParenToken); +} + +/** + * Checks whether or not the tokens of two given nodes are same. + * @param {ASTNode} left A node 1 to compare. + * @param {ASTNode} right A node 2 to compare. + * @param {SourceCode} sourceCode The ESLint source code object. + * @returns {boolean} the source code for the given node. + */ +function equalTokens(left, right, sourceCode) { + const tokensL = sourceCode.getTokens(left); + const tokensR = sourceCode.getTokens(right); + + if (tokensL.length !== tokensR.length) { + return false; + } + for (let i = 0; i < tokensL.length; ++i) { + if (tokensL[i].type !== tokensR[i].type || + tokensL[i].value !== tokensR[i].value + ) { + return false; + } + } + + return true; +} + +/** + * Check if the given node is a true logical expression or not. + * + * The three binary expressions logical-or (`||`), logical-and (`&&`), and + * coalesce (`??`) are known as `ShortCircuitExpression`. + * But ESTree represents those by `LogicalExpression` node. + * + * This function rejects coalesce expressions of `LogicalExpression` node. + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if the node is `&&` or `||`. + * @see https://tc39.es/ecma262/#prod-ShortCircuitExpression + */ +function isLogicalExpression(node) { + return ( + node.type === "LogicalExpression" && + (node.operator === "&&" || node.operator === "||") + ); +} + +/** + * Check if the given node is a nullish coalescing expression or not. + * + * The three binary expressions logical-or (`||`), logical-and (`&&`), and + * coalesce (`??`) are known as `ShortCircuitExpression`. + * But ESTree represents those by `LogicalExpression` node. + * + * This function finds only coalesce expressions of `LogicalExpression` node. + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if the node is `??`. + */ +function isCoalesceExpression(node) { + return node.type === "LogicalExpression" && node.operator === "??"; +} + +/** + * Check if given two nodes are the pair of a logical expression and a coalesce expression. + * @param {ASTNode} left A node to check. + * @param {ASTNode} right Another node to check. + * @returns {boolean} `true` if the two nodes are the pair of a logical expression and a coalesce expression. + */ +function isMixedLogicalAndCoalesceExpressions(left, right) { + return ( + (isLogicalExpression(left) && isCoalesceExpression(right)) || + (isCoalesceExpression(left) && isLogicalExpression(right)) + ); +} + +/** + * Checks if the given operator is a logical assignment operator. + * @param {string} operator The operator to check. + * @returns {boolean} `true` if the operator is a logical assignment operator. + */ +function isLogicalAssignmentOperator(operator) { + return LOGICAL_ASSIGNMENT_OPERATORS.has(operator); +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +module.exports = { + COMMENTS_IGNORE_PATTERN, + LINEBREAKS, + LINEBREAK_MATCHER: lineBreakPattern, + SHEBANG_MATCHER: shebangPattern, + STATEMENT_LIST_PARENTS, + + /** + * Determines whether two adjacent tokens are on the same line. + * @param {Object} left The left token object. + * @param {Object} right The right token object. + * @returns {boolean} Whether or not the tokens are on the same line. + * @public + */ + isTokenOnSameLine(left, right) { + return left.loc.end.line === right.loc.start.line; + }, + + isNullOrUndefined, + isCallee, + isES5Constructor, + getUpperFunction, + isFunction, + isLoop, + isInLoop, + isArrayFromMethod, + isParenthesised, + createGlobalLinebreakMatcher, + equalTokens, + + isArrowToken, + isClosingBraceToken, + isClosingBracketToken, + isClosingParenToken, + isColonToken, + isCommaToken, + isCommentToken, + isDotToken, + isQuestionDotToken, + isKeywordToken, + isNotClosingBraceToken: negate(isClosingBraceToken), + isNotClosingBracketToken: negate(isClosingBracketToken), + isNotClosingParenToken: negate(isClosingParenToken), + isNotColonToken: negate(isColonToken), + isNotCommaToken: negate(isCommaToken), + isNotDotToken: negate(isDotToken), + isNotQuestionDotToken: negate(isQuestionDotToken), + isNotOpeningBraceToken: negate(isOpeningBraceToken), + isNotOpeningBracketToken: negate(isOpeningBracketToken), + isNotOpeningParenToken: negate(isOpeningParenToken), + isNotSemicolonToken: negate(isSemicolonToken), + isOpeningBraceToken, + isOpeningBracketToken, + isOpeningParenToken, + isSemicolonToken, + + /** + * Checks whether or not a given node is a string literal. + * @param {ASTNode} node A node to check. + * @returns {boolean} `true` if the node is a string literal. + */ + isStringLiteral(node) { + return ( + (node.type === "Literal" && typeof node.value === "string") || + node.type === "TemplateLiteral" + ); + }, + + /** + * Checks whether a given node is a breakable statement or not. + * The node is breakable if the node is one of the following type: + * + * - DoWhileStatement + * - ForInStatement + * - ForOfStatement + * - ForStatement + * - SwitchStatement + * - WhileStatement + * @param {ASTNode} node A node to check. + * @returns {boolean} `true` if the node is breakable. + */ + isBreakableStatement(node) { + return breakableTypePattern.test(node.type); + }, + + /** + * Gets references which are non initializer and writable. + * @param {Reference[]} references An array of references. + * @returns {Reference[]} An array of only references which are non initializer and writable. + * @public + */ + getModifyingReferences(references) { + return references.filter(isModifyingReference); + }, + + /** + * Validate that a string passed in is surrounded by the specified character + * @param {string} val The text to check. + * @param {string} character The character to see if it's surrounded by. + * @returns {boolean} True if the text is surrounded by the character, false if not. + * @private + */ + isSurroundedBy(val, character) { + return val[0] === character && val[val.length - 1] === character; + }, + + /** + * Returns whether the provided node is an ESLint directive comment or not + * @param {Line|Block} node The comment token to be checked + * @returns {boolean} `true` if the node is an ESLint directive comment + */ + isDirectiveComment(node) { + const comment = node.value.trim(); + + return ( + node.type === "Line" && comment.indexOf("eslint-") === 0 || + node.type === "Block" && ( + comment.indexOf("global ") === 0 || + comment.indexOf("eslint ") === 0 || + comment.indexOf("eslint-") === 0 + ) + ); + }, + + /** + * Gets the trailing statement of a given node. + * + * if (code) + * consequent; + * + * When taking this `IfStatement`, returns `consequent;` statement. + * @param {ASTNode} A node to get. + * @returns {ASTNode|null} The trailing statement's node. + */ + getTrailingStatement: esutils__default['default'].ast.trailingStatement, + + /** + * Finds the variable by a given name in a given scope and its upper scopes. + * @param {eslint-scope.Scope} initScope A scope to start find. + * @param {string} name A variable name to find. + * @returns {eslint-scope.Variable|null} A found variable or `null`. + */ + getVariableByName(initScope, name) { + let scope = initScope; + + while (scope) { + const variable = scope.set.get(name); + + if (variable) { + return variable; + } + + scope = scope.upper; + } + + return null; + }, + + /** + * Checks whether or not a given function node is the default `this` binding. + * + * First, this checks the node: + * + * - The function name does not start with uppercase. It's a convention to capitalize the names + * of constructor functions. This check is not performed if `capIsConstructor` is set to `false`. + * - The function does not have a JSDoc comment that has a @this tag. + * + * Next, this checks the location of the node. + * If the location is below, this judges `this` is valid. + * + * - The location is not on an object literal. + * - The location is not assigned to a variable which starts with an uppercase letter. Applies to anonymous + * functions only, as the name of the variable is considered to be the name of the function in this case. + * This check is not performed if `capIsConstructor` is set to `false`. + * - The location is not on an ES2015 class. + * - Its `bind`/`call`/`apply` method is not called directly. + * - The function is not a callback of array methods (such as `.forEach()`) if `thisArg` is given. + * @param {ASTNode} node A function node to check. + * @param {SourceCode} sourceCode A SourceCode instance to get comments. + * @param {boolean} [capIsConstructor = true] `false` disables the assumption that functions which name starts + * with an uppercase or are assigned to a variable which name starts with an uppercase are constructors. + * @returns {boolean} The function node is the default `this` binding. + */ + isDefaultThisBinding(node, sourceCode, { capIsConstructor = true } = {}) { + if ( + (capIsConstructor && isES5Constructor(node)) || + hasJSDocThisTag(node, sourceCode) + ) { + return false; + } + const isAnonymous = node.id === null; + let currentNode = node; + + while (currentNode) { + const parent = currentNode.parent; + + switch (parent.type) { + + /* + * Looks up the destination. + * e.g., obj.foo = nativeFoo || function foo() { ... }; + */ + case "LogicalExpression": + case "ConditionalExpression": + case "ChainExpression": + currentNode = parent; + break; + + /* + * If the upper function is IIFE, checks the destination of the return value. + * e.g. + * obj.foo = (function() { + * // setup... + * return function foo() { ... }; + * })(); + * obj.foo = (() => + * function foo() { ... } + * )(); + */ + case "ReturnStatement": { + const func = getUpperFunction(parent); + + if (func === null || !isCallee(func)) { + return true; + } + currentNode = func.parent; + break; + } + case "ArrowFunctionExpression": + if (currentNode !== parent.body || !isCallee(parent)) { + return true; + } + currentNode = parent.parent; + break; + + /* + * e.g. + * var obj = { foo() { ... } }; + * var obj = { foo: function() { ... } }; + * class A { constructor() { ... } } + * class A { foo() { ... } } + * class A { get foo() { ... } } + * class A { set foo() { ... } } + * class A { static foo() { ... } } + */ + case "Property": + case "MethodDefinition": + return parent.value !== currentNode; + + /* + * e.g. + * obj.foo = function foo() { ... }; + * Foo = function() { ... }; + * [obj.foo = function foo() { ... }] = a; + * [Foo = function() { ... }] = a; + */ + case "AssignmentExpression": + case "AssignmentPattern": + if (parent.left.type === "MemberExpression") { + return false; + } + if ( + capIsConstructor && + isAnonymous && + parent.left.type === "Identifier" && + startsWithUpperCase(parent.left.name) + ) { + return false; + } + return true; + + /* + * e.g. + * var Foo = function() { ... }; + */ + case "VariableDeclarator": + return !( + capIsConstructor && + isAnonymous && + parent.init === currentNode && + parent.id.type === "Identifier" && + startsWithUpperCase(parent.id.name) + ); + + /* + * e.g. + * var foo = function foo() { ... }.bind(obj); + * (function foo() { ... }).call(obj); + * (function foo() { ... }).apply(obj, []); + */ + case "MemberExpression": + if ( + parent.object === currentNode && + isSpecificMemberAccess(parent, null, bindOrCallOrApplyPattern) + ) { + const maybeCalleeNode = parent.parent.type === "ChainExpression" + ? parent.parent + : parent; + + return !( + isCallee(maybeCalleeNode) && + maybeCalleeNode.parent.arguments.length >= 1 && + !isNullOrUndefined(maybeCalleeNode.parent.arguments[0]) + ); + } + return true; + + /* + * e.g. + * Reflect.apply(function() {}, obj, []); + * Array.from([], function() {}, obj); + * list.forEach(function() {}, obj); + */ + case "CallExpression": + if (isReflectApply(parent.callee)) { + return ( + parent.arguments.length !== 3 || + parent.arguments[0] !== currentNode || + isNullOrUndefined(parent.arguments[1]) + ); + } + if (isArrayFromMethod(parent.callee)) { + return ( + parent.arguments.length !== 3 || + parent.arguments[1] !== currentNode || + isNullOrUndefined(parent.arguments[2]) + ); + } + if (isMethodWhichHasThisArg(parent.callee)) { + return ( + parent.arguments.length !== 2 || + parent.arguments[0] !== currentNode || + isNullOrUndefined(parent.arguments[1]) + ); + } + return true; + + // Otherwise `this` is default. + default: + return true; + } + } + + /* istanbul ignore next */ + return true; + }, + + /** + * Get the precedence level based on the node type + * @param {ASTNode} node node to evaluate + * @returns {int} precedence level + * @private + */ + getPrecedence(node) { + switch (node.type) { + case "SequenceExpression": + return 0; + + case "AssignmentExpression": + case "ArrowFunctionExpression": + case "YieldExpression": + return 1; + + case "ConditionalExpression": + return 3; + + case "LogicalExpression": + switch (node.operator) { + case "||": + case "??": + return 4; + case "&&": + return 5; + + // no default + } + + /* falls through */ + + case "BinaryExpression": + + switch (node.operator) { + case "|": + return 6; + case "^": + return 7; + case "&": + return 8; + case "==": + case "!=": + case "===": + case "!==": + return 9; + case "<": + case "<=": + case ">": + case ">=": + case "in": + case "instanceof": + return 10; + case "<<": + case ">>": + case ">>>": + return 11; + case "+": + case "-": + return 12; + case "*": + case "/": + case "%": + return 13; + case "**": + return 15; + + // no default + } + + /* falls through */ + + case "UnaryExpression": + case "AwaitExpression": + return 16; + + case "UpdateExpression": + return 17; + + case "CallExpression": + case "ChainExpression": + case "ImportExpression": + return 18; + + case "NewExpression": + return 19; + + default: + return 20; + } + }, + + /** + * Checks whether the given node is an empty block node or not. + * @param {ASTNode|null} node The node to check. + * @returns {boolean} `true` if the node is an empty block. + */ + isEmptyBlock(node) { + return Boolean(node && node.type === "BlockStatement" && node.body.length === 0); + }, + + /** + * Checks whether the given node is an empty function node or not. + * @param {ASTNode|null} node The node to check. + * @returns {boolean} `true` if the node is an empty function. + */ + isEmptyFunction(node) { + return isFunction(node) && module.exports.isEmptyBlock(node.body); + }, + + /** + * Get directives from directive prologue of a Program or Function node. + * @param {ASTNode} node The node to check. + * @returns {ASTNode[]} The directives found in the directive prologue. + */ + getDirectivePrologue(node) { + const directives = []; + + // Directive prologues only occur at the top of files or functions. + if ( + node.type === "Program" || + node.type === "FunctionDeclaration" || + node.type === "FunctionExpression" || + + /* + * Do not check arrow functions with implicit return. + * `() => "use strict";` returns the string `"use strict"`. + */ + (node.type === "ArrowFunctionExpression" && node.body.type === "BlockStatement") + ) { + const statements = node.type === "Program" ? node.body : node.body.body; + + for (const statement of statements) { + if ( + statement.type === "ExpressionStatement" && + statement.expression.type === "Literal" + ) { + directives.push(statement); + } else { + break; + } + } + } + + return directives; + }, + + + /** + * Determines whether this node is a decimal integer literal. If a node is a decimal integer literal, a dot added + * after the node will be parsed as a decimal point, rather than a property-access dot. + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if this node is a decimal integer. + * @example + * + * 0 // true + * 5 // true + * 50 // true + * 5_000 // true + * 1_234_56 // true + * 08 // true + * 0192 // true + * 5. // false + * .5 // false + * 5.0 // false + * 5.00_00 // false + * 05 // false + * 0x5 // false + * 0b101 // false + * 0b11_01 // false + * 0o5 // false + * 5e0 // false + * 5e1_000 // false + * 5n // false + * 1_000n // false + * '5' // false + */ + isDecimalInteger(node) { + return node.type === "Literal" && typeof node.value === "number" && + DECIMAL_INTEGER_PATTERN.test(node.raw); + }, + + /** + * Determines whether this token is a decimal integer numeric token. + * This is similar to isDecimalInteger(), but for tokens. + * @param {Token} token The token to check. + * @returns {boolean} `true` if this token is a decimal integer. + */ + isDecimalIntegerNumericToken(token) { + return token.type === "Numeric" && DECIMAL_INTEGER_PATTERN.test(token.value); + }, + + /** + * Gets the name and kind of the given function node. + * + * - `function foo() {}` .................... `function 'foo'` + * - `(function foo() {})` .................. `function 'foo'` + * - `(function() {})` ...................... `function` + * - `function* foo() {}` ................... `generator function 'foo'` + * - `(function* foo() {})` ................. `generator function 'foo'` + * - `(function*() {})` ..................... `generator function` + * - `() => {}` ............................. `arrow function` + * - `async () => {}` ....................... `async arrow function` + * - `({ foo: function foo() {} })` ......... `method 'foo'` + * - `({ foo: function() {} })` ............. `method 'foo'` + * - `({ ['foo']: function() {} })` ......... `method 'foo'` + * - `({ [foo]: function() {} })` ........... `method` + * - `({ foo() {} })` ....................... `method 'foo'` + * - `({ foo: function* foo() {} })` ........ `generator method 'foo'` + * - `({ foo: function*() {} })` ............ `generator method 'foo'` + * - `({ ['foo']: function*() {} })` ........ `generator method 'foo'` + * - `({ [foo]: function*() {} })` .......... `generator method` + * - `({ *foo() {} })` ...................... `generator method 'foo'` + * - `({ foo: async function foo() {} })` ... `async method 'foo'` + * - `({ foo: async function() {} })` ....... `async method 'foo'` + * - `({ ['foo']: async function() {} })` ... `async method 'foo'` + * - `({ [foo]: async function() {} })` ..... `async method` + * - `({ async foo() {} })` ................. `async method 'foo'` + * - `({ get foo() {} })` ................... `getter 'foo'` + * - `({ set foo(a) {} })` .................. `setter 'foo'` + * - `class A { constructor() {} }` ......... `constructor` + * - `class A { foo() {} }` ................. `method 'foo'` + * - `class A { *foo() {} }` ................ `generator method 'foo'` + * - `class A { async foo() {} }` ........... `async method 'foo'` + * - `class A { ['foo']() {} }` ............. `method 'foo'` + * - `class A { *['foo']() {} }` ............ `generator method 'foo'` + * - `class A { async ['foo']() {} }` ....... `async method 'foo'` + * - `class A { [foo]() {} }` ............... `method` + * - `class A { *[foo]() {} }` .............. `generator method` + * - `class A { async [foo]() {} }` ......... `async method` + * - `class A { get foo() {} }` ............. `getter 'foo'` + * - `class A { set foo(a) {} }` ............ `setter 'foo'` + * - `class A { static foo() {} }` .......... `static method 'foo'` + * - `class A { static *foo() {} }` ......... `static generator method 'foo'` + * - `class A { static async foo() {} }` .... `static async method 'foo'` + * - `class A { static get foo() {} }` ...... `static getter 'foo'` + * - `class A { static set foo(a) {} }` ..... `static setter 'foo'` + * @param {ASTNode} node The function node to get. + * @returns {string} The name and kind of the function node. + */ + getFunctionNameWithKind(node) { + const parent = node.parent; + const tokens = []; + + if (parent.type === "MethodDefinition" && parent.static) { + tokens.push("static"); + } + if (node.async) { + tokens.push("async"); + } + if (node.generator) { + tokens.push("generator"); + } + + if (node.type === "ArrowFunctionExpression") { + tokens.push("arrow", "function"); + } else if (parent.type === "Property" || parent.type === "MethodDefinition") { + if (parent.kind === "constructor") { + return "constructor"; + } + if (parent.kind === "get") { + tokens.push("getter"); + } else if (parent.kind === "set") { + tokens.push("setter"); + } else { + tokens.push("method"); + } + } else { + tokens.push("function"); + } + + if (node.id) { + tokens.push(`'${node.id.name}'`); + } else { + const name = getStaticPropertyName(parent); + + if (name !== null) { + tokens.push(`'${name}'`); + } + } + + return tokens.join(" "); + }, + + /** + * Gets the location of the given function node for reporting. + * + * - `function foo() {}` + * ^^^^^^^^^^^^ + * - `(function foo() {})` + * ^^^^^^^^^^^^ + * - `(function() {})` + * ^^^^^^^^ + * - `function* foo() {}` + * ^^^^^^^^^^^^^ + * - `(function* foo() {})` + * ^^^^^^^^^^^^^ + * - `(function*() {})` + * ^^^^^^^^^ + * - `() => {}` + * ^^ + * - `async () => {}` + * ^^ + * - `({ foo: function foo() {} })` + * ^^^^^^^^^^^^^^^^^ + * - `({ foo: function() {} })` + * ^^^^^^^^^^^^^ + * - `({ ['foo']: function() {} })` + * ^^^^^^^^^^^^^^^^^ + * - `({ [foo]: function() {} })` + * ^^^^^^^^^^^^^^^ + * - `({ foo() {} })` + * ^^^ + * - `({ foo: function* foo() {} })` + * ^^^^^^^^^^^^^^^^^^ + * - `({ foo: function*() {} })` + * ^^^^^^^^^^^^^^ + * - `({ ['foo']: function*() {} })` + * ^^^^^^^^^^^^^^^^^^ + * - `({ [foo]: function*() {} })` + * ^^^^^^^^^^^^^^^^ + * - `({ *foo() {} })` + * ^^^^ + * - `({ foo: async function foo() {} })` + * ^^^^^^^^^^^^^^^^^^^^^^^ + * - `({ foo: async function() {} })` + * ^^^^^^^^^^^^^^^^^^^ + * - `({ ['foo']: async function() {} })` + * ^^^^^^^^^^^^^^^^^^^^^^^ + * - `({ [foo]: async function() {} })` + * ^^^^^^^^^^^^^^^^^^^^^ + * - `({ async foo() {} })` + * ^^^^^^^^^ + * - `({ get foo() {} })` + * ^^^^^^^ + * - `({ set foo(a) {} })` + * ^^^^^^^ + * - `class A { constructor() {} }` + * ^^^^^^^^^^^ + * - `class A { foo() {} }` + * ^^^ + * - `class A { *foo() {} }` + * ^^^^ + * - `class A { async foo() {} }` + * ^^^^^^^^^ + * - `class A { ['foo']() {} }` + * ^^^^^^^ + * - `class A { *['foo']() {} }` + * ^^^^^^^^ + * - `class A { async ['foo']() {} }` + * ^^^^^^^^^^^^^ + * - `class A { [foo]() {} }` + * ^^^^^ + * - `class A { *[foo]() {} }` + * ^^^^^^ + * - `class A { async [foo]() {} }` + * ^^^^^^^^^^^ + * - `class A { get foo() {} }` + * ^^^^^^^ + * - `class A { set foo(a) {} }` + * ^^^^^^^ + * - `class A { static foo() {} }` + * ^^^^^^^^^^ + * - `class A { static *foo() {} }` + * ^^^^^^^^^^^ + * - `class A { static async foo() {} }` + * ^^^^^^^^^^^^^^^^ + * - `class A { static get foo() {} }` + * ^^^^^^^^^^^^^^ + * - `class A { static set foo(a) {} }` + * ^^^^^^^^^^^^^^ + * @param {ASTNode} node The function node to get. + * @param {SourceCode} sourceCode The source code object to get tokens. + * @returns {string} The location of the function node for reporting. + */ + getFunctionHeadLoc(node, sourceCode) { + const parent = node.parent; + let start = null; + let end = null; + + if (node.type === "ArrowFunctionExpression") { + const arrowToken = sourceCode.getTokenBefore(node.body, isArrowToken); + + start = arrowToken.loc.start; + end = arrowToken.loc.end; + } else if (parent.type === "Property" || parent.type === "MethodDefinition") { + start = parent.loc.start; + end = getOpeningParenOfParams(node, sourceCode).loc.start; + } else { + start = node.loc.start; + end = getOpeningParenOfParams(node, sourceCode).loc.start; + } + + return { + start: Object.assign({}, start), + end: Object.assign({}, end) + }; + }, + + /** + * Gets next location when the result is not out of bound, otherwise returns null. + * + * Assumptions: + * + * - The given location represents a valid location in the given source code. + * - Columns are 0-based. + * - Lines are 1-based. + * - Column immediately after the last character in a line (not incl. linebreaks) is considered to be a valid location. + * - If the source code ends with a linebreak, `sourceCode.lines` array will have an extra element (empty string) at the end. + * The start (column 0) of that extra line is considered to be a valid location. + * + * Examples of successive locations (line, column): + * + * code: foo + * locations: (1, 0) -> (1, 1) -> (1, 2) -> (1, 3) -> null + * + * code: foo + * locations: (1, 0) -> (1, 1) -> (1, 2) -> (1, 3) -> (2, 0) -> null + * + * code: foo + * locations: (1, 0) -> (1, 1) -> (1, 2) -> (1, 3) -> (2, 0) -> null + * + * code: ab + * locations: (1, 0) -> (1, 1) -> (2, 0) -> (2, 1) -> null + * + * code: ab + * locations: (1, 0) -> (1, 1) -> (2, 0) -> (2, 1) -> (3, 0) -> null + * + * code: ab + * locations: (1, 0) -> (1, 1) -> (2, 0) -> (2, 1) -> (3, 0) -> null + * + * code: a + * locations: (1, 0) -> (1, 1) -> (2, 0) -> (3, 0) -> null + * + * code: + * locations: (1, 0) -> (2, 0) -> null + * + * code: + * locations: (1, 0) -> null + * @param {SourceCode} sourceCode The sourceCode + * @param {{line: number, column: number}} location The location + * @returns {{line: number, column: number} | null} Next location + */ + getNextLocation(sourceCode, { line, column }) { + if (column < sourceCode.lines[line - 1].length) { + return { + line, + column: column + 1 + }; + } + + if (line < sourceCode.lines.length) { + return { + line: line + 1, + column: 0 + }; + } + + return null; + }, + + /** + * Gets the parenthesized text of a node. This is similar to sourceCode.getText(node), but it also includes any parentheses + * surrounding the node. + * @param {SourceCode} sourceCode The source code object + * @param {ASTNode} node An expression node + * @returns {string} The text representing the node, with all surrounding parentheses included + */ + getParenthesisedText(sourceCode, node) { + let leftToken = sourceCode.getFirstToken(node); + let rightToken = sourceCode.getLastToken(node); + + while ( + sourceCode.getTokenBefore(leftToken) && + sourceCode.getTokenBefore(leftToken).type === "Punctuator" && + sourceCode.getTokenBefore(leftToken).value === "(" && + sourceCode.getTokenAfter(rightToken) && + sourceCode.getTokenAfter(rightToken).type === "Punctuator" && + sourceCode.getTokenAfter(rightToken).value === ")" + ) { + leftToken = sourceCode.getTokenBefore(leftToken); + rightToken = sourceCode.getTokenAfter(rightToken); + } + + return sourceCode.getText().slice(leftToken.range[0], rightToken.range[1]); + }, + + /* + * Determine if a node has a possibility to be an Error object + * @param {ASTNode} node ASTNode to check + * @returns {boolean} True if there is a chance it contains an Error obj + */ + couldBeError(node) { + switch (node.type) { + case "Identifier": + case "CallExpression": + case "NewExpression": + case "MemberExpression": + case "TaggedTemplateExpression": + case "YieldExpression": + case "AwaitExpression": + case "ChainExpression": + return true; // possibly an error object. + + case "AssignmentExpression": + if (["=", "&&="].includes(node.operator)) { + return module.exports.couldBeError(node.right); + } + + if (["||=", "??="].includes(node.operator)) { + return module.exports.couldBeError(node.left) || module.exports.couldBeError(node.right); + } + + /** + * All other assignment operators are mathematical assignment operators (arithmetic or bitwise). + * An assignment expression with a mathematical operator can either evaluate to a primitive value, + * or throw, depending on the operands. Thus, it cannot evaluate to an `Error` object. + */ + return false; + + case "SequenceExpression": { + const exprs = node.expressions; + + return exprs.length !== 0 && module.exports.couldBeError(exprs[exprs.length - 1]); + } + + case "LogicalExpression": + + /* + * If the && operator short-circuits, the left side was falsy and therefore not an error, and if it + * doesn't short-circuit, it takes the value from the right side, so the right side must always be + * a plausible error. A future improvement could verify that the left side could be truthy by + * excluding falsy literals. + */ + if (node.operator === "&&") { + return module.exports.couldBeError(node.right); + } + + return module.exports.couldBeError(node.left) || module.exports.couldBeError(node.right); + + case "ConditionalExpression": + return module.exports.couldBeError(node.consequent) || module.exports.couldBeError(node.alternate); + + default: + return false; + } + }, + + /** + * Check if a given node is a numeric literal or not. + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if the node is a number or bigint literal. + */ + isNumericLiteral(node) { + return ( + node.type === "Literal" && + (typeof node.value === "number" || Boolean(node.bigint)) + ); + }, + + /** + * Determines whether two tokens can safely be placed next to each other without merging into a single token + * @param {Token|string} leftValue The left token. If this is a string, it will be tokenized and the last token will be used. + * @param {Token|string} rightValue The right token. If this is a string, it will be tokenized and the first token will be used. + * @returns {boolean} If the tokens cannot be safely placed next to each other, returns `false`. If the tokens can be placed + * next to each other, behavior is undefined (although it should return `true` in most cases). + */ + canTokensBeAdjacent(leftValue, rightValue) { + const espreeOptions = { + ecmaVersion: espree__default['default'].latestEcmaVersion, + comment: true, + range: true + }; + + let leftToken; + + if (typeof leftValue === "string") { + let tokens; + + try { + tokens = espree__default['default'].tokenize(leftValue, espreeOptions); + } catch { + return false; + } + + const comments = tokens.comments; + + leftToken = tokens[tokens.length - 1]; + if (comments.length) { + const lastComment = comments[comments.length - 1]; + + if (lastComment.range[0] > leftToken.range[0]) { + leftToken = lastComment; + } + } + } else { + leftToken = leftValue; + } + + if (leftToken.type === "Shebang") { + return false; + } + + let rightToken; + + if (typeof rightValue === "string") { + let tokens; + + try { + tokens = espree__default['default'].tokenize(rightValue, espreeOptions); + } catch { + return false; + } + + const comments = tokens.comments; + + rightToken = tokens[0]; + if (comments.length) { + const firstComment = comments[0]; + + if (firstComment.range[0] < rightToken.range[0]) { + rightToken = firstComment; + } + } + } else { + rightToken = rightValue; + } + + if (leftToken.type === "Punctuator" || rightToken.type === "Punctuator") { + if (leftToken.type === "Punctuator" && rightToken.type === "Punctuator") { + const PLUS_TOKENS = new Set(["+", "++"]); + const MINUS_TOKENS = new Set(["-", "--"]); + + return !( + PLUS_TOKENS.has(leftToken.value) && PLUS_TOKENS.has(rightToken.value) || + MINUS_TOKENS.has(leftToken.value) && MINUS_TOKENS.has(rightToken.value) + ); + } + if (leftToken.type === "Punctuator" && leftToken.value === "/") { + return !["Block", "Line", "RegularExpression"].includes(rightToken.type); + } + return true; + } + + if ( + leftToken.type === "String" || rightToken.type === "String" || + leftToken.type === "Template" || rightToken.type === "Template" + ) { + return true; + } + + if (leftToken.type !== "Numeric" && rightToken.type === "Numeric" && rightToken.value.startsWith(".")) { + return true; + } + + if (leftToken.type === "Block" || rightToken.type === "Block" || rightToken.type === "Line") { + return true; + } + + return false; + }, + + /** + * Get the `loc` object of a given name in a `/*globals` directive comment. + * @param {SourceCode} sourceCode The source code to convert index to loc. + * @param {Comment} comment The `/*globals` directive comment which include the name. + * @param {string} name The name to find. + * @returns {SourceLocation} The `loc` object. + */ + getNameLocationInGlobalDirectiveComment(sourceCode, comment, name) { + const namePattern = new RegExp(`[\\s,]${lodash__default['default'].escapeRegExp(name)}(?:$|[\\s,:])`, "gu"); + + // To ignore the first text "global". + namePattern.lastIndex = comment.value.indexOf("global") + 6; + + // Search a given variable name. + const match = namePattern.exec(comment.value); + + // Convert the index to loc. + const start = sourceCode.getLocFromIndex( + comment.range[0] + + "/*".length + + (match ? match.index + 1 : 0) + ); + const end = { + line: start.line, + column: start.column + (match ? name.length : 1) + }; + + return { start, end }; + }, + + /** + * Determines whether the given raw string contains an octal escape sequence + * or a non-octal decimal escape sequence ("\8", "\9"). + * + * "\1", "\2" ... "\7", "\8", "\9" + * "\00", "\01" ... "\07", "\08", "\09" + * + * "\0", when not followed by a digit, is not an octal escape sequence. + * @param {string} rawString A string in its raw representation. + * @returns {boolean} `true` if the string contains at least one octal escape sequence + * or at least one non-octal decimal escape sequence. + */ + hasOctalOrNonOctalDecimalEscapeSequence(rawString) { + return OCTAL_OR_NON_OCTAL_DECIMAL_ESCAPE_PATTERN.test(rawString); + }, + + isLogicalExpression, + isCoalesceExpression, + isMixedLogicalAndCoalesceExpressions, + isNullLiteral, + getStaticStringValue, + getStaticPropertyName, + skipChainExpression, + isSpecificId, + isSpecificMemberAccess, + equalLiteralValue, + isSameReference, + isLogicalAssignmentOperator +}; +}); + +/** + * @fileoverview Rule to enforce getter and setter pairs in objects and classes. + * @author Gyandeep Singh + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Typedefs +//------------------------------------------------------------------------------ + +/** + * Property name if it can be computed statically, otherwise the list of the tokens of the key node. + * @typedef {string|Token[]} Key + */ + +/** + * Accessor nodes with the same key. + * @typedef {Object} AccessorData + * @property {Key} key Accessor's key + * @property {ASTNode[]} getters List of getter nodes. + * @property {ASTNode[]} setters List of setter nodes. + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not the given lists represent the equal tokens in the same order. + * Tokens are compared by their properties, not by instance. + * @param {Token[]} left First list of tokens. + * @param {Token[]} right Second list of tokens. + * @returns {boolean} `true` if the lists have same tokens. + */ +function areEqualTokenLists$1(left, right) { + if (left.length !== right.length) { + return false; + } + + for (let i = 0; i < left.length; i++) { + const leftToken = left[i], + rightToken = right[i]; + + if (leftToken.type !== rightToken.type || leftToken.value !== rightToken.value) { + return false; + } + } + + return true; +} + +/** + * Checks whether or not the given keys are equal. + * @param {Key} left First key. + * @param {Key} right Second key. + * @returns {boolean} `true` if the keys are equal. + */ +function areEqualKeys$1(left, right) { + if (typeof left === "string" && typeof right === "string") { + + // Statically computed names. + return left === right; + } + if (Array.isArray(left) && Array.isArray(right)) { + + // Token lists. + return areEqualTokenLists$1(left, right); + } + + return false; +} + +/** + * Checks whether or not a given node is of an accessor kind ('get' or 'set'). + * @param {ASTNode} node A node to check. + * @returns {boolean} `true` if the node is of an accessor kind. + */ +function isAccessorKind$1(node) { + return node.kind === "get" || node.kind === "set"; +} + +/** + * Checks whether or not a given node is an argument of a specified method call. + * @param {ASTNode} node A node to check. + * @param {number} index An expected index of the node in arguments. + * @param {string} object An expected name of the object of the method. + * @param {string} property An expected name of the method. + * @returns {boolean} `true` if the node is an argument of the specified method call. + */ +function isArgumentOfMethodCall(node, index, object, property) { + const parent = node.parent; + + return ( + parent.type === "CallExpression" && + astUtils.isSpecificMemberAccess(parent.callee, object, property) && + parent.arguments[index] === node + ); +} + +/** + * Checks whether or not a given node is a property descriptor. + * @param {ASTNode} node A node to check. + * @returns {boolean} `true` if the node is a property descriptor. + */ +function isPropertyDescriptor$1(node) { + + // Object.defineProperty(obj, "foo", {set: ...}) + if (isArgumentOfMethodCall(node, 2, "Object", "defineProperty") || + isArgumentOfMethodCall(node, 2, "Reflect", "defineProperty") + ) { + return true; + } + + /* + * Object.defineProperties(obj, {foo: {set: ...}}) + * Object.create(proto, {foo: {set: ...}}) + */ + const grandparent = node.parent.parent; + + return grandparent.type === "ObjectExpression" && ( + isArgumentOfMethodCall(grandparent, 1, "Object", "create") || + isArgumentOfMethodCall(grandparent, 1, "Object", "defineProperties") + ); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var accessorPairs = { + meta: { + type: "suggestion", + + docs: { + description: "enforce getter and setter pairs in objects and classes", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/accessor-pairs" + }, + + schema: [{ + type: "object", + properties: { + getWithoutSet: { + type: "boolean", + default: false + }, + setWithoutGet: { + type: "boolean", + default: true + }, + enforceForClassMembers: { + type: "boolean", + default: true + } + }, + additionalProperties: false + }], + + messages: { + missingGetterInPropertyDescriptor: "Getter is not present in property descriptor.", + missingSetterInPropertyDescriptor: "Setter is not present in property descriptor.", + missingGetterInObjectLiteral: "Getter is not present for {{ name }}.", + missingSetterInObjectLiteral: "Setter is not present for {{ name }}.", + missingGetterInClass: "Getter is not present for class {{ name }}.", + missingSetterInClass: "Setter is not present for class {{ name }}." + } + }, + create(context) { + const config = context.options[0] || {}; + const checkGetWithoutSet = config.getWithoutSet === true; + const checkSetWithoutGet = config.setWithoutGet !== false; + const enforceForClassMembers = config.enforceForClassMembers !== false; + const sourceCode = context.getSourceCode(); + + /** + * Reports the given node. + * @param {ASTNode} node The node to report. + * @param {string} messageKind "missingGetter" or "missingSetter". + * @returns {void} + * @private + */ + function report(node, messageKind) { + if (node.type === "Property") { + context.report({ + node, + messageId: `${messageKind}InObjectLiteral`, + loc: astUtils.getFunctionHeadLoc(node.value, sourceCode), + data: { name: astUtils.getFunctionNameWithKind(node.value) } + }); + } else if (node.type === "MethodDefinition") { + context.report({ + node, + messageId: `${messageKind}InClass`, + loc: astUtils.getFunctionHeadLoc(node.value, sourceCode), + data: { name: astUtils.getFunctionNameWithKind(node.value) } + }); + } else { + context.report({ + node, + messageId: `${messageKind}InPropertyDescriptor` + }); + } + } + + /** + * Reports each of the nodes in the given list using the same messageId. + * @param {ASTNode[]} nodes Nodes to report. + * @param {string} messageKind "missingGetter" or "missingSetter". + * @returns {void} + * @private + */ + function reportList(nodes, messageKind) { + for (const node of nodes) { + report(node, messageKind); + } + } + + /** + * Creates a new `AccessorData` object for the given getter or setter node. + * @param {ASTNode} node A getter or setter node. + * @returns {AccessorData} New `AccessorData` object that contains the given node. + * @private + */ + function createAccessorData(node) { + const name = astUtils.getStaticPropertyName(node); + const key = (name !== null) ? name : sourceCode.getTokens(node.key); + + return { + key, + getters: node.kind === "get" ? [node] : [], + setters: node.kind === "set" ? [node] : [] + }; + } + + /** + * Merges the given `AccessorData` object into the given accessors list. + * @param {AccessorData[]} accessors The list to merge into. + * @param {AccessorData} accessorData The object to merge. + * @returns {AccessorData[]} The same instance with the merged object. + * @private + */ + function mergeAccessorData(accessors, accessorData) { + const equalKeyElement = accessors.find(a => areEqualKeys$1(a.key, accessorData.key)); + + if (equalKeyElement) { + equalKeyElement.getters.push(...accessorData.getters); + equalKeyElement.setters.push(...accessorData.setters); + } else { + accessors.push(accessorData); + } + + return accessors; + } + + /** + * Checks accessor pairs in the given list of nodes. + * @param {ASTNode[]} nodes The list to check. + * @returns {void} + * @private + */ + function checkList(nodes) { + const accessors = nodes + .filter(isAccessorKind$1) + .map(createAccessorData) + .reduce(mergeAccessorData, []); + + for (const { getters, setters } of accessors) { + if (checkSetWithoutGet && setters.length && !getters.length) { + reportList(setters, "missingGetter"); + } + if (checkGetWithoutSet && getters.length && !setters.length) { + reportList(getters, "missingSetter"); + } + } + } + + /** + * Checks accessor pairs in an object literal. + * @param {ASTNode} node `ObjectExpression` node to check. + * @returns {void} + * @private + */ + function checkObjectLiteral(node) { + checkList(node.properties.filter(p => p.type === "Property")); + } + + /** + * Checks accessor pairs in a property descriptor. + * @param {ASTNode} node Property descriptor `ObjectExpression` node to check. + * @returns {void} + * @private + */ + function checkPropertyDescriptor(node) { + const namesToCheck = node.properties + .filter(p => p.type === "Property" && p.kind === "init" && !p.computed) + .map(({ key }) => key.name); + + const hasGetter = namesToCheck.includes("get"); + const hasSetter = namesToCheck.includes("set"); + + if (checkSetWithoutGet && hasSetter && !hasGetter) { + report(node, "missingGetter"); + } + if (checkGetWithoutSet && hasGetter && !hasSetter) { + report(node, "missingSetter"); + } + } + + /** + * Checks the given object expression as an object literal and as a possible property descriptor. + * @param {ASTNode} node `ObjectExpression` node to check. + * @returns {void} + * @private + */ + function checkObjectExpression(node) { + checkObjectLiteral(node); + if (isPropertyDescriptor$1(node)) { + checkPropertyDescriptor(node); + } + } + + /** + * Checks the given class body. + * @param {ASTNode} node `ClassBody` node to check. + * @returns {void} + * @private + */ + function checkClassBody(node) { + const methodDefinitions = node.body.filter(m => m.type === "MethodDefinition"); + + checkList(methodDefinitions.filter(m => m.static)); + checkList(methodDefinitions.filter(m => !m.static)); + } + + const listeners = {}; + + if (checkSetWithoutGet || checkGetWithoutSet) { + listeners.ObjectExpression = checkObjectExpression; + if (enforceForClassMembers) { + listeners.ClassBody = checkClassBody; + } + } + + return listeners; + } +}; + +/** + * @fileoverview Rule to enforce linebreaks after open and before close array brackets + * @author Jan Peer Stöcklmair + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var arrayBracketNewline = { + meta: { + type: "layout", + + docs: { + description: "enforce linebreaks after opening and before closing array brackets", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/array-bracket-newline" + }, + + fixable: "whitespace", + + schema: [ + { + oneOf: [ + { + enum: ["always", "never", "consistent"] + }, + { + type: "object", + properties: { + multiline: { + type: "boolean" + }, + minItems: { + type: ["integer", "null"], + minimum: 0 + } + }, + additionalProperties: false + } + ] + } + ], + + messages: { + unexpectedOpeningLinebreak: "There should be no linebreak after '['.", + unexpectedClosingLinebreak: "There should be no linebreak before ']'.", + missingOpeningLinebreak: "A linebreak is required after '['.", + missingClosingLinebreak: "A linebreak is required before ']'." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + + //---------------------------------------------------------------------- + // Helpers + //---------------------------------------------------------------------- + + /** + * Normalizes a given option value. + * @param {string|Object|undefined} option An option value to parse. + * @returns {{multiline: boolean, minItems: number}} Normalized option object. + */ + function normalizeOptionValue(option) { + let consistent = false; + let multiline = false; + let minItems = 0; + + if (option) { + if (option === "consistent") { + consistent = true; + minItems = Number.POSITIVE_INFINITY; + } else if (option === "always" || option.minItems === 0) { + minItems = 0; + } else if (option === "never") { + minItems = Number.POSITIVE_INFINITY; + } else { + multiline = Boolean(option.multiline); + minItems = option.minItems || Number.POSITIVE_INFINITY; + } + } else { + consistent = false; + multiline = true; + minItems = Number.POSITIVE_INFINITY; + } + + return { consistent, multiline, minItems }; + } + + /** + * Normalizes a given option value. + * @param {string|Object|undefined} options An option value to parse. + * @returns {{ArrayExpression: {multiline: boolean, minItems: number}, ArrayPattern: {multiline: boolean, minItems: number}}} Normalized option object. + */ + function normalizeOptions(options) { + const value = normalizeOptionValue(options); + + return { ArrayExpression: value, ArrayPattern: value }; + } + + /** + * Reports that there shouldn't be a linebreak after the first token + * @param {ASTNode} node The node to report in the event of an error. + * @param {Token} token The token to use for the report. + * @returns {void} + */ + function reportNoBeginningLinebreak(node, token) { + context.report({ + node, + loc: token.loc, + messageId: "unexpectedOpeningLinebreak", + fix(fixer) { + const nextToken = sourceCode.getTokenAfter(token, { includeComments: true }); + + if (astUtils.isCommentToken(nextToken)) { + return null; + } + + return fixer.removeRange([token.range[1], nextToken.range[0]]); + } + }); + } + + /** + * Reports that there shouldn't be a linebreak before the last token + * @param {ASTNode} node The node to report in the event of an error. + * @param {Token} token The token to use for the report. + * @returns {void} + */ + function reportNoEndingLinebreak(node, token) { + context.report({ + node, + loc: token.loc, + messageId: "unexpectedClosingLinebreak", + fix(fixer) { + const previousToken = sourceCode.getTokenBefore(token, { includeComments: true }); + + if (astUtils.isCommentToken(previousToken)) { + return null; + } + + return fixer.removeRange([previousToken.range[1], token.range[0]]); + } + }); + } + + /** + * Reports that there should be a linebreak after the first token + * @param {ASTNode} node The node to report in the event of an error. + * @param {Token} token The token to use for the report. + * @returns {void} + */ + function reportRequiredBeginningLinebreak(node, token) { + context.report({ + node, + loc: token.loc, + messageId: "missingOpeningLinebreak", + fix(fixer) { + return fixer.insertTextAfter(token, "\n"); + } + }); + } + + /** + * Reports that there should be a linebreak before the last token + * @param {ASTNode} node The node to report in the event of an error. + * @param {Token} token The token to use for the report. + * @returns {void} + */ + function reportRequiredEndingLinebreak(node, token) { + context.report({ + node, + loc: token.loc, + messageId: "missingClosingLinebreak", + fix(fixer) { + return fixer.insertTextBefore(token, "\n"); + } + }); + } + + /** + * Reports a given node if it violated this rule. + * @param {ASTNode} node A node to check. This is an ArrayExpression node or an ArrayPattern node. + * @returns {void} + */ + function check(node) { + const elements = node.elements; + const normalizedOptions = normalizeOptions(context.options[0]); + const options = normalizedOptions[node.type]; + const openBracket = sourceCode.getFirstToken(node); + const closeBracket = sourceCode.getLastToken(node); + const firstIncComment = sourceCode.getTokenAfter(openBracket, { includeComments: true }); + const lastIncComment = sourceCode.getTokenBefore(closeBracket, { includeComments: true }); + const first = sourceCode.getTokenAfter(openBracket); + const last = sourceCode.getTokenBefore(closeBracket); + + const needsLinebreaks = ( + elements.length >= options.minItems || + ( + options.multiline && + elements.length > 0 && + firstIncComment.loc.start.line !== lastIncComment.loc.end.line + ) || + ( + elements.length === 0 && + firstIncComment.type === "Block" && + firstIncComment.loc.start.line !== lastIncComment.loc.end.line && + firstIncComment === lastIncComment + ) || + ( + options.consistent && + openBracket.loc.end.line !== first.loc.start.line + ) + ); + + /* + * Use tokens or comments to check multiline or not. + * But use only tokens to check whether linebreaks are needed. + * This allows: + * var arr = [ // eslint-disable-line foo + * 'a' + * ] + */ + + if (needsLinebreaks) { + if (astUtils.isTokenOnSameLine(openBracket, first)) { + reportRequiredBeginningLinebreak(node, openBracket); + } + if (astUtils.isTokenOnSameLine(last, closeBracket)) { + reportRequiredEndingLinebreak(node, closeBracket); + } + } else { + if (!astUtils.isTokenOnSameLine(openBracket, first)) { + reportNoBeginningLinebreak(node, openBracket); + } + if (!astUtils.isTokenOnSameLine(last, closeBracket)) { + reportNoEndingLinebreak(node, closeBracket); + } + } + } + + //---------------------------------------------------------------------- + // Public + //---------------------------------------------------------------------- + + return { + ArrayPattern: check, + ArrayExpression: check + }; + } +}; + +/** + * @fileoverview Disallows or enforces spaces inside of array brackets. + * @author Jamund Ferguson + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var arrayBracketSpacing = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent spacing inside array brackets", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/array-bracket-spacing" + }, + + fixable: "whitespace", + + schema: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + singleValue: { + type: "boolean" + }, + objectsInArrays: { + type: "boolean" + }, + arraysInArrays: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + + messages: { + unexpectedSpaceAfter: "There should be no space after '{{tokenValue}}'.", + unexpectedSpaceBefore: "There should be no space before '{{tokenValue}}'.", + missingSpaceAfter: "A space is required after '{{tokenValue}}'.", + missingSpaceBefore: "A space is required before '{{tokenValue}}'." + } + }, + create(context) { + const spaced = context.options[0] === "always", + sourceCode = context.getSourceCode(); + + /** + * Determines whether an option is set, relative to the spacing option. + * If spaced is "always", then check whether option is set to false. + * If spaced is "never", then check whether option is set to true. + * @param {Object} option The option to exclude. + * @returns {boolean} Whether or not the property is excluded. + */ + function isOptionSet(option) { + return context.options[1] ? context.options[1][option] === !spaced : false; + } + + const options = { + spaced, + singleElementException: isOptionSet("singleValue"), + objectsInArraysException: isOptionSet("objectsInArrays"), + arraysInArraysException: isOptionSet("arraysInArrays") + }; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Reports that there shouldn't be a space after the first token + * @param {ASTNode} node The node to report in the event of an error. + * @param {Token} token The token to use for the report. + * @returns {void} + */ + function reportNoBeginningSpace(node, token) { + const nextToken = sourceCode.getTokenAfter(token); + + context.report({ + node, + loc: { start: token.loc.end, end: nextToken.loc.start }, + messageId: "unexpectedSpaceAfter", + data: { + tokenValue: token.value + }, + fix(fixer) { + return fixer.removeRange([token.range[1], nextToken.range[0]]); + } + }); + } + + /** + * Reports that there shouldn't be a space before the last token + * @param {ASTNode} node The node to report in the event of an error. + * @param {Token} token The token to use for the report. + * @returns {void} + */ + function reportNoEndingSpace(node, token) { + const previousToken = sourceCode.getTokenBefore(token); + + context.report({ + node, + loc: { start: previousToken.loc.end, end: token.loc.start }, + messageId: "unexpectedSpaceBefore", + data: { + tokenValue: token.value + }, + fix(fixer) { + return fixer.removeRange([previousToken.range[1], token.range[0]]); + } + }); + } + + /** + * Reports that there should be a space after the first token + * @param {ASTNode} node The node to report in the event of an error. + * @param {Token} token The token to use for the report. + * @returns {void} + */ + function reportRequiredBeginningSpace(node, token) { + context.report({ + node, + loc: token.loc, + messageId: "missingSpaceAfter", + data: { + tokenValue: token.value + }, + fix(fixer) { + return fixer.insertTextAfter(token, " "); + } + }); + } + + /** + * Reports that there should be a space before the last token + * @param {ASTNode} node The node to report in the event of an error. + * @param {Token} token The token to use for the report. + * @returns {void} + */ + function reportRequiredEndingSpace(node, token) { + context.report({ + node, + loc: token.loc, + messageId: "missingSpaceBefore", + data: { + tokenValue: token.value + }, + fix(fixer) { + return fixer.insertTextBefore(token, " "); + } + }); + } + + /** + * Determines if a node is an object type + * @param {ASTNode} node The node to check. + * @returns {boolean} Whether or not the node is an object type. + */ + function isObjectType(node) { + return node && (node.type === "ObjectExpression" || node.type === "ObjectPattern"); + } + + /** + * Determines if a node is an array type + * @param {ASTNode} node The node to check. + * @returns {boolean} Whether or not the node is an array type. + */ + function isArrayType(node) { + return node && (node.type === "ArrayExpression" || node.type === "ArrayPattern"); + } + + /** + * Validates the spacing around array brackets + * @param {ASTNode} node The node we're checking for spacing + * @returns {void} + */ + function validateArraySpacing(node) { + if (options.spaced && node.elements.length === 0) { + return; + } + + const first = sourceCode.getFirstToken(node), + second = sourceCode.getFirstToken(node, 1), + last = node.typeAnnotation + ? sourceCode.getTokenBefore(node.typeAnnotation) + : sourceCode.getLastToken(node), + penultimate = sourceCode.getTokenBefore(last), + firstElement = node.elements[0], + lastElement = node.elements[node.elements.length - 1]; + + const openingBracketMustBeSpaced = + options.objectsInArraysException && isObjectType(firstElement) || + options.arraysInArraysException && isArrayType(firstElement) || + options.singleElementException && node.elements.length === 1 + ? !options.spaced : options.spaced; + + const closingBracketMustBeSpaced = + options.objectsInArraysException && isObjectType(lastElement) || + options.arraysInArraysException && isArrayType(lastElement) || + options.singleElementException && node.elements.length === 1 + ? !options.spaced : options.spaced; + + if (astUtils.isTokenOnSameLine(first, second)) { + if (openingBracketMustBeSpaced && !sourceCode.isSpaceBetweenTokens(first, second)) { + reportRequiredBeginningSpace(node, first); + } + if (!openingBracketMustBeSpaced && sourceCode.isSpaceBetweenTokens(first, second)) { + reportNoBeginningSpace(node, first); + } + } + + if (first !== penultimate && astUtils.isTokenOnSameLine(penultimate, last)) { + if (closingBracketMustBeSpaced && !sourceCode.isSpaceBetweenTokens(penultimate, last)) { + reportRequiredEndingSpace(node, last); + } + if (!closingBracketMustBeSpaced && sourceCode.isSpaceBetweenTokens(penultimate, last)) { + reportNoEndingSpace(node, last); + } + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + ArrayPattern: validateArraySpacing, + ArrayExpression: validateArraySpacing + }; + } +}; + +/** + * @fileoverview Rule to enforce return statements in callbacks of array's methods + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const TARGET_NODE_TYPE$2 = /^(?:Arrow)?FunctionExpression$/u; +const TARGET_METHODS = /^(?:every|filter|find(?:Index)?|flatMap|forEach|map|reduce(?:Right)?|some|sort)$/u; + +/** + * Checks a given code path segment is reachable. + * @param {CodePathSegment} segment A segment to check. + * @returns {boolean} `true` if the segment is reachable. + */ +function isReachable$3(segment) { + return segment.reachable; +} + +/** + * Checks a given node is a member access which has the specified name's + * property. + * @param {ASTNode} node A node to check. + * @returns {boolean} `true` if the node is a member access which has + * the specified name's property. The node may be a `(Chain|Member)Expression` node. + */ +function isTargetMethod(node) { + return astUtils.isSpecificMemberAccess(node, null, TARGET_METHODS); +} + +/** + * Returns a human-legible description of an array method + * @param {string} arrayMethodName A method name to fully qualify + * @returns {string} the method name prefixed with `Array.` if it is a class method, + * or else `Array.prototype.` if it is an instance method. + */ +function fullMethodName(arrayMethodName) { + if (["from", "of", "isArray"].includes(arrayMethodName)) { + return "Array.".concat(arrayMethodName); + } + return "Array.prototype.".concat(arrayMethodName); +} + +/** + * Checks whether or not a given node is a function expression which is the + * callback of an array method, returning the method name. + * @param {ASTNode} node A node to check. This is one of + * FunctionExpression or ArrowFunctionExpression. + * @returns {string} The method name if the node is a callback method, + * null otherwise. + */ +function getArrayMethodName(node) { + let currentNode = node; + + while (currentNode) { + const parent = currentNode.parent; + + switch (parent.type) { + + /* + * Looks up the destination. e.g., + * foo.every(nativeFoo || function foo() { ... }); + */ + case "LogicalExpression": + case "ConditionalExpression": + case "ChainExpression": + currentNode = parent; + break; + + /* + * If the upper function is IIFE, checks the destination of the return value. + * e.g. + * foo.every((function() { + * // setup... + * return function callback() { ... }; + * })()); + */ + case "ReturnStatement": { + const func = astUtils.getUpperFunction(parent); + + if (func === null || !astUtils.isCallee(func)) { + return null; + } + currentNode = func.parent; + break; + } + + /* + * e.g. + * Array.from([], function() {}); + * list.every(function() {}); + */ + case "CallExpression": + if (astUtils.isArrayFromMethod(parent.callee)) { + if ( + parent.arguments.length >= 2 && + parent.arguments[1] === currentNode + ) { + return "from"; + } + } + if (isTargetMethod(parent.callee)) { + if ( + parent.arguments.length >= 1 && + parent.arguments[0] === currentNode + ) { + return astUtils.getStaticPropertyName(parent.callee); + } + } + return null; + + // Otherwise this node is not target. + default: + return null; + } + } + + /* istanbul ignore next: unreachable */ + return null; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var arrayCallbackReturn = { + meta: { + type: "problem", + + docs: { + description: "enforce `return` statements in callbacks of array methods", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/array-callback-return" + }, + + schema: [ + { + type: "object", + properties: { + allowImplicit: { + type: "boolean", + default: false + }, + checkForEach: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + messages: { + expectedAtEnd: "{{arrayMethodName}}() expects a value to be returned at the end of {{name}}.", + expectedInside: "{{arrayMethodName}}() expects a return value from {{name}}.", + expectedReturnValue: "{{arrayMethodName}}() expects a return value from {{name}}.", + expectedNoReturnValue: "{{arrayMethodName}}() expects no useless return value from {{name}}." + } + }, + + create(context) { + + const options = context.options[0] || { allowImplicit: false, checkForEach: false }; + const sourceCode = context.getSourceCode(); + + let funcInfo = { + arrayMethodName: null, + upper: null, + codePath: null, + hasReturn: false, + shouldCheck: false, + node: null + }; + + /** + * Checks whether or not the last code path segment is reachable. + * Then reports this function if the segment is reachable. + * + * If the last code path segment is reachable, there are paths which are not + * returned or thrown. + * @param {ASTNode} node A node to check. + * @returns {void} + */ + function checkLastSegment(node) { + + if (!funcInfo.shouldCheck) { + return; + } + + let messageId = null; + + if (funcInfo.arrayMethodName === "forEach") { + if (options.checkForEach && node.type === "ArrowFunctionExpression" && node.expression) { + messageId = "expectedNoReturnValue"; + } + } else { + if (node.body.type === "BlockStatement" && funcInfo.codePath.currentSegments.some(isReachable$3)) { + messageId = funcInfo.hasReturn ? "expectedAtEnd" : "expectedInside"; + } + } + + if (messageId) { + const name = astUtils.getFunctionNameWithKind(node); + + context.report({ + node, + loc: astUtils.getFunctionHeadLoc(node, sourceCode), + messageId, + data: { name, arrayMethodName: fullMethodName(funcInfo.arrayMethodName) } + }); + } + } + + return { + + // Stacks this function's information. + onCodePathStart(codePath, node) { + + let methodName = null; + + if (TARGET_NODE_TYPE$2.test(node.type)) { + methodName = getArrayMethodName(node); + } + + funcInfo = { + arrayMethodName: methodName, + upper: funcInfo, + codePath, + hasReturn: false, + shouldCheck: + methodName && + !node.async && + !node.generator, + node + }; + }, + + // Pops this function's information. + onCodePathEnd() { + funcInfo = funcInfo.upper; + }, + + // Checks the return statement is valid. + ReturnStatement(node) { + + if (!funcInfo.shouldCheck) { + return; + } + + funcInfo.hasReturn = true; + + let messageId = null; + + if (funcInfo.arrayMethodName === "forEach") { + + // if checkForEach: true, returning a value at any path inside a forEach is not allowed + if (options.checkForEach && node.argument) { + messageId = "expectedNoReturnValue"; + } + } else { + + // if allowImplicit: false, should also check node.argument + if (!options.allowImplicit && !node.argument) { + messageId = "expectedReturnValue"; + } + } + + if (messageId) { + context.report({ + node, + messageId, + data: { + name: astUtils.getFunctionNameWithKind(funcInfo.node), + arrayMethodName: fullMethodName(funcInfo.arrayMethodName) + } + }); + } + }, + + // Reports a given function if the last path is reachable. + "FunctionExpression:exit": checkLastSegment, + "ArrowFunctionExpression:exit": checkLastSegment + }; + } +}; + +/** + * @fileoverview Rule to enforce line breaks after each array element + * @author Jan Peer Stöcklmair + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var arrayElementNewline = { + meta: { + type: "layout", + + docs: { + description: "enforce line breaks after each array element", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/array-element-newline" + }, + + fixable: "whitespace", + + schema: { + definitions: { + basicConfig: { + oneOf: [ + { + enum: ["always", "never", "consistent"] + }, + { + type: "object", + properties: { + multiline: { + type: "boolean" + }, + minItems: { + type: ["integer", "null"], + minimum: 0 + } + }, + additionalProperties: false + } + ] + } + }, + items: [ + { + oneOf: [ + { + $ref: "#/definitions/basicConfig" + }, + { + type: "object", + properties: { + ArrayExpression: { + $ref: "#/definitions/basicConfig" + }, + ArrayPattern: { + $ref: "#/definitions/basicConfig" + } + }, + additionalProperties: false, + minProperties: 1 + } + ] + } + ] + }, + + messages: { + unexpectedLineBreak: "There should be no linebreak here.", + missingLineBreak: "There should be a linebreak after this element." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + //---------------------------------------------------------------------- + // Helpers + //---------------------------------------------------------------------- + + /** + * Normalizes a given option value. + * @param {string|Object|undefined} providedOption An option value to parse. + * @returns {{multiline: boolean, minItems: number}} Normalized option object. + */ + function normalizeOptionValue(providedOption) { + let consistent = false; + let multiline = false; + let minItems; + + const option = providedOption || "always"; + + if (!option || option === "always" || option.minItems === 0) { + minItems = 0; + } else if (option === "never") { + minItems = Number.POSITIVE_INFINITY; + } else if (option === "consistent") { + consistent = true; + minItems = Number.POSITIVE_INFINITY; + } else { + multiline = Boolean(option.multiline); + minItems = option.minItems || Number.POSITIVE_INFINITY; + } + + return { consistent, multiline, minItems }; + } + + /** + * Normalizes a given option value. + * @param {string|Object|undefined} options An option value to parse. + * @returns {{ArrayExpression: {multiline: boolean, minItems: number}, ArrayPattern: {multiline: boolean, minItems: number}}} Normalized option object. + */ + function normalizeOptions(options) { + if (options && (options.ArrayExpression || options.ArrayPattern)) { + let expressionOptions, patternOptions; + + if (options.ArrayExpression) { + expressionOptions = normalizeOptionValue(options.ArrayExpression); + } + + if (options.ArrayPattern) { + patternOptions = normalizeOptionValue(options.ArrayPattern); + } + + return { ArrayExpression: expressionOptions, ArrayPattern: patternOptions }; + } + + const value = normalizeOptionValue(options); + + return { ArrayExpression: value, ArrayPattern: value }; + } + + /** + * Reports that there shouldn't be a line break after the first token + * @param {Token} token The token to use for the report. + * @returns {void} + */ + function reportNoLineBreak(token) { + const tokenBefore = sourceCode.getTokenBefore(token, { includeComments: true }); + + context.report({ + loc: { + start: tokenBefore.loc.end, + end: token.loc.start + }, + messageId: "unexpectedLineBreak", + fix(fixer) { + if (astUtils.isCommentToken(tokenBefore)) { + return null; + } + + if (!astUtils.isTokenOnSameLine(tokenBefore, token)) { + return fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], " "); + } + + /* + * This will check if the comma is on the same line as the next element + * Following array: + * [ + * 1 + * , 2 + * , 3 + * ] + * + * will be fixed to: + * [ + * 1, 2, 3 + * ] + */ + const twoTokensBefore = sourceCode.getTokenBefore(tokenBefore, { includeComments: true }); + + if (astUtils.isCommentToken(twoTokensBefore)) { + return null; + } + + return fixer.replaceTextRange([twoTokensBefore.range[1], tokenBefore.range[0]], ""); + + } + }); + } + + /** + * Reports that there should be a line break after the first token + * @param {Token} token The token to use for the report. + * @returns {void} + */ + function reportRequiredLineBreak(token) { + const tokenBefore = sourceCode.getTokenBefore(token, { includeComments: true }); + + context.report({ + loc: { + start: tokenBefore.loc.end, + end: token.loc.start + }, + messageId: "missingLineBreak", + fix(fixer) { + return fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], "\n"); + } + }); + } + + /** + * Reports a given node if it violated this rule. + * @param {ASTNode} node A node to check. This is an ObjectExpression node or an ObjectPattern node. + * @returns {void} + */ + function check(node) { + const elements = node.elements; + const normalizedOptions = normalizeOptions(context.options[0]); + const options = normalizedOptions[node.type]; + + if (!options) { + return; + } + + let elementBreak = false; + + /* + * MULTILINE: true + * loop through every element and check + * if at least one element has linebreaks inside + * this ensures that following is not valid (due to elements are on the same line): + * + * [ + * 1, + * 2, + * 3 + * ] + */ + if (options.multiline) { + elementBreak = elements + .filter(element => element !== null) + .some(element => element.loc.start.line !== element.loc.end.line); + } + + const linebreaksCount = node.elements.map((element, i) => { + const previousElement = elements[i - 1]; + + if (i === 0 || element === null || previousElement === null) { + return false; + } + + const commaToken = sourceCode.getFirstTokenBetween(previousElement, element, astUtils.isCommaToken); + const lastTokenOfPreviousElement = sourceCode.getTokenBefore(commaToken); + const firstTokenOfCurrentElement = sourceCode.getTokenAfter(commaToken); + + return !astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement); + }).filter(isBreak => isBreak === true).length; + + const needsLinebreaks = ( + elements.length >= options.minItems || + ( + options.multiline && + elementBreak + ) || + ( + options.consistent && + linebreaksCount > 0 && + linebreaksCount < node.elements.length + ) + ); + + elements.forEach((element, i) => { + const previousElement = elements[i - 1]; + + if (i === 0 || element === null || previousElement === null) { + return; + } + + const commaToken = sourceCode.getFirstTokenBetween(previousElement, element, astUtils.isCommaToken); + const lastTokenOfPreviousElement = sourceCode.getTokenBefore(commaToken); + const firstTokenOfCurrentElement = sourceCode.getTokenAfter(commaToken); + + if (needsLinebreaks) { + if (astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement)) { + reportRequiredLineBreak(firstTokenOfCurrentElement); + } + } else { + if (!astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement)) { + reportNoLineBreak(firstTokenOfCurrentElement); + } + } + }); + } + + //---------------------------------------------------------------------- + // Public + //---------------------------------------------------------------------- + + return { + ArrayPattern: check, + ArrayExpression: check + }; + } +}; + +/** + * @fileoverview Rule to require braces in arrow function body. + * @author Alberto Rodríguez + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var arrowBodyStyle = { + meta: { + type: "suggestion", + + docs: { + description: "require braces around arrow function bodies", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/arrow-body-style" + }, + + schema: { + anyOf: [ + { + type: "array", + items: [ + { + enum: ["always", "never"] + } + ], + minItems: 0, + maxItems: 1 + }, + { + type: "array", + items: [ + { + enum: ["as-needed"] + }, + { + type: "object", + properties: { + requireReturnForObjectLiteral: { type: "boolean" } + }, + additionalProperties: false + } + ], + minItems: 0, + maxItems: 2 + } + ] + }, + + fixable: "code", + + messages: { + unexpectedOtherBlock: "Unexpected block statement surrounding arrow body.", + unexpectedEmptyBlock: "Unexpected block statement surrounding arrow body; put a value of `undefined` immediately after the `=>`.", + unexpectedObjectBlock: "Unexpected block statement surrounding arrow body; parenthesize the returned value and move it immediately after the `=>`.", + unexpectedSingleBlock: "Unexpected block statement surrounding arrow body; move the returned value immediately after the `=>`.", + expectedBlock: "Expected block statement surrounding arrow body." + } + }, + + create(context) { + const options = context.options; + const always = options[0] === "always"; + const asNeeded = !options[0] || options[0] === "as-needed"; + const never = options[0] === "never"; + const requireReturnForObjectLiteral = options[1] && options[1].requireReturnForObjectLiteral; + const sourceCode = context.getSourceCode(); + let funcInfo = null; + + /** + * Checks whether the given node has ASI problem or not. + * @param {Token} token The token to check. + * @returns {boolean} `true` if it changes semantics if `;` or `}` followed by the token are removed. + */ + function hasASIProblem(token) { + return token && token.type === "Punctuator" && /^[([/`+-]/u.test(token.value); + } + + /** + * Gets the closing parenthesis which is the pair of the given opening parenthesis. + * @param {Token} token The opening parenthesis token to get. + * @returns {Token} The found closing parenthesis token. + */ + function findClosingParen(token) { + let node = sourceCode.getNodeByRangeIndex(token.range[0]); + + while (!astUtils.isParenthesised(sourceCode, node)) { + node = node.parent; + } + return sourceCode.getTokenAfter(node); + } + + /** + * Check whether the node is inside of a for loop's init + * @param {ASTNode} node node is inside for loop + * @returns {boolean} `true` if the node is inside of a for loop, else `false` + */ + function isInsideForLoopInitializer(node) { + if (node && node.parent) { + if (node.parent.type === "ForStatement" && node.parent.init === node) { + return true; + } + return isInsideForLoopInitializer(node.parent); + } + return false; + } + + /** + * Determines whether a arrow function body needs braces + * @param {ASTNode} node The arrow function node. + * @returns {void} + */ + function validate(node) { + const arrowBody = node.body; + + if (arrowBody.type === "BlockStatement") { + const blockBody = arrowBody.body; + + if (blockBody.length !== 1 && !never) { + return; + } + + if (asNeeded && requireReturnForObjectLiteral && blockBody[0].type === "ReturnStatement" && + blockBody[0].argument && blockBody[0].argument.type === "ObjectExpression") { + return; + } + + if (never || asNeeded && blockBody[0].type === "ReturnStatement") { + let messageId; + + if (blockBody.length === 0) { + messageId = "unexpectedEmptyBlock"; + } else if (blockBody.length > 1) { + messageId = "unexpectedOtherBlock"; + } else if (blockBody[0].argument === null) { + messageId = "unexpectedSingleBlock"; + } else if (astUtils.isOpeningBraceToken(sourceCode.getFirstToken(blockBody[0], { skip: 1 }))) { + messageId = "unexpectedObjectBlock"; + } else { + messageId = "unexpectedSingleBlock"; + } + + context.report({ + node, + loc: arrowBody.loc, + messageId, + fix(fixer) { + const fixes = []; + + if (blockBody.length !== 1 || + blockBody[0].type !== "ReturnStatement" || + !blockBody[0].argument || + hasASIProblem(sourceCode.getTokenAfter(arrowBody)) + ) { + return fixes; + } + + const openingBrace = sourceCode.getFirstToken(arrowBody); + const closingBrace = sourceCode.getLastToken(arrowBody); + const firstValueToken = sourceCode.getFirstToken(blockBody[0], 1); + const lastValueToken = sourceCode.getLastToken(blockBody[0]); + const commentsExist = + sourceCode.commentsExistBetween(openingBrace, firstValueToken) || + sourceCode.commentsExistBetween(lastValueToken, closingBrace); + + /* + * Remove tokens around the return value. + * If comments don't exist, remove extra spaces as well. + */ + if (commentsExist) { + fixes.push( + fixer.remove(openingBrace), + fixer.remove(closingBrace), + fixer.remove(sourceCode.getTokenAfter(openingBrace)) // return keyword + ); + } else { + fixes.push( + fixer.removeRange([openingBrace.range[0], firstValueToken.range[0]]), + fixer.removeRange([lastValueToken.range[1], closingBrace.range[1]]) + ); + } + + /* + * If the first token of the return value is `{` or the return value is a sequence expression, + * enclose the return value by parentheses to avoid syntax error. + */ + if (astUtils.isOpeningBraceToken(firstValueToken) || blockBody[0].argument.type === "SequenceExpression" || (funcInfo.hasInOperator && isInsideForLoopInitializer(node))) { + if (!astUtils.isParenthesised(sourceCode, blockBody[0].argument)) { + fixes.push( + fixer.insertTextBefore(firstValueToken, "("), + fixer.insertTextAfter(lastValueToken, ")") + ); + } + } + + /* + * If the last token of the return statement is semicolon, remove it. + * Non-block arrow body is an expression, not a statement. + */ + if (astUtils.isSemicolonToken(lastValueToken)) { + fixes.push(fixer.remove(lastValueToken)); + } + + return fixes; + } + }); + } + } else { + if (always || (asNeeded && requireReturnForObjectLiteral && arrowBody.type === "ObjectExpression")) { + context.report({ + node, + loc: arrowBody.loc, + messageId: "expectedBlock", + fix(fixer) { + const fixes = []; + const arrowToken = sourceCode.getTokenBefore(arrowBody, astUtils.isArrowToken); + const [firstTokenAfterArrow, secondTokenAfterArrow] = sourceCode.getTokensAfter(arrowToken, { count: 2 }); + const lastToken = sourceCode.getLastToken(node); + const isParenthesisedObjectLiteral = + astUtils.isOpeningParenToken(firstTokenAfterArrow) && + astUtils.isOpeningBraceToken(secondTokenAfterArrow); + + // If the value is object literal, remove parentheses which were forced by syntax. + if (isParenthesisedObjectLiteral) { + const openingParenToken = firstTokenAfterArrow; + const openingBraceToken = secondTokenAfterArrow; + + if (astUtils.isTokenOnSameLine(openingParenToken, openingBraceToken)) { + fixes.push(fixer.replaceText(openingParenToken, "{return ")); + } else { + + // Avoid ASI + fixes.push( + fixer.replaceText(openingParenToken, "{"), + fixer.insertTextBefore(openingBraceToken, "return ") + ); + } + + // Closing paren for the object doesn't have to be lastToken, e.g.: () => ({}).foo() + fixes.push(fixer.remove(findClosingParen(openingBraceToken))); + fixes.push(fixer.insertTextAfter(lastToken, "}")); + + } else { + fixes.push(fixer.insertTextBefore(firstTokenAfterArrow, "{return ")); + fixes.push(fixer.insertTextAfter(lastToken, "}")); + } + + return fixes; + } + }); + } + } + } + + return { + "BinaryExpression[operator='in']"() { + let info = funcInfo; + + while (info) { + info.hasInOperator = true; + info = info.upper; + } + }, + ArrowFunctionExpression() { + funcInfo = { + upper: funcInfo, + hasInOperator: false + }; + }, + "ArrowFunctionExpression:exit"(node) { + validate(node); + funcInfo = funcInfo.upper; + } + }; + } +}; + +/** + * @fileoverview Rule to require parens in arrow function arguments. + * @author Jxck + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Determines if the given arrow function has block body. + * @param {ASTNode} node `ArrowFunctionExpression` node. + * @returns {boolean} `true` if the function has block body. + */ +function hasBlockBody(node) { + return node.body.type === "BlockStatement"; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var arrowParens = { + meta: { + type: "layout", + + docs: { + description: "require parentheses around arrow function arguments", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/arrow-parens" + }, + + fixable: "code", + + schema: [ + { + enum: ["always", "as-needed"] + }, + { + type: "object", + properties: { + requireForBlockBody: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + messages: { + unexpectedParens: "Unexpected parentheses around single function argument.", + expectedParens: "Expected parentheses around arrow function argument.", + + unexpectedParensInline: "Unexpected parentheses around single function argument having a body with no curly braces.", + expectedParensBlock: "Expected parentheses around arrow function argument having a body with curly braces." + } + }, + + create(context) { + const asNeeded = context.options[0] === "as-needed"; + const requireForBlockBody = asNeeded && context.options[1] && context.options[1].requireForBlockBody === true; + + const sourceCode = context.getSourceCode(); + + /** + * Finds opening paren of parameters for the given arrow function, if it exists. + * It is assumed that the given arrow function has exactly one parameter. + * @param {ASTNode} node `ArrowFunctionExpression` node. + * @returns {Token|null} the opening paren, or `null` if the given arrow function doesn't have parens of parameters. + */ + function findOpeningParenOfParams(node) { + const tokenBeforeParams = sourceCode.getTokenBefore(node.params[0]); + + if ( + tokenBeforeParams && + astUtils.isOpeningParenToken(tokenBeforeParams) && + node.range[0] <= tokenBeforeParams.range[0] + ) { + return tokenBeforeParams; + } + + return null; + } + + /** + * Finds closing paren of parameters for the given arrow function. + * It is assumed that the given arrow function has parens of parameters and that it has exactly one parameter. + * @param {ASTNode} node `ArrowFunctionExpression` node. + * @returns {Token} the closing paren of parameters. + */ + function getClosingParenOfParams(node) { + return sourceCode.getTokenAfter(node.params[0], astUtils.isClosingParenToken); + } + + /** + * Determines whether the given arrow function has comments inside parens of parameters. + * It is assumed that the given arrow function has parens of parameters. + * @param {ASTNode} node `ArrowFunctionExpression` node. + * @param {Token} openingParen Opening paren of parameters. + * @returns {boolean} `true` if the function has at least one comment inside of parens of parameters. + */ + function hasCommentsInParensOfParams(node, openingParen) { + return sourceCode.commentsExistBetween(openingParen, getClosingParenOfParams(node)); + } + + /** + * Determines whether the given arrow function has unexpected tokens before opening paren of parameters, + * in which case it will be assumed that the existing parens of parameters are necessary. + * Only tokens within the range of the arrow function (tokens that are part of the arrow function) are taken into account. + * Example: (a) => b + * @param {ASTNode} node `ArrowFunctionExpression` node. + * @param {Token} openingParen Opening paren of parameters. + * @returns {boolean} `true` if the function has at least one unexpected token. + */ + function hasUnexpectedTokensBeforeOpeningParen(node, openingParen) { + const expectedCount = node.async ? 1 : 0; + + return sourceCode.getFirstToken(node, { skip: expectedCount }) !== openingParen; + } + + return { + "ArrowFunctionExpression[params.length=1]"(node) { + const shouldHaveParens = !asNeeded || requireForBlockBody && hasBlockBody(node); + const openingParen = findOpeningParenOfParams(node); + const hasParens = openingParen !== null; + const [param] = node.params; + + if (shouldHaveParens && !hasParens) { + context.report({ + node, + messageId: requireForBlockBody ? "expectedParensBlock" : "expectedParens", + loc: param.loc, + *fix(fixer) { + yield fixer.insertTextBefore(param, "("); + yield fixer.insertTextAfter(param, ")"); + } + }); + } + + if ( + !shouldHaveParens && + hasParens && + param.type === "Identifier" && + !param.typeAnnotation && + !node.returnType && + !hasCommentsInParensOfParams(node, openingParen) && + !hasUnexpectedTokensBeforeOpeningParen(node, openingParen) + ) { + context.report({ + node, + messageId: requireForBlockBody ? "unexpectedParensInline" : "unexpectedParens", + loc: param.loc, + *fix(fixer) { + const tokenBeforeOpeningParen = sourceCode.getTokenBefore(openingParen); + const closingParen = getClosingParenOfParams(node); + + if ( + tokenBeforeOpeningParen && + tokenBeforeOpeningParen.range[1] === openingParen.range[0] && + !astUtils.canTokensBeAdjacent(tokenBeforeOpeningParen, sourceCode.getFirstToken(param)) + ) { + yield fixer.insertTextBefore(openingParen, " "); + } + + // remove parens, whitespace inside parens, and possible trailing comma + yield fixer.removeRange([openingParen.range[0], param.range[0]]); + yield fixer.removeRange([param.range[1], closingParen.range[1]]); + } + }); + } + } + }; + } +}; + +/** + * @fileoverview Rule to define spacing before/after arrow function's arrow. + * @author Jxck + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var arrowSpacing = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent spacing before and after the arrow in arrow functions", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/arrow-spacing" + }, + + fixable: "whitespace", + + schema: [ + { + type: "object", + properties: { + before: { + type: "boolean", + default: true + }, + after: { + type: "boolean", + default: true + } + }, + additionalProperties: false + } + ], + + messages: { + expectedBefore: "Missing space before =>.", + unexpectedBefore: "Unexpected space before =>.", + + expectedAfter: "Missing space after =>.", + unexpectedAfter: "Unexpected space after =>." + } + }, + + create(context) { + + // merge rules with default + const rule = Object.assign({}, context.options[0]); + + rule.before = rule.before !== false; + rule.after = rule.after !== false; + + const sourceCode = context.getSourceCode(); + + /** + * Get tokens of arrow(`=>`) and before/after arrow. + * @param {ASTNode} node The arrow function node. + * @returns {Object} Tokens of arrow and before/after arrow. + */ + function getTokens(node) { + const arrow = sourceCode.getTokenBefore(node.body, astUtils.isArrowToken); + + return { + before: sourceCode.getTokenBefore(arrow), + arrow, + after: sourceCode.getTokenAfter(arrow) + }; + } + + /** + * Count spaces before/after arrow(`=>`) token. + * @param {Object} tokens Tokens before/after arrow. + * @returns {Object} count of space before/after arrow. + */ + function countSpaces(tokens) { + const before = tokens.arrow.range[0] - tokens.before.range[1]; + const after = tokens.after.range[0] - tokens.arrow.range[1]; + + return { before, after }; + } + + /** + * Determines whether space(s) before after arrow(`=>`) is satisfy rule. + * if before/after value is `true`, there should be space(s). + * if before/after value is `false`, there should be no space. + * @param {ASTNode} node The arrow function node. + * @returns {void} + */ + function spaces(node) { + const tokens = getTokens(node); + const countSpace = countSpaces(tokens); + + if (rule.before) { + + // should be space(s) before arrow + if (countSpace.before === 0) { + context.report({ + node: tokens.before, + messageId: "expectedBefore", + fix(fixer) { + return fixer.insertTextBefore(tokens.arrow, " "); + } + }); + } + } else { + + // should be no space before arrow + if (countSpace.before > 0) { + context.report({ + node: tokens.before, + messageId: "unexpectedBefore", + fix(fixer) { + return fixer.removeRange([tokens.before.range[1], tokens.arrow.range[0]]); + } + }); + } + } + + if (rule.after) { + + // should be space(s) after arrow + if (countSpace.after === 0) { + context.report({ + node: tokens.after, + messageId: "expectedAfter", + fix(fixer) { + return fixer.insertTextAfter(tokens.arrow, " "); + } + }); + } + } else { + + // should be no space after arrow + if (countSpace.after > 0) { + context.report({ + node: tokens.after, + messageId: "unexpectedAfter", + fix(fixer) { + return fixer.removeRange([tokens.arrow.range[1], tokens.after.range[0]]); + } + }); + } + } + } + + return { + ArrowFunctionExpression: spaces + }; + } +}; + +/** + * @fileoverview Rule to check for "block scoped" variables by binding context + * @author Matt DuVall + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var blockScopedVar = { + meta: { + type: "suggestion", + + docs: { + description: "enforce the use of variables within the scope they are defined", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/block-scoped-var" + }, + + schema: [], + + messages: { + outOfScope: "'{{name}}' used outside of binding context." + } + }, + + create(context) { + let stack = []; + + /** + * Makes a block scope. + * @param {ASTNode} node A node of a scope. + * @returns {void} + */ + function enterScope(node) { + stack.push(node.range); + } + + /** + * Pops the last block scope. + * @returns {void} + */ + function exitScope() { + stack.pop(); + } + + /** + * Reports a given reference. + * @param {eslint-scope.Reference} reference A reference to report. + * @returns {void} + */ + function report(reference) { + const identifier = reference.identifier; + + context.report({ node: identifier, messageId: "outOfScope", data: { name: identifier.name } }); + } + + /** + * Finds and reports references which are outside of valid scopes. + * @param {ASTNode} node A node to get variables. + * @returns {void} + */ + function checkForVariables(node) { + if (node.kind !== "var") { + return; + } + + // Defines a predicate to check whether or not a given reference is outside of valid scope. + const scopeRange = stack[stack.length - 1]; + + /** + * Check if a reference is out of scope + * @param {ASTNode} reference node to examine + * @returns {boolean} True is its outside the scope + * @private + */ + function isOutsideOfScope(reference) { + const idRange = reference.identifier.range; + + return idRange[0] < scopeRange[0] || idRange[1] > scopeRange[1]; + } + + // Gets declared variables, and checks its references. + const variables = context.getDeclaredVariables(node); + + for (let i = 0; i < variables.length; ++i) { + + // Reports. + variables[i] + .references + .filter(isOutsideOfScope) + .forEach(report); + } + } + + return { + Program(node) { + stack = [node.range]; + }, + + // Manages scopes. + BlockStatement: enterScope, + "BlockStatement:exit": exitScope, + ForStatement: enterScope, + "ForStatement:exit": exitScope, + ForInStatement: enterScope, + "ForInStatement:exit": exitScope, + ForOfStatement: enterScope, + "ForOfStatement:exit": exitScope, + SwitchStatement: enterScope, + "SwitchStatement:exit": exitScope, + CatchClause: enterScope, + "CatchClause:exit": exitScope, + + // Finds and reports references which are outside of valid scope. + VariableDeclaration: checkForVariables + }; + + } +}; + +/** + * @fileoverview A rule to disallow or enforce spaces inside of single line blocks. + * @author Toru Nagashima + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var blockSpacing = { + meta: { + type: "layout", + + docs: { + description: "disallow or enforce spaces inside of blocks after opening block and before closing block", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/block-spacing" + }, + + fixable: "whitespace", + + schema: [ + { enum: ["always", "never"] } + ], + + messages: { + missing: "Requires a space {{location}} '{{token}}'.", + extra: "Unexpected space(s) {{location}} '{{token}}'." + } + }, + + create(context) { + const always = (context.options[0] !== "never"), + messageId = always ? "missing" : "extra", + sourceCode = context.getSourceCode(); + + /** + * Gets the open brace token from a given node. + * @param {ASTNode} node A BlockStatement/SwitchStatement node to get. + * @returns {Token} The token of the open brace. + */ + function getOpenBrace(node) { + if (node.type === "SwitchStatement") { + if (node.cases.length > 0) { + return sourceCode.getTokenBefore(node.cases[0]); + } + return sourceCode.getLastToken(node, 1); + } + return sourceCode.getFirstToken(node); + } + + /** + * Checks whether or not: + * - given tokens are on same line. + * - there is/isn't a space between given tokens. + * @param {Token} left A token to check. + * @param {Token} right The token which is next to `left`. + * @returns {boolean} + * When the option is `"always"`, `true` if there are one or more spaces between given tokens. + * When the option is `"never"`, `true` if there are not any spaces between given tokens. + * If given tokens are not on same line, it's always `true`. + */ + function isValid(left, right) { + return ( + !astUtils.isTokenOnSameLine(left, right) || + sourceCode.isSpaceBetweenTokens(left, right) === always + ); + } + + /** + * Reports invalid spacing style inside braces. + * @param {ASTNode} node A BlockStatement/SwitchStatement node to get. + * @returns {void} + */ + function checkSpacingInsideBraces(node) { + + // Gets braces and the first/last token of content. + const openBrace = getOpenBrace(node); + const closeBrace = sourceCode.getLastToken(node); + const firstToken = sourceCode.getTokenAfter(openBrace, { includeComments: true }); + const lastToken = sourceCode.getTokenBefore(closeBrace, { includeComments: true }); + + // Skip if the node is invalid or empty. + if (openBrace.type !== "Punctuator" || + openBrace.value !== "{" || + closeBrace.type !== "Punctuator" || + closeBrace.value !== "}" || + firstToken === closeBrace + ) { + return; + } + + // Skip line comments for option never + if (!always && firstToken.type === "Line") { + return; + } + + // Check. + if (!isValid(openBrace, firstToken)) { + let loc = openBrace.loc; + + if (messageId === "extra") { + loc = { + start: openBrace.loc.end, + end: firstToken.loc.start + }; + } + + context.report({ + node, + loc, + messageId, + data: { + location: "after", + token: openBrace.value + }, + fix(fixer) { + if (always) { + return fixer.insertTextBefore(firstToken, " "); + } + + return fixer.removeRange([openBrace.range[1], firstToken.range[0]]); + } + }); + } + if (!isValid(lastToken, closeBrace)) { + let loc = closeBrace.loc; + + if (messageId === "extra") { + loc = { + start: lastToken.loc.end, + end: closeBrace.loc.start + }; + } + context.report({ + node, + loc, + messageId, + data: { + location: "before", + token: closeBrace.value + }, + fix(fixer) { + if (always) { + return fixer.insertTextAfter(lastToken, " "); + } + + return fixer.removeRange([lastToken.range[1], closeBrace.range[0]]); + } + }); + } + } + + return { + BlockStatement: checkSpacingInsideBraces, + SwitchStatement: checkSpacingInsideBraces + }; + } +}; + +/** + * @fileoverview Rule to flag block statements that do not use the one true brace style + * @author Ian Christian Myers + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var braceStyle = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent brace style for blocks", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/brace-style" + }, + + schema: [ + { + enum: ["1tbs", "stroustrup", "allman"] + }, + { + type: "object", + properties: { + allowSingleLine: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + fixable: "whitespace", + + messages: { + nextLineOpen: "Opening curly brace does not appear on the same line as controlling statement.", + sameLineOpen: "Opening curly brace appears on the same line as controlling statement.", + blockSameLine: "Statement inside of curly braces should be on next line.", + nextLineClose: "Closing curly brace does not appear on the same line as the subsequent block.", + singleLineClose: "Closing curly brace should be on the same line as opening curly brace or on the line after the previous block.", + sameLineClose: "Closing curly brace appears on the same line as the subsequent block." + } + }, + + create(context) { + const style = context.options[0] || "1tbs", + params = context.options[1] || {}, + sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Fixes a place where a newline unexpectedly appears + * @param {Token} firstToken The token before the unexpected newline + * @param {Token} secondToken The token after the unexpected newline + * @returns {Function} A fixer function to remove the newlines between the tokens + */ + function removeNewlineBetween(firstToken, secondToken) { + const textRange = [firstToken.range[1], secondToken.range[0]]; + const textBetween = sourceCode.text.slice(textRange[0], textRange[1]); + + // Don't do a fix if there is a comment between the tokens + if (textBetween.trim()) { + return null; + } + return fixer => fixer.replaceTextRange(textRange, " "); + } + + /** + * Validates a pair of curly brackets based on the user's config + * @param {Token} openingCurly The opening curly bracket + * @param {Token} closingCurly The closing curly bracket + * @returns {void} + */ + function validateCurlyPair(openingCurly, closingCurly) { + const tokenBeforeOpeningCurly = sourceCode.getTokenBefore(openingCurly); + const tokenAfterOpeningCurly = sourceCode.getTokenAfter(openingCurly); + const tokenBeforeClosingCurly = sourceCode.getTokenBefore(closingCurly); + const singleLineException = params.allowSingleLine && astUtils.isTokenOnSameLine(openingCurly, closingCurly); + + if (style !== "allman" && !astUtils.isTokenOnSameLine(tokenBeforeOpeningCurly, openingCurly)) { + context.report({ + node: openingCurly, + messageId: "nextLineOpen", + fix: removeNewlineBetween(tokenBeforeOpeningCurly, openingCurly) + }); + } + + if (style === "allman" && astUtils.isTokenOnSameLine(tokenBeforeOpeningCurly, openingCurly) && !singleLineException) { + context.report({ + node: openingCurly, + messageId: "sameLineOpen", + fix: fixer => fixer.insertTextBefore(openingCurly, "\n") + }); + } + + if (astUtils.isTokenOnSameLine(openingCurly, tokenAfterOpeningCurly) && tokenAfterOpeningCurly !== closingCurly && !singleLineException) { + context.report({ + node: openingCurly, + messageId: "blockSameLine", + fix: fixer => fixer.insertTextAfter(openingCurly, "\n") + }); + } + + if (tokenBeforeClosingCurly !== openingCurly && !singleLineException && astUtils.isTokenOnSameLine(tokenBeforeClosingCurly, closingCurly)) { + context.report({ + node: closingCurly, + messageId: "singleLineClose", + fix: fixer => fixer.insertTextBefore(closingCurly, "\n") + }); + } + } + + /** + * Validates the location of a token that appears before a keyword (e.g. a newline before `else`) + * @param {Token} curlyToken The closing curly token. This is assumed to precede a keyword token (such as `else` or `finally`). + * @returns {void} + */ + function validateCurlyBeforeKeyword(curlyToken) { + const keywordToken = sourceCode.getTokenAfter(curlyToken); + + if (style === "1tbs" && !astUtils.isTokenOnSameLine(curlyToken, keywordToken)) { + context.report({ + node: curlyToken, + messageId: "nextLineClose", + fix: removeNewlineBetween(curlyToken, keywordToken) + }); + } + + if (style !== "1tbs" && astUtils.isTokenOnSameLine(curlyToken, keywordToken)) { + context.report({ + node: curlyToken, + messageId: "sameLineClose", + fix: fixer => fixer.insertTextAfter(curlyToken, "\n") + }); + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + BlockStatement(node) { + if (!astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type)) { + validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node)); + } + }, + ClassBody(node) { + validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node)); + }, + SwitchStatement(node) { + const closingCurly = sourceCode.getLastToken(node); + const openingCurly = sourceCode.getTokenBefore(node.cases.length ? node.cases[0] : closingCurly); + + validateCurlyPair(openingCurly, closingCurly); + }, + IfStatement(node) { + if (node.consequent.type === "BlockStatement" && node.alternate) { + + // Handle the keyword after the `if` block (before `else`) + validateCurlyBeforeKeyword(sourceCode.getLastToken(node.consequent)); + } + }, + TryStatement(node) { + + // Handle the keyword after the `try` block (before `catch` or `finally`) + validateCurlyBeforeKeyword(sourceCode.getLastToken(node.block)); + + if (node.handler && node.finalizer) { + + // Handle the keyword after the `catch` block (before `finally`) + validateCurlyBeforeKeyword(sourceCode.getLastToken(node.handler.body)); + } + } + }; + } +}; + +/** + * @fileoverview Enforce return after a callback. + * @author Jamund Ferguson + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var callbackReturn = { + meta: { + deprecated: true, + + replacedBy: [], + + type: "suggestion", + + docs: { + description: "require `return` statements after callbacks", + category: "Node.js and CommonJS", + recommended: false, + url: "https://eslint.org/docs/rules/callback-return" + }, + + schema: [{ + type: "array", + items: { type: "string" } + }], + + messages: { + missingReturn: "Expected return with your callback function." + } + }, + + create(context) { + + const callbacks = context.options[0] || ["callback", "cb", "next"], + sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Find the closest parent matching a list of types. + * @param {ASTNode} node The node whose parents we are searching + * @param {Array} types The node types to match + * @returns {ASTNode} The matched node or undefined. + */ + function findClosestParentOfType(node, types) { + if (!node.parent) { + return null; + } + if (types.indexOf(node.parent.type) === -1) { + return findClosestParentOfType(node.parent, types); + } + return node.parent; + } + + /** + * Check to see if a node contains only identifiers + * @param {ASTNode} node The node to check + * @returns {boolean} Whether or not the node contains only identifiers + */ + function containsOnlyIdentifiers(node) { + if (node.type === "Identifier") { + return true; + } + + if (node.type === "MemberExpression") { + if (node.object.type === "Identifier") { + return true; + } + if (node.object.type === "MemberExpression") { + return containsOnlyIdentifiers(node.object); + } + } + + return false; + } + + /** + * Check to see if a CallExpression is in our callback list. + * @param {ASTNode} node The node to check against our callback names list. + * @returns {boolean} Whether or not this function matches our callback name. + */ + function isCallback(node) { + return containsOnlyIdentifiers(node.callee) && callbacks.indexOf(sourceCode.getText(node.callee)) > -1; + } + + /** + * Determines whether or not the callback is part of a callback expression. + * @param {ASTNode} node The callback node + * @param {ASTNode} parentNode The expression node + * @returns {boolean} Whether or not this is part of a callback expression + */ + function isCallbackExpression(node, parentNode) { + + // ensure the parent node exists and is an expression + if (!parentNode || parentNode.type !== "ExpressionStatement") { + return false; + } + + // cb() + if (parentNode.expression === node) { + return true; + } + + // special case for cb && cb() and similar + if (parentNode.expression.type === "BinaryExpression" || parentNode.expression.type === "LogicalExpression") { + if (parentNode.expression.right === node) { + return true; + } + } + + return false; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + CallExpression(node) { + + // if we're not a callback we can return + if (!isCallback(node)) { + return; + } + + // find the closest block, return or loop + const closestBlock = findClosestParentOfType(node, ["BlockStatement", "ReturnStatement", "ArrowFunctionExpression"]) || {}; + + // if our parent is a return we know we're ok + if (closestBlock.type === "ReturnStatement") { + return; + } + + // arrow functions don't always have blocks and implicitly return + if (closestBlock.type === "ArrowFunctionExpression") { + return; + } + + // block statements are part of functions and most if statements + if (closestBlock.type === "BlockStatement") { + + // find the last item in the block + const lastItem = closestBlock.body[closestBlock.body.length - 1]; + + // if the callback is the last thing in a block that might be ok + if (isCallbackExpression(node, lastItem)) { + + const parentType = closestBlock.parent.type; + + // but only if the block is part of a function + if (parentType === "FunctionExpression" || + parentType === "FunctionDeclaration" || + parentType === "ArrowFunctionExpression" + ) { + return; + } + + } + + // ending a block with a return is also ok + if (lastItem.type === "ReturnStatement") { + + // but only if the callback is immediately before + if (isCallbackExpression(node, closestBlock.body[closestBlock.body.length - 2])) { + return; + } + } + + } + + // as long as you're the child of a function at this point you should be asked to return + if (findClosestParentOfType(node, ["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"])) { + context.report({ node, messageId: "missingReturn" }); + } + + } + + }; + } +}; + +/** + * @fileoverview Rule to flag non-camelcased identifiers + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var camelcase = { + meta: { + type: "suggestion", + + docs: { + description: "enforce camelcase naming convention", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/camelcase" + }, + + schema: [ + { + type: "object", + properties: { + ignoreDestructuring: { + type: "boolean", + default: false + }, + ignoreImports: { + type: "boolean", + default: false + }, + ignoreGlobals: { + type: "boolean", + default: false + }, + properties: { + enum: ["always", "never"] + }, + allow: { + type: "array", + items: [ + { + type: "string" + } + ], + minItems: 0, + uniqueItems: true + } + }, + additionalProperties: false + } + ], + + messages: { + notCamelCase: "Identifier '{{name}}' is not in camel case." + } + }, + + create(context) { + + const options = context.options[0] || {}; + let properties = options.properties || ""; + const ignoreDestructuring = options.ignoreDestructuring; + const ignoreImports = options.ignoreImports; + const ignoreGlobals = options.ignoreGlobals; + const allow = options.allow || []; + + let globalScope; + + if (properties !== "always" && properties !== "never") { + properties = "always"; + } + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + // contains reported nodes to avoid reporting twice on destructuring with shorthand notation + const reported = []; + const ALLOWED_PARENT_TYPES = new Set(["CallExpression", "NewExpression"]); + + /** + * Checks if a string contains an underscore and isn't all upper-case + * @param {string} name The string to check. + * @returns {boolean} if the string is underscored + * @private + */ + function isUnderscored(name) { + + // if there's an underscore, it might be A_CONSTANT, which is okay + return name.includes("_") && name !== name.toUpperCase(); + } + + /** + * Checks if a string match the ignore list + * @param {string} name The string to check. + * @returns {boolean} if the string is ignored + * @private + */ + function isAllowed(name) { + return allow.some( + entry => name === entry || name.match(new RegExp(entry, "u")) + ); + } + + /** + * Checks if a parent of a node is an ObjectPattern. + * @param {ASTNode} node The node to check. + * @returns {boolean} if the node is inside an ObjectPattern + * @private + */ + function isInsideObjectPattern(node) { + let current = node; + + while (current) { + const parent = current.parent; + + if (parent && parent.type === "Property" && parent.computed && parent.key === current) { + return false; + } + + if (current.type === "ObjectPattern") { + return true; + } + + current = parent; + } + + return false; + } + + /** + * Checks whether the given node represents assignment target property in destructuring. + * + * For examples: + * ({a: b.foo} = c); // => true for `foo` + * ([a.foo] = b); // => true for `foo` + * ([a.foo = 1] = b); // => true for `foo` + * ({...a.foo} = b); // => true for `foo` + * @param {ASTNode} node An Identifier node to check + * @returns {boolean} True if the node is an assignment target property in destructuring. + */ + function isAssignmentTargetPropertyInDestructuring(node) { + if ( + node.parent.type === "MemberExpression" && + node.parent.property === node && + !node.parent.computed + ) { + const effectiveParent = node.parent.parent; + + return ( + effectiveParent.type === "Property" && + effectiveParent.value === node.parent && + effectiveParent.parent.type === "ObjectPattern" || + effectiveParent.type === "ArrayPattern" || + effectiveParent.type === "RestElement" || + ( + effectiveParent.type === "AssignmentPattern" && + effectiveParent.left === node.parent + ) + ); + } + return false; + } + + /** + * Checks whether the given node represents a reference to a global variable that is not declared in the source code. + * These identifiers will be allowed, as it is assumed that user has no control over the names of external global variables. + * @param {ASTNode} node `Identifier` node to check. + * @returns {boolean} `true` if the node is a reference to a global variable. + */ + function isReferenceToGlobalVariable(node) { + const variable = globalScope.set.get(node.name); + + return variable && variable.defs.length === 0 && + variable.references.some(ref => ref.identifier === node); + } + + /** + * Checks whether the given node represents a reference to a property of an object in an object literal expression. + * This allows to differentiate between a global variable that is allowed to be used as a reference, and the key + * of the expressed object (which shouldn't be allowed). + * @param {ASTNode} node `Identifier` node to check. + * @returns {boolean} `true` if the node is a property name of an object literal expression + */ + function isPropertyNameInObjectLiteral(node) { + const parent = node.parent; + + return ( + parent.type === "Property" && + parent.parent.type === "ObjectExpression" && + !parent.computed && + parent.key === node + ); + } + + /** + * Reports an AST node as a rule violation. + * @param {ASTNode} node The node to report. + * @returns {void} + * @private + */ + function report(node) { + if (!reported.includes(node)) { + reported.push(node); + context.report({ node, messageId: "notCamelCase", data: { name: node.name } }); + } + } + + return { + + Program() { + globalScope = context.getScope(); + }, + + Identifier(node) { + + /* + * Leading and trailing underscores are commonly used to flag + * private/protected identifiers, strip them before checking if underscored + */ + const name = node.name, + nameIsUnderscored = isUnderscored(name.replace(/^_+|_+$/gu, "")), + effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent; + + // First, we ignore the node if it match the ignore list + if (isAllowed(name)) { + return; + } + + // Check if it's a global variable + if (ignoreGlobals && isReferenceToGlobalVariable(node) && !isPropertyNameInObjectLiteral(node)) { + return; + } + + // MemberExpressions get special rules + if (node.parent.type === "MemberExpression") { + + // "never" check properties + if (properties === "never") { + return; + } + + // Always report underscored object names + if (node.parent.object.type === "Identifier" && node.parent.object.name === node.name && nameIsUnderscored) { + report(node); + + // Report AssignmentExpressions only if they are the left side of the assignment + } else if (effectiveParent.type === "AssignmentExpression" && nameIsUnderscored && (effectiveParent.right.type !== "MemberExpression" || effectiveParent.left.type === "MemberExpression" && effectiveParent.left.property.name === node.name)) { + report(node); + + } else if (isAssignmentTargetPropertyInDestructuring(node) && nameIsUnderscored) { + report(node); + } + + /* + * Properties have their own rules, and + * AssignmentPattern nodes can be treated like Properties: + * e.g.: const { no_camelcased = false } = bar; + */ + } else if (node.parent.type === "Property" || node.parent.type === "AssignmentPattern") { + + if (node.parent.parent && node.parent.parent.type === "ObjectPattern") { + if (node.parent.shorthand && node.parent.value.left && nameIsUnderscored) { + report(node); + } + + const assignmentKeyEqualsValue = node.parent.key.name === node.parent.value.name; + + if (nameIsUnderscored && node.parent.computed) { + report(node); + } + + // prevent checking righthand side of destructured object + if (node.parent.key === node && node.parent.value !== node) { + return; + } + + const valueIsUnderscored = node.parent.value.name && nameIsUnderscored; + + // ignore destructuring if the option is set, unless a new identifier is created + if (valueIsUnderscored && !(assignmentKeyEqualsValue && ignoreDestructuring)) { + report(node); + } + } + + // "never" check properties or always ignore destructuring + if (properties === "never" || (ignoreDestructuring && isInsideObjectPattern(node))) { + return; + } + + // don't check right hand side of AssignmentExpression to prevent duplicate warnings + if (nameIsUnderscored && !ALLOWED_PARENT_TYPES.has(effectiveParent.type) && !(node.parent.right === node)) { + report(node); + } + + // Check if it's an import specifier + } else if (["ImportSpecifier", "ImportNamespaceSpecifier", "ImportDefaultSpecifier"].includes(node.parent.type)) { + + if (node.parent.type === "ImportSpecifier" && ignoreImports) { + return; + } + + // Report only if the local imported identifier is underscored + if ( + node.parent.local && + node.parent.local.name === node.name && + nameIsUnderscored + ) { + report(node); + } + + // Report anything that is underscored that isn't a CallExpression + } else if (nameIsUnderscored && !ALLOWED_PARENT_TYPES.has(effectiveParent.type)) { + report(node); + } + } + + }; + + } +}; + +/** + * @fileoverview Pattern for detecting any letter (even letters outside of ASCII). + * NOTE: This file was generated using this script in JSCS based on the Unicode 7.0.0 standard: https://github.com/jscs-dev/node-jscs/blob/f5ed14427deb7e7aac84f3056a5aab2d9f3e563e/publish/helpers/generate-patterns.js + * Do not edit this file by hand-- please use https://github.com/mathiasbynens/regenerate to regenerate the regular expression exported from this file. + * @author Kevin Partington + * @license MIT License (from JSCS). See below. + */ + +var letters = /[A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDE00-\uDE11\uDE13-\uDE2B\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDE00-\uDE2F\uDE44\uDE80-\uDEAA]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]/u; + +/** + * @fileoverview enforce or disallow capitalization of the first letter of a comment + * @author Kevin Partington + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const DEFAULT_IGNORE_PATTERN = astUtils.COMMENTS_IGNORE_PATTERN, + WHITESPACE = /\s/gu, + MAYBE_URL = /^\s*[^:/?#\s]+:\/\/[^?#]/u; // TODO: Combine w/ max-len pattern? + +/* + * Base schema body for defining the basic capitalization rule, ignorePattern, + * and ignoreInlineComments values. + * This can be used in a few different ways in the actual schema. + */ +const SCHEMA_BODY = { + type: "object", + properties: { + ignorePattern: { + type: "string" + }, + ignoreInlineComments: { + type: "boolean" + }, + ignoreConsecutiveComments: { + type: "boolean" + } + }, + additionalProperties: false +}; +const DEFAULTS = { + ignorePattern: "", + ignoreInlineComments: false, + ignoreConsecutiveComments: false +}; + +/** + * Get normalized options for either block or line comments from the given + * user-provided options. + * - If the user-provided options is just a string, returns a normalized + * set of options using default values for all other options. + * - If the user-provided options is an object, then a normalized option + * set is returned. Options specified in overrides will take priority + * over options specified in the main options object, which will in + * turn take priority over the rule's defaults. + * @param {Object|string} rawOptions The user-provided options. + * @param {string} which Either "line" or "block". + * @returns {Object} The normalized options. + */ +function getNormalizedOptions(rawOptions, which) { + return Object.assign({}, DEFAULTS, rawOptions[which] || rawOptions); +} + +/** + * Get normalized options for block and line comments. + * @param {Object|string} rawOptions The user-provided options. + * @returns {Object} An object with "Line" and "Block" keys and corresponding + * normalized options objects. + */ +function getAllNormalizedOptions(rawOptions = {}) { + return { + Line: getNormalizedOptions(rawOptions, "line"), + Block: getNormalizedOptions(rawOptions, "block") + }; +} + +/** + * Creates a regular expression for each ignorePattern defined in the rule + * options. + * + * This is done in order to avoid invoking the RegExp constructor repeatedly. + * @param {Object} normalizedOptions The normalized rule options. + * @returns {void} + */ +function createRegExpForIgnorePatterns(normalizedOptions) { + Object.keys(normalizedOptions).forEach(key => { + const ignorePatternStr = normalizedOptions[key].ignorePattern; + + if (ignorePatternStr) { + const regExp = RegExp(`^\\s*(?:${ignorePatternStr})`, "u"); + + normalizedOptions[key].ignorePatternRegExp = regExp; + } + }); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var capitalizedComments = { + meta: { + type: "suggestion", + + docs: { + description: "enforce or disallow capitalization of the first letter of a comment", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/capitalized-comments" + }, + + fixable: "code", + + schema: [ + { enum: ["always", "never"] }, + { + oneOf: [ + SCHEMA_BODY, + { + type: "object", + properties: { + line: SCHEMA_BODY, + block: SCHEMA_BODY + }, + additionalProperties: false + } + ] + } + ], + + messages: { + unexpectedLowercaseComment: "Comments should not begin with a lowercase character.", + unexpectedUppercaseComment: "Comments should not begin with an uppercase character." + } + }, + + create(context) { + + const capitalize = context.options[0] || "always", + normalizedOptions = getAllNormalizedOptions(context.options[1]), + sourceCode = context.getSourceCode(); + + createRegExpForIgnorePatterns(normalizedOptions); + + //---------------------------------------------------------------------- + // Helpers + //---------------------------------------------------------------------- + + /** + * Checks whether a comment is an inline comment. + * + * For the purpose of this rule, a comment is inline if: + * 1. The comment is preceded by a token on the same line; and + * 2. The command is followed by a token on the same line. + * + * Note that the comment itself need not be single-line! + * + * Also, it follows from this definition that only block comments can + * be considered as possibly inline. This is because line comments + * would consume any following tokens on the same line as the comment. + * @param {ASTNode} comment The comment node to check. + * @returns {boolean} True if the comment is an inline comment, false + * otherwise. + */ + function isInlineComment(comment) { + const previousToken = sourceCode.getTokenBefore(comment, { includeComments: true }), + nextToken = sourceCode.getTokenAfter(comment, { includeComments: true }); + + return Boolean( + previousToken && + nextToken && + comment.loc.start.line === previousToken.loc.end.line && + comment.loc.end.line === nextToken.loc.start.line + ); + } + + /** + * Determine if a comment follows another comment. + * @param {ASTNode} comment The comment to check. + * @returns {boolean} True if the comment follows a valid comment. + */ + function isConsecutiveComment(comment) { + const previousTokenOrComment = sourceCode.getTokenBefore(comment, { includeComments: true }); + + return Boolean( + previousTokenOrComment && + ["Block", "Line"].indexOf(previousTokenOrComment.type) !== -1 + ); + } + + /** + * Check a comment to determine if it is valid for this rule. + * @param {ASTNode} comment The comment node to process. + * @param {Object} options The options for checking this comment. + * @returns {boolean} True if the comment is valid, false otherwise. + */ + function isCommentValid(comment, options) { + + // 1. Check for default ignore pattern. + if (DEFAULT_IGNORE_PATTERN.test(comment.value)) { + return true; + } + + // 2. Check for custom ignore pattern. + const commentWithoutAsterisks = comment.value + .replace(/\*/gu, ""); + + if (options.ignorePatternRegExp && options.ignorePatternRegExp.test(commentWithoutAsterisks)) { + return true; + } + + // 3. Check for inline comments. + if (options.ignoreInlineComments && isInlineComment(comment)) { + return true; + } + + // 4. Is this a consecutive comment (and are we tolerating those)? + if (options.ignoreConsecutiveComments && isConsecutiveComment(comment)) { + return true; + } + + // 5. Does the comment start with a possible URL? + if (MAYBE_URL.test(commentWithoutAsterisks)) { + return true; + } + + // 6. Is the initial word character a letter? + const commentWordCharsOnly = commentWithoutAsterisks + .replace(WHITESPACE, ""); + + if (commentWordCharsOnly.length === 0) { + return true; + } + + const firstWordChar = commentWordCharsOnly[0]; + + if (!letters.test(firstWordChar)) { + return true; + } + + // 7. Check the case of the initial word character. + const isUppercase = firstWordChar !== firstWordChar.toLocaleLowerCase(), + isLowercase = firstWordChar !== firstWordChar.toLocaleUpperCase(); + + if (capitalize === "always" && isLowercase) { + return false; + } + if (capitalize === "never" && isUppercase) { + return false; + } + + return true; + } + + /** + * Process a comment to determine if it needs to be reported. + * @param {ASTNode} comment The comment node to process. + * @returns {void} + */ + function processComment(comment) { + const options = normalizedOptions[comment.type], + commentValid = isCommentValid(comment, options); + + if (!commentValid) { + const messageId = capitalize === "always" + ? "unexpectedLowercaseComment" + : "unexpectedUppercaseComment"; + + context.report({ + node: null, // Intentionally using loc instead + loc: comment.loc, + messageId, + fix(fixer) { + const match = comment.value.match(letters); + + return fixer.replaceTextRange( + + // Offset match.index by 2 to account for the first 2 characters that start the comment (// or /*) + [comment.range[0] + match.index + 2, comment.range[0] + match.index + 3], + capitalize === "always" ? match[0].toLocaleUpperCase() : match[0].toLocaleLowerCase() + ); + } + }); + } + } + + //---------------------------------------------------------------------- + // Public + //---------------------------------------------------------------------- + + return { + Program() { + const comments = sourceCode.getAllComments(); + + comments.filter(token => token.type !== "Shebang").forEach(processComment); + } + }; + } +}; + +/** + * @fileoverview Rule to enforce that all class methods use 'this'. + * @author Patrick Williams + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var classMethodsUseThis = { + meta: { + type: "suggestion", + + docs: { + description: "enforce that class methods utilize `this`", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/class-methods-use-this" + }, + + schema: [{ + type: "object", + properties: { + exceptMethods: { + type: "array", + items: { + type: "string" + } + } + }, + additionalProperties: false + }], + + messages: { + missingThis: "Expected 'this' to be used by class {{name}}." + } + }, + create(context) { + const config = Object.assign({}, context.options[0]); + const exceptMethods = new Set(config.exceptMethods || []); + + const stack = []; + + /** + * Initializes the current context to false and pushes it onto the stack. + * These booleans represent whether 'this' has been used in the context. + * @returns {void} + * @private + */ + function enterFunction() { + stack.push(false); + } + + /** + * Check if the node is an instance method + * @param {ASTNode} node node to check + * @returns {boolean} True if its an instance method + * @private + */ + function isInstanceMethod(node) { + return !node.static && node.kind !== "constructor" && node.type === "MethodDefinition"; + } + + /** + * Check if the node is an instance method not excluded by config + * @param {ASTNode} node node to check + * @returns {boolean} True if it is an instance method, and not excluded by config + * @private + */ + function isIncludedInstanceMethod(node) { + return isInstanceMethod(node) && + (node.computed || !exceptMethods.has(node.key.name)); + } + + /** + * Checks if we are leaving a function that is a method, and reports if 'this' has not been used. + * Static methods and the constructor are exempt. + * Then pops the context off the stack. + * @param {ASTNode} node A function node that was entered. + * @returns {void} + * @private + */ + function exitFunction(node) { + const methodUsesThis = stack.pop(); + + if (isIncludedInstanceMethod(node.parent) && !methodUsesThis) { + context.report({ + node, + messageId: "missingThis", + data: { + name: astUtils.getFunctionNameWithKind(node) + } + }); + } + } + + /** + * Mark the current context as having used 'this'. + * @returns {void} + * @private + */ + function markThisUsed() { + if (stack.length) { + stack[stack.length - 1] = true; + } + } + + return { + FunctionDeclaration: enterFunction, + "FunctionDeclaration:exit": exitFunction, + FunctionExpression: enterFunction, + "FunctionExpression:exit": exitFunction, + ThisExpression: markThisUsed, + Super: markThisUsed + }; + } +}; + +/** + * @fileoverview Rule to forbid or enforce dangling commas. + * @author Ian Christian Myers + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const DEFAULT_OPTIONS$1 = Object.freeze({ + arrays: "never", + objects: "never", + imports: "never", + exports: "never", + functions: "never" +}); + +/** + * Checks whether or not a trailing comma is allowed in a given node. + * If the `lastItem` is `RestElement` or `RestProperty`, it disallows trailing commas. + * @param {ASTNode} lastItem The node of the last element in the given node. + * @returns {boolean} `true` if a trailing comma is allowed. + */ +function isTrailingCommaAllowed(lastItem) { + return !( + lastItem.type === "RestElement" || + lastItem.type === "RestProperty" || + lastItem.type === "ExperimentalRestProperty" + ); +} + +/** + * Normalize option value. + * @param {string|Object|undefined} optionValue The 1st option value to normalize. + * @param {number} ecmaVersion The normalized ECMAScript version. + * @returns {Object} The normalized option value. + */ +function normalizeOptions$2(optionValue, ecmaVersion) { + if (typeof optionValue === "string") { + return { + arrays: optionValue, + objects: optionValue, + imports: optionValue, + exports: optionValue, + functions: (!ecmaVersion || ecmaVersion < 8) ? "ignore" : optionValue + }; + } + if (typeof optionValue === "object" && optionValue !== null) { + return { + arrays: optionValue.arrays || DEFAULT_OPTIONS$1.arrays, + objects: optionValue.objects || DEFAULT_OPTIONS$1.objects, + imports: optionValue.imports || DEFAULT_OPTIONS$1.imports, + exports: optionValue.exports || DEFAULT_OPTIONS$1.exports, + functions: optionValue.functions || DEFAULT_OPTIONS$1.functions + }; + } + + return DEFAULT_OPTIONS$1; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var commaDangle = { + meta: { + type: "layout", + + docs: { + description: "require or disallow trailing commas", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/comma-dangle" + }, + + fixable: "code", + + schema: { + definitions: { + value: { + enum: [ + "always-multiline", + "always", + "never", + "only-multiline" + ] + }, + valueWithIgnore: { + enum: [ + "always-multiline", + "always", + "ignore", + "never", + "only-multiline" + ] + } + }, + type: "array", + items: [ + { + oneOf: [ + { + $ref: "#/definitions/value" + }, + { + type: "object", + properties: { + arrays: { $ref: "#/definitions/valueWithIgnore" }, + objects: { $ref: "#/definitions/valueWithIgnore" }, + imports: { $ref: "#/definitions/valueWithIgnore" }, + exports: { $ref: "#/definitions/valueWithIgnore" }, + functions: { $ref: "#/definitions/valueWithIgnore" } + }, + additionalProperties: false + } + ] + } + ] + }, + + messages: { + unexpected: "Unexpected trailing comma.", + missing: "Missing trailing comma." + } + }, + + create(context) { + const options = normalizeOptions$2(context.options[0], context.parserOptions.ecmaVersion); + + const sourceCode = context.getSourceCode(); + + /** + * Gets the last item of the given node. + * @param {ASTNode} node The node to get. + * @returns {ASTNode|null} The last node or null. + */ + function getLastItem(node) { + switch (node.type) { + case "ObjectExpression": + case "ObjectPattern": + return lodash__default['default'].last(node.properties); + case "ArrayExpression": + case "ArrayPattern": + return lodash__default['default'].last(node.elements); + case "ImportDeclaration": + case "ExportNamedDeclaration": + return lodash__default['default'].last(node.specifiers); + case "FunctionDeclaration": + case "FunctionExpression": + case "ArrowFunctionExpression": + return lodash__default['default'].last(node.params); + case "CallExpression": + case "NewExpression": + return lodash__default['default'].last(node.arguments); + default: + return null; + } + } + + /** + * Gets the trailing comma token of the given node. + * If the trailing comma does not exist, this returns the token which is + * the insertion point of the trailing comma token. + * @param {ASTNode} node The node to get. + * @param {ASTNode} lastItem The last item of the node. + * @returns {Token} The trailing comma token or the insertion point. + */ + function getTrailingToken(node, lastItem) { + switch (node.type) { + case "ObjectExpression": + case "ArrayExpression": + case "CallExpression": + case "NewExpression": + return sourceCode.getLastToken(node, 1); + default: { + const nextToken = sourceCode.getTokenAfter(lastItem); + + if (astUtils.isCommaToken(nextToken)) { + return nextToken; + } + return sourceCode.getLastToken(lastItem); + } + } + } + + /** + * Checks whether or not a given node is multiline. + * This rule handles a given node as multiline when the closing parenthesis + * and the last element are not on the same line. + * @param {ASTNode} node A node to check. + * @returns {boolean} `true` if the node is multiline. + */ + function isMultiline(node) { + const lastItem = getLastItem(node); + + if (!lastItem) { + return false; + } + + const penultimateToken = getTrailingToken(node, lastItem); + const lastToken = sourceCode.getTokenAfter(penultimateToken); + + return lastToken.loc.end.line !== penultimateToken.loc.end.line; + } + + /** + * Reports a trailing comma if it exists. + * @param {ASTNode} node A node to check. Its type is one of + * ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern, + * ImportDeclaration, and ExportNamedDeclaration. + * @returns {void} + */ + function forbidTrailingComma(node) { + const lastItem = getLastItem(node); + + if (!lastItem || (node.type === "ImportDeclaration" && lastItem.type !== "ImportSpecifier")) { + return; + } + + const trailingToken = getTrailingToken(node, lastItem); + + if (astUtils.isCommaToken(trailingToken)) { + context.report({ + node: lastItem, + loc: trailingToken.loc, + messageId: "unexpected", + fix(fixer) { + return fixer.remove(trailingToken); + } + }); + } + } + + /** + * Reports the last element of a given node if it does not have a trailing + * comma. + * + * If a given node is `ArrayPattern` which has `RestElement`, the trailing + * comma is disallowed, so report if it exists. + * @param {ASTNode} node A node to check. Its type is one of + * ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern, + * ImportDeclaration, and ExportNamedDeclaration. + * @returns {void} + */ + function forceTrailingComma(node) { + const lastItem = getLastItem(node); + + if (!lastItem || (node.type === "ImportDeclaration" && lastItem.type !== "ImportSpecifier")) { + return; + } + if (!isTrailingCommaAllowed(lastItem)) { + forbidTrailingComma(node); + return; + } + + const trailingToken = getTrailingToken(node, lastItem); + + if (trailingToken.value !== ",") { + context.report({ + node: lastItem, + loc: { + start: trailingToken.loc.end, + end: astUtils.getNextLocation(sourceCode, trailingToken.loc.end) + }, + messageId: "missing", + fix(fixer) { + return fixer.insertTextAfter(trailingToken, ","); + } + }); + } + } + + /** + * If a given node is multiline, reports the last element of a given node + * when it does not have a trailing comma. + * Otherwise, reports a trailing comma if it exists. + * @param {ASTNode} node A node to check. Its type is one of + * ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern, + * ImportDeclaration, and ExportNamedDeclaration. + * @returns {void} + */ + function forceTrailingCommaIfMultiline(node) { + if (isMultiline(node)) { + forceTrailingComma(node); + } else { + forbidTrailingComma(node); + } + } + + /** + * Only if a given node is not multiline, reports the last element of a given node + * when it does not have a trailing comma. + * Otherwise, reports a trailing comma if it exists. + * @param {ASTNode} node A node to check. Its type is one of + * ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern, + * ImportDeclaration, and ExportNamedDeclaration. + * @returns {void} + */ + function allowTrailingCommaIfMultiline(node) { + if (!isMultiline(node)) { + forbidTrailingComma(node); + } + } + + const predicate = { + always: forceTrailingComma, + "always-multiline": forceTrailingCommaIfMultiline, + "only-multiline": allowTrailingCommaIfMultiline, + never: forbidTrailingComma, + ignore: lodash__default['default'].noop + }; + + return { + ObjectExpression: predicate[options.objects], + ObjectPattern: predicate[options.objects], + + ArrayExpression: predicate[options.arrays], + ArrayPattern: predicate[options.arrays], + + ImportDeclaration: predicate[options.imports], + + ExportNamedDeclaration: predicate[options.exports], + + FunctionDeclaration: predicate[options.functions], + FunctionExpression: predicate[options.functions], + ArrowFunctionExpression: predicate[options.functions], + CallExpression: predicate[options.functions], + NewExpression: predicate[options.functions] + }; + } +}; + +/** + * @fileoverview Comma spacing - validates spacing before and after comma + * @author Vignesh Anand aka vegetableman. + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var commaSpacing = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent spacing before and after commas", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/comma-spacing" + }, + + fixable: "whitespace", + + schema: [ + { + type: "object", + properties: { + before: { + type: "boolean", + default: false + }, + after: { + type: "boolean", + default: true + } + }, + additionalProperties: false + } + ], + + messages: { + missing: "A space is required {{loc}} ','.", + unexpected: "There should be no space {{loc}} ','." + } + }, + + create(context) { + + const sourceCode = context.getSourceCode(); + const tokensAndComments = sourceCode.tokensAndComments; + + const options = { + before: context.options[0] ? context.options[0].before : false, + after: context.options[0] ? context.options[0].after : true + }; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + // list of comma tokens to ignore for the check of leading whitespace + const commaTokensToIgnore = []; + + /** + * Reports a spacing error with an appropriate message. + * @param {ASTNode} node The binary expression node to report. + * @param {string} loc Is the error "before" or "after" the comma? + * @param {ASTNode} otherNode The node at the left or right of `node` + * @returns {void} + * @private + */ + function report(node, loc, otherNode) { + context.report({ + node, + fix(fixer) { + if (options[loc]) { + if (loc === "before") { + return fixer.insertTextBefore(node, " "); + } + return fixer.insertTextAfter(node, " "); + + } + let start, end; + const newText = ""; + + if (loc === "before") { + start = otherNode.range[1]; + end = node.range[0]; + } else { + start = node.range[1]; + end = otherNode.range[0]; + } + + return fixer.replaceTextRange([start, end], newText); + + }, + messageId: options[loc] ? "missing" : "unexpected", + data: { + loc + } + }); + } + + /** + * Validates the spacing around a comma token. + * @param {Object} tokens The tokens to be validated. + * @param {Token} tokens.comma The token representing the comma. + * @param {Token} [tokens.left] The last token before the comma. + * @param {Token} [tokens.right] The first token after the comma. + * @param {Token|ASTNode} reportItem The item to use when reporting an error. + * @returns {void} + * @private + */ + function validateCommaItemSpacing(tokens, reportItem) { + if (tokens.left && astUtils.isTokenOnSameLine(tokens.left, tokens.comma) && + (options.before !== sourceCode.isSpaceBetweenTokens(tokens.left, tokens.comma)) + ) { + report(reportItem, "before", tokens.left); + } + + if (tokens.right && astUtils.isClosingParenToken(tokens.right)) { + return; + } + + if (tokens.right && !options.after && tokens.right.type === "Line") { + return; + } + + if (tokens.right && astUtils.isTokenOnSameLine(tokens.comma, tokens.right) && + (options.after !== sourceCode.isSpaceBetweenTokens(tokens.comma, tokens.right)) + ) { + report(reportItem, "after", tokens.right); + } + } + + /** + * Adds null elements of the given ArrayExpression or ArrayPattern node to the ignore list. + * @param {ASTNode} node An ArrayExpression or ArrayPattern node. + * @returns {void} + */ + function addNullElementsToIgnoreList(node) { + let previousToken = sourceCode.getFirstToken(node); + + node.elements.forEach(element => { + let token; + + if (element === null) { + token = sourceCode.getTokenAfter(previousToken); + + if (astUtils.isCommaToken(token)) { + commaTokensToIgnore.push(token); + } + } else { + token = sourceCode.getTokenAfter(element); + } + + previousToken = token; + }); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + "Program:exit"() { + tokensAndComments.forEach((token, i) => { + + if (!astUtils.isCommaToken(token)) { + return; + } + + if (token && token.type === "JSXText") { + return; + } + + const previousToken = tokensAndComments[i - 1]; + const nextToken = tokensAndComments[i + 1]; + + validateCommaItemSpacing({ + comma: token, + left: astUtils.isCommaToken(previousToken) || commaTokensToIgnore.indexOf(token) > -1 ? null : previousToken, + right: astUtils.isCommaToken(nextToken) ? null : nextToken + }, token); + }); + }, + ArrayExpression: addNullElementsToIgnoreList, + ArrayPattern: addNullElementsToIgnoreList + + }; + + } +}; + +/** + * @fileoverview Comma style - enforces comma styles of two types: last and first + * @author Vignesh Anand aka vegetableman + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var commaStyle = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent comma style", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/comma-style" + }, + + fixable: "code", + + schema: [ + { + enum: ["first", "last"] + }, + { + type: "object", + properties: { + exceptions: { + type: "object", + additionalProperties: { + type: "boolean" + } + } + }, + additionalProperties: false + } + ], + + messages: { + unexpectedLineBeforeAndAfterComma: "Bad line breaking before and after ','.", + expectedCommaFirst: "',' should be placed first.", + expectedCommaLast: "',' should be placed last." + } + }, + + create(context) { + const style = context.options[0] || "last", + sourceCode = context.getSourceCode(); + const exceptions = { + ArrayPattern: true, + ArrowFunctionExpression: true, + CallExpression: true, + FunctionDeclaration: true, + FunctionExpression: true, + ImportDeclaration: true, + ObjectPattern: true, + NewExpression: true + }; + + if (context.options.length === 2 && Object.prototype.hasOwnProperty.call(context.options[1], "exceptions")) { + const keys = Object.keys(context.options[1].exceptions); + + for (let i = 0; i < keys.length; i++) { + exceptions[keys[i]] = context.options[1].exceptions[keys[i]]; + } + } + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Modified text based on the style + * @param {string} styleType Style type + * @param {string} text Source code text + * @returns {string} modified text + * @private + */ + function getReplacedText(styleType, text) { + switch (styleType) { + case "between": + return `,${text.replace(astUtils.LINEBREAK_MATCHER, "")}`; + + case "first": + return `${text},`; + + case "last": + return `,${text}`; + + default: + return ""; + } + } + + /** + * Determines the fixer function for a given style. + * @param {string} styleType comma style + * @param {ASTNode} previousItemToken The token to check. + * @param {ASTNode} commaToken The token to check. + * @param {ASTNode} currentItemToken The token to check. + * @returns {Function} Fixer function + * @private + */ + function getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken) { + const text = + sourceCode.text.slice(previousItemToken.range[1], commaToken.range[0]) + + sourceCode.text.slice(commaToken.range[1], currentItemToken.range[0]); + const range = [previousItemToken.range[1], currentItemToken.range[0]]; + + return function(fixer) { + return fixer.replaceTextRange(range, getReplacedText(styleType, text)); + }; + } + + /** + * Validates the spacing around single items in lists. + * @param {Token} previousItemToken The last token from the previous item. + * @param {Token} commaToken The token representing the comma. + * @param {Token} currentItemToken The first token of the current item. + * @param {Token} reportItem The item to use when reporting an error. + * @returns {void} + * @private + */ + function validateCommaItemSpacing(previousItemToken, commaToken, currentItemToken, reportItem) { + + // if single line + if (astUtils.isTokenOnSameLine(commaToken, currentItemToken) && + astUtils.isTokenOnSameLine(previousItemToken, commaToken)) ; else if (!astUtils.isTokenOnSameLine(commaToken, currentItemToken) && + !astUtils.isTokenOnSameLine(previousItemToken, commaToken)) { + + const comment = sourceCode.getCommentsAfter(commaToken)[0]; + const styleType = comment && comment.type === "Block" && astUtils.isTokenOnSameLine(commaToken, comment) + ? style + : "between"; + + // lone comma + context.report({ + node: reportItem, + loc: commaToken.loc, + messageId: "unexpectedLineBeforeAndAfterComma", + fix: getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken) + }); + + } else if (style === "first" && !astUtils.isTokenOnSameLine(commaToken, currentItemToken)) { + + context.report({ + node: reportItem, + loc: commaToken.loc, + messageId: "expectedCommaFirst", + fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken) + }); + + } else if (style === "last" && astUtils.isTokenOnSameLine(commaToken, currentItemToken)) { + + context.report({ + node: reportItem, + loc: commaToken.loc, + messageId: "expectedCommaLast", + fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken) + }); + } + } + + /** + * Checks the comma placement with regards to a declaration/property/element + * @param {ASTNode} node The binary expression node to check + * @param {string} property The property of the node containing child nodes. + * @private + * @returns {void} + */ + function validateComma(node, property) { + const items = node[property], + arrayLiteral = (node.type === "ArrayExpression" || node.type === "ArrayPattern"); + + if (items.length > 1 || arrayLiteral) { + + // seed as opening [ + let previousItemToken = sourceCode.getFirstToken(node); + + items.forEach(item => { + const commaToken = item ? sourceCode.getTokenBefore(item) : previousItemToken, + currentItemToken = item ? sourceCode.getFirstToken(item) : sourceCode.getTokenAfter(commaToken), + reportItem = item || currentItemToken; + + /* + * This works by comparing three token locations: + * - previousItemToken is the last token of the previous item + * - commaToken is the location of the comma before the current item + * - currentItemToken is the first token of the current item + * + * These values get switched around if item is undefined. + * previousItemToken will refer to the last token not belonging + * to the current item, which could be a comma or an opening + * square bracket. currentItemToken could be a comma. + * + * All comparisons are done based on these tokens directly, so + * they are always valid regardless of an undefined item. + */ + if (astUtils.isCommaToken(commaToken)) { + validateCommaItemSpacing(previousItemToken, commaToken, + currentItemToken, reportItem); + } + + if (item) { + const tokenAfterItem = sourceCode.getTokenAfter(item, astUtils.isNotClosingParenToken); + + previousItemToken = tokenAfterItem + ? sourceCode.getTokenBefore(tokenAfterItem) + : sourceCode.ast.tokens[sourceCode.ast.tokens.length - 1]; + } + }); + + /* + * Special case for array literals that have empty last items, such + * as [ 1, 2, ]. These arrays only have two items show up in the + * AST, so we need to look at the token to verify that there's no + * dangling comma. + */ + if (arrayLiteral) { + + const lastToken = sourceCode.getLastToken(node), + nextToLastToken = sourceCode.getTokenBefore(lastToken); + + if (astUtils.isCommaToken(nextToLastToken)) { + validateCommaItemSpacing( + sourceCode.getTokenBefore(nextToLastToken), + nextToLastToken, + lastToken, + lastToken + ); + } + } + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + const nodes = {}; + + if (!exceptions.VariableDeclaration) { + nodes.VariableDeclaration = function(node) { + validateComma(node, "declarations"); + }; + } + if (!exceptions.ObjectExpression) { + nodes.ObjectExpression = function(node) { + validateComma(node, "properties"); + }; + } + if (!exceptions.ObjectPattern) { + nodes.ObjectPattern = function(node) { + validateComma(node, "properties"); + }; + } + if (!exceptions.ArrayExpression) { + nodes.ArrayExpression = function(node) { + validateComma(node, "elements"); + }; + } + if (!exceptions.ArrayPattern) { + nodes.ArrayPattern = function(node) { + validateComma(node, "elements"); + }; + } + if (!exceptions.FunctionDeclaration) { + nodes.FunctionDeclaration = function(node) { + validateComma(node, "params"); + }; + } + if (!exceptions.FunctionExpression) { + nodes.FunctionExpression = function(node) { + validateComma(node, "params"); + }; + } + if (!exceptions.ArrowFunctionExpression) { + nodes.ArrowFunctionExpression = function(node) { + validateComma(node, "params"); + }; + } + if (!exceptions.CallExpression) { + nodes.CallExpression = function(node) { + validateComma(node, "arguments"); + }; + } + if (!exceptions.ImportDeclaration) { + nodes.ImportDeclaration = function(node) { + validateComma(node, "specifiers"); + }; + } + if (!exceptions.NewExpression) { + nodes.NewExpression = function(node) { + validateComma(node, "arguments"); + }; + } + + return nodes; + } +}; + +/** + * @fileoverview Counts the cyclomatic complexity of each function of the script. See http://en.wikipedia.org/wiki/Cyclomatic_complexity. + * Counts the number of if, conditional, for, while, try, switch/case, + * @author Patrick Brosset + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var complexity = { + meta: { + type: "suggestion", + + docs: { + description: "enforce a maximum cyclomatic complexity allowed in a program", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/complexity" + }, + + schema: [ + { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + type: "object", + properties: { + maximum: { + type: "integer", + minimum: 0 + }, + max: { + type: "integer", + minimum: 0 + } + }, + additionalProperties: false + } + ] + } + ], + + messages: { + complex: "{{name}} has a complexity of {{complexity}}. Maximum allowed is {{max}}." + } + }, + + create(context) { + const option = context.options[0]; + let THRESHOLD = 20; + + if ( + typeof option === "object" && + (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max")) + ) { + THRESHOLD = option.maximum || option.max; + } else if (typeof option === "number") { + THRESHOLD = option; + } + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + // Using a stack to store complexity (handling nested functions) + const fns = []; + + /** + * When parsing a new function, store it in our function stack + * @returns {void} + * @private + */ + function startFunction() { + fns.push(1); + } + + /** + * Evaluate the node at the end of function + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function endFunction(node) { + const name = lodash__default['default'].upperFirst(astUtils.getFunctionNameWithKind(node)); + const complexity = fns.pop(); + + if (complexity > THRESHOLD) { + context.report({ + node, + messageId: "complex", + data: { name, complexity, max: THRESHOLD } + }); + } + } + + /** + * Increase the complexity of the function in context + * @returns {void} + * @private + */ + function increaseComplexity() { + if (fns.length) { + fns[fns.length - 1]++; + } + } + + /** + * Increase the switch complexity in context + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function increaseSwitchComplexity(node) { + + // Avoiding `default` + if (node.test) { + increaseComplexity(); + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + FunctionDeclaration: startFunction, + FunctionExpression: startFunction, + ArrowFunctionExpression: startFunction, + "FunctionDeclaration:exit": endFunction, + "FunctionExpression:exit": endFunction, + "ArrowFunctionExpression:exit": endFunction, + + CatchClause: increaseComplexity, + ConditionalExpression: increaseComplexity, + LogicalExpression: increaseComplexity, + ForStatement: increaseComplexity, + ForInStatement: increaseComplexity, + ForOfStatement: increaseComplexity, + IfStatement: increaseComplexity, + SwitchCase: increaseSwitchComplexity, + WhileStatement: increaseComplexity, + DoWhileStatement: increaseComplexity, + + AssignmentExpression(node) { + if (astUtils.isLogicalAssignmentOperator(node.operator)) { + increaseComplexity(); + } + } + }; + + } +}; + +/** + * @fileoverview Disallows or enforces spaces inside computed properties. + * @author Jamund Ferguson + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var computedPropertySpacing = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent spacing inside computed property brackets", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/computed-property-spacing" + }, + + fixable: "whitespace", + + schema: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + enforceForClassMembers: { + type: "boolean", + default: true + } + }, + additionalProperties: false + } + ], + + messages: { + unexpectedSpaceBefore: "There should be no space before '{{tokenValue}}'.", + unexpectedSpaceAfter: "There should be no space after '{{tokenValue}}'.", + + missingSpaceBefore: "A space is required before '{{tokenValue}}'.", + missingSpaceAfter: "A space is required after '{{tokenValue}}'." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const propertyNameMustBeSpaced = context.options[0] === "always"; // default is "never" + const enforceForClassMembers = !context.options[1] || context.options[1].enforceForClassMembers; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Reports that there shouldn't be a space after the first token + * @param {ASTNode} node The node to report in the event of an error. + * @param {Token} token The token to use for the report. + * @param {Token} tokenAfter The token after `token`. + * @returns {void} + */ + function reportNoBeginningSpace(node, token, tokenAfter) { + context.report({ + node, + loc: { start: token.loc.end, end: tokenAfter.loc.start }, + messageId: "unexpectedSpaceAfter", + data: { + tokenValue: token.value + }, + fix(fixer) { + return fixer.removeRange([token.range[1], tokenAfter.range[0]]); + } + }); + } + + /** + * Reports that there shouldn't be a space before the last token + * @param {ASTNode} node The node to report in the event of an error. + * @param {Token} token The token to use for the report. + * @param {Token} tokenBefore The token before `token`. + * @returns {void} + */ + function reportNoEndingSpace(node, token, tokenBefore) { + context.report({ + node, + loc: { start: tokenBefore.loc.end, end: token.loc.start }, + messageId: "unexpectedSpaceBefore", + data: { + tokenValue: token.value + }, + fix(fixer) { + return fixer.removeRange([tokenBefore.range[1], token.range[0]]); + } + }); + } + + /** + * Reports that there should be a space after the first token + * @param {ASTNode} node The node to report in the event of an error. + * @param {Token} token The token to use for the report. + * @returns {void} + */ + function reportRequiredBeginningSpace(node, token) { + context.report({ + node, + loc: token.loc, + messageId: "missingSpaceAfter", + data: { + tokenValue: token.value + }, + fix(fixer) { + return fixer.insertTextAfter(token, " "); + } + }); + } + + /** + * Reports that there should be a space before the last token + * @param {ASTNode} node The node to report in the event of an error. + * @param {Token} token The token to use for the report. + * @returns {void} + */ + function reportRequiredEndingSpace(node, token) { + context.report({ + node, + loc: token.loc, + messageId: "missingSpaceBefore", + data: { + tokenValue: token.value + }, + fix(fixer) { + return fixer.insertTextBefore(token, " "); + } + }); + } + + /** + * Returns a function that checks the spacing of a node on the property name + * that was passed in. + * @param {string} propertyName The property on the node to check for spacing + * @returns {Function} A function that will check spacing on a node + */ + function checkSpacing(propertyName) { + return function(node) { + if (!node.computed) { + return; + } + + const property = node[propertyName]; + + const before = sourceCode.getTokenBefore(property, astUtils.isOpeningBracketToken), + first = sourceCode.getTokenAfter(before, { includeComments: true }), + after = sourceCode.getTokenAfter(property, astUtils.isClosingBracketToken), + last = sourceCode.getTokenBefore(after, { includeComments: true }); + + if (astUtils.isTokenOnSameLine(before, first)) { + if (propertyNameMustBeSpaced) { + if (!sourceCode.isSpaceBetweenTokens(before, first) && astUtils.isTokenOnSameLine(before, first)) { + reportRequiredBeginningSpace(node, before); + } + } else { + if (sourceCode.isSpaceBetweenTokens(before, first)) { + reportNoBeginningSpace(node, before, first); + } + } + } + + if (astUtils.isTokenOnSameLine(last, after)) { + if (propertyNameMustBeSpaced) { + if (!sourceCode.isSpaceBetweenTokens(last, after) && astUtils.isTokenOnSameLine(last, after)) { + reportRequiredEndingSpace(node, after); + } + } else { + if (sourceCode.isSpaceBetweenTokens(last, after)) { + reportNoEndingSpace(node, after, last); + } + } + } + }; + } + + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + const listeners = { + Property: checkSpacing("key"), + MemberExpression: checkSpacing("property") + }; + + if (enforceForClassMembers) { + listeners.MethodDefinition = checkSpacing("key"); + } + + return listeners; + + } +}; + +/** + * @fileoverview Rule to flag consistent return values + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a given code path segment is unreachable. + * @param {CodePathSegment} segment A CodePathSegment to check. + * @returns {boolean} `true` if the segment is unreachable. + */ +function isUnreachable$1(segment) { + return !segment.reachable; +} + +/** + * Checks whether a given node is a `constructor` method in an ES6 class + * @param {ASTNode} node A node to check + * @returns {boolean} `true` if the node is a `constructor` method + */ +function isClassConstructor(node) { + return node.type === "FunctionExpression" && + node.parent && + node.parent.type === "MethodDefinition" && + node.parent.kind === "constructor"; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var consistentReturn = { + meta: { + type: "suggestion", + + docs: { + description: "require `return` statements to either always or never specify values", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/consistent-return" + }, + + schema: [{ + type: "object", + properties: { + treatUndefinedAsUnspecified: { + type: "boolean", + default: false + } + }, + additionalProperties: false + }], + + messages: { + missingReturn: "Expected to return a value at the end of {{name}}.", + missingReturnValue: "{{name}} expected a return value.", + unexpectedReturnValue: "{{name}} expected no return value." + } + }, + + create(context) { + const options = context.options[0] || {}; + const treatUndefinedAsUnspecified = options.treatUndefinedAsUnspecified === true; + let funcInfo = null; + + /** + * Checks whether of not the implicit returning is consistent if the last + * code path segment is reachable. + * @param {ASTNode} node A program/function node to check. + * @returns {void} + */ + function checkLastSegment(node) { + let loc, name; + + /* + * Skip if it expected no return value or unreachable. + * When unreachable, all paths are returned or thrown. + */ + if (!funcInfo.hasReturnValue || + funcInfo.codePath.currentSegments.every(isUnreachable$1) || + astUtils.isES5Constructor(node) || + isClassConstructor(node) + ) { + return; + } + + // Adjust a location and a message. + if (node.type === "Program") { + + // The head of program. + loc = { line: 1, column: 0 }; + name = "program"; + } else if (node.type === "ArrowFunctionExpression") { + + // `=>` token + loc = context.getSourceCode().getTokenBefore(node.body, astUtils.isArrowToken).loc.start; + } else if ( + node.parent.type === "MethodDefinition" || + (node.parent.type === "Property" && node.parent.method) + ) { + + // Method name. + loc = node.parent.key.loc.start; + } else { + + // Function name or `function` keyword. + loc = (node.id || node).loc.start; + } + + if (!name) { + name = astUtils.getFunctionNameWithKind(node); + } + + // Reports. + context.report({ + node, + loc, + messageId: "missingReturn", + data: { name } + }); + } + + return { + + // Initializes/Disposes state of each code path. + onCodePathStart(codePath, node) { + funcInfo = { + upper: funcInfo, + codePath, + hasReturn: false, + hasReturnValue: false, + messageId: "", + node + }; + }, + onCodePathEnd() { + funcInfo = funcInfo.upper; + }, + + // Reports a given return statement if it's inconsistent. + ReturnStatement(node) { + const argument = node.argument; + let hasReturnValue = Boolean(argument); + + if (treatUndefinedAsUnspecified && hasReturnValue) { + hasReturnValue = !astUtils.isSpecificId(argument, "undefined") && argument.operator !== "void"; + } + + if (!funcInfo.hasReturn) { + funcInfo.hasReturn = true; + funcInfo.hasReturnValue = hasReturnValue; + funcInfo.messageId = hasReturnValue ? "missingReturnValue" : "unexpectedReturnValue"; + funcInfo.data = { + name: funcInfo.node.type === "Program" + ? "Program" + : lodash__default['default'].upperFirst(astUtils.getFunctionNameWithKind(funcInfo.node)) + }; + } else if (funcInfo.hasReturnValue !== hasReturnValue) { + context.report({ + node, + messageId: funcInfo.messageId, + data: funcInfo.data + }); + } + }, + + // Reports a given program/function if the implicit returning is not consistent. + "Program:exit": checkLastSegment, + "FunctionDeclaration:exit": checkLastSegment, + "FunctionExpression:exit": checkLastSegment, + "ArrowFunctionExpression:exit": checkLastSegment + }; + } +}; + +/** + * @fileoverview Rule to enforce consistent naming of "this" context variables + * @author Raphael Pigulla + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var consistentThis = { + meta: { + type: "suggestion", + + docs: { + description: "enforce consistent naming when capturing the current execution context", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/consistent-this" + }, + + schema: { + type: "array", + items: { + type: "string", + minLength: 1 + }, + uniqueItems: true + }, + + messages: { + aliasNotAssignedToThis: "Designated alias '{{name}}' is not assigned to 'this'.", + unexpectedAlias: "Unexpected alias '{{name}}' for 'this'." + } + }, + + create(context) { + let aliases = []; + + if (context.options.length === 0) { + aliases.push("that"); + } else { + aliases = context.options; + } + + /** + * Reports that a variable declarator or assignment expression is assigning + * a non-'this' value to the specified alias. + * @param {ASTNode} node The assigning node. + * @param {string} name the name of the alias that was incorrectly used. + * @returns {void} + */ + function reportBadAssignment(node, name) { + context.report({ node, messageId: "aliasNotAssignedToThis", data: { name } }); + } + + /** + * Checks that an assignment to an identifier only assigns 'this' to the + * appropriate alias, and the alias is only assigned to 'this'. + * @param {ASTNode} node The assigning node. + * @param {Identifier} name The name of the variable assigned to. + * @param {Expression} value The value of the assignment. + * @returns {void} + */ + function checkAssignment(node, name, value) { + const isThis = value.type === "ThisExpression"; + + if (aliases.indexOf(name) !== -1) { + if (!isThis || node.operator && node.operator !== "=") { + reportBadAssignment(node, name); + } + } else if (isThis) { + context.report({ node, messageId: "unexpectedAlias", data: { name } }); + } + } + + /** + * Ensures that a variable declaration of the alias in a program or function + * is assigned to the correct value. + * @param {string} alias alias the check the assignment of. + * @param {Object} scope scope of the current code we are checking. + * @private + * @returns {void} + */ + function checkWasAssigned(alias, scope) { + const variable = scope.set.get(alias); + + if (!variable) { + return; + } + + if (variable.defs.some(def => def.node.type === "VariableDeclarator" && + def.node.init !== null)) { + return; + } + + /* + * The alias has been declared and not assigned: check it was + * assigned later in the same scope. + */ + if (!variable.references.some(reference => { + const write = reference.writeExpr; + + return ( + reference.from === scope && + write && write.type === "ThisExpression" && + write.parent.operator === "=" + ); + })) { + variable.defs.map(def => def.node).forEach(node => { + reportBadAssignment(node, alias); + }); + } + } + + /** + * Check each alias to ensure that is was assigned to the correct value. + * @returns {void} + */ + function ensureWasAssigned() { + const scope = context.getScope(); + + aliases.forEach(alias => { + checkWasAssigned(alias, scope); + }); + } + + return { + "Program:exit": ensureWasAssigned, + "FunctionExpression:exit": ensureWasAssigned, + "FunctionDeclaration:exit": ensureWasAssigned, + + VariableDeclarator(node) { + const id = node.id; + const isDestructuring = + id.type === "ArrayPattern" || id.type === "ObjectPattern"; + + if (node.init !== null && !isDestructuring) { + checkAssignment(node, id.name, node.init); + } + }, + + AssignmentExpression(node) { + if (node.left.type === "Identifier") { + checkAssignment(node, node.left.name, node.right); + } + } + }; + + } +}; + +/** + * @fileoverview A rule to verify `super()` callings in constructor. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether a given code path segment is reachable or not. + * @param {CodePathSegment} segment A code path segment to check. + * @returns {boolean} `true` if the segment is reachable. + */ +function isReachable$2(segment) { + return segment.reachable; +} + +/** + * Checks whether or not a given node is a constructor. + * @param {ASTNode} node A node to check. This node type is one of + * `Program`, `FunctionDeclaration`, `FunctionExpression`, and + * `ArrowFunctionExpression`. + * @returns {boolean} `true` if the node is a constructor. + */ +function isConstructorFunction$1(node) { + return ( + node.type === "FunctionExpression" && + node.parent.type === "MethodDefinition" && + node.parent.kind === "constructor" + ); +} + +/** + * Checks whether a given node can be a constructor or not. + * @param {ASTNode} node A node to check. + * @returns {boolean} `true` if the node can be a constructor. + */ +function isPossibleConstructor(node) { + if (!node) { + return false; + } + + switch (node.type) { + case "ClassExpression": + case "FunctionExpression": + case "ThisExpression": + case "MemberExpression": + case "CallExpression": + case "NewExpression": + case "ChainExpression": + case "YieldExpression": + case "TaggedTemplateExpression": + case "MetaProperty": + return true; + + case "Identifier": + return node.name !== "undefined"; + + case "AssignmentExpression": + if (["=", "&&="].includes(node.operator)) { + return isPossibleConstructor(node.right); + } + + if (["||=", "??="].includes(node.operator)) { + return ( + isPossibleConstructor(node.left) || + isPossibleConstructor(node.right) + ); + } + + /** + * All other assignment operators are mathematical assignment operators (arithmetic or bitwise). + * An assignment expression with a mathematical operator can either evaluate to a primitive value, + * or throw, depending on the operands. Thus, it cannot evaluate to a constructor function. + */ + return false; + + case "LogicalExpression": + + /* + * If the && operator short-circuits, the left side was falsy and therefore not a constructor, and if + * it doesn't short-circuit, it takes the value from the right side, so the right side must always be a + * possible constructor. A future improvement could verify that the left side could be truthy by + * excluding falsy literals. + */ + if (node.operator === "&&") { + return isPossibleConstructor(node.right); + } + + return ( + isPossibleConstructor(node.left) || + isPossibleConstructor(node.right) + ); + + case "ConditionalExpression": + return ( + isPossibleConstructor(node.alternate) || + isPossibleConstructor(node.consequent) + ); + + case "SequenceExpression": { + const lastExpression = node.expressions[node.expressions.length - 1]; + + return isPossibleConstructor(lastExpression); + } + + default: + return false; + } +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var constructorSuper = { + meta: { + type: "problem", + + docs: { + description: "require `super()` calls in constructors", + category: "ECMAScript 6", + recommended: true, + url: "https://eslint.org/docs/rules/constructor-super" + }, + + schema: [], + + messages: { + missingSome: "Lacked a call of 'super()' in some code paths.", + missingAll: "Expected to call 'super()'.", + + duplicate: "Unexpected duplicate 'super()'.", + badSuper: "Unexpected 'super()' because 'super' is not a constructor.", + unexpected: "Unexpected 'super()'." + } + }, + + create(context) { + + /* + * {{hasExtends: boolean, scope: Scope, codePath: CodePath}[]} + * Information for each constructor. + * - upper: Information of the upper constructor. + * - hasExtends: A flag which shows whether own class has a valid `extends` + * part. + * - scope: The scope of own class. + * - codePath: The code path object of the constructor. + */ + let funcInfo = null; + + /* + * {Map} + * Information for each code path segment. + * - calledInSomePaths: A flag of be called `super()` in some code paths. + * - calledInEveryPaths: A flag of be called `super()` in all code paths. + * - validNodes: + */ + let segInfoMap = Object.create(null); + + /** + * Gets the flag which shows `super()` is called in some paths. + * @param {CodePathSegment} segment A code path segment to get. + * @returns {boolean} The flag which shows `super()` is called in some paths + */ + function isCalledInSomePath(segment) { + return segment.reachable && segInfoMap[segment.id].calledInSomePaths; + } + + /** + * Gets the flag which shows `super()` is called in all paths. + * @param {CodePathSegment} segment A code path segment to get. + * @returns {boolean} The flag which shows `super()` is called in all paths. + */ + function isCalledInEveryPath(segment) { + + /* + * If specific segment is the looped segment of the current segment, + * skip the segment. + * If not skipped, this never becomes true after a loop. + */ + if (segment.nextSegments.length === 1 && + segment.nextSegments[0].isLoopedPrevSegment(segment) + ) { + return true; + } + return segment.reachable && segInfoMap[segment.id].calledInEveryPaths; + } + + return { + + /** + * Stacks a constructor information. + * @param {CodePath} codePath A code path which was started. + * @param {ASTNode} node The current node. + * @returns {void} + */ + onCodePathStart(codePath, node) { + if (isConstructorFunction$1(node)) { + + // Class > ClassBody > MethodDefinition > FunctionExpression + const classNode = node.parent.parent.parent; + const superClass = classNode.superClass; + + funcInfo = { + upper: funcInfo, + isConstructor: true, + hasExtends: Boolean(superClass), + superIsConstructor: isPossibleConstructor(superClass), + codePath + }; + } else { + funcInfo = { + upper: funcInfo, + isConstructor: false, + hasExtends: false, + superIsConstructor: false, + codePath + }; + } + }, + + /** + * Pops a constructor information. + * And reports if `super()` lacked. + * @param {CodePath} codePath A code path which was ended. + * @param {ASTNode} node The current node. + * @returns {void} + */ + onCodePathEnd(codePath, node) { + const hasExtends = funcInfo.hasExtends; + + // Pop. + funcInfo = funcInfo.upper; + + if (!hasExtends) { + return; + } + + // Reports if `super()` lacked. + const segments = codePath.returnedSegments; + const calledInEveryPaths = segments.every(isCalledInEveryPath); + const calledInSomePaths = segments.some(isCalledInSomePath); + + if (!calledInEveryPaths) { + context.report({ + messageId: calledInSomePaths + ? "missingSome" + : "missingAll", + node: node.parent + }); + } + }, + + /** + * Initialize information of a given code path segment. + * @param {CodePathSegment} segment A code path segment to initialize. + * @returns {void} + */ + onCodePathSegmentStart(segment) { + if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) { + return; + } + + // Initialize info. + const info = segInfoMap[segment.id] = { + calledInSomePaths: false, + calledInEveryPaths: false, + validNodes: [] + }; + + // When there are previous segments, aggregates these. + const prevSegments = segment.prevSegments; + + if (prevSegments.length > 0) { + info.calledInSomePaths = prevSegments.some(isCalledInSomePath); + info.calledInEveryPaths = prevSegments.every(isCalledInEveryPath); + } + }, + + /** + * Update information of the code path segment when a code path was + * looped. + * @param {CodePathSegment} fromSegment The code path segment of the + * end of a loop. + * @param {CodePathSegment} toSegment A code path segment of the head + * of a loop. + * @returns {void} + */ + onCodePathSegmentLoop(fromSegment, toSegment) { + if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) { + return; + } + + // Update information inside of the loop. + const isRealLoop = toSegment.prevSegments.length >= 2; + + funcInfo.codePath.traverseSegments( + { first: toSegment, last: fromSegment }, + segment => { + const info = segInfoMap[segment.id]; + const prevSegments = segment.prevSegments; + + // Updates flags. + info.calledInSomePaths = prevSegments.some(isCalledInSomePath); + info.calledInEveryPaths = prevSegments.every(isCalledInEveryPath); + + // If flags become true anew, reports the valid nodes. + if (info.calledInSomePaths || isRealLoop) { + const nodes = info.validNodes; + + info.validNodes = []; + + for (let i = 0; i < nodes.length; ++i) { + const node = nodes[i]; + + context.report({ + messageId: "duplicate", + node + }); + } + } + } + ); + }, + + /** + * Checks for a call of `super()`. + * @param {ASTNode} node A CallExpression node to check. + * @returns {void} + */ + "CallExpression:exit"(node) { + if (!(funcInfo && funcInfo.isConstructor)) { + return; + } + + // Skips except `super()`. + if (node.callee.type !== "Super") { + return; + } + + // Reports if needed. + if (funcInfo.hasExtends) { + const segments = funcInfo.codePath.currentSegments; + let duplicate = false; + let info = null; + + for (let i = 0; i < segments.length; ++i) { + const segment = segments[i]; + + if (segment.reachable) { + info = segInfoMap[segment.id]; + + duplicate = duplicate || info.calledInSomePaths; + info.calledInSomePaths = info.calledInEveryPaths = true; + } + } + + if (info) { + if (duplicate) { + context.report({ + messageId: "duplicate", + node + }); + } else if (!funcInfo.superIsConstructor) { + context.report({ + messageId: "badSuper", + node + }); + } else { + info.validNodes.push(node); + } + } + } else if (funcInfo.codePath.currentSegments.some(isReachable$2)) { + context.report({ + messageId: "unexpected", + node + }); + } + }, + + /** + * Set the mark to the returned path as `super()` was called. + * @param {ASTNode} node A ReturnStatement node to check. + * @returns {void} + */ + ReturnStatement(node) { + if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) { + return; + } + + // Skips if no argument. + if (!node.argument) { + return; + } + + // Returning argument is a substitute of 'super()'. + const segments = funcInfo.codePath.currentSegments; + + for (let i = 0; i < segments.length; ++i) { + const segment = segments[i]; + + if (segment.reachable) { + const info = segInfoMap[segment.id]; + + info.calledInSomePaths = info.calledInEveryPaths = true; + } + } + }, + + /** + * Resets state. + * @returns {void} + */ + "Program:exit"() { + segInfoMap = Object.create(null); + } + }; + } +}; + +/** + * @fileoverview Rule to flag statements without curly braces + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var curly = { + meta: { + type: "suggestion", + + docs: { + description: "enforce consistent brace style for all control statements", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/curly" + }, + + schema: { + anyOf: [ + { + type: "array", + items: [ + { + enum: ["all"] + } + ], + minItems: 0, + maxItems: 1 + }, + { + type: "array", + items: [ + { + enum: ["multi", "multi-line", "multi-or-nest"] + }, + { + enum: ["consistent"] + } + ], + minItems: 0, + maxItems: 2 + } + ] + }, + + fixable: "code", + + messages: { + missingCurlyAfter: "Expected { after '{{name}}'.", + missingCurlyAfterCondition: "Expected { after '{{name}}' condition.", + unexpectedCurlyAfter: "Unnecessary { after '{{name}}'.", + unexpectedCurlyAfterCondition: "Unnecessary { after '{{name}}' condition." + } + }, + + create(context) { + + const multiOnly = (context.options[0] === "multi"); + const multiLine = (context.options[0] === "multi-line"); + const multiOrNest = (context.options[0] === "multi-or-nest"); + const consistent = (context.options[1] === "consistent"); + + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Determines if a given node is a one-liner that's on the same line as it's preceding code. + * @param {ASTNode} node The node to check. + * @returns {boolean} True if the node is a one-liner that's on the same line as it's preceding code. + * @private + */ + function isCollapsedOneLiner(node) { + const before = sourceCode.getTokenBefore(node); + const last = sourceCode.getLastToken(node); + const lastExcludingSemicolon = astUtils.isSemicolonToken(last) ? sourceCode.getTokenBefore(last) : last; + + return before.loc.start.line === lastExcludingSemicolon.loc.end.line; + } + + /** + * Determines if a given node is a one-liner. + * @param {ASTNode} node The node to check. + * @returns {boolean} True if the node is a one-liner. + * @private + */ + function isOneLiner(node) { + if (node.type === "EmptyStatement") { + return true; + } + + const first = sourceCode.getFirstToken(node); + const last = sourceCode.getLastToken(node); + const lastExcludingSemicolon = astUtils.isSemicolonToken(last) ? sourceCode.getTokenBefore(last) : last; + + return first.loc.start.line === lastExcludingSemicolon.loc.end.line; + } + + /** + * Determines if the given node is a lexical declaration (let, const, function, or class) + * @param {ASTNode} node The node to check + * @returns {boolean} True if the node is a lexical declaration + * @private + */ + function isLexicalDeclaration(node) { + if (node.type === "VariableDeclaration") { + return node.kind === "const" || node.kind === "let"; + } + + return node.type === "FunctionDeclaration" || node.type === "ClassDeclaration"; + } + + /** + * Checks if the given token is an `else` token or not. + * @param {Token} token The token to check. + * @returns {boolean} `true` if the token is an `else` token. + */ + function isElseKeywordToken(token) { + return token.value === "else" && token.type === "Keyword"; + } + + /** + * Gets the `else` keyword token of a given `IfStatement` node. + * @param {ASTNode} node A `IfStatement` node to get. + * @returns {Token} The `else` keyword token. + */ + function getElseKeyword(node) { + return node.alternate && sourceCode.getFirstTokenBetween(node.consequent, node.alternate, isElseKeywordToken); + } + + /** + * Determines whether the given node has an `else` keyword token as the first token after. + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if the node is followed by an `else` keyword token. + */ + function isFollowedByElseKeyword(node) { + const nextToken = sourceCode.getTokenAfter(node); + + return Boolean(nextToken) && isElseKeywordToken(nextToken); + } + + /** + * Determines if a semicolon needs to be inserted after removing a set of curly brackets, in order to avoid a SyntaxError. + * @param {Token} closingBracket The } token + * @returns {boolean} `true` if a semicolon needs to be inserted after the last statement in the block. + */ + function needsSemicolon(closingBracket) { + const tokenBefore = sourceCode.getTokenBefore(closingBracket); + const tokenAfter = sourceCode.getTokenAfter(closingBracket); + const lastBlockNode = sourceCode.getNodeByRangeIndex(tokenBefore.range[0]); + + if (astUtils.isSemicolonToken(tokenBefore)) { + + // If the last statement already has a semicolon, don't add another one. + return false; + } + + if (!tokenAfter) { + + // If there are no statements after this block, there is no need to add a semicolon. + return false; + } + + if (lastBlockNode.type === "BlockStatement" && lastBlockNode.parent.type !== "FunctionExpression" && lastBlockNode.parent.type !== "ArrowFunctionExpression") { + + /* + * If the last node surrounded by curly brackets is a BlockStatement (other than a FunctionExpression or an ArrowFunctionExpression), + * don't insert a semicolon. Otherwise, the semicolon would be parsed as a separate statement, which would cause + * a SyntaxError if it was followed by `else`. + */ + return false; + } + + if (tokenBefore.loc.end.line === tokenAfter.loc.start.line) { + + // If the next token is on the same line, insert a semicolon. + return true; + } + + if (/^[([/`+-]/u.test(tokenAfter.value)) { + + // If the next token starts with a character that would disrupt ASI, insert a semicolon. + return true; + } + + if (tokenBefore.type === "Punctuator" && (tokenBefore.value === "++" || tokenBefore.value === "--")) { + + // If the last token is ++ or --, insert a semicolon to avoid disrupting ASI. + return true; + } + + // Otherwise, do not insert a semicolon. + return false; + } + + /** + * Determines whether the code represented by the given node contains an `if` statement + * that would become associated with an `else` keyword directly appended to that code. + * + * Examples where it returns `true`: + * + * if (a) + * foo(); + * + * if (a) { + * foo(); + * } + * + * if (a) + * foo(); + * else if (b) + * bar(); + * + * while (a) + * if (b) + * if(c) + * foo(); + * else + * bar(); + * + * Examples where it returns `false`: + * + * if (a) + * foo(); + * else + * bar(); + * + * while (a) { + * if (b) + * if(c) + * foo(); + * else + * bar(); + * } + * + * while (a) + * if (b) { + * if(c) + * foo(); + * } + * else + * bar(); + * @param {ASTNode} node Node representing the code to check. + * @returns {boolean} `true` if an `if` statement within the code would become associated with an `else` appended to that code. + */ + function hasUnsafeIf(node) { + switch (node.type) { + case "IfStatement": + if (!node.alternate) { + return true; + } + return hasUnsafeIf(node.alternate); + case "ForStatement": + case "ForInStatement": + case "ForOfStatement": + case "LabeledStatement": + case "WithStatement": + case "WhileStatement": + return hasUnsafeIf(node.body); + default: + return false; + } + } + + /** + * Determines whether the existing curly braces around the single statement are necessary to preserve the semantics of the code. + * The braces, which make the given block body, are necessary in either of the following situations: + * + * 1. The statement is a lexical declaration. + * 2. Without the braces, an `if` within the statement would become associated with an `else` after the closing brace: + * + * if (a) { + * if (b) + * foo(); + * } + * else + * bar(); + * + * if (a) + * while (b) + * while (c) { + * while (d) + * if (e) + * while(f) + * foo(); + * } + * else + * bar(); + * @param {ASTNode} node `BlockStatement` body with exactly one statement directly inside. The statement can have its own nested statements. + * @returns {boolean} `true` if the braces are necessary - removing them (replacing the given `BlockStatement` body with its single statement content) + * would change the semantics of the code or produce a syntax error. + */ + function areBracesNecessary(node) { + const statement = node.body[0]; + + return isLexicalDeclaration(statement) || + hasUnsafeIf(statement) && isFollowedByElseKeyword(node); + } + + /** + * Prepares to check the body of a node to see if it's a block statement. + * @param {ASTNode} node The node to report if there's a problem. + * @param {ASTNode} body The body node to check for blocks. + * @param {string} name The name to report if there's a problem. + * @param {{ condition: boolean }} opts Options to pass to the report functions + * @returns {Object} a prepared check object, with "actual", "expected", "check" properties. + * "actual" will be `true` or `false` whether the body is already a block statement. + * "expected" will be `true` or `false` if the body should be a block statement or not, or + * `null` if it doesn't matter, depending on the rule options. It can be modified to change + * the final behavior of "check". + * "check" will be a function reporting appropriate problems depending on the other + * properties. + */ + function prepareCheck(node, body, name, opts) { + const hasBlock = (body.type === "BlockStatement"); + let expected = null; + + if (hasBlock && (body.body.length !== 1 || areBracesNecessary(body))) { + expected = true; + } else if (multiOnly) { + expected = false; + } else if (multiLine) { + if (!isCollapsedOneLiner(body)) { + expected = true; + } + + // otherwise, the body is allowed to have braces or not to have braces + + } else if (multiOrNest) { + if (hasBlock) { + const statement = body.body[0]; + const leadingCommentsInBlock = sourceCode.getCommentsBefore(statement); + + expected = !isOneLiner(statement) || leadingCommentsInBlock.length > 0; + } else { + expected = !isOneLiner(body); + } + } else { + + // default "all" + expected = true; + } + + return { + actual: hasBlock, + expected, + check() { + if (this.expected !== null && this.expected !== this.actual) { + if (this.expected) { + context.report({ + node, + loc: (name !== "else" ? node : getElseKeyword(node)).loc.start, + messageId: opts && opts.condition ? "missingCurlyAfterCondition" : "missingCurlyAfter", + data: { + name + }, + fix: fixer => fixer.replaceText(body, `{${sourceCode.getText(body)}}`) + }); + } else { + context.report({ + node, + loc: (name !== "else" ? node : getElseKeyword(node)).loc.start, + messageId: opts && opts.condition ? "unexpectedCurlyAfterCondition" : "unexpectedCurlyAfter", + data: { + name + }, + fix(fixer) { + + /* + * `do while` expressions sometimes need a space to be inserted after `do`. + * e.g. `do{foo()} while (bar)` should be corrected to `do foo() while (bar)` + */ + const needsPrecedingSpace = node.type === "DoWhileStatement" && + sourceCode.getTokenBefore(body).range[1] === body.range[0] && + !astUtils.canTokensBeAdjacent("do", sourceCode.getFirstToken(body, { skip: 1 })); + + const openingBracket = sourceCode.getFirstToken(body); + const closingBracket = sourceCode.getLastToken(body); + const lastTokenInBlock = sourceCode.getTokenBefore(closingBracket); + + if (needsSemicolon(closingBracket)) { + + /* + * If removing braces would cause a SyntaxError due to multiple statements on the same line (or + * change the semantics of the code due to ASI), don't perform a fix. + */ + return null; + } + + const resultingBodyText = sourceCode.getText().slice(openingBracket.range[1], lastTokenInBlock.range[0]) + + sourceCode.getText(lastTokenInBlock) + + sourceCode.getText().slice(lastTokenInBlock.range[1], closingBracket.range[0]); + + return fixer.replaceText(body, (needsPrecedingSpace ? " " : "") + resultingBodyText); + } + }); + } + } + } + }; + } + + /** + * Prepares to check the bodies of a "if", "else if" and "else" chain. + * @param {ASTNode} node The first IfStatement node of the chain. + * @returns {Object[]} prepared checks for each body of the chain. See `prepareCheck` for more + * information. + */ + function prepareIfChecks(node) { + const preparedChecks = []; + + for (let currentNode = node; currentNode; currentNode = currentNode.alternate) { + preparedChecks.push(prepareCheck(currentNode, currentNode.consequent, "if", { condition: true })); + if (currentNode.alternate && currentNode.alternate.type !== "IfStatement") { + preparedChecks.push(prepareCheck(currentNode, currentNode.alternate, "else")); + break; + } + } + + if (consistent) { + + /* + * If any node should have or already have braces, make sure they + * all have braces. + * If all nodes shouldn't have braces, make sure they don't. + */ + const expected = preparedChecks.some(preparedCheck => { + if (preparedCheck.expected !== null) { + return preparedCheck.expected; + } + return preparedCheck.actual; + }); + + preparedChecks.forEach(preparedCheck => { + preparedCheck.expected = expected; + }); + } + + return preparedChecks; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + IfStatement(node) { + const parent = node.parent; + const isElseIf = parent.type === "IfStatement" && parent.alternate === node; + + if (!isElseIf) { + + // This is a top `if`, check the whole `if-else-if` chain + prepareIfChecks(node).forEach(preparedCheck => { + preparedCheck.check(); + }); + } + + // Skip `else if`, it's already checked (when the top `if` was visited) + }, + + WhileStatement(node) { + prepareCheck(node, node.body, "while", { condition: true }).check(); + }, + + DoWhileStatement(node) { + prepareCheck(node, node.body, "do").check(); + }, + + ForStatement(node) { + prepareCheck(node, node.body, "for", { condition: true }).check(); + }, + + ForInStatement(node) { + prepareCheck(node, node.body, "for-in").check(); + }, + + ForOfStatement(node) { + prepareCheck(node, node.body, "for-of").check(); + } + }; + } +}; + +/** + * @fileoverview require default case in switch statements + * @author Aliaksei Shytkin + */ + +const DEFAULT_COMMENT_PATTERN = /^no default$/iu; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var defaultCase = { + meta: { + type: "suggestion", + + docs: { + description: "require `default` cases in `switch` statements", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/default-case" + }, + + schema: [{ + type: "object", + properties: { + commentPattern: { + type: "string" + } + }, + additionalProperties: false + }], + + messages: { + missingDefaultCase: "Expected a default case." + } + }, + + create(context) { + const options = context.options[0] || {}; + const commentPattern = options.commentPattern + ? new RegExp(options.commentPattern, "u") + : DEFAULT_COMMENT_PATTERN; + + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Shortcut to get last element of array + * @param {*[]} collection Array + * @returns {*} Last element + */ + function last(collection) { + return collection[collection.length - 1]; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + SwitchStatement(node) { + + if (!node.cases.length) { + + /* + * skip check of empty switch because there is no easy way + * to extract comments inside it now + */ + return; + } + + const hasDefault = node.cases.some(v => v.test === null); + + if (!hasDefault) { + + let comment; + + const lastCase = last(node.cases); + const comments = sourceCode.getCommentsAfter(lastCase); + + if (comments.length) { + comment = last(comments); + } + + if (!comment || !commentPattern.test(comment.value.trim())) { + context.report({ node, messageId: "missingDefaultCase" }); + } + } + } + }; + } +}; + +/** + * @fileoverview Rule to enforce default clauses in switch statements to be last + * @author Milos Djermanovic + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var defaultCaseLast = { + meta: { + type: "suggestion", + + docs: { + description: "enforce default clauses in switch statements to be last", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/default-case-last" + }, + + schema: [], + + messages: { + notLast: "Default clause should be the last clause." + } + }, + + create(context) { + return { + SwitchStatement(node) { + const cases = node.cases, + indexOfDefault = cases.findIndex(c => c.test === null); + + if (indexOfDefault !== -1 && indexOfDefault !== cases.length - 1) { + const defaultClause = cases[indexOfDefault]; + + context.report({ node: defaultClause, messageId: "notLast" }); + } + } + }; + } +}; + +/** + * @fileoverview enforce default parameters to be last + * @author Chiawen Chen + */ + +var defaultParamLast = { + meta: { + type: "suggestion", + + docs: { + description: "enforce default parameters to be last", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/default-param-last" + }, + + schema: [], + + messages: { + shouldBeLast: "Default parameters should be last." + } + }, + + create(context) { + + // eslint-disable-next-line jsdoc/require-description + /** + * @param {ASTNode} node function node + * @returns {void} + */ + function handleFunction(node) { + let hasSeenPlainParam = false; + + for (let i = node.params.length - 1; i >= 0; i -= 1) { + const param = node.params[i]; + + if ( + param.type !== "AssignmentPattern" && + param.type !== "RestElement" + ) { + hasSeenPlainParam = true; + continue; + } + + if (hasSeenPlainParam && param.type === "AssignmentPattern") { + context.report({ + node: param, + messageId: "shouldBeLast" + }); + } + } + } + + return { + FunctionDeclaration: handleFunction, + FunctionExpression: handleFunction, + ArrowFunctionExpression: handleFunction + }; + } +}; + +/** + * @fileoverview Validates newlines before and after dots + * @author Greg Cochard + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var dotLocation = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent newlines before and after dots", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/dot-location" + }, + + schema: [ + { + enum: ["object", "property"] + } + ], + + fixable: "code", + + messages: { + expectedDotAfterObject: "Expected dot to be on same line as object.", + expectedDotBeforeProperty: "Expected dot to be on same line as property." + } + }, + + create(context) { + + const config = context.options[0]; + + // default to onObject if no preference is passed + const onObject = config === "object" || !config; + + const sourceCode = context.getSourceCode(); + + /** + * Reports if the dot between object and property is on the correct location. + * @param {ASTNode} node The `MemberExpression` node. + * @returns {void} + */ + function checkDotLocation(node) { + const property = node.property; + const dotToken = sourceCode.getTokenBefore(property); + + if (onObject) { + + // `obj` expression can be parenthesized, but those paren tokens are not a part of the `obj` node. + const tokenBeforeDot = sourceCode.getTokenBefore(dotToken); + + if (!astUtils.isTokenOnSameLine(tokenBeforeDot, dotToken)) { + context.report({ + node, + loc: dotToken.loc, + messageId: "expectedDotAfterObject", + *fix(fixer) { + if (dotToken.value.startsWith(".") && astUtils.isDecimalIntegerNumericToken(tokenBeforeDot)) { + yield fixer.insertTextAfter(tokenBeforeDot, ` ${dotToken.value}`); + } else { + yield fixer.insertTextAfter(tokenBeforeDot, dotToken.value); + } + yield fixer.remove(dotToken); + } + }); + } + } else if (!astUtils.isTokenOnSameLine(dotToken, property)) { + context.report({ + node, + loc: dotToken.loc, + messageId: "expectedDotBeforeProperty", + *fix(fixer) { + yield fixer.remove(dotToken); + yield fixer.insertTextBefore(property, dotToken.value); + } + }); + } + } + + /** + * Checks the spacing of the dot within a member expression. + * @param {ASTNode} node The node to check. + * @returns {void} + */ + function checkNode(node) { + if (!node.computed) { + checkDotLocation(node); + } + } + + return { + MemberExpression: checkNode + }; + } +}; + +/** + * @fileoverview A shared list of ES3 keywords. + * @author Josh Perez + */ + +var keywords = [ + "abstract", + "boolean", + "break", + "byte", + "case", + "catch", + "char", + "class", + "const", + "continue", + "debugger", + "default", + "delete", + "do", + "double", + "else", + "enum", + "export", + "extends", + "false", + "final", + "finally", + "float", + "for", + "function", + "goto", + "if", + "implements", + "import", + "in", + "instanceof", + "int", + "interface", + "long", + "native", + "new", + "null", + "package", + "private", + "protected", + "public", + "return", + "short", + "static", + "super", + "switch", + "synchronized", + "this", + "throw", + "throws", + "transient", + "true", + "try", + "typeof", + "var", + "void", + "volatile", + "while", + "with" +]; + +/** + * @fileoverview Rule to warn about using dot notation instead of square bracket notation when possible. + * @author Josh Perez + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/u; + +// `null` literal must be handled separately. +const literalTypesToCheck = new Set(["string", "boolean"]); + +var dotNotation = { + meta: { + type: "suggestion", + + docs: { + description: "enforce dot notation whenever possible", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/dot-notation" + }, + + schema: [ + { + type: "object", + properties: { + allowKeywords: { + type: "boolean", + default: true + }, + allowPattern: { + type: "string", + default: "" + } + }, + additionalProperties: false + } + ], + + fixable: "code", + + messages: { + useDot: "[{{key}}] is better written in dot notation.", + useBrackets: ".{{key}} is a syntax error." + } + }, + + create(context) { + const options = context.options[0] || {}; + const allowKeywords = options.allowKeywords === void 0 || options.allowKeywords; + const sourceCode = context.getSourceCode(); + + let allowPattern; + + if (options.allowPattern) { + allowPattern = new RegExp(options.allowPattern, "u"); + } + + /** + * Check if the property is valid dot notation + * @param {ASTNode} node The dot notation node + * @param {string} value Value which is to be checked + * @returns {void} + */ + function checkComputedProperty(node, value) { + if ( + validIdentifier.test(value) && + (allowKeywords || keywords.indexOf(String(value)) === -1) && + !(allowPattern && allowPattern.test(value)) + ) { + const formattedValue = node.property.type === "Literal" ? JSON.stringify(value) : `\`${value}\``; + + context.report({ + node: node.property, + messageId: "useDot", + data: { + key: formattedValue + }, + *fix(fixer) { + const leftBracket = sourceCode.getTokenAfter(node.object, astUtils.isOpeningBracketToken); + const rightBracket = sourceCode.getLastToken(node); + const nextToken = sourceCode.getTokenAfter(node); + + // Don't perform any fixes if there are comments inside the brackets. + if (sourceCode.commentsExistBetween(leftBracket, rightBracket)) { + return; // eslint-disable-line eslint-plugin/fixer-return -- false positive + } + + // Replace the brackets by an identifier. + if (!node.optional) { + yield fixer.insertTextBefore( + leftBracket, + astUtils.isDecimalInteger(node.object) ? " ." : "." + ); + } + yield fixer.replaceTextRange( + [leftBracket.range[0], rightBracket.range[1]], + value + ); + + // Insert a space after the property if it will be connected to the next token. + if ( + nextToken && + rightBracket.range[1] === nextToken.range[0] && + !astUtils.canTokensBeAdjacent(String(value), nextToken) + ) { + yield fixer.insertTextAfter(node, " "); + } + } + }); + } + } + + return { + MemberExpression(node) { + if ( + node.computed && + node.property.type === "Literal" && + (literalTypesToCheck.has(typeof node.property.value) || astUtils.isNullLiteral(node.property)) + ) { + checkComputedProperty(node, node.property.value); + } + if ( + node.computed && + node.property.type === "TemplateLiteral" && + node.property.expressions.length === 0 + ) { + checkComputedProperty(node, node.property.quasis[0].value.cooked); + } + if ( + !allowKeywords && + !node.computed && + keywords.indexOf(String(node.property.name)) !== -1 + ) { + context.report({ + node: node.property, + messageId: "useBrackets", + data: { + key: node.property.name + }, + *fix(fixer) { + const dotToken = sourceCode.getTokenBefore(node.property); + + // A statement that starts with `let[` is parsed as a destructuring variable declaration, not a MemberExpression. + if (node.object.type === "Identifier" && node.object.name === "let" && !node.optional) { + return; // eslint-disable-line eslint-plugin/fixer-return -- false positive + } + + // Don't perform any fixes if there are comments between the dot and the property name. + if (sourceCode.commentsExistBetween(dotToken, node.property)) { + return; // eslint-disable-line eslint-plugin/fixer-return -- false positive + } + + // Replace the identifier to brackets. + if (!node.optional) { + yield fixer.remove(dotToken); + } + yield fixer.replaceText(node.property, `["${node.property.name}"]`); + } + }); + } + } + }; + } +}; + +/** + * @fileoverview Require or disallow newline at the end of files + * @author Nodeca Team + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var eolLast = { + meta: { + type: "layout", + + docs: { + description: "require or disallow newline at the end of files", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/eol-last" + }, + + fixable: "whitespace", + + schema: [ + { + enum: ["always", "never", "unix", "windows"] + } + ], + + messages: { + missing: "Newline required at end of file but not found.", + unexpected: "Newline not allowed at end of file." + } + }, + create(context) { + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + Program: function checkBadEOF(node) { + const sourceCode = context.getSourceCode(), + src = sourceCode.getText(), + location = { + column: lodash__default['default'].last(sourceCode.lines).length, + line: sourceCode.lines.length + }, + LF = "\n", + CRLF = `\r${LF}`, + endsWithNewline = src.endsWith(LF); + + /* + * Empty source is always valid: No content in file so we don't + * need to lint for a newline on the last line of content. + */ + if (!src.length) { + return; + } + + let mode = context.options[0] || "always", + appendCRLF = false; + + if (mode === "unix") { + + // `"unix"` should behave exactly as `"always"` + mode = "always"; + } + if (mode === "windows") { + + // `"windows"` should behave exactly as `"always"`, but append CRLF in the fixer for backwards compatibility + mode = "always"; + appendCRLF = true; + } + if (mode === "always" && !endsWithNewline) { + + // File is not newline-terminated, but should be + context.report({ + node, + loc: location, + messageId: "missing", + fix(fixer) { + return fixer.insertTextAfterRange([0, src.length], appendCRLF ? CRLF : LF); + } + }); + } else if (mode === "never" && endsWithNewline) { + + // File is newline-terminated, but shouldn't be + context.report({ + node, + loc: location, + messageId: "unexpected", + fix(fixer) { + const finalEOLs = /(?:\r?\n)+$/u, + match = finalEOLs.exec(sourceCode.text), + start = match.index, + end = sourceCode.text.length; + + return fixer.replaceTextRange([start, end], ""); + } + }); + } + } + }; + } +}; + +/** + * @fileoverview Rule to flag statements that use != and == instead of !== and === + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var eqeqeq = { + meta: { + type: "suggestion", + + docs: { + description: "require the use of `===` and `!==`", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/eqeqeq" + }, + + schema: { + anyOf: [ + { + type: "array", + items: [ + { + enum: ["always"] + }, + { + type: "object", + properties: { + null: { + enum: ["always", "never", "ignore"] + } + }, + additionalProperties: false + } + ], + additionalItems: false + }, + { + type: "array", + items: [ + { + enum: ["smart", "allow-null"] + } + ], + additionalItems: false + } + ] + }, + + fixable: "code", + + messages: { + unexpected: "Expected '{{expectedOperator}}' and instead saw '{{actualOperator}}'." + } + }, + + create(context) { + const config = context.options[0] || "always"; + const options = context.options[1] || {}; + const sourceCode = context.getSourceCode(); + + const nullOption = (config === "always") + ? options.null || "always" + : "ignore"; + const enforceRuleForNull = (nullOption === "always"); + const enforceInverseRuleForNull = (nullOption === "never"); + + /** + * Checks if an expression is a typeof expression + * @param {ASTNode} node The node to check + * @returns {boolean} if the node is a typeof expression + */ + function isTypeOf(node) { + return node.type === "UnaryExpression" && node.operator === "typeof"; + } + + /** + * Checks if either operand of a binary expression is a typeof operation + * @param {ASTNode} node The node to check + * @returns {boolean} if one of the operands is typeof + * @private + */ + function isTypeOfBinary(node) { + return isTypeOf(node.left) || isTypeOf(node.right); + } + + /** + * Checks if operands are literals of the same type (via typeof) + * @param {ASTNode} node The node to check + * @returns {boolean} if operands are of same type + * @private + */ + function areLiteralsAndSameType(node) { + return node.left.type === "Literal" && node.right.type === "Literal" && + typeof node.left.value === typeof node.right.value; + } + + /** + * Checks if one of the operands is a literal null + * @param {ASTNode} node The node to check + * @returns {boolean} if operands are null + * @private + */ + function isNullCheck(node) { + return astUtils.isNullLiteral(node.right) || astUtils.isNullLiteral(node.left); + } + + /** + * Reports a message for this rule. + * @param {ASTNode} node The binary expression node that was checked + * @param {string} expectedOperator The operator that was expected (either '==', '!=', '===', or '!==') + * @returns {void} + * @private + */ + function report(node, expectedOperator) { + const operatorToken = sourceCode.getFirstTokenBetween( + node.left, + node.right, + token => token.value === node.operator + ); + + context.report({ + node, + loc: operatorToken.loc, + messageId: "unexpected", + data: { expectedOperator, actualOperator: node.operator }, + fix(fixer) { + + // If the comparison is a `typeof` comparison or both sides are literals with the same type, then it's safe to fix. + if (isTypeOfBinary(node) || areLiteralsAndSameType(node)) { + return fixer.replaceText(operatorToken, expectedOperator); + } + return null; + } + }); + } + + return { + BinaryExpression(node) { + const isNull = isNullCheck(node); + + if (node.operator !== "==" && node.operator !== "!=") { + if (enforceInverseRuleForNull && isNull) { + report(node, node.operator.slice(0, -1)); + } + return; + } + + if (config === "smart" && (isTypeOfBinary(node) || + areLiteralsAndSameType(node) || isNull)) { + return; + } + + if (!enforceRuleForNull && isNull) { + return; + } + + report(node, `${node.operator}=`); + } + }; + + } +}; + +/** + * @fileoverview enforce "for" loop update clause moving the counter in the right direction.(for-direction) + * @author Aladdin-ADD + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var forDirection = { + meta: { + type: "problem", + + docs: { + description: "enforce \"for\" loop update clause moving the counter in the right direction.", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/for-direction" + }, + + fixable: null, + schema: [], + + messages: { + incorrectDirection: "The update clause in this loop moves the variable in the wrong direction." + } + }, + + create(context) { + + /** + * report an error. + * @param {ASTNode} node the node to report. + * @returns {void} + */ + function report(node) { + context.report({ + node, + messageId: "incorrectDirection" + }); + } + + /** + * check the right side of the assignment + * @param {ASTNode} update UpdateExpression to check + * @param {int} dir expected direction that could either be turned around or invalidated + * @returns {int} return dir, the negated dir or zero if it's not clear for identifiers + */ + function getRightDirection(update, dir) { + if (update.right.type === "UnaryExpression") { + if (update.right.operator === "-") { + return -dir; + } + } else if (update.right.type === "Identifier") { + return 0; + } + return dir; + } + + /** + * check UpdateExpression add/sub the counter + * @param {ASTNode} update UpdateExpression to check + * @param {string} counter variable name to check + * @returns {int} if add return 1, if sub return -1, if nochange, return 0 + */ + function getUpdateDirection(update, counter) { + if (update.argument.type === "Identifier" && update.argument.name === counter) { + if (update.operator === "++") { + return 1; + } + if (update.operator === "--") { + return -1; + } + } + return 0; + } + + /** + * check AssignmentExpression add/sub the counter + * @param {ASTNode} update AssignmentExpression to check + * @param {string} counter variable name to check + * @returns {int} if add return 1, if sub return -1, if nochange, return 0 + */ + function getAssignmentDirection(update, counter) { + if (update.left.name === counter) { + if (update.operator === "+=") { + return getRightDirection(update, 1); + } + if (update.operator === "-=") { + return getRightDirection(update, -1); + } + } + return 0; + } + return { + ForStatement(node) { + + if (node.test && node.test.type === "BinaryExpression" && node.test.left.type === "Identifier" && node.update) { + const counter = node.test.left.name; + const operator = node.test.operator; + const update = node.update; + + let wrongDirection; + + if (operator === "<" || operator === "<=") { + wrongDirection = -1; + } else if (operator === ">" || operator === ">=") { + wrongDirection = 1; + } else { + return; + } + + if (update.type === "UpdateExpression") { + if (getUpdateDirection(update, counter) === wrongDirection) { + report(node); + } + } else if (update.type === "AssignmentExpression" && getAssignmentDirection(update, counter) === wrongDirection) { + report(node); + } + } + } + }; + } +}; + +/** + * @fileoverview Rule to control spacing within function calls + * @author Matt DuVall + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var funcCallSpacing = { + meta: { + type: "layout", + + docs: { + description: "require or disallow spacing between function identifiers and their invocations", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/func-call-spacing" + }, + + fixable: "whitespace", + + schema: { + anyOf: [ + { + type: "array", + items: [ + { + enum: ["never"] + } + ], + minItems: 0, + maxItems: 1 + }, + { + type: "array", + items: [ + { + enum: ["always"] + }, + { + type: "object", + properties: { + allowNewlines: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + minItems: 0, + maxItems: 2 + } + ] + }, + + messages: { + unexpectedWhitespace: "Unexpected whitespace between function name and paren.", + unexpectedNewline: "Unexpected newline between function name and paren.", + missing: "Missing space between function name and paren." + } + }, + + create(context) { + + const never = context.options[0] !== "always"; + const allowNewlines = !never && context.options[1] && context.options[1].allowNewlines; + const sourceCode = context.getSourceCode(); + const text = sourceCode.getText(); + + /** + * Check if open space is present in a function name + * @param {ASTNode} node node to evaluate + * @param {Token} leftToken The last token of the callee. This may be the closing parenthesis that encloses the callee. + * @param {Token} rightToken Tha first token of the arguments. this is the opening parenthesis that encloses the arguments. + * @returns {void} + * @private + */ + function checkSpacing(node, leftToken, rightToken) { + const textBetweenTokens = text.slice(leftToken.range[1], rightToken.range[0]).replace(/\/\*.*?\*\//gu, ""); + const hasWhitespace = /\s/u.test(textBetweenTokens); + const hasNewline = hasWhitespace && astUtils.LINEBREAK_MATCHER.test(textBetweenTokens); + + /* + * never allowNewlines hasWhitespace hasNewline message + * F F F F Missing space between function name and paren. + * F F F T (Invalid `!hasWhitespace && hasNewline`) + * F F T T Unexpected newline between function name and paren. + * F F T F (OK) + * F T T F (OK) + * F T T T (OK) + * F T F T (Invalid `!hasWhitespace && hasNewline`) + * F T F F Missing space between function name and paren. + * T T F F (Invalid `never && allowNewlines`) + * T T F T (Invalid `!hasWhitespace && hasNewline`) + * T T T T (Invalid `never && allowNewlines`) + * T T T F (Invalid `never && allowNewlines`) + * T F T F Unexpected space between function name and paren. + * T F T T Unexpected space between function name and paren. + * T F F T (Invalid `!hasWhitespace && hasNewline`) + * T F F F (OK) + * + * T T Unexpected space between function name and paren. + * F F Missing space between function name and paren. + * F F T Unexpected newline between function name and paren. + */ + + if (never && hasWhitespace) { + context.report({ + node, + loc: { + start: leftToken.loc.end, + end: { + line: rightToken.loc.start.line, + column: rightToken.loc.start.column - 1 + } + }, + messageId: "unexpectedWhitespace", + fix(fixer) { + + // Don't remove comments. + if (sourceCode.commentsExistBetween(leftToken, rightToken)) { + return null; + } + + // If `?.` exists, it doesn't hide no-unexpected-multiline errors + if (node.optional) { + return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], "?."); + } + + /* + * Only autofix if there is no newline + * https://github.com/eslint/eslint/issues/7787 + */ + if (hasNewline) { + return null; + } + return fixer.removeRange([leftToken.range[1], rightToken.range[0]]); + } + }); + } else if (!never && !hasWhitespace) { + context.report({ + node, + loc: { + start: { + line: leftToken.loc.end.line, + column: leftToken.loc.end.column - 1 + }, + end: rightToken.loc.start + }, + messageId: "missing", + fix(fixer) { + if (node.optional) { + return null; // Not sure if inserting a space to either before/after `?.` token. + } + return fixer.insertTextBefore(rightToken, " "); + } + }); + } else if (!never && !allowNewlines && hasNewline) { + context.report({ + node, + loc: { + start: leftToken.loc.end, + end: rightToken.loc.start + }, + messageId: "unexpectedNewline", + fix(fixer) { + + /* + * Only autofix if there is no newline + * https://github.com/eslint/eslint/issues/7787 + * But if `?.` exists, it doesn't hide no-unexpected-multiline errors + */ + if (!node.optional) { + return null; + } + + // Don't remove comments. + if (sourceCode.commentsExistBetween(leftToken, rightToken)) { + return null; + } + + const range = [leftToken.range[1], rightToken.range[0]]; + const qdToken = sourceCode.getTokenAfter(leftToken); + + if (qdToken.range[0] === leftToken.range[1]) { + return fixer.replaceTextRange(range, "?. "); + } + if (qdToken.range[1] === rightToken.range[0]) { + return fixer.replaceTextRange(range, " ?."); + } + return fixer.replaceTextRange(range, " ?. "); + } + }); + } + } + + return { + "CallExpression, NewExpression"(node) { + const lastToken = sourceCode.getLastToken(node); + const lastCalleeToken = sourceCode.getLastToken(node.callee); + const parenToken = sourceCode.getFirstTokenBetween(lastCalleeToken, lastToken, astUtils.isOpeningParenToken); + const prevToken = parenToken && sourceCode.getTokenBefore(parenToken, astUtils.isNotQuestionDotToken); + + // Parens in NewExpression are optional + if (!(parenToken && parenToken.range[1] < node.range[1])) { + return; + } + + checkSpacing(node, prevToken, parenToken); + }, + + ImportExpression(node) { + const leftToken = sourceCode.getFirstToken(node); + const rightToken = sourceCode.getTokenAfter(leftToken); + + checkSpacing(node, leftToken, rightToken); + } + }; + + } +}; + +/** + * @fileoverview Rule to require function names to match the name of the variable or property to which they are assigned. + * @author Annie Zhang, Pavel Strashkin + */ + +//-------------------------------------------------------------------------- +// Requirements +//-------------------------------------------------------------------------- + + + + +//-------------------------------------------------------------------------- +// Helpers +//-------------------------------------------------------------------------- + +/** + * Determines if a pattern is `module.exports` or `module["exports"]` + * @param {ASTNode} pattern The left side of the AssignmentExpression + * @returns {boolean} True if the pattern is `module.exports` or `module["exports"]` + */ +function isModuleExports(pattern) { + if (pattern.type === "MemberExpression" && pattern.object.type === "Identifier" && pattern.object.name === "module") { + + // module.exports + if (pattern.property.type === "Identifier" && pattern.property.name === "exports") { + return true; + } + + // module["exports"] + if (pattern.property.type === "Literal" && pattern.property.value === "exports") { + return true; + } + } + return false; +} + +/** + * Determines if a string name is a valid identifier + * @param {string} name The string to be checked + * @param {int} ecmaVersion The ECMAScript version if specified in the parserOptions config + * @returns {boolean} True if the string is a valid identifier + */ +function isIdentifier(name, ecmaVersion) { + if (ecmaVersion >= 6) { + return esutils__default['default'].keyword.isIdentifierES6(name); + } + return esutils__default['default'].keyword.isIdentifierES5(name); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const alwaysOrNever = { enum: ["always", "never"] }; +const optionsObject = { + type: "object", + properties: { + considerPropertyDescriptor: { + type: "boolean" + }, + includeCommonJSModuleExports: { + type: "boolean" + } + }, + additionalProperties: false +}; + +var funcNameMatching = { + meta: { + type: "suggestion", + + docs: { + description: "require function names to match the name of the variable or property to which they are assigned", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/func-name-matching" + }, + + schema: { + anyOf: [{ + type: "array", + additionalItems: false, + items: [alwaysOrNever, optionsObject] + }, { + type: "array", + additionalItems: false, + items: [optionsObject] + }] + }, + + messages: { + matchProperty: "Function name `{{funcName}}` should match property name `{{name}}`.", + matchVariable: "Function name `{{funcName}}` should match variable name `{{name}}`.", + notMatchProperty: "Function name `{{funcName}}` should not match property name `{{name}}`.", + notMatchVariable: "Function name `{{funcName}}` should not match variable name `{{name}}`." + } + }, + + create(context) { + const options = (typeof context.options[0] === "object" ? context.options[0] : context.options[1]) || {}; + const nameMatches = typeof context.options[0] === "string" ? context.options[0] : "always"; + const considerPropertyDescriptor = options.considerPropertyDescriptor; + const includeModuleExports = options.includeCommonJSModuleExports; + const ecmaVersion = context.parserOptions && context.parserOptions.ecmaVersion ? context.parserOptions.ecmaVersion : 5; + + /** + * Check whether node is a certain CallExpression. + * @param {string} objName object name + * @param {string} funcName function name + * @param {ASTNode} node The node to check + * @returns {boolean} `true` if node matches CallExpression + */ + function isPropertyCall(objName, funcName, node) { + if (!node) { + return false; + } + return node.type === "CallExpression" && astUtils.isSpecificMemberAccess(node.callee, objName, funcName); + } + + /** + * Compares identifiers based on the nameMatches option + * @param {string} x the first identifier + * @param {string} y the second identifier + * @returns {boolean} whether the two identifiers should warn. + */ + function shouldWarn(x, y) { + return (nameMatches === "always" && x !== y) || (nameMatches === "never" && x === y); + } + + /** + * Reports + * @param {ASTNode} node The node to report + * @param {string} name The variable or property name + * @param {string} funcName The function name + * @param {boolean} isProp True if the reported node is a property assignment + * @returns {void} + */ + function report(node, name, funcName, isProp) { + let messageId; + + if (nameMatches === "always" && isProp) { + messageId = "matchProperty"; + } else if (nameMatches === "always") { + messageId = "matchVariable"; + } else if (isProp) { + messageId = "notMatchProperty"; + } else { + messageId = "notMatchVariable"; + } + context.report({ + node, + messageId, + data: { + name, + funcName + } + }); + } + + /** + * Determines whether a given node is a string literal + * @param {ASTNode} node The node to check + * @returns {boolean} `true` if the node is a string literal + */ + function isStringLiteral(node) { + return node.type === "Literal" && typeof node.value === "string"; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + VariableDeclarator(node) { + if (!node.init || node.init.type !== "FunctionExpression" || node.id.type !== "Identifier") { + return; + } + if (node.init.id && shouldWarn(node.id.name, node.init.id.name)) { + report(node, node.id.name, node.init.id.name, false); + } + }, + + AssignmentExpression(node) { + if ( + node.right.type !== "FunctionExpression" || + (node.left.computed && node.left.property.type !== "Literal") || + (!includeModuleExports && isModuleExports(node.left)) || + (node.left.type !== "Identifier" && node.left.type !== "MemberExpression") + ) { + return; + } + + const isProp = node.left.type === "MemberExpression"; + const name = isProp ? astUtils.getStaticPropertyName(node.left) : node.left.name; + + if (node.right.id && isIdentifier(name) && shouldWarn(name, node.right.id.name)) { + report(node, name, node.right.id.name, isProp); + } + }, + + Property(node) { + if (node.value.type !== "FunctionExpression" || !node.value.id || node.computed && !isStringLiteral(node.key)) { + return; + } + + if (node.key.type === "Identifier") { + const functionName = node.value.id.name; + let propertyName = node.key.name; + + if (considerPropertyDescriptor && propertyName === "value") { + if (isPropertyCall("Object", "defineProperty", node.parent.parent) || isPropertyCall("Reflect", "defineProperty", node.parent.parent)) { + const property = node.parent.parent.arguments[1]; + + if (isStringLiteral(property) && shouldWarn(property.value, functionName)) { + report(node, property.value, functionName, true); + } + } else if (isPropertyCall("Object", "defineProperties", node.parent.parent.parent.parent)) { + propertyName = node.parent.parent.key.name; + if (!node.parent.parent.computed && shouldWarn(propertyName, functionName)) { + report(node, propertyName, functionName, true); + } + } else if (isPropertyCall("Object", "create", node.parent.parent.parent.parent)) { + propertyName = node.parent.parent.key.name; + if (!node.parent.parent.computed && shouldWarn(propertyName, functionName)) { + report(node, propertyName, functionName, true); + } + } else if (shouldWarn(propertyName, functionName)) { + report(node, propertyName, functionName, true); + } + } else if (shouldWarn(propertyName, functionName)) { + report(node, propertyName, functionName, true); + } + return; + } + + if ( + isStringLiteral(node.key) && + isIdentifier(node.key.value, ecmaVersion) && + shouldWarn(node.key.value, node.value.id.name) + ) { + report(node, node.key.value, node.value.id.name, true); + } + } + }; + } +}; + +/** + * @fileoverview Rule to warn when a function expression does not have a name. + * @author Kyle T. Nunery + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +/** + * Checks whether or not a given variable is a function name. + * @param {eslint-scope.Variable} variable A variable to check. + * @returns {boolean} `true` if the variable is a function name. + */ +function isFunctionName$1(variable) { + return variable && variable.defs[0].type === "FunctionName"; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var funcNames = { + meta: { + type: "suggestion", + + docs: { + description: "require or disallow named `function` expressions", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/func-names" + }, + + schema: { + definitions: { + value: { + enum: [ + "always", + "as-needed", + "never" + ] + } + }, + items: [ + { + $ref: "#/definitions/value" + }, + { + type: "object", + properties: { + generators: { + $ref: "#/definitions/value" + } + }, + additionalProperties: false + } + ] + }, + + messages: { + unnamed: "Unexpected unnamed {{name}}.", + named: "Unexpected named {{name}}." + } + }, + + create(context) { + + const sourceCode = context.getSourceCode(); + + /** + * Returns the config option for the given node. + * @param {ASTNode} node A node to get the config for. + * @returns {string} The config option. + */ + function getConfigForNode(node) { + if ( + node.generator && + context.options.length > 1 && + context.options[1].generators + ) { + return context.options[1].generators; + } + + return context.options[0] || "always"; + } + + /** + * Determines whether the current FunctionExpression node is a get, set, or + * shorthand method in an object literal or a class. + * @param {ASTNode} node A node to check. + * @returns {boolean} True if the node is a get, set, or shorthand method. + */ + function isObjectOrClassMethod(node) { + const parent = node.parent; + + return (parent.type === "MethodDefinition" || ( + parent.type === "Property" && ( + parent.method || + parent.kind === "get" || + parent.kind === "set" + ) + )); + } + + /** + * Determines whether the current FunctionExpression node has a name that would be + * inferred from context in a conforming ES6 environment. + * @param {ASTNode} node A node to check. + * @returns {boolean} True if the node would have a name assigned automatically. + */ + function hasInferredName(node) { + const parent = node.parent; + + return isObjectOrClassMethod(node) || + (parent.type === "VariableDeclarator" && parent.id.type === "Identifier" && parent.init === node) || + (parent.type === "Property" && parent.value === node) || + (parent.type === "AssignmentExpression" && parent.left.type === "Identifier" && parent.right === node) || + (parent.type === "AssignmentPattern" && parent.left.type === "Identifier" && parent.right === node); + } + + /** + * Reports that an unnamed function should be named + * @param {ASTNode} node The node to report in the event of an error. + * @returns {void} + */ + function reportUnexpectedUnnamedFunction(node) { + context.report({ + node, + messageId: "unnamed", + loc: astUtils.getFunctionHeadLoc(node, sourceCode), + data: { name: astUtils.getFunctionNameWithKind(node) } + }); + } + + /** + * Reports that a named function should be unnamed + * @param {ASTNode} node The node to report in the event of an error. + * @returns {void} + */ + function reportUnexpectedNamedFunction(node) { + context.report({ + node, + messageId: "named", + loc: astUtils.getFunctionHeadLoc(node, sourceCode), + data: { name: astUtils.getFunctionNameWithKind(node) } + }); + } + + /** + * The listener for function nodes. + * @param {ASTNode} node function node + * @returns {void} + */ + function handleFunction(node) { + + // Skip recursive functions. + const nameVar = context.getDeclaredVariables(node)[0]; + + if (isFunctionName$1(nameVar) && nameVar.references.length > 0) { + return; + } + + const hasName = Boolean(node.id && node.id.name); + const config = getConfigForNode(node); + + if (config === "never") { + if (hasName && node.type !== "FunctionDeclaration") { + reportUnexpectedNamedFunction(node); + } + } else if (config === "as-needed") { + if (!hasName && !hasInferredName(node)) { + reportUnexpectedUnnamedFunction(node); + } + } else { + if (!hasName && !isObjectOrClassMethod(node)) { + reportUnexpectedUnnamedFunction(node); + } + } + } + + return { + "FunctionExpression:exit": handleFunction, + "ExportDefaultDeclaration > FunctionDeclaration": handleFunction + }; + } +}; + +/** + * @fileoverview Rule to enforce a particular function style + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var funcStyle = { + meta: { + type: "suggestion", + + docs: { + description: "enforce the consistent use of either `function` declarations or expressions", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/func-style" + }, + + schema: [ + { + enum: ["declaration", "expression"] + }, + { + type: "object", + properties: { + allowArrowFunctions: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + messages: { + expression: "Expected a function expression.", + declaration: "Expected a function declaration." + } + }, + + create(context) { + + const style = context.options[0], + allowArrowFunctions = context.options[1] && context.options[1].allowArrowFunctions, + enforceDeclarations = (style === "declaration"), + stack = []; + + const nodesToCheck = { + FunctionDeclaration(node) { + stack.push(false); + + if (!enforceDeclarations && node.parent.type !== "ExportDefaultDeclaration") { + context.report({ node, messageId: "expression" }); + } + }, + "FunctionDeclaration:exit"() { + stack.pop(); + }, + + FunctionExpression(node) { + stack.push(false); + + if (enforceDeclarations && node.parent.type === "VariableDeclarator") { + context.report({ node: node.parent, messageId: "declaration" }); + } + }, + "FunctionExpression:exit"() { + stack.pop(); + }, + + ThisExpression() { + if (stack.length > 0) { + stack[stack.length - 1] = true; + } + } + }; + + if (!allowArrowFunctions) { + nodesToCheck.ArrowFunctionExpression = function() { + stack.push(false); + }; + + nodesToCheck["ArrowFunctionExpression:exit"] = function(node) { + const hasThisExpr = stack.pop(); + + if (enforceDeclarations && !hasThisExpr && node.parent.type === "VariableDeclarator") { + context.report({ node: node.parent, messageId: "declaration" }); + } + }; + } + + return nodesToCheck; + + } +}; + +/** + * @fileoverview Rule to enforce line breaks between arguments of a function call + * @author Alexey Gonchar + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var functionCallArgumentNewline = { + meta: { + type: "layout", + + docs: { + description: "enforce line breaks between arguments of a function call", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/function-call-argument-newline" + }, + + fixable: "whitespace", + + schema: [ + { + enum: ["always", "never", "consistent"] + } + ], + + messages: { + unexpectedLineBreak: "There should be no line break here.", + missingLineBreak: "There should be a line break after this argument." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + const checkers = { + unexpected: { + messageId: "unexpectedLineBreak", + check: (prevToken, currentToken) => prevToken.loc.end.line !== currentToken.loc.start.line, + createFix: (token, tokenBefore) => fixer => + fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], " ") + }, + missing: { + messageId: "missingLineBreak", + check: (prevToken, currentToken) => prevToken.loc.end.line === currentToken.loc.start.line, + createFix: (token, tokenBefore) => fixer => + fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], "\n") + } + }; + + /** + * Check all arguments for line breaks in the CallExpression + * @param {CallExpression} node node to evaluate + * @param {{ messageId: string, check: Function }} checker selected checker + * @returns {void} + * @private + */ + function checkArguments(node, checker) { + for (let i = 1; i < node.arguments.length; i++) { + const prevArgToken = sourceCode.getLastToken(node.arguments[i - 1]); + const currentArgToken = sourceCode.getFirstToken(node.arguments[i]); + + if (checker.check(prevArgToken, currentArgToken)) { + const tokenBefore = sourceCode.getTokenBefore( + currentArgToken, + { includeComments: true } + ); + + const hasLineCommentBefore = tokenBefore.type === "Line"; + + context.report({ + node, + loc: { + start: tokenBefore.loc.end, + end: currentArgToken.loc.start + }, + messageId: checker.messageId, + fix: hasLineCommentBefore ? null : checker.createFix(currentArgToken, tokenBefore) + }); + } + } + } + + /** + * Check if open space is present in a function name + * @param {CallExpression} node node to evaluate + * @returns {void} + * @private + */ + function check(node) { + if (node.arguments.length < 2) { + return; + } + + const option = context.options[0] || "always"; + + if (option === "never") { + checkArguments(node, checkers.unexpected); + } else if (option === "always") { + checkArguments(node, checkers.missing); + } else if (option === "consistent") { + const firstArgToken = sourceCode.getLastToken(node.arguments[0]); + const secondArgToken = sourceCode.getFirstToken(node.arguments[1]); + + if (firstArgToken.loc.end.line === secondArgToken.loc.start.line) { + checkArguments(node, checkers.unexpected); + } else { + checkArguments(node, checkers.missing); + } + } + } + + return { + CallExpression: check, + NewExpression: check + }; + } +}; + +/** + * @fileoverview enforce consistent line breaks inside function parentheses + * @author Teddy Katz + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var functionParenNewline = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent line breaks inside function parentheses", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/function-paren-newline" + }, + + fixable: "whitespace", + + schema: [ + { + oneOf: [ + { + enum: ["always", "never", "consistent", "multiline", "multiline-arguments"] + }, + { + type: "object", + properties: { + minItems: { + type: "integer", + minimum: 0 + } + }, + additionalProperties: false + } + ] + } + ], + + messages: { + expectedBefore: "Expected newline before ')'.", + expectedAfter: "Expected newline after '('.", + expectedBetween: "Expected newline between arguments/params.", + unexpectedBefore: "Unexpected newline before ')'.", + unexpectedAfter: "Unexpected newline after '('." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const rawOption = context.options[0] || "multiline"; + const multilineOption = rawOption === "multiline"; + const multilineArgumentsOption = rawOption === "multiline-arguments"; + const consistentOption = rawOption === "consistent"; + let minItems; + + if (typeof rawOption === "object") { + minItems = rawOption.minItems; + } else if (rawOption === "always") { + minItems = 0; + } else if (rawOption === "never") { + minItems = Infinity; + } else { + minItems = null; + } + + //---------------------------------------------------------------------- + // Helpers + //---------------------------------------------------------------------- + + /** + * Determines whether there should be newlines inside function parens + * @param {ASTNode[]} elements The arguments or parameters in the list + * @param {boolean} hasLeftNewline `true` if the left paren has a newline in the current code. + * @returns {boolean} `true` if there should be newlines inside the function parens + */ + function shouldHaveNewlines(elements, hasLeftNewline) { + if (multilineArgumentsOption && elements.length === 1) { + return hasLeftNewline; + } + if (multilineOption || multilineArgumentsOption) { + return elements.some((element, index) => index !== elements.length - 1 && element.loc.end.line !== elements[index + 1].loc.start.line); + } + if (consistentOption) { + return hasLeftNewline; + } + return elements.length >= minItems; + } + + /** + * Validates parens + * @param {Object} parens An object with keys `leftParen` for the left paren token, and `rightParen` for the right paren token + * @param {ASTNode[]} elements The arguments or parameters in the list + * @returns {void} + */ + function validateParens(parens, elements) { + const leftParen = parens.leftParen; + const rightParen = parens.rightParen; + const tokenAfterLeftParen = sourceCode.getTokenAfter(leftParen); + const tokenBeforeRightParen = sourceCode.getTokenBefore(rightParen); + const hasLeftNewline = !astUtils.isTokenOnSameLine(leftParen, tokenAfterLeftParen); + const hasRightNewline = !astUtils.isTokenOnSameLine(tokenBeforeRightParen, rightParen); + const needsNewlines = shouldHaveNewlines(elements, hasLeftNewline); + + if (hasLeftNewline && !needsNewlines) { + context.report({ + node: leftParen, + messageId: "unexpectedAfter", + fix(fixer) { + return sourceCode.getText().slice(leftParen.range[1], tokenAfterLeftParen.range[0]).trim() + + // If there is a comment between the ( and the first element, don't do a fix. + ? null + : fixer.removeRange([leftParen.range[1], tokenAfterLeftParen.range[0]]); + } + }); + } else if (!hasLeftNewline && needsNewlines) { + context.report({ + node: leftParen, + messageId: "expectedAfter", + fix: fixer => fixer.insertTextAfter(leftParen, "\n") + }); + } + + if (hasRightNewline && !needsNewlines) { + context.report({ + node: rightParen, + messageId: "unexpectedBefore", + fix(fixer) { + return sourceCode.getText().slice(tokenBeforeRightParen.range[1], rightParen.range[0]).trim() + + // If there is a comment between the last element and the ), don't do a fix. + ? null + : fixer.removeRange([tokenBeforeRightParen.range[1], rightParen.range[0]]); + } + }); + } else if (!hasRightNewline && needsNewlines) { + context.report({ + node: rightParen, + messageId: "expectedBefore", + fix: fixer => fixer.insertTextBefore(rightParen, "\n") + }); + } + } + + /** + * Validates a list of arguments or parameters + * @param {Object} parens An object with keys `leftParen` for the left paren token, and `rightParen` for the right paren token + * @param {ASTNode[]} elements The arguments or parameters in the list + * @returns {void} + */ + function validateArguments(parens, elements) { + const leftParen = parens.leftParen; + const tokenAfterLeftParen = sourceCode.getTokenAfter(leftParen); + const hasLeftNewline = !astUtils.isTokenOnSameLine(leftParen, tokenAfterLeftParen); + const needsNewlines = shouldHaveNewlines(elements, hasLeftNewline); + + for (let i = 0; i <= elements.length - 2; i++) { + const currentElement = elements[i]; + const nextElement = elements[i + 1]; + const hasNewLine = currentElement.loc.end.line !== nextElement.loc.start.line; + + if (!hasNewLine && needsNewlines) { + context.report({ + node: currentElement, + messageId: "expectedBetween", + fix: fixer => fixer.insertTextBefore(nextElement, "\n") + }); + } + } + } + + /** + * Gets the left paren and right paren tokens of a node. + * @param {ASTNode} node The node with parens + * @returns {Object} An object with keys `leftParen` for the left paren token, and `rightParen` for the right paren token. + * Can also return `null` if an expression has no parens (e.g. a NewExpression with no arguments, or an ArrowFunctionExpression + * with a single parameter) + */ + function getParenTokens(node) { + switch (node.type) { + case "NewExpression": + if (!node.arguments.length && !( + astUtils.isOpeningParenToken(sourceCode.getLastToken(node, { skip: 1 })) && + astUtils.isClosingParenToken(sourceCode.getLastToken(node)) + )) { + + // If the NewExpression does not have parens (e.g. `new Foo`), return null. + return null; + } + + // falls through + + case "CallExpression": + return { + leftParen: sourceCode.getTokenAfter(node.callee, astUtils.isOpeningParenToken), + rightParen: sourceCode.getLastToken(node) + }; + + case "FunctionDeclaration": + case "FunctionExpression": { + const leftParen = sourceCode.getFirstToken(node, astUtils.isOpeningParenToken); + const rightParen = node.params.length + ? sourceCode.getTokenAfter(node.params[node.params.length - 1], astUtils.isClosingParenToken) + : sourceCode.getTokenAfter(leftParen); + + return { leftParen, rightParen }; + } + + case "ArrowFunctionExpression": { + const firstToken = sourceCode.getFirstToken(node, { skip: (node.async ? 1 : 0) }); + + if (!astUtils.isOpeningParenToken(firstToken)) { + + // If the ArrowFunctionExpression has a single param without parens, return null. + return null; + } + + return { + leftParen: firstToken, + rightParen: sourceCode.getTokenBefore(node.body, astUtils.isClosingParenToken) + }; + } + + case "ImportExpression": { + const leftParen = sourceCode.getFirstToken(node, 1); + const rightParen = sourceCode.getLastToken(node); + + return { leftParen, rightParen }; + } + + default: + throw new TypeError(`unexpected node with type ${node.type}`); + } + } + + //---------------------------------------------------------------------- + // Public + //---------------------------------------------------------------------- + + return { + [[ + "ArrowFunctionExpression", + "CallExpression", + "FunctionDeclaration", + "FunctionExpression", + "ImportExpression", + "NewExpression" + ]](node) { + const parens = getParenTokens(node); + let params; + + if (node.type === "ImportExpression") { + params = [node.source]; + } else if (astUtils.isFunction(node)) { + params = node.params; + } else { + params = node.arguments; + } + + if (parens) { + validateParens(parens, params); + + if (multilineArgumentsOption) { + validateArguments(parens, params); + } + } + } + }; + } +}; + +/** + * @fileoverview Rule to check the spacing around the * in generator functions. + * @author Jamund Ferguson + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const OVERRIDE_SCHEMA = { + oneOf: [ + { + enum: ["before", "after", "both", "neither"] + }, + { + type: "object", + properties: { + before: { type: "boolean" }, + after: { type: "boolean" } + }, + additionalProperties: false + } + ] +}; + +var generatorStarSpacing = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent spacing around `*` operators in generator functions", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/generator-star-spacing" + }, + + fixable: "whitespace", + + schema: [ + { + oneOf: [ + { + enum: ["before", "after", "both", "neither"] + }, + { + type: "object", + properties: { + before: { type: "boolean" }, + after: { type: "boolean" }, + named: OVERRIDE_SCHEMA, + anonymous: OVERRIDE_SCHEMA, + method: OVERRIDE_SCHEMA + }, + additionalProperties: false + } + ] + } + ], + + messages: { + missingBefore: "Missing space before *.", + missingAfter: "Missing space after *.", + unexpectedBefore: "Unexpected space before *.", + unexpectedAfter: "Unexpected space after *." + } + }, + + create(context) { + + const optionDefinitions = { + before: { before: true, after: false }, + after: { before: false, after: true }, + both: { before: true, after: true }, + neither: { before: false, after: false } + }; + + /** + * Returns resolved option definitions based on an option and defaults + * @param {any} option The option object or string value + * @param {Object} defaults The defaults to use if options are not present + * @returns {Object} the resolved object definition + */ + function optionToDefinition(option, defaults) { + if (!option) { + return defaults; + } + + return typeof option === "string" + ? optionDefinitions[option] + : Object.assign({}, defaults, option); + } + + const modes = (function(option) { + const defaults = optionToDefinition(option, optionDefinitions.before); + + return { + named: optionToDefinition(option.named, defaults), + anonymous: optionToDefinition(option.anonymous, defaults), + method: optionToDefinition(option.method, defaults) + }; + }(context.options[0] || {})); + + const sourceCode = context.getSourceCode(); + + /** + * Checks if the given token is a star token or not. + * @param {Token} token The token to check. + * @returns {boolean} `true` if the token is a star token. + */ + function isStarToken(token) { + return token.value === "*" && token.type === "Punctuator"; + } + + /** + * Gets the generator star token of the given function node. + * @param {ASTNode} node The function node to get. + * @returns {Token} Found star token. + */ + function getStarToken(node) { + return sourceCode.getFirstToken( + (node.parent.method || node.parent.type === "MethodDefinition") ? node.parent : node, + isStarToken + ); + } + + /** + * capitalize a given string. + * @param {string} str the given string. + * @returns {string} the capitalized string. + */ + function capitalize(str) { + return str[0].toUpperCase() + str.slice(1); + } + + /** + * Checks the spacing between two tokens before or after the star token. + * @param {string} kind Either "named", "anonymous", or "method" + * @param {string} side Either "before" or "after". + * @param {Token} leftToken `function` keyword token if side is "before", or + * star token if side is "after". + * @param {Token} rightToken Star token if side is "before", or identifier + * token if side is "after". + * @returns {void} + */ + function checkSpacing(kind, side, leftToken, rightToken) { + if (!!(rightToken.range[0] - leftToken.range[1]) !== modes[kind][side]) { + const after = leftToken.value === "*"; + const spaceRequired = modes[kind][side]; + const node = after ? leftToken : rightToken; + const messageId = `${spaceRequired ? "missing" : "unexpected"}${capitalize(side)}`; + + context.report({ + node, + messageId, + fix(fixer) { + if (spaceRequired) { + if (after) { + return fixer.insertTextAfter(node, " "); + } + return fixer.insertTextBefore(node, " "); + } + return fixer.removeRange([leftToken.range[1], rightToken.range[0]]); + } + }); + } + } + + /** + * Enforces the spacing around the star if node is a generator function. + * @param {ASTNode} node A function expression or declaration node. + * @returns {void} + */ + function checkFunction(node) { + if (!node.generator) { + return; + } + + const starToken = getStarToken(node); + const prevToken = sourceCode.getTokenBefore(starToken); + const nextToken = sourceCode.getTokenAfter(starToken); + + let kind = "named"; + + if (node.parent.type === "MethodDefinition" || (node.parent.type === "Property" && node.parent.method)) { + kind = "method"; + } else if (!node.id) { + kind = "anonymous"; + } + + // Only check before when preceded by `function`|`static` keyword + if (!(kind === "method" && starToken === sourceCode.getFirstToken(node.parent))) { + checkSpacing(kind, "before", prevToken, starToken); + } + + checkSpacing(kind, "after", starToken, nextToken); + } + + return { + FunctionDeclaration: checkFunction, + FunctionExpression: checkFunction + }; + + } +}; + +/** + * @fileoverview Enforces that a return statement is present in property getters. + * @author Aladdin-ADD(hh_2013@foxmail.com) + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ +const TARGET_NODE_TYPE$1 = /^(?:Arrow)?FunctionExpression$/u; + +/** + * Checks a given code path segment is reachable. + * @param {CodePathSegment} segment A segment to check. + * @returns {boolean} `true` if the segment is reachable. + */ +function isReachable$1(segment) { + return segment.reachable; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var getterReturn = { + meta: { + type: "problem", + + docs: { + description: "enforce `return` statements in getters", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/getter-return" + }, + + fixable: null, + + schema: [ + { + type: "object", + properties: { + allowImplicit: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + messages: { + expected: "Expected to return a value in {{name}}.", + expectedAlways: "Expected {{name}} to always return a value." + } + }, + + create(context) { + + const options = context.options[0] || { allowImplicit: false }; + const sourceCode = context.getSourceCode(); + + let funcInfo = { + upper: null, + codePath: null, + hasReturn: false, + shouldCheck: false, + node: null + }; + + /** + * Checks whether or not the last code path segment is reachable. + * Then reports this function if the segment is reachable. + * + * If the last code path segment is reachable, there are paths which are not + * returned or thrown. + * @param {ASTNode} node A node to check. + * @returns {void} + */ + function checkLastSegment(node) { + if (funcInfo.shouldCheck && + funcInfo.codePath.currentSegments.some(isReachable$1) + ) { + context.report({ + node, + loc: astUtils.getFunctionHeadLoc(node, sourceCode), + messageId: funcInfo.hasReturn ? "expectedAlways" : "expected", + data: { + name: astUtils.getFunctionNameWithKind(funcInfo.node) + } + }); + } + } + + /** + * Checks whether a node means a getter function. + * @param {ASTNode} node a node to check. + * @returns {boolean} if node means a getter, return true; else return false. + */ + function isGetter(node) { + const parent = node.parent; + + if (TARGET_NODE_TYPE$1.test(node.type) && node.body.type === "BlockStatement") { + if (parent.kind === "get") { + return true; + } + if (parent.type === "Property" && astUtils.getStaticPropertyName(parent) === "get" && parent.parent.type === "ObjectExpression") { + + // Object.defineProperty() + if (parent.parent.parent.type === "CallExpression" && + astUtils.getStaticPropertyName(parent.parent.parent.callee) === "defineProperty") { + return true; + } + + // Object.defineProperties() + if (parent.parent.parent.type === "Property" && + parent.parent.parent.parent.type === "ObjectExpression" && + parent.parent.parent.parent.parent.type === "CallExpression" && + astUtils.getStaticPropertyName(parent.parent.parent.parent.parent.callee) === "defineProperties") { + return true; + } + } + } + return false; + } + return { + + // Stacks this function's information. + onCodePathStart(codePath, node) { + funcInfo = { + upper: funcInfo, + codePath, + hasReturn: false, + shouldCheck: isGetter(node), + node + }; + }, + + // Pops this function's information. + onCodePathEnd() { + funcInfo = funcInfo.upper; + }, + + // Checks the return statement is valid. + ReturnStatement(node) { + if (funcInfo.shouldCheck) { + funcInfo.hasReturn = true; + + // if allowImplicit: false, should also check node.argument + if (!options.allowImplicit && !node.argument) { + context.report({ + node, + messageId: "expected", + data: { + name: astUtils.getFunctionNameWithKind(funcInfo.node) + } + }); + } + } + }, + + // Reports a given function if the last path is reachable. + "FunctionExpression:exit": checkLastSegment, + "ArrowFunctionExpression:exit": checkLastSegment + }; + } +}; + +/** + * @fileoverview Rule for disallowing require() outside of the top-level module context + * @author Jamund Ferguson + */ + +const ACCEPTABLE_PARENTS = [ + "AssignmentExpression", + "VariableDeclarator", + "MemberExpression", + "ExpressionStatement", + "CallExpression", + "ConditionalExpression", + "Program", + "VariableDeclaration", + "ChainExpression" +]; + +/** + * Finds the eslint-scope reference in the given scope. + * @param {Object} scope The scope to search. + * @param {ASTNode} node The identifier node. + * @returns {Reference|null} Returns the found reference or null if none were found. + */ +function findReference$1(scope, node) { + const references = scope.references.filter(reference => reference.identifier.range[0] === node.range[0] && + reference.identifier.range[1] === node.range[1]); + + /* istanbul ignore else: correctly returns null */ + if (references.length === 1) { + return references[0]; + } + return null; + +} + +/** + * Checks if the given identifier node is shadowed in the given scope. + * @param {Object} scope The current scope. + * @param {ASTNode} node The identifier node to check. + * @returns {boolean} Whether or not the name is shadowed. + */ +function isShadowed$2(scope, node) { + const reference = findReference$1(scope, node); + + return reference && reference.resolved && reference.resolved.defs.length > 0; +} + +var globalRequire = { + meta: { + deprecated: true, + + replacedBy: [], + + type: "suggestion", + + docs: { + description: "require `require()` calls to be placed at top-level module scope", + category: "Node.js and CommonJS", + recommended: false, + url: "https://eslint.org/docs/rules/global-require" + }, + + schema: [], + messages: { + unexpected: "Unexpected require()." + } + }, + + create(context) { + return { + CallExpression(node) { + const currentScope = context.getScope(); + + if (node.callee.name === "require" && !isShadowed$2(currentScope, node.callee)) { + const isGoodRequire = context.getAncestors().every(parent => ACCEPTABLE_PARENTS.indexOf(parent.type) > -1); + + if (!isGoodRequire) { + context.report({ node, messageId: "unexpected" }); + } + } + } + }; + } +}; + +/** + * @fileoverview Rule to require grouped accessor pairs in object literals and classes + * @author Milos Djermanovic + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Typedefs +//------------------------------------------------------------------------------ + +/** + * Property name if it can be computed statically, otherwise the list of the tokens of the key node. + * @typedef {string|Token[]} Key + */ + +/** + * Accessor nodes with the same key. + * @typedef {Object} AccessorData + * @property {Key} key Accessor's key + * @property {ASTNode[]} getters List of getter nodes. + * @property {ASTNode[]} setters List of setter nodes. + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not the given lists represent the equal tokens in the same order. + * Tokens are compared by their properties, not by instance. + * @param {Token[]} left First list of tokens. + * @param {Token[]} right Second list of tokens. + * @returns {boolean} `true` if the lists have same tokens. + */ +function areEqualTokenLists(left, right) { + if (left.length !== right.length) { + return false; + } + + for (let i = 0; i < left.length; i++) { + const leftToken = left[i], + rightToken = right[i]; + + if (leftToken.type !== rightToken.type || leftToken.value !== rightToken.value) { + return false; + } + } + + return true; +} + +/** + * Checks whether or not the given keys are equal. + * @param {Key} left First key. + * @param {Key} right Second key. + * @returns {boolean} `true` if the keys are equal. + */ +function areEqualKeys(left, right) { + if (typeof left === "string" && typeof right === "string") { + + // Statically computed names. + return left === right; + } + if (Array.isArray(left) && Array.isArray(right)) { + + // Token lists. + return areEqualTokenLists(left, right); + } + + return false; +} + +/** + * Checks whether or not a given node is of an accessor kind ('get' or 'set'). + * @param {ASTNode} node A node to check. + * @returns {boolean} `true` if the node is of an accessor kind. + */ +function isAccessorKind(node) { + return node.kind === "get" || node.kind === "set"; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var groupedAccessorPairs = { + meta: { + type: "suggestion", + + docs: { + description: "require grouped accessor pairs in object literals and classes", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/grouped-accessor-pairs" + }, + + schema: [ + { + enum: ["anyOrder", "getBeforeSet", "setBeforeGet"] + } + ], + + messages: { + notGrouped: "Accessor pair {{ formerName }} and {{ latterName }} should be grouped.", + invalidOrder: "Expected {{ latterName }} to be before {{ formerName }}." + } + }, + + create(context) { + const order = context.options[0] || "anyOrder"; + const sourceCode = context.getSourceCode(); + + /** + * Reports the given accessor pair. + * @param {string} messageId messageId to report. + * @param {ASTNode} formerNode getter/setter node that is defined before `latterNode`. + * @param {ASTNode} latterNode getter/setter node that is defined after `formerNode`. + * @returns {void} + * @private + */ + function report(messageId, formerNode, latterNode) { + context.report({ + node: latterNode, + messageId, + loc: astUtils.getFunctionHeadLoc(latterNode.value, sourceCode), + data: { + formerName: astUtils.getFunctionNameWithKind(formerNode.value), + latterName: astUtils.getFunctionNameWithKind(latterNode.value) + } + }); + } + + /** + * Creates a new `AccessorData` object for the given getter or setter node. + * @param {ASTNode} node A getter or setter node. + * @returns {AccessorData} New `AccessorData` object that contains the given node. + * @private + */ + function createAccessorData(node) { + const name = astUtils.getStaticPropertyName(node); + const key = (name !== null) ? name : sourceCode.getTokens(node.key); + + return { + key, + getters: node.kind === "get" ? [node] : [], + setters: node.kind === "set" ? [node] : [] + }; + } + + /** + * Merges the given `AccessorData` object into the given accessors list. + * @param {AccessorData[]} accessors The list to merge into. + * @param {AccessorData} accessorData The object to merge. + * @returns {AccessorData[]} The same instance with the merged object. + * @private + */ + function mergeAccessorData(accessors, accessorData) { + const equalKeyElement = accessors.find(a => areEqualKeys(a.key, accessorData.key)); + + if (equalKeyElement) { + equalKeyElement.getters.push(...accessorData.getters); + equalKeyElement.setters.push(...accessorData.setters); + } else { + accessors.push(accessorData); + } + + return accessors; + } + + /** + * Checks accessor pairs in the given list of nodes. + * @param {ASTNode[]} nodes The list to check. + * @param {Function} shouldCheck – Predicate that returns `true` if the node should be checked. + * @returns {void} + * @private + */ + function checkList(nodes, shouldCheck) { + const accessors = nodes + .filter(shouldCheck) + .filter(isAccessorKind) + .map(createAccessorData) + .reduce(mergeAccessorData, []); + + for (const { getters, setters } of accessors) { + + // Don't report accessor properties that have duplicate getters or setters. + if (getters.length === 1 && setters.length === 1) { + const [getter] = getters, + [setter] = setters, + getterIndex = nodes.indexOf(getter), + setterIndex = nodes.indexOf(setter), + formerNode = getterIndex < setterIndex ? getter : setter, + latterNode = getterIndex < setterIndex ? setter : getter; + + if (Math.abs(getterIndex - setterIndex) > 1) { + report("notGrouped", formerNode, latterNode); + } else if ( + (order === "getBeforeSet" && getterIndex > setterIndex) || + (order === "setBeforeGet" && getterIndex < setterIndex) + ) { + report("invalidOrder", formerNode, latterNode); + } + } + } + } + + return { + ObjectExpression(node) { + checkList(node.properties, n => n.type === "Property"); + }, + ClassBody(node) { + checkList(node.body, n => n.type === "MethodDefinition" && !n.static); + checkList(node.body, n => n.type === "MethodDefinition" && n.static); + } + }; + } +}; + +/** + * @fileoverview Rule to flag for-in loops without if statements inside + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var guardForIn = { + meta: { + type: "suggestion", + + docs: { + description: "require `for-in` loops to include an `if` statement", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/guard-for-in" + }, + + schema: [], + messages: { + wrap: "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype." + } + }, + + create(context) { + + return { + + ForInStatement(node) { + const body = node.body; + + // empty statement + if (body.type === "EmptyStatement") { + return; + } + + // if statement + if (body.type === "IfStatement") { + return; + } + + // empty block + if (body.type === "BlockStatement" && body.body.length === 0) { + return; + } + + // block with just if statement + if (body.type === "BlockStatement" && body.body.length === 1 && body.body[0].type === "IfStatement") { + return; + } + + // block that starts with if statement + if (body.type === "BlockStatement" && body.body.length >= 1 && body.body[0].type === "IfStatement") { + const i = body.body[0]; + + // ... whose consequent is a continue + if (i.consequent.type === "ContinueStatement") { + return; + } + + // ... whose consequent is a block that contains only a continue + if (i.consequent.type === "BlockStatement" && i.consequent.body.length === 1 && i.consequent.body[0].type === "ContinueStatement") { + return; + } + } + + context.report({ node, messageId: "wrap" }); + } + }; + + } +}; + +/** + * @fileoverview Ensure handling of errors when we know they exist. + * @author Jamund Ferguson + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var handleCallbackErr = { + meta: { + deprecated: true, + + replacedBy: [], + + type: "suggestion", + + docs: { + description: "require error handling in callbacks", + category: "Node.js and CommonJS", + recommended: false, + url: "https://eslint.org/docs/rules/handle-callback-err" + }, + + schema: [ + { + type: "string" + } + ], + messages: { + expected: "Expected error to be handled." + } + }, + + create(context) { + + const errorArgument = context.options[0] || "err"; + + /** + * Checks if the given argument should be interpreted as a regexp pattern. + * @param {string} stringToCheck The string which should be checked. + * @returns {boolean} Whether or not the string should be interpreted as a pattern. + */ + function isPattern(stringToCheck) { + const firstChar = stringToCheck[0]; + + return firstChar === "^"; + } + + /** + * Checks if the given name matches the configured error argument. + * @param {string} name The name which should be compared. + * @returns {boolean} Whether or not the given name matches the configured error variable name. + */ + function matchesConfiguredErrorName(name) { + if (isPattern(errorArgument)) { + const regexp = new RegExp(errorArgument, "u"); + + return regexp.test(name); + } + return name === errorArgument; + } + + /** + * Get the parameters of a given function scope. + * @param {Object} scope The function scope. + * @returns {Array} All parameters of the given scope. + */ + function getParameters(scope) { + return scope.variables.filter(variable => variable.defs[0] && variable.defs[0].type === "Parameter"); + } + + /** + * Check to see if we're handling the error object properly. + * @param {ASTNode} node The AST node to check. + * @returns {void} + */ + function checkForError(node) { + const scope = context.getScope(), + parameters = getParameters(scope), + firstParameter = parameters[0]; + + if (firstParameter && matchesConfiguredErrorName(firstParameter.name)) { + if (firstParameter.references.length === 0) { + context.report({ node, messageId: "expected" }); + } + } + } + + return { + FunctionDeclaration: checkForError, + FunctionExpression: checkForError, + ArrowFunctionExpression: checkForError + }; + + } +}; + +/** + * @fileoverview Rule that warns when identifier names that are + * specified in the configuration are used. + * @author Keith Cirkel (http://keithcirkel.co.uk) + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether the given node represents assignment target in a normal assignment or destructuring. + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if the node is assignment target. + */ +function isAssignmentTarget$1(node) { + const parent = node.parent; + + return ( + + // normal assignment + ( + parent.type === "AssignmentExpression" && + parent.left === node + ) || + + // destructuring + parent.type === "ArrayPattern" || + parent.type === "RestElement" || + ( + parent.type === "Property" && + parent.value === node && + parent.parent.type === "ObjectPattern" + ) || + ( + parent.type === "AssignmentPattern" && + parent.left === node + ) + ); +} + +/** + * Checks whether the given node represents an imported name that is renamed in the same import/export specifier. + * + * Examples: + * import { a as b } from 'mod'; // node `a` is renamed import + * export { a as b } from 'mod'; // node `a` is renamed import + * @param {ASTNode} node `Identifier` node to check. + * @returns {boolean} `true` if the node is a renamed import. + */ +function isRenamedImport$1(node) { + const parent = node.parent; + + return ( + ( + parent.type === "ImportSpecifier" && + parent.imported !== parent.local && + parent.imported === node + ) || + ( + parent.type === "ExportSpecifier" && + parent.parent.source && // re-export + parent.local !== parent.exported && + parent.local === node + ) + ); +} + +/** + * Checks whether the given node is a renamed identifier node in an ObjectPattern destructuring. + * + * Examples: + * const { a : b } = foo; // node `a` is renamed node. + * @param {ASTNode} node `Identifier` node to check. + * @returns {boolean} `true` if the node is a renamed node in an ObjectPattern destructuring. + */ +function isRenamedInDestructuring$1(node) { + const parent = node.parent; + + return ( + ( + !parent.computed && + parent.type === "Property" && + parent.parent.type === "ObjectPattern" && + parent.value !== node && + parent.key === node + ) + ); +} + +/** + * Checks whether the given node represents shorthand definition of a property in an object literal. + * @param {ASTNode} node `Identifier` node to check. + * @returns {boolean} `true` if the node is a shorthand property definition. + */ +function isShorthandPropertyDefinition$1(node) { + const parent = node.parent; + + return ( + parent.type === "Property" && + parent.parent.type === "ObjectExpression" && + parent.shorthand + ); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var idBlacklist = { + meta: { + deprecated: true, + replacedBy: ["id-denylist"], + + type: "suggestion", + + docs: { + description: "disallow specified identifiers", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/id-blacklist" + }, + + schema: { + type: "array", + items: { + type: "string" + }, + uniqueItems: true + }, + messages: { + restricted: "Identifier '{{name}}' is restricted." + } + }, + + create(context) { + + const denyList = new Set(context.options); + const reportedNodes = new Set(); + + let globalScope; + + /** + * Checks whether the given name is restricted. + * @param {string} name The name to check. + * @returns {boolean} `true` if the name is restricted. + * @private + */ + function isRestricted(name) { + return denyList.has(name); + } + + /** + * Checks whether the given node represents a reference to a global variable that is not declared in the source code. + * These identifiers will be allowed, as it is assumed that user has no control over the names of external global variables. + * @param {ASTNode} node `Identifier` node to check. + * @returns {boolean} `true` if the node is a reference to a global variable. + */ + function isReferenceToGlobalVariable(node) { + const variable = globalScope.set.get(node.name); + + return variable && variable.defs.length === 0 && + variable.references.some(ref => ref.identifier === node); + } + + /** + * Determines whether the given node should be checked. + * @param {ASTNode} node `Identifier` node. + * @returns {boolean} `true` if the node should be checked. + */ + function shouldCheck(node) { + const parent = node.parent; + + /* + * Member access has special rules for checking property names. + * Read access to a property with a restricted name is allowed, because it can be on an object that user has no control over. + * Write access isn't allowed, because it potentially creates a new property with a restricted name. + */ + if ( + parent.type === "MemberExpression" && + parent.property === node && + !parent.computed + ) { + return isAssignmentTarget$1(parent); + } + + return ( + parent.type !== "CallExpression" && + parent.type !== "NewExpression" && + !isRenamedImport$1(node) && + !isRenamedInDestructuring$1(node) && + !( + isReferenceToGlobalVariable(node) && + !isShorthandPropertyDefinition$1(node) + ) + ); + } + + /** + * Reports an AST node as a rule violation. + * @param {ASTNode} node The node to report. + * @returns {void} + * @private + */ + function report(node) { + if (!reportedNodes.has(node)) { + context.report({ + node, + messageId: "restricted", + data: { + name: node.name + } + }); + reportedNodes.add(node); + } + } + + return { + + Program() { + globalScope = context.getScope(); + }, + + Identifier(node) { + if (isRestricted(node.name) && shouldCheck(node)) { + report(node); + } + } + }; + } +}; + +/** + * @fileoverview Rule that warns when identifier names that are + * specified in the configuration are used. + * @author Keith Cirkel (http://keithcirkel.co.uk) + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether the given node represents assignment target in a normal assignment or destructuring. + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if the node is assignment target. + */ +function isAssignmentTarget(node) { + const parent = node.parent; + + return ( + + // normal assignment + ( + parent.type === "AssignmentExpression" && + parent.left === node + ) || + + // destructuring + parent.type === "ArrayPattern" || + parent.type === "RestElement" || + ( + parent.type === "Property" && + parent.value === node && + parent.parent.type === "ObjectPattern" + ) || + ( + parent.type === "AssignmentPattern" && + parent.left === node + ) + ); +} + +/** + * Checks whether the given node represents an imported name that is renamed in the same import/export specifier. + * + * Examples: + * import { a as b } from 'mod'; // node `a` is renamed import + * export { a as b } from 'mod'; // node `a` is renamed import + * @param {ASTNode} node `Identifier` node to check. + * @returns {boolean} `true` if the node is a renamed import. + */ +function isRenamedImport(node) { + const parent = node.parent; + + return ( + ( + parent.type === "ImportSpecifier" && + parent.imported !== parent.local && + parent.imported === node + ) || + ( + parent.type === "ExportSpecifier" && + parent.parent.source && // re-export + parent.local !== parent.exported && + parent.local === node + ) + ); +} + +/** + * Checks whether the given node is a renamed identifier node in an ObjectPattern destructuring. + * + * Examples: + * const { a : b } = foo; // node `a` is renamed node. + * @param {ASTNode} node `Identifier` node to check. + * @returns {boolean} `true` if the node is a renamed node in an ObjectPattern destructuring. + */ +function isRenamedInDestructuring(node) { + const parent = node.parent; + + return ( + ( + !parent.computed && + parent.type === "Property" && + parent.parent.type === "ObjectPattern" && + parent.value !== node && + parent.key === node + ) + ); +} + +/** + * Checks whether the given node represents shorthand definition of a property in an object literal. + * @param {ASTNode} node `Identifier` node to check. + * @returns {boolean} `true` if the node is a shorthand property definition. + */ +function isShorthandPropertyDefinition(node) { + const parent = node.parent; + + return ( + parent.type === "Property" && + parent.parent.type === "ObjectExpression" && + parent.shorthand + ); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var idDenylist = { + meta: { + type: "suggestion", + + docs: { + description: "disallow specified identifiers", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/id-denylist" + }, + + schema: { + type: "array", + items: { + type: "string" + }, + uniqueItems: true + }, + messages: { + restricted: "Identifier '{{name}}' is restricted." + } + }, + + create(context) { + + const denyList = new Set(context.options); + const reportedNodes = new Set(); + + let globalScope; + + /** + * Checks whether the given name is restricted. + * @param {string} name The name to check. + * @returns {boolean} `true` if the name is restricted. + * @private + */ + function isRestricted(name) { + return denyList.has(name); + } + + /** + * Checks whether the given node represents a reference to a global variable that is not declared in the source code. + * These identifiers will be allowed, as it is assumed that user has no control over the names of external global variables. + * @param {ASTNode} node `Identifier` node to check. + * @returns {boolean} `true` if the node is a reference to a global variable. + */ + function isReferenceToGlobalVariable(node) { + const variable = globalScope.set.get(node.name); + + return variable && variable.defs.length === 0 && + variable.references.some(ref => ref.identifier === node); + } + + /** + * Determines whether the given node should be checked. + * @param {ASTNode} node `Identifier` node. + * @returns {boolean} `true` if the node should be checked. + */ + function shouldCheck(node) { + const parent = node.parent; + + /* + * Member access has special rules for checking property names. + * Read access to a property with a restricted name is allowed, because it can be on an object that user has no control over. + * Write access isn't allowed, because it potentially creates a new property with a restricted name. + */ + if ( + parent.type === "MemberExpression" && + parent.property === node && + !parent.computed + ) { + return isAssignmentTarget(parent); + } + + return ( + parent.type !== "CallExpression" && + parent.type !== "NewExpression" && + !isRenamedImport(node) && + !isRenamedInDestructuring(node) && + !( + isReferenceToGlobalVariable(node) && + !isShorthandPropertyDefinition(node) + ) + ); + } + + /** + * Reports an AST node as a rule violation. + * @param {ASTNode} node The node to report. + * @returns {void} + * @private + */ + function report(node) { + if (!reportedNodes.has(node)) { + context.report({ + node, + messageId: "restricted", + data: { + name: node.name + } + }); + reportedNodes.add(node); + } + } + + return { + + Program() { + globalScope = context.getScope(); + }, + + Identifier(node) { + if (isRestricted(node.name) && shouldCheck(node)) { + report(node); + } + } + }; + } +}; + +/** + * @fileoverview Rule that warns when identifier names are shorter or longer + * than the values provided in configuration. + * @author Burak Yigit Kaya aka BYK + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var idLength = { + meta: { + type: "suggestion", + + docs: { + description: "enforce minimum and maximum identifier lengths", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/id-length" + }, + + schema: [ + { + type: "object", + properties: { + min: { + type: "integer", + default: 2 + }, + max: { + type: "integer" + }, + exceptions: { + type: "array", + uniqueItems: true, + items: { + type: "string" + } + }, + exceptionPatterns: { + type: "array", + uniqueItems: true, + items: { + type: "string" + } + }, + properties: { + enum: ["always", "never"] + } + }, + additionalProperties: false + } + ], + messages: { + tooShort: "Identifier name '{{name}}' is too short (< {{min}}).", + tooLong: "Identifier name '{{name}}' is too long (> {{max}})." + } + }, + + create(context) { + const options = context.options[0] || {}; + const minLength = typeof options.min !== "undefined" ? options.min : 2; + const maxLength = typeof options.max !== "undefined" ? options.max : Infinity; + const properties = options.properties !== "never"; + const exceptions = new Set(options.exceptions); + const exceptionPatterns = (options.exceptionPatterns || []).map(pattern => new RegExp(pattern, "u")); + const reportedNode = new Set(); + + /** + * Checks if a string matches the provided exception patterns + * @param {string} name The string to check. + * @returns {boolean} if the string is a match + * @private + */ + function matchesExceptionPattern(name) { + return exceptionPatterns.some(pattern => pattern.test(name)); + } + + const SUPPORTED_EXPRESSIONS = { + MemberExpression: properties && function(parent) { + return !parent.computed && ( + + // regular property assignment + (parent.parent.left === parent && parent.parent.type === "AssignmentExpression" || + + // or the last identifier in an ObjectPattern destructuring + parent.parent.type === "Property" && parent.parent.value === parent && + parent.parent.parent.type === "ObjectPattern" && parent.parent.parent.parent.left === parent.parent.parent) + ); + }, + AssignmentPattern(parent, node) { + return parent.left === node; + }, + VariableDeclarator(parent, node) { + return parent.id === node; + }, + Property(parent, node) { + + if (parent.parent.type === "ObjectPattern") { + return ( + parent.value !== parent.key && parent.value === node || + parent.value === parent.key && parent.key === node && properties + ); + } + return properties && !parent.computed && parent.key === node; + }, + ImportDefaultSpecifier: true, + RestElement: true, + FunctionExpression: true, + ArrowFunctionExpression: true, + ClassDeclaration: true, + FunctionDeclaration: true, + MethodDefinition: true, + CatchClause: true, + ArrayPattern: true + }; + + return { + Identifier(node) { + const name = node.name; + const parent = node.parent; + + const isShort = name.length < minLength; + const isLong = name.length > maxLength; + + if (!(isShort || isLong) || exceptions.has(name) || matchesExceptionPattern(name)) { + return; // Nothing to report + } + + const isValidExpression = SUPPORTED_EXPRESSIONS[parent.type]; + + if (isValidExpression && !reportedNode.has(node) && (isValidExpression === true || isValidExpression(parent, node))) { + reportedNode.add(node); + context.report({ + node, + messageId: isShort ? "tooShort" : "tooLong", + data: { name, min: minLength, max: maxLength } + }); + } + } + }; + } +}; + +/** + * @fileoverview Rule to flag non-matching identifiers + * @author Matthieu Larcher + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var idMatch = { + meta: { + type: "suggestion", + + docs: { + description: "require identifiers to match a specified regular expression", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/id-match" + }, + + schema: [ + { + type: "string" + }, + { + type: "object", + properties: { + properties: { + type: "boolean", + default: false + }, + onlyDeclarations: { + type: "boolean", + default: false + }, + ignoreDestructuring: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + messages: { + notMatch: "Identifier '{{name}}' does not match the pattern '{{pattern}}'." + } + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Options + //-------------------------------------------------------------------------- + const pattern = context.options[0] || "^.+$", + regexp = new RegExp(pattern, "u"); + + const options = context.options[1] || {}, + properties = !!options.properties, + onlyDeclarations = !!options.onlyDeclarations, + ignoreDestructuring = !!options.ignoreDestructuring; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + // contains reported nodes to avoid reporting twice on destructuring with shorthand notation + const reported = new Map(); + const ALLOWED_PARENT_TYPES = new Set(["CallExpression", "NewExpression"]); + const DECLARATION_TYPES = new Set(["FunctionDeclaration", "VariableDeclarator"]); + const IMPORT_TYPES = new Set(["ImportSpecifier", "ImportNamespaceSpecifier", "ImportDefaultSpecifier"]); + + /** + * Checks if a string matches the provided pattern + * @param {string} name The string to check. + * @returns {boolean} if the string is a match + * @private + */ + function isInvalid(name) { + return !regexp.test(name); + } + + /** + * Checks if a parent of a node is an ObjectPattern. + * @param {ASTNode} node The node to check. + * @returns {boolean} if the node is inside an ObjectPattern + * @private + */ + function isInsideObjectPattern(node) { + let { parent } = node; + + while (parent) { + if (parent.type === "ObjectPattern") { + return true; + } + + parent = parent.parent; + } + + return false; + } + + /** + * Verifies if we should report an error or not based on the effective + * parent node and the identifier name. + * @param {ASTNode} effectiveParent The effective parent node of the node to be reported + * @param {string} name The identifier name of the identifier node + * @returns {boolean} whether an error should be reported or not + */ + function shouldReport(effectiveParent, name) { + return (!onlyDeclarations || DECLARATION_TYPES.has(effectiveParent.type)) && + !ALLOWED_PARENT_TYPES.has(effectiveParent.type) && isInvalid(name); + } + + /** + * Reports an AST node as a rule violation. + * @param {ASTNode} node The node to report. + * @returns {void} + * @private + */ + function report(node) { + if (!reported.has(node)) { + context.report({ + node, + messageId: "notMatch", + data: { + name: node.name, + pattern + } + }); + reported.set(node, true); + } + } + + return { + + Identifier(node) { + const name = node.name, + parent = node.parent, + effectiveParent = (parent.type === "MemberExpression") ? parent.parent : parent; + + if (parent.type === "MemberExpression") { + + if (!properties) { + return; + } + + // Always check object names + if (parent.object.type === "Identifier" && + parent.object.name === name) { + if (isInvalid(name)) { + report(node); + } + + // Report AssignmentExpressions left side's assigned variable id + } else if (effectiveParent.type === "AssignmentExpression" && + effectiveParent.left.type === "MemberExpression" && + effectiveParent.left.property.name === node.name) { + if (isInvalid(name)) { + report(node); + } + + // Report AssignmentExpressions only if they are the left side of the assignment + } else if (effectiveParent.type === "AssignmentExpression" && effectiveParent.right.type !== "MemberExpression") { + if (isInvalid(name)) { + report(node); + } + } + + /* + * Properties have their own rules, and + * AssignmentPattern nodes can be treated like Properties: + * e.g.: const { no_camelcased = false } = bar; + */ + } else if (parent.type === "Property" || parent.type === "AssignmentPattern") { + + if (parent.parent && parent.parent.type === "ObjectPattern") { + if (parent.shorthand && parent.value.left && isInvalid(name)) { + + report(node); + } + + const assignmentKeyEqualsValue = parent.key.name === parent.value.name; + + // prevent checking righthand side of destructured object + if (!assignmentKeyEqualsValue && parent.key === node) { + return; + } + + const valueIsInvalid = parent.value.name && isInvalid(name); + + // ignore destructuring if the option is set, unless a new identifier is created + if (valueIsInvalid && !(assignmentKeyEqualsValue && ignoreDestructuring)) { + report(node); + } + } + + // never check properties or always ignore destructuring + if (!properties || (ignoreDestructuring && isInsideObjectPattern(node))) { + return; + } + + // don't check right hand side of AssignmentExpression to prevent duplicate warnings + if (parent.right !== node && shouldReport(effectiveParent, name)) { + report(node); + } + + // Check if it's an import specifier + } else if (IMPORT_TYPES.has(parent.type)) { + + // Report only if the local imported identifier is invalid + if (parent.local && parent.local.name === node.name && isInvalid(name)) { + report(node); + } + + // Report anything that is invalid that isn't a CallExpression + } else if (shouldReport(effectiveParent, name)) { + report(node); + } + } + + }; + + } +}; + +/** + * @fileoverview enforce the location of arrow function bodies + * @author Sharmila Jesupaul + */ + +const { isCommentToken, isNotOpeningParenToken } = astUtils; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ +var implicitArrowLinebreak = { + meta: { + type: "layout", + + docs: { + description: "enforce the location of arrow function bodies", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/implicit-arrow-linebreak" + }, + + fixable: "whitespace", + + schema: [ + { + enum: ["beside", "below"] + } + ], + messages: { + expected: "Expected a linebreak before this expression.", + unexpected: "Expected no linebreak before this expression." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const option = context.options[0] || "beside"; + + /** + * Validates the location of an arrow function body + * @param {ASTNode} node The arrow function body + * @returns {void} + */ + function validateExpression(node) { + if (node.body.type === "BlockStatement") { + return; + } + + const arrowToken = sourceCode.getTokenBefore(node.body, isNotOpeningParenToken); + const firstTokenOfBody = sourceCode.getTokenAfter(arrowToken); + + if (arrowToken.loc.end.line === firstTokenOfBody.loc.start.line && option === "below") { + context.report({ + node: firstTokenOfBody, + messageId: "expected", + fix: fixer => fixer.insertTextBefore(firstTokenOfBody, "\n") + }); + } else if (arrowToken.loc.end.line !== firstTokenOfBody.loc.start.line && option === "beside") { + context.report({ + node: firstTokenOfBody, + messageId: "unexpected", + fix(fixer) { + if (sourceCode.getFirstTokenBetween(arrowToken, firstTokenOfBody, { includeComments: true, filter: isCommentToken })) { + return null; + } + + return fixer.replaceTextRange([arrowToken.range[1], firstTokenOfBody.range[0]], " "); + } + }); + } + } + + //---------------------------------------------------------------------- + // Public + //---------------------------------------------------------------------- + return { + ArrowFunctionExpression: node => validateExpression(node) + }; + } +}; + +/** + * @fileoverview This rule sets a specific indentation style and width for your code + * + * @author Teddy Katz + * @author Vitaly Puzrin + * @author Gyandeep Singh + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const KNOWN_NODES = new Set([ + "AssignmentExpression", + "AssignmentPattern", + "ArrayExpression", + "ArrayPattern", + "ArrowFunctionExpression", + "AwaitExpression", + "BlockStatement", + "BinaryExpression", + "BreakStatement", + "CallExpression", + "CatchClause", + "ChainExpression", + "ClassBody", + "ClassDeclaration", + "ClassExpression", + "ConditionalExpression", + "ContinueStatement", + "DoWhileStatement", + "DebuggerStatement", + "EmptyStatement", + "ExperimentalRestProperty", + "ExperimentalSpreadProperty", + "ExpressionStatement", + "ForStatement", + "ForInStatement", + "ForOfStatement", + "FunctionDeclaration", + "FunctionExpression", + "Identifier", + "IfStatement", + "Literal", + "LabeledStatement", + "LogicalExpression", + "MemberExpression", + "MetaProperty", + "MethodDefinition", + "NewExpression", + "ObjectExpression", + "ObjectPattern", + "Program", + "Property", + "RestElement", + "ReturnStatement", + "SequenceExpression", + "SpreadElement", + "Super", + "SwitchCase", + "SwitchStatement", + "TaggedTemplateExpression", + "TemplateElement", + "TemplateLiteral", + "ThisExpression", + "ThrowStatement", + "TryStatement", + "UnaryExpression", + "UpdateExpression", + "VariableDeclaration", + "VariableDeclarator", + "WhileStatement", + "WithStatement", + "YieldExpression", + "JSXFragment", + "JSXOpeningFragment", + "JSXClosingFragment", + "JSXIdentifier", + "JSXNamespacedName", + "JSXMemberExpression", + "JSXEmptyExpression", + "JSXExpressionContainer", + "JSXElement", + "JSXClosingElement", + "JSXOpeningElement", + "JSXAttribute", + "JSXSpreadAttribute", + "JSXText", + "ExportDefaultDeclaration", + "ExportNamedDeclaration", + "ExportAllDeclaration", + "ExportSpecifier", + "ImportDeclaration", + "ImportSpecifier", + "ImportDefaultSpecifier", + "ImportNamespaceSpecifier", + "ImportExpression" +]); + +/* + * General rule strategy: + * 1. An OffsetStorage instance stores a map of desired offsets, where each token has a specified offset from another + * specified token or to the first column. + * 2. As the AST is traversed, modify the desired offsets of tokens accordingly. For example, when entering a + * BlockStatement, offset all of the tokens in the BlockStatement by 1 indent level from the opening curly + * brace of the BlockStatement. + * 3. After traversing the AST, calculate the expected indentation levels of every token according to the + * OffsetStorage container. + * 4. For each line, compare the expected indentation of the first token to the actual indentation in the file, + * and report the token if the two values are not equal. + */ + + +/** + * A mutable balanced binary search tree that stores (key, value) pairs. The keys are numeric, and must be unique. + * This is intended to be a generic wrapper around a balanced binary search tree library, so that the underlying implementation + * can easily be swapped out. + */ +class BinarySearchTree { + + /** + * Creates an empty tree + */ + constructor() { + this._rbTree = createTree__default['default'](); + } + + /** + * Inserts an entry into the tree. + * @param {number} key The entry's key + * @param {*} value The entry's value + * @returns {void} + */ + insert(key, value) { + const iterator = this._rbTree.find(key); + + if (iterator.valid) { + this._rbTree = iterator.update(value); + } else { + this._rbTree = this._rbTree.insert(key, value); + } + } + + /** + * Finds the entry with the largest key less than or equal to the provided key + * @param {number} key The provided key + * @returns {{key: number, value: *}|null} The found entry, or null if no such entry exists. + */ + findLe(key) { + const iterator = this._rbTree.le(key); + + return iterator && { key: iterator.key, value: iterator.value }; + } + + /** + * Deletes all of the keys in the interval [start, end) + * @param {number} start The start of the range + * @param {number} end The end of the range + * @returns {void} + */ + deleteRange(start, end) { + + // Exit without traversing the tree if the range has zero size. + if (start === end) { + return; + } + const iterator = this._rbTree.ge(start); + + while (iterator.valid && iterator.key < end) { + this._rbTree = this._rbTree.remove(iterator.key); + iterator.next(); + } + } +} + +/** + * A helper class to get token-based info related to indentation + */ +class TokenInfo { + + // eslint-disable-next-line jsdoc/require-description + /** + * @param {SourceCode} sourceCode A SourceCode object + */ + constructor(sourceCode) { + this.sourceCode = sourceCode; + this.firstTokensByLineNumber = sourceCode.tokensAndComments.reduce((map, token) => { + if (!map.has(token.loc.start.line)) { + map.set(token.loc.start.line, token); + } + if (!map.has(token.loc.end.line) && sourceCode.text.slice(token.range[1] - token.loc.end.column, token.range[1]).trim()) { + map.set(token.loc.end.line, token); + } + return map; + }, new Map()); + } + + /** + * Gets the first token on a given token's line + * @param {Token|ASTNode} token a node or token + * @returns {Token} The first token on the given line + */ + getFirstTokenOfLine(token) { + return this.firstTokensByLineNumber.get(token.loc.start.line); + } + + /** + * Determines whether a token is the first token in its line + * @param {Token} token The token + * @returns {boolean} `true` if the token is the first on its line + */ + isFirstTokenOfLine(token) { + return this.getFirstTokenOfLine(token) === token; + } + + /** + * Get the actual indent of a token + * @param {Token} token Token to examine. This should be the first token on its line. + * @returns {string} The indentation characters that precede the token + */ + getTokenIndent(token) { + return this.sourceCode.text.slice(token.range[0] - token.loc.start.column, token.range[0]); + } +} + +/** + * A class to store information on desired offsets of tokens from each other + */ +class OffsetStorage { + + // eslint-disable-next-line jsdoc/require-description + /** + * @param {TokenInfo} tokenInfo a TokenInfo instance + * @param {number} indentSize The desired size of each indentation level + * @param {string} indentType The indentation character + */ + constructor(tokenInfo, indentSize, indentType) { + this._tokenInfo = tokenInfo; + this._indentSize = indentSize; + this._indentType = indentType; + + this._tree = new BinarySearchTree(); + this._tree.insert(0, { offset: 0, from: null, force: false }); + + this._lockedFirstTokens = new WeakMap(); + this._desiredIndentCache = new WeakMap(); + this._ignoredTokens = new WeakSet(); + } + + _getOffsetDescriptor(token) { + return this._tree.findLe(token.range[0]).value; + } + + /** + * Sets the offset column of token B to match the offset column of token A. + * **WARNING**: This matches a *column*, even if baseToken is not the first token on its line. In + * most cases, `setDesiredOffset` should be used instead. + * @param {Token} baseToken The first token + * @param {Token} offsetToken The second token, whose offset should be matched to the first token + * @returns {void} + */ + matchOffsetOf(baseToken, offsetToken) { + + /* + * lockedFirstTokens is a map from a token whose indentation is controlled by the "first" option to + * the token that it depends on. For example, with the `ArrayExpression: first` option, the first + * token of each element in the array after the first will be mapped to the first token of the first + * element. The desired indentation of each of these tokens is computed based on the desired indentation + * of the "first" element, rather than through the normal offset mechanism. + */ + this._lockedFirstTokens.set(offsetToken, baseToken); + } + + /** + * Sets the desired offset of a token. + * + * This uses a line-based offset collapsing behavior to handle tokens on the same line. + * For example, consider the following two cases: + * + * ( + * [ + * bar + * ] + * ) + * + * ([ + * bar + * ]) + * + * Based on the first case, it's clear that the `bar` token needs to have an offset of 1 indent level (4 spaces) from + * the `[` token, and the `[` token has to have an offset of 1 indent level from the `(` token. Since the `(` token is + * the first on its line (with an indent of 0 spaces), the `bar` token needs to be offset by 2 indent levels (8 spaces) + * from the start of its line. + * + * However, in the second case `bar` should only be indented by 4 spaces. This is because the offset of 1 indent level + * between the `(` and the `[` tokens gets "collapsed" because the two tokens are on the same line. As a result, the + * `(` token is mapped to the `[` token with an offset of 0, and the rule correctly decides that `bar` should be indented + * by 1 indent level from the start of the line. + * + * This is useful because rule listeners can usually just call `setDesiredOffset` for all the tokens in the node, + * without needing to check which lines those tokens are on. + * + * Note that since collapsing only occurs when two tokens are on the same line, there are a few cases where non-intuitive + * behavior can occur. For example, consider the following cases: + * + * foo( + * ). + * bar( + * baz + * ) + * + * foo( + * ).bar( + * baz + * ) + * + * Based on the first example, it would seem that `bar` should be offset by 1 indent level from `foo`, and `baz` + * should be offset by 1 indent level from `bar`. However, this is not correct, because it would result in `baz` + * being indented by 2 indent levels in the second case (since `foo`, `bar`, and `baz` are all on separate lines, no + * collapsing would occur). + * + * Instead, the correct way would be to offset `baz` by 1 level from `bar`, offset `bar` by 1 level from the `)`, and + * offset the `)` by 0 levels from `foo`. This ensures that the offset between `bar` and the `)` are correctly collapsed + * in the second case. + * @param {Token} token The token + * @param {Token} fromToken The token that `token` should be offset from + * @param {number} offset The desired indent level + * @returns {void} + */ + setDesiredOffset(token, fromToken, offset) { + return this.setDesiredOffsets(token.range, fromToken, offset); + } + + /** + * Sets the desired offset of all tokens in a range + * It's common for node listeners in this file to need to apply the same offset to a large, contiguous range of tokens. + * Moreover, the offset of any given token is usually updated multiple times (roughly once for each node that contains + * it). This means that the offset of each token is updated O(AST depth) times. + * It would not be performant to store and update the offsets for each token independently, because the rule would end + * up having a time complexity of O(number of tokens * AST depth), which is quite slow for large files. + * + * Instead, the offset tree is represented as a collection of contiguous offset ranges in a file. For example, the following + * list could represent the state of the offset tree at a given point: + * + * * Tokens starting in the interval [0, 15) are aligned with the beginning of the file + * * Tokens starting in the interval [15, 30) are offset by 1 indent level from the `bar` token + * * Tokens starting in the interval [30, 43) are offset by 1 indent level from the `foo` token + * * Tokens starting in the interval [43, 820) are offset by 2 indent levels from the `bar` token + * * Tokens starting in the interval [820, ∞) are offset by 1 indent level from the `baz` token + * + * The `setDesiredOffsets` methods inserts ranges like the ones above. The third line above would be inserted by using: + * `setDesiredOffsets([30, 43], fooToken, 1);` + * @param {[number, number]} range A [start, end] pair. All tokens with range[0] <= token.start < range[1] will have the offset applied. + * @param {Token} fromToken The token that this is offset from + * @param {number} offset The desired indent level + * @param {boolean} force `true` if this offset should not use the normal collapsing behavior. This should almost always be false. + * @returns {void} + */ + setDesiredOffsets(range, fromToken, offset, force) { + + /* + * Offset ranges are stored as a collection of nodes, where each node maps a numeric key to an offset + * descriptor. The tree for the example above would have the following nodes: + * + * * key: 0, value: { offset: 0, from: null } + * * key: 15, value: { offset: 1, from: barToken } + * * key: 30, value: { offset: 1, from: fooToken } + * * key: 43, value: { offset: 2, from: barToken } + * * key: 820, value: { offset: 1, from: bazToken } + * + * To find the offset descriptor for any given token, one needs to find the node with the largest key + * which is <= token.start. To make this operation fast, the nodes are stored in a balanced binary + * search tree indexed by key. + */ + + const descriptorToInsert = { offset, from: fromToken, force }; + + const descriptorAfterRange = this._tree.findLe(range[1]).value; + + const fromTokenIsInRange = fromToken && fromToken.range[0] >= range[0] && fromToken.range[1] <= range[1]; + const fromTokenDescriptor = fromTokenIsInRange && this._getOffsetDescriptor(fromToken); + + // First, remove any existing nodes in the range from the tree. + this._tree.deleteRange(range[0] + 1, range[1]); + + // Insert a new node into the tree for this range + this._tree.insert(range[0], descriptorToInsert); + + /* + * To avoid circular offset dependencies, keep the `fromToken` token mapped to whatever it was mapped to previously, + * even if it's in the current range. + */ + if (fromTokenIsInRange) { + this._tree.insert(fromToken.range[0], fromTokenDescriptor); + this._tree.insert(fromToken.range[1], descriptorToInsert); + } + + /* + * To avoid modifying the offset of tokens after the range, insert another node to keep the offset of the following + * tokens the same as it was before. + */ + this._tree.insert(range[1], descriptorAfterRange); + } + + /** + * Gets the desired indent of a token + * @param {Token} token The token + * @returns {string} The desired indent of the token + */ + getDesiredIndent(token) { + if (!this._desiredIndentCache.has(token)) { + + if (this._ignoredTokens.has(token)) { + + /* + * If the token is ignored, use the actual indent of the token as the desired indent. + * This ensures that no errors are reported for this token. + */ + this._desiredIndentCache.set( + token, + this._tokenInfo.getTokenIndent(token) + ); + } else if (this._lockedFirstTokens.has(token)) { + const firstToken = this._lockedFirstTokens.get(token); + + this._desiredIndentCache.set( + token, + + // (indentation for the first element's line) + this.getDesiredIndent(this._tokenInfo.getFirstTokenOfLine(firstToken)) + + + // (space between the start of the first element's line and the first element) + this._indentType.repeat(firstToken.loc.start.column - this._tokenInfo.getFirstTokenOfLine(firstToken).loc.start.column) + ); + } else { + const offsetInfo = this._getOffsetDescriptor(token); + const offset = ( + offsetInfo.from && + offsetInfo.from.loc.start.line === token.loc.start.line && + !/^\s*?\n/u.test(token.value) && + !offsetInfo.force + ) ? 0 : offsetInfo.offset * this._indentSize; + + this._desiredIndentCache.set( + token, + (offsetInfo.from ? this.getDesiredIndent(offsetInfo.from) : "") + this._indentType.repeat(offset) + ); + } + } + return this._desiredIndentCache.get(token); + } + + /** + * Ignores a token, preventing it from being reported. + * @param {Token} token The token + * @returns {void} + */ + ignoreToken(token) { + if (this._tokenInfo.isFirstTokenOfLine(token)) { + this._ignoredTokens.add(token); + } + } + + /** + * Gets the first token that the given token's indentation is dependent on + * @param {Token} token The token + * @returns {Token} The token that the given token depends on, or `null` if the given token is at the top level + */ + getFirstDependency(token) { + return this._getOffsetDescriptor(token).from; + } +} + +const ELEMENT_LIST_SCHEMA = { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + enum: ["first", "off"] + } + ] +}; + +var indent = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent indentation", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/indent" + }, + + fixable: "whitespace", + + schema: [ + { + oneOf: [ + { + enum: ["tab"] + }, + { + type: "integer", + minimum: 0 + } + ] + }, + { + type: "object", + properties: { + SwitchCase: { + type: "integer", + minimum: 0, + default: 0 + }, + VariableDeclarator: { + oneOf: [ + ELEMENT_LIST_SCHEMA, + { + type: "object", + properties: { + var: ELEMENT_LIST_SCHEMA, + let: ELEMENT_LIST_SCHEMA, + const: ELEMENT_LIST_SCHEMA + }, + additionalProperties: false + } + ] + }, + outerIIFEBody: { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + enum: ["off"] + } + ] + }, + MemberExpression: { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + enum: ["off"] + } + ] + }, + FunctionDeclaration: { + type: "object", + properties: { + parameters: ELEMENT_LIST_SCHEMA, + body: { + type: "integer", + minimum: 0 + } + }, + additionalProperties: false + }, + FunctionExpression: { + type: "object", + properties: { + parameters: ELEMENT_LIST_SCHEMA, + body: { + type: "integer", + minimum: 0 + } + }, + additionalProperties: false + }, + CallExpression: { + type: "object", + properties: { + arguments: ELEMENT_LIST_SCHEMA + }, + additionalProperties: false + }, + ArrayExpression: ELEMENT_LIST_SCHEMA, + ObjectExpression: ELEMENT_LIST_SCHEMA, + ImportDeclaration: ELEMENT_LIST_SCHEMA, + flatTernaryExpressions: { + type: "boolean", + default: false + }, + offsetTernaryExpressions: { + type: "boolean", + default: false + }, + ignoredNodes: { + type: "array", + items: { + type: "string", + not: { + pattern: ":exit$" + } + } + }, + ignoreComments: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + messages: { + wrongIndentation: "Expected indentation of {{expected}} but found {{actual}}." + } + }, + + create(context) { + const DEFAULT_VARIABLE_INDENT = 1; + const DEFAULT_PARAMETER_INDENT = 1; + const DEFAULT_FUNCTION_BODY_INDENT = 1; + + let indentType = "space"; + let indentSize = 4; + const options = { + SwitchCase: 0, + VariableDeclarator: { + var: DEFAULT_VARIABLE_INDENT, + let: DEFAULT_VARIABLE_INDENT, + const: DEFAULT_VARIABLE_INDENT + }, + outerIIFEBody: 1, + FunctionDeclaration: { + parameters: DEFAULT_PARAMETER_INDENT, + body: DEFAULT_FUNCTION_BODY_INDENT + }, + FunctionExpression: { + parameters: DEFAULT_PARAMETER_INDENT, + body: DEFAULT_FUNCTION_BODY_INDENT + }, + CallExpression: { + arguments: DEFAULT_PARAMETER_INDENT + }, + MemberExpression: 1, + ArrayExpression: 1, + ObjectExpression: 1, + ImportDeclaration: 1, + flatTernaryExpressions: false, + ignoredNodes: [], + ignoreComments: false + }; + + if (context.options.length) { + if (context.options[0] === "tab") { + indentSize = 1; + indentType = "tab"; + } else { + indentSize = context.options[0]; + indentType = "space"; + } + + if (context.options[1]) { + Object.assign(options, context.options[1]); + + if (typeof options.VariableDeclarator === "number" || options.VariableDeclarator === "first") { + options.VariableDeclarator = { + var: options.VariableDeclarator, + let: options.VariableDeclarator, + const: options.VariableDeclarator + }; + } + } + } + + const sourceCode = context.getSourceCode(); + const tokenInfo = new TokenInfo(sourceCode); + const offsets = new OffsetStorage(tokenInfo, indentSize, indentType === "space" ? " " : "\t"); + const parameterParens = new WeakSet(); + + /** + * Creates an error message for a line, given the expected/actual indentation. + * @param {int} expectedAmount The expected amount of indentation characters for this line + * @param {int} actualSpaces The actual number of indentation spaces that were found on this line + * @param {int} actualTabs The actual number of indentation tabs that were found on this line + * @returns {string} An error message for this line + */ + function createErrorMessageData(expectedAmount, actualSpaces, actualTabs) { + const expectedStatement = `${expectedAmount} ${indentType}${expectedAmount === 1 ? "" : "s"}`; // e.g. "2 tabs" + const foundSpacesWord = `space${actualSpaces === 1 ? "" : "s"}`; // e.g. "space" + const foundTabsWord = `tab${actualTabs === 1 ? "" : "s"}`; // e.g. "tabs" + let foundStatement; + + if (actualSpaces > 0) { + + /* + * Abbreviate the message if the expected indentation is also spaces. + * e.g. 'Expected 4 spaces but found 2' rather than 'Expected 4 spaces but found 2 spaces' + */ + foundStatement = indentType === "space" ? actualSpaces : `${actualSpaces} ${foundSpacesWord}`; + } else if (actualTabs > 0) { + foundStatement = indentType === "tab" ? actualTabs : `${actualTabs} ${foundTabsWord}`; + } else { + foundStatement = "0"; + } + return { + expected: expectedStatement, + actual: foundStatement + }; + } + + /** + * Reports a given indent violation + * @param {Token} token Token violating the indent rule + * @param {string} neededIndent Expected indentation string + * @returns {void} + */ + function report(token, neededIndent) { + const actualIndent = Array.from(tokenInfo.getTokenIndent(token)); + const numSpaces = actualIndent.filter(char => char === " ").length; + const numTabs = actualIndent.filter(char => char === "\t").length; + + context.report({ + node: token, + messageId: "wrongIndentation", + data: createErrorMessageData(neededIndent.length, numSpaces, numTabs), + loc: { + start: { line: token.loc.start.line, column: 0 }, + end: { line: token.loc.start.line, column: token.loc.start.column } + }, + fix(fixer) { + const range = [token.range[0] - token.loc.start.column, token.range[0]]; + const newText = neededIndent; + + return fixer.replaceTextRange(range, newText); + } + }); + } + + /** + * Checks if a token's indentation is correct + * @param {Token} token Token to examine + * @param {string} desiredIndent Desired indentation of the string + * @returns {boolean} `true` if the token's indentation is correct + */ + function validateTokenIndent(token, desiredIndent) { + const indentation = tokenInfo.getTokenIndent(token); + + return indentation === desiredIndent || + + // To avoid conflicts with no-mixed-spaces-and-tabs, don't report mixed spaces and tabs. + indentation.includes(" ") && indentation.includes("\t"); + } + + /** + * Check to see if the node is a file level IIFE + * @param {ASTNode} node The function node to check. + * @returns {boolean} True if the node is the outer IIFE + */ + function isOuterIIFE(node) { + + /* + * Verify that the node is an IIFE + */ + if (!node.parent || node.parent.type !== "CallExpression" || node.parent.callee !== node) { + return false; + } + + /* + * Navigate legal ancestors to determine whether this IIFE is outer. + * A "legal ancestor" is an expression or statement that causes the function to get executed immediately. + * For example, `!(function(){})()` is an outer IIFE even though it is preceded by a ! operator. + */ + let statement = node.parent && node.parent.parent; + + while ( + statement.type === "UnaryExpression" && ["!", "~", "+", "-"].indexOf(statement.operator) > -1 || + statement.type === "AssignmentExpression" || + statement.type === "LogicalExpression" || + statement.type === "SequenceExpression" || + statement.type === "VariableDeclarator" + ) { + statement = statement.parent; + } + + return (statement.type === "ExpressionStatement" || statement.type === "VariableDeclaration") && statement.parent.type === "Program"; + } + + /** + * Counts the number of linebreaks that follow the last non-whitespace character in a string + * @param {string} string The string to check + * @returns {number} The number of JavaScript linebreaks that follow the last non-whitespace character, + * or the total number of linebreaks if the string is all whitespace. + */ + function countTrailingLinebreaks(string) { + const trailingWhitespace = string.match(/\s*$/u)[0]; + const linebreakMatches = trailingWhitespace.match(astUtils.createGlobalLinebreakMatcher()); + + return linebreakMatches === null ? 0 : linebreakMatches.length; + } + + /** + * Check indentation for lists of elements (arrays, objects, function params) + * @param {ASTNode[]} elements List of elements that should be offset + * @param {Token} startToken The start token of the list that element should be aligned against, e.g. '[' + * @param {Token} endToken The end token of the list, e.g. ']' + * @param {number|string} offset The amount that the elements should be offset + * @returns {void} + */ + function addElementListIndent(elements, startToken, endToken, offset) { + + /** + * Gets the first token of a given element, including surrounding parentheses. + * @param {ASTNode} element A node in the `elements` list + * @returns {Token} The first token of this element + */ + function getFirstToken(element) { + let token = sourceCode.getTokenBefore(element); + + while (astUtils.isOpeningParenToken(token) && token !== startToken) { + token = sourceCode.getTokenBefore(token); + } + return sourceCode.getTokenAfter(token); + } + + // Run through all the tokens in the list, and offset them by one indent level (mainly for comments, other things will end up overridden) + offsets.setDesiredOffsets( + [startToken.range[1], endToken.range[0]], + startToken, + typeof offset === "number" ? offset : 1 + ); + offsets.setDesiredOffset(endToken, startToken, 0); + + // If the preference is "first" but there is no first element (e.g. sparse arrays w/ empty first slot), fall back to 1 level. + if (offset === "first" && elements.length && !elements[0]) { + return; + } + elements.forEach((element, index) => { + if (!element) { + + // Skip holes in arrays + return; + } + if (offset === "off") { + + // Ignore the first token of every element if the "off" option is used + offsets.ignoreToken(getFirstToken(element)); + } + + // Offset the following elements correctly relative to the first element + if (index === 0) { + return; + } + if (offset === "first" && tokenInfo.isFirstTokenOfLine(getFirstToken(element))) { + offsets.matchOffsetOf(getFirstToken(elements[0]), getFirstToken(element)); + } else { + const previousElement = elements[index - 1]; + const firstTokenOfPreviousElement = previousElement && getFirstToken(previousElement); + const previousElementLastToken = previousElement && sourceCode.getLastToken(previousElement); + + if ( + previousElement && + previousElementLastToken.loc.end.line - countTrailingLinebreaks(previousElementLastToken.value) > startToken.loc.end.line + ) { + offsets.setDesiredOffsets( + [previousElement.range[1], element.range[1]], + firstTokenOfPreviousElement, + 0 + ); + } + } + }); + } + + /** + * Check and decide whether to check for indentation for blockless nodes + * Scenarios are for or while statements without braces around them + * @param {ASTNode} node node to examine + * @returns {void} + */ + function addBlocklessNodeIndent(node) { + if (node.type !== "BlockStatement") { + const lastParentToken = sourceCode.getTokenBefore(node, astUtils.isNotOpeningParenToken); + + let firstBodyToken = sourceCode.getFirstToken(node); + let lastBodyToken = sourceCode.getLastToken(node); + + while ( + astUtils.isOpeningParenToken(sourceCode.getTokenBefore(firstBodyToken)) && + astUtils.isClosingParenToken(sourceCode.getTokenAfter(lastBodyToken)) + ) { + firstBodyToken = sourceCode.getTokenBefore(firstBodyToken); + lastBodyToken = sourceCode.getTokenAfter(lastBodyToken); + } + + offsets.setDesiredOffsets([firstBodyToken.range[0], lastBodyToken.range[1]], lastParentToken, 1); + + /* + * For blockless nodes with semicolon-first style, don't indent the semicolon. + * e.g. + * if (foo) bar() + * ; [1, 2, 3].map(foo) + */ + const lastToken = sourceCode.getLastToken(node); + + if (node.type !== "EmptyStatement" && astUtils.isSemicolonToken(lastToken)) { + offsets.setDesiredOffset(lastToken, lastParentToken, 0); + } + } + } + + /** + * Checks the indentation for nodes that are like function calls (`CallExpression` and `NewExpression`) + * @param {ASTNode} node A CallExpression or NewExpression node + * @returns {void} + */ + function addFunctionCallIndent(node) { + let openingParen; + + if (node.arguments.length) { + openingParen = sourceCode.getFirstTokenBetween(node.callee, node.arguments[0], astUtils.isOpeningParenToken); + } else { + openingParen = sourceCode.getLastToken(node, 1); + } + const closingParen = sourceCode.getLastToken(node); + + parameterParens.add(openingParen); + parameterParens.add(closingParen); + + /* + * If `?.` token exists, set desired offset for that. + * This logic is copied from `MemberExpression`'s. + */ + if (node.optional) { + const dotToken = sourceCode.getTokenAfter(node.callee, astUtils.isQuestionDotToken); + const calleeParenCount = sourceCode.getTokensBetween(node.callee, dotToken, { filter: astUtils.isClosingParenToken }).length; + const firstTokenOfCallee = calleeParenCount + ? sourceCode.getTokenBefore(node.callee, { skip: calleeParenCount - 1 }) + : sourceCode.getFirstToken(node.callee); + const lastTokenOfCallee = sourceCode.getTokenBefore(dotToken); + const offsetBase = lastTokenOfCallee.loc.end.line === openingParen.loc.start.line + ? lastTokenOfCallee + : firstTokenOfCallee; + + offsets.setDesiredOffset(dotToken, offsetBase, 1); + } + + const offsetAfterToken = node.callee.type === "TaggedTemplateExpression" ? sourceCode.getFirstToken(node.callee.quasi) : openingParen; + const offsetToken = sourceCode.getTokenBefore(offsetAfterToken); + + offsets.setDesiredOffset(openingParen, offsetToken, 0); + + addElementListIndent(node.arguments, openingParen, closingParen, options.CallExpression.arguments); + } + + /** + * Checks the indentation of parenthesized values, given a list of tokens in a program + * @param {Token[]} tokens A list of tokens + * @returns {void} + */ + function addParensIndent(tokens) { + const parenStack = []; + const parenPairs = []; + + tokens.forEach(nextToken => { + + // Accumulate a list of parenthesis pairs + if (astUtils.isOpeningParenToken(nextToken)) { + parenStack.push(nextToken); + } else if (astUtils.isClosingParenToken(nextToken)) { + parenPairs.unshift({ left: parenStack.pop(), right: nextToken }); + } + }); + + parenPairs.forEach(pair => { + const leftParen = pair.left; + const rightParen = pair.right; + + // We only want to handle parens around expressions, so exclude parentheses that are in function parameters and function call arguments. + if (!parameterParens.has(leftParen) && !parameterParens.has(rightParen)) { + const parenthesizedTokens = new Set(sourceCode.getTokensBetween(leftParen, rightParen)); + + parenthesizedTokens.forEach(token => { + if (!parenthesizedTokens.has(offsets.getFirstDependency(token))) { + offsets.setDesiredOffset(token, leftParen, 1); + } + }); + } + + offsets.setDesiredOffset(rightParen, leftParen, 0); + }); + } + + /** + * Ignore all tokens within an unknown node whose offset do not depend + * on another token's offset within the unknown node + * @param {ASTNode} node Unknown Node + * @returns {void} + */ + function ignoreNode(node) { + const unknownNodeTokens = new Set(sourceCode.getTokens(node, { includeComments: true })); + + unknownNodeTokens.forEach(token => { + if (!unknownNodeTokens.has(offsets.getFirstDependency(token))) { + const firstTokenOfLine = tokenInfo.getFirstTokenOfLine(token); + + if (token === firstTokenOfLine) { + offsets.ignoreToken(token); + } else { + offsets.setDesiredOffset(token, firstTokenOfLine, 0); + } + } + }); + } + + /** + * Check whether the given token is on the first line of a statement. + * @param {Token} token The token to check. + * @param {ASTNode} leafNode The expression node that the token belongs directly. + * @returns {boolean} `true` if the token is on the first line of a statement. + */ + function isOnFirstLineOfStatement(token, leafNode) { + let node = leafNode; + + while (node.parent && !node.parent.type.endsWith("Statement") && !node.parent.type.endsWith("Declaration")) { + node = node.parent; + } + node = node.parent; + + return !node || node.loc.start.line === token.loc.start.line; + } + + /** + * Check whether there are any blank (whitespace-only) lines between + * two tokens on separate lines. + * @param {Token} firstToken The first token. + * @param {Token} secondToken The second token. + * @returns {boolean} `true` if the tokens are on separate lines and + * there exists a blank line between them, `false` otherwise. + */ + function hasBlankLinesBetween(firstToken, secondToken) { + const firstTokenLine = firstToken.loc.end.line; + const secondTokenLine = secondToken.loc.start.line; + + if (firstTokenLine === secondTokenLine || firstTokenLine === secondTokenLine - 1) { + return false; + } + + for (let line = firstTokenLine + 1; line < secondTokenLine; ++line) { + if (!tokenInfo.firstTokensByLineNumber.has(line)) { + return true; + } + } + + return false; + } + + const ignoredNodeFirstTokens = new Set(); + + const baseOffsetListeners = { + "ArrayExpression, ArrayPattern"(node) { + const openingBracket = sourceCode.getFirstToken(node); + const closingBracket = sourceCode.getTokenAfter(lodash__default['default'].findLast(node.elements) || openingBracket, astUtils.isClosingBracketToken); + + addElementListIndent(node.elements, openingBracket, closingBracket, options.ArrayExpression); + }, + + "ObjectExpression, ObjectPattern"(node) { + const openingCurly = sourceCode.getFirstToken(node); + const closingCurly = sourceCode.getTokenAfter( + node.properties.length ? node.properties[node.properties.length - 1] : openingCurly, + astUtils.isClosingBraceToken + ); + + addElementListIndent(node.properties, openingCurly, closingCurly, options.ObjectExpression); + }, + + ArrowFunctionExpression(node) { + const maybeOpeningParen = sourceCode.getFirstToken(node, { skip: node.async ? 1 : 0 }); + + if (astUtils.isOpeningParenToken(maybeOpeningParen)) { + const openingParen = maybeOpeningParen; + const closingParen = sourceCode.getTokenBefore(node.body, astUtils.isClosingParenToken); + + parameterParens.add(openingParen); + parameterParens.add(closingParen); + addElementListIndent(node.params, openingParen, closingParen, options.FunctionExpression.parameters); + } + + addBlocklessNodeIndent(node.body); + }, + + AssignmentExpression(node) { + const operator = sourceCode.getFirstTokenBetween(node.left, node.right, token => token.value === node.operator); + + offsets.setDesiredOffsets([operator.range[0], node.range[1]], sourceCode.getLastToken(node.left), 1); + offsets.ignoreToken(operator); + offsets.ignoreToken(sourceCode.getTokenAfter(operator)); + }, + + "BinaryExpression, LogicalExpression"(node) { + const operator = sourceCode.getFirstTokenBetween(node.left, node.right, token => token.value === node.operator); + + /* + * For backwards compatibility, don't check BinaryExpression indents, e.g. + * var foo = bar && + * baz; + */ + + const tokenAfterOperator = sourceCode.getTokenAfter(operator); + + offsets.ignoreToken(operator); + offsets.ignoreToken(tokenAfterOperator); + offsets.setDesiredOffset(tokenAfterOperator, operator, 0); + }, + + "BlockStatement, ClassBody"(node) { + let blockIndentLevel; + + if (node.parent && isOuterIIFE(node.parent)) { + blockIndentLevel = options.outerIIFEBody; + } else if (node.parent && (node.parent.type === "FunctionExpression" || node.parent.type === "ArrowFunctionExpression")) { + blockIndentLevel = options.FunctionExpression.body; + } else if (node.parent && node.parent.type === "FunctionDeclaration") { + blockIndentLevel = options.FunctionDeclaration.body; + } else { + blockIndentLevel = 1; + } + + /* + * For blocks that aren't lone statements, ensure that the opening curly brace + * is aligned with the parent. + */ + if (!astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type)) { + offsets.setDesiredOffset(sourceCode.getFirstToken(node), sourceCode.getFirstToken(node.parent), 0); + } + + addElementListIndent(node.body, sourceCode.getFirstToken(node), sourceCode.getLastToken(node), blockIndentLevel); + }, + + CallExpression: addFunctionCallIndent, + + "ClassDeclaration[superClass], ClassExpression[superClass]"(node) { + const classToken = sourceCode.getFirstToken(node); + const extendsToken = sourceCode.getTokenBefore(node.superClass, astUtils.isNotOpeningParenToken); + + offsets.setDesiredOffsets([extendsToken.range[0], node.body.range[0]], classToken, 1); + }, + + ConditionalExpression(node) { + const firstToken = sourceCode.getFirstToken(node); + + // `flatTernaryExpressions` option is for the following style: + // var a = + // foo > 0 ? bar : + // foo < 0 ? baz : + // /*else*/ qiz ; + if (!options.flatTernaryExpressions || + !astUtils.isTokenOnSameLine(node.test, node.consequent) || + isOnFirstLineOfStatement(firstToken, node) + ) { + const questionMarkToken = sourceCode.getFirstTokenBetween(node.test, node.consequent, token => token.type === "Punctuator" && token.value === "?"); + const colonToken = sourceCode.getFirstTokenBetween(node.consequent, node.alternate, token => token.type === "Punctuator" && token.value === ":"); + + const firstConsequentToken = sourceCode.getTokenAfter(questionMarkToken); + const lastConsequentToken = sourceCode.getTokenBefore(colonToken); + const firstAlternateToken = sourceCode.getTokenAfter(colonToken); + + offsets.setDesiredOffset(questionMarkToken, firstToken, 1); + offsets.setDesiredOffset(colonToken, firstToken, 1); + + offsets.setDesiredOffset(firstConsequentToken, firstToken, + firstConsequentToken.type === "Punctuator" && + options.offsetTernaryExpressions ? 2 : 1); + + /* + * The alternate and the consequent should usually have the same indentation. + * If they share part of a line, align the alternate against the first token of the consequent. + * This allows the alternate to be indented correctly in cases like this: + * foo ? ( + * bar + * ) : ( // this '(' is aligned with the '(' above, so it's considered to be aligned with `foo` + * baz // as a result, `baz` is offset by 1 rather than 2 + * ) + */ + if (lastConsequentToken.loc.end.line === firstAlternateToken.loc.start.line) { + offsets.setDesiredOffset(firstAlternateToken, firstConsequentToken, 0); + } else { + + /** + * If the alternate and consequent do not share part of a line, offset the alternate from the first + * token of the conditional expression. For example: + * foo ? bar + * : baz + * + * If `baz` were aligned with `bar` rather than being offset by 1 from `foo`, `baz` would end up + * having no expected indentation. + */ + offsets.setDesiredOffset(firstAlternateToken, firstToken, + firstAlternateToken.type === "Punctuator" && + options.offsetTernaryExpressions ? 2 : 1); + } + } + }, + + "DoWhileStatement, WhileStatement, ForInStatement, ForOfStatement": node => addBlocklessNodeIndent(node.body), + + ExportNamedDeclaration(node) { + if (node.declaration === null) { + const closingCurly = sourceCode.getLastToken(node, astUtils.isClosingBraceToken); + + // Indent the specifiers in `export {foo, bar, baz}` + addElementListIndent(node.specifiers, sourceCode.getFirstToken(node, { skip: 1 }), closingCurly, 1); + + if (node.source) { + + // Indent everything after and including the `from` token in `export {foo, bar, baz} from 'qux'` + offsets.setDesiredOffsets([closingCurly.range[1], node.range[1]], sourceCode.getFirstToken(node), 1); + } + } + }, + + ForStatement(node) { + const forOpeningParen = sourceCode.getFirstToken(node, 1); + + if (node.init) { + offsets.setDesiredOffsets(node.init.range, forOpeningParen, 1); + } + if (node.test) { + offsets.setDesiredOffsets(node.test.range, forOpeningParen, 1); + } + if (node.update) { + offsets.setDesiredOffsets(node.update.range, forOpeningParen, 1); + } + addBlocklessNodeIndent(node.body); + }, + + "FunctionDeclaration, FunctionExpression"(node) { + const closingParen = sourceCode.getTokenBefore(node.body); + const openingParen = sourceCode.getTokenBefore(node.params.length ? node.params[0] : closingParen); + + parameterParens.add(openingParen); + parameterParens.add(closingParen); + addElementListIndent(node.params, openingParen, closingParen, options[node.type].parameters); + }, + + IfStatement(node) { + addBlocklessNodeIndent(node.consequent); + if (node.alternate && node.alternate.type !== "IfStatement") { + addBlocklessNodeIndent(node.alternate); + } + }, + + ImportDeclaration(node) { + if (node.specifiers.some(specifier => specifier.type === "ImportSpecifier")) { + const openingCurly = sourceCode.getFirstToken(node, astUtils.isOpeningBraceToken); + const closingCurly = sourceCode.getLastToken(node, astUtils.isClosingBraceToken); + + addElementListIndent(node.specifiers.filter(specifier => specifier.type === "ImportSpecifier"), openingCurly, closingCurly, options.ImportDeclaration); + } + + const fromToken = sourceCode.getLastToken(node, token => token.type === "Identifier" && token.value === "from"); + const sourceToken = sourceCode.getLastToken(node, token => token.type === "String"); + const semiToken = sourceCode.getLastToken(node, token => token.type === "Punctuator" && token.value === ";"); + + if (fromToken) { + const end = semiToken && semiToken.range[1] === sourceToken.range[1] ? node.range[1] : sourceToken.range[1]; + + offsets.setDesiredOffsets([fromToken.range[0], end], sourceCode.getFirstToken(node), 1); + } + }, + + ImportExpression(node) { + const openingParen = sourceCode.getFirstToken(node, 1); + const closingParen = sourceCode.getLastToken(node); + + parameterParens.add(openingParen); + parameterParens.add(closingParen); + offsets.setDesiredOffset(openingParen, sourceCode.getTokenBefore(openingParen), 0); + + addElementListIndent([node.source], openingParen, closingParen, options.CallExpression.arguments); + }, + + "MemberExpression, JSXMemberExpression, MetaProperty"(node) { + const object = node.type === "MetaProperty" ? node.meta : node.object; + const firstNonObjectToken = sourceCode.getFirstTokenBetween(object, node.property, astUtils.isNotClosingParenToken); + const secondNonObjectToken = sourceCode.getTokenAfter(firstNonObjectToken); + + const objectParenCount = sourceCode.getTokensBetween(object, node.property, { filter: astUtils.isClosingParenToken }).length; + const firstObjectToken = objectParenCount + ? sourceCode.getTokenBefore(object, { skip: objectParenCount - 1 }) + : sourceCode.getFirstToken(object); + const lastObjectToken = sourceCode.getTokenBefore(firstNonObjectToken); + const firstPropertyToken = node.computed ? firstNonObjectToken : secondNonObjectToken; + + if (node.computed) { + + // For computed MemberExpressions, match the closing bracket with the opening bracket. + offsets.setDesiredOffset(sourceCode.getLastToken(node), firstNonObjectToken, 0); + offsets.setDesiredOffsets(node.property.range, firstNonObjectToken, 1); + } + + /* + * If the object ends on the same line that the property starts, match against the last token + * of the object, to ensure that the MemberExpression is not indented. + * + * Otherwise, match against the first token of the object, e.g. + * foo + * .bar + * .baz // <-- offset by 1 from `foo` + */ + const offsetBase = lastObjectToken.loc.end.line === firstPropertyToken.loc.start.line + ? lastObjectToken + : firstObjectToken; + + if (typeof options.MemberExpression === "number") { + + // Match the dot (for non-computed properties) or the opening bracket (for computed properties) against the object. + offsets.setDesiredOffset(firstNonObjectToken, offsetBase, options.MemberExpression); + + /* + * For computed MemberExpressions, match the first token of the property against the opening bracket. + * Otherwise, match the first token of the property against the object. + */ + offsets.setDesiredOffset(secondNonObjectToken, node.computed ? firstNonObjectToken : offsetBase, options.MemberExpression); + } else { + + // If the MemberExpression option is off, ignore the dot and the first token of the property. + offsets.ignoreToken(firstNonObjectToken); + offsets.ignoreToken(secondNonObjectToken); + + // To ignore the property indentation, ensure that the property tokens depend on the ignored tokens. + offsets.setDesiredOffset(firstNonObjectToken, offsetBase, 0); + offsets.setDesiredOffset(secondNonObjectToken, firstNonObjectToken, 0); + } + }, + + NewExpression(node) { + + // Only indent the arguments if the NewExpression has parens (e.g. `new Foo(bar)` or `new Foo()`, but not `new Foo` + if (node.arguments.length > 0 || + astUtils.isClosingParenToken(sourceCode.getLastToken(node)) && + astUtils.isOpeningParenToken(sourceCode.getLastToken(node, 1))) { + addFunctionCallIndent(node); + } + }, + + Property(node) { + if (!node.shorthand && !node.method && node.kind === "init") { + const colon = sourceCode.getFirstTokenBetween(node.key, node.value, astUtils.isColonToken); + + offsets.ignoreToken(sourceCode.getTokenAfter(colon)); + } + }, + + SwitchStatement(node) { + const openingCurly = sourceCode.getTokenAfter(node.discriminant, astUtils.isOpeningBraceToken); + const closingCurly = sourceCode.getLastToken(node); + + offsets.setDesiredOffsets([openingCurly.range[1], closingCurly.range[0]], openingCurly, options.SwitchCase); + + if (node.cases.length) { + sourceCode.getTokensBetween( + node.cases[node.cases.length - 1], + closingCurly, + { includeComments: true, filter: astUtils.isCommentToken } + ).forEach(token => offsets.ignoreToken(token)); + } + }, + + SwitchCase(node) { + if (!(node.consequent.length === 1 && node.consequent[0].type === "BlockStatement")) { + const caseKeyword = sourceCode.getFirstToken(node); + const tokenAfterCurrentCase = sourceCode.getTokenAfter(node); + + offsets.setDesiredOffsets([caseKeyword.range[1], tokenAfterCurrentCase.range[0]], caseKeyword, 1); + } + }, + + TemplateLiteral(node) { + node.expressions.forEach((expression, index) => { + const previousQuasi = node.quasis[index]; + const nextQuasi = node.quasis[index + 1]; + const tokenToAlignFrom = previousQuasi.loc.start.line === previousQuasi.loc.end.line + ? sourceCode.getFirstToken(previousQuasi) + : null; + + offsets.setDesiredOffsets([previousQuasi.range[1], nextQuasi.range[0]], tokenToAlignFrom, 1); + offsets.setDesiredOffset(sourceCode.getFirstToken(nextQuasi), tokenToAlignFrom, 0); + }); + }, + + VariableDeclaration(node) { + let variableIndent = Object.prototype.hasOwnProperty.call(options.VariableDeclarator, node.kind) + ? options.VariableDeclarator[node.kind] + : DEFAULT_VARIABLE_INDENT; + + const firstToken = sourceCode.getFirstToken(node), + lastToken = sourceCode.getLastToken(node); + + if (options.VariableDeclarator[node.kind] === "first") { + if (node.declarations.length > 1) { + addElementListIndent( + node.declarations, + firstToken, + lastToken, + "first" + ); + return; + } + + variableIndent = DEFAULT_VARIABLE_INDENT; + } + + if (node.declarations[node.declarations.length - 1].loc.start.line > node.loc.start.line) { + + /* + * VariableDeclarator indentation is a bit different from other forms of indentation, in that the + * indentation of an opening bracket sometimes won't match that of a closing bracket. For example, + * the following indentations are correct: + * + * var foo = { + * ok: true + * }; + * + * var foo = { + * ok: true, + * }, + * bar = 1; + * + * Account for when exiting the AST (after indentations have already been set for the nodes in + * the declaration) by manually increasing the indentation level of the tokens in this declarator + * on the same line as the start of the declaration, provided that there are declarators that + * follow this one. + */ + offsets.setDesiredOffsets(node.range, firstToken, variableIndent, true); + } else { + offsets.setDesiredOffsets(node.range, firstToken, variableIndent); + } + + if (astUtils.isSemicolonToken(lastToken)) { + offsets.ignoreToken(lastToken); + } + }, + + VariableDeclarator(node) { + if (node.init) { + const equalOperator = sourceCode.getTokenBefore(node.init, astUtils.isNotOpeningParenToken); + const tokenAfterOperator = sourceCode.getTokenAfter(equalOperator); + + offsets.ignoreToken(equalOperator); + offsets.ignoreToken(tokenAfterOperator); + offsets.setDesiredOffsets([tokenAfterOperator.range[0], node.range[1]], equalOperator, 1); + offsets.setDesiredOffset(equalOperator, sourceCode.getLastToken(node.id), 0); + } + }, + + "JSXAttribute[value]"(node) { + const equalsToken = sourceCode.getFirstTokenBetween(node.name, node.value, token => token.type === "Punctuator" && token.value === "="); + + offsets.setDesiredOffsets([equalsToken.range[0], node.value.range[1]], sourceCode.getFirstToken(node.name), 1); + }, + + JSXElement(node) { + if (node.closingElement) { + addElementListIndent(node.children, sourceCode.getFirstToken(node.openingElement), sourceCode.getFirstToken(node.closingElement), 1); + } + }, + + JSXOpeningElement(node) { + const firstToken = sourceCode.getFirstToken(node); + let closingToken; + + if (node.selfClosing) { + closingToken = sourceCode.getLastToken(node, { skip: 1 }); + offsets.setDesiredOffset(sourceCode.getLastToken(node), closingToken, 0); + } else { + closingToken = sourceCode.getLastToken(node); + } + offsets.setDesiredOffsets(node.name.range, sourceCode.getFirstToken(node)); + addElementListIndent(node.attributes, firstToken, closingToken, 1); + }, + + JSXClosingElement(node) { + const firstToken = sourceCode.getFirstToken(node); + + offsets.setDesiredOffsets(node.name.range, firstToken, 1); + }, + + JSXFragment(node) { + const firstOpeningToken = sourceCode.getFirstToken(node.openingFragment); + const firstClosingToken = sourceCode.getFirstToken(node.closingFragment); + + addElementListIndent(node.children, firstOpeningToken, firstClosingToken, 1); + }, + + JSXOpeningFragment(node) { + const firstToken = sourceCode.getFirstToken(node); + const closingToken = sourceCode.getLastToken(node); + + offsets.setDesiredOffsets(node.range, firstToken, 1); + offsets.matchOffsetOf(firstToken, closingToken); + }, + + JSXClosingFragment(node) { + const firstToken = sourceCode.getFirstToken(node); + const slashToken = sourceCode.getLastToken(node, { skip: 1 }); + const closingToken = sourceCode.getLastToken(node); + const tokenToMatch = astUtils.isTokenOnSameLine(slashToken, closingToken) ? slashToken : closingToken; + + offsets.setDesiredOffsets(node.range, firstToken, 1); + offsets.matchOffsetOf(firstToken, tokenToMatch); + }, + + JSXExpressionContainer(node) { + const openingCurly = sourceCode.getFirstToken(node); + const closingCurly = sourceCode.getLastToken(node); + + offsets.setDesiredOffsets( + [openingCurly.range[1], closingCurly.range[0]], + openingCurly, + 1 + ); + }, + + JSXSpreadAttribute(node) { + const openingCurly = sourceCode.getFirstToken(node); + const closingCurly = sourceCode.getLastToken(node); + + offsets.setDesiredOffsets( + [openingCurly.range[1], closingCurly.range[0]], + openingCurly, + 1 + ); + }, + + "*"(node) { + const firstToken = sourceCode.getFirstToken(node); + + // Ensure that the children of every node are indented at least as much as the first token. + if (firstToken && !ignoredNodeFirstTokens.has(firstToken)) { + offsets.setDesiredOffsets(node.range, firstToken, 0); + } + } + }; + + const listenerCallQueue = []; + + /* + * To ignore the indentation of a node: + * 1. Don't call the node's listener when entering it (if it has a listener) + * 2. Don't set any offsets against the first token of the node. + * 3. Call `ignoreNode` on the node sometime after exiting it and before validating offsets. + */ + const offsetListeners = lodash__default['default'].mapValues( + baseOffsetListeners, + + /* + * Offset listener calls are deferred until traversal is finished, and are called as + * part of the final `Program:exit` listener. This is necessary because a node might + * be matched by multiple selectors. + * + * Example: Suppose there is an offset listener for `Identifier`, and the user has + * specified in configuration that `MemberExpression > Identifier` should be ignored. + * Due to selector specificity rules, the `Identifier` listener will get called first. However, + * if a given Identifier node is supposed to be ignored, then the `Identifier` offset listener + * should not have been called at all. Without doing extra selector matching, we don't know + * whether the Identifier matches the `MemberExpression > Identifier` selector until the + * `MemberExpression > Identifier` listener is called. + * + * To avoid this, the `Identifier` listener isn't called until traversal finishes and all + * ignored nodes are known. + */ + listener => + node => + listenerCallQueue.push({ listener, node }) + ); + + // For each ignored node selector, set up a listener to collect it into the `ignoredNodes` set. + const ignoredNodes = new Set(); + + /** + * Ignores a node + * @param {ASTNode} node The node to ignore + * @returns {void} + */ + function addToIgnoredNodes(node) { + ignoredNodes.add(node); + ignoredNodeFirstTokens.add(sourceCode.getFirstToken(node)); + } + + const ignoredNodeListeners = options.ignoredNodes.reduce( + (listeners, ignoredSelector) => Object.assign(listeners, { [ignoredSelector]: addToIgnoredNodes }), + {} + ); + + /* + * Join the listeners, and add a listener to verify that all tokens actually have the correct indentation + * at the end. + * + * Using Object.assign will cause some offset listeners to be overwritten if the same selector also appears + * in `ignoredNodeListeners`. This isn't a problem because all of the matching nodes will be ignored, + * so those listeners wouldn't be called anyway. + */ + return Object.assign( + offsetListeners, + ignoredNodeListeners, + { + "*:exit"(node) { + + // If a node's type is nonstandard, we can't tell how its children should be offset, so ignore it. + if (!KNOWN_NODES.has(node.type)) { + addToIgnoredNodes(node); + } + }, + "Program:exit"() { + + // If ignoreComments option is enabled, ignore all comment tokens. + if (options.ignoreComments) { + sourceCode.getAllComments() + .forEach(comment => offsets.ignoreToken(comment)); + } + + // Invoke the queued offset listeners for the nodes that aren't ignored. + listenerCallQueue + .filter(nodeInfo => !ignoredNodes.has(nodeInfo.node)) + .forEach(nodeInfo => nodeInfo.listener(nodeInfo.node)); + + // Update the offsets for ignored nodes to prevent their child tokens from being reported. + ignoredNodes.forEach(ignoreNode); + + addParensIndent(sourceCode.ast.tokens); + + /* + * Create a Map from (tokenOrComment) => (precedingToken). + * This is necessary because sourceCode.getTokenBefore does not handle a comment as an argument correctly. + */ + const precedingTokens = sourceCode.ast.comments.reduce((commentMap, comment) => { + const tokenOrCommentBefore = sourceCode.getTokenBefore(comment, { includeComments: true }); + + return commentMap.set(comment, commentMap.has(tokenOrCommentBefore) ? commentMap.get(tokenOrCommentBefore) : tokenOrCommentBefore); + }, new WeakMap()); + + sourceCode.lines.forEach((line, lineIndex) => { + const lineNumber = lineIndex + 1; + + if (!tokenInfo.firstTokensByLineNumber.has(lineNumber)) { + + // Don't check indentation on blank lines + return; + } + + const firstTokenOfLine = tokenInfo.firstTokensByLineNumber.get(lineNumber); + + if (firstTokenOfLine.loc.start.line !== lineNumber) { + + // Don't check the indentation of multi-line tokens (e.g. template literals or block comments) twice. + return; + } + + if (astUtils.isCommentToken(firstTokenOfLine)) { + const tokenBefore = precedingTokens.get(firstTokenOfLine); + const tokenAfter = tokenBefore ? sourceCode.getTokenAfter(tokenBefore) : sourceCode.ast.tokens[0]; + const mayAlignWithBefore = tokenBefore && !hasBlankLinesBetween(tokenBefore, firstTokenOfLine); + const mayAlignWithAfter = tokenAfter && !hasBlankLinesBetween(firstTokenOfLine, tokenAfter); + + /* + * If a comment precedes a line that begins with a semicolon token, align to that token, i.e. + * + * let foo + * // comment + * ;(async () => {})() + */ + if (tokenAfter && astUtils.isSemicolonToken(tokenAfter) && !astUtils.isTokenOnSameLine(firstTokenOfLine, tokenAfter)) { + offsets.setDesiredOffset(firstTokenOfLine, tokenAfter, 0); + } + + // If a comment matches the expected indentation of the token immediately before or after, don't report it. + if ( + mayAlignWithBefore && validateTokenIndent(firstTokenOfLine, offsets.getDesiredIndent(tokenBefore)) || + mayAlignWithAfter && validateTokenIndent(firstTokenOfLine, offsets.getDesiredIndent(tokenAfter)) + ) { + return; + } + } + + // If the token matches the expected indentation, don't report it. + if (validateTokenIndent(firstTokenOfLine, offsets.getDesiredIndent(firstTokenOfLine))) { + return; + } + + // Otherwise, report the token/comment. + report(firstTokenOfLine, offsets.getDesiredIndent(firstTokenOfLine)); + }); + } + } + ); + } +}; + +/** + * @fileoverview This option sets a specific tab width for your code + * + * This rule has been ported and modified from nodeca. + * @author Vitaly Puzrin + * @author Gyandeep Singh + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +/* istanbul ignore next: this rule has known coverage issues, but it's deprecated and shouldn't be updated in the future anyway. */ +var indentLegacy = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent indentation", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/indent-legacy" + }, + + deprecated: true, + + replacedBy: ["indent"], + + fixable: "whitespace", + + schema: [ + { + oneOf: [ + { + enum: ["tab"] + }, + { + type: "integer", + minimum: 0 + } + ] + }, + { + type: "object", + properties: { + SwitchCase: { + type: "integer", + minimum: 0 + }, + VariableDeclarator: { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + type: "object", + properties: { + var: { + type: "integer", + minimum: 0 + }, + let: { + type: "integer", + minimum: 0 + }, + const: { + type: "integer", + minimum: 0 + } + } + } + ] + }, + outerIIFEBody: { + type: "integer", + minimum: 0 + }, + MemberExpression: { + type: "integer", + minimum: 0 + }, + FunctionDeclaration: { + type: "object", + properties: { + parameters: { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + enum: ["first"] + } + ] + }, + body: { + type: "integer", + minimum: 0 + } + } + }, + FunctionExpression: { + type: "object", + properties: { + parameters: { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + enum: ["first"] + } + ] + }, + body: { + type: "integer", + minimum: 0 + } + } + }, + CallExpression: { + type: "object", + properties: { + parameters: { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + enum: ["first"] + } + ] + } + } + }, + ArrayExpression: { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + enum: ["first"] + } + ] + }, + ObjectExpression: { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + enum: ["first"] + } + ] + } + }, + additionalProperties: false + } + ], + messages: { + expected: "Expected indentation of {{expected}} but found {{actual}}." + } + }, + + create(context) { + const DEFAULT_VARIABLE_INDENT = 1; + const DEFAULT_PARAMETER_INDENT = null; // For backwards compatibility, don't check parameter indentation unless specified in the config + const DEFAULT_FUNCTION_BODY_INDENT = 1; + + let indentType = "space"; + let indentSize = 4; + const options = { + SwitchCase: 0, + VariableDeclarator: { + var: DEFAULT_VARIABLE_INDENT, + let: DEFAULT_VARIABLE_INDENT, + const: DEFAULT_VARIABLE_INDENT + }, + outerIIFEBody: null, + FunctionDeclaration: { + parameters: DEFAULT_PARAMETER_INDENT, + body: DEFAULT_FUNCTION_BODY_INDENT + }, + FunctionExpression: { + parameters: DEFAULT_PARAMETER_INDENT, + body: DEFAULT_FUNCTION_BODY_INDENT + }, + CallExpression: { + arguments: DEFAULT_PARAMETER_INDENT + }, + ArrayExpression: 1, + ObjectExpression: 1 + }; + + const sourceCode = context.getSourceCode(); + + if (context.options.length) { + if (context.options[0] === "tab") { + indentSize = 1; + indentType = "tab"; + } else /* istanbul ignore else : this will be caught by options validation */ if (typeof context.options[0] === "number") { + indentSize = context.options[0]; + indentType = "space"; + } + + if (context.options[1]) { + const opts = context.options[1]; + + options.SwitchCase = opts.SwitchCase || 0; + const variableDeclaratorRules = opts.VariableDeclarator; + + if (typeof variableDeclaratorRules === "number") { + options.VariableDeclarator = { + var: variableDeclaratorRules, + let: variableDeclaratorRules, + const: variableDeclaratorRules + }; + } else if (typeof variableDeclaratorRules === "object") { + Object.assign(options.VariableDeclarator, variableDeclaratorRules); + } + + if (typeof opts.outerIIFEBody === "number") { + options.outerIIFEBody = opts.outerIIFEBody; + } + + if (typeof opts.MemberExpression === "number") { + options.MemberExpression = opts.MemberExpression; + } + + if (typeof opts.FunctionDeclaration === "object") { + Object.assign(options.FunctionDeclaration, opts.FunctionDeclaration); + } + + if (typeof opts.FunctionExpression === "object") { + Object.assign(options.FunctionExpression, opts.FunctionExpression); + } + + if (typeof opts.CallExpression === "object") { + Object.assign(options.CallExpression, opts.CallExpression); + } + + if (typeof opts.ArrayExpression === "number" || typeof opts.ArrayExpression === "string") { + options.ArrayExpression = opts.ArrayExpression; + } + + if (typeof opts.ObjectExpression === "number" || typeof opts.ObjectExpression === "string") { + options.ObjectExpression = opts.ObjectExpression; + } + } + } + + const caseIndentStore = {}; + + /** + * Creates an error message for a line, given the expected/actual indentation. + * @param {int} expectedAmount The expected amount of indentation characters for this line + * @param {int} actualSpaces The actual number of indentation spaces that were found on this line + * @param {int} actualTabs The actual number of indentation tabs that were found on this line + * @returns {string} An error message for this line + */ + function createErrorMessageData(expectedAmount, actualSpaces, actualTabs) { + const expectedStatement = `${expectedAmount} ${indentType}${expectedAmount === 1 ? "" : "s"}`; // e.g. "2 tabs" + const foundSpacesWord = `space${actualSpaces === 1 ? "" : "s"}`; // e.g. "space" + const foundTabsWord = `tab${actualTabs === 1 ? "" : "s"}`; // e.g. "tabs" + let foundStatement; + + if (actualSpaces > 0 && actualTabs > 0) { + foundStatement = `${actualSpaces} ${foundSpacesWord} and ${actualTabs} ${foundTabsWord}`; // e.g. "1 space and 2 tabs" + } else if (actualSpaces > 0) { + + /* + * Abbreviate the message if the expected indentation is also spaces. + * e.g. 'Expected 4 spaces but found 2' rather than 'Expected 4 spaces but found 2 spaces' + */ + foundStatement = indentType === "space" ? actualSpaces : `${actualSpaces} ${foundSpacesWord}`; + } else if (actualTabs > 0) { + foundStatement = indentType === "tab" ? actualTabs : `${actualTabs} ${foundTabsWord}`; + } else { + foundStatement = "0"; + } + return { + expected: expectedStatement, + actual: foundStatement + }; + } + + /** + * Reports a given indent violation + * @param {ASTNode} node Node violating the indent rule + * @param {int} needed Expected indentation character count + * @param {int} gottenSpaces Indentation space count in the actual node/code + * @param {int} gottenTabs Indentation tab count in the actual node/code + * @param {Object} [loc] Error line and column location + * @param {boolean} isLastNodeCheck Is the error for last node check + * @returns {void} + */ + function report(node, needed, gottenSpaces, gottenTabs, loc, isLastNodeCheck) { + if (gottenSpaces && gottenTabs) { + + // To avoid conflicts with `no-mixed-spaces-and-tabs`, don't report lines that have both spaces and tabs. + return; + } + + const desiredIndent = (indentType === "space" ? " " : "\t").repeat(needed); + + const textRange = isLastNodeCheck + ? [node.range[1] - node.loc.end.column, node.range[1] - node.loc.end.column + gottenSpaces + gottenTabs] + : [node.range[0] - node.loc.start.column, node.range[0] - node.loc.start.column + gottenSpaces + gottenTabs]; + + context.report({ + node, + loc, + messageId: "expected", + data: createErrorMessageData(needed, gottenSpaces, gottenTabs), + fix: fixer => fixer.replaceTextRange(textRange, desiredIndent) + }); + } + + /** + * Get the actual indent of node + * @param {ASTNode|Token} node Node to examine + * @param {boolean} [byLastLine=false] get indent of node's last line + * @returns {Object} The node's indent. Contains keys `space` and `tab`, representing the indent of each character. Also + * contains keys `goodChar` and `badChar`, where `goodChar` is the amount of the user's desired indentation character, and + * `badChar` is the amount of the other indentation character. + */ + function getNodeIndent(node, byLastLine) { + const token = byLastLine ? sourceCode.getLastToken(node) : sourceCode.getFirstToken(node); + const srcCharsBeforeNode = sourceCode.getText(token, token.loc.start.column).split(""); + const indentChars = srcCharsBeforeNode.slice(0, srcCharsBeforeNode.findIndex(char => char !== " " && char !== "\t")); + const spaces = indentChars.filter(char => char === " ").length; + const tabs = indentChars.filter(char => char === "\t").length; + + return { + space: spaces, + tab: tabs, + goodChar: indentType === "space" ? spaces : tabs, + badChar: indentType === "space" ? tabs : spaces + }; + } + + /** + * Checks node is the first in its own start line. By default it looks by start line. + * @param {ASTNode} node The node to check + * @param {boolean} [byEndLocation=false] Lookup based on start position or end + * @returns {boolean} true if its the first in the its start line + */ + function isNodeFirstInLine(node, byEndLocation) { + const firstToken = byEndLocation === true ? sourceCode.getLastToken(node, 1) : sourceCode.getTokenBefore(node), + startLine = byEndLocation === true ? node.loc.end.line : node.loc.start.line, + endLine = firstToken ? firstToken.loc.end.line : -1; + + return startLine !== endLine; + } + + /** + * Check indent for node + * @param {ASTNode} node Node to check + * @param {int} neededIndent needed indent + * @returns {void} + */ + function checkNodeIndent(node, neededIndent) { + const actualIndent = getNodeIndent(node, false); + + if ( + node.type !== "ArrayExpression" && + node.type !== "ObjectExpression" && + (actualIndent.goodChar !== neededIndent || actualIndent.badChar !== 0) && + isNodeFirstInLine(node) + ) { + report(node, neededIndent, actualIndent.space, actualIndent.tab); + } + + if (node.type === "IfStatement" && node.alternate) { + const elseToken = sourceCode.getTokenBefore(node.alternate); + + checkNodeIndent(elseToken, neededIndent); + + if (!isNodeFirstInLine(node.alternate)) { + checkNodeIndent(node.alternate, neededIndent); + } + } + + if (node.type === "TryStatement" && node.handler) { + const catchToken = sourceCode.getFirstToken(node.handler); + + checkNodeIndent(catchToken, neededIndent); + } + + if (node.type === "TryStatement" && node.finalizer) { + const finallyToken = sourceCode.getTokenBefore(node.finalizer); + + checkNodeIndent(finallyToken, neededIndent); + } + + if (node.type === "DoWhileStatement") { + const whileToken = sourceCode.getTokenAfter(node.body); + + checkNodeIndent(whileToken, neededIndent); + } + } + + /** + * Check indent for nodes list + * @param {ASTNode[]} nodes list of node objects + * @param {int} indent needed indent + * @returns {void} + */ + function checkNodesIndent(nodes, indent) { + nodes.forEach(node => checkNodeIndent(node, indent)); + } + + /** + * Check last node line indent this detects, that block closed correctly + * @param {ASTNode} node Node to examine + * @param {int} lastLineIndent needed indent + * @returns {void} + */ + function checkLastNodeLineIndent(node, lastLineIndent) { + const lastToken = sourceCode.getLastToken(node); + const endIndent = getNodeIndent(lastToken, true); + + if ((endIndent.goodChar !== lastLineIndent || endIndent.badChar !== 0) && isNodeFirstInLine(node, true)) { + report( + node, + lastLineIndent, + endIndent.space, + endIndent.tab, + { line: lastToken.loc.start.line, column: lastToken.loc.start.column }, + true + ); + } + } + + /** + * Check last node line indent this detects, that block closed correctly + * This function for more complicated return statement case, where closing parenthesis may be followed by ';' + * @param {ASTNode} node Node to examine + * @param {int} firstLineIndent first line needed indent + * @returns {void} + */ + function checkLastReturnStatementLineIndent(node, firstLineIndent) { + + /* + * in case if return statement ends with ');' we have traverse back to ')' + * otherwise we'll measure indent for ';' and replace ')' + */ + const lastToken = sourceCode.getLastToken(node, astUtils.isClosingParenToken); + const textBeforeClosingParenthesis = sourceCode.getText(lastToken, lastToken.loc.start.column).slice(0, -1); + + if (textBeforeClosingParenthesis.trim()) { + + // There are tokens before the closing paren, don't report this case + return; + } + + const endIndent = getNodeIndent(lastToken, true); + + if (endIndent.goodChar !== firstLineIndent) { + report( + node, + firstLineIndent, + endIndent.space, + endIndent.tab, + { line: lastToken.loc.start.line, column: lastToken.loc.start.column }, + true + ); + } + } + + /** + * Check first node line indent is correct + * @param {ASTNode} node Node to examine + * @param {int} firstLineIndent needed indent + * @returns {void} + */ + function checkFirstNodeLineIndent(node, firstLineIndent) { + const startIndent = getNodeIndent(node, false); + + if ((startIndent.goodChar !== firstLineIndent || startIndent.badChar !== 0) && isNodeFirstInLine(node)) { + report( + node, + firstLineIndent, + startIndent.space, + startIndent.tab, + { line: node.loc.start.line, column: node.loc.start.column } + ); + } + } + + /** + * Returns a parent node of given node based on a specified type + * if not present then return null + * @param {ASTNode} node node to examine + * @param {string} type type that is being looked for + * @param {string} stopAtList end points for the evaluating code + * @returns {ASTNode|void} if found then node otherwise null + */ + function getParentNodeByType(node, type, stopAtList) { + let parent = node.parent; + const stopAtSet = new Set(stopAtList || ["Program"]); + + while (parent.type !== type && !stopAtSet.has(parent.type) && parent.type !== "Program") { + parent = parent.parent; + } + + return parent.type === type ? parent : null; + } + + /** + * Returns the VariableDeclarator based on the current node + * if not present then return null + * @param {ASTNode} node node to examine + * @returns {ASTNode|void} if found then node otherwise null + */ + function getVariableDeclaratorNode(node) { + return getParentNodeByType(node, "VariableDeclarator"); + } + + /** + * Check to see if the node is part of the multi-line variable declaration. + * Also if its on the same line as the varNode + * @param {ASTNode} node node to check + * @param {ASTNode} varNode variable declaration node to check against + * @returns {boolean} True if all the above condition satisfy + */ + function isNodeInVarOnTop(node, varNode) { + return varNode && + varNode.parent.loc.start.line === node.loc.start.line && + varNode.parent.declarations.length > 1; + } + + /** + * Check to see if the argument before the callee node is multi-line and + * there should only be 1 argument before the callee node + * @param {ASTNode} node node to check + * @returns {boolean} True if arguments are multi-line + */ + function isArgBeforeCalleeNodeMultiline(node) { + const parent = node.parent; + + if (parent.arguments.length >= 2 && parent.arguments[1] === node) { + return parent.arguments[0].loc.end.line > parent.arguments[0].loc.start.line; + } + + return false; + } + + /** + * Check to see if the node is a file level IIFE + * @param {ASTNode} node The function node to check. + * @returns {boolean} True if the node is the outer IIFE + */ + function isOuterIIFE(node) { + const parent = node.parent; + let stmt = parent.parent; + + /* + * Verify that the node is an IIEF + */ + if ( + parent.type !== "CallExpression" || + parent.callee !== node) { + + return false; + } + + /* + * Navigate legal ancestors to determine whether this IIEF is outer + */ + while ( + stmt.type === "UnaryExpression" && ( + stmt.operator === "!" || + stmt.operator === "~" || + stmt.operator === "+" || + stmt.operator === "-") || + stmt.type === "AssignmentExpression" || + stmt.type === "LogicalExpression" || + stmt.type === "SequenceExpression" || + stmt.type === "VariableDeclarator") { + + stmt = stmt.parent; + } + + return (( + stmt.type === "ExpressionStatement" || + stmt.type === "VariableDeclaration") && + stmt.parent && stmt.parent.type === "Program" + ); + } + + /** + * Check indent for function block content + * @param {ASTNode} node A BlockStatement node that is inside of a function. + * @returns {void} + */ + function checkIndentInFunctionBlock(node) { + + /* + * Search first caller in chain. + * Ex.: + * + * Models <- Identifier + * .User + * .find() + * .exec(function() { + * // function body + * }); + * + * Looks for 'Models' + */ + const calleeNode = node.parent; // FunctionExpression + let indent; + + if (calleeNode.parent && + (calleeNode.parent.type === "Property" || + calleeNode.parent.type === "ArrayExpression")) { + + // If function is part of array or object, comma can be put at left + indent = getNodeIndent(calleeNode, false).goodChar; + } else { + + // If function is standalone, simple calculate indent + indent = getNodeIndent(calleeNode).goodChar; + } + + if (calleeNode.parent.type === "CallExpression") { + const calleeParent = calleeNode.parent; + + if (calleeNode.type !== "FunctionExpression" && calleeNode.type !== "ArrowFunctionExpression") { + if (calleeParent && calleeParent.loc.start.line < node.loc.start.line) { + indent = getNodeIndent(calleeParent).goodChar; + } + } else { + if (isArgBeforeCalleeNodeMultiline(calleeNode) && + calleeParent.callee.loc.start.line === calleeParent.callee.loc.end.line && + !isNodeFirstInLine(calleeNode)) { + indent = getNodeIndent(calleeParent).goodChar; + } + } + } + + /* + * function body indent should be indent + indent size, unless this + * is a FunctionDeclaration, FunctionExpression, or outer IIFE and the corresponding options are enabled. + */ + let functionOffset = indentSize; + + if (options.outerIIFEBody !== null && isOuterIIFE(calleeNode)) { + functionOffset = options.outerIIFEBody * indentSize; + } else if (calleeNode.type === "FunctionExpression") { + functionOffset = options.FunctionExpression.body * indentSize; + } else if (calleeNode.type === "FunctionDeclaration") { + functionOffset = options.FunctionDeclaration.body * indentSize; + } + indent += functionOffset; + + // check if the node is inside a variable + const parentVarNode = getVariableDeclaratorNode(node); + + if (parentVarNode && isNodeInVarOnTop(node, parentVarNode)) { + indent += indentSize * options.VariableDeclarator[parentVarNode.parent.kind]; + } + + if (node.body.length > 0) { + checkNodesIndent(node.body, indent); + } + + checkLastNodeLineIndent(node, indent - functionOffset); + } + + + /** + * Checks if the given node starts and ends on the same line + * @param {ASTNode} node The node to check + * @returns {boolean} Whether or not the block starts and ends on the same line. + */ + function isSingleLineNode(node) { + const lastToken = sourceCode.getLastToken(node), + startLine = node.loc.start.line, + endLine = lastToken.loc.end.line; + + return startLine === endLine; + } + + /** + * Check indent for array block content or object block content + * @param {ASTNode} node node to examine + * @returns {void} + */ + function checkIndentInArrayOrObjectBlock(node) { + + // Skip inline + if (isSingleLineNode(node)) { + return; + } + + let elements = (node.type === "ArrayExpression") ? node.elements : node.properties; + + // filter out empty elements example would be [ , 2] so remove first element as espree considers it as null + elements = elements.filter(elem => elem !== null); + + let nodeIndent; + let elementsIndent; + const parentVarNode = getVariableDeclaratorNode(node); + + // TODO - come up with a better strategy in future + if (isNodeFirstInLine(node)) { + const parent = node.parent; + + nodeIndent = getNodeIndent(parent).goodChar; + if (!parentVarNode || parentVarNode.loc.start.line !== node.loc.start.line) { + if (parent.type !== "VariableDeclarator" || parentVarNode === parentVarNode.parent.declarations[0]) { + if (parent.type === "VariableDeclarator" && parentVarNode.loc.start.line === parent.loc.start.line) { + nodeIndent += (indentSize * options.VariableDeclarator[parentVarNode.parent.kind]); + } else if (parent.type === "ObjectExpression" || parent.type === "ArrayExpression") { + const parentElements = node.parent.type === "ObjectExpression" ? node.parent.properties : node.parent.elements; + + if (parentElements[0] && + parentElements[0].loc.start.line === parent.loc.start.line && + parentElements[0].loc.end.line !== parent.loc.start.line) ; else if (typeof options[parent.type] === "number") { + nodeIndent += options[parent.type] * indentSize; + } else { + nodeIndent = parentElements[0].loc.start.column; + } + } else if (parent.type === "CallExpression" || parent.type === "NewExpression") { + if (typeof options.CallExpression.arguments === "number") { + nodeIndent += options.CallExpression.arguments * indentSize; + } else if (options.CallExpression.arguments === "first") { + if (parent.arguments.indexOf(node) !== -1) { + nodeIndent = parent.arguments[0].loc.start.column; + } + } else { + nodeIndent += indentSize; + } + } else if (parent.type === "LogicalExpression" || parent.type === "ArrowFunctionExpression") { + nodeIndent += indentSize; + } + } + } + + checkFirstNodeLineIndent(node, nodeIndent); + } else { + nodeIndent = getNodeIndent(node).goodChar; + } + + if (options[node.type] === "first") { + elementsIndent = elements.length ? elements[0].loc.start.column : 0; // If there are no elements, elementsIndent doesn't matter. + } else { + elementsIndent = nodeIndent + indentSize * options[node.type]; + } + + /* + * Check if the node is a multiple variable declaration; if so, then + * make sure indentation takes that into account. + */ + if (isNodeInVarOnTop(node, parentVarNode)) { + elementsIndent += indentSize * options.VariableDeclarator[parentVarNode.parent.kind]; + } + + checkNodesIndent(elements, elementsIndent); + + if (elements.length > 0) { + + // Skip last block line check if last item in same line + if (elements[elements.length - 1].loc.end.line === node.loc.end.line) { + return; + } + } + + checkLastNodeLineIndent(node, nodeIndent + + (isNodeInVarOnTop(node, parentVarNode) ? options.VariableDeclarator[parentVarNode.parent.kind] * indentSize : 0)); + } + + /** + * Check if the node or node body is a BlockStatement or not + * @param {ASTNode} node node to test + * @returns {boolean} True if it or its body is a block statement + */ + function isNodeBodyBlock(node) { + return node.type === "BlockStatement" || node.type === "ClassBody" || (node.body && node.body.type === "BlockStatement") || + (node.consequent && node.consequent.type === "BlockStatement"); + } + + /** + * Check indentation for blocks + * @param {ASTNode} node node to check + * @returns {void} + */ + function blockIndentationCheck(node) { + + // Skip inline blocks + if (isSingleLineNode(node)) { + return; + } + + if (node.parent && ( + node.parent.type === "FunctionExpression" || + node.parent.type === "FunctionDeclaration" || + node.parent.type === "ArrowFunctionExpression") + ) { + checkIndentInFunctionBlock(node); + return; + } + + let indent; + let nodesToCheck = []; + + /* + * For this statements we should check indent from statement beginning, + * not from the beginning of the block. + */ + const statementsWithProperties = [ + "IfStatement", "WhileStatement", "ForStatement", "ForInStatement", "ForOfStatement", "DoWhileStatement", "ClassDeclaration", "TryStatement" + ]; + + if (node.parent && statementsWithProperties.indexOf(node.parent.type) !== -1 && isNodeBodyBlock(node)) { + indent = getNodeIndent(node.parent).goodChar; + } else if (node.parent && node.parent.type === "CatchClause") { + indent = getNodeIndent(node.parent.parent).goodChar; + } else { + indent = getNodeIndent(node).goodChar; + } + + if (node.type === "IfStatement" && node.consequent.type !== "BlockStatement") { + nodesToCheck = [node.consequent]; + } else if (Array.isArray(node.body)) { + nodesToCheck = node.body; + } else { + nodesToCheck = [node.body]; + } + + if (nodesToCheck.length > 0) { + checkNodesIndent(nodesToCheck, indent + indentSize); + } + + if (node.type === "BlockStatement") { + checkLastNodeLineIndent(node, indent); + } + } + + /** + * Filter out the elements which are on the same line of each other or the node. + * basically have only 1 elements from each line except the variable declaration line. + * @param {ASTNode} node Variable declaration node + * @returns {ASTNode[]} Filtered elements + */ + function filterOutSameLineVars(node) { + return node.declarations.reduce((finalCollection, elem) => { + const lastElem = finalCollection[finalCollection.length - 1]; + + if ((elem.loc.start.line !== node.loc.start.line && !lastElem) || + (lastElem && lastElem.loc.start.line !== elem.loc.start.line)) { + finalCollection.push(elem); + } + + return finalCollection; + }, []); + } + + /** + * Check indentation for variable declarations + * @param {ASTNode} node node to examine + * @returns {void} + */ + function checkIndentInVariableDeclarations(node) { + const elements = filterOutSameLineVars(node); + const nodeIndent = getNodeIndent(node).goodChar; + const lastElement = elements[elements.length - 1]; + + const elementsIndent = nodeIndent + indentSize * options.VariableDeclarator[node.kind]; + + checkNodesIndent(elements, elementsIndent); + + // Only check the last line if there is any token after the last item + if (sourceCode.getLastToken(node).loc.end.line <= lastElement.loc.end.line) { + return; + } + + const tokenBeforeLastElement = sourceCode.getTokenBefore(lastElement); + + if (tokenBeforeLastElement.value === ",") { + + // Special case for comma-first syntax where the semicolon is indented + checkLastNodeLineIndent(node, getNodeIndent(tokenBeforeLastElement).goodChar); + } else { + checkLastNodeLineIndent(node, elementsIndent - indentSize); + } + } + + /** + * Check and decide whether to check for indentation for blockless nodes + * Scenarios are for or while statements without braces around them + * @param {ASTNode} node node to examine + * @returns {void} + */ + function blockLessNodes(node) { + if (node.body.type !== "BlockStatement") { + blockIndentationCheck(node); + } + } + + /** + * Returns the expected indentation for the case statement + * @param {ASTNode} node node to examine + * @param {int} [providedSwitchIndent] indent for switch statement + * @returns {int} indent size + */ + function expectedCaseIndent(node, providedSwitchIndent) { + const switchNode = (node.type === "SwitchStatement") ? node : node.parent; + const switchIndent = typeof providedSwitchIndent === "undefined" + ? getNodeIndent(switchNode).goodChar + : providedSwitchIndent; + let caseIndent; + + if (caseIndentStore[switchNode.loc.start.line]) { + return caseIndentStore[switchNode.loc.start.line]; + } + + if (switchNode.cases.length > 0 && options.SwitchCase === 0) { + caseIndent = switchIndent; + } else { + caseIndent = switchIndent + (indentSize * options.SwitchCase); + } + + caseIndentStore[switchNode.loc.start.line] = caseIndent; + return caseIndent; + + } + + /** + * Checks whether a return statement is wrapped in () + * @param {ASTNode} node node to examine + * @returns {boolean} the result + */ + function isWrappedInParenthesis(node) { + const regex = /^return\s*?\(\s*?\);*?/u; + + const statementWithoutArgument = sourceCode.getText(node).replace( + sourceCode.getText(node.argument), "" + ); + + return regex.test(statementWithoutArgument); + } + + return { + Program(node) { + if (node.body.length > 0) { + + // Root nodes should have no indent + checkNodesIndent(node.body, getNodeIndent(node).goodChar); + } + }, + + ClassBody: blockIndentationCheck, + + BlockStatement: blockIndentationCheck, + + WhileStatement: blockLessNodes, + + ForStatement: blockLessNodes, + + ForInStatement: blockLessNodes, + + ForOfStatement: blockLessNodes, + + DoWhileStatement: blockLessNodes, + + IfStatement(node) { + if (node.consequent.type !== "BlockStatement" && node.consequent.loc.start.line > node.loc.start.line) { + blockIndentationCheck(node); + } + }, + + VariableDeclaration(node) { + if (node.declarations[node.declarations.length - 1].loc.start.line > node.declarations[0].loc.start.line) { + checkIndentInVariableDeclarations(node); + } + }, + + ObjectExpression(node) { + checkIndentInArrayOrObjectBlock(node); + }, + + ArrayExpression(node) { + checkIndentInArrayOrObjectBlock(node); + }, + + MemberExpression(node) { + + if (typeof options.MemberExpression === "undefined") { + return; + } + + if (isSingleLineNode(node)) { + return; + } + + /* + * The typical layout of variable declarations and assignments + * alter the expectation of correct indentation. Skip them. + * TODO: Add appropriate configuration options for variable + * declarations and assignments. + */ + if (getParentNodeByType(node, "VariableDeclarator", ["FunctionExpression", "ArrowFunctionExpression"])) { + return; + } + + if (getParentNodeByType(node, "AssignmentExpression", ["FunctionExpression"])) { + return; + } + + const propertyIndent = getNodeIndent(node).goodChar + indentSize * options.MemberExpression; + + const checkNodes = [node.property]; + + const dot = sourceCode.getTokenBefore(node.property); + + if (dot.type === "Punctuator" && dot.value === ".") { + checkNodes.push(dot); + } + + checkNodesIndent(checkNodes, propertyIndent); + }, + + SwitchStatement(node) { + + // Switch is not a 'BlockStatement' + const switchIndent = getNodeIndent(node).goodChar; + const caseIndent = expectedCaseIndent(node, switchIndent); + + checkNodesIndent(node.cases, caseIndent); + + + checkLastNodeLineIndent(node, switchIndent); + }, + + SwitchCase(node) { + + // Skip inline cases + if (isSingleLineNode(node)) { + return; + } + const caseIndent = expectedCaseIndent(node); + + checkNodesIndent(node.consequent, caseIndent + indentSize); + }, + + FunctionDeclaration(node) { + if (isSingleLineNode(node)) { + return; + } + if (options.FunctionDeclaration.parameters === "first" && node.params.length) { + checkNodesIndent(node.params.slice(1), node.params[0].loc.start.column); + } else if (options.FunctionDeclaration.parameters !== null) { + checkNodesIndent(node.params, getNodeIndent(node).goodChar + indentSize * options.FunctionDeclaration.parameters); + } + }, + + FunctionExpression(node) { + if (isSingleLineNode(node)) { + return; + } + if (options.FunctionExpression.parameters === "first" && node.params.length) { + checkNodesIndent(node.params.slice(1), node.params[0].loc.start.column); + } else if (options.FunctionExpression.parameters !== null) { + checkNodesIndent(node.params, getNodeIndent(node).goodChar + indentSize * options.FunctionExpression.parameters); + } + }, + + ReturnStatement(node) { + if (isSingleLineNode(node)) { + return; + } + + const firstLineIndent = getNodeIndent(node).goodChar; + + // in case if return statement is wrapped in parenthesis + if (isWrappedInParenthesis(node)) { + checkLastReturnStatementLineIndent(node, firstLineIndent); + } else { + checkNodeIndent(node, firstLineIndent); + } + }, + + CallExpression(node) { + if (isSingleLineNode(node)) { + return; + } + if (options.CallExpression.arguments === "first" && node.arguments.length) { + checkNodesIndent(node.arguments.slice(1), node.arguments[0].loc.start.column); + } else if (options.CallExpression.arguments !== null) { + checkNodesIndent(node.arguments, getNodeIndent(node).goodChar + indentSize * options.CallExpression.arguments); + } + } + + }; + + } +}; + +/** + * @fileoverview A rule to control the style of variable initializations. + * @author Colin Ihrig + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a given node is a for loop. + * @param {ASTNode} block A node to check. + * @returns {boolean} `true` when the node is a for loop. + */ +function isForLoop(block) { + return block.type === "ForInStatement" || + block.type === "ForOfStatement" || + block.type === "ForStatement"; +} + +/** + * Checks whether or not a given declarator node has its initializer. + * @param {ASTNode} node A declarator node to check. + * @returns {boolean} `true` when the node has its initializer. + */ +function isInitialized$1(node) { + const declaration = node.parent; + const block = declaration.parent; + + if (isForLoop(block)) { + if (block.type === "ForStatement") { + return block.init === declaration; + } + return block.left === declaration; + } + return Boolean(node.init); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var initDeclarations = { + meta: { + type: "suggestion", + + docs: { + description: "require or disallow initialization in variable declarations", + category: "Variables", + recommended: false, + url: "https://eslint.org/docs/rules/init-declarations" + }, + + schema: { + anyOf: [ + { + type: "array", + items: [ + { + enum: ["always"] + } + ], + minItems: 0, + maxItems: 1 + }, + { + type: "array", + items: [ + { + enum: ["never"] + }, + { + type: "object", + properties: { + ignoreForLoopInit: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + minItems: 0, + maxItems: 2 + } + ] + }, + messages: { + initialized: "Variable '{{idName}}' should be initialized on declaration.", + notInitialized: "Variable '{{idName}}' should not be initialized on declaration." + } + }, + + create(context) { + + const MODE_ALWAYS = "always", + MODE_NEVER = "never"; + + const mode = context.options[0] || MODE_ALWAYS; + const params = context.options[1] || {}; + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + "VariableDeclaration:exit"(node) { + + const kind = node.kind, + declarations = node.declarations; + + for (let i = 0; i < declarations.length; ++i) { + const declaration = declarations[i], + id = declaration.id, + initialized = isInitialized$1(declaration), + isIgnoredForLoop = params.ignoreForLoopInit && isForLoop(node.parent); + let messageId = ""; + + if (mode === MODE_ALWAYS && !initialized) { + messageId = "initialized"; + } else if (mode === MODE_NEVER && kind !== "const" && initialized && !isIgnoredForLoop) { + messageId = "notInitialized"; + } + + if (id.type === "Identifier" && messageId) { + context.report({ + node: declaration, + messageId, + data: { + idName: id.name + } + }); + } + } + } + }; + } +}; + +/** + * @fileoverview A rule to ensure consistent quotes used in jsx syntax. + * @author Mathias Schreck + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Constants +//------------------------------------------------------------------------------ + +const QUOTE_SETTINGS$1 = { + "prefer-double": { + quote: "\"", + description: "singlequote", + convert(str) { + return str.replace(/'/gu, "\""); + } + }, + "prefer-single": { + quote: "'", + description: "doublequote", + convert(str) { + return str.replace(/"/gu, "'"); + } + } +}; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var jsxQuotes = { + meta: { + type: "layout", + + docs: { + description: "enforce the consistent use of either double or single quotes in JSX attributes", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/jsx-quotes" + }, + + fixable: "whitespace", + + schema: [ + { + enum: ["prefer-single", "prefer-double"] + } + ], + messages: { + unexpected: "Unexpected usage of {{description}}." + } + }, + + create(context) { + const quoteOption = context.options[0] || "prefer-double", + setting = QUOTE_SETTINGS$1[quoteOption]; + + /** + * Checks if the given string literal node uses the expected quotes + * @param {ASTNode} node A string literal node. + * @returns {boolean} Whether or not the string literal used the expected quotes. + * @public + */ + function usesExpectedQuotes(node) { + return node.value.indexOf(setting.quote) !== -1 || astUtils.isSurroundedBy(node.raw, setting.quote); + } + + return { + JSXAttribute(node) { + const attributeValue = node.value; + + if (attributeValue && astUtils.isStringLiteral(attributeValue) && !usesExpectedQuotes(attributeValue)) { + context.report({ + node: attributeValue, + messageId: "unexpected", + data: { + description: setting.description + }, + fix(fixer) { + return fixer.replaceText(attributeValue, setting.convert(attributeValue.raw)); + } + }); + } + } + }; + } +}; + +/** + * @fileoverview Rule to specify spacing of object literal keys and values + * @author Brandon Mills + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether a string contains a line terminator as defined in + * http://www.ecma-international.org/ecma-262/5.1/#sec-7.3 + * @param {string} str String to test. + * @returns {boolean} True if str contains a line terminator. + */ +function containsLineTerminator(str) { + return astUtils.LINEBREAK_MATCHER.test(str); +} + +/** + * Gets the last element of an array. + * @param {Array} arr An array. + * @returns {any} Last element of arr. + */ +function last(arr) { + return arr[arr.length - 1]; +} + +/** + * Checks whether a node is contained on a single line. + * @param {ASTNode} node AST Node being evaluated. + * @returns {boolean} True if the node is a single line. + */ +function isSingleLine(node) { + return (node.loc.end.line === node.loc.start.line); +} + +/** + * Checks whether the properties on a single line. + * @param {ASTNode[]} properties List of Property AST nodes. + * @returns {boolean} True if all properties is on a single line. + */ +function isSingleLineProperties(properties) { + const [firstProp] = properties, + lastProp = last(properties); + + return firstProp.loc.start.line === lastProp.loc.end.line; +} + +/** + * Initializes a single option property from the configuration with defaults for undefined values + * @param {Object} toOptions Object to be initialized + * @param {Object} fromOptions Object to be initialized from + * @returns {Object} The object with correctly initialized options and values + */ +function initOptionProperty(toOptions, fromOptions) { + toOptions.mode = fromOptions.mode || "strict"; + + // Set value of beforeColon + if (typeof fromOptions.beforeColon !== "undefined") { + toOptions.beforeColon = +fromOptions.beforeColon; + } else { + toOptions.beforeColon = 0; + } + + // Set value of afterColon + if (typeof fromOptions.afterColon !== "undefined") { + toOptions.afterColon = +fromOptions.afterColon; + } else { + toOptions.afterColon = 1; + } + + // Set align if exists + if (typeof fromOptions.align !== "undefined") { + if (typeof fromOptions.align === "object") { + toOptions.align = fromOptions.align; + } else { // "string" + toOptions.align = { + on: fromOptions.align, + mode: toOptions.mode, + beforeColon: toOptions.beforeColon, + afterColon: toOptions.afterColon + }; + } + } + + return toOptions; +} + +/** + * Initializes all the option values (singleLine, multiLine and align) from the configuration with defaults for undefined values + * @param {Object} toOptions Object to be initialized + * @param {Object} fromOptions Object to be initialized from + * @returns {Object} The object with correctly initialized options and values + */ +function initOptions(toOptions, fromOptions) { + if (typeof fromOptions.align === "object") { + + // Initialize the alignment configuration + toOptions.align = initOptionProperty({}, fromOptions.align); + toOptions.align.on = fromOptions.align.on || "colon"; + toOptions.align.mode = fromOptions.align.mode || "strict"; + + toOptions.multiLine = initOptionProperty({}, (fromOptions.multiLine || fromOptions)); + toOptions.singleLine = initOptionProperty({}, (fromOptions.singleLine || fromOptions)); + + } else { // string or undefined + toOptions.multiLine = initOptionProperty({}, (fromOptions.multiLine || fromOptions)); + toOptions.singleLine = initOptionProperty({}, (fromOptions.singleLine || fromOptions)); + + // If alignment options are defined in multiLine, pull them out into the general align configuration + if (toOptions.multiLine.align) { + toOptions.align = { + on: toOptions.multiLine.align.on, + mode: toOptions.multiLine.align.mode || toOptions.multiLine.mode, + beforeColon: toOptions.multiLine.align.beforeColon, + afterColon: toOptions.multiLine.align.afterColon + }; + } + } + + return toOptions; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var keySpacing = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent spacing between keys and values in object literal properties", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/key-spacing" + }, + + fixable: "whitespace", + + schema: [{ + anyOf: [ + { + type: "object", + properties: { + align: { + anyOf: [ + { + enum: ["colon", "value"] + }, + { + type: "object", + properties: { + mode: { + enum: ["strict", "minimum"] + }, + on: { + enum: ["colon", "value"] + }, + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + mode: { + enum: ["strict", "minimum"] + }, + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + }, + { + type: "object", + properties: { + singleLine: { + type: "object", + properties: { + mode: { + enum: ["strict", "minimum"] + }, + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + }, + multiLine: { + type: "object", + properties: { + align: { + anyOf: [ + { + enum: ["colon", "value"] + }, + { + type: "object", + properties: { + mode: { + enum: ["strict", "minimum"] + }, + on: { + enum: ["colon", "value"] + }, + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + mode: { + enum: ["strict", "minimum"] + }, + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + } + }, + additionalProperties: false + }, + { + type: "object", + properties: { + singleLine: { + type: "object", + properties: { + mode: { + enum: ["strict", "minimum"] + }, + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + }, + multiLine: { + type: "object", + properties: { + mode: { + enum: ["strict", "minimum"] + }, + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + }, + align: { + type: "object", + properties: { + mode: { + enum: ["strict", "minimum"] + }, + on: { + enum: ["colon", "value"] + }, + beforeColon: { + type: "boolean" + }, + afterColon: { + type: "boolean" + } + }, + additionalProperties: false + } + }, + additionalProperties: false + } + ] + }], + messages: { + extraKey: "Extra space after {{computed}}key '{{key}}'.", + extraValue: "Extra space before value for {{computed}}key '{{key}}'.", + missingKey: "Missing space after {{computed}}key '{{key}}'.", + missingValue: "Missing space before value for {{computed}}key '{{key}}'." + } + }, + + create(context) { + + /** + * OPTIONS + * "key-spacing": [2, { + * beforeColon: false, + * afterColon: true, + * align: "colon" // Optional, or "value" + * } + */ + const options = context.options[0] || {}, + ruleOptions = initOptions({}, options), + multiLineOptions = ruleOptions.multiLine, + singleLineOptions = ruleOptions.singleLine, + alignmentOptions = ruleOptions.align || null; + + const sourceCode = context.getSourceCode(); + + /** + * Checks whether a property is a member of the property group it follows. + * @param {ASTNode} lastMember The last Property known to be in the group. + * @param {ASTNode} candidate The next Property that might be in the group. + * @returns {boolean} True if the candidate property is part of the group. + */ + function continuesPropertyGroup(lastMember, candidate) { + const groupEndLine = lastMember.loc.start.line, + candidateStartLine = candidate.loc.start.line; + + if (candidateStartLine - groupEndLine <= 1) { + return true; + } + + /* + * Check that the first comment is adjacent to the end of the group, the + * last comment is adjacent to the candidate property, and that successive + * comments are adjacent to each other. + */ + const leadingComments = sourceCode.getCommentsBefore(candidate); + + if ( + leadingComments.length && + leadingComments[0].loc.start.line - groupEndLine <= 1 && + candidateStartLine - last(leadingComments).loc.end.line <= 1 + ) { + for (let i = 1; i < leadingComments.length; i++) { + if (leadingComments[i].loc.start.line - leadingComments[i - 1].loc.end.line > 1) { + return false; + } + } + return true; + } + + return false; + } + + /** + * Determines if the given property is key-value property. + * @param {ASTNode} property Property node to check. + * @returns {boolean} Whether the property is a key-value property. + */ + function isKeyValueProperty(property) { + return !( + (property.method || + property.shorthand || + property.kind !== "init" || property.type !== "Property") // Could be "ExperimentalSpreadProperty" or "SpreadElement" + ); + } + + /** + * Starting from the given a node (a property.key node here) looks forward + * until it finds the last token before a colon punctuator and returns it. + * @param {ASTNode} node The node to start looking from. + * @returns {ASTNode} The last token before a colon punctuator. + */ + function getLastTokenBeforeColon(node) { + const colonToken = sourceCode.getTokenAfter(node, astUtils.isColonToken); + + return sourceCode.getTokenBefore(colonToken); + } + + /** + * Starting from the given a node (a property.key node here) looks forward + * until it finds the colon punctuator and returns it. + * @param {ASTNode} node The node to start looking from. + * @returns {ASTNode} The colon punctuator. + */ + function getNextColon(node) { + return sourceCode.getTokenAfter(node, astUtils.isColonToken); + } + + /** + * Gets an object literal property's key as the identifier name or string value. + * @param {ASTNode} property Property node whose key to retrieve. + * @returns {string} The property's key. + */ + function getKey(property) { + const key = property.key; + + if (property.computed) { + return sourceCode.getText().slice(key.range[0], key.range[1]); + } + return astUtils.getStaticPropertyName(property); + } + + /** + * Reports an appropriately-formatted error if spacing is incorrect on one + * side of the colon. + * @param {ASTNode} property Key-value pair in an object literal. + * @param {string} side Side being verified - either "key" or "value". + * @param {string} whitespace Actual whitespace string. + * @param {int} expected Expected whitespace length. + * @param {string} mode Value of the mode as "strict" or "minimum" + * @returns {void} + */ + function report(property, side, whitespace, expected, mode) { + const diff = whitespace.length - expected, + nextColon = getNextColon(property.key), + tokenBeforeColon = sourceCode.getTokenBefore(nextColon, { includeComments: true }), + tokenAfterColon = sourceCode.getTokenAfter(nextColon, { includeComments: true }), + isKeySide = side === "key", + isExtra = diff > 0, + diffAbs = Math.abs(diff), + spaces = Array(diffAbs + 1).join(" "); + + const locStart = isKeySide ? tokenBeforeColon.loc.end : nextColon.loc.start; + const locEnd = isKeySide ? nextColon.loc.start : tokenAfterColon.loc.start; + const missingLoc = isKeySide ? tokenBeforeColon.loc : tokenAfterColon.loc; + const loc = isExtra ? { start: locStart, end: locEnd } : missingLoc; + + if (( + diff && mode === "strict" || + diff < 0 && mode === "minimum" || + diff > 0 && !expected && mode === "minimum") && + !(expected && containsLineTerminator(whitespace)) + ) { + let fix; + + if (isExtra) { + let range; + + // Remove whitespace + if (isKeySide) { + range = [tokenBeforeColon.range[1], tokenBeforeColon.range[1] + diffAbs]; + } else { + range = [tokenAfterColon.range[0] - diffAbs, tokenAfterColon.range[0]]; + } + fix = function(fixer) { + return fixer.removeRange(range); + }; + } else { + + // Add whitespace + if (isKeySide) { + fix = function(fixer) { + return fixer.insertTextAfter(tokenBeforeColon, spaces); + }; + } else { + fix = function(fixer) { + return fixer.insertTextBefore(tokenAfterColon, spaces); + }; + } + } + + let messageId = ""; + + if (isExtra) { + messageId = side === "key" ? "extraKey" : "extraValue"; + } else { + messageId = side === "key" ? "missingKey" : "missingValue"; + } + + context.report({ + node: property[side], + loc, + messageId, + data: { + computed: property.computed ? "computed " : "", + key: getKey(property) + }, + fix + }); + } + } + + /** + * Gets the number of characters in a key, including quotes around string + * keys and braces around computed property keys. + * @param {ASTNode} property Property of on object literal. + * @returns {int} Width of the key. + */ + function getKeyWidth(property) { + const startToken = sourceCode.getFirstToken(property); + const endToken = getLastTokenBeforeColon(property.key); + + return endToken.range[1] - startToken.range[0]; + } + + /** + * Gets the whitespace around the colon in an object literal property. + * @param {ASTNode} property Property node from an object literal. + * @returns {Object} Whitespace before and after the property's colon. + */ + function getPropertyWhitespace(property) { + const whitespace = /(\s*):(\s*)/u.exec(sourceCode.getText().slice( + property.key.range[1], property.value.range[0] + )); + + if (whitespace) { + return { + beforeColon: whitespace[1], + afterColon: whitespace[2] + }; + } + return null; + } + + /** + * Creates groups of properties. + * @param {ASTNode} node ObjectExpression node being evaluated. + * @returns {Array.} Groups of property AST node lists. + */ + function createGroups(node) { + if (node.properties.length === 1) { + return [node.properties]; + } + + return node.properties.reduce((groups, property) => { + const currentGroup = last(groups), + prev = last(currentGroup); + + if (!prev || continuesPropertyGroup(prev, property)) { + currentGroup.push(property); + } else { + groups.push([property]); + } + + return groups; + }, [ + [] + ]); + } + + /** + * Verifies correct vertical alignment of a group of properties. + * @param {ASTNode[]} properties List of Property AST nodes. + * @returns {void} + */ + function verifyGroupAlignment(properties) { + const length = properties.length, + widths = properties.map(getKeyWidth), // Width of keys, including quotes + align = alignmentOptions.on; // "value" or "colon" + let targetWidth = Math.max(...widths), + beforeColon, afterColon, mode; + + if (alignmentOptions && length > 1) { // When aligning values within a group, use the alignment configuration. + beforeColon = alignmentOptions.beforeColon; + afterColon = alignmentOptions.afterColon; + mode = alignmentOptions.mode; + } else { + beforeColon = multiLineOptions.beforeColon; + afterColon = multiLineOptions.afterColon; + mode = alignmentOptions.mode; + } + + // Conditionally include one space before or after colon + targetWidth += (align === "colon" ? beforeColon : afterColon); + + for (let i = 0; i < length; i++) { + const property = properties[i]; + const whitespace = getPropertyWhitespace(property); + + if (whitespace) { // Object literal getters/setters lack a colon + const width = widths[i]; + + if (align === "value") { + report(property, "key", whitespace.beforeColon, beforeColon, mode); + report(property, "value", whitespace.afterColon, targetWidth - width, mode); + } else { // align = "colon" + report(property, "key", whitespace.beforeColon, targetWidth - width, mode); + report(property, "value", whitespace.afterColon, afterColon, mode); + } + } + } + } + + /** + * Verifies spacing of property conforms to specified options. + * @param {ASTNode} node Property node being evaluated. + * @param {Object} lineOptions Configured singleLine or multiLine options + * @returns {void} + */ + function verifySpacing(node, lineOptions) { + const actual = getPropertyWhitespace(node); + + if (actual) { // Object literal getters/setters lack colons + report(node, "key", actual.beforeColon, lineOptions.beforeColon, lineOptions.mode); + report(node, "value", actual.afterColon, lineOptions.afterColon, lineOptions.mode); + } + } + + /** + * Verifies spacing of each property in a list. + * @param {ASTNode[]} properties List of Property AST nodes. + * @param {Object} lineOptions Configured singleLine or multiLine options + * @returns {void} + */ + function verifyListSpacing(properties, lineOptions) { + const length = properties.length; + + for (let i = 0; i < length; i++) { + verifySpacing(properties[i], lineOptions); + } + } + + /** + * Verifies vertical alignment, taking into account groups of properties. + * @param {ASTNode} node ObjectExpression node being evaluated. + * @returns {void} + */ + function verifyAlignment(node) { + createGroups(node).forEach(group => { + const properties = group.filter(isKeyValueProperty); + + if (properties.length > 0 && isSingleLineProperties(properties)) { + verifyListSpacing(properties, multiLineOptions); + } else { + verifyGroupAlignment(properties); + } + }); + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + if (alignmentOptions) { // Verify vertical alignment + + return { + ObjectExpression(node) { + if (isSingleLine(node)) { + verifyListSpacing(node.properties.filter(isKeyValueProperty), singleLineOptions); + } else { + verifyAlignment(node); + } + } + }; + + } + + // Obey beforeColon and afterColon in each property as configured + return { + Property(node) { + verifySpacing(node, isSingleLine(node.parent) ? singleLineOptions : multiLineOptions); + } + }; + + + } +}; + +/** + * @fileoverview Rule to enforce spacing before and after keywords. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Constants +//------------------------------------------------------------------------------ + +const PREV_TOKEN = /^[)\]}>]$/u; +const NEXT_TOKEN = /^(?:[([{<~!]|\+\+?|--?)$/u; +const PREV_TOKEN_M = /^[)\]}>*]$/u; +const NEXT_TOKEN_M = /^[{*]$/u; +const TEMPLATE_OPEN_PAREN = /\$\{$/u; +const TEMPLATE_CLOSE_PAREN = /^\}/u; +const CHECK_TYPE = /^(?:JSXElement|RegularExpression|String|Template)$/u; +const KEYS = keywords.concat(["as", "async", "await", "from", "get", "let", "of", "set", "yield"]); + +// check duplications. +(function() { + KEYS.sort(); + for (let i = 1; i < KEYS.length; ++i) { + if (KEYS[i] === KEYS[i - 1]) { + throw new Error(`Duplication was found in the keyword list: ${KEYS[i]}`); + } + } +}()); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a given token is a "Template" token ends with "${". + * @param {Token} token A token to check. + * @returns {boolean} `true` if the token is a "Template" token ends with "${". + */ +function isOpenParenOfTemplate(token) { + return token.type === "Template" && TEMPLATE_OPEN_PAREN.test(token.value); +} + +/** + * Checks whether or not a given token is a "Template" token starts with "}". + * @param {Token} token A token to check. + * @returns {boolean} `true` if the token is a "Template" token starts with "}". + */ +function isCloseParenOfTemplate(token) { + return token.type === "Template" && TEMPLATE_CLOSE_PAREN.test(token.value); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var keywordSpacing = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent spacing before and after keywords", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/keyword-spacing" + }, + + fixable: "whitespace", + + schema: [ + { + type: "object", + properties: { + before: { type: "boolean", default: true }, + after: { type: "boolean", default: true }, + overrides: { + type: "object", + properties: KEYS.reduce((retv, key) => { + retv[key] = { + type: "object", + properties: { + before: { type: "boolean" }, + after: { type: "boolean" } + }, + additionalProperties: false + }; + return retv; + }, {}), + additionalProperties: false + } + }, + additionalProperties: false + } + ], + messages: { + expectedBefore: "Expected space(s) before \"{{value}}\".", + expectedAfter: "Expected space(s) after \"{{value}}\".", + unexpectedBefore: "Unexpected space(s) before \"{{value}}\".", + unexpectedAfter: "Unexpected space(s) after \"{{value}}\"." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + /** + * Reports a given token if there are not space(s) before the token. + * @param {Token} token A token to report. + * @param {RegExp} pattern A pattern of the previous token to check. + * @returns {void} + */ + function expectSpaceBefore(token, pattern) { + const prevToken = sourceCode.getTokenBefore(token); + + if (prevToken && + (CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) && + !isOpenParenOfTemplate(prevToken) && + astUtils.isTokenOnSameLine(prevToken, token) && + !sourceCode.isSpaceBetweenTokens(prevToken, token) + ) { + context.report({ + loc: token.loc, + messageId: "expectedBefore", + data: token, + fix(fixer) { + return fixer.insertTextBefore(token, " "); + } + }); + } + } + + /** + * Reports a given token if there are space(s) before the token. + * @param {Token} token A token to report. + * @param {RegExp} pattern A pattern of the previous token to check. + * @returns {void} + */ + function unexpectSpaceBefore(token, pattern) { + const prevToken = sourceCode.getTokenBefore(token); + + if (prevToken && + (CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) && + !isOpenParenOfTemplate(prevToken) && + astUtils.isTokenOnSameLine(prevToken, token) && + sourceCode.isSpaceBetweenTokens(prevToken, token) + ) { + context.report({ + loc: { start: prevToken.loc.end, end: token.loc.start }, + messageId: "unexpectedBefore", + data: token, + fix(fixer) { + return fixer.removeRange([prevToken.range[1], token.range[0]]); + } + }); + } + } + + /** + * Reports a given token if there are not space(s) after the token. + * @param {Token} token A token to report. + * @param {RegExp} pattern A pattern of the next token to check. + * @returns {void} + */ + function expectSpaceAfter(token, pattern) { + const nextToken = sourceCode.getTokenAfter(token); + + if (nextToken && + (CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) && + !isCloseParenOfTemplate(nextToken) && + astUtils.isTokenOnSameLine(token, nextToken) && + !sourceCode.isSpaceBetweenTokens(token, nextToken) + ) { + context.report({ + loc: token.loc, + messageId: "expectedAfter", + data: token, + fix(fixer) { + return fixer.insertTextAfter(token, " "); + } + }); + } + } + + /** + * Reports a given token if there are space(s) after the token. + * @param {Token} token A token to report. + * @param {RegExp} pattern A pattern of the next token to check. + * @returns {void} + */ + function unexpectSpaceAfter(token, pattern) { + const nextToken = sourceCode.getTokenAfter(token); + + if (nextToken && + (CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) && + !isCloseParenOfTemplate(nextToken) && + astUtils.isTokenOnSameLine(token, nextToken) && + sourceCode.isSpaceBetweenTokens(token, nextToken) + ) { + + context.report({ + loc: { start: token.loc.end, end: nextToken.loc.start }, + messageId: "unexpectedAfter", + data: token, + fix(fixer) { + return fixer.removeRange([token.range[1], nextToken.range[0]]); + } + }); + } + } + + /** + * Parses the option object and determines check methods for each keyword. + * @param {Object|undefined} options The option object to parse. + * @returns {Object} - Normalized option object. + * Keys are keywords (there are for every keyword). + * Values are instances of `{"before": function, "after": function}`. + */ + function parseOptions(options = {}) { + const before = options.before !== false; + const after = options.after !== false; + const defaultValue = { + before: before ? expectSpaceBefore : unexpectSpaceBefore, + after: after ? expectSpaceAfter : unexpectSpaceAfter + }; + const overrides = (options && options.overrides) || {}; + const retv = Object.create(null); + + for (let i = 0; i < KEYS.length; ++i) { + const key = KEYS[i]; + const override = overrides[key]; + + if (override) { + const thisBefore = ("before" in override) ? override.before : before; + const thisAfter = ("after" in override) ? override.after : after; + + retv[key] = { + before: thisBefore ? expectSpaceBefore : unexpectSpaceBefore, + after: thisAfter ? expectSpaceAfter : unexpectSpaceAfter + }; + } else { + retv[key] = defaultValue; + } + } + + return retv; + } + + const checkMethodMap = parseOptions(context.options[0]); + + /** + * Reports a given token if usage of spacing followed by the token is + * invalid. + * @param {Token} token A token to report. + * @param {RegExp} [pattern] Optional. A pattern of the previous + * token to check. + * @returns {void} + */ + function checkSpacingBefore(token, pattern) { + checkMethodMap[token.value].before(token, pattern || PREV_TOKEN); + } + + /** + * Reports a given token if usage of spacing preceded by the token is + * invalid. + * @param {Token} token A token to report. + * @param {RegExp} [pattern] Optional. A pattern of the next + * token to check. + * @returns {void} + */ + function checkSpacingAfter(token, pattern) { + checkMethodMap[token.value].after(token, pattern || NEXT_TOKEN); + } + + /** + * Reports a given token if usage of spacing around the token is invalid. + * @param {Token} token A token to report. + * @returns {void} + */ + function checkSpacingAround(token) { + checkSpacingBefore(token); + checkSpacingAfter(token); + } + + /** + * Reports the first token of a given node if the first token is a keyword + * and usage of spacing around the token is invalid. + * @param {ASTNode|null} node A node to report. + * @returns {void} + */ + function checkSpacingAroundFirstToken(node) { + const firstToken = node && sourceCode.getFirstToken(node); + + if (firstToken && firstToken.type === "Keyword") { + checkSpacingAround(firstToken); + } + } + + /** + * Reports the first token of a given node if the first token is a keyword + * and usage of spacing followed by the token is invalid. + * + * This is used for unary operators (e.g. `typeof`), `function`, and `super`. + * Other rules are handling usage of spacing preceded by those keywords. + * @param {ASTNode|null} node A node to report. + * @returns {void} + */ + function checkSpacingBeforeFirstToken(node) { + const firstToken = node && sourceCode.getFirstToken(node); + + if (firstToken && firstToken.type === "Keyword") { + checkSpacingBefore(firstToken); + } + } + + /** + * Reports the previous token of a given node if the token is a keyword and + * usage of spacing around the token is invalid. + * @param {ASTNode|null} node A node to report. + * @returns {void} + */ + function checkSpacingAroundTokenBefore(node) { + if (node) { + const token = sourceCode.getTokenBefore(node, astUtils.isKeywordToken); + + checkSpacingAround(token); + } + } + + /** + * Reports `async` or `function` keywords of a given node if usage of + * spacing around those keywords is invalid. + * @param {ASTNode} node A node to report. + * @returns {void} + */ + function checkSpacingForFunction(node) { + const firstToken = node && sourceCode.getFirstToken(node); + + if (firstToken && + ((firstToken.type === "Keyword" && firstToken.value === "function") || + firstToken.value === "async") + ) { + checkSpacingBefore(firstToken); + } + } + + /** + * Reports `class` and `extends` keywords of a given node if usage of + * spacing around those keywords is invalid. + * @param {ASTNode} node A node to report. + * @returns {void} + */ + function checkSpacingForClass(node) { + checkSpacingAroundFirstToken(node); + checkSpacingAroundTokenBefore(node.superClass); + } + + /** + * Reports `if` and `else` keywords of a given node if usage of spacing + * around those keywords is invalid. + * @param {ASTNode} node A node to report. + * @returns {void} + */ + function checkSpacingForIfStatement(node) { + checkSpacingAroundFirstToken(node); + checkSpacingAroundTokenBefore(node.alternate); + } + + /** + * Reports `try`, `catch`, and `finally` keywords of a given node if usage + * of spacing around those keywords is invalid. + * @param {ASTNode} node A node to report. + * @returns {void} + */ + function checkSpacingForTryStatement(node) { + checkSpacingAroundFirstToken(node); + checkSpacingAroundFirstToken(node.handler); + checkSpacingAroundTokenBefore(node.finalizer); + } + + /** + * Reports `do` and `while` keywords of a given node if usage of spacing + * around those keywords is invalid. + * @param {ASTNode} node A node to report. + * @returns {void} + */ + function checkSpacingForDoWhileStatement(node) { + checkSpacingAroundFirstToken(node); + checkSpacingAroundTokenBefore(node.test); + } + + /** + * Reports `for` and `in` keywords of a given node if usage of spacing + * around those keywords is invalid. + * @param {ASTNode} node A node to report. + * @returns {void} + */ + function checkSpacingForForInStatement(node) { + checkSpacingAroundFirstToken(node); + checkSpacingAroundTokenBefore(node.right); + } + + /** + * Reports `for` and `of` keywords of a given node if usage of spacing + * around those keywords is invalid. + * @param {ASTNode} node A node to report. + * @returns {void} + */ + function checkSpacingForForOfStatement(node) { + if (node.await) { + checkSpacingBefore(sourceCode.getFirstToken(node, 0)); + checkSpacingAfter(sourceCode.getFirstToken(node, 1)); + } else { + checkSpacingAroundFirstToken(node); + } + checkSpacingAround(sourceCode.getTokenBefore(node.right, astUtils.isNotOpeningParenToken)); + } + + /** + * Reports `import`, `export`, `as`, and `from` keywords of a given node if + * usage of spacing around those keywords is invalid. + * + * This rule handles the `*` token in module declarations. + * + * import*as A from "./a"; /*error Expected space(s) after "import". + * error Expected space(s) before "as". + * @param {ASTNode} node A node to report. + * @returns {void} + */ + function checkSpacingForModuleDeclaration(node) { + const firstToken = sourceCode.getFirstToken(node); + + checkSpacingBefore(firstToken, PREV_TOKEN_M); + checkSpacingAfter(firstToken, NEXT_TOKEN_M); + + if (node.type === "ExportDefaultDeclaration") { + checkSpacingAround(sourceCode.getTokenAfter(firstToken)); + } + + if (node.type === "ExportAllDeclaration" && node.exported) { + const asToken = sourceCode.getTokenBefore(node.exported); + + checkSpacingBefore(asToken, PREV_TOKEN_M); + } + + if (node.source) { + const fromToken = sourceCode.getTokenBefore(node.source); + + checkSpacingBefore(fromToken, PREV_TOKEN_M); + checkSpacingAfter(fromToken, NEXT_TOKEN_M); + } + } + + /** + * Reports `as` keyword of a given node if usage of spacing around this + * keyword is invalid. + * @param {ASTNode} node A node to report. + * @returns {void} + */ + function checkSpacingForImportNamespaceSpecifier(node) { + const asToken = sourceCode.getFirstToken(node, 1); + + checkSpacingBefore(asToken, PREV_TOKEN_M); + } + + /** + * Reports `static`, `get`, and `set` keywords of a given node if usage of + * spacing around those keywords is invalid. + * @param {ASTNode} node A node to report. + * @returns {void} + */ + function checkSpacingForProperty(node) { + if (node.static) { + checkSpacingAroundFirstToken(node); + } + if (node.kind === "get" || + node.kind === "set" || + ( + (node.method || node.type === "MethodDefinition") && + node.value.async + ) + ) { + const token = sourceCode.getTokenBefore( + node.key, + tok => { + switch (tok.value) { + case "get": + case "set": + case "async": + return true; + default: + return false; + } + } + ); + + if (!token) { + throw new Error("Failed to find token get, set, or async beside method name"); + } + + + checkSpacingAround(token); + } + } + + /** + * Reports `await` keyword of a given node if usage of spacing before + * this keyword is invalid. + * @param {ASTNode} node A node to report. + * @returns {void} + */ + function checkSpacingForAwaitExpression(node) { + checkSpacingBefore(sourceCode.getFirstToken(node)); + } + + return { + + // Statements + DebuggerStatement: checkSpacingAroundFirstToken, + WithStatement: checkSpacingAroundFirstToken, + + // Statements - Control flow + BreakStatement: checkSpacingAroundFirstToken, + ContinueStatement: checkSpacingAroundFirstToken, + ReturnStatement: checkSpacingAroundFirstToken, + ThrowStatement: checkSpacingAroundFirstToken, + TryStatement: checkSpacingForTryStatement, + + // Statements - Choice + IfStatement: checkSpacingForIfStatement, + SwitchStatement: checkSpacingAroundFirstToken, + SwitchCase: checkSpacingAroundFirstToken, + + // Statements - Loops + DoWhileStatement: checkSpacingForDoWhileStatement, + ForInStatement: checkSpacingForForInStatement, + ForOfStatement: checkSpacingForForOfStatement, + ForStatement: checkSpacingAroundFirstToken, + WhileStatement: checkSpacingAroundFirstToken, + + // Statements - Declarations + ClassDeclaration: checkSpacingForClass, + ExportNamedDeclaration: checkSpacingForModuleDeclaration, + ExportDefaultDeclaration: checkSpacingForModuleDeclaration, + ExportAllDeclaration: checkSpacingForModuleDeclaration, + FunctionDeclaration: checkSpacingForFunction, + ImportDeclaration: checkSpacingForModuleDeclaration, + VariableDeclaration: checkSpacingAroundFirstToken, + + // Expressions + ArrowFunctionExpression: checkSpacingForFunction, + AwaitExpression: checkSpacingForAwaitExpression, + ClassExpression: checkSpacingForClass, + FunctionExpression: checkSpacingForFunction, + NewExpression: checkSpacingBeforeFirstToken, + Super: checkSpacingBeforeFirstToken, + ThisExpression: checkSpacingBeforeFirstToken, + UnaryExpression: checkSpacingBeforeFirstToken, + YieldExpression: checkSpacingBeforeFirstToken, + + // Others + ImportNamespaceSpecifier: checkSpacingForImportNamespaceSpecifier, + MethodDefinition: checkSpacingForProperty, + Property: checkSpacingForProperty + }; + } +}; + +/** + * @fileoverview Rule to enforce the position of line comments + * @author Alberto Rodríguez + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var lineCommentPosition = { + meta: { + type: "layout", + + docs: { + description: "enforce position of line comments", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/line-comment-position" + }, + + schema: [ + { + oneOf: [ + { + enum: ["above", "beside"] + }, + { + type: "object", + properties: { + position: { + enum: ["above", "beside"] + }, + ignorePattern: { + type: "string" + }, + applyDefaultPatterns: { + type: "boolean" + }, + applyDefaultIgnorePatterns: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + } + ], + messages: { + above: "Expected comment to be above code.", + beside: "Expected comment to be beside code." + } + }, + + create(context) { + const options = context.options[0]; + + let above, + ignorePattern, + applyDefaultIgnorePatterns = true; + + if (!options || typeof options === "string") { + above = !options || options === "above"; + + } else { + above = !options.position || options.position === "above"; + ignorePattern = options.ignorePattern; + + if (Object.prototype.hasOwnProperty.call(options, "applyDefaultIgnorePatterns")) { + applyDefaultIgnorePatterns = options.applyDefaultIgnorePatterns; + } else { + applyDefaultIgnorePatterns = options.applyDefaultPatterns !== false; + } + } + + const defaultIgnoreRegExp = astUtils.COMMENTS_IGNORE_PATTERN; + const fallThroughRegExp = /^\s*falls?\s?through/u; + const customIgnoreRegExp = new RegExp(ignorePattern, "u"); + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + Program() { + const comments = sourceCode.getAllComments(); + + comments.filter(token => token.type === "Line").forEach(node => { + if (applyDefaultIgnorePatterns && (defaultIgnoreRegExp.test(node.value) || fallThroughRegExp.test(node.value))) { + return; + } + + if (ignorePattern && customIgnoreRegExp.test(node.value)) { + return; + } + + const previous = sourceCode.getTokenBefore(node, { includeComments: true }); + const isOnSameLine = previous && previous.loc.end.line === node.loc.start.line; + + if (above) { + if (isOnSameLine) { + context.report({ + node, + messageId: "above" + }); + } + } else { + if (!isOnSameLine) { + context.report({ + node, + messageId: "beside" + }); + } + } + }); + } + }; + } +}; + +/** + * @fileoverview Rule to enforce a single linebreak style. + * @author Erik Mueller + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var linebreakStyle = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent linebreak style", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/linebreak-style" + }, + + fixable: "whitespace", + + schema: [ + { + enum: ["unix", "windows"] + } + ], + messages: { + expectedLF: "Expected linebreaks to be 'LF' but found 'CRLF'.", + expectedCRLF: "Expected linebreaks to be 'CRLF' but found 'LF'." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Builds a fix function that replaces text at the specified range in the source text. + * @param {int[]} range The range to replace + * @param {string} text The text to insert. + * @returns {Function} Fixer function + * @private + */ + function createFix(range, text) { + return function(fixer) { + return fixer.replaceTextRange(range, text); + }; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + Program: function checkForLinebreakStyle(node) { + const linebreakStyle = context.options[0] || "unix", + expectedLF = linebreakStyle === "unix", + expectedLFChars = expectedLF ? "\n" : "\r\n", + source = sourceCode.getText(), + pattern = astUtils.createGlobalLinebreakMatcher(); + let match; + + let i = 0; + + while ((match = pattern.exec(source)) !== null) { + i++; + if (match[0] === expectedLFChars) { + continue; + } + + const index = match.index; + const range = [index, index + match[0].length]; + + context.report({ + node, + loc: { + start: { + line: i, + column: sourceCode.lines[i - 1].length + }, + end: { + line: i + 1, + column: 0 + } + }, + messageId: expectedLF ? "expectedLF" : "expectedCRLF", + fix: createFix(range, expectedLFChars) + }); + } + } + }; + } +}; + +/** + * @fileoverview Enforces empty lines around comments. + * @author Jamund Ferguson + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Return an array with with any line numbers that are empty. + * @param {Array} lines An array of each line of the file. + * @returns {Array} An array of line numbers. + */ +function getEmptyLineNums(lines) { + const emptyLines = lines.map((line, i) => ({ + code: line.trim(), + num: i + 1 + })).filter(line => !line.code).map(line => line.num); + + return emptyLines; +} + +/** + * Return an array with with any line numbers that contain comments. + * @param {Array} comments An array of comment tokens. + * @returns {Array} An array of line numbers. + */ +function getCommentLineNums(comments) { + const lines = []; + + comments.forEach(token => { + const start = token.loc.start.line; + const end = token.loc.end.line; + + lines.push(start, end); + }); + return lines; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var linesAroundComment = { + meta: { + type: "layout", + + docs: { + description: "require empty lines around comments", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/lines-around-comment" + }, + + fixable: "whitespace", + + schema: [ + { + type: "object", + properties: { + beforeBlockComment: { + type: "boolean", + default: true + }, + afterBlockComment: { + type: "boolean", + default: false + }, + beforeLineComment: { + type: "boolean", + default: false + }, + afterLineComment: { + type: "boolean", + default: false + }, + allowBlockStart: { + type: "boolean", + default: false + }, + allowBlockEnd: { + type: "boolean", + default: false + }, + allowClassStart: { + type: "boolean" + }, + allowClassEnd: { + type: "boolean" + }, + allowObjectStart: { + type: "boolean" + }, + allowObjectEnd: { + type: "boolean" + }, + allowArrayStart: { + type: "boolean" + }, + allowArrayEnd: { + type: "boolean" + }, + ignorePattern: { + type: "string" + }, + applyDefaultIgnorePatterns: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + messages: { + after: "Expected line after comment.", + before: "Expected line before comment." + } + }, + + create(context) { + + const options = Object.assign({}, context.options[0]); + const ignorePattern = options.ignorePattern; + const defaultIgnoreRegExp = astUtils.COMMENTS_IGNORE_PATTERN; + const customIgnoreRegExp = new RegExp(ignorePattern, "u"); + const applyDefaultIgnorePatterns = options.applyDefaultIgnorePatterns !== false; + + options.beforeBlockComment = typeof options.beforeBlockComment !== "undefined" ? options.beforeBlockComment : true; + + const sourceCode = context.getSourceCode(); + + const lines = sourceCode.lines, + numLines = lines.length + 1, + comments = sourceCode.getAllComments(), + commentLines = getCommentLineNums(comments), + emptyLines = getEmptyLineNums(lines), + commentAndEmptyLines = commentLines.concat(emptyLines); + + /** + * Returns whether or not comments are on lines starting with or ending with code + * @param {token} token The comment token to check. + * @returns {boolean} True if the comment is not alone. + */ + function codeAroundComment(token) { + let currentToken = token; + + do { + currentToken = sourceCode.getTokenBefore(currentToken, { includeComments: true }); + } while (currentToken && astUtils.isCommentToken(currentToken)); + + if (currentToken && astUtils.isTokenOnSameLine(currentToken, token)) { + return true; + } + + currentToken = token; + do { + currentToken = sourceCode.getTokenAfter(currentToken, { includeComments: true }); + } while (currentToken && astUtils.isCommentToken(currentToken)); + + if (currentToken && astUtils.isTokenOnSameLine(token, currentToken)) { + return true; + } + + return false; + } + + /** + * Returns whether or not comments are inside a node type or not. + * @param {ASTNode} parent The Comment parent node. + * @param {string} nodeType The parent type to check against. + * @returns {boolean} True if the comment is inside nodeType. + */ + function isParentNodeType(parent, nodeType) { + return parent.type === nodeType || + (parent.body && parent.body.type === nodeType) || + (parent.consequent && parent.consequent.type === nodeType); + } + + /** + * Returns the parent node that contains the given token. + * @param {token} token The token to check. + * @returns {ASTNode} The parent node that contains the given token. + */ + function getParentNodeOfToken(token) { + return sourceCode.getNodeByRangeIndex(token.range[0]); + } + + /** + * Returns whether or not comments are at the parent start or not. + * @param {token} token The Comment token. + * @param {string} nodeType The parent type to check against. + * @returns {boolean} True if the comment is at parent start. + */ + function isCommentAtParentStart(token, nodeType) { + const parent = getParentNodeOfToken(token); + + return parent && isParentNodeType(parent, nodeType) && + token.loc.start.line - parent.loc.start.line === 1; + } + + /** + * Returns whether or not comments are at the parent end or not. + * @param {token} token The Comment token. + * @param {string} nodeType The parent type to check against. + * @returns {boolean} True if the comment is at parent end. + */ + function isCommentAtParentEnd(token, nodeType) { + const parent = getParentNodeOfToken(token); + + return parent && isParentNodeType(parent, nodeType) && + parent.loc.end.line - token.loc.end.line === 1; + } + + /** + * Returns whether or not comments are at the block start or not. + * @param {token} token The Comment token. + * @returns {boolean} True if the comment is at block start. + */ + function isCommentAtBlockStart(token) { + return isCommentAtParentStart(token, "ClassBody") || isCommentAtParentStart(token, "BlockStatement") || isCommentAtParentStart(token, "SwitchCase"); + } + + /** + * Returns whether or not comments are at the block end or not. + * @param {token} token The Comment token. + * @returns {boolean} True if the comment is at block end. + */ + function isCommentAtBlockEnd(token) { + return isCommentAtParentEnd(token, "ClassBody") || isCommentAtParentEnd(token, "BlockStatement") || isCommentAtParentEnd(token, "SwitchCase") || isCommentAtParentEnd(token, "SwitchStatement"); + } + + /** + * Returns whether or not comments are at the class start or not. + * @param {token} token The Comment token. + * @returns {boolean} True if the comment is at class start. + */ + function isCommentAtClassStart(token) { + return isCommentAtParentStart(token, "ClassBody"); + } + + /** + * Returns whether or not comments are at the class end or not. + * @param {token} token The Comment token. + * @returns {boolean} True if the comment is at class end. + */ + function isCommentAtClassEnd(token) { + return isCommentAtParentEnd(token, "ClassBody"); + } + + /** + * Returns whether or not comments are at the object start or not. + * @param {token} token The Comment token. + * @returns {boolean} True if the comment is at object start. + */ + function isCommentAtObjectStart(token) { + return isCommentAtParentStart(token, "ObjectExpression") || isCommentAtParentStart(token, "ObjectPattern"); + } + + /** + * Returns whether or not comments are at the object end or not. + * @param {token} token The Comment token. + * @returns {boolean} True if the comment is at object end. + */ + function isCommentAtObjectEnd(token) { + return isCommentAtParentEnd(token, "ObjectExpression") || isCommentAtParentEnd(token, "ObjectPattern"); + } + + /** + * Returns whether or not comments are at the array start or not. + * @param {token} token The Comment token. + * @returns {boolean} True if the comment is at array start. + */ + function isCommentAtArrayStart(token) { + return isCommentAtParentStart(token, "ArrayExpression") || isCommentAtParentStart(token, "ArrayPattern"); + } + + /** + * Returns whether or not comments are at the array end or not. + * @param {token} token The Comment token. + * @returns {boolean} True if the comment is at array end. + */ + function isCommentAtArrayEnd(token) { + return isCommentAtParentEnd(token, "ArrayExpression") || isCommentAtParentEnd(token, "ArrayPattern"); + } + + /** + * Checks if a comment token has lines around it (ignores inline comments) + * @param {token} token The Comment token. + * @param {Object} opts Options to determine the newline. + * @param {boolean} opts.after Should have a newline after this line. + * @param {boolean} opts.before Should have a newline before this line. + * @returns {void} + */ + function checkForEmptyLine(token, opts) { + if (applyDefaultIgnorePatterns && defaultIgnoreRegExp.test(token.value)) { + return; + } + + if (ignorePattern && customIgnoreRegExp.test(token.value)) { + return; + } + + let after = opts.after, + before = opts.before; + + const prevLineNum = token.loc.start.line - 1, + nextLineNum = token.loc.end.line + 1, + commentIsNotAlone = codeAroundComment(token); + + const blockStartAllowed = options.allowBlockStart && + isCommentAtBlockStart(token) && + !(options.allowClassStart === false && + isCommentAtClassStart(token)), + blockEndAllowed = options.allowBlockEnd && isCommentAtBlockEnd(token) && !(options.allowClassEnd === false && isCommentAtClassEnd(token)), + classStartAllowed = options.allowClassStart && isCommentAtClassStart(token), + classEndAllowed = options.allowClassEnd && isCommentAtClassEnd(token), + objectStartAllowed = options.allowObjectStart && isCommentAtObjectStart(token), + objectEndAllowed = options.allowObjectEnd && isCommentAtObjectEnd(token), + arrayStartAllowed = options.allowArrayStart && isCommentAtArrayStart(token), + arrayEndAllowed = options.allowArrayEnd && isCommentAtArrayEnd(token); + + const exceptionStartAllowed = blockStartAllowed || classStartAllowed || objectStartAllowed || arrayStartAllowed; + const exceptionEndAllowed = blockEndAllowed || classEndAllowed || objectEndAllowed || arrayEndAllowed; + + // ignore top of the file and bottom of the file + if (prevLineNum < 1) { + before = false; + } + if (nextLineNum >= numLines) { + after = false; + } + + // we ignore all inline comments + if (commentIsNotAlone) { + return; + } + + const previousTokenOrComment = sourceCode.getTokenBefore(token, { includeComments: true }); + const nextTokenOrComment = sourceCode.getTokenAfter(token, { includeComments: true }); + + // check for newline before + if (!exceptionStartAllowed && before && !commentAndEmptyLines.includes(prevLineNum) && + !(astUtils.isCommentToken(previousTokenOrComment) && astUtils.isTokenOnSameLine(previousTokenOrComment, token))) { + const lineStart = token.range[0] - token.loc.start.column; + const range = [lineStart, lineStart]; + + context.report({ + node: token, + messageId: "before", + fix(fixer) { + return fixer.insertTextBeforeRange(range, "\n"); + } + }); + } + + // check for newline after + if (!exceptionEndAllowed && after && !commentAndEmptyLines.includes(nextLineNum) && + !(astUtils.isCommentToken(nextTokenOrComment) && astUtils.isTokenOnSameLine(token, nextTokenOrComment))) { + context.report({ + node: token, + messageId: "after", + fix(fixer) { + return fixer.insertTextAfter(token, "\n"); + } + }); + } + + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + Program() { + comments.forEach(token => { + if (token.type === "Line") { + if (options.beforeLineComment || options.afterLineComment) { + checkForEmptyLine(token, { + after: options.afterLineComment, + before: options.beforeLineComment + }); + } + } else if (token.type === "Block") { + if (options.beforeBlockComment || options.afterBlockComment) { + checkForEmptyLine(token, { + after: options.afterBlockComment, + before: options.beforeBlockComment + }); + } + } + }); + } + }; + } +}; + +/** + * @fileoverview Require or disallow newlines around directives. + * @author Kai Cataldo + * @deprecated + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var linesAroundDirective = { + meta: { + type: "layout", + + docs: { + description: "require or disallow newlines around directives", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/lines-around-directive" + }, + + schema: [{ + oneOf: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + before: { + enum: ["always", "never"] + }, + after: { + enum: ["always", "never"] + } + }, + additionalProperties: false, + minProperties: 2 + } + ] + }], + + fixable: "whitespace", + messages: { + expected: "Expected newline {{location}} \"{{value}}\" directive.", + unexpected: "Unexpected newline {{location}} \"{{value}}\" directive." + }, + deprecated: true, + replacedBy: ["padding-line-between-statements"] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const config = context.options[0] || "always"; + const expectLineBefore = typeof config === "string" ? config : config.before; + const expectLineAfter = typeof config === "string" ? config : config.after; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Check if node is preceded by a blank newline. + * @param {ASTNode} node Node to check. + * @returns {boolean} Whether or not the passed in node is preceded by a blank newline. + */ + function hasNewlineBefore(node) { + const tokenBefore = sourceCode.getTokenBefore(node, { includeComments: true }); + const tokenLineBefore = tokenBefore ? tokenBefore.loc.end.line : 0; + + return node.loc.start.line - tokenLineBefore >= 2; + } + + /** + * Gets the last token of a node that is on the same line as the rest of the node. + * This will usually be the last token of the node, but it will be the second-to-last token if the node has a trailing + * semicolon on a different line. + * @param {ASTNode} node A directive node + * @returns {Token} The last token of the node on the line + */ + function getLastTokenOnLine(node) { + const lastToken = sourceCode.getLastToken(node); + const secondToLastToken = sourceCode.getTokenBefore(lastToken); + + return astUtils.isSemicolonToken(lastToken) && lastToken.loc.start.line > secondToLastToken.loc.end.line + ? secondToLastToken + : lastToken; + } + + /** + * Check if node is followed by a blank newline. + * @param {ASTNode} node Node to check. + * @returns {boolean} Whether or not the passed in node is followed by a blank newline. + */ + function hasNewlineAfter(node) { + const lastToken = getLastTokenOnLine(node); + const tokenAfter = sourceCode.getTokenAfter(lastToken, { includeComments: true }); + + return tokenAfter.loc.start.line - lastToken.loc.end.line >= 2; + } + + /** + * Report errors for newlines around directives. + * @param {ASTNode} node Node to check. + * @param {string} location Whether the error was found before or after the directive. + * @param {boolean} expected Whether or not a newline was expected or unexpected. + * @returns {void} + */ + function reportError(node, location, expected) { + context.report({ + node, + messageId: expected ? "expected" : "unexpected", + data: { + value: node.expression.value, + location + }, + fix(fixer) { + const lastToken = getLastTokenOnLine(node); + + if (expected) { + return location === "before" ? fixer.insertTextBefore(node, "\n") : fixer.insertTextAfter(lastToken, "\n"); + } + return fixer.removeRange(location === "before" ? [node.range[0] - 1, node.range[0]] : [lastToken.range[1], lastToken.range[1] + 1]); + } + }); + } + + /** + * Check lines around directives in node + * @param {ASTNode} node node to check + * @returns {void} + */ + function checkDirectives(node) { + const directives = astUtils.getDirectivePrologue(node); + + if (!directives.length) { + return; + } + + const firstDirective = directives[0]; + const leadingComments = sourceCode.getCommentsBefore(firstDirective); + + /* + * Only check before the first directive if it is preceded by a comment or if it is at the top of + * the file and expectLineBefore is set to "never". This is to not force a newline at the top of + * the file if there are no comments as well as for compatibility with padded-blocks. + */ + if (leadingComments.length) { + if (expectLineBefore === "always" && !hasNewlineBefore(firstDirective)) { + reportError(firstDirective, "before", true); + } + + if (expectLineBefore === "never" && hasNewlineBefore(firstDirective)) { + reportError(firstDirective, "before", false); + } + } else if ( + node.type === "Program" && + expectLineBefore === "never" && + !leadingComments.length && + hasNewlineBefore(firstDirective) + ) { + reportError(firstDirective, "before", false); + } + + const lastDirective = directives[directives.length - 1]; + const statements = node.type === "Program" ? node.body : node.body.body; + + /* + * Do not check after the last directive if the body only + * contains a directive prologue and isn't followed by a comment to ensure + * this rule behaves well with padded-blocks. + */ + if (lastDirective === statements[statements.length - 1] && !lastDirective.trailingComments) { + return; + } + + if (expectLineAfter === "always" && !hasNewlineAfter(lastDirective)) { + reportError(lastDirective, "after", true); + } + + if (expectLineAfter === "never" && hasNewlineAfter(lastDirective)) { + reportError(lastDirective, "after", false); + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + Program: checkDirectives, + FunctionDeclaration: checkDirectives, + FunctionExpression: checkDirectives, + ArrowFunctionExpression: checkDirectives + }; + } +}; + +/** + * @fileoverview Rule to check empty newline between class members + * @author 薛定谔的猫 + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var linesBetweenClassMembers = { + meta: { + type: "layout", + + docs: { + description: "require or disallow an empty line between class members", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/lines-between-class-members" + }, + + fixable: "whitespace", + + schema: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + exceptAfterSingleLine: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + messages: { + never: "Unexpected blank line between class members.", + always: "Expected blank line between class members." + } + }, + + create(context) { + + const options = []; + + options[0] = context.options[0] || "always"; + options[1] = context.options[1] || { exceptAfterSingleLine: false }; + + const sourceCode = context.getSourceCode(); + + /** + * Return the last token among the consecutive tokens that have no exceed max line difference in between, before the first token in the next member. + * @param {Token} prevLastToken The last token in the previous member node. + * @param {Token} nextFirstToken The first token in the next member node. + * @param {number} maxLine The maximum number of allowed line difference between consecutive tokens. + * @returns {Token} The last token among the consecutive tokens. + */ + function findLastConsecutiveTokenAfter(prevLastToken, nextFirstToken, maxLine) { + const after = sourceCode.getTokenAfter(prevLastToken, { includeComments: true }); + + if (after !== nextFirstToken && after.loc.start.line - prevLastToken.loc.end.line <= maxLine) { + return findLastConsecutiveTokenAfter(after, nextFirstToken, maxLine); + } + return prevLastToken; + } + + /** + * Return the first token among the consecutive tokens that have no exceed max line difference in between, after the last token in the previous member. + * @param {Token} nextFirstToken The first token in the next member node. + * @param {Token} prevLastToken The last token in the previous member node. + * @param {number} maxLine The maximum number of allowed line difference between consecutive tokens. + * @returns {Token} The first token among the consecutive tokens. + */ + function findFirstConsecutiveTokenBefore(nextFirstToken, prevLastToken, maxLine) { + const before = sourceCode.getTokenBefore(nextFirstToken, { includeComments: true }); + + if (before !== prevLastToken && nextFirstToken.loc.start.line - before.loc.end.line <= maxLine) { + return findFirstConsecutiveTokenBefore(before, prevLastToken, maxLine); + } + return nextFirstToken; + } + + /** + * Checks if there is a token or comment between two tokens. + * @param {Token} before The token before. + * @param {Token} after The token after. + * @returns {boolean} True if there is a token or comment between two tokens. + */ + function hasTokenOrCommentBetween(before, after) { + return sourceCode.getTokensBetween(before, after, { includeComments: true }).length !== 0; + } + + return { + ClassBody(node) { + const body = node.body; + + for (let i = 0; i < body.length - 1; i++) { + const curFirst = sourceCode.getFirstToken(body[i]); + const curLast = sourceCode.getLastToken(body[i]); + const nextFirst = sourceCode.getFirstToken(body[i + 1]); + const isMulti = !astUtils.isTokenOnSameLine(curFirst, curLast); + const skip = !isMulti && options[1].exceptAfterSingleLine; + const beforePadding = findLastConsecutiveTokenAfter(curLast, nextFirst, 1); + const afterPadding = findFirstConsecutiveTokenBefore(nextFirst, curLast, 1); + const isPadded = afterPadding.loc.start.line - beforePadding.loc.end.line > 1; + const hasTokenInPadding = hasTokenOrCommentBetween(beforePadding, afterPadding); + const curLineLastToken = findLastConsecutiveTokenAfter(curLast, nextFirst, 0); + + if ((options[0] === "always" && !skip && !isPadded) || + (options[0] === "never" && isPadded)) { + context.report({ + node: body[i + 1], + messageId: isPadded ? "never" : "always", + fix(fixer) { + if (hasTokenInPadding) { + return null; + } + return isPadded + ? fixer.replaceTextRange([beforePadding.range[1], afterPadding.range[0]], "\n") + : fixer.insertTextAfter(curLineLastToken, "\n"); + } + }); + } + } + } + }; + } +}; + +/** + * @fileoverview Enforce a maximum number of classes per file + * @author James Garbutt + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var maxClassesPerFile = { + meta: { + type: "suggestion", + + docs: { + description: "enforce a maximum number of classes per file", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/max-classes-per-file" + }, + + schema: [ + { + type: "integer", + minimum: 1 + } + ], + + messages: { + maximumExceeded: "File has too many classes ({{ classCount }}). Maximum allowed is {{ max }}." + } + }, + create(context) { + + const maxClasses = context.options[0] || 1; + + let classCount = 0; + + return { + Program() { + classCount = 0; + }, + "Program:exit"(node) { + if (classCount > maxClasses) { + context.report({ + node, + messageId: "maximumExceeded", + data: { + classCount, + max: maxClasses + } + }); + } + }, + "ClassDeclaration, ClassExpression"() { + classCount++; + } + }; + } +}; + +/** + * @fileoverview A rule to set the maximum depth block can be nested in a function. + * @author Ian Christian Myers + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var maxDepth = { + meta: { + type: "suggestion", + + docs: { + description: "enforce a maximum depth that blocks can be nested", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/max-depth" + }, + + schema: [ + { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + type: "object", + properties: { + maximum: { + type: "integer", + minimum: 0 + }, + max: { + type: "integer", + minimum: 0 + } + }, + additionalProperties: false + } + ] + } + ], + messages: { + tooDeeply: "Blocks are nested too deeply ({{depth}}). Maximum allowed is {{maxDepth}}." + } + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + const functionStack = [], + option = context.options[0]; + let maxDepth = 4; + + if ( + typeof option === "object" && + (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max")) + ) { + maxDepth = option.maximum || option.max; + } + if (typeof option === "number") { + maxDepth = option; + } + + /** + * When parsing a new function, store it in our function stack + * @returns {void} + * @private + */ + function startFunction() { + functionStack.push(0); + } + + /** + * When parsing is done then pop out the reference + * @returns {void} + * @private + */ + function endFunction() { + functionStack.pop(); + } + + /** + * Save the block and Evaluate the node + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function pushBlock(node) { + const len = ++functionStack[functionStack.length - 1]; + + if (len > maxDepth) { + context.report({ node, messageId: "tooDeeply", data: { depth: len, maxDepth } }); + } + } + + /** + * Pop the saved block + * @returns {void} + * @private + */ + function popBlock() { + functionStack[functionStack.length - 1]--; + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + Program: startFunction, + FunctionDeclaration: startFunction, + FunctionExpression: startFunction, + ArrowFunctionExpression: startFunction, + + IfStatement(node) { + if (node.parent.type !== "IfStatement") { + pushBlock(node); + } + }, + SwitchStatement: pushBlock, + TryStatement: pushBlock, + DoWhileStatement: pushBlock, + WhileStatement: pushBlock, + WithStatement: pushBlock, + ForStatement: pushBlock, + ForInStatement: pushBlock, + ForOfStatement: pushBlock, + + "IfStatement:exit": popBlock, + "SwitchStatement:exit": popBlock, + "TryStatement:exit": popBlock, + "DoWhileStatement:exit": popBlock, + "WhileStatement:exit": popBlock, + "WithStatement:exit": popBlock, + "ForStatement:exit": popBlock, + "ForInStatement:exit": popBlock, + "ForOfStatement:exit": popBlock, + + "FunctionDeclaration:exit": endFunction, + "FunctionExpression:exit": endFunction, + "ArrowFunctionExpression:exit": endFunction, + "Program:exit": endFunction + }; + + } +}; + +/** + * @fileoverview Rule to check for max length on a line. + * @author Matt DuVall + */ + +//------------------------------------------------------------------------------ +// Constants +//------------------------------------------------------------------------------ + +const OPTIONS_SCHEMA$1 = { + type: "object", + properties: { + code: { + type: "integer", + minimum: 0 + }, + comments: { + type: "integer", + minimum: 0 + }, + tabWidth: { + type: "integer", + minimum: 0 + }, + ignorePattern: { + type: "string" + }, + ignoreComments: { + type: "boolean" + }, + ignoreStrings: { + type: "boolean" + }, + ignoreUrls: { + type: "boolean" + }, + ignoreTemplateLiterals: { + type: "boolean" + }, + ignoreRegExpLiterals: { + type: "boolean" + }, + ignoreTrailingComments: { + type: "boolean" + } + }, + additionalProperties: false +}; + +const OPTIONS_OR_INTEGER_SCHEMA$1 = { + anyOf: [ + OPTIONS_SCHEMA$1, + { + type: "integer", + minimum: 0 + } + ] +}; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var maxLen = { + meta: { + type: "layout", + + docs: { + description: "enforce a maximum line length", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/max-len" + }, + + schema: [ + OPTIONS_OR_INTEGER_SCHEMA$1, + OPTIONS_OR_INTEGER_SCHEMA$1, + OPTIONS_SCHEMA$1 + ], + messages: { + max: "This line has a length of {{lineLength}}. Maximum allowed is {{maxLength}}.", + maxComment: "This line has a comment length of {{lineLength}}. Maximum allowed is {{maxCommentLength}}." + } + }, + + create(context) { + + /* + * Inspired by http://tools.ietf.org/html/rfc3986#appendix-B, however: + * - They're matching an entire string that we know is a URI + * - We're matching part of a string where we think there *might* be a URL + * - We're only concerned about URLs, as picking out any URI would cause + * too many false positives + * - We don't care about matching the entire URL, any small segment is fine + */ + const URL_REGEXP = /[^:/?#]:\/\/[^?#]/u; + + const sourceCode = context.getSourceCode(); + + /** + * Computes the length of a line that may contain tabs. The width of each + * tab will be the number of spaces to the next tab stop. + * @param {string} line The line. + * @param {int} tabWidth The width of each tab stop in spaces. + * @returns {int} The computed line length. + * @private + */ + function computeLineLength(line, tabWidth) { + let extraCharacterCount = 0; + + line.replace(/\t/gu, (match, offset) => { + const totalOffset = offset + extraCharacterCount, + previousTabStopOffset = tabWidth ? totalOffset % tabWidth : 0, + spaceCount = tabWidth - previousTabStopOffset; + + extraCharacterCount += spaceCount - 1; // -1 for the replaced tab + }); + return Array.from(line).length + extraCharacterCount; + } + + // The options object must be the last option specified… + const options = Object.assign({}, context.options[context.options.length - 1]); + + // …but max code length… + if (typeof context.options[0] === "number") { + options.code = context.options[0]; + } + + // …and tabWidth can be optionally specified directly as integers. + if (typeof context.options[1] === "number") { + options.tabWidth = context.options[1]; + } + + const maxLength = typeof options.code === "number" ? options.code : 80, + tabWidth = typeof options.tabWidth === "number" ? options.tabWidth : 4, + ignoreComments = !!options.ignoreComments, + ignoreStrings = !!options.ignoreStrings, + ignoreTemplateLiterals = !!options.ignoreTemplateLiterals, + ignoreRegExpLiterals = !!options.ignoreRegExpLiterals, + ignoreTrailingComments = !!options.ignoreTrailingComments || !!options.ignoreComments, + ignoreUrls = !!options.ignoreUrls, + maxCommentLength = options.comments; + let ignorePattern = options.ignorePattern || null; + + if (ignorePattern) { + ignorePattern = new RegExp(ignorePattern, "u"); + } + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Tells if a given comment is trailing: it starts on the current line and + * extends to or past the end of the current line. + * @param {string} line The source line we want to check for a trailing comment on + * @param {number} lineNumber The one-indexed line number for line + * @param {ASTNode} comment The comment to inspect + * @returns {boolean} If the comment is trailing on the given line + */ + function isTrailingComment(line, lineNumber, comment) { + return comment && + (comment.loc.start.line === lineNumber && lineNumber <= comment.loc.end.line) && + (comment.loc.end.line > lineNumber || comment.loc.end.column === line.length); + } + + /** + * Tells if a comment encompasses the entire line. + * @param {string} line The source line with a trailing comment + * @param {number} lineNumber The one-indexed line number this is on + * @param {ASTNode} comment The comment to remove + * @returns {boolean} If the comment covers the entire line + */ + function isFullLineComment(line, lineNumber, comment) { + const start = comment.loc.start, + end = comment.loc.end, + isFirstTokenOnLine = !line.slice(0, comment.loc.start.column).trim(); + + return comment && + (start.line < lineNumber || (start.line === lineNumber && isFirstTokenOnLine)) && + (end.line > lineNumber || (end.line === lineNumber && end.column === line.length)); + } + + /** + * Check if a node is a JSXEmptyExpression contained in a single line JSXExpressionContainer. + * @param {ASTNode} node A node to check. + * @returns {boolean} True if the node is a JSXEmptyExpression contained in a single line JSXExpressionContainer. + */ + function isJSXEmptyExpressionInSingleLineContainer(node) { + if (!node || !node.parent || node.type !== "JSXEmptyExpression" || node.parent.type !== "JSXExpressionContainer") { + return false; + } + + const parent = node.parent; + + return parent.loc.start.line === parent.loc.end.line; + } + + /** + * Gets the line after the comment and any remaining trailing whitespace is + * stripped. + * @param {string} line The source line with a trailing comment + * @param {ASTNode} comment The comment to remove + * @returns {string} Line without comment and trailing whitespace + */ + function stripTrailingComment(line, comment) { + + // loc.column is zero-indexed + return line.slice(0, comment.loc.start.column).replace(/\s+$/u, ""); + } + + /** + * Ensure that an array exists at [key] on `object`, and add `value` to it. + * @param {Object} object the object to mutate + * @param {string} key the object's key + * @param {*} value the value to add + * @returns {void} + * @private + */ + function ensureArrayAndPush(object, key, value) { + if (!Array.isArray(object[key])) { + object[key] = []; + } + object[key].push(value); + } + + /** + * Retrieves an array containing all strings (" or ') in the source code. + * @returns {ASTNode[]} An array of string nodes. + */ + function getAllStrings() { + return sourceCode.ast.tokens.filter(token => (token.type === "String" || + (token.type === "JSXText" && sourceCode.getNodeByRangeIndex(token.range[0] - 1).type === "JSXAttribute"))); + } + + /** + * Retrieves an array containing all template literals in the source code. + * @returns {ASTNode[]} An array of template literal nodes. + */ + function getAllTemplateLiterals() { + return sourceCode.ast.tokens.filter(token => token.type === "Template"); + } + + + /** + * Retrieves an array containing all RegExp literals in the source code. + * @returns {ASTNode[]} An array of RegExp literal nodes. + */ + function getAllRegExpLiterals() { + return sourceCode.ast.tokens.filter(token => token.type === "RegularExpression"); + } + + + /** + * A reducer to group an AST node by line number, both start and end. + * @param {Object} acc the accumulator + * @param {ASTNode} node the AST node in question + * @returns {Object} the modified accumulator + * @private + */ + function groupByLineNumber(acc, node) { + for (let i = node.loc.start.line; i <= node.loc.end.line; ++i) { + ensureArrayAndPush(acc, i, node); + } + return acc; + } + + /** + * Returns an array of all comments in the source code. + * If the element in the array is a JSXEmptyExpression contained with a single line JSXExpressionContainer, + * the element is changed with JSXExpressionContainer node. + * @returns {ASTNode[]} An array of comment nodes + */ + function getAllComments() { + const comments = []; + + sourceCode.getAllComments() + .forEach(commentNode => { + const containingNode = sourceCode.getNodeByRangeIndex(commentNode.range[0]); + + if (isJSXEmptyExpressionInSingleLineContainer(containingNode)) { + + // push a unique node only + if (comments[comments.length - 1] !== containingNode.parent) { + comments.push(containingNode.parent); + } + } else { + comments.push(commentNode); + } + }); + + return comments; + } + + /** + * Check the program for max length + * @param {ASTNode} node Node to examine + * @returns {void} + * @private + */ + function checkProgramForMaxLength(node) { + + // split (honors line-ending) + const lines = sourceCode.lines, + + // list of comments to ignore + comments = ignoreComments || maxCommentLength || ignoreTrailingComments ? getAllComments() : []; + + // we iterate over comments in parallel with the lines + let commentsIndex = 0; + + const strings = getAllStrings(); + const stringsByLine = strings.reduce(groupByLineNumber, {}); + + const templateLiterals = getAllTemplateLiterals(); + const templateLiteralsByLine = templateLiterals.reduce(groupByLineNumber, {}); + + const regExpLiterals = getAllRegExpLiterals(); + const regExpLiteralsByLine = regExpLiterals.reduce(groupByLineNumber, {}); + + lines.forEach((line, i) => { + + // i is zero-indexed, line numbers are one-indexed + const lineNumber = i + 1; + + /* + * if we're checking comment length; we need to know whether this + * line is a comment + */ + let lineIsComment = false; + let textToMeasure; + + /* + * We can short-circuit the comment checks if we're already out of + * comments to check. + */ + if (commentsIndex < comments.length) { + let comment = null; + + // iterate over comments until we find one past the current line + do { + comment = comments[++commentsIndex]; + } while (comment && comment.loc.start.line <= lineNumber); + + // and step back by one + comment = comments[--commentsIndex]; + + if (isFullLineComment(line, lineNumber, comment)) { + lineIsComment = true; + textToMeasure = line; + } else if (ignoreTrailingComments && isTrailingComment(line, lineNumber, comment)) { + textToMeasure = stripTrailingComment(line, comment); + + // ignore multiple trailing comments in the same line + let lastIndex = commentsIndex; + + while (isTrailingComment(textToMeasure, lineNumber, comments[--lastIndex])) { + textToMeasure = stripTrailingComment(textToMeasure, comments[lastIndex]); + } + } else { + textToMeasure = line; + } + } else { + textToMeasure = line; + } + if (ignorePattern && ignorePattern.test(textToMeasure) || + ignoreUrls && URL_REGEXP.test(textToMeasure) || + ignoreStrings && stringsByLine[lineNumber] || + ignoreTemplateLiterals && templateLiteralsByLine[lineNumber] || + ignoreRegExpLiterals && regExpLiteralsByLine[lineNumber] + ) { + + // ignore this line + return; + } + + const lineLength = computeLineLength(textToMeasure, tabWidth); + const commentLengthApplies = lineIsComment && maxCommentLength; + + if (lineIsComment && ignoreComments) { + return; + } + + const loc = { + start: { + line: lineNumber, + column: 0 + }, + end: { + line: lineNumber, + column: textToMeasure.length + } + }; + + if (commentLengthApplies) { + if (lineLength > maxCommentLength) { + context.report({ + node, + loc, + messageId: "maxComment", + data: { + lineLength, + maxCommentLength + } + }); + } + } else if (lineLength > maxLength) { + context.report({ + node, + loc, + messageId: "max", + data: { + lineLength, + maxLength + } + }); + } + }); + } + + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + Program: checkProgramForMaxLength + }; + + } +}; + +/** + * @fileoverview enforce a maximum file length + * @author Alberto Rodríguez + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var maxLines = { + meta: { + type: "suggestion", + + docs: { + description: "enforce a maximum number of lines per file", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/max-lines" + }, + + schema: [ + { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + type: "object", + properties: { + max: { + type: "integer", + minimum: 0 + }, + skipComments: { + type: "boolean" + }, + skipBlankLines: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + } + ], + messages: { + exceed: + "File has too many lines ({{actual}}). Maximum allowed is {{max}}." + } + }, + + create(context) { + const option = context.options[0]; + let max = 300; + + if ( + typeof option === "object" && + Object.prototype.hasOwnProperty.call(option, "max") + ) { + max = option.max; + } else if (typeof option === "number") { + max = option; + } + + const skipComments = option && option.skipComments; + const skipBlankLines = option && option.skipBlankLines; + + const sourceCode = context.getSourceCode(); + + /** + * Returns whether or not a token is a comment node type + * @param {Token} token The token to check + * @returns {boolean} True if the token is a comment node + */ + function isCommentNodeType(token) { + return token && (token.type === "Block" || token.type === "Line"); + } + + /** + * Returns the line numbers of a comment that don't have any code on the same line + * @param {Node} comment The comment node to check + * @returns {number[]} The line numbers + */ + function getLinesWithoutCode(comment) { + let start = comment.loc.start.line; + let end = comment.loc.end.line; + + let token; + + token = comment; + do { + token = sourceCode.getTokenBefore(token, { + includeComments: true + }); + } while (isCommentNodeType(token)); + + if (token && astUtils.isTokenOnSameLine(token, comment)) { + start += 1; + } + + token = comment; + do { + token = sourceCode.getTokenAfter(token, { + includeComments: true + }); + } while (isCommentNodeType(token)); + + if (token && astUtils.isTokenOnSameLine(comment, token)) { + end -= 1; + } + + if (start <= end) { + return lodash__default['default'].range(start, end + 1); + } + return []; + } + + return { + "Program:exit"() { + let lines = sourceCode.lines.map((text, i) => ({ + lineNumber: i + 1, + text + })); + + /* + * If file ends with a linebreak, `sourceCode.lines` will have one extra empty line at the end. + * That isn't a real line, so we shouldn't count it. + */ + if (lines.length > 1 && lodash__default['default'].last(lines).text === "") { + lines.pop(); + } + + if (skipBlankLines) { + lines = lines.filter(l => l.text.trim() !== ""); + } + + if (skipComments) { + const comments = sourceCode.getAllComments(); + + const commentLines = lodash__default['default'].flatten( + comments.map(comment => getLinesWithoutCode(comment)) + ); + + lines = lines.filter( + l => !commentLines.includes(l.lineNumber) + ); + } + + if (lines.length > max) { + const loc = { + start: { + line: lines[max].lineNumber, + column: 0 + }, + end: { + line: sourceCode.lines.length, + column: lodash__default['default'].last(sourceCode.lines).length + } + }; + + context.report({ + loc, + messageId: "exceed", + data: { + max, + actual: lines.length + } + }); + } + } + }; + } +}; + +/** + * @fileoverview A rule to set the maximum number of line of code in a function. + * @author Pete Ward + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + + +//------------------------------------------------------------------------------ +// Constants +//------------------------------------------------------------------------------ + +const OPTIONS_SCHEMA = { + type: "object", + properties: { + max: { + type: "integer", + minimum: 0 + }, + skipComments: { + type: "boolean" + }, + skipBlankLines: { + type: "boolean" + }, + IIFEs: { + type: "boolean" + } + }, + additionalProperties: false +}; + +const OPTIONS_OR_INTEGER_SCHEMA = { + oneOf: [ + OPTIONS_SCHEMA, + { + type: "integer", + minimum: 1 + } + ] +}; + +/** + * Given a list of comment nodes, return a map with numeric keys (source code line numbers) and comment token values. + * @param {Array} comments An array of comment nodes. + * @returns {Map.} A map with numeric keys (source code line numbers) and comment token values. + */ +function getCommentLineNumbers(comments) { + const map = new Map(); + + comments.forEach(comment => { + for (let i = comment.loc.start.line; i <= comment.loc.end.line; i++) { + map.set(i, comment); + } + }); + return map; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var maxLinesPerFunction = { + meta: { + type: "suggestion", + + docs: { + description: "enforce a maximum number of lines of code in a function", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/max-lines-per-function" + }, + + schema: [ + OPTIONS_OR_INTEGER_SCHEMA + ], + messages: { + exceed: "{{name}} has too many lines ({{lineCount}}). Maximum allowed is {{maxLines}}." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const lines = sourceCode.lines; + + const option = context.options[0]; + let maxLines = 50; + let skipComments = false; + let skipBlankLines = false; + let IIFEs = false; + + if (typeof option === "object") { + maxLines = typeof option.max === "number" ? option.max : 50; + skipComments = !!option.skipComments; + skipBlankLines = !!option.skipBlankLines; + IIFEs = !!option.IIFEs; + } else if (typeof option === "number") { + maxLines = option; + } + + const commentLineNumbers = getCommentLineNumbers(sourceCode.getAllComments()); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Tells if a comment encompasses the entire line. + * @param {string} line The source line with a trailing comment + * @param {number} lineNumber The one-indexed line number this is on + * @param {ASTNode} comment The comment to remove + * @returns {boolean} If the comment covers the entire line + */ + function isFullLineComment(line, lineNumber, comment) { + const start = comment.loc.start, + end = comment.loc.end, + isFirstTokenOnLine = start.line === lineNumber && !line.slice(0, start.column).trim(), + isLastTokenOnLine = end.line === lineNumber && !line.slice(end.column).trim(); + + return comment && + (start.line < lineNumber || isFirstTokenOnLine) && + (end.line > lineNumber || isLastTokenOnLine); + } + + /** + * Identifies is a node is a FunctionExpression which is part of an IIFE + * @param {ASTNode} node Node to test + * @returns {boolean} True if it's an IIFE + */ + function isIIFE(node) { + return (node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression") && node.parent && node.parent.type === "CallExpression" && node.parent.callee === node; + } + + /** + * Identifies is a node is a FunctionExpression which is embedded within a MethodDefinition or Property + * @param {ASTNode} node Node to test + * @returns {boolean} True if it's a FunctionExpression embedded within a MethodDefinition or Property + */ + function isEmbedded(node) { + if (!node.parent) { + return false; + } + if (node !== node.parent.value) { + return false; + } + if (node.parent.type === "MethodDefinition") { + return true; + } + if (node.parent.type === "Property") { + return node.parent.method === true || node.parent.kind === "get" || node.parent.kind === "set"; + } + return false; + } + + /** + * Count the lines in the function + * @param {ASTNode} funcNode Function AST node + * @returns {void} + * @private + */ + function processFunction(funcNode) { + const node = isEmbedded(funcNode) ? funcNode.parent : funcNode; + + if (!IIFEs && isIIFE(node)) { + return; + } + let lineCount = 0; + + for (let i = node.loc.start.line - 1; i < node.loc.end.line; ++i) { + const line = lines[i]; + + if (skipComments) { + if (commentLineNumbers.has(i + 1) && isFullLineComment(line, i + 1, commentLineNumbers.get(i + 1))) { + continue; + } + } + + if (skipBlankLines) { + if (line.match(/^\s*$/u)) { + continue; + } + } + + lineCount++; + } + + if (lineCount > maxLines) { + const name = lodash__default['default'].upperFirst(astUtils.getFunctionNameWithKind(funcNode)); + + context.report({ + node, + messageId: "exceed", + data: { name, lineCount, maxLines } + }); + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + FunctionDeclaration: processFunction, + FunctionExpression: processFunction, + ArrowFunctionExpression: processFunction + }; + } +}; + +/** + * @fileoverview Rule to enforce a maximum number of nested callbacks. + * @author Ian Christian Myers + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var maxNestedCallbacks = { + meta: { + type: "suggestion", + + docs: { + description: "enforce a maximum depth that callbacks can be nested", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/max-nested-callbacks" + }, + + schema: [ + { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + type: "object", + properties: { + maximum: { + type: "integer", + minimum: 0 + }, + max: { + type: "integer", + minimum: 0 + } + }, + additionalProperties: false + } + ] + } + ], + messages: { + exceed: "Too many nested callbacks ({{num}}). Maximum allowed is {{max}}." + } + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Constants + //-------------------------------------------------------------------------- + const option = context.options[0]; + let THRESHOLD = 10; + + if ( + typeof option === "object" && + (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max")) + ) { + THRESHOLD = option.maximum || option.max; + } else if (typeof option === "number") { + THRESHOLD = option; + } + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + const callbackStack = []; + + /** + * Checks a given function node for too many callbacks. + * @param {ASTNode} node The node to check. + * @returns {void} + * @private + */ + function checkFunction(node) { + const parent = node.parent; + + if (parent.type === "CallExpression") { + callbackStack.push(node); + } + + if (callbackStack.length > THRESHOLD) { + const opts = { num: callbackStack.length, max: THRESHOLD }; + + context.report({ node, messageId: "exceed", data: opts }); + } + } + + /** + * Pops the call stack. + * @returns {void} + * @private + */ + function popStack() { + callbackStack.pop(); + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + ArrowFunctionExpression: checkFunction, + "ArrowFunctionExpression:exit": popStack, + + FunctionExpression: checkFunction, + "FunctionExpression:exit": popStack + }; + + } +}; + +/** + * @fileoverview Rule to flag when a function has too many parameters + * @author Ilya Volodin + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var maxParams = { + meta: { + type: "suggestion", + + docs: { + description: "enforce a maximum number of parameters in function definitions", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/max-params" + }, + + schema: [ + { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + type: "object", + properties: { + maximum: { + type: "integer", + minimum: 0 + }, + max: { + type: "integer", + minimum: 0 + } + }, + additionalProperties: false + } + ] + } + ], + messages: { + exceed: "{{name}} has too many parameters ({{count}}). Maximum allowed is {{max}}." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const option = context.options[0]; + let numParams = 3; + + if ( + typeof option === "object" && + (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max")) + ) { + numParams = option.maximum || option.max; + } + if (typeof option === "number") { + numParams = option; + } + + /** + * Checks a function to see if it has too many parameters. + * @param {ASTNode} node The node to check. + * @returns {void} + * @private + */ + function checkFunction(node) { + if (node.params.length > numParams) { + context.report({ + loc: astUtils.getFunctionHeadLoc(node, sourceCode), + node, + messageId: "exceed", + data: { + name: lodash__default['default'].upperFirst(astUtils.getFunctionNameWithKind(node)), + count: node.params.length, + max: numParams + } + }); + } + } + + return { + FunctionDeclaration: checkFunction, + ArrowFunctionExpression: checkFunction, + FunctionExpression: checkFunction + }; + + } +}; + +/** + * @fileoverview A rule to set the maximum number of statements in a function. + * @author Ian Christian Myers + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var maxStatements = { + meta: { + type: "suggestion", + + docs: { + description: "enforce a maximum number of statements allowed in function blocks", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/max-statements" + }, + + schema: [ + { + oneOf: [ + { + type: "integer", + minimum: 0 + }, + { + type: "object", + properties: { + maximum: { + type: "integer", + minimum: 0 + }, + max: { + type: "integer", + minimum: 0 + } + }, + additionalProperties: false + } + ] + }, + { + type: "object", + properties: { + ignoreTopLevelFunctions: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + messages: { + exceed: "{{name}} has too many statements ({{count}}). Maximum allowed is {{max}}." + } + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + const functionStack = [], + option = context.options[0], + ignoreTopLevelFunctions = context.options[1] && context.options[1].ignoreTopLevelFunctions || false, + topLevelFunctions = []; + let maxStatements = 10; + + if ( + typeof option === "object" && + (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max")) + ) { + maxStatements = option.maximum || option.max; + } else if (typeof option === "number") { + maxStatements = option; + } + + /** + * Reports a node if it has too many statements + * @param {ASTNode} node node to evaluate + * @param {int} count Number of statements in node + * @param {int} max Maximum number of statements allowed + * @returns {void} + * @private + */ + function reportIfTooManyStatements(node, count, max) { + if (count > max) { + const name = lodash__default['default'].upperFirst(astUtils.getFunctionNameWithKind(node)); + + context.report({ + node, + messageId: "exceed", + data: { name, count, max } + }); + } + } + + /** + * When parsing a new function, store it in our function stack + * @returns {void} + * @private + */ + function startFunction() { + functionStack.push(0); + } + + /** + * Evaluate the node at the end of function + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function endFunction(node) { + const count = functionStack.pop(); + + if (ignoreTopLevelFunctions && functionStack.length === 0) { + topLevelFunctions.push({ node, count }); + } else { + reportIfTooManyStatements(node, count, maxStatements); + } + } + + /** + * Increment the count of the functions + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function countStatements(node) { + functionStack[functionStack.length - 1] += node.body.length; + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + FunctionDeclaration: startFunction, + FunctionExpression: startFunction, + ArrowFunctionExpression: startFunction, + + BlockStatement: countStatements, + + "FunctionDeclaration:exit": endFunction, + "FunctionExpression:exit": endFunction, + "ArrowFunctionExpression:exit": endFunction, + + "Program:exit"() { + if (topLevelFunctions.length === 1) { + return; + } + + topLevelFunctions.forEach(element => { + const count = element.count; + const node = element.node; + + reportIfTooManyStatements(node, count, maxStatements); + }); + } + }; + + } +}; + +/** + * @fileoverview Specify the maximum number of statements allowed per line. + * @author Kenneth Williams + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var maxStatementsPerLine = { + meta: { + type: "layout", + + docs: { + description: "enforce a maximum number of statements allowed per line", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/max-statements-per-line" + }, + + schema: [ + { + type: "object", + properties: { + max: { + type: "integer", + minimum: 1, + default: 1 + } + }, + additionalProperties: false + } + ], + messages: { + exceed: "This line has {{numberOfStatementsOnThisLine}} {{statements}}. Maximum allowed is {{maxStatementsPerLine}}." + } + }, + + create(context) { + + const sourceCode = context.getSourceCode(), + options = context.options[0] || {}, + maxStatementsPerLine = typeof options.max !== "undefined" ? options.max : 1; + + let lastStatementLine = 0, + numberOfStatementsOnThisLine = 0, + firstExtraStatement; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + const SINGLE_CHILD_ALLOWED = /^(?:(?:DoWhile|For|ForIn|ForOf|If|Labeled|While)Statement|Export(?:Default|Named)Declaration)$/u; + + /** + * Reports with the first extra statement, and clears it. + * @returns {void} + */ + function reportFirstExtraStatementAndClear() { + if (firstExtraStatement) { + context.report({ + node: firstExtraStatement, + messageId: "exceed", + data: { + numberOfStatementsOnThisLine, + maxStatementsPerLine, + statements: numberOfStatementsOnThisLine === 1 ? "statement" : "statements" + } + }); + } + firstExtraStatement = null; + } + + /** + * Gets the actual last token of a given node. + * @param {ASTNode} node A node to get. This is a node except EmptyStatement. + * @returns {Token} The actual last token. + */ + function getActualLastToken(node) { + return sourceCode.getLastToken(node, astUtils.isNotSemicolonToken); + } + + /** + * Addresses a given node. + * It updates the state of this rule, then reports the node if the node violated this rule. + * @param {ASTNode} node A node to check. + * @returns {void} + */ + function enterStatement(node) { + const line = node.loc.start.line; + + /* + * Skip to allow non-block statements if this is direct child of control statements. + * `if (a) foo();` is counted as 1. + * But `if (a) foo(); else foo();` should be counted as 2. + */ + if (SINGLE_CHILD_ALLOWED.test(node.parent.type) && + node.parent.alternate !== node + ) { + return; + } + + // Update state. + if (line === lastStatementLine) { + numberOfStatementsOnThisLine += 1; + } else { + reportFirstExtraStatementAndClear(); + numberOfStatementsOnThisLine = 1; + lastStatementLine = line; + } + + // Reports if the node violated this rule. + if (numberOfStatementsOnThisLine === maxStatementsPerLine + 1) { + firstExtraStatement = firstExtraStatement || node; + } + } + + /** + * Updates the state of this rule with the end line of leaving node to check with the next statement. + * @param {ASTNode} node A node to check. + * @returns {void} + */ + function leaveStatement(node) { + const line = getActualLastToken(node).loc.end.line; + + // Update state. + if (line !== lastStatementLine) { + reportFirstExtraStatementAndClear(); + numberOfStatementsOnThisLine = 1; + lastStatementLine = line; + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + BreakStatement: enterStatement, + ClassDeclaration: enterStatement, + ContinueStatement: enterStatement, + DebuggerStatement: enterStatement, + DoWhileStatement: enterStatement, + ExpressionStatement: enterStatement, + ForInStatement: enterStatement, + ForOfStatement: enterStatement, + ForStatement: enterStatement, + FunctionDeclaration: enterStatement, + IfStatement: enterStatement, + ImportDeclaration: enterStatement, + LabeledStatement: enterStatement, + ReturnStatement: enterStatement, + SwitchStatement: enterStatement, + ThrowStatement: enterStatement, + TryStatement: enterStatement, + VariableDeclaration: enterStatement, + WhileStatement: enterStatement, + WithStatement: enterStatement, + ExportNamedDeclaration: enterStatement, + ExportDefaultDeclaration: enterStatement, + ExportAllDeclaration: enterStatement, + + "BreakStatement:exit": leaveStatement, + "ClassDeclaration:exit": leaveStatement, + "ContinueStatement:exit": leaveStatement, + "DebuggerStatement:exit": leaveStatement, + "DoWhileStatement:exit": leaveStatement, + "ExpressionStatement:exit": leaveStatement, + "ForInStatement:exit": leaveStatement, + "ForOfStatement:exit": leaveStatement, + "ForStatement:exit": leaveStatement, + "FunctionDeclaration:exit": leaveStatement, + "IfStatement:exit": leaveStatement, + "ImportDeclaration:exit": leaveStatement, + "LabeledStatement:exit": leaveStatement, + "ReturnStatement:exit": leaveStatement, + "SwitchStatement:exit": leaveStatement, + "ThrowStatement:exit": leaveStatement, + "TryStatement:exit": leaveStatement, + "VariableDeclaration:exit": leaveStatement, + "WhileStatement:exit": leaveStatement, + "WithStatement:exit": leaveStatement, + "ExportNamedDeclaration:exit": leaveStatement, + "ExportDefaultDeclaration:exit": leaveStatement, + "ExportAllDeclaration:exit": leaveStatement, + "Program:exit": reportFirstExtraStatementAndClear + }; + } +}; + +/** + * @fileoverview enforce a particular style for multiline comments + * @author Teddy Katz + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var multilineCommentStyle = { + meta: { + type: "suggestion", + + docs: { + description: "enforce a particular style for multiline comments", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/multiline-comment-style" + }, + + fixable: "whitespace", + schema: [{ enum: ["starred-block", "separate-lines", "bare-block"] }], + messages: { + expectedBlock: "Expected a block comment instead of consecutive line comments.", + expectedBareBlock: "Expected a block comment without padding stars.", + startNewline: "Expected a linebreak after '/*'.", + endNewline: "Expected a linebreak before '*/'.", + missingStar: "Expected a '*' at the start of this line.", + alignment: "Expected this line to be aligned with the start of the comment.", + expectedLines: "Expected multiple line comments instead of a block comment." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const option = context.options[0] || "starred-block"; + + //---------------------------------------------------------------------- + // Helpers + //---------------------------------------------------------------------- + + /** + * Checks if a comment line is starred. + * @param {string} line A string representing a comment line. + * @returns {boolean} Whether or not the comment line is starred. + */ + function isStarredCommentLine(line) { + return /^\s*\*/u.test(line); + } + + /** + * Checks if a comment group is in starred-block form. + * @param {Token[]} commentGroup A group of comments, containing either multiple line comments or a single block comment. + * @returns {boolean} Whether or not the comment group is in starred block form. + */ + function isStarredBlockComment([firstComment]) { + if (firstComment.type !== "Block") { + return false; + } + + const lines = firstComment.value.split(astUtils.LINEBREAK_MATCHER); + + // The first and last lines can only contain whitespace. + return lines.length > 0 && lines.every((line, i) => (i === 0 || i === lines.length - 1 ? /^\s*$/u : /^\s*\*/u).test(line)); + } + + /** + * Checks if a comment group is in JSDoc form. + * @param {Token[]} commentGroup A group of comments, containing either multiple line comments or a single block comment. + * @returns {boolean} Whether or not the comment group is in JSDoc form. + */ + function isJSDocComment([firstComment]) { + if (firstComment.type !== "Block") { + return false; + } + + const lines = firstComment.value.split(astUtils.LINEBREAK_MATCHER); + + return /^\*\s*$/u.test(lines[0]) && + lines.slice(1, -1).every(line => /^\s* /u.test(line)) && + /^\s*$/u.test(lines[lines.length - 1]); + } + + /** + * Processes a comment group that is currently in separate-line form, calculating the offset for each line. + * @param {Token[]} commentGroup A group of comments containing multiple line comments. + * @returns {string[]} An array of the processed lines. + */ + function processSeparateLineComments(commentGroup) { + const allLinesHaveLeadingSpace = commentGroup + .map(({ value }) => value) + .filter(line => line.trim().length) + .every(line => line.startsWith(" ")); + + return commentGroup.map(({ value }) => (allLinesHaveLeadingSpace ? value.replace(/^ /u, "") : value)); + } + + /** + * Processes a comment group that is currently in starred-block form, calculating the offset for each line. + * @param {Token} comment A single block comment token in starred-block form. + * @returns {string[]} An array of the processed lines. + */ + function processStarredBlockComment(comment) { + const lines = comment.value.split(astUtils.LINEBREAK_MATCHER) + .filter((line, i, linesArr) => !(i === 0 || i === linesArr.length - 1)) + .map(line => line.replace(/^\s*$/u, "")); + const allLinesHaveLeadingSpace = lines + .map(line => line.replace(/\s*\*/u, "")) + .filter(line => line.trim().length) + .every(line => line.startsWith(" ")); + + return lines.map(line => line.replace(allLinesHaveLeadingSpace ? /\s*\* ?/u : /\s*\*/u, "")); + } + + /** + * Processes a comment group that is currently in bare-block form, calculating the offset for each line. + * @param {Token} comment A single block comment token in bare-block form. + * @returns {string[]} An array of the processed lines. + */ + function processBareBlockComment(comment) { + const lines = comment.value.split(astUtils.LINEBREAK_MATCHER).map(line => line.replace(/^\s*$/u, "")); + const leadingWhitespace = `${sourceCode.text.slice(comment.range[0] - comment.loc.start.column, comment.range[0])} `; + let offset = ""; + + /* + * Calculate the offset of the least indented line and use that as the basis for offsetting all the lines. + * The first line should not be checked because it is inline with the opening block comment delimiter. + */ + for (const [i, line] of lines.entries()) { + if (!line.trim().length || i === 0) { + continue; + } + + const [, lineOffset] = line.match(/^(\s*\*?\s*)/u); + + if (lineOffset.length < leadingWhitespace.length) { + const newOffset = leadingWhitespace.slice(lineOffset.length - leadingWhitespace.length); + + if (newOffset.length > offset.length) { + offset = newOffset; + } + } + } + + return lines.map(line => { + const match = line.match(/^(\s*\*?\s*)(.*)/u); + const [, lineOffset, lineContents] = match; + + if (lineOffset.length > leadingWhitespace.length) { + return `${lineOffset.slice(leadingWhitespace.length - (offset.length + lineOffset.length))}${lineContents}`; + } + + if (lineOffset.length < leadingWhitespace.length) { + return `${lineOffset.slice(leadingWhitespace.length)}${lineContents}`; + } + + return lineContents; + }); + } + + /** + * Gets a list of comment lines in a group, formatting leading whitespace as necessary. + * @param {Token[]} commentGroup A group of comments containing either multiple line comments or a single block comment. + * @returns {string[]} A list of comment lines. + */ + function getCommentLines(commentGroup) { + const [firstComment] = commentGroup; + + if (firstComment.type === "Line") { + return processSeparateLineComments(commentGroup); + } + + if (isStarredBlockComment(commentGroup)) { + return processStarredBlockComment(firstComment); + } + + return processBareBlockComment(firstComment); + } + + /** + * Gets the initial offset (whitespace) from the beginning of a line to a given comment token. + * @param {Token} comment The token to check. + * @returns {string} The offset from the beginning of a line to the token. + */ + function getInitialOffset(comment) { + return sourceCode.text.slice(comment.range[0] - comment.loc.start.column, comment.range[0]); + } + + /** + * Converts a comment into starred-block form + * @param {Token} firstComment The first comment of the group being converted + * @param {string[]} commentLinesList A list of lines to appear in the new starred-block comment + * @returns {string} A representation of the comment value in starred-block form, excluding start and end markers + */ + function convertToStarredBlock(firstComment, commentLinesList) { + const initialOffset = getInitialOffset(firstComment); + + return `/*\n${commentLinesList.map(line => `${initialOffset} * ${line}`).join("\n")}\n${initialOffset} */`; + } + + /** + * Converts a comment into separate-line form + * @param {Token} firstComment The first comment of the group being converted + * @param {string[]} commentLinesList A list of lines to appear in the new starred-block comment + * @returns {string} A representation of the comment value in separate-line form + */ + function convertToSeparateLines(firstComment, commentLinesList) { + return commentLinesList.map(line => `// ${line}`).join(`\n${getInitialOffset(firstComment)}`); + } + + /** + * Converts a comment into bare-block form + * @param {Token} firstComment The first comment of the group being converted + * @param {string[]} commentLinesList A list of lines to appear in the new starred-block comment + * @returns {string} A representation of the comment value in bare-block form + */ + function convertToBlock(firstComment, commentLinesList) { + return `/* ${commentLinesList.join(`\n${getInitialOffset(firstComment)} `)} */`; + } + + /** + * Each method checks a group of comments to see if it's valid according to the given option. + * @param {Token[]} commentGroup A list of comments that appear together. This will either contain a single + * block comment or multiple line comments. + * @returns {void} + */ + const commentGroupCheckers = { + "starred-block"(commentGroup) { + const [firstComment] = commentGroup; + const commentLines = getCommentLines(commentGroup); + + if (commentLines.some(value => value.includes("*/"))) { + return; + } + + if (commentGroup.length > 1) { + context.report({ + loc: { + start: firstComment.loc.start, + end: commentGroup[commentGroup.length - 1].loc.end + }, + messageId: "expectedBlock", + fix(fixer) { + const range = [firstComment.range[0], commentGroup[commentGroup.length - 1].range[1]]; + + return commentLines.some(value => value.startsWith("/")) + ? null + : fixer.replaceTextRange(range, convertToStarredBlock(firstComment, commentLines)); + } + }); + } else { + const lines = firstComment.value.split(astUtils.LINEBREAK_MATCHER); + const expectedLeadingWhitespace = getInitialOffset(firstComment); + const expectedLinePrefix = `${expectedLeadingWhitespace} *`; + + if (!/^\*?\s*$/u.test(lines[0])) { + const start = firstComment.value.startsWith("*") ? firstComment.range[0] + 1 : firstComment.range[0]; + + context.report({ + loc: { + start: firstComment.loc.start, + end: { line: firstComment.loc.start.line, column: firstComment.loc.start.column + 2 } + }, + messageId: "startNewline", + fix: fixer => fixer.insertTextAfterRange([start, start + 2], `\n${expectedLinePrefix}`) + }); + } + + if (!/^\s*$/u.test(lines[lines.length - 1])) { + context.report({ + loc: { + start: { line: firstComment.loc.end.line, column: firstComment.loc.end.column - 2 }, + end: firstComment.loc.end + }, + messageId: "endNewline", + fix: fixer => fixer.replaceTextRange([firstComment.range[1] - 2, firstComment.range[1]], `\n${expectedLinePrefix}/`) + }); + } + + for (let lineNumber = firstComment.loc.start.line + 1; lineNumber <= firstComment.loc.end.line; lineNumber++) { + const lineText = sourceCode.lines[lineNumber - 1]; + const errorType = isStarredCommentLine(lineText) + ? "alignment" + : "missingStar"; + + if (!lineText.startsWith(expectedLinePrefix)) { + context.report({ + loc: { + start: { line: lineNumber, column: 0 }, + end: { line: lineNumber, column: lineText.length } + }, + messageId: errorType, + fix(fixer) { + const lineStartIndex = sourceCode.getIndexFromLoc({ line: lineNumber, column: 0 }); + + if (errorType === "alignment") { + const [, commentTextPrefix = ""] = lineText.match(/^(\s*\*)/u) || []; + const commentTextStartIndex = lineStartIndex + commentTextPrefix.length; + + return fixer.replaceTextRange([lineStartIndex, commentTextStartIndex], expectedLinePrefix); + } + + const [, commentTextPrefix = ""] = lineText.match(/^(\s*)/u) || []; + const commentTextStartIndex = lineStartIndex + commentTextPrefix.length; + let offset; + + for (const [idx, line] of lines.entries()) { + if (!/\S+/u.test(line)) { + continue; + } + + const lineTextToAlignWith = sourceCode.lines[firstComment.loc.start.line - 1 + idx]; + const [, prefix = "", initialOffset = ""] = lineTextToAlignWith.match(/^(\s*(?:\/?\*)?(\s*))/u) || []; + + offset = `${commentTextPrefix.slice(prefix.length)}${initialOffset}`; + + if (/^\s*\//u.test(lineText) && offset.length === 0) { + offset += " "; + } + break; + } + + return fixer.replaceTextRange([lineStartIndex, commentTextStartIndex], `${expectedLinePrefix}${offset}`); + } + }); + } + } + } + }, + "separate-lines"(commentGroup) { + const [firstComment] = commentGroup; + + if (firstComment.type !== "Block" || isJSDocComment(commentGroup)) { + return; + } + + const commentLines = getCommentLines(commentGroup); + const tokenAfter = sourceCode.getTokenAfter(firstComment, { includeComments: true }); + + if (tokenAfter && firstComment.loc.end.line === tokenAfter.loc.start.line) { + return; + } + + context.report({ + loc: { + start: firstComment.loc.start, + end: { line: firstComment.loc.start.line, column: firstComment.loc.start.column + 2 } + }, + messageId: "expectedLines", + fix(fixer) { + return fixer.replaceText(firstComment, convertToSeparateLines(firstComment, commentLines)); + } + }); + }, + "bare-block"(commentGroup) { + if (isJSDocComment(commentGroup)) { + return; + } + + const [firstComment] = commentGroup; + const commentLines = getCommentLines(commentGroup); + + // Disallows consecutive line comments in favor of using a block comment. + if (firstComment.type === "Line" && commentLines.length > 1 && + !commentLines.some(value => value.includes("*/"))) { + context.report({ + loc: { + start: firstComment.loc.start, + end: commentGroup[commentGroup.length - 1].loc.end + }, + messageId: "expectedBlock", + fix(fixer) { + return fixer.replaceTextRange( + [firstComment.range[0], commentGroup[commentGroup.length - 1].range[1]], + convertToBlock(firstComment, commentLines) + ); + } + }); + } + + // Prohibits block comments from having a * at the beginning of each line. + if (isStarredBlockComment(commentGroup)) { + context.report({ + loc: { + start: firstComment.loc.start, + end: { line: firstComment.loc.start.line, column: firstComment.loc.start.column + 2 } + }, + messageId: "expectedBareBlock", + fix(fixer) { + return fixer.replaceText(firstComment, convertToBlock(firstComment, commentLines)); + } + }); + } + } + }; + + //---------------------------------------------------------------------- + // Public + //---------------------------------------------------------------------- + + return { + Program() { + return sourceCode.getAllComments() + .filter(comment => comment.type !== "Shebang") + .filter(comment => !astUtils.COMMENTS_IGNORE_PATTERN.test(comment.value)) + .filter(comment => { + const tokenBefore = sourceCode.getTokenBefore(comment, { includeComments: true }); + + return !tokenBefore || tokenBefore.loc.end.line < comment.loc.start.line; + }) + .reduce((commentGroups, comment, index, commentList) => { + const tokenBefore = sourceCode.getTokenBefore(comment, { includeComments: true }); + + if ( + comment.type === "Line" && + index && commentList[index - 1].type === "Line" && + tokenBefore && tokenBefore.loc.end.line === comment.loc.start.line - 1 && + tokenBefore === commentList[index - 1] + ) { + commentGroups[commentGroups.length - 1].push(comment); + } else { + commentGroups.push([comment]); + } + + return commentGroups; + }, []) + .filter(commentGroup => !(commentGroup.length === 1 && commentGroup[0].loc.start.line === commentGroup[0].loc.end.line)) + .forEach(commentGroupCheckers[option]); + } + }; + } +}; + +/** + * @fileoverview Enforce newlines between operands of ternary expressions + * @author Kai Cataldo + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var multilineTernary = { + meta: { + type: "layout", + + docs: { + description: "enforce newlines between operands of ternary expressions", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/multiline-ternary" + }, + + schema: [ + { + enum: ["always", "always-multiline", "never"] + } + ], + + messages: { + expectedTestCons: "Expected newline between test and consequent of ternary expression.", + expectedConsAlt: "Expected newline between consequent and alternate of ternary expression.", + unexpectedTestCons: "Unexpected newline between test and consequent of ternary expression.", + unexpectedConsAlt: "Unexpected newline between consequent and alternate of ternary expression." + }, + + fixable: "whitespace" + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const option = context.options[0]; + const multiline = option !== "never"; + const allowSingleLine = option === "always-multiline"; + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + ConditionalExpression(node) { + const questionToken = sourceCode.getTokenAfter(node.test, astUtils.isNotClosingParenToken); + const colonToken = sourceCode.getTokenAfter(node.consequent, astUtils.isNotClosingParenToken); + + const firstTokenOfTest = sourceCode.getFirstToken(node); + const lastTokenOfTest = sourceCode.getTokenBefore(questionToken); + const firstTokenOfConsequent = sourceCode.getTokenAfter(questionToken); + const lastTokenOfConsequent = sourceCode.getTokenBefore(colonToken); + const firstTokenOfAlternate = sourceCode.getTokenAfter(colonToken); + + const areTestAndConsequentOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfTest, firstTokenOfConsequent); + const areConsequentAndAlternateOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfConsequent, firstTokenOfAlternate); + + const hasComments = !!sourceCode.getCommentsInside(node).length; + + if (!multiline) { + if (!areTestAndConsequentOnSameLine) { + context.report({ + node: node.test, + loc: { + start: firstTokenOfTest.loc.start, + end: lastTokenOfTest.loc.end + }, + messageId: "unexpectedTestCons", + fix: fixer => { + if (hasComments) { + return null; + } + const fixers = []; + const areTestAndQuestionOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfTest, questionToken); + const areQuestionAndConsOnSameLine = astUtils.isTokenOnSameLine(questionToken, firstTokenOfConsequent); + + if (!areTestAndQuestionOnSameLine) { + fixers.push(fixer.removeRange([lastTokenOfTest.range[1], questionToken.range[0]])); + } + if (!areQuestionAndConsOnSameLine) { + fixers.push(fixer.removeRange([questionToken.range[1], firstTokenOfConsequent.range[0]])); + } + + return fixers; + } + }); + } + + if (!areConsequentAndAlternateOnSameLine) { + context.report({ + node: node.consequent, + loc: { + start: firstTokenOfConsequent.loc.start, + end: lastTokenOfConsequent.loc.end + }, + messageId: "unexpectedConsAlt", + fix: fixer => { + if (hasComments) { + return null; + } + const fixers = []; + const areConsAndColonOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfConsequent, colonToken); + const areColonAndAltOnSameLine = astUtils.isTokenOnSameLine(colonToken, firstTokenOfAlternate); + + if (!areConsAndColonOnSameLine) { + fixers.push(fixer.removeRange([lastTokenOfConsequent.range[1], colonToken.range[0]])); + } + if (!areColonAndAltOnSameLine) { + fixers.push(fixer.removeRange([colonToken.range[1], firstTokenOfAlternate.range[0]])); + } + + return fixers; + } + }); + } + } else { + if (allowSingleLine && node.loc.start.line === node.loc.end.line) { + return; + } + + if (areTestAndConsequentOnSameLine) { + context.report({ + node: node.test, + loc: { + start: firstTokenOfTest.loc.start, + end: lastTokenOfTest.loc.end + }, + messageId: "expectedTestCons", + fix: fixer => (hasComments ? null : ( + fixer.replaceTextRange( + [ + lastTokenOfTest.range[1], + questionToken.range[0] + ], + "\n" + ) + )) + }); + } + + if (areConsequentAndAlternateOnSameLine) { + context.report({ + node: node.consequent, + loc: { + start: firstTokenOfConsequent.loc.start, + end: lastTokenOfConsequent.loc.end + }, + messageId: "expectedConsAlt", + fix: (fixer => (hasComments ? null : ( + fixer.replaceTextRange( + [ + lastTokenOfConsequent.range[1], + colonToken.range[0] + ], + "\n" + ) + ))) + }); + } + } + } + }; + } +}; + +/** + * @fileoverview Rule to flag use of constructors without capital letters + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const CAPS_ALLOWED = [ + "Array", + "Boolean", + "Date", + "Error", + "Function", + "Number", + "Object", + "RegExp", + "String", + "Symbol", + "BigInt" +]; + +/** + * Ensure that if the key is provided, it must be an array. + * @param {Object} obj Object to check with `key`. + * @param {string} key Object key to check on `obj`. + * @param {*} fallback If obj[key] is not present, this will be returned. + * @returns {string[]} Returns obj[key] if it's an Array, otherwise `fallback` + */ +function checkArray(obj, key, fallback) { + + /* istanbul ignore if */ + if (Object.prototype.hasOwnProperty.call(obj, key) && !Array.isArray(obj[key])) { + throw new TypeError(`${key}, if provided, must be an Array`); + } + return obj[key] || fallback; +} + +/** + * A reducer function to invert an array to an Object mapping the string form of the key, to `true`. + * @param {Object} map Accumulator object for the reduce. + * @param {string} key Object key to set to `true`. + * @returns {Object} Returns the updated Object for further reduction. + */ +function invert(map, key) { + map[key] = true; + return map; +} + +/** + * Creates an object with the cap is new exceptions as its keys and true as their values. + * @param {Object} config Rule configuration + * @returns {Object} Object with cap is new exceptions. + */ +function calculateCapIsNewExceptions(config) { + let capIsNewExceptions = checkArray(config, "capIsNewExceptions", CAPS_ALLOWED); + + if (capIsNewExceptions !== CAPS_ALLOWED) { + capIsNewExceptions = capIsNewExceptions.concat(CAPS_ALLOWED); + } + + return capIsNewExceptions.reduce(invert, {}); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var newCap = { + meta: { + type: "suggestion", + + docs: { + description: "require constructor names to begin with a capital letter", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/new-cap" + }, + + schema: [ + { + type: "object", + properties: { + newIsCap: { + type: "boolean", + default: true + }, + capIsNew: { + type: "boolean", + default: true + }, + newIsCapExceptions: { + type: "array", + items: { + type: "string" + } + }, + newIsCapExceptionPattern: { + type: "string" + }, + capIsNewExceptions: { + type: "array", + items: { + type: "string" + } + }, + capIsNewExceptionPattern: { + type: "string" + }, + properties: { + type: "boolean", + default: true + } + }, + additionalProperties: false + } + ], + messages: { + upper: "A function with a name starting with an uppercase letter should only be used as a constructor.", + lower: "A constructor name should not start with a lowercase letter." + } + }, + + create(context) { + + const config = Object.assign({}, context.options[0]); + + config.newIsCap = config.newIsCap !== false; + config.capIsNew = config.capIsNew !== false; + const skipProperties = config.properties === false; + + const newIsCapExceptions = checkArray(config, "newIsCapExceptions", []).reduce(invert, {}); + const newIsCapExceptionPattern = config.newIsCapExceptionPattern ? new RegExp(config.newIsCapExceptionPattern, "u") : null; + + const capIsNewExceptions = calculateCapIsNewExceptions(config); + const capIsNewExceptionPattern = config.capIsNewExceptionPattern ? new RegExp(config.capIsNewExceptionPattern, "u") : null; + + const listeners = {}; + + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Get exact callee name from expression + * @param {ASTNode} node CallExpression or NewExpression node + * @returns {string} name + */ + function extractNameFromExpression(node) { + return node.callee.type === "Identifier" + ? node.callee.name + : astUtils.getStaticPropertyName(node.callee) || ""; + } + + /** + * Returns the capitalization state of the string - + * Whether the first character is uppercase, lowercase, or non-alphabetic + * @param {string} str String + * @returns {string} capitalization state: "non-alpha", "lower", or "upper" + */ + function getCap(str) { + const firstChar = str.charAt(0); + + const firstCharLower = firstChar.toLowerCase(); + const firstCharUpper = firstChar.toUpperCase(); + + if (firstCharLower === firstCharUpper) { + + // char has no uppercase variant, so it's non-alphabetic + return "non-alpha"; + } + if (firstChar === firstCharLower) { + return "lower"; + } + return "upper"; + + } + + /** + * Check if capitalization is allowed for a CallExpression + * @param {Object} allowedMap Object mapping calleeName to a Boolean + * @param {ASTNode} node CallExpression node + * @param {string} calleeName Capitalized callee name from a CallExpression + * @param {Object} pattern RegExp object from options pattern + * @returns {boolean} Returns true if the callee may be capitalized + */ + function isCapAllowed(allowedMap, node, calleeName, pattern) { + const sourceText = sourceCode.getText(node.callee); + + if (allowedMap[calleeName] || allowedMap[sourceText]) { + return true; + } + + if (pattern && pattern.test(sourceText)) { + return true; + } + + const callee = astUtils.skipChainExpression(node.callee); + + if (calleeName === "UTC" && callee.type === "MemberExpression") { + + // allow if callee is Date.UTC + return callee.object.type === "Identifier" && + callee.object.name === "Date"; + } + + return skipProperties && callee.type === "MemberExpression"; + } + + /** + * Reports the given messageId for the given node. The location will be the start of the property or the callee. + * @param {ASTNode} node CallExpression or NewExpression node. + * @param {string} messageId The messageId to report. + * @returns {void} + */ + function report(node, messageId) { + let callee = astUtils.skipChainExpression(node.callee); + + if (callee.type === "MemberExpression") { + callee = callee.property; + } + + context.report({ node, loc: callee.loc, messageId }); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + if (config.newIsCap) { + listeners.NewExpression = function(node) { + + const constructorName = extractNameFromExpression(node); + + if (constructorName) { + const capitalization = getCap(constructorName); + const isAllowed = capitalization !== "lower" || isCapAllowed(newIsCapExceptions, node, constructorName, newIsCapExceptionPattern); + + if (!isAllowed) { + report(node, "lower"); + } + } + }; + } + + if (config.capIsNew) { + listeners.CallExpression = function(node) { + + const calleeName = extractNameFromExpression(node); + + if (calleeName) { + const capitalization = getCap(calleeName); + const isAllowed = capitalization !== "upper" || isCapAllowed(capIsNewExceptions, node, calleeName, capIsNewExceptionPattern); + + if (!isAllowed) { + report(node, "upper"); + } + } + }; + } + + return listeners; + } +}; + +/** + * @fileoverview Rule to flag when using constructor without parentheses + * @author Ilya Volodin + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var newParens = { + meta: { + type: "layout", + + docs: { + description: "enforce or disallow parentheses when invoking a constructor with no arguments", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/new-parens" + }, + + fixable: "code", + schema: { + anyOf: [ + { + type: "array", + items: [ + { + enum: ["always", "never"] + } + ], + minItems: 0, + maxItems: 1 + } + ] + }, + messages: { + missing: "Missing '()' invoking a constructor.", + unnecessary: "Unnecessary '()' invoking a constructor with no arguments." + } + }, + + create(context) { + const options = context.options; + const always = options[0] !== "never"; // Default is always + + const sourceCode = context.getSourceCode(); + + return { + NewExpression(node) { + if (node.arguments.length !== 0) { + return; // if there are arguments, there have to be parens + } + + const lastToken = sourceCode.getLastToken(node); + const hasLastParen = lastToken && astUtils.isClosingParenToken(lastToken); + + // `hasParens` is true only if the new expression ends with its own parens, e.g., new new foo() does not end with its own parens + const hasParens = hasLastParen && + astUtils.isOpeningParenToken(sourceCode.getTokenBefore(lastToken)) && + node.callee.range[1] < node.range[1]; + + if (always) { + if (!hasParens) { + context.report({ + node, + messageId: "missing", + fix: fixer => fixer.insertTextAfter(node, "()") + }); + } + } else { + if (hasParens) { + context.report({ + node, + messageId: "unnecessary", + fix: fixer => [ + fixer.remove(sourceCode.getTokenBefore(lastToken)), + fixer.remove(lastToken), + fixer.insertTextBefore(node, "("), + fixer.insertTextAfter(node, ")") + ] + }); + } + } + } + }; + } +}; + +/** + * @fileoverview Rule to check empty newline after "var" statement + * @author Gopal Venkatesan + * @deprecated + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var newlineAfterVar = { + meta: { + type: "layout", + + docs: { + description: "require or disallow an empty line after variable declarations", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/newline-after-var" + }, + schema: [ + { + enum: ["never", "always"] + } + ], + fixable: "whitespace", + messages: { + expected: "Expected blank line after variable declarations.", + unexpected: "Unexpected blank line after variable declarations." + }, + + deprecated: true, + + replacedBy: ["padding-line-between-statements"] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + // Default `mode` to "always". + const mode = context.options[0] === "never" ? "never" : "always"; + + // Cache starting and ending line numbers of comments for faster lookup + const commentEndLine = sourceCode.getAllComments().reduce((result, token) => { + result[token.loc.start.line] = token.loc.end.line; + return result; + }, {}); + + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Gets a token from the given node to compare line to the next statement. + * + * In general, the token is the last token of the node. However, the token is the second last token if the following conditions satisfy. + * + * - The last token is semicolon. + * - The semicolon is on a different line from the previous token of the semicolon. + * + * This behavior would address semicolon-less style code. e.g.: + * + * var foo = 1 + * + * ;(a || b).doSomething() + * @param {ASTNode} node The node to get. + * @returns {Token} The token to compare line to the next statement. + */ + function getLastToken(node) { + const lastToken = sourceCode.getLastToken(node); + + if (lastToken.type === "Punctuator" && lastToken.value === ";") { + const prevToken = sourceCode.getTokenBefore(lastToken); + + if (prevToken.loc.end.line !== lastToken.loc.start.line) { + return prevToken; + } + } + + return lastToken; + } + + /** + * Determine if provided keyword is a variable declaration + * @private + * @param {string} keyword keyword to test + * @returns {boolean} True if `keyword` is a type of var + */ + function isVar(keyword) { + return keyword === "var" || keyword === "let" || keyword === "const"; + } + + /** + * Determine if provided keyword is a variant of for specifiers + * @private + * @param {string} keyword keyword to test + * @returns {boolean} True if `keyword` is a variant of for specifier + */ + function isForTypeSpecifier(keyword) { + return keyword === "ForStatement" || keyword === "ForInStatement" || keyword === "ForOfStatement"; + } + + /** + * Determine if provided keyword is an export specifiers + * @private + * @param {string} nodeType nodeType to test + * @returns {boolean} True if `nodeType` is an export specifier + */ + function isExportSpecifier(nodeType) { + return nodeType === "ExportNamedDeclaration" || nodeType === "ExportSpecifier" || + nodeType === "ExportDefaultDeclaration" || nodeType === "ExportAllDeclaration"; + } + + /** + * Determine if provided node is the last of their parent block. + * @private + * @param {ASTNode} node node to test + * @returns {boolean} True if `node` is last of their parent block. + */ + function isLastNode(node) { + const token = sourceCode.getTokenAfter(node); + + return !token || (token.type === "Punctuator" && token.value === "}"); + } + + /** + * Gets the last line of a group of consecutive comments + * @param {number} commentStartLine The starting line of the group + * @returns {number} The number of the last comment line of the group + */ + function getLastCommentLineOfBlock(commentStartLine) { + const currentCommentEnd = commentEndLine[commentStartLine]; + + return commentEndLine[currentCommentEnd + 1] ? getLastCommentLineOfBlock(currentCommentEnd + 1) : currentCommentEnd; + } + + /** + * Determine if a token starts more than one line after a comment ends + * @param {token} token The token being checked + * @param {integer} commentStartLine The line number on which the comment starts + * @returns {boolean} True if `token` does not start immediately after a comment + */ + function hasBlankLineAfterComment(token, commentStartLine) { + return token.loc.start.line > getLastCommentLineOfBlock(commentStartLine) + 1; + } + + /** + * Checks that a blank line exists after a variable declaration when mode is + * set to "always", or checks that there is no blank line when mode is set + * to "never" + * @private + * @param {ASTNode} node `VariableDeclaration` node to test + * @returns {void} + */ + function checkForBlankLine(node) { + + /* + * lastToken is the last token on the node's line. It will usually also be the last token of the node, but it will + * sometimes be second-last if there is a semicolon on a different line. + */ + const lastToken = getLastToken(node), + + /* + * If lastToken is the last token of the node, nextToken should be the token after the node. Otherwise, nextToken + * is the last token of the node. + */ + nextToken = lastToken === sourceCode.getLastToken(node) ? sourceCode.getTokenAfter(node) : sourceCode.getLastToken(node), + nextLineNum = lastToken.loc.end.line + 1; + + // Ignore if there is no following statement + if (!nextToken) { + return; + } + + // Ignore if parent of node is a for variant + if (isForTypeSpecifier(node.parent.type)) { + return; + } + + // Ignore if parent of node is an export specifier + if (isExportSpecifier(node.parent.type)) { + return; + } + + /* + * Some coding styles use multiple `var` statements, so do nothing if + * the next token is a `var` statement. + */ + if (nextToken.type === "Keyword" && isVar(nextToken.value)) { + return; + } + + // Ignore if it is last statement in a block + if (isLastNode(node)) { + return; + } + + // Next statement is not a `var`... + const noNextLineToken = nextToken.loc.start.line > nextLineNum; + const hasNextLineComment = (typeof commentEndLine[nextLineNum] !== "undefined"); + + if (mode === "never" && noNextLineToken && !hasNextLineComment) { + context.report({ + node, + messageId: "unexpected", + data: { identifier: node.name }, + fix(fixer) { + const linesBetween = sourceCode.getText().slice(lastToken.range[1], nextToken.range[0]).split(astUtils.LINEBREAK_MATCHER); + + return fixer.replaceTextRange([lastToken.range[1], nextToken.range[0]], `${linesBetween.slice(0, -1).join("")}\n${linesBetween[linesBetween.length - 1]}`); + } + }); + } + + // Token on the next line, or comment without blank line + if ( + mode === "always" && ( + !noNextLineToken || + hasNextLineComment && !hasBlankLineAfterComment(nextToken, nextLineNum) + ) + ) { + context.report({ + node, + messageId: "expected", + data: { identifier: node.name }, + fix(fixer) { + if ((noNextLineToken ? getLastCommentLineOfBlock(nextLineNum) : lastToken.loc.end.line) === nextToken.loc.start.line) { + return fixer.insertTextBefore(nextToken, "\n\n"); + } + + return fixer.insertTextBeforeRange([nextToken.range[0] - nextToken.loc.start.column, nextToken.range[1]], "\n"); + } + }); + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + VariableDeclaration: checkForBlankLine + }; + + } +}; + +/** + * @fileoverview Rule to require newlines before `return` statement + * @author Kai Cataldo + * @deprecated + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var newlineBeforeReturn = { + meta: { + type: "layout", + + docs: { + description: "require an empty line before `return` statements", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/newline-before-return" + }, + + fixable: "whitespace", + schema: [], + messages: { + expected: "Expected newline before return statement." + }, + + deprecated: true, + replacedBy: ["padding-line-between-statements"] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Tests whether node is preceded by supplied tokens + * @param {ASTNode} node node to check + * @param {Array} testTokens array of tokens to test against + * @returns {boolean} Whether or not the node is preceded by one of the supplied tokens + * @private + */ + function isPrecededByTokens(node, testTokens) { + const tokenBefore = sourceCode.getTokenBefore(node); + + return testTokens.some(token => tokenBefore.value === token); + } + + /** + * Checks whether node is the first node after statement or in block + * @param {ASTNode} node node to check + * @returns {boolean} Whether or not the node is the first node after statement or in block + * @private + */ + function isFirstNode(node) { + const parentType = node.parent.type; + + if (node.parent.body) { + return Array.isArray(node.parent.body) + ? node.parent.body[0] === node + : node.parent.body === node; + } + + if (parentType === "IfStatement") { + return isPrecededByTokens(node, ["else", ")"]); + } + if (parentType === "DoWhileStatement") { + return isPrecededByTokens(node, ["do"]); + } + if (parentType === "SwitchCase") { + return isPrecededByTokens(node, [":"]); + } + return isPrecededByTokens(node, [")"]); + + } + + /** + * Returns the number of lines of comments that precede the node + * @param {ASTNode} node node to check for overlapping comments + * @param {number} lineNumTokenBefore line number of previous token, to check for overlapping comments + * @returns {number} Number of lines of comments that precede the node + * @private + */ + function calcCommentLines(node, lineNumTokenBefore) { + const comments = sourceCode.getCommentsBefore(node); + let numLinesComments = 0; + + if (!comments.length) { + return numLinesComments; + } + + comments.forEach(comment => { + numLinesComments++; + + if (comment.type === "Block") { + numLinesComments += comment.loc.end.line - comment.loc.start.line; + } + + // avoid counting lines with inline comments twice + if (comment.loc.start.line === lineNumTokenBefore) { + numLinesComments--; + } + + if (comment.loc.end.line === node.loc.start.line) { + numLinesComments--; + } + }); + + return numLinesComments; + } + + /** + * Returns the line number of the token before the node that is passed in as an argument + * @param {ASTNode} node The node to use as the start of the calculation + * @returns {number} Line number of the token before `node` + * @private + */ + function getLineNumberOfTokenBefore(node) { + const tokenBefore = sourceCode.getTokenBefore(node); + let lineNumTokenBefore; + + /** + * Global return (at the beginning of a script) is a special case. + * If there is no token before `return`, then we expect no line + * break before the return. Comments are allowed to occupy lines + * before the global return, just no blank lines. + * Setting lineNumTokenBefore to zero in that case results in the + * desired behavior. + */ + if (tokenBefore) { + lineNumTokenBefore = tokenBefore.loc.end.line; + } else { + lineNumTokenBefore = 0; // global return at beginning of script + } + + return lineNumTokenBefore; + } + + /** + * Checks whether node is preceded by a newline + * @param {ASTNode} node node to check + * @returns {boolean} Whether or not the node is preceded by a newline + * @private + */ + function hasNewlineBefore(node) { + const lineNumNode = node.loc.start.line; + const lineNumTokenBefore = getLineNumberOfTokenBefore(node); + const commentLines = calcCommentLines(node, lineNumTokenBefore); + + return (lineNumNode - lineNumTokenBefore - commentLines) > 1; + } + + /** + * Checks whether it is safe to apply a fix to a given return statement. + * + * The fix is not considered safe if the given return statement has leading comments, + * as we cannot safely determine if the newline should be added before or after the comments. + * For more information, see: https://github.com/eslint/eslint/issues/5958#issuecomment-222767211 + * @param {ASTNode} node The return statement node to check. + * @returns {boolean} `true` if it can fix the node. + * @private + */ + function canFix(node) { + const leadingComments = sourceCode.getCommentsBefore(node); + const lastLeadingComment = leadingComments[leadingComments.length - 1]; + const tokenBefore = sourceCode.getTokenBefore(node); + + if (leadingComments.length === 0) { + return true; + } + + /* + * if the last leading comment ends in the same line as the previous token and + * does not share a line with the `return` node, we can consider it safe to fix. + * Example: + * function a() { + * var b; //comment + * return; + * } + */ + if (lastLeadingComment.loc.end.line === tokenBefore.loc.end.line && + lastLeadingComment.loc.end.line !== node.loc.start.line) { + return true; + } + + return false; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + ReturnStatement(node) { + if (!isFirstNode(node) && !hasNewlineBefore(node)) { + context.report({ + node, + messageId: "expected", + fix(fixer) { + if (canFix(node)) { + const tokenBefore = sourceCode.getTokenBefore(node); + const newlines = node.loc.start.line === tokenBefore.loc.end.line ? "\n\n" : "\n"; + + return fixer.insertTextBefore(node, newlines); + } + return null; + } + }); + } + } + }; + } +}; + +/** + * @fileoverview Rule to ensure newline per method call when chaining calls + * @author Rajendra Patil + * @author Burak Yigit Kaya + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var newlinePerChainedCall = { + meta: { + type: "layout", + + docs: { + description: "require a newline after each call in a method chain", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/newline-per-chained-call" + }, + + fixable: "whitespace", + + schema: [{ + type: "object", + properties: { + ignoreChainWithDepth: { + type: "integer", + minimum: 1, + maximum: 10, + default: 2 + } + }, + additionalProperties: false + }], + messages: { + expected: "Expected line break before `{{callee}}`." + } + }, + + create(context) { + + const options = context.options[0] || {}, + ignoreChainWithDepth = options.ignoreChainWithDepth || 2; + + const sourceCode = context.getSourceCode(); + + /** + * Get the prefix of a given MemberExpression node. + * If the MemberExpression node is a computed value it returns a + * left bracket. If not it returns a period. + * @param {ASTNode} node A MemberExpression node to get + * @returns {string} The prefix of the node. + */ + function getPrefix(node) { + if (node.computed) { + if (node.optional) { + return "?.["; + } + return "["; + } + if (node.optional) { + return "?."; + } + return "."; + } + + /** + * Gets the property text of a given MemberExpression node. + * If the text is multiline, this returns only the first line. + * @param {ASTNode} node A MemberExpression node to get. + * @returns {string} The property text of the node. + */ + function getPropertyText(node) { + const prefix = getPrefix(node); + const lines = sourceCode.getText(node.property).split(astUtils.LINEBREAK_MATCHER); + const suffix = node.computed && lines.length === 1 ? "]" : ""; + + return prefix + lines[0] + suffix; + } + + return { + "CallExpression:exit"(node) { + const callee = astUtils.skipChainExpression(node.callee); + + if (callee.type !== "MemberExpression") { + return; + } + + let parent = astUtils.skipChainExpression(callee.object); + let depth = 1; + + while (parent && parent.callee) { + depth += 1; + parent = astUtils.skipChainExpression(astUtils.skipChainExpression(parent.callee).object); + } + + if (depth > ignoreChainWithDepth && astUtils.isTokenOnSameLine(callee.object, callee.property)) { + const firstTokenAfterObject = sourceCode.getTokenAfter(callee.object, astUtils.isNotClosingParenToken); + + context.report({ + node: callee.property, + loc: { + start: firstTokenAfterObject.loc.start, + end: callee.loc.end + }, + messageId: "expected", + data: { + callee: getPropertyText(callee) + }, + fix(fixer) { + return fixer.insertTextBefore(firstTokenAfterObject, "\n"); + } + }); + } + } + }; + } +}; + +/** + * @fileoverview Rule to flag use of alert, confirm, prompt + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const { + getStaticPropertyName: getPropertyName$2, + getVariableByName, + skipChainExpression +} = astUtils; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks if the given name is a prohibited identifier. + * @param {string} name The name to check + * @returns {boolean} Whether or not the name is prohibited. + */ +function isProhibitedIdentifier(name) { + return /^(alert|confirm|prompt)$/u.test(name); +} + +/** + * Finds the eslint-scope reference in the given scope. + * @param {Object} scope The scope to search. + * @param {ASTNode} node The identifier node. + * @returns {Reference|null} Returns the found reference or null if none were found. + */ +function findReference(scope, node) { + const references = scope.references.filter(reference => reference.identifier.range[0] === node.range[0] && + reference.identifier.range[1] === node.range[1]); + + if (references.length === 1) { + return references[0]; + } + return null; +} + +/** + * Checks if the given identifier node is shadowed in the given scope. + * @param {Object} scope The current scope. + * @param {string} node The identifier node to check + * @returns {boolean} Whether or not the name is shadowed. + */ +function isShadowed$1(scope, node) { + const reference = findReference(scope, node); + + return reference && reference.resolved && reference.resolved.defs.length > 0; +} + +/** + * Checks if the given identifier node is a ThisExpression in the global scope or the global window property. + * @param {Object} scope The current scope. + * @param {string} node The identifier node to check + * @returns {boolean} Whether or not the node is a reference to the global object. + */ +function isGlobalThisReferenceOrGlobalWindow(scope, node) { + if (scope.type === "global" && node.type === "ThisExpression") { + return true; + } + if ( + node.type === "Identifier" && + ( + node.name === "window" || + (node.name === "globalThis" && getVariableByName(scope, "globalThis")) + ) + ) { + return !isShadowed$1(scope, node); + } + + return false; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noAlert = { + meta: { + type: "suggestion", + + docs: { + description: "disallow the use of `alert`, `confirm`, and `prompt`", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-alert" + }, + + schema: [], + + messages: { + unexpected: "Unexpected {{name}}." + } + }, + + create(context) { + return { + CallExpression(node) { + const callee = skipChainExpression(node.callee), + currentScope = context.getScope(); + + // without window. + if (callee.type === "Identifier") { + const name = callee.name; + + if (!isShadowed$1(currentScope, callee) && isProhibitedIdentifier(callee.name)) { + context.report({ + node, + messageId: "unexpected", + data: { name } + }); + } + + } else if (callee.type === "MemberExpression" && isGlobalThisReferenceOrGlobalWindow(currentScope, callee.object)) { + const name = getPropertyName$2(callee); + + if (isProhibitedIdentifier(name)) { + context.report({ + node, + messageId: "unexpected", + data: { name } + }); + } + } + } + }; + + } +}; + +/** + * @fileoverview Disallow construction of dense arrays using the Array constructor + * @author Matt DuVall + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noArrayConstructor = { + meta: { + type: "suggestion", + + docs: { + description: "disallow `Array` constructors", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-array-constructor" + }, + + schema: [], + + messages: { + preferLiteral: "The array literal notation [] is preferable." + } + }, + + create(context) { + + /** + * Disallow construction of dense arrays using the Array constructor + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function check(node) { + if ( + node.arguments.length !== 1 && + node.callee.type === "Identifier" && + node.callee.name === "Array" + ) { + context.report({ node, messageId: "preferLiteral" }); + } + } + + return { + CallExpression: check, + NewExpression: check + }; + + } +}; + +/** + * @fileoverview disallow using an async function as a Promise executor + * @author Teddy Katz + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noAsyncPromiseExecutor = { + meta: { + type: "problem", + + docs: { + description: "disallow using an async function as a Promise executor", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-async-promise-executor" + }, + + fixable: null, + schema: [], + messages: { + async: "Promise executor functions should not be async." + } + }, + + create(context) { + return { + "NewExpression[callee.name='Promise'][arguments.0.async=true]"(node) { + context.report({ + node: context.getSourceCode().getFirstToken(node.arguments[0], token => token.value === "async"), + messageId: "async" + }); + } + }; + } +}; + +/** + * @fileoverview Rule to disallow uses of await inside of loops. + * @author Nat Mote (nmote) + */ + +/** + * Check whether it should stop traversing ancestors at the given node. + * @param {ASTNode} node A node to check. + * @returns {boolean} `true` if it should stop traversing. + */ +function isBoundary(node) { + const t = node.type; + + return ( + t === "FunctionDeclaration" || + t === "FunctionExpression" || + t === "ArrowFunctionExpression" || + + /* + * Don't report the await expressions on for-await-of loop since it's + * asynchronous iteration intentionally. + */ + (t === "ForOfStatement" && node.await === true) + ); +} + +/** + * Check whether the given node is in loop. + * @param {ASTNode} node A node to check. + * @param {ASTNode} parent A parent node to check. + * @returns {boolean} `true` if the node is in loop. + */ +function isLooped(node, parent) { + switch (parent.type) { + case "ForStatement": + return ( + node === parent.test || + node === parent.update || + node === parent.body + ); + + case "ForOfStatement": + case "ForInStatement": + return node === parent.body; + + case "WhileStatement": + case "DoWhileStatement": + return node === parent.test || node === parent.body; + + default: + return false; + } +} + +var noAwaitInLoop = { + meta: { + type: "problem", + + docs: { + description: "disallow `await` inside of loops", + category: "Possible Errors", + recommended: false, + url: "https://eslint.org/docs/rules/no-await-in-loop" + }, + + schema: [], + + messages: { + unexpectedAwait: "Unexpected `await` inside a loop." + } + }, + create(context) { + + /** + * Validate an await expression. + * @param {ASTNode} awaitNode An AwaitExpression or ForOfStatement node to validate. + * @returns {void} + */ + function validate(awaitNode) { + if (awaitNode.type === "ForOfStatement" && !awaitNode.await) { + return; + } + + let node = awaitNode; + let parent = node.parent; + + while (parent && !isBoundary(parent)) { + if (isLooped(node, parent)) { + context.report({ + node: awaitNode, + messageId: "unexpectedAwait" + }); + return; + } + node = parent; + parent = parent.parent; + } + } + + return { + AwaitExpression: validate, + ForOfStatement: validate + }; + } +}; + +/** + * @fileoverview Rule to flag bitwise identifiers + * @author Nicholas C. Zakas + */ + +/* + * + * Set of bitwise operators. + * + */ +const BITWISE_OPERATORS$1 = [ + "^", "|", "&", "<<", ">>", ">>>", + "^=", "|=", "&=", "<<=", ">>=", ">>>=", + "~" +]; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noBitwise = { + meta: { + type: "suggestion", + + docs: { + description: "disallow bitwise operators", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-bitwise" + }, + + schema: [ + { + type: "object", + properties: { + allow: { + type: "array", + items: { + enum: BITWISE_OPERATORS$1 + }, + uniqueItems: true + }, + int32Hint: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + messages: { + unexpected: "Unexpected use of '{{operator}}'." + } + }, + + create(context) { + const options = context.options[0] || {}; + const allowed = options.allow || []; + const int32Hint = options.int32Hint === true; + + /** + * Reports an unexpected use of a bitwise operator. + * @param {ASTNode} node Node which contains the bitwise operator. + * @returns {void} + */ + function report(node) { + context.report({ node, messageId: "unexpected", data: { operator: node.operator } }); + } + + /** + * Checks if the given node has a bitwise operator. + * @param {ASTNode} node The node to check. + * @returns {boolean} Whether or not the node has a bitwise operator. + */ + function hasBitwiseOperator(node) { + return BITWISE_OPERATORS$1.indexOf(node.operator) !== -1; + } + + /** + * Checks if exceptions were provided, e.g. `{ allow: ['~', '|'] }`. + * @param {ASTNode} node The node to check. + * @returns {boolean} Whether or not the node has a bitwise operator. + */ + function allowedOperator(node) { + return allowed.indexOf(node.operator) !== -1; + } + + /** + * Checks if the given bitwise operator is used for integer typecasting, i.e. "|0" + * @param {ASTNode} node The node to check. + * @returns {boolean} whether the node is used in integer typecasting. + */ + function isInt32Hint(node) { + return int32Hint && node.operator === "|" && node.right && + node.right.type === "Literal" && node.right.value === 0; + } + + /** + * Report if the given node contains a bitwise operator. + * @param {ASTNode} node The node to check. + * @returns {void} + */ + function checkNodeForBitwiseOperator(node) { + if (hasBitwiseOperator(node) && !allowedOperator(node) && !isInt32Hint(node)) { + report(node); + } + } + + return { + AssignmentExpression: checkNodeForBitwiseOperator, + BinaryExpression: checkNodeForBitwiseOperator, + UnaryExpression: checkNodeForBitwiseOperator + }; + + } +}; + +/** + * @fileoverview disallow use of the Buffer() constructor + * @author Teddy Katz + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noBufferConstructor = { + meta: { + deprecated: true, + + replacedBy: [], + + type: "problem", + + docs: { + description: "disallow use of the `Buffer()` constructor", + category: "Node.js and CommonJS", + recommended: false, + url: "https://eslint.org/docs/rules/no-buffer-constructor" + }, + + schema: [], + + messages: { + deprecated: "{{expr}} is deprecated. Use Buffer.from(), Buffer.alloc(), or Buffer.allocUnsafe() instead." + } + }, + + create(context) { + + //---------------------------------------------------------------------- + // Public + //---------------------------------------------------------------------- + + return { + "CallExpression[callee.name='Buffer'], NewExpression[callee.name='Buffer']"(node) { + context.report({ + node, + messageId: "deprecated", + data: { expr: node.type === "CallExpression" ? "Buffer()" : "new Buffer()" } + }); + } + }; + } +}; + +/** + * @fileoverview Rule to flag use of arguments.callee and arguments.caller. + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noCaller = { + meta: { + type: "suggestion", + + docs: { + description: "disallow the use of `arguments.caller` or `arguments.callee`", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-caller" + }, + + schema: [], + + messages: { + unexpected: "Avoid arguments.{{prop}}." + } + }, + + create(context) { + + return { + + MemberExpression(node) { + const objectName = node.object.name, + propertyName = node.property.name; + + if (objectName === "arguments" && !node.computed && propertyName && propertyName.match(/^calle[er]$/u)) { + context.report({ node, messageId: "unexpected", data: { prop: propertyName } }); + } + + } + }; + + } +}; + +/** + * @fileoverview Rule to flag use of an lexical declarations inside a case clause + * @author Erik Arvidsson + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noCaseDeclarations = { + meta: { + type: "suggestion", + + docs: { + description: "disallow lexical declarations in case clauses", + category: "Best Practices", + recommended: true, + url: "https://eslint.org/docs/rules/no-case-declarations" + }, + + schema: [], + + messages: { + unexpected: "Unexpected lexical declaration in case block." + } + }, + + create(context) { + + /** + * Checks whether or not a node is a lexical declaration. + * @param {ASTNode} node A direct child statement of a switch case. + * @returns {boolean} Whether or not the node is a lexical declaration. + */ + function isLexicalDeclaration(node) { + switch (node.type) { + case "FunctionDeclaration": + case "ClassDeclaration": + return true; + case "VariableDeclaration": + return node.kind !== "var"; + default: + return false; + } + } + + return { + SwitchCase(node) { + for (let i = 0; i < node.consequent.length; i++) { + const statement = node.consequent[i]; + + if (isLexicalDeclaration(statement)) { + context.report({ + node: statement, + messageId: "unexpected" + }); + } + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag variable leak in CatchClauses in IE 8 and earlier + * @author Ian Christian Myers + * @deprecated in ESLint v5.1.0 + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noCatchShadow = { + meta: { + type: "suggestion", + + docs: { + description: "disallow `catch` clause parameters from shadowing variables in the outer scope", + category: "Variables", + recommended: false, + url: "https://eslint.org/docs/rules/no-catch-shadow" + }, + + replacedBy: ["no-shadow"], + + deprecated: true, + schema: [], + + messages: { + mutable: "Value of '{{name}}' may be overwritten in IE 8 and earlier." + } + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Check if the parameters are been shadowed + * @param {Object} scope current scope + * @param {string} name parameter name + * @returns {boolean} True is its been shadowed + */ + function paramIsShadowing(scope, name) { + return astUtils.getVariableByName(scope, name) !== null; + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + + "CatchClause[param!=null]"(node) { + let scope = context.getScope(); + + /* + * When ecmaVersion >= 6, CatchClause creates its own scope + * so start from one upper scope to exclude the current node + */ + if (scope.block === node) { + scope = scope.upper; + } + + if (paramIsShadowing(scope, node.param.name)) { + context.report({ node, messageId: "mutable", data: { name: node.param.name } }); + } + } + }; + + } +}; + +/** + * @fileoverview A rule to disallow modifying variables of class declarations + * @author Toru Nagashima + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noClassAssign = { + meta: { + type: "problem", + + docs: { + description: "disallow reassigning class members", + category: "ECMAScript 6", + recommended: true, + url: "https://eslint.org/docs/rules/no-class-assign" + }, + + schema: [], + + messages: { + class: "'{{name}}' is a class." + } + }, + + create(context) { + + /** + * Finds and reports references that are non initializer and writable. + * @param {Variable} variable A variable to check. + * @returns {void} + */ + function checkVariable(variable) { + astUtils.getModifyingReferences(variable.references).forEach(reference => { + context.report({ node: reference.identifier, messageId: "class", data: { name: reference.identifier.name } }); + + }); + } + + /** + * Finds and reports references that are non initializer and writable. + * @param {ASTNode} node A ClassDeclaration/ClassExpression node to check. + * @returns {void} + */ + function checkForClass(node) { + context.getDeclaredVariables(node).forEach(checkVariable); + } + + return { + ClassDeclaration: checkForClass, + ClassExpression: checkForClass + }; + + } +}; + +/** + * @fileoverview The rule should warn against code that tries to compare against -0. + * @author Aladdin-ADD + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noCompareNegZero = { + meta: { + type: "problem", + + docs: { + description: "disallow comparing against -0", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-compare-neg-zero" + }, + + fixable: null, + schema: [], + + messages: { + unexpected: "Do not use the '{{operator}}' operator to compare against -0." + } + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Checks a given node is -0 + * @param {ASTNode} node A node to check. + * @returns {boolean} `true` if the node is -0. + */ + function isNegZero(node) { + return node.type === "UnaryExpression" && node.operator === "-" && node.argument.type === "Literal" && node.argument.value === 0; + } + const OPERATORS_TO_CHECK = new Set([">", ">=", "<", "<=", "==", "===", "!=", "!=="]); + + return { + BinaryExpression(node) { + if (OPERATORS_TO_CHECK.has(node.operator)) { + if (isNegZero(node.left) || isNegZero(node.right)) { + context.report({ + node, + messageId: "unexpected", + data: { operator: node.operator } + }); + } + } + } + }; + } +}; + +/** + * @fileoverview Rule to flag assignment in a conditional statement's test expression + * @author Stephen Murray + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const TEST_CONDITION_PARENT_TYPES = new Set(["IfStatement", "WhileStatement", "DoWhileStatement", "ForStatement", "ConditionalExpression"]); + +const NODE_DESCRIPTIONS = { + DoWhileStatement: "a 'do...while' statement", + ForStatement: "a 'for' statement", + IfStatement: "an 'if' statement", + WhileStatement: "a 'while' statement" +}; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noCondAssign = { + meta: { + type: "problem", + + docs: { + description: "disallow assignment operators in conditional expressions", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-cond-assign" + }, + + schema: [ + { + enum: ["except-parens", "always"] + } + ], + + messages: { + unexpected: "Unexpected assignment within {{type}}.", + + // must match JSHint's error message + missing: "Expected a conditional expression and instead saw an assignment." + } + }, + + create(context) { + + const prohibitAssign = (context.options[0] || "except-parens"); + + const sourceCode = context.getSourceCode(); + + /** + * Check whether an AST node is the test expression for a conditional statement. + * @param {!Object} node The node to test. + * @returns {boolean} `true` if the node is the text expression for a conditional statement; otherwise, `false`. + */ + function isConditionalTestExpression(node) { + return node.parent && + TEST_CONDITION_PARENT_TYPES.has(node.parent.type) && + node === node.parent.test; + } + + /** + * Given an AST node, perform a bottom-up search for the first ancestor that represents a conditional statement. + * @param {!Object} node The node to use at the start of the search. + * @returns {?Object} The closest ancestor node that represents a conditional statement. + */ + function findConditionalAncestor(node) { + let currentAncestor = node; + + do { + if (isConditionalTestExpression(currentAncestor)) { + return currentAncestor.parent; + } + } while ((currentAncestor = currentAncestor.parent) && !astUtils.isFunction(currentAncestor)); + + return null; + } + + /** + * Check whether the code represented by an AST node is enclosed in two sets of parentheses. + * @param {!Object} node The node to test. + * @returns {boolean} `true` if the code is enclosed in two sets of parentheses; otherwise, `false`. + */ + function isParenthesisedTwice(node) { + const previousToken = sourceCode.getTokenBefore(node, 1), + nextToken = sourceCode.getTokenAfter(node, 1); + + return astUtils.isParenthesised(sourceCode, node) && + previousToken && astUtils.isOpeningParenToken(previousToken) && previousToken.range[1] <= node.range[0] && + astUtils.isClosingParenToken(nextToken) && nextToken.range[0] >= node.range[1]; + } + + /** + * Check a conditional statement's test expression for top-level assignments that are not enclosed in parentheses. + * @param {!Object} node The node for the conditional statement. + * @returns {void} + */ + function testForAssign(node) { + if (node.test && + (node.test.type === "AssignmentExpression") && + (node.type === "ForStatement" + ? !astUtils.isParenthesised(sourceCode, node.test) + : !isParenthesisedTwice(node.test) + ) + ) { + + context.report({ + node: node.test, + messageId: "missing" + }); + } + } + + /** + * Check whether an assignment expression is descended from a conditional statement's test expression. + * @param {!Object} node The node for the assignment expression. + * @returns {void} + */ + function testForConditionalAncestor(node) { + const ancestor = findConditionalAncestor(node); + + if (ancestor) { + context.report({ + node, + messageId: "unexpected", + data: { + type: NODE_DESCRIPTIONS[ancestor.type] || ancestor.type + } + }); + } + } + + if (prohibitAssign === "always") { + return { + AssignmentExpression: testForConditionalAncestor + }; + } + + return { + DoWhileStatement: testForAssign, + ForStatement: testForAssign, + IfStatement: testForAssign, + WhileStatement: testForAssign, + ConditionalExpression: testForAssign + }; + + } +}; + +/** + * @fileoverview A rule to warn against using arrow functions when they could be + * confused with comparisons + * @author Jxck + */ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a node is a conditional expression. + * @param {ASTNode} node node to test + * @returns {boolean} `true` if the node is a conditional expression. + */ +function isConditional(node) { + return node && node.type === "ConditionalExpression"; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noConfusingArrow = { + meta: { + type: "suggestion", + + docs: { + description: "disallow arrow functions where they could be confused with comparisons", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/no-confusing-arrow" + }, + + fixable: "code", + + schema: [{ + type: "object", + properties: { + allowParens: { type: "boolean", default: true } + }, + additionalProperties: false + }], + + messages: { + confusing: "Arrow function used ambiguously with a conditional expression." + } + }, + + create(context) { + const config = context.options[0] || {}; + const allowParens = config.allowParens || (config.allowParens === void 0); + const sourceCode = context.getSourceCode(); + + + /** + * Reports if an arrow function contains an ambiguous conditional. + * @param {ASTNode} node A node to check and report. + * @returns {void} + */ + function checkArrowFunc(node) { + const body = node.body; + + if (isConditional(body) && !(allowParens && astUtils.isParenthesised(sourceCode, body))) { + context.report({ + node, + messageId: "confusing", + fix(fixer) { + + // if `allowParens` is not set to true don't bother wrapping in parens + return allowParens && fixer.replaceText(node.body, `(${sourceCode.getText(node.body)})`); + } + }); + } + } + + return { + ArrowFunctionExpression: checkArrowFunc + }; + } +}; + +/** + * @fileoverview Rule to flag use of console object + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noConsole = { + meta: { + type: "suggestion", + + docs: { + description: "disallow the use of `console`", + category: "Possible Errors", + recommended: false, + url: "https://eslint.org/docs/rules/no-console" + }, + + schema: [ + { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string" + }, + minItems: 1, + uniqueItems: true + } + }, + additionalProperties: false + } + ], + + messages: { + unexpected: "Unexpected console statement." + } + }, + + create(context) { + const options = context.options[0] || {}; + const allowed = options.allow || []; + + /** + * Checks whether the given reference is 'console' or not. + * @param {eslint-scope.Reference} reference The reference to check. + * @returns {boolean} `true` if the reference is 'console'. + */ + function isConsole(reference) { + const id = reference.identifier; + + return id && id.name === "console"; + } + + /** + * Checks whether the property name of the given MemberExpression node + * is allowed by options or not. + * @param {ASTNode} node The MemberExpression node to check. + * @returns {boolean} `true` if the property name of the node is allowed. + */ + function isAllowed(node) { + const propertyName = astUtils.getStaticPropertyName(node); + + return propertyName && allowed.indexOf(propertyName) !== -1; + } + + /** + * Checks whether the given reference is a member access which is not + * allowed by options or not. + * @param {eslint-scope.Reference} reference The reference to check. + * @returns {boolean} `true` if the reference is a member access which + * is not allowed by options. + */ + function isMemberAccessExceptAllowed(reference) { + const node = reference.identifier; + const parent = node.parent; + + return ( + parent.type === "MemberExpression" && + parent.object === node && + !isAllowed(parent) + ); + } + + /** + * Reports the given reference as a violation. + * @param {eslint-scope.Reference} reference The reference to report. + * @returns {void} + */ + function report(reference) { + const node = reference.identifier.parent; + + context.report({ + node, + loc: node.loc, + messageId: "unexpected" + }); + } + + return { + "Program:exit"() { + const scope = context.getScope(); + const consoleVar = astUtils.getVariableByName(scope, "console"); + const shadowed = consoleVar && consoleVar.defs.length > 0; + + /* + * 'scope.through' includes all references to undefined + * variables. If the variable 'console' is not defined, it uses + * 'scope.through'. + */ + const references = consoleVar + ? consoleVar.references + : scope.through.filter(isConsole); + + if (!shadowed) { + references + .filter(isMemberAccessExceptAllowed) + .forEach(report); + } + } + }; + } +}; + +/** + * @fileoverview A rule to disallow modifying variables that are declared using `const` + * @author Toru Nagashima + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noConstAssign = { + meta: { + type: "problem", + + docs: { + description: "disallow reassigning `const` variables", + category: "ECMAScript 6", + recommended: true, + url: "https://eslint.org/docs/rules/no-const-assign" + }, + + schema: [], + + messages: { + const: "'{{name}}' is constant." + } + }, + + create(context) { + + /** + * Finds and reports references that are non initializer and writable. + * @param {Variable} variable A variable to check. + * @returns {void} + */ + function checkVariable(variable) { + astUtils.getModifyingReferences(variable.references).forEach(reference => { + context.report({ node: reference.identifier, messageId: "const", data: { name: reference.identifier.name } }); + }); + } + + return { + VariableDeclaration(node) { + if (node.kind === "const") { + context.getDeclaredVariables(node).forEach(checkVariable); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag use constant conditions + * @author Christian Schulz + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noConstantCondition = { + meta: { + type: "problem", + + docs: { + description: "disallow constant expressions in conditions", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-constant-condition" + }, + + schema: [ + { + type: "object", + properties: { + checkLoops: { + type: "boolean", + default: true + } + }, + additionalProperties: false + } + ], + + messages: { + unexpected: "Unexpected constant condition." + } + }, + + create(context) { + const options = context.options[0] || {}, + checkLoops = options.checkLoops !== false, + loopSetStack = []; + + let loopsInCurrentScope = new Set(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Returns literal's value converted to the Boolean type + * @param {ASTNode} node any `Literal` node + * @returns {boolean | null} `true` when node is truthy, `false` when node is falsy, + * `null` when it cannot be determined. + */ + function getBooleanValue(node) { + if (node.value === null) { + + /* + * it might be a null literal or bigint/regex literal in unsupported environments . + * https://github.com/estree/estree/blob/14df8a024956ea289bd55b9c2226a1d5b8a473ee/es5.md#regexpliteral + * https://github.com/estree/estree/blob/14df8a024956ea289bd55b9c2226a1d5b8a473ee/es2020.md#bigintliteral + */ + + if (node.raw === "null") { + return false; + } + + // regex is always truthy + if (typeof node.regex === "object") { + return true; + } + + return null; + } + + return !!node.value; + } + + /** + * Checks if a branch node of LogicalExpression short circuits the whole condition + * @param {ASTNode} node The branch of main condition which needs to be checked + * @param {string} operator The operator of the main LogicalExpression. + * @returns {boolean} true when condition short circuits whole condition + */ + function isLogicalIdentity(node, operator) { + switch (node.type) { + case "Literal": + return (operator === "||" && getBooleanValue(node) === true) || + (operator === "&&" && getBooleanValue(node) === false); + + case "UnaryExpression": + return (operator === "&&" && node.operator === "void"); + + case "LogicalExpression": + + /* + * handles `a && false || b` + * `false` is an identity element of `&&` but not `||` + */ + return operator === node.operator && + ( + isLogicalIdentity(node.left, operator) || + isLogicalIdentity(node.right, operator) + ); + + case "AssignmentExpression": + return ["||=", "&&="].includes(node.operator) && + operator === node.operator.slice(0, -1) && + isLogicalIdentity(node.right, operator); + + // no default + } + return false; + } + + /** + * Checks if a node has a constant truthiness value. + * @param {ASTNode} node The AST node to check. + * @param {boolean} inBooleanPosition `false` if checking branch of a condition. + * `true` in all other cases + * @returns {Bool} true when node's truthiness is constant + * @private + */ + function isConstant(node, inBooleanPosition) { + + // node.elements can return null values in the case of sparse arrays ex. [,] + if (!node) { + return true; + } + switch (node.type) { + case "Literal": + case "ArrowFunctionExpression": + case "FunctionExpression": + case "ObjectExpression": + return true; + case "TemplateLiteral": + return (inBooleanPosition && node.quasis.some(quasi => quasi.value.cooked.length)) || + node.expressions.every(exp => isConstant(exp, inBooleanPosition)); + + case "ArrayExpression": { + if (node.parent.type === "BinaryExpression" && node.parent.operator === "+") { + return node.elements.every(element => isConstant(element, false)); + } + return true; + } + + case "UnaryExpression": + if ( + node.operator === "void" || + node.operator === "typeof" && inBooleanPosition + ) { + return true; + } + + if (node.operator === "!") { + return isConstant(node.argument, true); + } + + return isConstant(node.argument, false); + + case "BinaryExpression": + return isConstant(node.left, false) && + isConstant(node.right, false) && + node.operator !== "in"; + + case "LogicalExpression": { + const isLeftConstant = isConstant(node.left, inBooleanPosition); + const isRightConstant = isConstant(node.right, inBooleanPosition); + const isLeftShortCircuit = (isLeftConstant && isLogicalIdentity(node.left, node.operator)); + const isRightShortCircuit = (inBooleanPosition && isRightConstant && isLogicalIdentity(node.right, node.operator)); + + return (isLeftConstant && isRightConstant) || + isLeftShortCircuit || + isRightShortCircuit; + } + + case "AssignmentExpression": + if (node.operator === "=") { + return isConstant(node.right, inBooleanPosition); + } + + if (["||=", "&&="].includes(node.operator) && inBooleanPosition) { + return isLogicalIdentity(node.right, node.operator.slice(0, -1)); + } + + return false; + + case "SequenceExpression": + return isConstant(node.expressions[node.expressions.length - 1], inBooleanPosition); + + // no default + } + return false; + } + + /** + * Tracks when the given node contains a constant condition. + * @param {ASTNode} node The AST node to check. + * @returns {void} + * @private + */ + function trackConstantConditionLoop(node) { + if (node.test && isConstant(node.test, true)) { + loopsInCurrentScope.add(node); + } + } + + /** + * Reports when the set contains the given constant condition node + * @param {ASTNode} node The AST node to check. + * @returns {void} + * @private + */ + function checkConstantConditionLoopInSet(node) { + if (loopsInCurrentScope.has(node)) { + loopsInCurrentScope.delete(node); + context.report({ node: node.test, messageId: "unexpected" }); + } + } + + /** + * Reports when the given node contains a constant condition. + * @param {ASTNode} node The AST node to check. + * @returns {void} + * @private + */ + function reportIfConstant(node) { + if (node.test && isConstant(node.test, true)) { + context.report({ node: node.test, messageId: "unexpected" }); + } + } + + /** + * Stores current set of constant loops in loopSetStack temporarily + * and uses a new set to track constant loops + * @returns {void} + * @private + */ + function enterFunction() { + loopSetStack.push(loopsInCurrentScope); + loopsInCurrentScope = new Set(); + } + + /** + * Reports when the set still contains stored constant conditions + * @returns {void} + * @private + */ + function exitFunction() { + loopsInCurrentScope = loopSetStack.pop(); + } + + /** + * Checks node when checkLoops option is enabled + * @param {ASTNode} node The AST node to check. + * @returns {void} + * @private + */ + function checkLoop(node) { + if (checkLoops) { + trackConstantConditionLoop(node); + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + ConditionalExpression: reportIfConstant, + IfStatement: reportIfConstant, + WhileStatement: checkLoop, + "WhileStatement:exit": checkConstantConditionLoopInSet, + DoWhileStatement: checkLoop, + "DoWhileStatement:exit": checkConstantConditionLoopInSet, + ForStatement: checkLoop, + "ForStatement > .test": node => checkLoop(node.parent), + "ForStatement:exit": checkConstantConditionLoopInSet, + FunctionDeclaration: enterFunction, + "FunctionDeclaration:exit": exitFunction, + FunctionExpression: enterFunction, + "FunctionExpression:exit": exitFunction, + YieldExpression: () => loopsInCurrentScope.clear() + }; + + } +}; + +/** + * @fileoverview Rule to disallow returning value from constructor. + * @author Pig Fang + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noConstructorReturn = { + meta: { + type: "problem", + + docs: { + description: "disallow returning value from constructor", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-constructor-return" + }, + + schema: {}, + + fixable: null, + + messages: { + unexpected: "Unexpected return statement in constructor." + } + }, + + create(context) { + const stack = []; + + return { + onCodePathStart(_, node) { + stack.push(node); + }, + onCodePathEnd() { + stack.pop(); + }, + ReturnStatement(node) { + const last = stack[stack.length - 1]; + + if (!last.parent) { + return; + } + + if ( + last.parent.type === "MethodDefinition" && + last.parent.kind === "constructor" && + (node.parent.parent === last || node.argument) + ) { + context.report({ + node, + messageId: "unexpected" + }); + } + } + }; + } +}; + +/** + * @fileoverview Rule to flag use of continue statement + * @author Borislav Zhivkov + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noContinue = { + meta: { + type: "suggestion", + + docs: { + description: "disallow `continue` statements", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-continue" + }, + + schema: [], + + messages: { + unexpected: "Unexpected use of continue statement." + } + }, + + create(context) { + + return { + ContinueStatement(node) { + context.report({ node, messageId: "unexpected" }); + } + }; + + } +}; + +/** + * @fileoverview Rule to forbid control characters from regular expressions. + * @author Nicholas C. Zakas + */ + +const RegExpValidator$1 = regexpp__default['default'].RegExpValidator; +const collector = new (class { + constructor() { + this._source = ""; + this._controlChars = []; + this._validator = new RegExpValidator$1(this); + } + + onPatternEnter() { + this._controlChars = []; + } + + onCharacter(start, end, cp) { + if (cp >= 0x00 && + cp <= 0x1F && + ( + this._source.codePointAt(start) === cp || + this._source.slice(start, end).startsWith("\\x") || + this._source.slice(start, end).startsWith("\\u") + ) + ) { + this._controlChars.push(`\\x${`0${cp.toString(16)}`.slice(-2)}`); + } + } + + collectControlChars(regexpStr) { + try { + this._source = regexpStr; + this._validator.validatePattern(regexpStr); // Call onCharacter hook + } catch { + + // Ignore syntax errors in RegExp. + } + return this._controlChars; + } +})(); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noControlRegex = { + meta: { + type: "problem", + + docs: { + description: "disallow control characters in regular expressions", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-control-regex" + }, + + schema: [], + + messages: { + unexpected: "Unexpected control character(s) in regular expression: {{controlChars}}." + } + }, + + create(context) { + + /** + * Get the regex expression + * @param {ASTNode} node node to evaluate + * @returns {RegExp|null} Regex if found else null + * @private + */ + function getRegExpPattern(node) { + if (node.regex) { + return node.regex.pattern; + } + if (typeof node.value === "string" && + (node.parent.type === "NewExpression" || node.parent.type === "CallExpression") && + node.parent.callee.type === "Identifier" && + node.parent.callee.name === "RegExp" && + node.parent.arguments[0] === node + ) { + return node.value; + } + + return null; + } + + return { + Literal(node) { + const pattern = getRegExpPattern(node); + + if (pattern) { + const controlCharacters = collector.collectControlChars(pattern); + + if (controlCharacters.length > 0) { + context.report({ + node, + messageId: "unexpected", + data: { + controlChars: controlCharacters.join(", ") + } + }); + } + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag use of a debugger statement + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noDebugger = { + meta: { + type: "problem", + + docs: { + description: "disallow the use of `debugger`", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-debugger" + }, + + fixable: null, + schema: [], + + messages: { + unexpected: "Unexpected 'debugger' statement." + } + }, + + create(context) { + + return { + DebuggerStatement(node) { + context.report({ + node, + messageId: "unexpected" + }); + } + }; + + } +}; + +/** + * @fileoverview Rule to flag when deleting variables + * @author Ilya Volodin + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noDeleteVar = { + meta: { + type: "suggestion", + + docs: { + description: "disallow deleting variables", + category: "Variables", + recommended: true, + url: "https://eslint.org/docs/rules/no-delete-var" + }, + + schema: [], + + messages: { + unexpected: "Variables should not be deleted." + } + }, + + create(context) { + + return { + + UnaryExpression(node) { + if (node.operator === "delete" && node.argument.type === "Identifier") { + context.report({ node, messageId: "unexpected" }); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to check for ambiguous div operator in regexes + * @author Matt DuVall + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noDivRegex = { + meta: { + type: "suggestion", + + docs: { + description: "disallow division operators explicitly at the beginning of regular expressions", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-div-regex" + }, + + fixable: "code", + + schema: [], + + messages: { + unexpected: "A regular expression literal can be confused with '/='." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + + Literal(node) { + const token = sourceCode.getFirstToken(node); + + if (token.type === "RegularExpression" && token.value[1] === "=") { + context.report({ + node, + messageId: "unexpected", + fix(fixer) { + return fixer.replaceTextRange([token.range[0] + 1, token.range[0] + 2], "[=]"); + } + }); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag duplicate arguments + * @author Jamund Ferguson + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noDupeArgs = { + meta: { + type: "problem", + + docs: { + description: "disallow duplicate arguments in `function` definitions", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-dupe-args" + }, + + schema: [], + + messages: { + unexpected: "Duplicate param '{{name}}'." + } + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Checks whether or not a given definition is a parameter's. + * @param {eslint-scope.DefEntry} def A definition to check. + * @returns {boolean} `true` if the definition is a parameter's. + */ + function isParameter(def) { + return def.type === "Parameter"; + } + + /** + * Determines if a given node has duplicate parameters. + * @param {ASTNode} node The node to check. + * @returns {void} + * @private + */ + function checkParams(node) { + const variables = context.getDeclaredVariables(node); + + for (let i = 0; i < variables.length; ++i) { + const variable = variables[i]; + + // Checks and reports duplications. + const defs = variable.defs.filter(isParameter); + + if (defs.length >= 2) { + context.report({ + node, + messageId: "unexpected", + data: { name: variable.name } + }); + } + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + FunctionDeclaration: checkParams, + FunctionExpression: checkParams + }; + + } +}; + +/** + * @fileoverview A rule to disallow duplicate name in class members. + * @author Toru Nagashima + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noDupeClassMembers = { + meta: { + type: "problem", + + docs: { + description: "disallow duplicate class members", + category: "ECMAScript 6", + recommended: true, + url: "https://eslint.org/docs/rules/no-dupe-class-members" + }, + + schema: [], + + messages: { + unexpected: "Duplicate name '{{name}}'." + } + }, + + create(context) { + let stack = []; + + /** + * Gets state of a given member name. + * @param {string} name A name of a member. + * @param {boolean} isStatic A flag which specifies that is a static member. + * @returns {Object} A state of a given member name. + * - retv.init {boolean} A flag which shows the name is declared as normal member. + * - retv.get {boolean} A flag which shows the name is declared as getter. + * - retv.set {boolean} A flag which shows the name is declared as setter. + */ + function getState(name, isStatic) { + const stateMap = stack[stack.length - 1]; + const key = `$${name}`; // to avoid "__proto__". + + if (!stateMap[key]) { + stateMap[key] = { + nonStatic: { init: false, get: false, set: false }, + static: { init: false, get: false, set: false } + }; + } + + return stateMap[key][isStatic ? "static" : "nonStatic"]; + } + + return { + + // Initializes the stack of state of member declarations. + Program() { + stack = []; + }, + + // Initializes state of member declarations for the class. + ClassBody() { + stack.push(Object.create(null)); + }, + + // Disposes the state for the class. + "ClassBody:exit"() { + stack.pop(); + }, + + // Reports the node if its name has been declared already. + MethodDefinition(node) { + const name = astUtils.getStaticPropertyName(node); + + if (name === null || node.kind === "constructor") { + return; + } + + const state = getState(name, node.static); + let isDuplicate = false; + + if (node.kind === "get") { + isDuplicate = (state.init || state.get); + state.get = true; + } else if (node.kind === "set") { + isDuplicate = (state.init || state.set); + state.set = true; + } else { + isDuplicate = (state.init || state.get || state.set); + state.init = true; + } + + if (isDuplicate) { + context.report({ node, messageId: "unexpected", data: { name } }); + } + } + }; + } +}; + +/** + * @fileoverview Rule to disallow duplicate conditions in if-else-if chains + * @author Milos Djermanovic + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Determines whether the first given array is a subset of the second given array. + * @param {Function} comparator A function to compare two elements, should return `true` if they are equal. + * @param {Array} arrA The array to compare from. + * @param {Array} arrB The array to compare against. + * @returns {boolean} `true` if the array `arrA` is a subset of the array `arrB`. + */ +function isSubsetByComparator(comparator, arrA, arrB) { + return arrA.every(a => arrB.some(b => comparator(a, b))); +} + +/** + * Splits the given node by the given logical operator. + * @param {string} operator Logical operator `||` or `&&`. + * @param {ASTNode} node The node to split. + * @returns {ASTNode[]} Array of conditions that makes the node when joined by the operator. + */ +function splitByLogicalOperator(operator, node) { + if (node.type === "LogicalExpression" && node.operator === operator) { + return [...splitByLogicalOperator(operator, node.left), ...splitByLogicalOperator(operator, node.right)]; + } + return [node]; +} + +const splitByOr = splitByLogicalOperator.bind(null, "||"); +const splitByAnd = splitByLogicalOperator.bind(null, "&&"); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noDupeElseIf = { + meta: { + type: "problem", + + docs: { + description: "disallow duplicate conditions in if-else-if chains", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-dupe-else-if" + }, + + schema: [], + + messages: { + unexpected: "This branch can never execute. Its condition is a duplicate or covered by previous conditions in the if-else-if chain." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + /** + * Determines whether the two given nodes are considered to be equal. In particular, given that the nodes + * represent expressions in a boolean context, `||` and `&&` can be considered as commutative operators. + * @param {ASTNode} a First node. + * @param {ASTNode} b Second node. + * @returns {boolean} `true` if the nodes are considered to be equal. + */ + function equal(a, b) { + if (a.type !== b.type) { + return false; + } + + if ( + a.type === "LogicalExpression" && + (a.operator === "||" || a.operator === "&&") && + a.operator === b.operator + ) { + return equal(a.left, b.left) && equal(a.right, b.right) || + equal(a.left, b.right) && equal(a.right, b.left); + } + + return astUtils.equalTokens(a, b, sourceCode); + } + + const isSubset = isSubsetByComparator.bind(null, equal); + + return { + IfStatement(node) { + const test = node.test, + conditionsToCheck = test.type === "LogicalExpression" && test.operator === "&&" + ? [test, ...splitByAnd(test)] + : [test]; + let current = node, + listToCheck = conditionsToCheck.map(c => splitByOr(c).map(splitByAnd)); + + while (current.parent && current.parent.type === "IfStatement" && current.parent.alternate === current) { + current = current.parent; + + const currentOrOperands = splitByOr(current.test).map(splitByAnd); + + listToCheck = listToCheck.map(orOperands => orOperands.filter( + orOperand => !currentOrOperands.some(currentOrOperand => isSubset(currentOrOperand, orOperand)) + )); + + if (listToCheck.some(orOperands => orOperands.length === 0)) { + context.report({ node: test, messageId: "unexpected" }); + break; + } + } + } + }; + } +}; + +/** + * @fileoverview Rule to flag use of duplicate keys in an object. + * @author Ian Christian Myers + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const GET_KIND = /^(?:init|get)$/u; +const SET_KIND = /^(?:init|set)$/u; + +/** + * The class which stores properties' information of an object. + */ +class ObjectInfo { + + // eslint-disable-next-line jsdoc/require-description + /** + * @param {ObjectInfo|null} upper The information of the outer object. + * @param {ASTNode} node The ObjectExpression node of this information. + */ + constructor(upper, node) { + this.upper = upper; + this.node = node; + this.properties = new Map(); + } + + /** + * Gets the information of the given Property node. + * @param {ASTNode} node The Property node to get. + * @returns {{get: boolean, set: boolean}} The information of the property. + */ + getPropertyInfo(node) { + const name = astUtils.getStaticPropertyName(node); + + if (!this.properties.has(name)) { + this.properties.set(name, { get: false, set: false }); + } + return this.properties.get(name); + } + + /** + * Checks whether the given property has been defined already or not. + * @param {ASTNode} node The Property node to check. + * @returns {boolean} `true` if the property has been defined. + */ + isPropertyDefined(node) { + const entry = this.getPropertyInfo(node); + + return ( + (GET_KIND.test(node.kind) && entry.get) || + (SET_KIND.test(node.kind) && entry.set) + ); + } + + /** + * Defines the given property. + * @param {ASTNode} node The Property node to define. + * @returns {void} + */ + defineProperty(node) { + const entry = this.getPropertyInfo(node); + + if (GET_KIND.test(node.kind)) { + entry.get = true; + } + if (SET_KIND.test(node.kind)) { + entry.set = true; + } + } +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noDupeKeys = { + meta: { + type: "problem", + + docs: { + description: "disallow duplicate keys in object literals", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-dupe-keys" + }, + + schema: [], + + messages: { + unexpected: "Duplicate key '{{name}}'." + } + }, + + create(context) { + let info = null; + + return { + ObjectExpression(node) { + info = new ObjectInfo(info, node); + }, + "ObjectExpression:exit"() { + info = info.upper; + }, + + Property(node) { + const name = astUtils.getStaticPropertyName(node); + + // Skip destructuring. + if (node.parent.type !== "ObjectExpression") { + return; + } + + // Skip if the name is not static. + if (name === null) { + return; + } + + // Reports if the name is defined already. + if (info.isPropertyDefined(node)) { + context.report({ + node: info.node, + loc: node.key.loc, + messageId: "unexpected", + data: { name } + }); + } + + // Update info. + info.defineProperty(node); + } + }; + } +}; + +/** + * @fileoverview Rule to disallow a duplicate case label. + * @author Dieter Oberkofler + * @author Burak Yigit Kaya + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noDuplicateCase = { + meta: { + type: "problem", + + docs: { + description: "disallow duplicate case labels", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-duplicate-case" + }, + + schema: [], + + messages: { + unexpected: "Duplicate case label." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + /** + * Determines whether the two given nodes are considered to be equal. + * @param {ASTNode} a First node. + * @param {ASTNode} b Second node. + * @returns {boolean} `true` if the nodes are considered to be equal. + */ + function equal(a, b) { + if (a.type !== b.type) { + return false; + } + + return astUtils.equalTokens(a, b, sourceCode); + } + return { + SwitchStatement(node) { + const previousTests = []; + + for (const switchCase of node.cases) { + if (switchCase.test) { + const test = switchCase.test; + + if (previousTests.some(previousTest => equal(previousTest, test))) { + context.report({ node: switchCase, messageId: "unexpected" }); + } else { + previousTests.push(test); + } + } + } + } + }; + } +}; + +/** + * @fileoverview Restrict usage of duplicate imports. + * @author Simen Bekkhus + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +/** + * Returns the name of the module imported or re-exported. + * @param {ASTNode} node A node to get. + * @returns {string} the name of the module, or empty string if no name. + */ +function getValue(node) { + if (node && node.source && node.source.value) { + return node.source.value.trim(); + } + + return ""; +} + +/** + * Checks if the name of the import or export exists in the given array, and reports if so. + * @param {RuleContext} context The ESLint rule context object. + * @param {ASTNode} node A node to get. + * @param {string} value The name of the imported or exported module. + * @param {string[]} array The array containing other imports or exports in the file. + * @param {string} messageId A messageId to be reported after the name of the module + * + * @returns {void} No return value + */ +function checkAndReport(context, node, value, array, messageId) { + if (array.indexOf(value) !== -1) { + context.report({ + node, + messageId, + data: { + module: value + } + }); + } +} + +/** + * @callback nodeCallback + * @param {ASTNode} node A node to handle. + */ + +/** + * Returns a function handling the imports of a given file + * @param {RuleContext} context The ESLint rule context object. + * @param {boolean} includeExports Whether or not to check for exports in addition to imports. + * @param {string[]} importsInFile The array containing other imports in the file. + * @param {string[]} exportsInFile The array containing other exports in the file. + * + * @returns {nodeCallback} A function passed to ESLint to handle the statement. + */ +function handleImports(context, includeExports, importsInFile, exportsInFile) { + return function(node) { + const value = getValue(node); + + if (value) { + checkAndReport(context, node, value, importsInFile, "import"); + + if (includeExports) { + checkAndReport(context, node, value, exportsInFile, "importAs"); + } + + importsInFile.push(value); + } + }; +} + +/** + * Returns a function handling the exports of a given file + * @param {RuleContext} context The ESLint rule context object. + * @param {string[]} importsInFile The array containing other imports in the file. + * @param {string[]} exportsInFile The array containing other exports in the file. + * + * @returns {nodeCallback} A function passed to ESLint to handle the statement. + */ +function handleExports(context, importsInFile, exportsInFile) { + return function(node) { + const value = getValue(node); + + if (value) { + checkAndReport(context, node, value, exportsInFile, "export"); + checkAndReport(context, node, value, importsInFile, "exportAs"); + + exportsInFile.push(value); + } + }; +} + +var noDuplicateImports = { + meta: { + type: "problem", + + docs: { + description: "disallow duplicate module imports", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/no-duplicate-imports" + }, + + schema: [{ + type: "object", + properties: { + includeExports: { + type: "boolean", + default: false + } + }, + additionalProperties: false + }], + messages: { + import: "'{{module}}' import is duplicated.", + importAs: "'{{module}}' import is duplicated as export.", + export: "'{{module}}' export is duplicated.", + exportAs: "'{{module}}' export is duplicated as import." + } + }, + + create(context) { + const includeExports = (context.options[0] || {}).includeExports, + importsInFile = [], + exportsInFile = []; + + const handlers = { + ImportDeclaration: handleImports(context, includeExports, importsInFile, exportsInFile) + }; + + if (includeExports) { + handlers.ExportNamedDeclaration = handleExports(context, importsInFile, exportsInFile); + handlers.ExportAllDeclaration = handleExports(context, importsInFile, exportsInFile); + } + + return handlers; + } +}; + +/** + * @fileoverview Helper class to aid in constructing fix commands. + * @author Alan Pierce + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * A helper class to combine fix options into a fix command. Currently, it + * exposes some "retain" methods that extend the range of the text being + * replaced so that other fixes won't touch that region in the same pass. + */ +class FixTracker { + + /** + * Create a new FixTracker. + * @param {ruleFixer} fixer A ruleFixer instance. + * @param {SourceCode} sourceCode A SourceCode object for the current code. + */ + constructor(fixer, sourceCode) { + this.fixer = fixer; + this.sourceCode = sourceCode; + this.retainedRange = null; + } + + /** + * Mark the given range as "retained", meaning that other fixes may not + * may not modify this region in the same pass. + * @param {int[]} range The range to retain. + * @returns {FixTracker} The same RuleFixer, for chained calls. + */ + retainRange(range) { + this.retainedRange = range; + return this; + } + + /** + * Given a node, find the function containing it (or the entire program) and + * mark it as retained, meaning that other fixes may not modify it in this + * pass. This is useful for avoiding conflicts in fixes that modify control + * flow. + * @param {ASTNode} node The node to use as a starting point. + * @returns {FixTracker} The same RuleFixer, for chained calls. + */ + retainEnclosingFunction(node) { + const functionNode = astUtils.getUpperFunction(node); + + return this.retainRange(functionNode ? functionNode.range : this.sourceCode.ast.range); + } + + /** + * Given a node or token, find the token before and afterward, and mark that + * range as retained, meaning that other fixes may not modify it in this + * pass. This is useful for avoiding conflicts in fixes that make a small + * change to the code where the AST should not be changed. + * @param {ASTNode|Token} nodeOrToken The node or token to use as a starting + * point. The token to the left and right are use in the range. + * @returns {FixTracker} The same RuleFixer, for chained calls. + */ + retainSurroundingTokens(nodeOrToken) { + const tokenBefore = this.sourceCode.getTokenBefore(nodeOrToken) || nodeOrToken; + const tokenAfter = this.sourceCode.getTokenAfter(nodeOrToken) || nodeOrToken; + + return this.retainRange([tokenBefore.range[0], tokenAfter.range[1]]); + } + + /** + * Create a fix command that replaces the given range with the given text, + * accounting for any retained ranges. + * @param {int[]} range The range to remove in the fix. + * @param {string} text The text to insert in place of the range. + * @returns {Object} The fix command. + */ + replaceTextRange(range, text) { + let actualRange; + + if (this.retainedRange) { + actualRange = [ + Math.min(this.retainedRange[0], range[0]), + Math.max(this.retainedRange[1], range[1]) + ]; + } else { + actualRange = range; + } + + return this.fixer.replaceTextRange( + actualRange, + this.sourceCode.text.slice(actualRange[0], range[0]) + + text + + this.sourceCode.text.slice(range[1], actualRange[1]) + ); + } + + /** + * Create a fix command that removes the given node or token, accounting for + * any retained ranges. + * @param {ASTNode|Token} nodeOrToken The node or token to remove. + * @returns {Object} The fix command. + */ + remove(nodeOrToken) { + return this.replaceTextRange(nodeOrToken.range, ""); + } +} + +var fixTracker = FixTracker; + +/** + * @fileoverview Rule to flag `else` after a `return` in `if` + * @author Ian Christian Myers + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noElseReturn = { + meta: { + type: "suggestion", + + docs: { + description: "disallow `else` blocks after `return` statements in `if` statements", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-else-return" + }, + + schema: [{ + type: "object", + properties: { + allowElseIf: { + type: "boolean", + default: true + } + }, + additionalProperties: false + }], + + fixable: "code", + + messages: { + unexpected: "Unnecessary 'else' after 'return'." + } + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Checks whether the given names can be safely used to declare block-scoped variables + * in the given scope. Name collisions can produce redeclaration syntax errors, + * or silently change references and modify behavior of the original code. + * + * This is not a generic function. In particular, it is assumed that the scope is a function scope or + * a function's inner scope, and that the names can be valid identifiers in the given scope. + * @param {string[]} names Array of variable names. + * @param {eslint-scope.Scope} scope Function scope or a function's inner scope. + * @returns {boolean} True if all names can be safely declared, false otherwise. + */ + function isSafeToDeclare(names, scope) { + + if (names.length === 0) { + return true; + } + + const functionScope = scope.variableScope; + + /* + * If this is a function scope, scope.variables will contain parameters, implicit variables such as "arguments", + * all function-scoped variables ('var'), and block-scoped variables defined in the scope. + * If this is an inner scope, scope.variables will contain block-scoped variables defined in the scope. + * + * Redeclaring any of these would cause a syntax error, except for the implicit variables. + */ + const declaredVariables = scope.variables.filter(({ defs }) => defs.length > 0); + + if (declaredVariables.some(({ name }) => names.includes(name))) { + return false; + } + + // Redeclaring a catch variable would also cause a syntax error. + if (scope !== functionScope && scope.upper.type === "catch") { + if (scope.upper.variables.some(({ name }) => names.includes(name))) { + return false; + } + } + + /* + * Redeclaring an implicit variable, such as "arguments", would not cause a syntax error. + * However, if the variable was used, declaring a new one with the same name would change references + * and modify behavior. + */ + const usedImplicitVariables = scope.variables.filter(({ defs, references }) => + defs.length === 0 && references.length > 0); + + if (usedImplicitVariables.some(({ name }) => names.includes(name))) { + return false; + } + + /* + * Declaring a variable with a name that was already used to reference a variable from an upper scope + * would change references and modify behavior. + */ + if (scope.through.some(t => names.includes(t.identifier.name))) { + return false; + } + + /* + * If the scope is an inner scope (not the function scope), an uninitialized `var` variable declared inside + * the scope node (directly or in one of its descendants) is neither declared nor 'through' in the scope. + * + * For example, this would be a syntax error "Identifier 'a' has already been declared": + * function foo() { if (bar) { let a; if (baz) { var a; } } } + */ + if (scope !== functionScope) { + const scopeNodeRange = scope.block.range; + const variablesToCheck = functionScope.variables.filter(({ name }) => names.includes(name)); + + if (variablesToCheck.some(v => v.defs.some(({ node: { range } }) => + scopeNodeRange[0] <= range[0] && range[1] <= scopeNodeRange[1]))) { + return false; + } + } + + return true; + } + + + /** + * Checks whether the removal of `else` and its braces is safe from variable name collisions. + * @param {Node} node The 'else' node. + * @param {eslint-scope.Scope} scope The scope in which the node and the whole 'if' statement is. + * @returns {boolean} True if it is safe, false otherwise. + */ + function isSafeFromNameCollisions(node, scope) { + + if (node.type === "FunctionDeclaration") { + + // Conditional function declaration. Scope and hoisting are unpredictable, different engines work differently. + return false; + } + + if (node.type !== "BlockStatement") { + return true; + } + + const elseBlockScope = scope.childScopes.find(({ block }) => block === node); + + if (!elseBlockScope) { + + // ecmaVersion < 6, `else` block statement cannot have its own scope, no possible collisions. + return true; + } + + /* + * elseBlockScope is supposed to merge into its upper scope. elseBlockScope.variables array contains + * only block-scoped variables (such as let and const variables or class and function declarations) + * defined directly in the elseBlockScope. These are exactly the only names that could cause collisions. + */ + const namesToCheck = elseBlockScope.variables.map(({ name }) => name); + + return isSafeToDeclare(namesToCheck, scope); + } + + /** + * Display the context report if rule is violated + * @param {Node} node The 'else' node + * @returns {void} + */ + function displayReport(node) { + const currentScope = context.getScope(); + + context.report({ + node, + messageId: "unexpected", + fix: fixer => { + + if (!isSafeFromNameCollisions(node, currentScope)) { + return null; + } + + const sourceCode = context.getSourceCode(); + const startToken = sourceCode.getFirstToken(node); + const elseToken = sourceCode.getTokenBefore(startToken); + const source = sourceCode.getText(node); + const lastIfToken = sourceCode.getTokenBefore(elseToken); + let fixedSource, firstTokenOfElseBlock; + + if (startToken.type === "Punctuator" && startToken.value === "{") { + firstTokenOfElseBlock = sourceCode.getTokenAfter(startToken); + } else { + firstTokenOfElseBlock = startToken; + } + + /* + * If the if block does not have curly braces and does not end in a semicolon + * and the else block starts with (, [, /, +, ` or -, then it is not + * safe to remove the else keyword, because ASI will not add a semicolon + * after the if block + */ + const ifBlockMaybeUnsafe = node.parent.consequent.type !== "BlockStatement" && lastIfToken.value !== ";"; + const elseBlockUnsafe = /^[([/+`-]/u.test(firstTokenOfElseBlock.value); + + if (ifBlockMaybeUnsafe && elseBlockUnsafe) { + return null; + } + + const endToken = sourceCode.getLastToken(node); + const lastTokenOfElseBlock = sourceCode.getTokenBefore(endToken); + + if (lastTokenOfElseBlock.value !== ";") { + const nextToken = sourceCode.getTokenAfter(endToken); + + const nextTokenUnsafe = nextToken && /^[([/+`-]/u.test(nextToken.value); + const nextTokenOnSameLine = nextToken && nextToken.loc.start.line === lastTokenOfElseBlock.loc.start.line; + + /* + * If the else block contents does not end in a semicolon, + * and the else block starts with (, [, /, +, ` or -, then it is not + * safe to remove the else block, because ASI will not add a semicolon + * after the remaining else block contents + */ + if (nextTokenUnsafe || (nextTokenOnSameLine && nextToken.value !== "}")) { + return null; + } + } + + if (startToken.type === "Punctuator" && startToken.value === "{") { + fixedSource = source.slice(1, -1); + } else { + fixedSource = source; + } + + /* + * Extend the replacement range to include the entire + * function to avoid conflicting with no-useless-return. + * https://github.com/eslint/eslint/issues/8026 + * + * Also, to avoid name collisions between two else blocks. + */ + return new fixTracker(fixer, sourceCode) + .retainEnclosingFunction(node) + .replaceTextRange([elseToken.range[0], node.range[1]], fixedSource); + } + }); + } + + /** + * Check to see if the node is a ReturnStatement + * @param {Node} node The node being evaluated + * @returns {boolean} True if node is a return + */ + function checkForReturn(node) { + return node.type === "ReturnStatement"; + } + + /** + * Naive return checking, does not iterate through the whole + * BlockStatement because we make the assumption that the ReturnStatement + * will be the last node in the body of the BlockStatement. + * @param {Node} node The consequent/alternate node + * @returns {boolean} True if it has a return + */ + function naiveHasReturn(node) { + if (node.type === "BlockStatement") { + const body = node.body, + lastChildNode = body[body.length - 1]; + + return lastChildNode && checkForReturn(lastChildNode); + } + return checkForReturn(node); + } + + /** + * Check to see if the node is valid for evaluation, + * meaning it has an else. + * @param {Node} node The node being evaluated + * @returns {boolean} True if the node is valid + */ + function hasElse(node) { + return node.alternate && node.consequent; + } + + /** + * If the consequent is an IfStatement, check to see if it has an else + * and both its consequent and alternate path return, meaning this is + * a nested case of rule violation. If-Else not considered currently. + * @param {Node} node The consequent node + * @returns {boolean} True if this is a nested rule violation + */ + function checkForIf(node) { + return node.type === "IfStatement" && hasElse(node) && + naiveHasReturn(node.alternate) && naiveHasReturn(node.consequent); + } + + /** + * Check the consequent/body node to make sure it is not + * a ReturnStatement or an IfStatement that returns on both + * code paths. + * @param {Node} node The consequent or body node + * @returns {boolean} `true` if it is a Return/If node that always returns. + */ + function checkForReturnOrIf(node) { + return checkForReturn(node) || checkForIf(node); + } + + + /** + * Check whether a node returns in every codepath. + * @param {Node} node The node to be checked + * @returns {boolean} `true` if it returns on every codepath. + */ + function alwaysReturns(node) { + if (node.type === "BlockStatement") { + + // If we have a BlockStatement, check each consequent body node. + return node.body.some(checkForReturnOrIf); + } + + /* + * If not a block statement, make sure the consequent isn't a + * ReturnStatement or an IfStatement with returns on both paths. + */ + return checkForReturnOrIf(node); + } + + + /** + * Check the if statement, but don't catch else-if blocks. + * @returns {void} + * @param {Node} node The node for the if statement to check + * @private + */ + function checkIfWithoutElse(node) { + const parent = node.parent; + + /* + * Fixing this would require splitting one statement into two, so no error should + * be reported if this node is in a position where only one statement is allowed. + */ + if (!astUtils.STATEMENT_LIST_PARENTS.has(parent.type)) { + return; + } + + const consequents = []; + let alternate; + + for (let currentNode = node; currentNode.type === "IfStatement"; currentNode = currentNode.alternate) { + if (!currentNode.alternate) { + return; + } + consequents.push(currentNode.consequent); + alternate = currentNode.alternate; + } + + if (consequents.every(alwaysReturns)) { + displayReport(alternate); + } + } + + /** + * Check the if statement + * @returns {void} + * @param {Node} node The node for the if statement to check + * @private + */ + function checkIfWithElse(node) { + const parent = node.parent; + + + /* + * Fixing this would require splitting one statement into two, so no error should + * be reported if this node is in a position where only one statement is allowed. + */ + if (!astUtils.STATEMENT_LIST_PARENTS.has(parent.type)) { + return; + } + + const alternate = node.alternate; + + if (alternate && alwaysReturns(node.consequent)) { + displayReport(alternate); + } + } + + const allowElseIf = !(context.options[0] && context.options[0].allowElseIf === false); + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + + "IfStatement:exit": allowElseIf ? checkIfWithoutElse : checkIfWithElse + + }; + + } +}; + +/** + * @fileoverview Rule to flag use of an empty block statement + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noEmpty = { + meta: { + type: "suggestion", + + docs: { + description: "disallow empty block statements", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-empty" + }, + + schema: [ + { + type: "object", + properties: { + allowEmptyCatch: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + messages: { + unexpected: "Empty {{type}} statement." + } + }, + + create(context) { + const options = context.options[0] || {}, + allowEmptyCatch = options.allowEmptyCatch || false; + + const sourceCode = context.getSourceCode(); + + return { + BlockStatement(node) { + + // if the body is not empty, we can just return immediately + if (node.body.length !== 0) { + return; + } + + // a function is generally allowed to be empty + if (astUtils.isFunction(node.parent)) { + return; + } + + if (allowEmptyCatch && node.parent.type === "CatchClause") { + return; + } + + // any other block is only allowed to be empty, if it contains a comment + if (sourceCode.getCommentsInside(node).length > 0) { + return; + } + + context.report({ node, messageId: "unexpected", data: { type: "block" } }); + }, + + SwitchStatement(node) { + + if (typeof node.cases === "undefined" || node.cases.length === 0) { + context.report({ node, messageId: "unexpected", data: { type: "switch" } }); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag the use of empty character classes in regular expressions + * @author Ian Christian Myers + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/* + * plain-English description of the following regexp: + * 0. `^` fix the match at the beginning of the string + * 1. `\/`: the `/` that begins the regexp + * 2. `([^\\[]|\\.|\[([^\\\]]|\\.)+\])*`: regexp contents; 0 or more of the following + * 2.0. `[^\\[]`: any character that's not a `\` or a `[` (anything but escape sequences and character classes) + * 2.1. `\\.`: an escape sequence + * 2.2. `\[([^\\\]]|\\.)+\]`: a character class that isn't empty + * 3. `\/` the `/` that ends the regexp + * 4. `[gimuy]*`: optional regexp flags + * 5. `$`: fix the match at the end of the string + */ +const regex = /^\/([^\\[]|\\.|\[([^\\\]]|\\.)+\])*\/[gimuys]*$/u; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noEmptyCharacterClass = { + meta: { + type: "problem", + + docs: { + description: "disallow empty character classes in regular expressions", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-empty-character-class" + }, + + schema: [], + + messages: { + unexpected: "Empty class." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + + Literal(node) { + const token = sourceCode.getFirstToken(node); + + if (token.type === "RegularExpression" && !regex.test(token.value)) { + context.report({ node, messageId: "unexpected" }); + } + } + + }; + + } +}; + +/** + * @fileoverview Rule to disallow empty functions. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const ALLOW_OPTIONS = Object.freeze([ + "functions", + "arrowFunctions", + "generatorFunctions", + "methods", + "generatorMethods", + "getters", + "setters", + "constructors", + "asyncFunctions", + "asyncMethods" +]); + +/** + * Gets the kind of a given function node. + * @param {ASTNode} node A function node to get. This is one of + * an ArrowFunctionExpression, a FunctionDeclaration, or a + * FunctionExpression. + * @returns {string} The kind of the function. This is one of "functions", + * "arrowFunctions", "generatorFunctions", "asyncFunctions", "methods", + * "generatorMethods", "asyncMethods", "getters", "setters", and + * "constructors". + */ +function getKind(node) { + const parent = node.parent; + let kind = ""; + + if (node.type === "ArrowFunctionExpression") { + return "arrowFunctions"; + } + + // Detects main kind. + if (parent.type === "Property") { + if (parent.kind === "get") { + return "getters"; + } + if (parent.kind === "set") { + return "setters"; + } + kind = parent.method ? "methods" : "functions"; + + } else if (parent.type === "MethodDefinition") { + if (parent.kind === "get") { + return "getters"; + } + if (parent.kind === "set") { + return "setters"; + } + if (parent.kind === "constructor") { + return "constructors"; + } + kind = "methods"; + + } else { + kind = "functions"; + } + + // Detects prefix. + let prefix = ""; + + if (node.generator) { + prefix = "generator"; + } else if (node.async) { + prefix = "async"; + } else { + return kind; + } + return prefix + kind[0].toUpperCase() + kind.slice(1); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noEmptyFunction = { + meta: { + type: "suggestion", + + docs: { + description: "disallow empty functions", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-empty-function" + }, + + schema: [ + { + type: "object", + properties: { + allow: { + type: "array", + items: { enum: ALLOW_OPTIONS }, + uniqueItems: true + } + }, + additionalProperties: false + } + ], + + messages: { + unexpected: "Unexpected empty {{name}}." + } + }, + + create(context) { + const options = context.options[0] || {}; + const allowed = options.allow || []; + + const sourceCode = context.getSourceCode(); + + /** + * Reports a given function node if the node matches the following patterns. + * + * - Not allowed by options. + * - The body is empty. + * - The body doesn't have any comments. + * @param {ASTNode} node A function node to report. This is one of + * an ArrowFunctionExpression, a FunctionDeclaration, or a + * FunctionExpression. + * @returns {void} + */ + function reportIfEmpty(node) { + const kind = getKind(node); + const name = astUtils.getFunctionNameWithKind(node); + const innerComments = sourceCode.getTokens(node.body, { + includeComments: true, + filter: astUtils.isCommentToken + }); + + if (allowed.indexOf(kind) === -1 && + node.body.type === "BlockStatement" && + node.body.body.length === 0 && + innerComments.length === 0 + ) { + context.report({ + node, + loc: node.body.loc, + messageId: "unexpected", + data: { name } + }); + } + } + + return { + ArrowFunctionExpression: reportIfEmpty, + FunctionDeclaration: reportIfEmpty, + FunctionExpression: reportIfEmpty + }; + } +}; + +/** + * @fileoverview Rule to disallow an empty pattern + * @author Alberto Rodríguez + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noEmptyPattern = { + meta: { + type: "problem", + + docs: { + description: "disallow empty destructuring patterns", + category: "Best Practices", + recommended: true, + url: "https://eslint.org/docs/rules/no-empty-pattern" + }, + + schema: [], + + messages: { + unexpected: "Unexpected empty {{type}} pattern." + } + }, + + create(context) { + return { + ObjectPattern(node) { + if (node.properties.length === 0) { + context.report({ node, messageId: "unexpected", data: { type: "object" } }); + } + }, + ArrayPattern(node) { + if (node.elements.length === 0) { + context.report({ node, messageId: "unexpected", data: { type: "array" } }); + } + } + }; + } +}; + +/** + * @fileoverview Rule to flag comparisons to null without a type-checking + * operator. + * @author Ian Christian Myers + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noEqNull = { + meta: { + type: "suggestion", + + docs: { + description: "disallow `null` comparisons without type-checking operators", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-eq-null" + }, + + schema: [], + + messages: { + unexpected: "Use '===' to compare with null." + } + }, + + create(context) { + + return { + + BinaryExpression(node) { + const badOperator = node.operator === "==" || node.operator === "!="; + + if (node.right.type === "Literal" && node.right.raw === "null" && badOperator || + node.left.type === "Literal" && node.left.raw === "null" && badOperator) { + context.report({ node, messageId: "unexpected" }); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag use of eval() statement + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const candidatesOfGlobalObject = Object.freeze([ + "global", + "window", + "globalThis" +]); + +/** + * Checks a given node is a MemberExpression node which has the specified name's + * property. + * @param {ASTNode} node A node to check. + * @param {string} name A name to check. + * @returns {boolean} `true` if the node is a MemberExpression node which has + * the specified name's property + */ +function isMember(node, name) { + return astUtils.isSpecificMemberAccess(node, null, name); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noEval = { + meta: { + type: "suggestion", + + docs: { + description: "disallow the use of `eval()`", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-eval" + }, + + schema: [ + { + type: "object", + properties: { + allowIndirect: { type: "boolean", default: false } + }, + additionalProperties: false + } + ], + + messages: { + unexpected: "eval can be harmful." + } + }, + + create(context) { + const allowIndirect = Boolean( + context.options[0] && + context.options[0].allowIndirect + ); + const sourceCode = context.getSourceCode(); + let funcInfo = null; + + /** + * Pushs a variable scope (Program or Function) information to the stack. + * + * This is used in order to check whether or not `this` binding is a + * reference to the global object. + * @param {ASTNode} node A node of the scope. This is one of Program, + * FunctionDeclaration, FunctionExpression, and ArrowFunctionExpression. + * @returns {void} + */ + function enterVarScope(node) { + const strict = context.getScope().isStrict; + + funcInfo = { + upper: funcInfo, + node, + strict, + defaultThis: false, + initialized: strict + }; + } + + /** + * Pops a variable scope from the stack. + * @returns {void} + */ + function exitVarScope() { + funcInfo = funcInfo.upper; + } + + /** + * Reports a given node. + * + * `node` is `Identifier` or `MemberExpression`. + * The parent of `node` might be `CallExpression`. + * + * The location of the report is always `eval` `Identifier` (or possibly + * `Literal`). The type of the report is `CallExpression` if the parent is + * `CallExpression`. Otherwise, it's the given node type. + * @param {ASTNode} node A node to report. + * @returns {void} + */ + function report(node) { + const parent = node.parent; + const locationNode = node.type === "MemberExpression" + ? node.property + : node; + + const reportNode = parent.type === "CallExpression" && parent.callee === node + ? parent + : node; + + context.report({ + node: reportNode, + loc: locationNode.loc, + messageId: "unexpected" + }); + } + + /** + * Reports accesses of `eval` via the global object. + * @param {eslint-scope.Scope} globalScope The global scope. + * @returns {void} + */ + function reportAccessingEvalViaGlobalObject(globalScope) { + for (let i = 0; i < candidatesOfGlobalObject.length; ++i) { + const name = candidatesOfGlobalObject[i]; + const variable = astUtils.getVariableByName(globalScope, name); + + if (!variable) { + continue; + } + + const references = variable.references; + + for (let j = 0; j < references.length; ++j) { + const identifier = references[j].identifier; + let node = identifier.parent; + + // To detect code like `window.window.eval`. + while (isMember(node, name)) { + node = node.parent; + } + + // Reports. + if (isMember(node, "eval")) { + report(node); + } + } + } + } + + /** + * Reports all accesses of `eval` (excludes direct calls to eval). + * @param {eslint-scope.Scope} globalScope The global scope. + * @returns {void} + */ + function reportAccessingEval(globalScope) { + const variable = astUtils.getVariableByName(globalScope, "eval"); + + if (!variable) { + return; + } + + const references = variable.references; + + for (let i = 0; i < references.length; ++i) { + const reference = references[i]; + const id = reference.identifier; + + if (id.name === "eval" && !astUtils.isCallee(id)) { + + // Is accessing to eval (excludes direct calls to eval) + report(id); + } + } + } + + if (allowIndirect) { + + // Checks only direct calls to eval. It's simple! + return { + "CallExpression:exit"(node) { + const callee = node.callee; + + /* + * Optional call (`eval?.("code")`) is not direct eval. + * The direct eval is only step 6.a.vi of https://tc39.es/ecma262/#sec-function-calls-runtime-semantics-evaluation + * But the optional call is https://tc39.es/ecma262/#sec-optional-chaining-chain-evaluation + */ + if (!node.optional && astUtils.isSpecificId(callee, "eval")) { + report(callee); + } + } + }; + } + + return { + "CallExpression:exit"(node) { + const callee = node.callee; + + if (astUtils.isSpecificId(callee, "eval")) { + report(callee); + } + }, + + Program(node) { + const scope = context.getScope(), + features = context.parserOptions.ecmaFeatures || {}, + strict = + scope.isStrict || + node.sourceType === "module" || + (features.globalReturn && scope.childScopes[0].isStrict); + + funcInfo = { + upper: null, + node, + strict, + defaultThis: true, + initialized: true + }; + }, + + "Program:exit"() { + const globalScope = context.getScope(); + + exitVarScope(); + reportAccessingEval(globalScope); + reportAccessingEvalViaGlobalObject(globalScope); + }, + + FunctionDeclaration: enterVarScope, + "FunctionDeclaration:exit": exitVarScope, + FunctionExpression: enterVarScope, + "FunctionExpression:exit": exitVarScope, + ArrowFunctionExpression: enterVarScope, + "ArrowFunctionExpression:exit": exitVarScope, + + ThisExpression(node) { + if (!isMember(node.parent, "eval")) { + return; + } + + /* + * `this.eval` is found. + * Checks whether or not the value of `this` is the global object. + */ + if (!funcInfo.initialized) { + funcInfo.initialized = true; + funcInfo.defaultThis = astUtils.isDefaultThisBinding( + funcInfo.node, + sourceCode + ); + } + + if (!funcInfo.strict && funcInfo.defaultThis) { + + // `this.eval` is possible built-in `eval`. + report(node.parent); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag assignment of the exception parameter + * @author Stephen Murray + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noExAssign = { + meta: { + type: "problem", + + docs: { + description: "disallow reassigning exceptions in `catch` clauses", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-ex-assign" + }, + + schema: [], + + messages: { + unexpected: "Do not assign to the exception parameter." + } + }, + + create(context) { + + /** + * Finds and reports references that are non initializer and writable. + * @param {Variable} variable A variable to check. + * @returns {void} + */ + function checkVariable(variable) { + astUtils.getModifyingReferences(variable.references).forEach(reference => { + context.report({ node: reference.identifier, messageId: "unexpected" }); + }); + } + + return { + CatchClause(node) { + context.getDeclaredVariables(node).forEach(checkVariable); + } + }; + + } +}; + +/** + * @fileoverview Rule to flag adding properties to native object's prototypes. + * @author David Nelson + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noExtendNative = { + meta: { + type: "suggestion", + + docs: { + description: "disallow extending native types", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-extend-native" + }, + + schema: [ + { + type: "object", + properties: { + exceptions: { + type: "array", + items: { + type: "string" + }, + uniqueItems: true + } + }, + additionalProperties: false + } + ], + + messages: { + unexpected: "{{builtin}} prototype is read only, properties should not be added." + } + }, + + create(context) { + + const config = context.options[0] || {}; + const exceptions = new Set(config.exceptions || []); + const modifiedBuiltins = new Set( + Object.keys(globals__default['default'].builtin) + .filter(builtin => builtin[0].toUpperCase() === builtin[0]) + .filter(builtin => !exceptions.has(builtin)) + ); + + /** + * Reports a lint error for the given node. + * @param {ASTNode} node The node to report. + * @param {string} builtin The name of the native builtin being extended. + * @returns {void} + */ + function reportNode(node, builtin) { + context.report({ + node, + messageId: "unexpected", + data: { + builtin + } + }); + } + + /** + * Check to see if the `prototype` property of the given object + * identifier node is being accessed. + * @param {ASTNode} identifierNode The Identifier representing the object + * to check. + * @returns {boolean} True if the identifier is the object of a + * MemberExpression and its `prototype` property is being accessed, + * false otherwise. + */ + function isPrototypePropertyAccessed(identifierNode) { + return Boolean( + identifierNode && + identifierNode.parent && + identifierNode.parent.type === "MemberExpression" && + identifierNode.parent.object === identifierNode && + astUtils.getStaticPropertyName(identifierNode.parent) === "prototype" + ); + } + + /** + * Check if it's an assignment to the property of the given node. + * Example: `*.prop = 0` // the `*` is the given node. + * @param {ASTNode} node The node to check. + * @returns {boolean} True if an assignment to the property of the node. + */ + function isAssigningToPropertyOf(node) { + return ( + node.parent.type === "MemberExpression" && + node.parent.object === node && + node.parent.parent.type === "AssignmentExpression" && + node.parent.parent.left === node.parent + ); + } + + /** + * Checks if the given node is at the first argument of the method call of `Object.defineProperty()` or `Object.defineProperties()`. + * @param {ASTNode} node The node to check. + * @returns {boolean} True if the node is at the first argument of the method call of `Object.defineProperty()` or `Object.defineProperties()`. + */ + function isInDefinePropertyCall(node) { + return ( + node.parent.type === "CallExpression" && + node.parent.arguments[0] === node && + astUtils.isSpecificMemberAccess(node.parent.callee, "Object", /^definePropert(?:y|ies)$/u) + ); + } + + /** + * Check to see if object prototype access is part of a prototype + * extension. There are three ways a prototype can be extended: + * 1. Assignment to prototype property (Object.prototype.foo = 1) + * 2. Object.defineProperty()/Object.defineProperties() on a prototype + * If prototype extension is detected, report the AssignmentExpression + * or CallExpression node. + * @param {ASTNode} identifierNode The Identifier representing the object + * which prototype is being accessed and possibly extended. + * @returns {void} + */ + function checkAndReportPrototypeExtension(identifierNode) { + if (!isPrototypePropertyAccessed(identifierNode)) { + return; // This is not `*.prototype` access. + } + + /* + * `identifierNode.parent` is a MemberExpression `*.prototype`. + * If it's an optional member access, it may be wrapped by a `ChainExpression` node. + */ + const prototypeNode = + identifierNode.parent.parent.type === "ChainExpression" + ? identifierNode.parent.parent + : identifierNode.parent; + + if (isAssigningToPropertyOf(prototypeNode)) { + + // `*.prototype` -> MemberExpression -> AssignmentExpression + reportNode(prototypeNode.parent.parent, identifierNode.name); + } else if (isInDefinePropertyCall(prototypeNode)) { + + // `*.prototype` -> CallExpression + reportNode(prototypeNode.parent, identifierNode.name); + } + } + + return { + + "Program:exit"() { + const globalScope = context.getScope(); + + modifiedBuiltins.forEach(builtin => { + const builtinVar = globalScope.set.get(builtin); + + if (builtinVar && builtinVar.references) { + builtinVar.references + .map(ref => ref.identifier) + .forEach(checkAndReportPrototypeExtension); + } + }); + } + }; + + } +}; + +/** + * @fileoverview Rule to flag unnecessary bind calls + * @author Bence Dányi + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const SIDE_EFFECT_FREE_NODE_TYPES = new Set(["Literal", "Identifier", "ThisExpression", "FunctionExpression"]); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noExtraBind = { + meta: { + type: "suggestion", + + docs: { + description: "disallow unnecessary calls to `.bind()`", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-extra-bind" + }, + + schema: [], + fixable: "code", + + messages: { + unexpected: "The function binding is unnecessary." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + let scopeInfo = null; + + /** + * Checks if a node is free of side effects. + * + * This check is stricter than it needs to be, in order to keep the implementation simple. + * @param {ASTNode} node A node to check. + * @returns {boolean} True if the node is known to be side-effect free, false otherwise. + */ + function isSideEffectFree(node) { + return SIDE_EFFECT_FREE_NODE_TYPES.has(node.type); + } + + /** + * Reports a given function node. + * @param {ASTNode} node A node to report. This is a FunctionExpression or + * an ArrowFunctionExpression. + * @returns {void} + */ + function report(node) { + const memberNode = node.parent; + const callNode = memberNode.parent.type === "ChainExpression" + ? memberNode.parent.parent + : memberNode.parent; + + context.report({ + node: callNode, + messageId: "unexpected", + loc: memberNode.property.loc, + + fix(fixer) { + if (!isSideEffectFree(callNode.arguments[0])) { + return null; + } + + /* + * The list of the first/last token pair of a removal range. + * This is two parts because closing parentheses may exist between the method name and arguments. + * E.g. `(function(){}.bind ) (obj)` + * ^^^^^ ^^^^^ < removal ranges + * E.g. `(function(){}?.['bind'] ) ?.(obj)` + * ^^^^^^^^^^ ^^^^^^^ < removal ranges + */ + const tokenPairs = [ + [ + + // `.`, `?.`, or `[` token. + sourceCode.getTokenAfter( + memberNode.object, + astUtils.isNotClosingParenToken + ), + + // property name or `]` token. + sourceCode.getLastToken(memberNode) + ], + [ + + // `?.` or `(` token of arguments. + sourceCode.getTokenAfter( + memberNode, + astUtils.isNotClosingParenToken + ), + + // `)` token of arguments. + sourceCode.getLastToken(callNode) + ] + ]; + const firstTokenToRemove = tokenPairs[0][0]; + const lastTokenToRemove = tokenPairs[1][1]; + + if (sourceCode.commentsExistBetween(firstTokenToRemove, lastTokenToRemove)) { + return null; + } + + return tokenPairs.map(([start, end]) => + fixer.removeRange([start.range[0], end.range[1]])); + } + }); + } + + /** + * Checks whether or not a given function node is the callee of `.bind()` + * method. + * + * e.g. `(function() {}.bind(foo))` + * @param {ASTNode} node A node to report. This is a FunctionExpression or + * an ArrowFunctionExpression. + * @returns {boolean} `true` if the node is the callee of `.bind()` method. + */ + function isCalleeOfBindMethod(node) { + if (!astUtils.isSpecificMemberAccess(node.parent, null, "bind")) { + return false; + } + + // The node of `*.bind` member access. + const bindNode = node.parent.parent.type === "ChainExpression" + ? node.parent.parent + : node.parent; + + return ( + bindNode.parent.type === "CallExpression" && + bindNode.parent.callee === bindNode && + bindNode.parent.arguments.length === 1 && + bindNode.parent.arguments[0].type !== "SpreadElement" + ); + } + + /** + * Adds a scope information object to the stack. + * @param {ASTNode} node A node to add. This node is a FunctionExpression + * or a FunctionDeclaration node. + * @returns {void} + */ + function enterFunction(node) { + scopeInfo = { + isBound: isCalleeOfBindMethod(node), + thisFound: false, + upper: scopeInfo + }; + } + + /** + * Removes the scope information object from the top of the stack. + * At the same time, this reports the function node if the function has + * `.bind()` and the `this` keywords found. + * @param {ASTNode} node A node to remove. This node is a + * FunctionExpression or a FunctionDeclaration node. + * @returns {void} + */ + function exitFunction(node) { + if (scopeInfo.isBound && !scopeInfo.thisFound) { + report(node); + } + + scopeInfo = scopeInfo.upper; + } + + /** + * Reports a given arrow function if the function is callee of `.bind()` + * method. + * @param {ASTNode} node A node to report. This node is an + * ArrowFunctionExpression. + * @returns {void} + */ + function exitArrowFunction(node) { + if (isCalleeOfBindMethod(node)) { + report(node); + } + } + + /** + * Set the mark as the `this` keyword was found in this scope. + * @returns {void} + */ + function markAsThisFound() { + if (scopeInfo) { + scopeInfo.thisFound = true; + } + } + + return { + "ArrowFunctionExpression:exit": exitArrowFunction, + FunctionDeclaration: enterFunction, + "FunctionDeclaration:exit": exitFunction, + FunctionExpression: enterFunction, + "FunctionExpression:exit": exitFunction, + ThisExpression: markAsThisFound + }; + } +}; + +/** + * @fileoverview Rule to flag unnecessary double negation in Boolean contexts + * @author Brandon Mills + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +const precedence = astUtils.getPrecedence; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noExtraBooleanCast = { + meta: { + type: "suggestion", + + docs: { + description: "disallow unnecessary boolean casts", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-extra-boolean-cast" + }, + + schema: [{ + type: "object", + properties: { + enforceForLogicalOperands: { + type: "boolean", + default: false + } + }, + additionalProperties: false + }], + fixable: "code", + + messages: { + unexpectedCall: "Redundant Boolean call.", + unexpectedNegation: "Redundant double negation." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + // Node types which have a test which will coerce values to booleans. + const BOOLEAN_NODE_TYPES = [ + "IfStatement", + "DoWhileStatement", + "WhileStatement", + "ConditionalExpression", + "ForStatement" + ]; + + /** + * Check if a node is a Boolean function or constructor. + * @param {ASTNode} node the node + * @returns {boolean} If the node is Boolean function or constructor + */ + function isBooleanFunctionOrConstructorCall(node) { + + // Boolean() and new Boolean() + return (node.type === "CallExpression" || node.type === "NewExpression") && + node.callee.type === "Identifier" && + node.callee.name === "Boolean"; + } + + /** + * Checks whether the node is a logical expression and that the option is enabled + * @param {ASTNode} node the node + * @returns {boolean} if the node is a logical expression and option is enabled + */ + function isLogicalContext(node) { + return node.type === "LogicalExpression" && + (node.operator === "||" || node.operator === "&&") && + (context.options.length && context.options[0].enforceForLogicalOperands === true); + + } + + + /** + * Check if a node is in a context where its value would be coerced to a boolean at runtime. + * @param {ASTNode} node The node + * @returns {boolean} If it is in a boolean context + */ + function isInBooleanContext(node) { + return ( + (isBooleanFunctionOrConstructorCall(node.parent) && + node === node.parent.arguments[0]) || + + (BOOLEAN_NODE_TYPES.indexOf(node.parent.type) !== -1 && + node === node.parent.test) || + + // ! + (node.parent.type === "UnaryExpression" && + node.parent.operator === "!") + ); + } + + /** + * Checks whether the node is a context that should report an error + * Acts recursively if it is in a logical context + * @param {ASTNode} node the node + * @returns {boolean} If the node is in one of the flagged contexts + */ + function isInFlaggedContext(node) { + if (node.parent.type === "ChainExpression") { + return isInFlaggedContext(node.parent); + } + + return isInBooleanContext(node) || + (isLogicalContext(node.parent) && + + // For nested logical statements + isInFlaggedContext(node.parent) + ); + } + + + /** + * Check if a node has comments inside. + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if it has comments inside. + */ + function hasCommentsInside(node) { + return Boolean(sourceCode.getCommentsInside(node).length); + } + + /** + * Checks if the given node is wrapped in grouping parentheses. Parentheses for constructs such as if() don't count. + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if the node is parenthesized. + * @private + */ + function isParenthesized(node) { + return require$$0__default$1['default'].isParenthesized(1, node, sourceCode); + } + + /** + * Determines whether the given node needs to be parenthesized when replacing the previous node. + * It assumes that `previousNode` is the node to be reported by this rule, so it has a limited list + * of possible parent node types. By the same assumption, the node's role in a particular parent is already known. + * For example, if the parent is `ConditionalExpression`, `previousNode` must be its `test` child. + * @param {ASTNode} previousNode Previous node. + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if the node needs to be parenthesized. + */ + function needsParens(previousNode, node) { + if (previousNode.parent.type === "ChainExpression") { + return needsParens(previousNode.parent, node); + } + if (isParenthesized(previousNode)) { + + // parentheses around the previous node will stay, so there is no need for an additional pair + return false; + } + + // parent of the previous node will become parent of the replacement node + const parent = previousNode.parent; + + switch (parent.type) { + case "CallExpression": + case "NewExpression": + return node.type === "SequenceExpression"; + case "IfStatement": + case "DoWhileStatement": + case "WhileStatement": + case "ForStatement": + return false; + case "ConditionalExpression": + return precedence(node) <= precedence(parent); + case "UnaryExpression": + return precedence(node) < precedence(parent); + case "LogicalExpression": + if (astUtils.isMixedLogicalAndCoalesceExpressions(node, parent)) { + return true; + } + if (previousNode === parent.left) { + return precedence(node) < precedence(parent); + } + return precedence(node) <= precedence(parent); + + /* istanbul ignore next */ + default: + throw new Error(`Unexpected parent type: ${parent.type}`); + } + } + + return { + UnaryExpression(node) { + const parent = node.parent; + + + // Exit early if it's guaranteed not to match + if (node.operator !== "!" || + parent.type !== "UnaryExpression" || + parent.operator !== "!") { + return; + } + + + if (isInFlaggedContext(parent)) { + context.report({ + node: parent, + messageId: "unexpectedNegation", + fix(fixer) { + if (hasCommentsInside(parent)) { + return null; + } + + if (needsParens(parent, node.argument)) { + return fixer.replaceText(parent, `(${sourceCode.getText(node.argument)})`); + } + + let prefix = ""; + const tokenBefore = sourceCode.getTokenBefore(parent); + const firstReplacementToken = sourceCode.getFirstToken(node.argument); + + if ( + tokenBefore && + tokenBefore.range[1] === parent.range[0] && + !astUtils.canTokensBeAdjacent(tokenBefore, firstReplacementToken) + ) { + prefix = " "; + } + + return fixer.replaceText(parent, prefix + sourceCode.getText(node.argument)); + } + }); + } + }, + + CallExpression(node) { + if (node.callee.type !== "Identifier" || node.callee.name !== "Boolean") { + return; + } + + if (isInFlaggedContext(node)) { + context.report({ + node, + messageId: "unexpectedCall", + fix(fixer) { + const parent = node.parent; + + if (node.arguments.length === 0) { + if (parent.type === "UnaryExpression" && parent.operator === "!") { + + /* + * !Boolean() -> true + */ + + if (hasCommentsInside(parent)) { + return null; + } + + const replacement = "true"; + let prefix = ""; + const tokenBefore = sourceCode.getTokenBefore(parent); + + if ( + tokenBefore && + tokenBefore.range[1] === parent.range[0] && + !astUtils.canTokensBeAdjacent(tokenBefore, replacement) + ) { + prefix = " "; + } + + return fixer.replaceText(parent, prefix + replacement); + } + + /* + * Boolean() -> false + */ + + if (hasCommentsInside(node)) { + return null; + } + + return fixer.replaceText(node, "false"); + } + + if (node.arguments.length === 1) { + const argument = node.arguments[0]; + + if (argument.type === "SpreadElement" || hasCommentsInside(node)) { + return null; + } + + /* + * Boolean(expression) -> expression + */ + + if (needsParens(node, argument)) { + return fixer.replaceText(node, `(${sourceCode.getText(argument)})`); + } + + return fixer.replaceText(node, sourceCode.getText(argument)); + } + + // two or more arguments + return null; + } + }); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to disallow unnecessary labels + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noExtraLabel = { + meta: { + type: "suggestion", + + docs: { + description: "disallow unnecessary labels", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-extra-label" + }, + + schema: [], + fixable: "code", + + messages: { + unexpected: "This label '{{name}}' is unnecessary." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + let scopeInfo = null; + + /** + * Creates a new scope with a breakable statement. + * @param {ASTNode} node A node to create. This is a BreakableStatement. + * @returns {void} + */ + function enterBreakableStatement(node) { + scopeInfo = { + label: node.parent.type === "LabeledStatement" ? node.parent.label : null, + breakable: true, + upper: scopeInfo + }; + } + + /** + * Removes the top scope of the stack. + * @returns {void} + */ + function exitBreakableStatement() { + scopeInfo = scopeInfo.upper; + } + + /** + * Creates a new scope with a labeled statement. + * + * This ignores it if the body is a breakable statement. + * In this case it's handled in the `enterBreakableStatement` function. + * @param {ASTNode} node A node to create. This is a LabeledStatement. + * @returns {void} + */ + function enterLabeledStatement(node) { + if (!astUtils.isBreakableStatement(node.body)) { + scopeInfo = { + label: node.label, + breakable: false, + upper: scopeInfo + }; + } + } + + /** + * Removes the top scope of the stack. + * + * This ignores it if the body is a breakable statement. + * In this case it's handled in the `exitBreakableStatement` function. + * @param {ASTNode} node A node. This is a LabeledStatement. + * @returns {void} + */ + function exitLabeledStatement(node) { + if (!astUtils.isBreakableStatement(node.body)) { + scopeInfo = scopeInfo.upper; + } + } + + /** + * Reports a given control node if it's unnecessary. + * @param {ASTNode} node A node. This is a BreakStatement or a + * ContinueStatement. + * @returns {void} + */ + function reportIfUnnecessary(node) { + if (!node.label) { + return; + } + + const labelNode = node.label; + + for (let info = scopeInfo; info !== null; info = info.upper) { + if (info.breakable || info.label && info.label.name === labelNode.name) { + if (info.breakable && info.label && info.label.name === labelNode.name) { + context.report({ + node: labelNode, + messageId: "unexpected", + data: labelNode, + fix(fixer) { + const breakOrContinueToken = sourceCode.getFirstToken(node); + + if (sourceCode.commentsExistBetween(breakOrContinueToken, labelNode)) { + return null; + } + + return fixer.removeRange([breakOrContinueToken.range[1], labelNode.range[1]]); + } + }); + } + return; + } + } + } + + return { + WhileStatement: enterBreakableStatement, + "WhileStatement:exit": exitBreakableStatement, + DoWhileStatement: enterBreakableStatement, + "DoWhileStatement:exit": exitBreakableStatement, + ForStatement: enterBreakableStatement, + "ForStatement:exit": exitBreakableStatement, + ForInStatement: enterBreakableStatement, + "ForInStatement:exit": exitBreakableStatement, + ForOfStatement: enterBreakableStatement, + "ForOfStatement:exit": exitBreakableStatement, + SwitchStatement: enterBreakableStatement, + "SwitchStatement:exit": exitBreakableStatement, + LabeledStatement: enterLabeledStatement, + "LabeledStatement:exit": exitLabeledStatement, + BreakStatement: reportIfUnnecessary, + ContinueStatement: reportIfUnnecessary + }; + } +}; + +/** + * @fileoverview Disallow parenthesising higher precedence subexpressions. + * @author Michael Ficarra + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const { isParenthesized: isParenthesizedRaw } = require$$0__default$1['default']; + + +var noExtraParens = { + meta: { + type: "layout", + + docs: { + description: "disallow unnecessary parentheses", + category: "Possible Errors", + recommended: false, + url: "https://eslint.org/docs/rules/no-extra-parens" + }, + + fixable: "code", + + schema: { + anyOf: [ + { + type: "array", + items: [ + { + enum: ["functions"] + } + ], + minItems: 0, + maxItems: 1 + }, + { + type: "array", + items: [ + { + enum: ["all"] + }, + { + type: "object", + properties: { + conditionalAssign: { type: "boolean" }, + nestedBinaryExpressions: { type: "boolean" }, + returnAssign: { type: "boolean" }, + ignoreJSX: { enum: ["none", "all", "single-line", "multi-line"] }, + enforceForArrowConditionals: { type: "boolean" }, + enforceForSequenceExpressions: { type: "boolean" }, + enforceForNewInMemberExpressions: { type: "boolean" }, + enforceForFunctionPrototypeMethods: { type: "boolean" } + }, + additionalProperties: false + } + ], + minItems: 0, + maxItems: 2 + } + ] + }, + + messages: { + unexpected: "Unnecessary parentheses around expression." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + const tokensToIgnore = new WeakSet(); + const precedence = astUtils.getPrecedence; + const ALL_NODES = context.options[0] !== "functions"; + const EXCEPT_COND_ASSIGN = ALL_NODES && context.options[1] && context.options[1].conditionalAssign === false; + const NESTED_BINARY = ALL_NODES && context.options[1] && context.options[1].nestedBinaryExpressions === false; + const EXCEPT_RETURN_ASSIGN = ALL_NODES && context.options[1] && context.options[1].returnAssign === false; + const IGNORE_JSX = ALL_NODES && context.options[1] && context.options[1].ignoreJSX; + const IGNORE_ARROW_CONDITIONALS = ALL_NODES && context.options[1] && + context.options[1].enforceForArrowConditionals === false; + const IGNORE_SEQUENCE_EXPRESSIONS = ALL_NODES && context.options[1] && + context.options[1].enforceForSequenceExpressions === false; + const IGNORE_NEW_IN_MEMBER_EXPR = ALL_NODES && context.options[1] && + context.options[1].enforceForNewInMemberExpressions === false; + const IGNORE_FUNCTION_PROTOTYPE_METHODS = ALL_NODES && context.options[1] && + context.options[1].enforceForFunctionPrototypeMethods === false; + + const PRECEDENCE_OF_ASSIGNMENT_EXPR = precedence({ type: "AssignmentExpression" }); + const PRECEDENCE_OF_UPDATE_EXPR = precedence({ type: "UpdateExpression" }); + + let reportsBuffer; + + /** + * Determines whether the given node is a `call` or `apply` method call, invoked directly on a `FunctionExpression` node. + * Example: function(){}.call() + * @param {ASTNode} node The node to be checked. + * @returns {boolean} True if the node is an immediate `call` or `apply` method call. + * @private + */ + function isImmediateFunctionPrototypeMethodCall(node) { + const callNode = astUtils.skipChainExpression(node); + + if (callNode.type !== "CallExpression") { + return false; + } + const callee = astUtils.skipChainExpression(callNode.callee); + + return ( + callee.type === "MemberExpression" && + callee.object.type === "FunctionExpression" && + ["call", "apply"].includes(astUtils.getStaticPropertyName(callee)) + ); + } + + /** + * Determines if this rule should be enforced for a node given the current configuration. + * @param {ASTNode} node The node to be checked. + * @returns {boolean} True if the rule should be enforced for this node. + * @private + */ + function ruleApplies(node) { + if (node.type === "JSXElement" || node.type === "JSXFragment") { + const isSingleLine = node.loc.start.line === node.loc.end.line; + + switch (IGNORE_JSX) { + + // Exclude this JSX element from linting + case "all": + return false; + + // Exclude this JSX element if it is multi-line element + case "multi-line": + return isSingleLine; + + // Exclude this JSX element if it is single-line element + case "single-line": + return !isSingleLine; + + // no default + } + } + + if (node.type === "SequenceExpression" && IGNORE_SEQUENCE_EXPRESSIONS) { + return false; + } + + if (isImmediateFunctionPrototypeMethodCall(node) && IGNORE_FUNCTION_PROTOTYPE_METHODS) { + return false; + } + + return ALL_NODES || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression"; + } + + /** + * Determines if a node is surrounded by parentheses. + * @param {ASTNode} node The node to be checked. + * @returns {boolean} True if the node is parenthesised. + * @private + */ + function isParenthesised(node) { + return isParenthesizedRaw(1, node, sourceCode); + } + + /** + * Determines if a node is surrounded by parentheses twice. + * @param {ASTNode} node The node to be checked. + * @returns {boolean} True if the node is doubly parenthesised. + * @private + */ + function isParenthesisedTwice(node) { + return isParenthesizedRaw(2, node, sourceCode); + } + + /** + * Determines if a node is surrounded by (potentially) invalid parentheses. + * @param {ASTNode} node The node to be checked. + * @returns {boolean} True if the node is incorrectly parenthesised. + * @private + */ + function hasExcessParens(node) { + return ruleApplies(node) && isParenthesised(node); + } + + /** + * Determines if a node that is expected to be parenthesised is surrounded by + * (potentially) invalid extra parentheses. + * @param {ASTNode} node The node to be checked. + * @returns {boolean} True if the node is has an unexpected extra pair of parentheses. + * @private + */ + function hasDoubleExcessParens(node) { + return ruleApplies(node) && isParenthesisedTwice(node); + } + + /** + * Determines if a node that is expected to be parenthesised is surrounded by + * (potentially) invalid extra parentheses with considering precedence level of the node. + * If the preference level of the node is not higher or equal to precedence lower limit, it also checks + * whether the node is surrounded by parentheses twice or not. + * @param {ASTNode} node The node to be checked. + * @param {number} precedenceLowerLimit The lower limit of precedence. + * @returns {boolean} True if the node is has an unexpected extra pair of parentheses. + * @private + */ + function hasExcessParensWithPrecedence(node, precedenceLowerLimit) { + if (ruleApplies(node) && isParenthesised(node)) { + if ( + precedence(node) >= precedenceLowerLimit || + isParenthesisedTwice(node) + ) { + return true; + } + } + return false; + } + + /** + * Determines if a node test expression is allowed to have a parenthesised assignment + * @param {ASTNode} node The node to be checked. + * @returns {boolean} True if the assignment can be parenthesised. + * @private + */ + function isCondAssignException(node) { + return EXCEPT_COND_ASSIGN && node.test.type === "AssignmentExpression"; + } + + /** + * Determines if a node is in a return statement + * @param {ASTNode} node The node to be checked. + * @returns {boolean} True if the node is in a return statement. + * @private + */ + function isInReturnStatement(node) { + for (let currentNode = node; currentNode; currentNode = currentNode.parent) { + if ( + currentNode.type === "ReturnStatement" || + (currentNode.type === "ArrowFunctionExpression" && currentNode.body.type !== "BlockStatement") + ) { + return true; + } + } + + return false; + } + + /** + * Determines if a constructor function is newed-up with parens + * @param {ASTNode} newExpression The NewExpression node to be checked. + * @returns {boolean} True if the constructor is called with parens. + * @private + */ + function isNewExpressionWithParens(newExpression) { + const lastToken = sourceCode.getLastToken(newExpression); + const penultimateToken = sourceCode.getTokenBefore(lastToken); + + return newExpression.arguments.length > 0 || + ( + + // The expression should end with its own parens, e.g., new new foo() is not a new expression with parens + astUtils.isOpeningParenToken(penultimateToken) && + astUtils.isClosingParenToken(lastToken) && + newExpression.callee.range[1] < newExpression.range[1] + ); + } + + /** + * Determines if a node is or contains an assignment expression + * @param {ASTNode} node The node to be checked. + * @returns {boolean} True if the node is or contains an assignment expression. + * @private + */ + function containsAssignment(node) { + if (node.type === "AssignmentExpression") { + return true; + } + if (node.type === "ConditionalExpression" && + (node.consequent.type === "AssignmentExpression" || node.alternate.type === "AssignmentExpression")) { + return true; + } + if ((node.left && node.left.type === "AssignmentExpression") || + (node.right && node.right.type === "AssignmentExpression")) { + return true; + } + + return false; + } + + /** + * Determines if a node is contained by or is itself a return statement and is allowed to have a parenthesised assignment + * @param {ASTNode} node The node to be checked. + * @returns {boolean} True if the assignment can be parenthesised. + * @private + */ + function isReturnAssignException(node) { + if (!EXCEPT_RETURN_ASSIGN || !isInReturnStatement(node)) { + return false; + } + + if (node.type === "ReturnStatement") { + return node.argument && containsAssignment(node.argument); + } + if (node.type === "ArrowFunctionExpression" && node.body.type !== "BlockStatement") { + return containsAssignment(node.body); + } + return containsAssignment(node); + + } + + /** + * Determines if a node following a [no LineTerminator here] restriction is + * surrounded by (potentially) invalid extra parentheses. + * @param {Token} token The token preceding the [no LineTerminator here] restriction. + * @param {ASTNode} node The node to be checked. + * @returns {boolean} True if the node is incorrectly parenthesised. + * @private + */ + function hasExcessParensNoLineTerminator(token, node) { + if (token.loc.end.line === node.loc.start.line) { + return hasExcessParens(node); + } + + return hasDoubleExcessParens(node); + } + + /** + * Determines whether a node should be preceded by an additional space when removing parens + * @param {ASTNode} node node to evaluate; must be surrounded by parentheses + * @returns {boolean} `true` if a space should be inserted before the node + * @private + */ + function requiresLeadingSpace(node) { + const leftParenToken = sourceCode.getTokenBefore(node); + const tokenBeforeLeftParen = sourceCode.getTokenBefore(leftParenToken, { includeComments: true }); + const tokenAfterLeftParen = sourceCode.getTokenAfter(leftParenToken, { includeComments: true }); + + return tokenBeforeLeftParen && + tokenBeforeLeftParen.range[1] === leftParenToken.range[0] && + leftParenToken.range[1] === tokenAfterLeftParen.range[0] && + !astUtils.canTokensBeAdjacent(tokenBeforeLeftParen, tokenAfterLeftParen); + } + + /** + * Determines whether a node should be followed by an additional space when removing parens + * @param {ASTNode} node node to evaluate; must be surrounded by parentheses + * @returns {boolean} `true` if a space should be inserted after the node + * @private + */ + function requiresTrailingSpace(node) { + const nextTwoTokens = sourceCode.getTokensAfter(node, { count: 2 }); + const rightParenToken = nextTwoTokens[0]; + const tokenAfterRightParen = nextTwoTokens[1]; + const tokenBeforeRightParen = sourceCode.getLastToken(node); + + return rightParenToken && tokenAfterRightParen && + !sourceCode.isSpaceBetweenTokens(rightParenToken, tokenAfterRightParen) && + !astUtils.canTokensBeAdjacent(tokenBeforeRightParen, tokenAfterRightParen); + } + + /** + * Determines if a given expression node is an IIFE + * @param {ASTNode} node The node to check + * @returns {boolean} `true` if the given node is an IIFE + */ + function isIIFE(node) { + const maybeCallNode = astUtils.skipChainExpression(node); + + return maybeCallNode.type === "CallExpression" && maybeCallNode.callee.type === "FunctionExpression"; + } + + /** + * Determines if the given node can be the assignment target in destructuring or the LHS of an assignment. + * This is to avoid an autofix that could change behavior because parsers mistakenly allow invalid syntax, + * such as `(a = b) = c` and `[(a = b) = c] = []`. Ideally, this function shouldn't be necessary. + * @param {ASTNode} [node] The node to check + * @returns {boolean} `true` if the given node can be a valid assignment target + */ + function canBeAssignmentTarget(node) { + return node && (node.type === "Identifier" || node.type === "MemberExpression"); + } + + /** + * Report the node + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function report(node) { + const leftParenToken = sourceCode.getTokenBefore(node); + const rightParenToken = sourceCode.getTokenAfter(node); + + if (!isParenthesisedTwice(node)) { + if (tokensToIgnore.has(sourceCode.getFirstToken(node))) { + return; + } + + if (isIIFE(node) && !isParenthesised(node.callee)) { + return; + } + } + + /** + * Finishes reporting + * @returns {void} + * @private + */ + function finishReport() { + context.report({ + node, + loc: leftParenToken.loc, + messageId: "unexpected", + fix(fixer) { + const parenthesizedSource = sourceCode.text.slice(leftParenToken.range[1], rightParenToken.range[0]); + + return fixer.replaceTextRange([ + leftParenToken.range[0], + rightParenToken.range[1] + ], (requiresLeadingSpace(node) ? " " : "") + parenthesizedSource + (requiresTrailingSpace(node) ? " " : "")); + } + }); + } + + if (reportsBuffer) { + reportsBuffer.reports.push({ node, finishReport }); + return; + } + + finishReport(); + } + + /** + * Evaluate a argument of the node. + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function checkArgumentWithPrecedence(node) { + if (hasExcessParensWithPrecedence(node.argument, precedence(node))) { + report(node.argument); + } + } + + /** + * Check if a member expression contains a call expression + * @param {ASTNode} node MemberExpression node to evaluate + * @returns {boolean} true if found, false if not + */ + function doesMemberExpressionContainCallExpression(node) { + let currentNode = node.object; + let currentNodeType = node.object.type; + + while (currentNodeType === "MemberExpression") { + currentNode = currentNode.object; + currentNodeType = currentNode.type; + } + + return currentNodeType === "CallExpression"; + } + + /** + * Evaluate a new call + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function checkCallNew(node) { + const callee = node.callee; + + if (hasExcessParensWithPrecedence(callee, precedence(node))) { + if ( + hasDoubleExcessParens(callee) || + !( + isIIFE(node) || + + // (new A)(); new (new A)(); + ( + callee.type === "NewExpression" && + !isNewExpressionWithParens(callee) && + !( + node.type === "NewExpression" && + !isNewExpressionWithParens(node) + ) + ) || + + // new (a().b)(); new (a.b().c); + ( + node.type === "NewExpression" && + callee.type === "MemberExpression" && + doesMemberExpressionContainCallExpression(callee) + ) || + + // (a?.b)(); (a?.())(); + ( + !node.optional && + callee.type === "ChainExpression" + ) + ) + ) { + report(node.callee); + } + } + node.arguments + .filter(arg => hasExcessParensWithPrecedence(arg, PRECEDENCE_OF_ASSIGNMENT_EXPR)) + .forEach(report); + } + + /** + * Evaluate binary logicals + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function checkBinaryLogical(node) { + const prec = precedence(node); + const leftPrecedence = precedence(node.left); + const rightPrecedence = precedence(node.right); + const isExponentiation = node.operator === "**"; + const shouldSkipLeft = NESTED_BINARY && (node.left.type === "BinaryExpression" || node.left.type === "LogicalExpression"); + const shouldSkipRight = NESTED_BINARY && (node.right.type === "BinaryExpression" || node.right.type === "LogicalExpression"); + + if (!shouldSkipLeft && hasExcessParens(node.left)) { + if ( + !(["AwaitExpression", "UnaryExpression"].includes(node.left.type) && isExponentiation) && + !astUtils.isMixedLogicalAndCoalesceExpressions(node.left, node) && + (leftPrecedence > prec || (leftPrecedence === prec && !isExponentiation)) || + isParenthesisedTwice(node.left) + ) { + report(node.left); + } + } + + if (!shouldSkipRight && hasExcessParens(node.right)) { + if ( + !astUtils.isMixedLogicalAndCoalesceExpressions(node.right, node) && + (rightPrecedence > prec || (rightPrecedence === prec && isExponentiation)) || + isParenthesisedTwice(node.right) + ) { + report(node.right); + } + } + } + + /** + * Check the parentheses around the super class of the given class definition. + * @param {ASTNode} node The node of class declarations to check. + * @returns {void} + */ + function checkClass(node) { + if (!node.superClass) { + return; + } + + /* + * If `node.superClass` is a LeftHandSideExpression, parentheses are extra. + * Otherwise, parentheses are needed. + */ + const hasExtraParens = precedence(node.superClass) > PRECEDENCE_OF_UPDATE_EXPR + ? hasExcessParens(node.superClass) + : hasDoubleExcessParens(node.superClass); + + if (hasExtraParens) { + report(node.superClass); + } + } + + /** + * Check the parentheses around the argument of the given spread operator. + * @param {ASTNode} node The node of spread elements/properties to check. + * @returns {void} + */ + function checkSpreadOperator(node) { + if (hasExcessParensWithPrecedence(node.argument, PRECEDENCE_OF_ASSIGNMENT_EXPR)) { + report(node.argument); + } + } + + /** + * Checks the parentheses for an ExpressionStatement or ExportDefaultDeclaration + * @param {ASTNode} node The ExpressionStatement.expression or ExportDefaultDeclaration.declaration node + * @returns {void} + */ + function checkExpressionOrExportStatement(node) { + const firstToken = isParenthesised(node) ? sourceCode.getTokenBefore(node) : sourceCode.getFirstToken(node); + const secondToken = sourceCode.getTokenAfter(firstToken, astUtils.isNotOpeningParenToken); + const thirdToken = secondToken ? sourceCode.getTokenAfter(secondToken) : null; + const tokenAfterClosingParens = secondToken ? sourceCode.getTokenAfter(secondToken, astUtils.isNotClosingParenToken) : null; + + if ( + astUtils.isOpeningParenToken(firstToken) && + ( + astUtils.isOpeningBraceToken(secondToken) || + secondToken.type === "Keyword" && ( + secondToken.value === "function" || + secondToken.value === "class" || + secondToken.value === "let" && + tokenAfterClosingParens && + ( + astUtils.isOpeningBracketToken(tokenAfterClosingParens) || + tokenAfterClosingParens.type === "Identifier" + ) + ) || + secondToken && secondToken.type === "Identifier" && secondToken.value === "async" && thirdToken && thirdToken.type === "Keyword" && thirdToken.value === "function" + ) + ) { + tokensToIgnore.add(secondToken); + } + + const hasExtraParens = node.parent.type === "ExportDefaultDeclaration" + ? hasExcessParensWithPrecedence(node, PRECEDENCE_OF_ASSIGNMENT_EXPR) + : hasExcessParens(node); + + if (hasExtraParens) { + report(node); + } + } + + /** + * Finds the path from the given node to the specified ancestor. + * @param {ASTNode} node First node in the path. + * @param {ASTNode} ancestor Last node in the path. + * @returns {ASTNode[]} Path, including both nodes. + * @throws {Error} If the given node does not have the specified ancestor. + */ + function pathToAncestor(node, ancestor) { + const path = [node]; + let currentNode = node; + + while (currentNode !== ancestor) { + + currentNode = currentNode.parent; + + /* istanbul ignore if */ + if (currentNode === null) { + throw new Error("Nodes are not in the ancestor-descendant relationship."); + } + + path.push(currentNode); + } + + return path; + } + + /** + * Finds the path from the given node to the specified descendant. + * @param {ASTNode} node First node in the path. + * @param {ASTNode} descendant Last node in the path. + * @returns {ASTNode[]} Path, including both nodes. + * @throws {Error} If the given node does not have the specified descendant. + */ + function pathToDescendant(node, descendant) { + return pathToAncestor(descendant, node).reverse(); + } + + /** + * Checks whether the syntax of the given ancestor of an 'in' expression inside a for-loop initializer + * is preventing the 'in' keyword from being interpreted as a part of an ill-formed for-in loop. + * @param {ASTNode} node Ancestor of an 'in' expression. + * @param {ASTNode} child Child of the node, ancestor of the same 'in' expression or the 'in' expression itself. + * @returns {boolean} True if the keyword 'in' would be interpreted as the 'in' operator, without any parenthesis. + */ + function isSafelyEnclosingInExpression(node, child) { + switch (node.type) { + case "ArrayExpression": + case "ArrayPattern": + case "BlockStatement": + case "ObjectExpression": + case "ObjectPattern": + case "TemplateLiteral": + return true; + case "ArrowFunctionExpression": + case "FunctionExpression": + return node.params.includes(child); + case "CallExpression": + case "NewExpression": + return node.arguments.includes(child); + case "MemberExpression": + return node.computed && node.property === child; + case "ConditionalExpression": + return node.consequent === child; + default: + return false; + } + } + + /** + * Starts a new reports buffering. Warnings will be stored in a buffer instead of being reported immediately. + * An additional logic that requires multiple nodes (e.g. a whole subtree) may dismiss some of the stored warnings. + * @returns {void} + */ + function startNewReportsBuffering() { + reportsBuffer = { + upper: reportsBuffer, + inExpressionNodes: [], + reports: [] + }; + } + + /** + * Ends the current reports buffering. + * @returns {void} + */ + function endCurrentReportsBuffering() { + const { upper, inExpressionNodes, reports } = reportsBuffer; + + if (upper) { + upper.inExpressionNodes.push(...inExpressionNodes); + upper.reports.push(...reports); + } else { + + // flush remaining reports + reports.forEach(({ finishReport }) => finishReport()); + } + + reportsBuffer = upper; + } + + /** + * Checks whether the given node is in the current reports buffer. + * @param {ASTNode} node Node to check. + * @returns {boolean} True if the node is in the current buffer, false otherwise. + */ + function isInCurrentReportsBuffer(node) { + return reportsBuffer.reports.some(r => r.node === node); + } + + /** + * Removes the given node from the current reports buffer. + * @param {ASTNode} node Node to remove. + * @returns {void} + */ + function removeFromCurrentReportsBuffer(node) { + reportsBuffer.reports = reportsBuffer.reports.filter(r => r.node !== node); + } + + /** + * Checks whether a node is a MemberExpression at NewExpression's callee. + * @param {ASTNode} node node to check. + * @returns {boolean} True if the node is a MemberExpression at NewExpression's callee. false otherwise. + */ + function isMemberExpInNewCallee(node) { + if (node.type === "MemberExpression") { + return node.parent.type === "NewExpression" && node.parent.callee === node + ? true + : node.parent.object === node && isMemberExpInNewCallee(node.parent); + } + return false; + } + + return { + ArrayExpression(node) { + node.elements + .filter(e => e && hasExcessParensWithPrecedence(e, PRECEDENCE_OF_ASSIGNMENT_EXPR)) + .forEach(report); + }, + + ArrayPattern(node) { + node.elements + .filter(e => canBeAssignmentTarget(e) && hasExcessParens(e)) + .forEach(report); + }, + + ArrowFunctionExpression(node) { + if (isReturnAssignException(node)) { + return; + } + + if (node.body.type === "ConditionalExpression" && + IGNORE_ARROW_CONDITIONALS + ) { + return; + } + + if (node.body.type !== "BlockStatement") { + const firstBodyToken = sourceCode.getFirstToken(node.body, astUtils.isNotOpeningParenToken); + const tokenBeforeFirst = sourceCode.getTokenBefore(firstBodyToken); + + if (astUtils.isOpeningParenToken(tokenBeforeFirst) && astUtils.isOpeningBraceToken(firstBodyToken)) { + tokensToIgnore.add(firstBodyToken); + } + if (hasExcessParensWithPrecedence(node.body, PRECEDENCE_OF_ASSIGNMENT_EXPR)) { + report(node.body); + } + } + }, + + AssignmentExpression(node) { + if (canBeAssignmentTarget(node.left) && hasExcessParens(node.left)) { + report(node.left); + } + + if (!isReturnAssignException(node) && hasExcessParensWithPrecedence(node.right, precedence(node))) { + report(node.right); + } + }, + + BinaryExpression(node) { + if (reportsBuffer && node.operator === "in") { + reportsBuffer.inExpressionNodes.push(node); + } + + checkBinaryLogical(node); + }, + + CallExpression: checkCallNew, + + ClassBody(node) { + node.body + .filter(member => member.type === "MethodDefinition" && member.computed && member.key) + .filter(member => hasExcessParensWithPrecedence(member.key, PRECEDENCE_OF_ASSIGNMENT_EXPR)) + .forEach(member => report(member.key)); + }, + + ConditionalExpression(node) { + if (isReturnAssignException(node)) { + return; + } + if ( + !isCondAssignException(node) && + hasExcessParensWithPrecedence(node.test, precedence({ type: "LogicalExpression", operator: "||" })) + ) { + report(node.test); + } + + if (hasExcessParensWithPrecedence(node.consequent, PRECEDENCE_OF_ASSIGNMENT_EXPR)) { + report(node.consequent); + } + + if (hasExcessParensWithPrecedence(node.alternate, PRECEDENCE_OF_ASSIGNMENT_EXPR)) { + report(node.alternate); + } + }, + + DoWhileStatement(node) { + if (hasExcessParens(node.test) && !isCondAssignException(node)) { + report(node.test); + } + }, + + ExportDefaultDeclaration: node => checkExpressionOrExportStatement(node.declaration), + ExpressionStatement: node => checkExpressionOrExportStatement(node.expression), + + ForInStatement(node) { + if (node.left.type !== "VariableDeclaration") { + const firstLeftToken = sourceCode.getFirstToken(node.left, astUtils.isNotOpeningParenToken); + + if ( + firstLeftToken.value === "let" && + astUtils.isOpeningBracketToken( + sourceCode.getTokenAfter(firstLeftToken, astUtils.isNotClosingParenToken) + ) + ) { + + // ForInStatement#left expression cannot start with `let[`. + tokensToIgnore.add(firstLeftToken); + } + } + + if (hasExcessParens(node.left)) { + report(node.left); + } + + if (hasExcessParens(node.right)) { + report(node.right); + } + }, + + ForOfStatement(node) { + if (node.left.type !== "VariableDeclaration") { + const firstLeftToken = sourceCode.getFirstToken(node.left, astUtils.isNotOpeningParenToken); + + if (firstLeftToken.value === "let") { + + // ForOfStatement#left expression cannot start with `let`. + tokensToIgnore.add(firstLeftToken); + } + } + + if (hasExcessParens(node.left)) { + report(node.left); + } + + if (hasExcessParensWithPrecedence(node.right, PRECEDENCE_OF_ASSIGNMENT_EXPR)) { + report(node.right); + } + }, + + ForStatement(node) { + if (node.test && hasExcessParens(node.test) && !isCondAssignException(node)) { + report(node.test); + } + + if (node.update && hasExcessParens(node.update)) { + report(node.update); + } + + if (node.init) { + + if (node.init.type !== "VariableDeclaration") { + const firstToken = sourceCode.getFirstToken(node.init, astUtils.isNotOpeningParenToken); + + if ( + firstToken.value === "let" && + astUtils.isOpeningBracketToken( + sourceCode.getTokenAfter(firstToken, astUtils.isNotClosingParenToken) + ) + ) { + + // ForStatement#init expression cannot start with `let[`. + tokensToIgnore.add(firstToken); + } + } + + startNewReportsBuffering(); + + if (hasExcessParens(node.init)) { + report(node.init); + } + } + }, + + "ForStatement > *.init:exit"(node) { + + /* + * Removing parentheses around `in` expressions might change semantics and cause errors. + * + * For example, this valid for loop: + * for (let a = (b in c); ;); + * after removing parentheses would be treated as an invalid for-in loop: + * for (let a = b in c; ;); + */ + + if (reportsBuffer.reports.length) { + reportsBuffer.inExpressionNodes.forEach(inExpressionNode => { + const path = pathToDescendant(node, inExpressionNode); + let nodeToExclude; + + for (let i = 0; i < path.length; i++) { + const pathNode = path[i]; + + if (i < path.length - 1) { + const nextPathNode = path[i + 1]; + + if (isSafelyEnclosingInExpression(pathNode, nextPathNode)) { + + // The 'in' expression in safely enclosed by the syntax of its ancestor nodes (e.g. by '{}' or '[]'). + return; + } + } + + if (isParenthesised(pathNode)) { + if (isInCurrentReportsBuffer(pathNode)) { + + // This node was supposed to be reported, but parentheses might be necessary. + + if (isParenthesisedTwice(pathNode)) { + + /* + * This node is parenthesised twice, it certainly has at least one pair of `extra` parentheses. + * If the --fix option is on, the current fixing iteration will remove only one pair of parentheses. + * The remaining pair is safely enclosing the 'in' expression. + */ + return; + } + + // Exclude the outermost node only. + if (!nodeToExclude) { + nodeToExclude = pathNode; + } + + // Don't break the loop here, there might be some safe nodes or parentheses that will stay inside. + + } else { + + // This node will stay parenthesised, the 'in' expression in safely enclosed by '()'. + return; + } + } + } + + // Exclude the node from the list (i.e. treat parentheses as necessary) + removeFromCurrentReportsBuffer(nodeToExclude); + }); + } + + endCurrentReportsBuffering(); + }, + + IfStatement(node) { + if (hasExcessParens(node.test) && !isCondAssignException(node)) { + report(node.test); + } + }, + + ImportExpression(node) { + const { source } = node; + + if (source.type === "SequenceExpression") { + if (hasDoubleExcessParens(source)) { + report(source); + } + } else if (hasExcessParens(source)) { + report(source); + } + }, + + LogicalExpression: checkBinaryLogical, + + MemberExpression(node) { + const shouldAllowWrapOnce = isMemberExpInNewCallee(node) && + doesMemberExpressionContainCallExpression(node); + const nodeObjHasExcessParens = shouldAllowWrapOnce + ? hasDoubleExcessParens(node.object) + : hasExcessParens(node.object) && + !( + isImmediateFunctionPrototypeMethodCall(node.parent) && + node.parent.callee === node && + IGNORE_FUNCTION_PROTOTYPE_METHODS + ); + + if ( + nodeObjHasExcessParens && + precedence(node.object) >= precedence(node) && + ( + node.computed || + !( + astUtils.isDecimalInteger(node.object) || + + // RegExp literal is allowed to have parens (#1589) + (node.object.type === "Literal" && node.object.regex) + ) + ) + ) { + report(node.object); + } + + if (nodeObjHasExcessParens && + node.object.type === "CallExpression" + ) { + report(node.object); + } + + if (nodeObjHasExcessParens && + !IGNORE_NEW_IN_MEMBER_EXPR && + node.object.type === "NewExpression" && + isNewExpressionWithParens(node.object)) { + report(node.object); + } + + if (nodeObjHasExcessParens && + node.optional && + node.object.type === "ChainExpression" + ) { + report(node.object); + } + + if (node.computed && hasExcessParens(node.property)) { + report(node.property); + } + }, + + NewExpression: checkCallNew, + + ObjectExpression(node) { + node.properties + .filter(property => property.value && hasExcessParensWithPrecedence(property.value, PRECEDENCE_OF_ASSIGNMENT_EXPR)) + .forEach(property => report(property.value)); + }, + + ObjectPattern(node) { + node.properties + .filter(property => { + const value = property.value; + + return canBeAssignmentTarget(value) && hasExcessParens(value); + }).forEach(property => report(property.value)); + }, + + Property(node) { + if (node.computed) { + const { key } = node; + + if (key && hasExcessParensWithPrecedence(key, PRECEDENCE_OF_ASSIGNMENT_EXPR)) { + report(key); + } + } + }, + + RestElement(node) { + const argument = node.argument; + + if (canBeAssignmentTarget(argument) && hasExcessParens(argument)) { + report(argument); + } + }, + + ReturnStatement(node) { + const returnToken = sourceCode.getFirstToken(node); + + if (isReturnAssignException(node)) { + return; + } + + if (node.argument && + hasExcessParensNoLineTerminator(returnToken, node.argument) && + + // RegExp literal is allowed to have parens (#1589) + !(node.argument.type === "Literal" && node.argument.regex)) { + report(node.argument); + } + }, + + SequenceExpression(node) { + const precedenceOfNode = precedence(node); + + node.expressions + .filter(e => hasExcessParensWithPrecedence(e, precedenceOfNode)) + .forEach(report); + }, + + SwitchCase(node) { + if (node.test && hasExcessParens(node.test)) { + report(node.test); + } + }, + + SwitchStatement(node) { + if (hasExcessParens(node.discriminant)) { + report(node.discriminant); + } + }, + + ThrowStatement(node) { + const throwToken = sourceCode.getFirstToken(node); + + if (hasExcessParensNoLineTerminator(throwToken, node.argument)) { + report(node.argument); + } + }, + + UnaryExpression: checkArgumentWithPrecedence, + UpdateExpression(node) { + if (node.prefix) { + checkArgumentWithPrecedence(node); + } else { + const { argument } = node; + const operatorToken = sourceCode.getLastToken(node); + + if (argument.loc.end.line === operatorToken.loc.start.line) { + checkArgumentWithPrecedence(node); + } else { + if (hasDoubleExcessParens(argument)) { + report(argument); + } + } + } + }, + AwaitExpression: checkArgumentWithPrecedence, + + VariableDeclarator(node) { + if ( + node.init && hasExcessParensWithPrecedence(node.init, PRECEDENCE_OF_ASSIGNMENT_EXPR) && + + // RegExp literal is allowed to have parens (#1589) + !(node.init.type === "Literal" && node.init.regex) + ) { + report(node.init); + } + }, + + WhileStatement(node) { + if (hasExcessParens(node.test) && !isCondAssignException(node)) { + report(node.test); + } + }, + + WithStatement(node) { + if (hasExcessParens(node.object)) { + report(node.object); + } + }, + + YieldExpression(node) { + if (node.argument) { + const yieldToken = sourceCode.getFirstToken(node); + + if ((precedence(node.argument) >= precedence(node) && + hasExcessParensNoLineTerminator(yieldToken, node.argument)) || + hasDoubleExcessParens(node.argument)) { + report(node.argument); + } + } + }, + + ClassDeclaration: checkClass, + ClassExpression: checkClass, + + SpreadElement: checkSpreadOperator, + SpreadProperty: checkSpreadOperator, + ExperimentalSpreadProperty: checkSpreadOperator, + + TemplateLiteral(node) { + node.expressions + .filter(e => e && hasExcessParens(e)) + .forEach(report); + }, + + AssignmentPattern(node) { + const { left, right } = node; + + if (canBeAssignmentTarget(left) && hasExcessParens(left)) { + report(left); + } + + if (right && hasExcessParensWithPrecedence(right, PRECEDENCE_OF_ASSIGNMENT_EXPR)) { + report(right); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag use of unnecessary semicolons + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noExtraSemi = { + meta: { + type: "suggestion", + + docs: { + description: "disallow unnecessary semicolons", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-extra-semi" + }, + + fixable: "code", + schema: [], + + messages: { + unexpected: "Unnecessary semicolon." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + /** + * Reports an unnecessary semicolon error. + * @param {Node|Token} nodeOrToken A node or a token to be reported. + * @returns {void} + */ + function report(nodeOrToken) { + context.report({ + node: nodeOrToken, + messageId: "unexpected", + fix(fixer) { + + /* + * Expand the replacement range to include the surrounding + * tokens to avoid conflicting with semi. + * https://github.com/eslint/eslint/issues/7928 + */ + return new fixTracker(fixer, context.getSourceCode()) + .retainSurroundingTokens(nodeOrToken) + .remove(nodeOrToken); + } + }); + } + + /** + * Checks for a part of a class body. + * This checks tokens from a specified token to a next MethodDefinition or the end of class body. + * @param {Token} firstToken The first token to check. + * @returns {void} + */ + function checkForPartOfClassBody(firstToken) { + for (let token = firstToken; + token.type === "Punctuator" && !astUtils.isClosingBraceToken(token); + token = sourceCode.getTokenAfter(token) + ) { + if (astUtils.isSemicolonToken(token)) { + report(token); + } + } + } + + return { + + /** + * Reports this empty statement, except if the parent node is a loop. + * @param {Node} node A EmptyStatement node to be reported. + * @returns {void} + */ + EmptyStatement(node) { + const parent = node.parent, + allowedParentTypes = [ + "ForStatement", + "ForInStatement", + "ForOfStatement", + "WhileStatement", + "DoWhileStatement", + "IfStatement", + "LabeledStatement", + "WithStatement" + ]; + + if (allowedParentTypes.indexOf(parent.type) === -1) { + report(node); + } + }, + + /** + * Checks tokens from the head of this class body to the first MethodDefinition or the end of this class body. + * @param {Node} node A ClassBody node to check. + * @returns {void} + */ + ClassBody(node) { + checkForPartOfClassBody(sourceCode.getFirstToken(node, 1)); // 0 is `{`. + }, + + /** + * Checks tokens from this MethodDefinition to the next MethodDefinition or the end of this class body. + * @param {Node} node A MethodDefinition node of the start point. + * @returns {void} + */ + MethodDefinition(node) { + checkForPartOfClassBody(sourceCode.getTokenAfter(node)); + } + }; + + } +}; + +/** + * @fileoverview Rule to flag fall-through cases in switch statements. + * @author Matt DuVall + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const DEFAULT_FALLTHROUGH_COMMENT = /falls?\s?through/iu; + +/** + * Checks whether or not a given node has a fallthrough comment. + * @param {ASTNode} node A SwitchCase node to get comments. + * @param {RuleContext} context A rule context which stores comments. + * @param {RegExp} fallthroughCommentPattern A pattern to match comment to. + * @returns {boolean} `true` if the node has a valid fallthrough comment. + */ +function hasFallthroughComment(node, context, fallthroughCommentPattern) { + const sourceCode = context.getSourceCode(); + const comment = lodash__default['default'].last(sourceCode.getCommentsBefore(node)); + + return Boolean(comment && fallthroughCommentPattern.test(comment.value)); +} + +/** + * Checks whether or not a given code path segment is reachable. + * @param {CodePathSegment} segment A CodePathSegment to check. + * @returns {boolean} `true` if the segment is reachable. + */ +function isReachable(segment) { + return segment.reachable; +} + +/** + * Checks whether a node and a token are separated by blank lines + * @param {ASTNode} node The node to check + * @param {Token} token The token to compare against + * @returns {boolean} `true` if there are blank lines between node and token + */ +function hasBlankLinesBetween(node, token) { + return token.loc.start.line > node.loc.end.line + 1; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noFallthrough = { + meta: { + type: "problem", + + docs: { + description: "disallow fallthrough of `case` statements", + category: "Best Practices", + recommended: true, + url: "https://eslint.org/docs/rules/no-fallthrough" + }, + + schema: [ + { + type: "object", + properties: { + commentPattern: { + type: "string", + default: "" + } + }, + additionalProperties: false + } + ], + messages: { + case: "Expected a 'break' statement before 'case'.", + default: "Expected a 'break' statement before 'default'." + } + }, + + create(context) { + const options = context.options[0] || {}; + let currentCodePath = null; + const sourceCode = context.getSourceCode(); + + /* + * We need to use leading comments of the next SwitchCase node because + * trailing comments is wrong if semicolons are omitted. + */ + let fallthroughCase = null; + let fallthroughCommentPattern = null; + + if (options.commentPattern) { + fallthroughCommentPattern = new RegExp(options.commentPattern, "u"); + } else { + fallthroughCommentPattern = DEFAULT_FALLTHROUGH_COMMENT; + } + + return { + onCodePathStart(codePath) { + currentCodePath = codePath; + }, + onCodePathEnd() { + currentCodePath = currentCodePath.upper; + }, + + SwitchCase(node) { + + /* + * Checks whether or not there is a fallthrough comment. + * And reports the previous fallthrough node if that does not exist. + */ + if (fallthroughCase && !hasFallthroughComment(node, context, fallthroughCommentPattern)) { + context.report({ + messageId: node.test ? "case" : "default", + node + }); + } + fallthroughCase = null; + }, + + "SwitchCase:exit"(node) { + const nextToken = sourceCode.getTokenAfter(node); + + /* + * `reachable` meant fall through because statements preceded by + * `break`, `return`, or `throw` are unreachable. + * And allows empty cases and the last case. + */ + if (currentCodePath.currentSegments.some(isReachable) && + (node.consequent.length > 0 || hasBlankLinesBetween(node, nextToken)) && + lodash__default['default'].last(node.parent.cases) !== node) { + fallthroughCase = node; + } + } + }; + } +}; + +/** + * @fileoverview Rule to flag use of a leading/trailing decimal point in a numeric literal + * @author James Allardice + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noFloatingDecimal = { + meta: { + type: "suggestion", + + docs: { + description: "disallow leading or trailing decimal points in numeric literals", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-floating-decimal" + }, + + schema: [], + fixable: "code", + messages: { + leading: "A leading decimal point can be confused with a dot.", + trailing: "A trailing decimal point can be confused with a dot." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + Literal(node) { + + if (typeof node.value === "number") { + if (node.raw.startsWith(".")) { + context.report({ + node, + messageId: "leading", + fix(fixer) { + const tokenBefore = sourceCode.getTokenBefore(node); + const needsSpaceBefore = tokenBefore && + tokenBefore.range[1] === node.range[0] && + !astUtils.canTokensBeAdjacent(tokenBefore, `0${node.raw}`); + + return fixer.insertTextBefore(node, needsSpaceBefore ? " 0" : "0"); + } + }); + } + if (node.raw.indexOf(".") === node.raw.length - 1) { + context.report({ + node, + messageId: "trailing", + fix: fixer => fixer.insertTextAfter(node, "0") + }); + } + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag use of function declaration identifiers as variables. + * @author Ian Christian Myers + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noFuncAssign = { + meta: { + type: "problem", + + docs: { + description: "disallow reassigning `function` declarations", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-func-assign" + }, + + schema: [], + + messages: { + isAFunction: "'{{name}}' is a function." + } + }, + + create(context) { + + /** + * Reports a reference if is non initializer and writable. + * @param {References} references Collection of reference to check. + * @returns {void} + */ + function checkReference(references) { + astUtils.getModifyingReferences(references).forEach(reference => { + context.report({ + node: reference.identifier, + messageId: "isAFunction", + data: { + name: reference.identifier.name + } + }); + }); + } + + /** + * Finds and reports references that are non initializer and writable. + * @param {Variable} variable A variable to check. + * @returns {void} + */ + function checkVariable(variable) { + if (variable.defs[0].type === "FunctionName") { + checkReference(variable.references); + } + } + + /** + * Checks parameters of a given function node. + * @param {ASTNode} node A function node to check. + * @returns {void} + */ + function checkForFunction(node) { + context.getDeclaredVariables(node).forEach(checkVariable); + } + + return { + FunctionDeclaration: checkForFunction, + FunctionExpression: checkForFunction + }; + } +}; + +/** + * @fileoverview Rule to disallow assignments to native objects or read-only global variables + * @author Ilya Volodin + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noGlobalAssign = { + meta: { + type: "suggestion", + + docs: { + description: "disallow assignments to native objects or read-only global variables", + category: "Best Practices", + recommended: true, + url: "https://eslint.org/docs/rules/no-global-assign" + }, + + schema: [ + { + type: "object", + properties: { + exceptions: { + type: "array", + items: { type: "string" }, + uniqueItems: true + } + }, + additionalProperties: false + } + ], + + messages: { + globalShouldNotBeModified: "Read-only global '{{name}}' should not be modified." + } + }, + + create(context) { + const config = context.options[0]; + const exceptions = (config && config.exceptions) || []; + + /** + * Reports write references. + * @param {Reference} reference A reference to check. + * @param {int} index The index of the reference in the references. + * @param {Reference[]} references The array that the reference belongs to. + * @returns {void} + */ + function checkReference(reference, index, references) { + const identifier = reference.identifier; + + if (reference.init === false && + reference.isWrite() && + + /* + * Destructuring assignments can have multiple default value, + * so possibly there are multiple writeable references for the same identifier. + */ + (index === 0 || references[index - 1].identifier !== identifier) + ) { + context.report({ + node: identifier, + messageId: "globalShouldNotBeModified", + data: { + name: identifier.name + } + }); + } + } + + /** + * Reports write references if a given variable is read-only builtin. + * @param {Variable} variable A variable to check. + * @returns {void} + */ + function checkVariable(variable) { + if (variable.writeable === false && exceptions.indexOf(variable.name) === -1) { + variable.references.forEach(checkReference); + } + } + + return { + Program() { + const globalScope = context.getScope(); + + globalScope.variables.forEach(checkVariable); + } + }; + } +}; + +/** + * @fileoverview A rule to disallow the type conversions with shorter notations. + * @author Toru Nagashima + */ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const INDEX_OF_PATTERN = /^(?:i|lastI)ndexOf$/u; +const ALLOWABLE_OPERATORS = ["~", "!!", "+", "*"]; + +/** + * Parses and normalizes an option object. + * @param {Object} options An option object to parse. + * @returns {Object} The parsed and normalized option object. + */ +function parseOptions$1(options) { + return { + boolean: "boolean" in options ? options.boolean : true, + number: "number" in options ? options.number : true, + string: "string" in options ? options.string : true, + disallowTemplateShorthand: "disallowTemplateShorthand" in options ? options.disallowTemplateShorthand : false, + allow: options.allow || [] + }; +} + +/** + * Checks whether or not a node is a double logical nigating. + * @param {ASTNode} node An UnaryExpression node to check. + * @returns {boolean} Whether or not the node is a double logical nigating. + */ +function isDoubleLogicalNegating(node) { + return ( + node.operator === "!" && + node.argument.type === "UnaryExpression" && + node.argument.operator === "!" + ); +} + +/** + * Checks whether or not a node is a binary negating of `.indexOf()` method calling. + * @param {ASTNode} node An UnaryExpression node to check. + * @returns {boolean} Whether or not the node is a binary negating of `.indexOf()` method calling. + */ +function isBinaryNegatingOfIndexOf(node) { + if (node.operator !== "~") { + return false; + } + const callNode = astUtils.skipChainExpression(node.argument); + + return ( + callNode.type === "CallExpression" && + astUtils.isSpecificMemberAccess(callNode.callee, null, INDEX_OF_PATTERN) + ); +} + +/** + * Checks whether or not a node is a multiplying by one. + * @param {BinaryExpression} node A BinaryExpression node to check. + * @returns {boolean} Whether or not the node is a multiplying by one. + */ +function isMultiplyByOne(node) { + return node.operator === "*" && ( + node.left.type === "Literal" && node.left.value === 1 || + node.right.type === "Literal" && node.right.value === 1 + ); +} + +/** + * Checks whether the result of a node is numeric or not + * @param {ASTNode} node The node to test + * @returns {boolean} true if the node is a number literal or a `Number()`, `parseInt` or `parseFloat` call + */ +function isNumeric(node) { + return ( + node.type === "Literal" && typeof node.value === "number" || + node.type === "CallExpression" && ( + node.callee.name === "Number" || + node.callee.name === "parseInt" || + node.callee.name === "parseFloat" + ) + ); +} + +/** + * Returns the first non-numeric operand in a BinaryExpression. Designed to be + * used from bottom to up since it walks up the BinaryExpression trees using + * node.parent to find the result. + * @param {BinaryExpression} node The BinaryExpression node to be walked up on + * @returns {ASTNode|null} The first non-numeric item in the BinaryExpression tree or null + */ +function getNonNumericOperand(node) { + const left = node.left, + right = node.right; + + if (right.type !== "BinaryExpression" && !isNumeric(right)) { + return right; + } + + if (left.type !== "BinaryExpression" && !isNumeric(left)) { + return left; + } + + return null; +} + +/** + * Checks whether a node is an empty string literal or not. + * @param {ASTNode} node The node to check. + * @returns {boolean} Whether or not the passed in node is an + * empty string literal or not. + */ +function isEmptyString(node) { + return astUtils.isStringLiteral(node) && (node.value === "" || (node.type === "TemplateLiteral" && node.quasis.length === 1 && node.quasis[0].value.cooked === "")); +} + +/** + * Checks whether or not a node is a concatenating with an empty string. + * @param {ASTNode} node A BinaryExpression node to check. + * @returns {boolean} Whether or not the node is a concatenating with an empty string. + */ +function isConcatWithEmptyString(node) { + return node.operator === "+" && ( + (isEmptyString(node.left) && !astUtils.isStringLiteral(node.right)) || + (isEmptyString(node.right) && !astUtils.isStringLiteral(node.left)) + ); +} + +/** + * Checks whether or not a node is appended with an empty string. + * @param {ASTNode} node An AssignmentExpression node to check. + * @returns {boolean} Whether or not the node is appended with an empty string. + */ +function isAppendEmptyString(node) { + return node.operator === "+=" && isEmptyString(node.right); +} + +/** + * Returns the operand that is not an empty string from a flagged BinaryExpression. + * @param {ASTNode} node The flagged BinaryExpression node to check. + * @returns {ASTNode} The operand that is not an empty string from a flagged BinaryExpression. + */ +function getNonEmptyOperand(node) { + return isEmptyString(node.left) ? node.right : node.left; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noImplicitCoercion = { + meta: { + type: "suggestion", + + docs: { + description: "disallow shorthand type conversions", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-implicit-coercion" + }, + + fixable: "code", + + schema: [{ + type: "object", + properties: { + boolean: { + type: "boolean", + default: true + }, + number: { + type: "boolean", + default: true + }, + string: { + type: "boolean", + default: true + }, + disallowTemplateShorthand: { + type: "boolean", + default: false + }, + allow: { + type: "array", + items: { + enum: ALLOWABLE_OPERATORS + }, + uniqueItems: true + } + }, + additionalProperties: false + }], + + messages: { + useRecommendation: "use `{{recommendation}}` instead." + } + }, + + create(context) { + const options = parseOptions$1(context.options[0] || {}); + const sourceCode = context.getSourceCode(); + + /** + * Reports an error and autofixes the node + * @param {ASTNode} node An ast node to report the error on. + * @param {string} recommendation The recommended code for the issue + * @param {bool} shouldFix Whether this report should fix the node + * @returns {void} + */ + function report(node, recommendation, shouldFix) { + context.report({ + node, + messageId: "useRecommendation", + data: { + recommendation + }, + fix(fixer) { + if (!shouldFix) { + return null; + } + + const tokenBefore = sourceCode.getTokenBefore(node); + + if ( + tokenBefore && + tokenBefore.range[1] === node.range[0] && + !astUtils.canTokensBeAdjacent(tokenBefore, recommendation) + ) { + return fixer.replaceText(node, ` ${recommendation}`); + } + return fixer.replaceText(node, recommendation); + } + }); + } + + return { + UnaryExpression(node) { + let operatorAllowed; + + // !!foo + operatorAllowed = options.allow.indexOf("!!") >= 0; + if (!operatorAllowed && options.boolean && isDoubleLogicalNegating(node)) { + const recommendation = `Boolean(${sourceCode.getText(node.argument.argument)})`; + + report(node, recommendation, true); + } + + // ~foo.indexOf(bar) + operatorAllowed = options.allow.indexOf("~") >= 0; + if (!operatorAllowed && options.boolean && isBinaryNegatingOfIndexOf(node)) { + + // `foo?.indexOf(bar) !== -1` will be true (== found) if the `foo` is nullish. So use `>= 0` in that case. + const comparison = node.argument.type === "ChainExpression" ? ">= 0" : "!== -1"; + const recommendation = `${sourceCode.getText(node.argument)} ${comparison}`; + + report(node, recommendation, false); + } + + // +foo + operatorAllowed = options.allow.indexOf("+") >= 0; + if (!operatorAllowed && options.number && node.operator === "+" && !isNumeric(node.argument)) { + const recommendation = `Number(${sourceCode.getText(node.argument)})`; + + report(node, recommendation, true); + } + }, + + // Use `:exit` to prevent double reporting + "BinaryExpression:exit"(node) { + let operatorAllowed; + + // 1 * foo + operatorAllowed = options.allow.indexOf("*") >= 0; + const nonNumericOperand = !operatorAllowed && options.number && isMultiplyByOne(node) && getNonNumericOperand(node); + + if (nonNumericOperand) { + const recommendation = `Number(${sourceCode.getText(nonNumericOperand)})`; + + report(node, recommendation, true); + } + + // "" + foo + operatorAllowed = options.allow.indexOf("+") >= 0; + if (!operatorAllowed && options.string && isConcatWithEmptyString(node)) { + const recommendation = `String(${sourceCode.getText(getNonEmptyOperand(node))})`; + + report(node, recommendation, true); + } + }, + + AssignmentExpression(node) { + + // foo += "" + const operatorAllowed = options.allow.indexOf("+") >= 0; + + if (!operatorAllowed && options.string && isAppendEmptyString(node)) { + const code = sourceCode.getText(getNonEmptyOperand(node)); + const recommendation = `${code} = String(${code})`; + + report(node, recommendation, true); + } + }, + + TemplateLiteral(node) { + if (!options.disallowTemplateShorthand) { + return; + } + + // tag`${foo}` + if (node.parent.type === "TaggedTemplateExpression") { + return; + } + + // `` or `${foo}${bar}` + if (node.expressions.length !== 1) { + return; + } + + + // `prefix${foo}` + if (node.quasis[0].value.cooked !== "") { + return; + } + + // `${foo}postfix` + if (node.quasis[1].value.cooked !== "") { + return; + } + + const code = sourceCode.getText(node.expressions[0]); + const recommendation = `String(${code})`; + + report(node, recommendation, true); + } + }; + } +}; + +/** + * @fileoverview Rule to check for implicit global variables, functions and classes. + * @author Joshua Peek + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noImplicitGlobals = { + meta: { + type: "suggestion", + + docs: { + description: "disallow declarations in the global scope", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-implicit-globals" + }, + + schema: [{ + type: "object", + properties: { + lexicalBindings: { + type: "boolean", + default: false + } + }, + additionalProperties: false + }], + + messages: { + globalNonLexicalBinding: "Unexpected {{kind}} declaration in the global scope, wrap in an IIFE for a local variable, assign as global property for a global variable.", + globalLexicalBinding: "Unexpected {{kind}} declaration in the global scope, wrap in a block or in an IIFE.", + globalVariableLeak: "Global variable leak, declare the variable if it is intended to be local.", + assignmentToReadonlyGlobal: "Unexpected assignment to read-only global variable.", + redeclarationOfReadonlyGlobal: "Unexpected redeclaration of read-only global variable." + } + }, + + create(context) { + + const checkLexicalBindings = context.options[0] && context.options[0].lexicalBindings === true; + + /** + * Reports the node. + * @param {ASTNode} node Node to report. + * @param {string} messageId Id of the message to report. + * @param {string|undefined} kind Declaration kind, can be 'var', 'const', 'let', function or class. + * @returns {void} + */ + function report(node, messageId, kind) { + context.report({ + node, + messageId, + data: { + kind + } + }); + } + + return { + Program() { + const scope = context.getScope(); + + scope.variables.forEach(variable => { + + // Only ESLint global variables have the `writable` key. + const isReadonlyEslintGlobalVariable = variable.writeable === false; + const isWritableEslintGlobalVariable = variable.writeable === true; + + if (isWritableEslintGlobalVariable) { + + // Everything is allowed with writable ESLint global variables. + return; + } + + variable.defs.forEach(def => { + const defNode = def.node; + + if (def.type === "FunctionName" || (def.type === "Variable" && def.parent.kind === "var")) { + if (isReadonlyEslintGlobalVariable) { + report(defNode, "redeclarationOfReadonlyGlobal"); + } else { + report( + defNode, + "globalNonLexicalBinding", + def.type === "FunctionName" ? "function" : `'${def.parent.kind}'` + ); + } + } + + if (checkLexicalBindings) { + if (def.type === "ClassName" || + (def.type === "Variable" && (def.parent.kind === "let" || def.parent.kind === "const"))) { + if (isReadonlyEslintGlobalVariable) { + report(defNode, "redeclarationOfReadonlyGlobal"); + } else { + report( + defNode, + "globalLexicalBinding", + def.type === "ClassName" ? "class" : `'${def.parent.kind}'` + ); + } + } + } + }); + }); + + // Undeclared assigned variables. + scope.implicit.variables.forEach(variable => { + const scopeVariable = scope.set.get(variable.name); + let messageId; + + if (scopeVariable) { + + // ESLint global variable + if (scopeVariable.writeable) { + return; + } + messageId = "assignmentToReadonlyGlobal"; + + } else { + + // Reference to an unknown variable, possible global leak. + messageId = "globalVariableLeak"; + } + + // def.node is an AssignmentExpression, ForInStatement or ForOfStatement. + variable.defs.forEach(def => { + report(def.node, messageId); + }); + }); + } + }; + + } +}; + +/** + * @fileoverview Rule to flag use of implied eval via setTimeout and setInterval + * @author James Allardice + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + +const { getStaticValue } = require$$0__default$1['default']; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noImpliedEval = { + meta: { + type: "suggestion", + + docs: { + description: "disallow the use of `eval()`-like methods", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-implied-eval" + }, + + schema: [], + + messages: { + impliedEval: "Implied eval. Consider passing a function instead of a string." + } + }, + + create(context) { + const GLOBAL_CANDIDATES = Object.freeze(["global", "window", "globalThis"]); + const EVAL_LIKE_FUNC_PATTERN = /^(?:set(?:Interval|Timeout)|execScript)$/u; + + /** + * Checks whether a node is evaluated as a string or not. + * @param {ASTNode} node A node to check. + * @returns {boolean} True if the node is evaluated as a string. + */ + function isEvaluatedString(node) { + if ( + (node.type === "Literal" && typeof node.value === "string") || + node.type === "TemplateLiteral" + ) { + return true; + } + if (node.type === "BinaryExpression" && node.operator === "+") { + return isEvaluatedString(node.left) || isEvaluatedString(node.right); + } + return false; + } + + /** + * Reports if the `CallExpression` node has evaluated argument. + * @param {ASTNode} node A CallExpression to check. + * @returns {void} + */ + function reportImpliedEvalCallExpression(node) { + const [firstArgument] = node.arguments; + + if (firstArgument) { + + const staticValue = getStaticValue(firstArgument, context.getScope()); + const isStaticString = staticValue && typeof staticValue.value === "string"; + const isString = isStaticString || isEvaluatedString(firstArgument); + + if (isString) { + context.report({ + node, + messageId: "impliedEval" + }); + } + } + + } + + /** + * Reports calls of `implied eval` via the global references. + * @param {Variable} globalVar A global variable to check. + * @returns {void} + */ + function reportImpliedEvalViaGlobal(globalVar) { + const { references, name } = globalVar; + + references.forEach(ref => { + const identifier = ref.identifier; + let node = identifier.parent; + + while (astUtils.isSpecificMemberAccess(node, null, name)) { + node = node.parent; + } + + if (astUtils.isSpecificMemberAccess(node, null, EVAL_LIKE_FUNC_PATTERN)) { + const calleeNode = node.parent.type === "ChainExpression" ? node.parent : node; + const parent = calleeNode.parent; + + if (parent.type === "CallExpression" && parent.callee === calleeNode) { + reportImpliedEvalCallExpression(parent); + } + } + }); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + CallExpression(node) { + if (astUtils.isSpecificId(node.callee, EVAL_LIKE_FUNC_PATTERN)) { + reportImpliedEvalCallExpression(node); + } + }, + "Program:exit"() { + const globalScope = context.getScope(); + + GLOBAL_CANDIDATES + .map(candidate => astUtils.getVariableByName(globalScope, candidate)) + .filter(globalVar => !!globalVar && globalVar.defs.length === 0) + .forEach(reportImpliedEvalViaGlobal); + } + }; + + } +}; + +/** + * @fileoverview Rule to flag updates of imported bindings. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const { findVariable: findVariable$3 } = require$$0__default$1['default']; + + +const WellKnownMutationFunctions = { + Object: /^(?:assign|definePropert(?:y|ies)|freeze|setPrototypeOf)$/u, + Reflect: /^(?:(?:define|delete)Property|set(?:PrototypeOf)?)$/u +}; + +/** + * Check if a given node is LHS of an assignment node. + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if the node is LHS. + */ +function isAssignmentLeft(node) { + const { parent } = node; + + return ( + ( + parent.type === "AssignmentExpression" && + parent.left === node + ) || + + // Destructuring assignments + parent.type === "ArrayPattern" || + ( + parent.type === "Property" && + parent.value === node && + parent.parent.type === "ObjectPattern" + ) || + parent.type === "RestElement" || + ( + parent.type === "AssignmentPattern" && + parent.left === node + ) + ); +} + +/** + * Check if a given node is the operand of mutation unary operator. + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if the node is the operand of mutation unary operator. + */ +function isOperandOfMutationUnaryOperator(node) { + const argumentNode = node.parent.type === "ChainExpression" + ? node.parent + : node; + const { parent } = argumentNode; + + return ( + ( + parent.type === "UpdateExpression" && + parent.argument === argumentNode + ) || + ( + parent.type === "UnaryExpression" && + parent.operator === "delete" && + parent.argument === argumentNode + ) + ); +} + +/** + * Check if a given node is the iteration variable of `for-in`/`for-of` syntax. + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if the node is the iteration variable. + */ +function isIterationVariable(node) { + const { parent } = node; + + return ( + ( + parent.type === "ForInStatement" && + parent.left === node + ) || + ( + parent.type === "ForOfStatement" && + parent.left === node + ) + ); +} + +/** + * Check if a given node is at the first argument of a well-known mutation function. + * - `Object.assign` + * - `Object.defineProperty` + * - `Object.defineProperties` + * - `Object.freeze` + * - `Object.setPrototypeOf` + * - `Reflect.defineProperty` + * - `Reflect.deleteProperty` + * - `Reflect.set` + * - `Reflect.setPrototypeOf` + * @param {ASTNode} node The node to check. + * @param {Scope} scope A `escope.Scope` object to find variable (whichever). + * @returns {boolean} `true` if the node is at the first argument of a well-known mutation function. + */ +function isArgumentOfWellKnownMutationFunction(node, scope) { + const { parent } = node; + + if (parent.type !== "CallExpression" || parent.arguments[0] !== node) { + return false; + } + const callee = astUtils.skipChainExpression(parent.callee); + + if ( + !astUtils.isSpecificMemberAccess(callee, "Object", WellKnownMutationFunctions.Object) && + !astUtils.isSpecificMemberAccess(callee, "Reflect", WellKnownMutationFunctions.Reflect) + ) { + return false; + } + const variable = findVariable$3(scope, callee.object); + + return variable !== null && variable.scope.type === "global"; +} + +/** + * Check if the identifier node is placed at to update members. + * @param {ASTNode} id The Identifier node to check. + * @param {Scope} scope A `escope.Scope` object to find variable (whichever). + * @returns {boolean} `true` if the member of `id` was updated. + */ +function isMemberWrite(id, scope) { + const { parent } = id; + + return ( + ( + parent.type === "MemberExpression" && + parent.object === id && + ( + isAssignmentLeft(parent) || + isOperandOfMutationUnaryOperator(parent) || + isIterationVariable(parent) + ) + ) || + isArgumentOfWellKnownMutationFunction(id, scope) + ); +} + +/** + * Get the mutation node. + * @param {ASTNode} id The Identifier node to get. + * @returns {ASTNode} The mutation node. + */ +function getWriteNode(id) { + let node = id.parent; + + while ( + node && + node.type !== "AssignmentExpression" && + node.type !== "UpdateExpression" && + node.type !== "UnaryExpression" && + node.type !== "CallExpression" && + node.type !== "ForInStatement" && + node.type !== "ForOfStatement" + ) { + node = node.parent; + } + + return node || id; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noImportAssign = { + meta: { + type: "problem", + + docs: { + description: "disallow assigning to imported bindings", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-import-assign" + }, + + schema: [], + + messages: { + readonly: "'{{name}}' is read-only.", + readonlyMember: "The members of '{{name}}' are read-only." + } + }, + + create(context) { + return { + ImportDeclaration(node) { + const scope = context.getScope(); + + for (const variable of context.getDeclaredVariables(node)) { + const shouldCheckMembers = variable.defs.some( + d => d.node.type === "ImportNamespaceSpecifier" + ); + let prevIdNode = null; + + for (const reference of variable.references) { + const idNode = reference.identifier; + + /* + * AssignmentPattern (e.g. `[a = 0] = b`) makes two write + * references for the same identifier. This should skip + * the one of the two in order to prevent redundant reports. + */ + if (idNode === prevIdNode) { + continue; + } + prevIdNode = idNode; + + if (reference.isWrite()) { + context.report({ + node: getWriteNode(idNode), + messageId: "readonly", + data: { name: idNode.name } + }); + } else if (shouldCheckMembers && isMemberWrite(idNode, scope)) { + context.report({ + node: getWriteNode(idNode), + messageId: "readonlyMember", + data: { name: idNode.name } + }); + } + } + } + } + }; + + } +}; + +/** + * @fileoverview Enforces or disallows inline comments. + * @author Greg Cochard + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noInlineComments = { + meta: { + type: "suggestion", + + docs: { + description: "disallow inline comments after code", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-inline-comments" + }, + + schema: [ + { + type: "object", + properties: { + ignorePattern: { + type: "string" + } + }, + additionalProperties: false + } + ], + + messages: { + unexpectedInlineComment: "Unexpected comment inline with code." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const options = context.options[0]; + let customIgnoreRegExp; + + if (options && options.ignorePattern) { + customIgnoreRegExp = new RegExp(options.ignorePattern, "u"); + } + + /** + * Will check that comments are not on lines starting with or ending with code + * @param {ASTNode} node The comment node to check + * @private + * @returns {void} + */ + function testCodeAroundComment(node) { + + const startLine = String(sourceCode.lines[node.loc.start.line - 1]), + endLine = String(sourceCode.lines[node.loc.end.line - 1]), + preamble = startLine.slice(0, node.loc.start.column).trim(), + postamble = endLine.slice(node.loc.end.column).trim(), + isPreambleEmpty = !preamble, + isPostambleEmpty = !postamble; + + // Nothing on both sides + if (isPreambleEmpty && isPostambleEmpty) { + return; + } + + // Matches the ignore pattern + if (customIgnoreRegExp && customIgnoreRegExp.test(node.value)) { + return; + } + + // JSX Exception + if ( + (isPreambleEmpty || preamble === "{") && + (isPostambleEmpty || postamble === "}") + ) { + const enclosingNode = sourceCode.getNodeByRangeIndex(node.range[0]); + + if (enclosingNode && enclosingNode.type === "JSXEmptyExpression") { + return; + } + } + + // Don't report ESLint directive comments + if (astUtils.isDirectiveComment(node)) { + return; + } + + context.report({ + node, + messageId: "unexpectedInlineComment" + }); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + Program() { + sourceCode.getAllComments() + .filter(token => token.type !== "Shebang") + .forEach(testCodeAroundComment); + } + }; + } +}; + +/** + * @fileoverview Rule to enforce declarations in program or function body root. + * @author Brandon Mills + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const validParent = new Set(["Program", "ExportNamedDeclaration", "ExportDefaultDeclaration"]); +const validBlockStatementParent = new Set(["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"]); + +var noInnerDeclarations = { + meta: { + type: "problem", + + docs: { + description: "disallow variable or `function` declarations in nested blocks", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-inner-declarations" + }, + + schema: [ + { + enum: ["functions", "both"] + } + ], + + messages: { + moveDeclToRoot: "Move {{type}} declaration to {{body}} root." + } + }, + + create(context) { + + /** + * Ensure that a given node is at a program or function body's root. + * @param {ASTNode} node Declaration node to check. + * @returns {void} + */ + function check(node) { + const parent = node.parent; + + if ( + parent.type === "BlockStatement" && validBlockStatementParent.has(parent.parent.type) + ) { + return; + } + + if (validParent.has(parent.type)) { + return; + } + + const upperFunction = astUtils.getUpperFunction(parent); + + context.report({ + node, + messageId: "moveDeclToRoot", + data: { + type: (node.type === "FunctionDeclaration" ? "function" : "variable"), + body: (upperFunction === null ? "program" : "function body") + } + }); + } + + + return { + + FunctionDeclaration: check, + VariableDeclaration(node) { + if (context.options[0] === "both" && node.kind === "var") { + check(node); + } + } + + }; + + } +}; + +/** + * @fileoverview Validate strings passed to the RegExp constructor + * @author Michael Ficarra + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const RegExpValidator = regexpp__default['default'].RegExpValidator; +const validator = new RegExpValidator(); +const validFlags = /[gimuys]/gu; +const undefined1 = void 0; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noInvalidRegexp = { + meta: { + type: "problem", + + docs: { + description: "disallow invalid regular expression strings in `RegExp` constructors", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-invalid-regexp" + }, + + schema: [{ + type: "object", + properties: { + allowConstructorFlags: { + type: "array", + items: { + type: "string" + } + } + }, + additionalProperties: false + }], + + messages: { + regexMessage: "{{message}}." + } + }, + + create(context) { + + const options = context.options[0]; + let allowedFlags = null; + + if (options && options.allowConstructorFlags) { + const temp = options.allowConstructorFlags.join("").replace(validFlags, ""); + + if (temp) { + allowedFlags = new RegExp(`[${temp}]`, "giu"); + } + } + + /** + * Check if node is a string + * @param {ASTNode} node node to evaluate + * @returns {boolean} True if its a string + * @private + */ + function isString(node) { + return node && node.type === "Literal" && typeof node.value === "string"; + } + + /** + * Gets flags of a regular expression created by the given `RegExp()` or `new RegExp()` call + * Examples: + * new RegExp(".") // => "" + * new RegExp(".", "gu") // => "gu" + * new RegExp(".", flags) // => null + * @param {ASTNode} node `CallExpression` or `NewExpression` node + * @returns {string|null} flags if they can be determined, `null` otherwise + * @private + */ + function getFlags(node) { + if (node.arguments.length < 2) { + return ""; + } + + if (isString(node.arguments[1])) { + return node.arguments[1].value; + } + + return null; + } + + /** + * Check syntax error in a given pattern. + * @param {string} pattern The RegExp pattern to validate. + * @param {boolean} uFlag The Unicode flag. + * @returns {string|null} The syntax error. + */ + function validateRegExpPattern(pattern, uFlag) { + try { + validator.validatePattern(pattern, undefined1, undefined1, uFlag); + return null; + } catch (err) { + return err.message; + } + } + + /** + * Check syntax error in a given flags. + * @param {string} flags The RegExp flags to validate. + * @returns {string|null} The syntax error. + */ + function validateRegExpFlags(flags) { + try { + validator.validateFlags(flags); + return null; + } catch { + return `Invalid flags supplied to RegExp constructor '${flags}'`; + } + } + + return { + "CallExpression, NewExpression"(node) { + if (node.callee.type !== "Identifier" || node.callee.name !== "RegExp" || !isString(node.arguments[0])) { + return; + } + const pattern = node.arguments[0].value; + let flags = getFlags(node); + + if (flags && allowedFlags) { + flags = flags.replace(allowedFlags, ""); + } + + const message = + ( + flags && validateRegExpFlags(flags) + ) || + ( + + // If flags are unknown, report the regex only if its pattern is invalid both with and without the "u" flag + flags === null + ? validateRegExpPattern(pattern, true) && validateRegExpPattern(pattern, false) + : validateRegExpPattern(pattern, flags.includes("u")) + ); + + if (message) { + context.report({ + node, + messageId: "regexMessage", + data: { message } + }); + } + } + }; + } +}; + +/** + * @fileoverview A rule to disallow `this` keywords outside of classes or class-like objects. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noInvalidThis = { + meta: { + type: "suggestion", + + docs: { + description: "disallow `this` keywords outside of classes or class-like objects", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-invalid-this" + }, + + schema: [ + { + type: "object", + properties: { + capIsConstructor: { + type: "boolean", + default: true + } + }, + additionalProperties: false + } + ], + + messages: { + unexpectedThis: "Unexpected 'this'." + } + }, + + create(context) { + const options = context.options[0] || {}; + const capIsConstructor = options.capIsConstructor !== false; + const stack = [], + sourceCode = context.getSourceCode(); + + /** + * Gets the current checking context. + * + * The return value has a flag that whether or not `this` keyword is valid. + * The flag is initialized when got at the first time. + * @returns {{valid: boolean}} + * an object which has a flag that whether or not `this` keyword is valid. + */ + stack.getCurrent = function() { + const current = this[this.length - 1]; + + if (!current.init) { + current.init = true; + current.valid = !astUtils.isDefaultThisBinding( + current.node, + sourceCode, + { capIsConstructor } + ); + } + return current; + }; + + /** + * Pushs new checking context into the stack. + * + * The checking context is not initialized yet. + * Because most functions don't have `this` keyword. + * When `this` keyword was found, the checking context is initialized. + * @param {ASTNode} node A function node that was entered. + * @returns {void} + */ + function enterFunction(node) { + + // `this` can be invalid only under strict mode. + stack.push({ + init: !context.getScope().isStrict, + node, + valid: true + }); + } + + /** + * Pops the current checking context from the stack. + * @returns {void} + */ + function exitFunction() { + stack.pop(); + } + + return { + + /* + * `this` is invalid only under strict mode. + * Modules is always strict mode. + */ + Program(node) { + const scope = context.getScope(), + features = context.parserOptions.ecmaFeatures || {}; + + stack.push({ + init: true, + node, + valid: !( + scope.isStrict || + node.sourceType === "module" || + (features.globalReturn && scope.childScopes[0].isStrict) + ) + }); + }, + + "Program:exit"() { + stack.pop(); + }, + + FunctionDeclaration: enterFunction, + "FunctionDeclaration:exit": exitFunction, + FunctionExpression: enterFunction, + "FunctionExpression:exit": exitFunction, + + // Reports if `this` of the current context is invalid. + ThisExpression(node) { + const current = stack.getCurrent(); + + if (current && !current.valid) { + context.report({ + node, + messageId: "unexpectedThis" + }); + } + } + }; + } +}; + +/** + * @fileoverview Rule to disallow whitespace that is not a tab or space, whitespace inside strings and comments are allowed + * @author Jonathan Kingston + * @author Christophe Porteneuve + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Constants +//------------------------------------------------------------------------------ + +const ALL_IRREGULARS = /[\f\v\u0085\ufeff\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000\u2028\u2029]/u; +const IRREGULAR_WHITESPACE = /[\f\v\u0085\ufeff\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000]+/mgu; +const IRREGULAR_LINE_TERMINATORS = /[\u2028\u2029]/mgu; +const LINE_BREAK = astUtils.createGlobalLinebreakMatcher(); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noIrregularWhitespace = { + meta: { + type: "problem", + + docs: { + description: "disallow irregular whitespace", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-irregular-whitespace" + }, + + schema: [ + { + type: "object", + properties: { + skipComments: { + type: "boolean", + default: false + }, + skipStrings: { + type: "boolean", + default: true + }, + skipTemplates: { + type: "boolean", + default: false + }, + skipRegExps: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + messages: { + noIrregularWhitespace: "Irregular whitespace not allowed." + } + }, + + create(context) { + + // Module store of errors that we have found + let errors = []; + + // Lookup the `skipComments` option, which defaults to `false`. + const options = context.options[0] || {}; + const skipComments = !!options.skipComments; + const skipStrings = options.skipStrings !== false; + const skipRegExps = !!options.skipRegExps; + const skipTemplates = !!options.skipTemplates; + + const sourceCode = context.getSourceCode(); + const commentNodes = sourceCode.getAllComments(); + + /** + * Removes errors that occur inside the given node + * @param {ASTNode} node to check for matching errors. + * @returns {void} + * @private + */ + function removeWhitespaceError(node) { + const locStart = node.loc.start; + const locEnd = node.loc.end; + + errors = errors.filter(({ loc: { start: errorLocStart } }) => ( + errorLocStart.line < locStart.line || + errorLocStart.line === locStart.line && errorLocStart.column < locStart.column || + errorLocStart.line === locEnd.line && errorLocStart.column >= locEnd.column || + errorLocStart.line > locEnd.line + )); + } + + /** + * Checks identifier or literal nodes for errors that we are choosing to ignore and calls the relevant methods to remove the errors + * @param {ASTNode} node to check for matching errors. + * @returns {void} + * @private + */ + function removeInvalidNodeErrorsInIdentifierOrLiteral(node) { + const shouldCheckStrings = skipStrings && (typeof node.value === "string"); + const shouldCheckRegExps = skipRegExps && Boolean(node.regex); + + if (shouldCheckStrings || shouldCheckRegExps) { + + // If we have irregular characters remove them from the errors list + if (ALL_IRREGULARS.test(node.raw)) { + removeWhitespaceError(node); + } + } + } + + /** + * Checks template string literal nodes for errors that we are choosing to ignore and calls the relevant methods to remove the errors + * @param {ASTNode} node to check for matching errors. + * @returns {void} + * @private + */ + function removeInvalidNodeErrorsInTemplateLiteral(node) { + if (typeof node.value.raw === "string") { + if (ALL_IRREGULARS.test(node.value.raw)) { + removeWhitespaceError(node); + } + } + } + + /** + * Checks comment nodes for errors that we are choosing to ignore and calls the relevant methods to remove the errors + * @param {ASTNode} node to check for matching errors. + * @returns {void} + * @private + */ + function removeInvalidNodeErrorsInComment(node) { + if (ALL_IRREGULARS.test(node.value)) { + removeWhitespaceError(node); + } + } + + /** + * Checks the program source for irregular whitespace + * @param {ASTNode} node The program node + * @returns {void} + * @private + */ + function checkForIrregularWhitespace(node) { + const sourceLines = sourceCode.lines; + + sourceLines.forEach((sourceLine, lineIndex) => { + const lineNumber = lineIndex + 1; + let match; + + while ((match = IRREGULAR_WHITESPACE.exec(sourceLine)) !== null) { + errors.push({ + node, + messageId: "noIrregularWhitespace", + loc: { + start: { + line: lineNumber, + column: match.index + }, + end: { + line: lineNumber, + column: match.index + match[0].length + } + } + }); + } + }); + } + + /** + * Checks the program source for irregular line terminators + * @param {ASTNode} node The program node + * @returns {void} + * @private + */ + function checkForIrregularLineTerminators(node) { + const source = sourceCode.getText(), + sourceLines = sourceCode.lines, + linebreaks = source.match(LINE_BREAK); + let lastLineIndex = -1, + match; + + while ((match = IRREGULAR_LINE_TERMINATORS.exec(source)) !== null) { + const lineIndex = linebreaks.indexOf(match[0], lastLineIndex + 1) || 0; + + errors.push({ + node, + messageId: "noIrregularWhitespace", + loc: { + start: { + line: lineIndex + 1, + column: sourceLines[lineIndex].length + }, + end: { + line: lineIndex + 2, + column: 0 + } + } + }); + + lastLineIndex = lineIndex; + } + } + + /** + * A no-op function to act as placeholder for comment accumulation when the `skipComments` option is `false`. + * @returns {void} + * @private + */ + function noop() {} + + const nodes = {}; + + if (ALL_IRREGULARS.test(sourceCode.getText())) { + nodes.Program = function(node) { + + /* + * As we can easily fire warnings for all white space issues with + * all the source its simpler to fire them here. + * This means we can check all the application code without having + * to worry about issues caused in the parser tokens. + * When writing this code also evaluating per node was missing out + * connecting tokens in some cases. + * We can later filter the errors when they are found to be not an + * issue in nodes we don't care about. + */ + checkForIrregularWhitespace(node); + checkForIrregularLineTerminators(node); + }; + + nodes.Identifier = removeInvalidNodeErrorsInIdentifierOrLiteral; + nodes.Literal = removeInvalidNodeErrorsInIdentifierOrLiteral; + nodes.TemplateElement = skipTemplates ? removeInvalidNodeErrorsInTemplateLiteral : noop; + nodes["Program:exit"] = function() { + if (skipComments) { + + // First strip errors occurring in comment nodes. + commentNodes.forEach(removeInvalidNodeErrorsInComment); + } + + // If we have any errors remaining report on them + errors.forEach(error => context.report(error)); + }; + } else { + nodes.Program = noop; + } + + return nodes; + } +}; + +/** + * @fileoverview Rule to flag usage of __iterator__ property + * @author Ian Christian Myers + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const { getStaticPropertyName: getStaticPropertyName$1 } = astUtils; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noIterator = { + meta: { + type: "suggestion", + + docs: { + description: "disallow the use of the `__iterator__` property", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-iterator" + }, + + schema: [], + + messages: { + noIterator: "Reserved name '__iterator__'." + } + }, + + create(context) { + + return { + + MemberExpression(node) { + + if (getStaticPropertyName$1(node) === "__iterator__") { + context.report({ + node, + messageId: "noIterator" + }); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag labels that are the same as an identifier + * @author Ian Christian Myers + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noLabelVar = { + meta: { + type: "suggestion", + + docs: { + description: "disallow labels that share a name with a variable", + category: "Variables", + recommended: false, + url: "https://eslint.org/docs/rules/no-label-var" + }, + + schema: [], + + messages: { + identifierClashWithLabel: "Found identifier with same name as label." + } + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Check if the identifier is present inside current scope + * @param {Object} scope current scope + * @param {string} name To evaluate + * @returns {boolean} True if its present + * @private + */ + function findIdentifier(scope, name) { + return astUtils.getVariableByName(scope, name) !== null; + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + + LabeledStatement(node) { + + // Fetch the innermost scope. + const scope = context.getScope(); + + /* + * Recursively find the identifier walking up the scope, starting + * with the innermost scope. + */ + if (findIdentifier(scope, node.label.name)) { + context.report({ + node, + messageId: "identifierClashWithLabel" + }); + } + } + + }; + + } +}; + +/** + * @fileoverview Disallow Labeled Statements + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noLabels = { + meta: { + type: "suggestion", + + docs: { + description: "disallow labeled statements", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-labels" + }, + + schema: [ + { + type: "object", + properties: { + allowLoop: { + type: "boolean", + default: false + }, + allowSwitch: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + messages: { + unexpectedLabel: "Unexpected labeled statement.", + unexpectedLabelInBreak: "Unexpected label in break statement.", + unexpectedLabelInContinue: "Unexpected label in continue statement." + } + }, + + create(context) { + const options = context.options[0]; + const allowLoop = options && options.allowLoop; + const allowSwitch = options && options.allowSwitch; + let scopeInfo = null; + + /** + * Gets the kind of a given node. + * @param {ASTNode} node A node to get. + * @returns {string} The kind of the node. + */ + function getBodyKind(node) { + if (astUtils.isLoop(node)) { + return "loop"; + } + if (node.type === "SwitchStatement") { + return "switch"; + } + return "other"; + } + + /** + * Checks whether the label of a given kind is allowed or not. + * @param {string} kind A kind to check. + * @returns {boolean} `true` if the kind is allowed. + */ + function isAllowed(kind) { + switch (kind) { + case "loop": return allowLoop; + case "switch": return allowSwitch; + default: return false; + } + } + + /** + * Checks whether a given name is a label of a loop or not. + * @param {string} label A name of a label to check. + * @returns {boolean} `true` if the name is a label of a loop. + */ + function getKind(label) { + let info = scopeInfo; + + while (info) { + if (info.label === label) { + return info.kind; + } + info = info.upper; + } + + /* istanbul ignore next: syntax error */ + return "other"; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + LabeledStatement(node) { + scopeInfo = { + label: node.label.name, + kind: getBodyKind(node.body), + upper: scopeInfo + }; + }, + + "LabeledStatement:exit"(node) { + if (!isAllowed(scopeInfo.kind)) { + context.report({ + node, + messageId: "unexpectedLabel" + }); + } + + scopeInfo = scopeInfo.upper; + }, + + BreakStatement(node) { + if (node.label && !isAllowed(getKind(node.label.name))) { + context.report({ + node, + messageId: "unexpectedLabelInBreak" + }); + } + }, + + ContinueStatement(node) { + if (node.label && !isAllowed(getKind(node.label.name))) { + context.report({ + node, + messageId: "unexpectedLabelInContinue" + }); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag blocks with no reason to exist + * @author Brandon Mills + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noLoneBlocks = { + meta: { + type: "suggestion", + + docs: { + description: "disallow unnecessary nested blocks", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-lone-blocks" + }, + + schema: [], + + messages: { + redundantBlock: "Block is redundant.", + redundantNestedBlock: "Nested block is redundant." + } + }, + + create(context) { + + // A stack of lone blocks to be checked for block-level bindings + const loneBlocks = []; + let ruleDef; + + /** + * Reports a node as invalid. + * @param {ASTNode} node The node to be reported. + * @returns {void} + */ + function report(node) { + const messageId = node.parent.type === "BlockStatement" ? "redundantNestedBlock" : "redundantBlock"; + + context.report({ + node, + messageId + }); + } + + /** + * Checks for any occurrence of a BlockStatement in a place where lists of statements can appear + * @param {ASTNode} node The node to check + * @returns {boolean} True if the node is a lone block. + */ + function isLoneBlock(node) { + return node.parent.type === "BlockStatement" || + node.parent.type === "Program" || + + // Don't report blocks in switch cases if the block is the only statement of the case. + node.parent.type === "SwitchCase" && !(node.parent.consequent[0] === node && node.parent.consequent.length === 1); + } + + /** + * Checks the enclosing block of the current node for block-level bindings, + * and "marks it" as valid if any. + * @returns {void} + */ + function markLoneBlock() { + if (loneBlocks.length === 0) { + return; + } + + const block = context.getAncestors().pop(); + + if (loneBlocks[loneBlocks.length - 1] === block) { + loneBlocks.pop(); + } + } + + // Default rule definition: report all lone blocks + ruleDef = { + BlockStatement(node) { + if (isLoneBlock(node)) { + report(node); + } + } + }; + + // ES6: report blocks without block-level bindings, or that's only child of another block + if (context.parserOptions.ecmaVersion >= 6) { + ruleDef = { + BlockStatement(node) { + if (isLoneBlock(node)) { + loneBlocks.push(node); + } + }, + "BlockStatement:exit"(node) { + if (loneBlocks.length > 0 && loneBlocks[loneBlocks.length - 1] === node) { + loneBlocks.pop(); + report(node); + } else if ( + node.parent.type === "BlockStatement" && + node.parent.body.length === 1 + ) { + report(node); + } + } + }; + + ruleDef.VariableDeclaration = function(node) { + if (node.kind === "let" || node.kind === "const") { + markLoneBlock(); + } + }; + + ruleDef.FunctionDeclaration = function() { + if (context.getScope().isStrict) { + markLoneBlock(); + } + }; + + ruleDef.ClassDeclaration = markLoneBlock; + } + + return ruleDef; + } +}; + +/** + * @fileoverview Rule to disallow if as the only statement in an else block + * @author Brandon Mills + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noLonelyIf = { + meta: { + type: "suggestion", + + docs: { + description: "disallow `if` statements as the only statement in `else` blocks", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-lonely-if" + }, + + schema: [], + fixable: "code", + + messages: { + unexpectedLonelyIf: "Unexpected if as the only statement in an else block." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + IfStatement(node) { + const ancestors = context.getAncestors(), + parent = ancestors.pop(), + grandparent = ancestors.pop(); + + if (parent && parent.type === "BlockStatement" && + parent.body.length === 1 && grandparent && + grandparent.type === "IfStatement" && + parent === grandparent.alternate) { + context.report({ + node, + messageId: "unexpectedLonelyIf", + fix(fixer) { + const openingElseCurly = sourceCode.getFirstToken(parent); + const closingElseCurly = sourceCode.getLastToken(parent); + const elseKeyword = sourceCode.getTokenBefore(openingElseCurly); + const tokenAfterElseBlock = sourceCode.getTokenAfter(closingElseCurly); + const lastIfToken = sourceCode.getLastToken(node.consequent); + const sourceText = sourceCode.getText(); + + if (sourceText.slice(openingElseCurly.range[1], + node.range[0]).trim() || sourceText.slice(node.range[1], closingElseCurly.range[0]).trim()) { + + // Don't fix if there are any non-whitespace characters interfering (e.g. comments) + return null; + } + + if ( + node.consequent.type !== "BlockStatement" && lastIfToken.value !== ";" && tokenAfterElseBlock && + ( + node.consequent.loc.end.line === tokenAfterElseBlock.loc.start.line || + /^[([/+`-]/u.test(tokenAfterElseBlock.value) || + lastIfToken.value === "++" || + lastIfToken.value === "--" + ) + ) { + + /* + * If the `if` statement has no block, and is not followed by a semicolon, make sure that fixing + * the issue would not change semantics due to ASI. If this would happen, don't do a fix. + */ + return null; + } + + return fixer.replaceTextRange( + [openingElseCurly.range[0], closingElseCurly.range[1]], + (elseKeyword.range[1] === openingElseCurly.range[0] ? " " : "") + sourceCode.getText(node) + ); + } + }); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag creation of function inside a loop + * @author Ilya Volodin + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Gets the containing loop node of a specified node. + * + * We don't need to check nested functions, so this ignores those. + * `Scope.through` contains references of nested functions. + * @param {ASTNode} node An AST node to get. + * @returns {ASTNode|null} The containing loop node of the specified node, or + * `null`. + */ +function getContainingLoopNode(node) { + for (let currentNode = node; currentNode.parent; currentNode = currentNode.parent) { + const parent = currentNode.parent; + + switch (parent.type) { + case "WhileStatement": + case "DoWhileStatement": + return parent; + + case "ForStatement": + + // `init` is outside of the loop. + if (parent.init !== currentNode) { + return parent; + } + break; + + case "ForInStatement": + case "ForOfStatement": + + // `right` is outside of the loop. + if (parent.right !== currentNode) { + return parent; + } + break; + + case "ArrowFunctionExpression": + case "FunctionExpression": + case "FunctionDeclaration": + + // We don't need to check nested functions. + return null; + } + } + + return null; +} + +/** + * Gets the containing loop node of a given node. + * If the loop was nested, this returns the most outer loop. + * @param {ASTNode} node A node to get. This is a loop node. + * @param {ASTNode|null} excludedNode A node that the result node should not + * include. + * @returns {ASTNode} The most outer loop node. + */ +function getTopLoopNode(node, excludedNode) { + const border = excludedNode ? excludedNode.range[1] : 0; + let retv = node; + let containingLoopNode = node; + + while (containingLoopNode && containingLoopNode.range[0] >= border) { + retv = containingLoopNode; + containingLoopNode = getContainingLoopNode(containingLoopNode); + } + + return retv; +} + +/** + * Checks whether a given reference which refers to an upper scope's variable is + * safe or not. + * @param {ASTNode} loopNode A containing loop node. + * @param {eslint-scope.Reference} reference A reference to check. + * @returns {boolean} `true` if the reference is safe or not. + */ +function isSafe(loopNode, reference) { + const variable = reference.resolved; + const definition = variable && variable.defs[0]; + const declaration = definition && definition.parent; + const kind = (declaration && declaration.type === "VariableDeclaration") + ? declaration.kind + : ""; + + // Variables which are declared by `const` is safe. + if (kind === "const") { + return true; + } + + /* + * Variables which are declared by `let` in the loop is safe. + * It's a different instance from the next loop step's. + */ + if (kind === "let" && + declaration.range[0] > loopNode.range[0] && + declaration.range[1] < loopNode.range[1] + ) { + return true; + } + + /* + * WriteReferences which exist after this border are unsafe because those + * can modify the variable. + */ + const border = getTopLoopNode( + loopNode, + (kind === "let") ? declaration : null + ).range[0]; + + /** + * Checks whether a given reference is safe or not. + * The reference is every reference of the upper scope's variable we are + * looking now. + * + * It's safeafe if the reference matches one of the following condition. + * - is readonly. + * - doesn't exist inside a local function and after the border. + * @param {eslint-scope.Reference} upperRef A reference to check. + * @returns {boolean} `true` if the reference is safe. + */ + function isSafeReference(upperRef) { + const id = upperRef.identifier; + + return ( + !upperRef.isWrite() || + variable.scope.variableScope === upperRef.from.variableScope && + id.range[0] < border + ); + } + + return Boolean(variable) && variable.references.every(isSafeReference); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noLoopFunc = { + meta: { + type: "suggestion", + + docs: { + description: "disallow function declarations that contain unsafe references inside loop statements", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-loop-func" + }, + + schema: [], + + messages: { + unsafeRefs: "Function declared in a loop contains unsafe references to variable(s) {{ varNames }}." + } + }, + + create(context) { + + /** + * Reports functions which match the following condition: + * + * - has a loop node in ancestors. + * - has any references which refers to an unsafe variable. + * @param {ASTNode} node The AST node to check. + * @returns {boolean} Whether or not the node is within a loop. + */ + function checkForLoops(node) { + const loopNode = getContainingLoopNode(node); + + if (!loopNode) { + return; + } + + const references = context.getScope().through; + const unsafeRefs = references.filter(r => !isSafe(loopNode, r)).map(r => r.identifier.name); + + if (unsafeRefs.length > 0) { + context.report({ + node, + messageId: "unsafeRefs", + data: { varNames: `'${unsafeRefs.join("', '")}'` } + }); + } + } + + return { + ArrowFunctionExpression: checkForLoops, + FunctionExpression: checkForLoops, + FunctionDeclaration: checkForLoops + }; + } +}; + +/** + * @fileoverview Rule to flag numbers that will lose significant figure precision at runtime + * @author Jacob Moore + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noLossOfPrecision = { + meta: { + type: "problem", + + docs: { + description: "disallow literal numbers that lose precision", + category: "Possible Errors", + recommended: false, + url: "https://eslint.org/docs/rules/no-loss-of-precision" + }, + schema: [], + messages: { + noLossOfPrecision: "This number literal will lose precision at runtime." + } + }, + + create(context) { + + /** + * Returns whether the node is number literal + * @param {Node} node the node literal being evaluated + * @returns {boolean} true if the node is a number literal + */ + function isNumber(node) { + return typeof node.value === "number"; + } + + /** + * Gets the source code of the given number literal. Removes `_` numeric separators from the result. + * @param {Node} node the number `Literal` node + * @returns {string} raw source code of the literal, without numeric separators + */ + function getRaw(node) { + return node.raw.replace(/_/gu, ""); + } + + /** + * Checks whether the number is base ten + * @param {ASTNode} node the node being evaluated + * @returns {boolean} true if the node is in base ten + */ + function isBaseTen(node) { + const prefixes = ["0x", "0X", "0b", "0B", "0o", "0O"]; + + return prefixes.every(prefix => !node.raw.startsWith(prefix)) && + !/^0[0-7]+$/u.test(node.raw); + } + + /** + * Checks that the user-intended non-base ten number equals the actual number after is has been converted to the Number type + * @param {Node} node the node being evaluated + * @returns {boolean} true if they do not match + */ + function notBaseTenLosesPrecision(node) { + const rawString = getRaw(node).toUpperCase(); + let base = 0; + + if (rawString.startsWith("0B")) { + base = 2; + } else if (rawString.startsWith("0X")) { + base = 16; + } else { + base = 8; + } + + return !rawString.endsWith(node.value.toString(base).toUpperCase()); + } + + /** + * Adds a decimal point to the numeric string at index 1 + * @param {string} stringNumber the numeric string without any decimal point + * @returns {string} the numeric string with a decimal point in the proper place + */ + function addDecimalPointToNumber(stringNumber) { + return `${stringNumber.slice(0, 1)}.${stringNumber.slice(1)}`; + } + + /** + * Returns the number stripped of leading zeros + * @param {string} numberAsString the string representation of the number + * @returns {string} the stripped string + */ + function removeLeadingZeros(numberAsString) { + return numberAsString.replace(/^0*/u, ""); + } + + /** + * Returns the number stripped of trailing zeros + * @param {string} numberAsString the string representation of the number + * @returns {string} the stripped string + */ + function removeTrailingZeros(numberAsString) { + return numberAsString.replace(/0*$/u, ""); + } + + /** + * Converts an integer to to an object containing the integer's coefficient and order of magnitude + * @param {string} stringInteger the string representation of the integer being converted + * @returns {Object} the object containing the integer's coefficient and order of magnitude + */ + function normalizeInteger(stringInteger) { + const significantDigits = removeTrailingZeros(removeLeadingZeros(stringInteger)); + + return { + magnitude: stringInteger.startsWith("0") ? stringInteger.length - 2 : stringInteger.length - 1, + coefficient: addDecimalPointToNumber(significantDigits) + }; + } + + /** + * + * Converts a float to to an object containing the floats's coefficient and order of magnitude + * @param {string} stringFloat the string representation of the float being converted + * @returns {Object} the object containing the integer's coefficient and order of magnitude + */ + function normalizeFloat(stringFloat) { + const trimmedFloat = removeLeadingZeros(stringFloat); + + if (trimmedFloat.startsWith(".")) { + const decimalDigits = trimmedFloat.split(".").pop(); + const significantDigits = removeLeadingZeros(decimalDigits); + + return { + magnitude: significantDigits.length - decimalDigits.length - 1, + coefficient: addDecimalPointToNumber(significantDigits) + }; + + } + return { + magnitude: trimmedFloat.indexOf(".") - 1, + coefficient: addDecimalPointToNumber(trimmedFloat.replace(".", "")) + + }; + } + + + /** + * Converts a base ten number to proper scientific notation + * @param {string} stringNumber the string representation of the base ten number to be converted + * @returns {string} the number converted to scientific notation + */ + function convertNumberToScientificNotation(stringNumber) { + const splitNumber = stringNumber.replace("E", "e").split("e"); + const originalCoefficient = splitNumber[0]; + const normalizedNumber = stringNumber.includes(".") ? normalizeFloat(originalCoefficient) + : normalizeInteger(originalCoefficient); + const normalizedCoefficient = normalizedNumber.coefficient; + const magnitude = splitNumber.length > 1 ? (parseInt(splitNumber[1], 10) + normalizedNumber.magnitude) + : normalizedNumber.magnitude; + + return `${normalizedCoefficient}e${magnitude}`; + + } + + /** + * Checks that the user-intended base ten number equals the actual number after is has been converted to the Number type + * @param {Node} node the node being evaluated + * @returns {boolean} true if they do not match + */ + function baseTenLosesPrecision(node) { + const normalizedRawNumber = convertNumberToScientificNotation(getRaw(node)); + const requestedPrecision = normalizedRawNumber.split("e")[0].replace(".", "").length; + + if (requestedPrecision > 100) { + return true; + } + const storedNumber = node.value.toPrecision(requestedPrecision); + const normalizedStoredNumber = convertNumberToScientificNotation(storedNumber); + + return normalizedRawNumber !== normalizedStoredNumber; + } + + + /** + * Checks that the user-intended number equals the actual number after is has been converted to the Number type + * @param {Node} node the node being evaluated + * @returns {boolean} true if they do not match + */ + function losesPrecision(node) { + return isBaseTen(node) ? baseTenLosesPrecision(node) : notBaseTenLosesPrecision(node); + } + + + return { + Literal(node) { + if (node.value && isNumber(node) && losesPrecision(node)) { + context.report({ + messageId: "noLossOfPrecision", + node + }); + } + } + }; + } +}; + +/** + * @fileoverview Rule to flag statements that use magic numbers (adapted from https://github.com/danielstjules/buddy.js) + * @author Vincent Lemeunier + */ + + + +// Maximum array length by the ECMAScript Specification. +const MAX_ARRAY_LENGTH = 2 ** 32 - 1; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +/** + * Convert the value to bigint if it's a string. Otherwise return the value as-is. + * @param {bigint|number|string} x The value to normalize. + * @returns {bigint|number} The normalized value. + */ +function normalizeIgnoreValue(x) { + if (typeof x === "string") { + return BigInt(x.slice(0, -1)); + } + return x; +} + +var noMagicNumbers = { + meta: { + type: "suggestion", + + docs: { + description: "disallow magic numbers", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-magic-numbers" + }, + + schema: [{ + type: "object", + properties: { + detectObjects: { + type: "boolean", + default: false + }, + enforceConst: { + type: "boolean", + default: false + }, + ignore: { + type: "array", + items: { + anyOf: [ + { type: "number" }, + { type: "string", pattern: "^[+-]?(?:0|[1-9][0-9]*)n$" } + ] + }, + uniqueItems: true + }, + ignoreArrayIndexes: { + type: "boolean", + default: false + }, + ignoreDefaultValues: { + type: "boolean", + default: false + } + }, + additionalProperties: false + }], + + messages: { + useConst: "Number constants declarations must use 'const'.", + noMagic: "No magic number: {{raw}}." + } + }, + + create(context) { + const config = context.options[0] || {}, + detectObjects = !!config.detectObjects, + enforceConst = !!config.enforceConst, + ignore = (config.ignore || []).map(normalizeIgnoreValue), + ignoreArrayIndexes = !!config.ignoreArrayIndexes, + ignoreDefaultValues = !!config.ignoreDefaultValues; + + const okTypes = detectObjects ? [] : ["ObjectExpression", "Property", "AssignmentExpression"]; + + /** + * Returns whether the rule is configured to ignore the given value + * @param {bigint|number} value The value to check + * @returns {boolean} true if the value is ignored + */ + function isIgnoredValue(value) { + return ignore.indexOf(value) !== -1; + } + + /** + * Returns whether the number is a default value assignment. + * @param {ASTNode} fullNumberNode `Literal` or `UnaryExpression` full number node + * @returns {boolean} true if the number is a default value + */ + function isDefaultValue(fullNumberNode) { + const parent = fullNumberNode.parent; + + return parent.type === "AssignmentPattern" && parent.right === fullNumberNode; + } + + /** + * Returns whether the given node is used as a radix within parseInt() or Number.parseInt() + * @param {ASTNode} fullNumberNode `Literal` or `UnaryExpression` full number node + * @returns {boolean} true if the node is radix + */ + function isParseIntRadix(fullNumberNode) { + const parent = fullNumberNode.parent; + + return parent.type === "CallExpression" && fullNumberNode === parent.arguments[1] && + ( + astUtils.isSpecificId(parent.callee, "parseInt") || + astUtils.isSpecificMemberAccess(parent.callee, "Number", "parseInt") + ); + } + + /** + * Returns whether the given node is a direct child of a JSX node. + * In particular, it aims to detect numbers used as prop values in JSX tags. + * Example: + * @param {ASTNode} fullNumberNode `Literal` or `UnaryExpression` full number node + * @returns {boolean} true if the node is a JSX number + */ + function isJSXNumber(fullNumberNode) { + return fullNumberNode.parent.type.indexOf("JSX") === 0; + } + + /** + * Returns whether the given node is used as an array index. + * Value must coerce to a valid array index name: "0", "1", "2" ... "4294967294". + * + * All other values, like "-1", "2.5", or "4294967295", are just "normal" object properties, + * which can be created and accessed on an array in addition to the array index properties, + * but they don't affect array's length and are not considered by methods such as .map(), .forEach() etc. + * + * The maximum array length by the specification is 2 ** 32 - 1 = 4294967295, + * thus the maximum valid index is 2 ** 32 - 2 = 4294967294. + * + * All notations are allowed, as long as the value coerces to one of "0", "1", "2" ... "4294967294". + * + * Valid examples: + * a[0], a[1], a[1.2e1], a[0xAB], a[0n], a[1n] + * a[-0] (same as a[0] because -0 coerces to "0") + * a[-0n] (-0n evaluates to 0n) + * + * Invalid examples: + * a[-1], a[-0xAB], a[-1n], a[2.5], a[1.23e1], a[12e-1] + * a[4294967295] (above the max index, it's an access to a regular property a["4294967295"]) + * a[999999999999999999999] (even if it wasn't above the max index, it would be a["1e+21"]) + * a[1e310] (same as a["Infinity"]) + * @param {ASTNode} fullNumberNode `Literal` or `UnaryExpression` full number node + * @param {bigint|number} value Value expressed by the fullNumberNode + * @returns {boolean} true if the node is a valid array index + */ + function isArrayIndex(fullNumberNode, value) { + const parent = fullNumberNode.parent; + + return parent.type === "MemberExpression" && parent.property === fullNumberNode && + (Number.isInteger(value) || typeof value === "bigint") && + value >= 0 && value < MAX_ARRAY_LENGTH; + } + + return { + Literal(node) { + if (!astUtils.isNumericLiteral(node)) { + return; + } + + let fullNumberNode; + let value; + let raw; + + // Treat unary minus as a part of the number + if (node.parent.type === "UnaryExpression" && node.parent.operator === "-") { + fullNumberNode = node.parent; + value = -node.value; + raw = `-${node.raw}`; + } else { + fullNumberNode = node; + value = node.value; + raw = node.raw; + } + + const parent = fullNumberNode.parent; + + // Always allow radix arguments and JSX props + if ( + isIgnoredValue(value) || + (ignoreDefaultValues && isDefaultValue(fullNumberNode)) || + isParseIntRadix(fullNumberNode) || + isJSXNumber(fullNumberNode) || + (ignoreArrayIndexes && isArrayIndex(fullNumberNode, value)) + ) { + return; + } + + if (parent.type === "VariableDeclarator") { + if (enforceConst && parent.parent.kind !== "const") { + context.report({ + node: fullNumberNode, + messageId: "useConst" + }); + } + } else if ( + okTypes.indexOf(parent.type) === -1 || + (parent.type === "AssignmentExpression" && parent.left.type === "Identifier") + ) { + context.report({ + node: fullNumberNode, + messageId: "noMagic", + data: { + raw + } + }); + } + } + }; + } +}; + +/** + * @author Toru Nagashima + */ + +/** + * Check whether a given character is a combining mark or not. + * @param {number} codePoint The character code to check. + * @returns {boolean} `true` if the character belongs to the category, any of `Mc`, `Me`, and `Mn`. + */ +var isCombiningCharacter$1 = function isCombiningCharacter(codePoint) { + return /^[\p{Mc}\p{Me}\p{Mn}]$/u.test(String.fromCodePoint(codePoint)); +}; + +/** + * @author Toru Nagashima + */ + +/** + * Check whether a given character is an emoji modifier. + * @param {number} code The character code to check. + * @returns {boolean} `true` if the character is an emoji modifier. + */ +var isEmojiModifier$1 = function isEmojiModifier(code) { + return code >= 0x1F3FB && code <= 0x1F3FF; +}; + +/** + * @author Toru Nagashima + */ + +/** + * Check whether a given character is a regional indicator symbol. + * @param {number} code The character code to check. + * @returns {boolean} `true` if the character is a regional indicator symbol. + */ +var isRegionalIndicatorSymbol$1 = function isRegionalIndicatorSymbol(code) { + return code >= 0x1F1E6 && code <= 0x1F1FF; +}; + +/** + * @author Toru Nagashima + */ + +/** + * Check whether given two characters are a surrogate pair. + * @param {number} lead The code of the lead character. + * @param {number} tail The code of the tail character. + * @returns {boolean} `true` if the character pair is a surrogate pair. + */ +var isSurrogatePair$1 = function isSurrogatePair(lead, tail) { + return lead >= 0xD800 && lead < 0xDC00 && tail >= 0xDC00 && tail < 0xE000; +}; + +/** + * @author Toru Nagashima + */ + +var unicode = { + isCombiningCharacter: isCombiningCharacter$1, + isEmojiModifier: isEmojiModifier$1, + isRegionalIndicatorSymbol: isRegionalIndicatorSymbol$1, + isSurrogatePair: isSurrogatePair$1 +}; + +/** + * @author Toru Nagashima + */ + +const { CALL: CALL$7, CONSTRUCT: CONSTRUCT$5, ReferenceTracker: ReferenceTracker$7, getStringIfConstant: getStringIfConstant$3 } = require$$0__default$1['default']; +const { RegExpParser: RegExpParser$1, visitRegExpAST: visitRegExpAST$1 } = regexpp__default['default']; +const { isCombiningCharacter, isEmojiModifier, isRegionalIndicatorSymbol, isSurrogatePair } = unicode; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Iterate character sequences of a given nodes. + * + * CharacterClassRange syntax can steal a part of character sequence, + * so this function reverts CharacterClassRange syntax and restore the sequence. + * @param {regexpp.AST.CharacterClassElement[]} nodes The node list to iterate character sequences. + * @returns {IterableIterator} The list of character sequences. + */ +function *iterateCharacterSequence(nodes) { + let seq = []; + + for (const node of nodes) { + switch (node.type) { + case "Character": + seq.push(node.value); + break; + + case "CharacterClassRange": + seq.push(node.min.value); + yield seq; + seq = [node.max.value]; + break; + + case "CharacterSet": + if (seq.length > 0) { + yield seq; + seq = []; + } + break; + + // no default + } + } + + if (seq.length > 0) { + yield seq; + } +} + +const hasCharacterSequence = { + surrogatePairWithoutUFlag(chars) { + return chars.some((c, i) => i !== 0 && isSurrogatePair(chars[i - 1], c)); + }, + + combiningClass(chars) { + return chars.some((c, i) => ( + i !== 0 && + isCombiningCharacter(c) && + !isCombiningCharacter(chars[i - 1]) + )); + }, + + emojiModifier(chars) { + return chars.some((c, i) => ( + i !== 0 && + isEmojiModifier(c) && + !isEmojiModifier(chars[i - 1]) + )); + }, + + regionalIndicatorSymbol(chars) { + return chars.some((c, i) => ( + i !== 0 && + isRegionalIndicatorSymbol(c) && + isRegionalIndicatorSymbol(chars[i - 1]) + )); + }, + + zwj(chars) { + const lastIndex = chars.length - 1; + + return chars.some((c, i) => ( + i !== 0 && + i !== lastIndex && + c === 0x200d && + chars[i - 1] !== 0x200d && + chars[i + 1] !== 0x200d + )); + } +}; + +const kinds = Object.keys(hasCharacterSequence); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noMisleadingCharacterClass = { + meta: { + type: "problem", + + docs: { + description: "disallow characters which are made with multiple code points in character class syntax", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-misleading-character-class" + }, + + schema: [], + + messages: { + surrogatePairWithoutUFlag: "Unexpected surrogate pair in character class. Use 'u' flag.", + combiningClass: "Unexpected combined character in character class.", + emojiModifier: "Unexpected modified Emoji in character class.", + regionalIndicatorSymbol: "Unexpected national flag in character class.", + zwj: "Unexpected joined character sequence in character class." + } + }, + create(context) { + const parser = new RegExpParser$1(); + + /** + * Verify a given regular expression. + * @param {Node} node The node to report. + * @param {string} pattern The regular expression pattern to verify. + * @param {string} flags The flags of the regular expression. + * @returns {void} + */ + function verify(node, pattern, flags) { + const has = { + surrogatePairWithoutUFlag: false, + combiningClass: false, + variationSelector: false, + emojiModifier: false, + regionalIndicatorSymbol: false, + zwj: false + }; + let patternNode; + + try { + patternNode = parser.parsePattern( + pattern, + 0, + pattern.length, + flags.includes("u") + ); + } catch { + + // Ignore regular expressions with syntax errors + return; + } + + visitRegExpAST$1(patternNode, { + onCharacterClassEnter(ccNode) { + for (const chars of iterateCharacterSequence(ccNode.elements)) { + for (const kind of kinds) { + has[kind] = has[kind] || hasCharacterSequence[kind](chars); + } + } + } + }); + + for (const kind of kinds) { + if (has[kind]) { + context.report({ node, messageId: kind }); + } + } + } + + return { + "Literal[regex]"(node) { + verify(node, node.regex.pattern, node.regex.flags); + }, + "Program"() { + const scope = context.getScope(); + const tracker = new ReferenceTracker$7(scope); + + /* + * Iterate calls of RegExp. + * E.g., `new RegExp()`, `RegExp()`, `new window.RegExp()`, + * `const {RegExp: a} = window; new a()`, etc... + */ + for (const { node } of tracker.iterateGlobalReferences({ + RegExp: { [CALL$7]: true, [CONSTRUCT$5]: true } + })) { + const [patternNode, flagsNode] = node.arguments; + const pattern = getStringIfConstant$3(patternNode, scope); + const flags = getStringIfConstant$3(flagsNode, scope); + + if (typeof pattern === "string") { + verify(node, pattern, flags || ""); + } + } + } + }; + } +}; + +/** + * @fileoverview Rule to disallow mixed binary operators. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const ARITHMETIC_OPERATORS = ["+", "-", "*", "/", "%", "**"]; +const BITWISE_OPERATORS = ["&", "|", "^", "~", "<<", ">>", ">>>"]; +const COMPARISON_OPERATORS = ["==", "!=", "===", "!==", ">", ">=", "<", "<="]; +const LOGICAL_OPERATORS = ["&&", "||"]; +const RELATIONAL_OPERATORS = ["in", "instanceof"]; +const TERNARY_OPERATOR = ["?:"]; +const COALESCE_OPERATOR = ["??"]; +const ALL_OPERATORS = [].concat( + ARITHMETIC_OPERATORS, + BITWISE_OPERATORS, + COMPARISON_OPERATORS, + LOGICAL_OPERATORS, + RELATIONAL_OPERATORS, + TERNARY_OPERATOR, + COALESCE_OPERATOR +); +const DEFAULT_GROUPS = [ + ARITHMETIC_OPERATORS, + BITWISE_OPERATORS, + COMPARISON_OPERATORS, + LOGICAL_OPERATORS, + RELATIONAL_OPERATORS +]; +const TARGET_NODE_TYPE = /^(?:Binary|Logical|Conditional)Expression$/u; + +/** + * Normalizes options. + * @param {Object|undefined} options A options object to normalize. + * @returns {Object} Normalized option object. + */ +function normalizeOptions$1(options = {}) { + const hasGroups = options.groups && options.groups.length > 0; + const groups = hasGroups ? options.groups : DEFAULT_GROUPS; + const allowSamePrecedence = options.allowSamePrecedence !== false; + + return { + groups, + allowSamePrecedence + }; +} + +/** + * Checks whether any group which includes both given operator exists or not. + * @param {Array.} groups A list of groups to check. + * @param {string} left An operator. + * @param {string} right Another operator. + * @returns {boolean} `true` if such group existed. + */ +function includesBothInAGroup(groups, left, right) { + return groups.some(group => group.indexOf(left) !== -1 && group.indexOf(right) !== -1); +} + +/** + * Checks whether the given node is a conditional expression and returns the test node else the left node. + * @param {ASTNode} node A node which can be a BinaryExpression or a LogicalExpression node. + * This parent node can be BinaryExpression, LogicalExpression + * , or a ConditionalExpression node + * @returns {ASTNode} node the appropriate node(left or test). + */ +function getChildNode(node) { + return node.type === "ConditionalExpression" ? node.test : node.left; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noMixedOperators = { + meta: { + type: "suggestion", + + docs: { + description: "disallow mixed binary operators", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-mixed-operators" + }, + + schema: [ + { + type: "object", + properties: { + groups: { + type: "array", + items: { + type: "array", + items: { enum: ALL_OPERATORS }, + minItems: 2, + uniqueItems: true + }, + uniqueItems: true + }, + allowSamePrecedence: { + type: "boolean", + default: true + } + }, + additionalProperties: false + } + ], + + messages: { + unexpectedMixedOperator: "Unexpected mix of '{{leftOperator}}' and '{{rightOperator}}'." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const options = normalizeOptions$1(context.options[0]); + + /** + * Checks whether a given node should be ignored by options or not. + * @param {ASTNode} node A node to check. This is a BinaryExpression + * node or a LogicalExpression node. This parent node is one of + * them, too. + * @returns {boolean} `true` if the node should be ignored. + */ + function shouldIgnore(node) { + const a = node; + const b = node.parent; + + return ( + !includesBothInAGroup(options.groups, a.operator, b.type === "ConditionalExpression" ? "?:" : b.operator) || + ( + options.allowSamePrecedence && + astUtils.getPrecedence(a) === astUtils.getPrecedence(b) + ) + ); + } + + /** + * Checks whether the operator of a given node is mixed with parent + * node's operator or not. + * @param {ASTNode} node A node to check. This is a BinaryExpression + * node or a LogicalExpression node. This parent node is one of + * them, too. + * @returns {boolean} `true` if the node was mixed. + */ + function isMixedWithParent(node) { + + return ( + node.operator !== node.parent.operator && + !astUtils.isParenthesised(sourceCode, node) + ); + } + + /** + * Gets the operator token of a given node. + * @param {ASTNode} node A node to check. This is a BinaryExpression + * node or a LogicalExpression node. + * @returns {Token} The operator token of the node. + */ + function getOperatorToken(node) { + return sourceCode.getTokenAfter(getChildNode(node), astUtils.isNotClosingParenToken); + } + + /** + * Reports both the operator of a given node and the operator of the + * parent node. + * @param {ASTNode} node A node to check. This is a BinaryExpression + * node or a LogicalExpression node. This parent node is one of + * them, too. + * @returns {void} + */ + function reportBothOperators(node) { + const parent = node.parent; + const left = (getChildNode(parent) === node) ? node : parent; + const right = (getChildNode(parent) !== node) ? node : parent; + const data = { + leftOperator: left.operator || "?:", + rightOperator: right.operator || "?:" + }; + + context.report({ + node: left, + loc: getOperatorToken(left).loc, + messageId: "unexpectedMixedOperator", + data + }); + context.report({ + node: right, + loc: getOperatorToken(right).loc, + messageId: "unexpectedMixedOperator", + data + }); + } + + /** + * Checks between the operator of this node and the operator of the + * parent node. + * @param {ASTNode} node A node to check. + * @returns {void} + */ + function check(node) { + if ( + TARGET_NODE_TYPE.test(node.parent.type) && + isMixedWithParent(node) && + !shouldIgnore(node) + ) { + reportBothOperators(node); + } + } + + return { + BinaryExpression: check, + LogicalExpression: check + }; + } +}; + +/** + * @fileoverview Rule to enforce grouped require statements for Node.JS + * @author Raphael Pigulla + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noMixedRequires = { + meta: { + deprecated: true, + + replacedBy: [], + + type: "suggestion", + + docs: { + description: "disallow `require` calls to be mixed with regular variable declarations", + category: "Node.js and CommonJS", + recommended: false, + url: "https://eslint.org/docs/rules/no-mixed-requires" + }, + + schema: [ + { + oneOf: [ + { + type: "boolean" + }, + { + type: "object", + properties: { + grouping: { + type: "boolean" + }, + allowCall: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + } + ], + + messages: { + noMixRequire: "Do not mix 'require' and other declarations.", + noMixCoreModuleFileComputed: "Do not mix core, module, file and computed requires." + } + }, + + create(context) { + + const options = context.options[0]; + let grouping = false, + allowCall = false; + + if (typeof options === "object") { + grouping = options.grouping; + allowCall = options.allowCall; + } else { + grouping = !!options; + } + + /** + * Returns the list of built-in modules. + * @returns {string[]} An array of built-in Node.js modules. + */ + function getBuiltinModules() { + + /* + * This list is generated using: + * `require("repl")._builtinLibs.concat('repl').sort()` + * This particular list is as per nodejs v0.12.2 and iojs v0.7.1 + */ + return [ + "assert", "buffer", "child_process", "cluster", "crypto", + "dgram", "dns", "domain", "events", "fs", "http", "https", + "net", "os", "path", "punycode", "querystring", "readline", + "repl", "smalloc", "stream", "string_decoder", "tls", "tty", + "url", "util", "v8", "vm", "zlib" + ]; + } + + const BUILTIN_MODULES = getBuiltinModules(); + + const DECL_REQUIRE = "require", + DECL_UNINITIALIZED = "uninitialized", + DECL_OTHER = "other"; + + const REQ_CORE = "core", + REQ_FILE = "file", + REQ_MODULE = "module", + REQ_COMPUTED = "computed"; + + /** + * Determines the type of a declaration statement. + * @param {ASTNode} initExpression The init node of the VariableDeclarator. + * @returns {string} The type of declaration represented by the expression. + */ + function getDeclarationType(initExpression) { + if (!initExpression) { + + // "var x;" + return DECL_UNINITIALIZED; + } + + if (initExpression.type === "CallExpression" && + initExpression.callee.type === "Identifier" && + initExpression.callee.name === "require" + ) { + + // "var x = require('util');" + return DECL_REQUIRE; + } + if (allowCall && + initExpression.type === "CallExpression" && + initExpression.callee.type === "CallExpression" + ) { + + // "var x = require('diagnose')('sub-module');" + return getDeclarationType(initExpression.callee); + } + if (initExpression.type === "MemberExpression") { + + // "var x = require('glob').Glob;" + return getDeclarationType(initExpression.object); + } + + // "var x = 42;" + return DECL_OTHER; + } + + /** + * Determines the type of module that is loaded via require. + * @param {ASTNode} initExpression The init node of the VariableDeclarator. + * @returns {string} The module type. + */ + function inferModuleType(initExpression) { + if (initExpression.type === "MemberExpression") { + + // "var x = require('glob').Glob;" + return inferModuleType(initExpression.object); + } + if (initExpression.arguments.length === 0) { + + // "var x = require();" + return REQ_COMPUTED; + } + + const arg = initExpression.arguments[0]; + + if (arg.type !== "Literal" || typeof arg.value !== "string") { + + // "var x = require(42);" + return REQ_COMPUTED; + } + + if (BUILTIN_MODULES.indexOf(arg.value) !== -1) { + + // "var fs = require('fs');" + return REQ_CORE; + } + if (/^\.{0,2}\//u.test(arg.value)) { + + // "var utils = require('./utils');" + return REQ_FILE; + } + + // "var async = require('async');" + return REQ_MODULE; + + } + + /** + * Check if the list of variable declarations is mixed, i.e. whether it + * contains both require and other declarations. + * @param {ASTNode} declarations The list of VariableDeclarators. + * @returns {boolean} True if the declarations are mixed, false if not. + */ + function isMixed(declarations) { + const contains = {}; + + declarations.forEach(declaration => { + const type = getDeclarationType(declaration.init); + + contains[type] = true; + }); + + return !!( + contains[DECL_REQUIRE] && + (contains[DECL_UNINITIALIZED] || contains[DECL_OTHER]) + ); + } + + /** + * Check if all require declarations in the given list are of the same + * type. + * @param {ASTNode} declarations The list of VariableDeclarators. + * @returns {boolean} True if the declarations are grouped, false if not. + */ + function isGrouped(declarations) { + const found = {}; + + declarations.forEach(declaration => { + if (getDeclarationType(declaration.init) === DECL_REQUIRE) { + found[inferModuleType(declaration.init)] = true; + } + }); + + return Object.keys(found).length <= 1; + } + + + return { + + VariableDeclaration(node) { + + if (isMixed(node.declarations)) { + context.report({ + node, + messageId: "noMixRequire" + }); + } else if (grouping && !isGrouped(node.declarations)) { + context.report({ + node, + messageId: "noMixCoreModuleFileComputed" + }); + } + } + }; + + } +}; + +/** + * @fileoverview Disallow mixed spaces and tabs for indentation + * @author Jary Niebur + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noMixedSpacesAndTabs = { + meta: { + type: "layout", + + docs: { + description: "disallow mixed spaces and tabs for indentation", + category: "Stylistic Issues", + recommended: true, + url: "https://eslint.org/docs/rules/no-mixed-spaces-and-tabs" + }, + + schema: [ + { + enum: ["smart-tabs", true, false] + } + ], + + messages: { + mixedSpacesAndTabs: "Mixed spaces and tabs." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + let smartTabs; + + switch (context.options[0]) { + case true: // Support old syntax, maybe add deprecation warning here + case "smart-tabs": + smartTabs = true; + break; + default: + smartTabs = false; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + "Program:exit"(node) { + const lines = sourceCode.lines, + comments = sourceCode.getAllComments(), + ignoredCommentLines = new Set(); + + // Add all lines except the first ones. + comments.forEach(comment => { + for (let i = comment.loc.start.line + 1; i <= comment.loc.end.line; i++) { + ignoredCommentLines.add(i); + } + }); + + /* + * At least one space followed by a tab + * or the reverse before non-tab/-space + * characters begin. + */ + let regex = /^(?=( +|\t+))\1(?:\t| )/u; + + if (smartTabs) { + + /* + * At least one space followed by a tab + * before non-tab/-space characters begin. + */ + regex = /^(?=(\t*))\1(?=( +))\2\t/u; + } + + lines.forEach((line, i) => { + const match = regex.exec(line); + + if (match) { + const lineNumber = i + 1; + const loc = { + start: { + line: lineNumber, + column: match[0].length - 2 + }, + end: { + line: lineNumber, + column: match[0].length + } + }; + + if (!ignoredCommentLines.has(lineNumber)) { + const containingNode = sourceCode.getNodeByRangeIndex(sourceCode.getIndexFromLoc(loc.start)); + + if (!(containingNode && ["Literal", "TemplateElement"].includes(containingNode.type))) { + context.report({ + node, + loc, + messageId: "mixedSpacesAndTabs" + }); + } + } + } + }); + } + }; + } +}; + +/** + * @fileoverview Rule to check use of chained assignment expressions + * @author Stewart Rand + */ + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noMultiAssign = { + meta: { + type: "suggestion", + + docs: { + description: "disallow use of chained assignment expressions", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-multi-assign" + }, + + schema: [{ + type: "object", + properties: { + ignoreNonDeclaration: { + type: "boolean", + default: false + } + }, + additionalProperties: false + }], + + messages: { + unexpectedChain: "Unexpected chained assignment." + } + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + const options = context.options[0] || { + ignoreNonDeclaration: false + }; + const targetParent = options.ignoreNonDeclaration ? ["VariableDeclarator"] : ["AssignmentExpression", "VariableDeclarator"]; + + return { + AssignmentExpression(node) { + if (targetParent.indexOf(node.parent.type) !== -1) { + context.report({ + node, + messageId: "unexpectedChain" + }); + } + } + }; + + } +}; + +/** + * @fileoverview Disallow use of multiple spaces. + * @author Nicholas C. Zakas + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noMultiSpaces = { + meta: { + type: "layout", + + docs: { + description: "disallow multiple spaces", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-multi-spaces" + }, + + fixable: "whitespace", + + schema: [ + { + type: "object", + properties: { + exceptions: { + type: "object", + patternProperties: { + "^([A-Z][a-z]*)+$": { + type: "boolean" + } + }, + additionalProperties: false + }, + ignoreEOLComments: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + messages: { + multipleSpaces: "Multiple spaces found before '{{displayValue}}'." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const options = context.options[0] || {}; + const ignoreEOLComments = options.ignoreEOLComments; + const exceptions = Object.assign({ Property: true }, options.exceptions); + const hasExceptions = Object.keys(exceptions).filter(key => exceptions[key]).length > 0; + + /** + * Formats value of given comment token for error message by truncating its length. + * @param {Token} token comment token + * @returns {string} formatted value + * @private + */ + function formatReportedCommentValue(token) { + const valueLines = token.value.split("\n"); + const value = valueLines[0]; + const formattedValue = `${value.slice(0, 12)}...`; + + return valueLines.length === 1 && value.length <= 12 ? value : formattedValue; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + Program() { + sourceCode.tokensAndComments.forEach((leftToken, leftIndex, tokensAndComments) => { + if (leftIndex === tokensAndComments.length - 1) { + return; + } + const rightToken = tokensAndComments[leftIndex + 1]; + + // Ignore tokens that don't have 2 spaces between them or are on different lines + if ( + !sourceCode.text.slice(leftToken.range[1], rightToken.range[0]).includes(" ") || + leftToken.loc.end.line < rightToken.loc.start.line + ) { + return; + } + + // Ignore comments that are the last token on their line if `ignoreEOLComments` is active. + if ( + ignoreEOLComments && + astUtils.isCommentToken(rightToken) && + ( + leftIndex === tokensAndComments.length - 2 || + rightToken.loc.end.line < tokensAndComments[leftIndex + 2].loc.start.line + ) + ) { + return; + } + + // Ignore tokens that are in a node in the "exceptions" object + if (hasExceptions) { + const parentNode = sourceCode.getNodeByRangeIndex(rightToken.range[0] - 1); + + if (parentNode && exceptions[parentNode.type]) { + return; + } + } + + let displayValue; + + if (rightToken.type === "Block") { + displayValue = `/*${formatReportedCommentValue(rightToken)}*/`; + } else if (rightToken.type === "Line") { + displayValue = `//${formatReportedCommentValue(rightToken)}`; + } else { + displayValue = rightToken.value; + } + + context.report({ + node: rightToken, + loc: { start: leftToken.loc.end, end: rightToken.loc.start }, + messageId: "multipleSpaces", + data: { displayValue }, + fix: fixer => fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], " ") + }); + }); + } + }; + + } +}; + +/** + * @fileoverview Rule to flag when using multiline strings + * @author Ilya Volodin + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noMultiStr = { + meta: { + type: "suggestion", + + docs: { + description: "disallow multiline strings", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-multi-str" + }, + + schema: [], + + messages: { + multilineString: "Multiline support is limited to browsers supporting ES5 only." + } + }, + + create(context) { + + /** + * Determines if a given node is part of JSX syntax. + * @param {ASTNode} node The node to check. + * @returns {boolean} True if the node is a JSX node, false if not. + * @private + */ + function isJSXElement(node) { + return node.type.indexOf("JSX") === 0; + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + + Literal(node) { + if (astUtils.LINEBREAK_MATCHER.test(node.raw) && !isJSXElement(node.parent)) { + context.report({ + node, + messageId: "multilineString" + }); + } + } + }; + + } +}; + +/** + * @fileoverview Disallows multiple blank lines. + * implementation adapted from the no-trailing-spaces rule. + * @author Greg Cochard + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noMultipleEmptyLines = { + meta: { + type: "layout", + + docs: { + description: "disallow multiple empty lines", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-multiple-empty-lines" + }, + + fixable: "whitespace", + + schema: [ + { + type: "object", + properties: { + max: { + type: "integer", + minimum: 0 + }, + maxEOF: { + type: "integer", + minimum: 0 + }, + maxBOF: { + type: "integer", + minimum: 0 + } + }, + required: ["max"], + additionalProperties: false + } + ], + + messages: { + blankBeginningOfFile: "Too many blank lines at the beginning of file. Max of {{max}} allowed.", + blankEndOfFile: "Too many blank lines at the end of file. Max of {{max}} allowed.", + consecutiveBlank: "More than {{max}} blank {{pluralizedLines}} not allowed." + } + }, + + create(context) { + + // Use options.max or 2 as default + let max = 2, + maxEOF = max, + maxBOF = max; + + if (context.options.length) { + max = context.options[0].max; + maxEOF = typeof context.options[0].maxEOF !== "undefined" ? context.options[0].maxEOF : max; + maxBOF = typeof context.options[0].maxBOF !== "undefined" ? context.options[0].maxBOF : max; + } + + const sourceCode = context.getSourceCode(); + + // Swallow the final newline, as some editors add it automatically and we don't want it to cause an issue + const allLines = sourceCode.lines[sourceCode.lines.length - 1] === "" ? sourceCode.lines.slice(0, -1) : sourceCode.lines; + const templateLiteralLines = new Set(); + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + TemplateLiteral(node) { + node.quasis.forEach(literalPart => { + + // Empty lines have a semantic meaning if they're inside template literals. Don't count these as empty lines. + for (let ignoredLine = literalPart.loc.start.line; ignoredLine < literalPart.loc.end.line; ignoredLine++) { + templateLiteralLines.add(ignoredLine); + } + }); + }, + "Program:exit"(node) { + return allLines + + // Given a list of lines, first get a list of line numbers that are non-empty. + .reduce((nonEmptyLineNumbers, line, index) => { + if (line.trim() || templateLiteralLines.has(index + 1)) { + nonEmptyLineNumbers.push(index + 1); + } + return nonEmptyLineNumbers; + }, []) + + // Add a value at the end to allow trailing empty lines to be checked. + .concat(allLines.length + 1) + + // Given two line numbers of non-empty lines, report the lines between if the difference is too large. + .reduce((lastLineNumber, lineNumber) => { + let messageId, maxAllowed; + + if (lastLineNumber === 0) { + messageId = "blankBeginningOfFile"; + maxAllowed = maxBOF; + } else if (lineNumber === allLines.length + 1) { + messageId = "blankEndOfFile"; + maxAllowed = maxEOF; + } else { + messageId = "consecutiveBlank"; + maxAllowed = max; + } + + if (lineNumber - lastLineNumber - 1 > maxAllowed) { + context.report({ + node, + loc: { + start: { line: lastLineNumber + maxAllowed + 1, column: 0 }, + end: { line: lineNumber, column: 0 } + }, + messageId, + data: { + max: maxAllowed, + pluralizedLines: maxAllowed === 1 ? "line" : "lines" + }, + fix(fixer) { + const rangeStart = sourceCode.getIndexFromLoc({ line: lastLineNumber + 1, column: 0 }); + + /* + * The end of the removal range is usually the start index of the next line. + * However, at the end of the file there is no next line, so the end of the + * range is just the length of the text. + */ + const lineNumberAfterRemovedLines = lineNumber - maxAllowed; + const rangeEnd = lineNumberAfterRemovedLines <= allLines.length + ? sourceCode.getIndexFromLoc({ line: lineNumberAfterRemovedLines, column: 0 }) + : sourceCode.text.length; + + return fixer.removeRange([rangeStart, rangeEnd]); + } + }); + } + + return lineNumber; + }, 0); + } + }; + } +}; + +/** + * @fileoverview Rule to disallow assignments to native objects or read-only global variables + * @author Ilya Volodin + * @deprecated in ESLint v3.3.0 + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noNativeReassign = { + meta: { + type: "suggestion", + + docs: { + description: "disallow assignments to native objects or read-only global variables", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-native-reassign" + }, + + deprecated: true, + + replacedBy: ["no-global-assign"], + + schema: [ + { + type: "object", + properties: { + exceptions: { + type: "array", + items: { type: "string" }, + uniqueItems: true + } + }, + additionalProperties: false + } + ], + + messages: { + nativeReassign: "Read-only global '{{name}}' should not be modified." + } + }, + + create(context) { + const config = context.options[0]; + const exceptions = (config && config.exceptions) || []; + + /** + * Reports write references. + * @param {Reference} reference A reference to check. + * @param {int} index The index of the reference in the references. + * @param {Reference[]} references The array that the reference belongs to. + * @returns {void} + */ + function checkReference(reference, index, references) { + const identifier = reference.identifier; + + if (reference.init === false && + reference.isWrite() && + + /* + * Destructuring assignments can have multiple default value, + * so possibly there are multiple writeable references for the same identifier. + */ + (index === 0 || references[index - 1].identifier !== identifier) + ) { + context.report({ + node: identifier, + messageId: "nativeReassign", + data: identifier + }); + } + } + + /** + * Reports write references if a given variable is read-only builtin. + * @param {Variable} variable A variable to check. + * @returns {void} + */ + function checkVariable(variable) { + if (variable.writeable === false && exceptions.indexOf(variable.name) === -1) { + variable.references.forEach(checkReference); + } + } + + return { + Program() { + const globalScope = context.getScope(); + + globalScope.variables.forEach(checkVariable); + } + }; + } +}; + +/** + * @fileoverview Rule to disallow a negated condition + * @author Alberto Rodríguez + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noNegatedCondition = { + meta: { + type: "suggestion", + + docs: { + description: "disallow negated conditions", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-negated-condition" + }, + + schema: [], + + messages: { + unexpectedNegated: "Unexpected negated condition." + } + }, + + create(context) { + + /** + * Determines if a given node is an if-else without a condition on the else + * @param {ASTNode} node The node to check. + * @returns {boolean} True if the node has an else without an if. + * @private + */ + function hasElseWithoutCondition(node) { + return node.alternate && node.alternate.type !== "IfStatement"; + } + + /** + * Determines if a given node is a negated unary expression + * @param {Object} test The test object to check. + * @returns {boolean} True if the node is a negated unary expression. + * @private + */ + function isNegatedUnaryExpression(test) { + return test.type === "UnaryExpression" && test.operator === "!"; + } + + /** + * Determines if a given node is a negated binary expression + * @param {Test} test The test to check. + * @returns {boolean} True if the node is a negated binary expression. + * @private + */ + function isNegatedBinaryExpression(test) { + return test.type === "BinaryExpression" && + (test.operator === "!=" || test.operator === "!=="); + } + + /** + * Determines if a given node has a negated if expression + * @param {ASTNode} node The node to check. + * @returns {boolean} True if the node has a negated if expression. + * @private + */ + function isNegatedIf(node) { + return isNegatedUnaryExpression(node.test) || isNegatedBinaryExpression(node.test); + } + + return { + IfStatement(node) { + if (!hasElseWithoutCondition(node)) { + return; + } + + if (isNegatedIf(node)) { + context.report({ + node, + messageId: "unexpectedNegated" + }); + } + }, + ConditionalExpression(node) { + if (isNegatedIf(node)) { + context.report({ + node, + messageId: "unexpectedNegated" + }); + } + } + }; + } +}; + +/** + * @fileoverview A rule to disallow negated left operands of the `in` operator + * @author Michael Ficarra + * @deprecated in ESLint v3.3.0 + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noNegatedInLhs = { + meta: { + type: "problem", + + docs: { + description: "disallow negating the left operand in `in` expressions", + category: "Possible Errors", + recommended: false, + url: "https://eslint.org/docs/rules/no-negated-in-lhs" + }, + + replacedBy: ["no-unsafe-negation"], + + deprecated: true, + schema: [], + + messages: { + negatedLHS: "The 'in' expression's left operand is negated." + } + }, + + create(context) { + + return { + + BinaryExpression(node) { + if (node.operator === "in" && node.left.type === "UnaryExpression" && node.left.operator === "!") { + context.report({ node, messageId: "negatedLHS" }); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag nested ternary expressions + * @author Ian Christian Myers + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noNestedTernary = { + meta: { + type: "suggestion", + + docs: { + description: "disallow nested ternary expressions", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-nested-ternary" + }, + + schema: [], + + messages: { + noNestedTernary: "Do not nest ternary expressions." + } + }, + + create(context) { + + return { + ConditionalExpression(node) { + if (node.alternate.type === "ConditionalExpression" || + node.consequent.type === "ConditionalExpression") { + context.report({ + node, + messageId: "noNestedTernary" + }); + } + } + }; + } +}; + +/** + * @fileoverview Rule to flag statements with function invocation preceded by + * "new" and not part of assignment + * @author Ilya Volodin + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noNew = { + meta: { + type: "suggestion", + + docs: { + description: "disallow `new` operators outside of assignments or comparisons", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-new" + }, + + schema: [], + + messages: { + noNewStatement: "Do not use 'new' for side effects." + } + }, + + create(context) { + + return { + "ExpressionStatement > NewExpression"(node) { + context.report({ + node: node.parent, + messageId: "noNewStatement" + }); + } + }; + + } +}; + +/** + * @fileoverview Rule to flag when using new Function + * @author Ilya Volodin + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noNewFunc = { + meta: { + type: "suggestion", + + docs: { + description: "disallow `new` operators with the `Function` object", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-new-func" + }, + + schema: [], + + messages: { + noFunctionConstructor: "The Function constructor is eval." + } + }, + + create(context) { + + return { + "Program:exit"() { + const globalScope = context.getScope(); + const variable = globalScope.set.get("Function"); + + if (variable && variable.defs.length === 0) { + variable.references.forEach(ref => { + const node = ref.identifier; + const { parent } = node; + + if ( + parent && + (parent.type === "NewExpression" || parent.type === "CallExpression") && + node === parent.callee + ) { + context.report({ + node: parent, + messageId: "noFunctionConstructor" + }); + } + }); + } + } + }; + + } +}; + +/** + * @fileoverview A rule to disallow calls to the Object constructor + * @author Matt DuVall + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noNewObject = { + meta: { + type: "suggestion", + + docs: { + description: "disallow `Object` constructors", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-new-object" + }, + + schema: [], + + messages: { + preferLiteral: "The object literal notation {} is preferrable." + } + }, + + create(context) { + return { + NewExpression(node) { + const variable = astUtils.getVariableByName( + context.getScope(), + node.callee.name + ); + + if (variable && variable.identifiers.length > 0) { + return; + } + + if (node.callee.name === "Object") { + context.report({ + node, + messageId: "preferLiteral" + }); + } + } + }; + } +}; + +/** + * @fileoverview Rule to disallow use of new operator with the `require` function + * @author Wil Moore III + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noNewRequire = { + meta: { + deprecated: true, + + replacedBy: [], + + type: "suggestion", + + docs: { + description: "disallow `new` operators with calls to `require`", + category: "Node.js and CommonJS", + recommended: false, + url: "https://eslint.org/docs/rules/no-new-require" + }, + + schema: [], + + messages: { + noNewRequire: "Unexpected use of new with require." + } + }, + + create(context) { + + return { + + NewExpression(node) { + if (node.callee.type === "Identifier" && node.callee.name === "require") { + context.report({ + node, + messageId: "noNewRequire" + }); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to disallow use of the new operator with the `Symbol` object + * @author Alberto Rodríguez + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noNewSymbol = { + meta: { + type: "problem", + + docs: { + description: "disallow `new` operators with the `Symbol` object", + category: "ECMAScript 6", + recommended: true, + url: "https://eslint.org/docs/rules/no-new-symbol" + }, + + schema: [], + + messages: { + noNewSymbol: "`Symbol` cannot be called as a constructor." + } + }, + + create(context) { + + return { + "Program:exit"() { + const globalScope = context.getScope(); + const variable = globalScope.set.get("Symbol"); + + if (variable && variable.defs.length === 0) { + variable.references.forEach(ref => { + const node = ref.identifier; + const parent = node.parent; + + if (parent && parent.type === "NewExpression" && parent.callee === node) { + context.report({ + node, + messageId: "noNewSymbol" + }); + } + }); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag when using constructor for wrapper objects + * @author Ilya Volodin + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noNewWrappers = { + meta: { + type: "suggestion", + + docs: { + description: "disallow `new` operators with the `String`, `Number`, and `Boolean` objects", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-new-wrappers" + }, + + schema: [], + + messages: { + noConstructor: "Do not use {{fn}} as a constructor." + } + }, + + create(context) { + + return { + + NewExpression(node) { + const wrapperObjects = ["String", "Number", "Boolean"]; + + if (wrapperObjects.indexOf(node.callee.name) > -1) { + context.report({ + node, + messageId: "noConstructor", + data: { fn: node.callee.name } + }); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to disallow `\8` and `\9` escape sequences in string literals. + * @author Milos Djermanovic + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const QUICK_TEST_REGEX = /\\[89]/u; + +/** + * Returns unicode escape sequence that represents the given character. + * @param {string} character A single code unit. + * @returns {string} "\uXXXX" sequence. + */ +function getUnicodeEscape(character) { + return `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noNonoctalDecimalEscape = { + meta: { + type: "suggestion", + + docs: { + description: "disallow `\\8` and `\\9` escape sequences in string literals", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-nonoctal-decimal-escape", + suggestion: true + }, + + schema: [], + + messages: { + decimalEscape: "Don't use '{{decimalEscape}}' escape sequence.", + + // suggestions + refactor: "Replace '{{original}}' with '{{replacement}}'. This maintains the current functionality.", + escapeBackslash: "Replace '{{original}}' with '{{replacement}}' to include the actual backslash character." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + /** + * Creates a new Suggestion object. + * @param {string} messageId "refactor" or "escapeBackslash". + * @param {int[]} range The range to replace. + * @param {string} replacement New text for the range. + * @returns {Object} Suggestion + */ + function createSuggestion(messageId, range, replacement) { + return { + messageId, + data: { + original: sourceCode.getText().slice(...range), + replacement + }, + fix(fixer) { + return fixer.replaceTextRange(range, replacement); + } + }; + } + + return { + Literal(node) { + if (typeof node.value !== "string") { + return; + } + + if (!QUICK_TEST_REGEX.test(node.raw)) { + return; + } + + const regex = /(?:[^\\]|(?\\.))*?(?\\[89])/suy; + let match; + + while ((match = regex.exec(node.raw))) { + const { previousEscape, decimalEscape } = match.groups; + const decimalEscapeRangeEnd = node.range[0] + match.index + match[0].length; + const decimalEscapeRangeStart = decimalEscapeRangeEnd - decimalEscape.length; + const decimalEscapeRange = [decimalEscapeRangeStart, decimalEscapeRangeEnd]; + const suggest = []; + + // When `regex` is matched, `previousEscape` can only capture characters adjacent to `decimalEscape` + if (previousEscape === "\\0") { + + /* + * Now we have a NULL escape "\0" immediately followed by a decimal escape, e.g.: "\0\8". + * Fixing this to "\08" would turn "\0" into a legacy octal escape. To avoid producing + * an octal escape while fixing a decimal escape, we provide different suggestions. + */ + suggest.push( + createSuggestion( // "\0\8" -> "\u00008" + "refactor", + [decimalEscapeRangeStart - previousEscape.length, decimalEscapeRangeEnd], + `${getUnicodeEscape("\0")}${decimalEscape[1]}` + ), + createSuggestion( // "\8" -> "\u0038" + "refactor", + decimalEscapeRange, + getUnicodeEscape(decimalEscape[1]) + ) + ); + } else { + suggest.push( + createSuggestion( // "\8" -> "8" + "refactor", + decimalEscapeRange, + decimalEscape[1] + ) + ); + } + + suggest.push( + createSuggestion( // "\8" -> "\\8" + "escapeBackslash", + decimalEscapeRange, + `\\${decimalEscape}` + ) + ); + + context.report({ + node, + loc: { + start: sourceCode.getLocFromIndex(decimalEscapeRangeStart), + end: sourceCode.getLocFromIndex(decimalEscapeRangeEnd) + }, + messageId: "decimalEscape", + data: { + decimalEscape + }, + suggest + }); + } + } + }; + } +}; + +/** + * @fileoverview Rule to flag use of an object property of the global object (Math and JSON) as a function + * @author James Allardice + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const { CALL: CALL$6, CONSTRUCT: CONSTRUCT$4, ReferenceTracker: ReferenceTracker$6 } = require$$0__default$1['default']; +const getPropertyName$1 = astUtils.getStaticPropertyName; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const nonCallableGlobals = ["Atomics", "JSON", "Math", "Reflect"]; + +/** + * Returns the name of the node to report + * @param {ASTNode} node A node to report + * @returns {string} name to report + */ +function getReportNodeName(node) { + if (node.type === "ChainExpression") { + return getReportNodeName(node.expression); + } + if (node.type === "MemberExpression") { + return getPropertyName$1(node); + } + return node.name; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noObjCalls = { + meta: { + type: "problem", + + docs: { + description: "disallow calling global object properties as functions", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-obj-calls" + }, + + schema: [], + + messages: { + unexpectedCall: "'{{name}}' is not a function.", + unexpectedRefCall: "'{{name}}' is reference to '{{ref}}', which is not a function." + } + }, + + create(context) { + + return { + Program() { + const scope = context.getScope(); + const tracker = new ReferenceTracker$6(scope); + const traceMap = {}; + + for (const g of nonCallableGlobals) { + traceMap[g] = { + [CALL$6]: true, + [CONSTRUCT$4]: true + }; + } + + for (const { node, path } of tracker.iterateGlobalReferences(traceMap)) { + const name = getReportNodeName(node.callee); + const ref = path[0]; + const messageId = name === ref ? "unexpectedCall" : "unexpectedRefCall"; + + context.report({ node, messageId, data: { name, ref } }); + } + } + }; + } +}; + +/** + * @fileoverview Rule to flag when initializing octal literal + * @author Ilya Volodin + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noOctal = { + meta: { + type: "suggestion", + + docs: { + description: "disallow octal literals", + category: "Best Practices", + recommended: true, + url: "https://eslint.org/docs/rules/no-octal" + }, + + schema: [], + + messages: { + noOcatal: "Octal literals should not be used." + } + }, + + create(context) { + + return { + + Literal(node) { + if (typeof node.value === "number" && /^0[0-9]/u.test(node.raw)) { + context.report({ + node, + messageId: "noOcatal" + }); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag octal escape sequences in string literals. + * @author Ian Christian Myers + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noOctalEscape = { + meta: { + type: "suggestion", + + docs: { + description: "disallow octal escape sequences in string literals", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-octal-escape" + }, + + schema: [], + + messages: { + octalEscapeSequence: "Don't use octal: '\\{{sequence}}'. Use '\\u....' instead." + } + }, + + create(context) { + + return { + + Literal(node) { + if (typeof node.value !== "string") { + return; + } + + // \0 represents a valid NULL character if it isn't followed by a digit. + const match = node.raw.match( + /^(?:[^\\]|\\.)*?\\([0-3][0-7]{1,2}|[4-7][0-7]|0(?=[89])|[1-7])/su + ); + + if (match) { + context.report({ + node, + messageId: "octalEscapeSequence", + data: { sequence: match[1] } + }); + } + } + + }; + + } +}; + +/** + * @fileoverview Disallow reassignment of function parameters. + * @author Nat Burns + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const stopNodePattern = /(?:Statement|Declaration|Function(?:Expression)?|Program)$/u; + +var noParamReassign = { + meta: { + type: "suggestion", + + docs: { + description: "disallow reassigning `function` parameters", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-param-reassign" + }, + + schema: [ + { + oneOf: [ + { + type: "object", + properties: { + props: { + enum: [false] + } + }, + additionalProperties: false + }, + { + type: "object", + properties: { + props: { + enum: [true] + }, + ignorePropertyModificationsFor: { + type: "array", + items: { + type: "string" + }, + uniqueItems: true + }, + ignorePropertyModificationsForRegex: { + type: "array", + items: { + type: "string" + }, + uniqueItems: true + } + }, + additionalProperties: false + } + ] + } + ], + + messages: { + assignmentToFunctionParam: "Assignment to function parameter '{{name}}'.", + assignmentToFunctionParamProp: "Assignment to property of function parameter '{{name}}'." + } + }, + + create(context) { + const props = context.options[0] && context.options[0].props; + const ignoredPropertyAssignmentsFor = context.options[0] && context.options[0].ignorePropertyModificationsFor || []; + const ignoredPropertyAssignmentsForRegex = context.options[0] && context.options[0].ignorePropertyModificationsForRegex || []; + + /** + * Checks whether or not the reference modifies properties of its variable. + * @param {Reference} reference A reference to check. + * @returns {boolean} Whether or not the reference modifies properties of its variable. + */ + function isModifyingProp(reference) { + let node = reference.identifier; + let parent = node.parent; + + while (parent && (!stopNodePattern.test(parent.type) || + parent.type === "ForInStatement" || parent.type === "ForOfStatement")) { + switch (parent.type) { + + // e.g. foo.a = 0; + case "AssignmentExpression": + return parent.left === node; + + // e.g. ++foo.a; + case "UpdateExpression": + return true; + + // e.g. delete foo.a; + case "UnaryExpression": + if (parent.operator === "delete") { + return true; + } + break; + + // e.g. for (foo.a in b) {} + case "ForInStatement": + case "ForOfStatement": + if (parent.left === node) { + return true; + } + + // this is a stop node for parent.right and parent.body + return false; + + // EXCLUDES: e.g. cache.get(foo.a).b = 0; + case "CallExpression": + if (parent.callee !== node) { + return false; + } + break; + + // EXCLUDES: e.g. cache[foo.a] = 0; + case "MemberExpression": + if (parent.property === node) { + return false; + } + break; + + // EXCLUDES: e.g. ({ [foo]: a }) = bar; + case "Property": + if (parent.key === node) { + return false; + } + + break; + + // EXCLUDES: e.g. (foo ? a : b).c = bar; + case "ConditionalExpression": + if (parent.test === node) { + return false; + } + + break; + + // no default + } + + node = parent; + parent = node.parent; + } + + return false; + } + + /** + * Tests that an identifier name matches any of the ignored property assignments. + * First we test strings in ignoredPropertyAssignmentsFor. + * Then we instantiate and test RegExp objects from ignoredPropertyAssignmentsForRegex strings. + * @param {string} identifierName A string that describes the name of an identifier to + * ignore property assignments for. + * @returns {boolean} Whether the string matches an ignored property assignment regular expression or not. + */ + function isIgnoredPropertyAssignment(identifierName) { + return ignoredPropertyAssignmentsFor.includes(identifierName) || + ignoredPropertyAssignmentsForRegex.some(ignored => new RegExp(ignored, "u").test(identifierName)); + } + + /** + * Reports a reference if is non initializer and writable. + * @param {Reference} reference A reference to check. + * @param {int} index The index of the reference in the references. + * @param {Reference[]} references The array that the reference belongs to. + * @returns {void} + */ + function checkReference(reference, index, references) { + const identifier = reference.identifier; + + if (identifier && + !reference.init && + + /* + * Destructuring assignments can have multiple default value, + * so possibly there are multiple writeable references for the same identifier. + */ + (index === 0 || references[index - 1].identifier !== identifier) + ) { + if (reference.isWrite()) { + context.report({ + node: identifier, + messageId: "assignmentToFunctionParam", + data: { name: identifier.name } + }); + } else if (props && isModifyingProp(reference) && !isIgnoredPropertyAssignment(identifier.name)) { + context.report({ + node: identifier, + messageId: "assignmentToFunctionParamProp", + data: { name: identifier.name } + }); + } + } + } + + /** + * Finds and reports references that are non initializer and writable. + * @param {Variable} variable A variable to check. + * @returns {void} + */ + function checkVariable(variable) { + if (variable.defs[0].type === "Parameter") { + variable.references.forEach(checkReference); + } + } + + /** + * Checks parameters of a given function node. + * @param {ASTNode} node A function node to check. + * @returns {void} + */ + function checkForFunction(node) { + context.getDeclaredVariables(node).forEach(checkVariable); + } + + return { + + // `:exit` is needed for the `node.parent` property of identifier nodes. + "FunctionDeclaration:exit": checkForFunction, + "FunctionExpression:exit": checkForFunction, + "ArrowFunctionExpression:exit": checkForFunction + }; + + } +}; + +/** + * @fileoverview Disallow string concatenation when using __dirname and __filename + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noPathConcat = { + meta: { + deprecated: true, + + replacedBy: [], + + type: "suggestion", + + docs: { + description: "disallow string concatenation with `__dirname` and `__filename`", + category: "Node.js and CommonJS", + recommended: false, + url: "https://eslint.org/docs/rules/no-path-concat" + }, + + schema: [], + + messages: { + usePathFunctions: "Use path.join() or path.resolve() instead of + to create paths." + } + }, + + create(context) { + + const MATCHER = /^__(?:dir|file)name$/u; + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + BinaryExpression(node) { + + const left = node.left, + right = node.right; + + if (node.operator === "+" && + ((left.type === "Identifier" && MATCHER.test(left.name)) || + (right.type === "Identifier" && MATCHER.test(right.name))) + ) { + + context.report({ + node, + messageId: "usePathFunctions" + }); + } + } + + }; + + } +}; + +/** + * @fileoverview Rule to flag use of unary increment and decrement operators. + * @author Ian Christian Myers + * @author Brody McKee (github.com/mrmckeb) + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Determines whether the given node is the update node of a `ForStatement`. + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if the node is `ForStatement` update. + */ +function isForStatementUpdate(node) { + const parent = node.parent; + + return parent.type === "ForStatement" && parent.update === node; +} + +/** + * Determines whether the given node is considered to be a for loop "afterthought" by the logic of this rule. + * In particular, it returns `true` if the given node is either: + * - The update node of a `ForStatement`: for (;; i++) {} + * - An operand of a sequence expression that is the update node: for (;; foo(), i++) {} + * - An operand of a sequence expression that is child of another sequence expression, etc., + * up to the sequence expression that is the update node: for (;; foo(), (bar(), (baz(), i++))) {} + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if the node is a for loop afterthought. + */ +function isForLoopAfterthought(node) { + const parent = node.parent; + + if (parent.type === "SequenceExpression") { + return isForLoopAfterthought(parent); + } + + return isForStatementUpdate(node); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noPlusplus = { + meta: { + type: "suggestion", + + docs: { + description: "disallow the unary operators `++` and `--`", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-plusplus" + }, + + schema: [ + { + type: "object", + properties: { + allowForLoopAfterthoughts: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + messages: { + unexpectedUnaryOp: "Unary operator '{{operator}}' used." + } + }, + + create(context) { + + const config = context.options[0]; + let allowForLoopAfterthoughts = false; + + if (typeof config === "object") { + allowForLoopAfterthoughts = config.allowForLoopAfterthoughts === true; + } + + return { + + UpdateExpression(node) { + if (allowForLoopAfterthoughts && isForLoopAfterthought(node)) { + return; + } + + context.report({ + node, + messageId: "unexpectedUnaryOp", + data: { + operator: node.operator + } + }); + } + + }; + + } +}; + +/** + * @fileoverview Disallow the use of process.env() + * @author Vignesh Anand + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noProcessEnv = { + meta: { + deprecated: true, + + replacedBy: [], + + type: "suggestion", + + docs: { + description: "disallow the use of `process.env`", + category: "Node.js and CommonJS", + recommended: false, + url: "https://eslint.org/docs/rules/no-process-env" + }, + + schema: [], + + messages: { + unexpectedProcessEnv: "Unexpected use of process.env." + } + }, + + create(context) { + + return { + + MemberExpression(node) { + const objectName = node.object.name, + propertyName = node.property.name; + + if (objectName === "process" && !node.computed && propertyName && propertyName === "env") { + context.report({ node, messageId: "unexpectedProcessEnv" }); + } + + } + + }; + + } +}; + +/** + * @fileoverview Disallow the use of process.exit() + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noProcessExit = { + meta: { + deprecated: true, + + replacedBy: [], + + type: "suggestion", + + docs: { + description: "disallow the use of `process.exit()`", + category: "Node.js and CommonJS", + recommended: false, + url: "https://eslint.org/docs/rules/no-process-exit" + }, + + schema: [], + + messages: { + noProcessExit: "Don't use process.exit(); throw an error instead." + } + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + "CallExpression > MemberExpression.callee[object.name = 'process'][property.name = 'exit']"(node) { + context.report({ node: node.parent, messageId: "noProcessExit" }); + } + }; + + } +}; + +/** + * @fileoverview Rule to disallow returning values from Promise executor functions + * @author Milos Djermanovic + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const { findVariable: findVariable$2 } = require$$0__default$1['default']; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const functionTypesToCheck = new Set(["ArrowFunctionExpression", "FunctionExpression"]); + +/** + * Determines whether the given identifier node is a reference to a global variable. + * @param {ASTNode} node `Identifier` node to check. + * @param {Scope} scope Scope to which the node belongs. + * @returns {boolean} True if the identifier is a reference to a global variable. + */ +function isGlobalReference$1(node, scope) { + const variable = findVariable$2(scope, node); + + return variable !== null && variable.scope.type === "global" && variable.defs.length === 0; +} + +/** + * Finds function's outer scope. + * @param {Scope} scope Function's own scope. + * @returns {Scope} Function's outer scope. + */ +function getOuterScope$1(scope) { + const upper = scope.upper; + + if (upper.type === "function-expression-name") { + return upper.upper; + } + return upper; +} + +/** + * Determines whether the given function node is used as a Promise executor. + * @param {ASTNode} node The node to check. + * @param {Scope} scope Function's own scope. + * @returns {boolean} `true` if the node is a Promise executor. + */ +function isPromiseExecutor(node, scope) { + const parent = node.parent; + + return parent.type === "NewExpression" && + parent.arguments[0] === node && + parent.callee.type === "Identifier" && + parent.callee.name === "Promise" && + isGlobalReference$1(parent.callee, getOuterScope$1(scope)); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noPromiseExecutorReturn = { + meta: { + type: "problem", + + docs: { + description: "disallow returning values from Promise executor functions", + category: "Possible Errors", + recommended: false, + url: "https://eslint.org/docs/rules/no-promise-executor-return" + }, + + schema: [], + + messages: { + returnsValue: "Return values from promise executor functions cannot be read." + } + }, + + create(context) { + + let funcInfo = null; + + /** + * Reports the given node. + * @param {ASTNode} node Node to report. + * @returns {void} + */ + function report(node) { + context.report({ node, messageId: "returnsValue" }); + } + + return { + + onCodePathStart(_, node) { + funcInfo = { + upper: funcInfo, + shouldCheck: functionTypesToCheck.has(node.type) && isPromiseExecutor(node, context.getScope()) + }; + + if (funcInfo.shouldCheck && node.type === "ArrowFunctionExpression" && node.expression) { + report(node.body); + } + }, + + onCodePathEnd() { + funcInfo = funcInfo.upper; + }, + + ReturnStatement(node) { + if (funcInfo.shouldCheck && node.argument) { + report(node); + } + } + }; + } +}; + +/** + * @fileoverview Rule to flag usage of __proto__ property + * @author Ilya Volodin + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const { getStaticPropertyName } = astUtils; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noProto = { + meta: { + type: "suggestion", + + docs: { + description: "disallow the use of the `__proto__` property", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-proto" + }, + + schema: [], + + messages: { + unexpectedProto: "The '__proto__' property is deprecated." + } + }, + + create(context) { + + return { + + MemberExpression(node) { + if (getStaticPropertyName(node) === "__proto__") { + context.report({ node, messageId: "unexpectedProto" }); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to disallow use of Object.prototype builtins on objects + * @author Andrew Levine + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noPrototypeBuiltins = { + meta: { + type: "problem", + + docs: { + description: "disallow calling some `Object.prototype` methods directly on objects", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-prototype-builtins" + }, + + schema: [], + + messages: { + prototypeBuildIn: "Do not access Object.prototype method '{{prop}}' from target object." + } + }, + + create(context) { + const DISALLOWED_PROPS = [ + "hasOwnProperty", + "isPrototypeOf", + "propertyIsEnumerable" + ]; + + /** + * Reports if a disallowed property is used in a CallExpression + * @param {ASTNode} node The CallExpression node. + * @returns {void} + */ + function disallowBuiltIns(node) { + + const callee = astUtils.skipChainExpression(node.callee); + + if (callee.type !== "MemberExpression") { + return; + } + + const propName = astUtils.getStaticPropertyName(callee); + + if (propName !== null && DISALLOWED_PROPS.indexOf(propName) > -1) { + context.report({ + messageId: "prototypeBuildIn", + loc: callee.property.loc, + data: { prop: propName }, + node + }); + } + } + + return { + CallExpression: disallowBuiltIns + }; + } +}; + +/** + * @fileoverview Rule to flag when the same variable is declared more then once. + * @author Ilya Volodin + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noRedeclare = { + meta: { + type: "suggestion", + + docs: { + description: "disallow variable redeclaration", + category: "Best Practices", + recommended: true, + url: "https://eslint.org/docs/rules/no-redeclare" + }, + + messages: { + redeclared: "'{{id}}' is already defined.", + redeclaredAsBuiltin: "'{{id}}' is already defined as a built-in global variable.", + redeclaredBySyntax: "'{{id}}' is already defined by a variable declaration." + }, + + schema: [ + { + type: "object", + properties: { + builtinGlobals: { type: "boolean", default: true } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const options = { + builtinGlobals: Boolean( + context.options.length === 0 || + context.options[0].builtinGlobals + ) + }; + const sourceCode = context.getSourceCode(); + + /** + * Iterate declarations of a given variable. + * @param {escope.variable} variable The variable object to iterate declarations. + * @returns {IterableIterator<{type:string,node:ASTNode,loc:SourceLocation}>} The declarations. + */ + function *iterateDeclarations(variable) { + if (options.builtinGlobals && ( + variable.eslintImplicitGlobalSetting === "readonly" || + variable.eslintImplicitGlobalSetting === "writable" + )) { + yield { type: "builtin" }; + } + + for (const id of variable.identifiers) { + yield { type: "syntax", node: id, loc: id.loc }; + } + + if (variable.eslintExplicitGlobalComments) { + for (const comment of variable.eslintExplicitGlobalComments) { + yield { + type: "comment", + node: comment, + loc: astUtils.getNameLocationInGlobalDirectiveComment( + sourceCode, + comment, + variable.name + ) + }; + } + } + } + + /** + * Find variables in a given scope and flag redeclared ones. + * @param {Scope} scope An eslint-scope scope object. + * @returns {void} + * @private + */ + function findVariablesInScope(scope) { + for (const variable of scope.variables) { + const [ + declaration, + ...extraDeclarations + ] = iterateDeclarations(variable); + + if (extraDeclarations.length === 0) { + continue; + } + + /* + * If the type of a declaration is different from the type of + * the first declaration, it shows the location of the first + * declaration. + */ + const detailMessageId = declaration.type === "builtin" + ? "redeclaredAsBuiltin" + : "redeclaredBySyntax"; + const data = { id: variable.name }; + + // Report extra declarations. + for (const { type, node, loc } of extraDeclarations) { + const messageId = type === declaration.type + ? "redeclared" + : detailMessageId; + + context.report({ node, loc, messageId, data }); + } + } + } + + /** + * Find variables in the current scope. + * @param {ASTNode} node The node of the current scope. + * @returns {void} + * @private + */ + function checkForBlock(node) { + const scope = context.getScope(); + + /* + * In ES5, some node type such as `BlockStatement` doesn't have that scope. + * `scope.block` is a different node in such a case. + */ + if (scope.block === node) { + findVariablesInScope(scope); + } + } + + return { + Program() { + const scope = context.getScope(); + + findVariablesInScope(scope); + + // Node.js or ES modules has a special scope. + if ( + scope.type === "global" && + scope.childScopes[0] && + + // The special scope's block is the Program node. + scope.block === scope.childScopes[0].block + ) { + findVariablesInScope(scope.childScopes[0]); + } + }, + + FunctionDeclaration: checkForBlock, + FunctionExpression: checkForBlock, + ArrowFunctionExpression: checkForBlock, + + BlockStatement: checkForBlock, + ForStatement: checkForBlock, + ForInStatement: checkForBlock, + ForOfStatement: checkForBlock, + SwitchStatement: checkForBlock + }; + } +}; + +/** + * @fileoverview Rule to count multiple spaces in regular expressions + * @author Matt DuVall + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const regExpParser = new regexpp__default['default'].RegExpParser(); +const DOUBLE_SPACE = / {2}/u; + +/** + * Check if node is a string + * @param {ASTNode} node node to evaluate + * @returns {boolean} True if its a string + * @private + */ +function isString(node) { + return node && node.type === "Literal" && typeof node.value === "string"; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noRegexSpaces = { + meta: { + type: "suggestion", + + docs: { + description: "disallow multiple spaces in regular expressions", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-regex-spaces" + }, + + schema: [], + fixable: "code", + + messages: { + multipleSpaces: "Spaces are hard to count. Use {{{length}}}." + } + }, + + create(context) { + + /** + * Validate regular expression + * @param {ASTNode} nodeToReport Node to report. + * @param {string} pattern Regular expression pattern to validate. + * @param {string} rawPattern Raw representation of the pattern in the source code. + * @param {number} rawPatternStartRange Start range of the pattern in the source code. + * @param {string} flags Regular expression flags. + * @returns {void} + * @private + */ + function checkRegex(nodeToReport, pattern, rawPattern, rawPatternStartRange, flags) { + + // Skip if there are no consecutive spaces in the source code, to avoid reporting e.g., RegExp(' \ '). + if (!DOUBLE_SPACE.test(rawPattern)) { + return; + } + + const characterClassNodes = []; + let regExpAST; + + try { + regExpAST = regExpParser.parsePattern(pattern, 0, pattern.length, flags.includes("u")); + } catch { + + // Ignore regular expressions with syntax errors + return; + } + + regexpp__default['default'].visitRegExpAST(regExpAST, { + onCharacterClassEnter(ccNode) { + characterClassNodes.push(ccNode); + } + }); + + const spacesPattern = /( {2,})(?: [+*{?]|[^+*{?]|$)/gu; + let match; + + while ((match = spacesPattern.exec(pattern))) { + const { 1: { length }, index } = match; + + // Report only consecutive spaces that are not in character classes. + if ( + characterClassNodes.every(({ start, end }) => index < start || end <= index) + ) { + context.report({ + node: nodeToReport, + messageId: "multipleSpaces", + data: { length }, + fix(fixer) { + if (pattern !== rawPattern) { + return null; + } + return fixer.replaceTextRange( + [rawPatternStartRange + index, rawPatternStartRange + index + length], + ` {${length}}` + ); + } + }); + + // Report only the first occurrence of consecutive spaces + return; + } + } + } + + /** + * Validate regular expression literals + * @param {ASTNode} node node to validate + * @returns {void} + * @private + */ + function checkLiteral(node) { + if (node.regex) { + const pattern = node.regex.pattern; + const rawPattern = node.raw.slice(1, node.raw.lastIndexOf("/")); + const rawPatternStartRange = node.range[0] + 1; + const flags = node.regex.flags; + + checkRegex( + node, + pattern, + rawPattern, + rawPatternStartRange, + flags + ); + } + } + + /** + * Validate strings passed to the RegExp constructor + * @param {ASTNode} node node to validate + * @returns {void} + * @private + */ + function checkFunction(node) { + const scope = context.getScope(); + const regExpVar = astUtils.getVariableByName(scope, "RegExp"); + const shadowed = regExpVar && regExpVar.defs.length > 0; + const patternNode = node.arguments[0]; + const flagsNode = node.arguments[1]; + + if (node.callee.type === "Identifier" && node.callee.name === "RegExp" && isString(patternNode) && !shadowed) { + const pattern = patternNode.value; + const rawPattern = patternNode.raw.slice(1, -1); + const rawPatternStartRange = patternNode.range[0] + 1; + const flags = isString(flagsNode) ? flagsNode.value : ""; + + checkRegex( + node, + pattern, + rawPattern, + rawPatternStartRange, + flags + ); + } + } + + return { + Literal: checkLiteral, + CallExpression: checkFunction, + NewExpression: checkFunction + }; + } +}; + +/** + * @fileoverview Rule to disallow specified names in exports + * @author Milos Djermanovic + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noRestrictedExports = { + meta: { + type: "suggestion", + + docs: { + description: "disallow specified names in exports", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/no-restricted-exports" + }, + + schema: [{ + type: "object", + properties: { + restrictedNamedExports: { + type: "array", + items: { + type: "string" + }, + uniqueItems: true + } + }, + additionalProperties: false + }], + + messages: { + restrictedNamed: "'{{name}}' is restricted from being used as an exported name." + } + }, + + create(context) { + + const restrictedNames = new Set(context.options[0] && context.options[0].restrictedNamedExports); + + /** + * Checks and reports given exported identifier. + * @param {ASTNode} node exported `Identifier` node to check. + * @returns {void} + */ + function checkExportedName(node) { + const name = node.name; + + if (restrictedNames.has(name)) { + context.report({ + node, + messageId: "restrictedNamed", + data: { name } + }); + } + } + + return { + ExportAllDeclaration(node) { + if (node.exported) { + checkExportedName(node.exported); + } + }, + + ExportNamedDeclaration(node) { + const declaration = node.declaration; + + if (declaration) { + if (declaration.type === "FunctionDeclaration" || declaration.type === "ClassDeclaration") { + checkExportedName(declaration.id); + } else if (declaration.type === "VariableDeclaration") { + context.getDeclaredVariables(declaration) + .map(v => v.defs.find(d => d.parent === declaration)) + .map(d => d.name) // Identifier nodes + .forEach(checkExportedName); + } + } else { + node.specifiers + .map(s => s.exported) + .forEach(checkExportedName); + } + } + }; + } +}; + +/** + * @fileoverview Restrict usage of specified globals. + * @author Benoît Zugmeyer + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noRestrictedGlobals = { + meta: { + type: "suggestion", + + docs: { + description: "disallow specified global variables", + category: "Variables", + recommended: false, + url: "https://eslint.org/docs/rules/no-restricted-globals" + }, + + schema: { + type: "array", + items: { + oneOf: [ + { + type: "string" + }, + { + type: "object", + properties: { + name: { type: "string" }, + message: { type: "string" } + }, + required: ["name"], + additionalProperties: false + } + ] + }, + uniqueItems: true, + minItems: 0 + }, + + messages: { + defaultMessage: "Unexpected use of '{{name}}'.", + // eslint-disable-next-line eslint-plugin/report-message-format + customMessage: "Unexpected use of '{{name}}'. {{customMessage}}" + } + }, + + create(context) { + + // If no globals are restricted, we don't need to do anything + if (context.options.length === 0) { + return {}; + } + + const restrictedGlobalMessages = context.options.reduce((memo, option) => { + if (typeof option === "string") { + memo[option] = null; + } else { + memo[option.name] = option.message; + } + + return memo; + }, {}); + + /** + * Report a variable to be used as a restricted global. + * @param {Reference} reference the variable reference + * @returns {void} + * @private + */ + function reportReference(reference) { + const name = reference.identifier.name, + customMessage = restrictedGlobalMessages[name], + messageId = customMessage + ? "customMessage" + : "defaultMessage"; + + context.report({ + node: reference.identifier, + messageId, + data: { + name, + customMessage + } + }); + } + + /** + * Check if the given name is a restricted global name. + * @param {string} name name of a variable + * @returns {boolean} whether the variable is a restricted global or not + * @private + */ + function isRestricted(name) { + return Object.prototype.hasOwnProperty.call(restrictedGlobalMessages, name); + } + + return { + Program() { + const scope = context.getScope(); + + // Report variables declared elsewhere (ex: variables defined as "global" by eslint) + scope.variables.forEach(variable => { + if (!variable.defs.length && isRestricted(variable.name)) { + variable.references.forEach(reportReference); + } + }); + + // Report variables not declared at all + scope.through.forEach(reference => { + if (isRestricted(reference.identifier.name)) { + reportReference(reference); + } + }); + + } + }; + } +}; + +/** + * @fileoverview Restrict usage of specified node imports. + * @author Guy Ellis + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + + + +const arrayOfStrings$1 = { + type: "array", + items: { type: "string" }, + uniqueItems: true +}; + +const arrayOfStringsOrObjects$1 = { + type: "array", + items: { + anyOf: [ + { type: "string" }, + { + type: "object", + properties: { + name: { type: "string" }, + message: { + type: "string", + minLength: 1 + }, + importNames: { + type: "array", + items: { + type: "string" + } + } + }, + additionalProperties: false, + required: ["name"] + } + ] + }, + uniqueItems: true +}; + +var noRestrictedImports = { + meta: { + type: "suggestion", + + docs: { + description: "disallow specified modules when loaded by `import`", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/no-restricted-imports" + }, + + messages: { + path: "'{{importSource}}' import is restricted from being used.", + // eslint-disable-next-line eslint-plugin/report-message-format + pathWithCustomMessage: "'{{importSource}}' import is restricted from being used. {{customMessage}}", + + patterns: "'{{importSource}}' import is restricted from being used by a pattern.", + + everything: "* import is invalid because '{{importNames}}' from '{{importSource}}' is restricted.", + // eslint-disable-next-line eslint-plugin/report-message-format + everythingWithCustomMessage: "* import is invalid because '{{importNames}}' from '{{importSource}}' is restricted. {{customMessage}}", + + importName: "'{{importName}}' import from '{{importSource}}' is restricted.", + // eslint-disable-next-line eslint-plugin/report-message-format + importNameWithCustomMessage: "'{{importName}}' import from '{{importSource}}' is restricted. {{customMessage}}" + }, + + schema: { + anyOf: [ + arrayOfStringsOrObjects$1, + { + type: "array", + items: [{ + type: "object", + properties: { + paths: arrayOfStringsOrObjects$1, + patterns: arrayOfStrings$1 + }, + additionalProperties: false + }], + additionalItems: false + } + ] + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const options = Array.isArray(context.options) ? context.options : []; + const isPathAndPatternsObject = + typeof options[0] === "object" && + (Object.prototype.hasOwnProperty.call(options[0], "paths") || Object.prototype.hasOwnProperty.call(options[0], "patterns")); + + const restrictedPaths = (isPathAndPatternsObject ? options[0].paths : context.options) || []; + const restrictedPatterns = (isPathAndPatternsObject ? options[0].patterns : []) || []; + + // if no imports are restricted we don"t need to check + if (Object.keys(restrictedPaths).length === 0 && restrictedPatterns.length === 0) { + return {}; + } + + const restrictedPathMessages = restrictedPaths.reduce((memo, importSource) => { + if (typeof importSource === "string") { + memo[importSource] = { message: null }; + } else { + memo[importSource.name] = { + message: importSource.message, + importNames: importSource.importNames + }; + } + return memo; + }, {}); + + const restrictedPatternsMatcher = ignore__default['default']().add(restrictedPatterns); + + /** + * Report a restricted path. + * @param {string} importSource path of the import + * @param {Map} importNames Map of import names that are being imported + * @param {node} node representing the restricted path reference + * @returns {void} + * @private + */ + function checkRestrictedPathAndReport(importSource, importNames, node) { + if (!Object.prototype.hasOwnProperty.call(restrictedPathMessages, importSource)) { + return; + } + + const customMessage = restrictedPathMessages[importSource].message; + const restrictedImportNames = restrictedPathMessages[importSource].importNames; + + if (restrictedImportNames) { + if (importNames.has("*")) { + const specifierData = importNames.get("*")[0]; + + context.report({ + node, + messageId: customMessage ? "everythingWithCustomMessage" : "everything", + loc: specifierData.loc, + data: { + importSource, + importNames: restrictedImportNames, + customMessage + } + }); + } + + restrictedImportNames.forEach(importName => { + if (importNames.has(importName)) { + const specifiers = importNames.get(importName); + + specifiers.forEach(specifier => { + context.report({ + node, + messageId: customMessage ? "importNameWithCustomMessage" : "importName", + loc: specifier.loc, + data: { + importSource, + customMessage, + importName + } + }); + }); + } + }); + } else { + context.report({ + node, + messageId: customMessage ? "pathWithCustomMessage" : "path", + data: { + importSource, + customMessage + } + }); + } + } + + /** + * Report a restricted path specifically for patterns. + * @param {node} node representing the restricted path reference + * @returns {void} + * @private + */ + function reportPathForPatterns(node) { + const importSource = node.source.value.trim(); + + context.report({ + node, + messageId: "patterns", + data: { + importSource + } + }); + } + + /** + * Check if the given importSource is restricted by a pattern. + * @param {string} importSource path of the import + * @returns {boolean} whether the variable is a restricted pattern or not + * @private + */ + function isRestrictedPattern(importSource) { + return restrictedPatterns.length > 0 && restrictedPatternsMatcher.ignores(importSource); + } + + /** + * Checks a node to see if any problems should be reported. + * @param {ASTNode} node The node to check. + * @returns {void} + * @private + */ + function checkNode(node) { + const importSource = node.source.value.trim(); + const importNames = new Map(); + + if (node.type === "ExportAllDeclaration") { + const starToken = sourceCode.getFirstToken(node, 1); + + importNames.set("*", [{ loc: starToken.loc }]); + } else if (node.specifiers) { + for (const specifier of node.specifiers) { + let name; + const specifierData = { loc: specifier.loc }; + + if (specifier.type === "ImportDefaultSpecifier") { + name = "default"; + } else if (specifier.type === "ImportNamespaceSpecifier") { + name = "*"; + } else if (specifier.imported) { + name = specifier.imported.name; + } else if (specifier.local) { + name = specifier.local.name; + } + + if (name) { + if (importNames.has(name)) { + importNames.get(name).push(specifierData); + } else { + importNames.set(name, [specifierData]); + } + } + } + } + + checkRestrictedPathAndReport(importSource, importNames, node); + + if (isRestrictedPattern(importSource)) { + reportPathForPatterns(node); + } + } + + return { + ImportDeclaration: checkNode, + ExportNamedDeclaration(node) { + if (node.source) { + checkNode(node); + } + }, + ExportAllDeclaration: checkNode + }; + } +}; + +/** + * @fileoverview Restrict usage of specified node modules. + * @author Christian Schulz + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + + + +const arrayOfStrings = { + type: "array", + items: { type: "string" }, + uniqueItems: true +}; + +const arrayOfStringsOrObjects = { + type: "array", + items: { + anyOf: [ + { type: "string" }, + { + type: "object", + properties: { + name: { type: "string" }, + message: { + type: "string", + minLength: 1 + } + }, + additionalProperties: false, + required: ["name"] + } + ] + }, + uniqueItems: true +}; + +var noRestrictedModules = { + meta: { + deprecated: true, + + replacedBy: [], + + type: "suggestion", + + docs: { + description: "disallow specified modules when loaded by `require`", + category: "Node.js and CommonJS", + recommended: false, + url: "https://eslint.org/docs/rules/no-restricted-modules" + }, + + schema: { + anyOf: [ + arrayOfStringsOrObjects, + { + type: "array", + items: { + type: "object", + properties: { + paths: arrayOfStringsOrObjects, + patterns: arrayOfStrings + }, + additionalProperties: false + }, + additionalItems: false + } + ] + }, + + messages: { + defaultMessage: "'{{name}}' module is restricted from being used.", + // eslint-disable-next-line eslint-plugin/report-message-format + customMessage: "'{{name}}' module is restricted from being used. {{customMessage}}", + patternMessage: "'{{name}}' module is restricted from being used by a pattern." + } + }, + + create(context) { + const options = Array.isArray(context.options) ? context.options : []; + const isPathAndPatternsObject = + typeof options[0] === "object" && + (Object.prototype.hasOwnProperty.call(options[0], "paths") || Object.prototype.hasOwnProperty.call(options[0], "patterns")); + + const restrictedPaths = (isPathAndPatternsObject ? options[0].paths : context.options) || []; + const restrictedPatterns = (isPathAndPatternsObject ? options[0].patterns : []) || []; + + const restrictedPathMessages = restrictedPaths.reduce((memo, importName) => { + if (typeof importName === "string") { + memo[importName] = null; + } else { + memo[importName.name] = importName.message; + } + return memo; + }, {}); + + // if no imports are restricted we don"t need to check + if (Object.keys(restrictedPaths).length === 0 && restrictedPatterns.length === 0) { + return {}; + } + + const ig = ignore__default['default']().add(restrictedPatterns); + + + /** + * Function to check if a node is a string literal. + * @param {ASTNode} node The node to check. + * @returns {boolean} If the node is a string literal. + */ + function isStringLiteral(node) { + return node && node.type === "Literal" && typeof node.value === "string"; + } + + /** + * Function to check if a node is a static string template literal. + * @param {ASTNode} node The node to check. + * @returns {boolean} If the node is a string template literal. + */ + function isStaticTemplateLiteral(node) { + return node && node.type === "TemplateLiteral" && node.expressions.length === 0; + } + + /** + * Function to check if a node is a require call. + * @param {ASTNode} node The node to check. + * @returns {boolean} If the node is a require call. + */ + function isRequireCall(node) { + return node.callee.type === "Identifier" && node.callee.name === "require"; + } + + /** + * Extract string from Literal or TemplateLiteral node + * @param {ASTNode} node The node to extract from + * @returns {string|null} Extracted string or null if node doesn't represent a string + */ + function getFirstArgumentString(node) { + if (isStringLiteral(node)) { + return node.value.trim(); + } + + if (isStaticTemplateLiteral(node)) { + return node.quasis[0].value.cooked.trim(); + } + + return null; + } + + /** + * Report a restricted path. + * @param {node} node representing the restricted path reference + * @param {string} name restricted path + * @returns {void} + * @private + */ + function reportPath(node, name) { + const customMessage = restrictedPathMessages[name]; + const messageId = customMessage + ? "customMessage" + : "defaultMessage"; + + context.report({ + node, + messageId, + data: { + name, + customMessage + } + }); + } + + /** + * Check if the given name is a restricted path name + * @param {string} name name of a variable + * @returns {boolean} whether the variable is a restricted path or not + * @private + */ + function isRestrictedPath(name) { + return Object.prototype.hasOwnProperty.call(restrictedPathMessages, name); + } + + return { + CallExpression(node) { + if (isRequireCall(node)) { + + // node has arguments + if (node.arguments.length) { + const name = getFirstArgumentString(node.arguments[0]); + + // if first argument is a string literal or a static string template literal + if (name) { + + // check if argument value is in restricted modules array + if (isRestrictedPath(name)) { + reportPath(node, name); + } + + if (restrictedPatterns.length > 0 && ig.ignores(name)) { + context.report({ + node, + messageId: "patternMessage", + data: { name } + }); + } + } + } + } + } + }; + } +}; + +/** + * @fileoverview Rule to disallow certain object properties + * @author Will Klein & Eli White + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noRestrictedProperties = { + meta: { + type: "suggestion", + + docs: { + description: "disallow certain properties on certain objects", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-restricted-properties" + }, + + schema: { + type: "array", + items: { + anyOf: [ // `object` and `property` are both optional, but at least one of them must be provided. + { + type: "object", + properties: { + object: { + type: "string" + }, + property: { + type: "string" + }, + message: { + type: "string" + } + }, + additionalProperties: false, + required: ["object"] + }, + { + type: "object", + properties: { + object: { + type: "string" + }, + property: { + type: "string" + }, + message: { + type: "string" + } + }, + additionalProperties: false, + required: ["property"] + } + ] + }, + uniqueItems: true + }, + + messages: { + // eslint-disable-next-line eslint-plugin/report-message-format + restrictedObjectProperty: "'{{objectName}}.{{propertyName}}' is restricted from being used.{{message}}", + // eslint-disable-next-line eslint-plugin/report-message-format + restrictedProperty: "'{{propertyName}}' is restricted from being used.{{message}}" + } + }, + + create(context) { + const restrictedCalls = context.options; + + if (restrictedCalls.length === 0) { + return {}; + } + + const restrictedProperties = new Map(); + const globallyRestrictedObjects = new Map(); + const globallyRestrictedProperties = new Map(); + + restrictedCalls.forEach(option => { + const objectName = option.object; + const propertyName = option.property; + + if (typeof objectName === "undefined") { + globallyRestrictedProperties.set(propertyName, { message: option.message }); + } else if (typeof propertyName === "undefined") { + globallyRestrictedObjects.set(objectName, { message: option.message }); + } else { + if (!restrictedProperties.has(objectName)) { + restrictedProperties.set(objectName, new Map()); + } + + restrictedProperties.get(objectName).set(propertyName, { + message: option.message + }); + } + }); + + /** + * Checks to see whether a property access is restricted, and reports it if so. + * @param {ASTNode} node The node to report + * @param {string} objectName The name of the object + * @param {string} propertyName The name of the property + * @returns {undefined} + */ + function checkPropertyAccess(node, objectName, propertyName) { + if (propertyName === null) { + return; + } + const matchedObject = restrictedProperties.get(objectName); + const matchedObjectProperty = matchedObject ? matchedObject.get(propertyName) : globallyRestrictedObjects.get(objectName); + const globalMatchedProperty = globallyRestrictedProperties.get(propertyName); + + if (matchedObjectProperty) { + const message = matchedObjectProperty.message ? ` ${matchedObjectProperty.message}` : ""; + + context.report({ + node, + messageId: "restrictedObjectProperty", + data: { + objectName, + propertyName, + message + } + }); + } else if (globalMatchedProperty) { + const message = globalMatchedProperty.message ? ` ${globalMatchedProperty.message}` : ""; + + context.report({ + node, + messageId: "restrictedProperty", + data: { + propertyName, + message + } + }); + } + } + + /** + * Checks property accesses in a destructuring assignment expression, e.g. `var foo; ({foo} = bar);` + * @param {ASTNode} node An AssignmentExpression or AssignmentPattern node + * @returns {undefined} + */ + function checkDestructuringAssignment(node) { + if (node.right.type === "Identifier") { + const objectName = node.right.name; + + if (node.left.type === "ObjectPattern") { + node.left.properties.forEach(property => { + checkPropertyAccess(node.left, objectName, astUtils.getStaticPropertyName(property)); + }); + } + } + } + + return { + MemberExpression(node) { + checkPropertyAccess(node, node.object && node.object.name, astUtils.getStaticPropertyName(node)); + }, + VariableDeclarator(node) { + if (node.init && node.init.type === "Identifier") { + const objectName = node.init.name; + + if (node.id.type === "ObjectPattern") { + node.id.properties.forEach(property => { + checkPropertyAccess(node.id, objectName, astUtils.getStaticPropertyName(property)); + }); + } + } + }, + AssignmentExpression: checkDestructuringAssignment, + AssignmentPattern: checkDestructuringAssignment + }; + } +}; + +/** + * @fileoverview Rule to flag use of certain node types + * @author Burak Yigit Kaya + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noRestrictedSyntax = { + meta: { + type: "suggestion", + + docs: { + description: "disallow specified syntax", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-restricted-syntax" + }, + + schema: { + type: "array", + items: { + oneOf: [ + { + type: "string" + }, + { + type: "object", + properties: { + selector: { type: "string" }, + message: { type: "string" } + }, + required: ["selector"], + additionalProperties: false + } + ] + }, + uniqueItems: true, + minItems: 0 + }, + + messages: { + // eslint-disable-next-line eslint-plugin/report-message-format + restrictedSyntax: "{{message}}" + } + }, + + create(context) { + return context.options.reduce((result, selectorOrObject) => { + const isStringFormat = (typeof selectorOrObject === "string"); + const hasCustomMessage = !isStringFormat && Boolean(selectorOrObject.message); + + const selector = isStringFormat ? selectorOrObject : selectorOrObject.selector; + const message = hasCustomMessage ? selectorOrObject.message : `Using '${selector}' is not allowed.`; + + return Object.assign(result, { + [selector](node) { + context.report({ + node, + messageId: "restrictedSyntax", + data: { message } + }); + } + }); + }, {}); + + } +}; + +/** + * @fileoverview Rule to flag when return statement contains assignment + * @author Ilya Volodin + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const SENTINEL_TYPE$1 = /^(?:[a-zA-Z]+?Statement|ArrowFunctionExpression|FunctionExpression|ClassExpression)$/u; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noReturnAssign = { + meta: { + type: "suggestion", + + docs: { + description: "disallow assignment operators in `return` statements", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-return-assign" + }, + + schema: [ + { + enum: ["except-parens", "always"] + } + ], + + messages: { + returnAssignment: "Return statement should not contain assignment.", + arrowAssignment: "Arrow function should not return assignment." + } + }, + + create(context) { + const always = (context.options[0] || "except-parens") !== "except-parens"; + const sourceCode = context.getSourceCode(); + + return { + AssignmentExpression(node) { + if (!always && astUtils.isParenthesised(sourceCode, node)) { + return; + } + + let currentChild = node; + let parent = currentChild.parent; + + // Find ReturnStatement or ArrowFunctionExpression in ancestors. + while (parent && !SENTINEL_TYPE$1.test(parent.type)) { + currentChild = parent; + parent = parent.parent; + } + + // Reports. + if (parent && parent.type === "ReturnStatement") { + context.report({ + node: parent, + messageId: "returnAssignment" + }); + } else if (parent && parent.type === "ArrowFunctionExpression" && parent.body === currentChild) { + context.report({ + node: parent, + messageId: "arrowAssignment" + }); + } + } + }; + } +}; + +/** + * @fileoverview Disallows unnecessary `return await` + * @author Jordan Harband + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noReturnAwait = { + meta: { + type: "suggestion", + + docs: { + description: "disallow unnecessary `return await`", + category: "Best Practices", + + recommended: false, + + url: "https://eslint.org/docs/rules/no-return-await" + }, + + fixable: null, + + schema: [ + ], + + messages: { + redundantUseOfAwait: "Redundant use of `await` on a return value." + } + }, + + create(context) { + + /** + * Reports a found unnecessary `await` expression. + * @param {ASTNode} node The node representing the `await` expression to report + * @returns {void} + */ + function reportUnnecessaryAwait(node) { + context.report({ + node: context.getSourceCode().getFirstToken(node), + loc: node.loc, + messageId: "redundantUseOfAwait" + }); + } + + /** + * Determines whether a thrown error from this node will be caught/handled within this function rather than immediately halting + * this function. For example, a statement in a `try` block will always have an error handler. A statement in + * a `catch` block will only have an error handler if there is also a `finally` block. + * @param {ASTNode} node A node representing a location where an could be thrown + * @returns {boolean} `true` if a thrown error will be caught/handled in this function + */ + function hasErrorHandler(node) { + let ancestor = node; + + while (!astUtils.isFunction(ancestor) && ancestor.type !== "Program") { + if (ancestor.parent.type === "TryStatement" && (ancestor === ancestor.parent.block || ancestor === ancestor.parent.handler && ancestor.parent.finalizer)) { + return true; + } + ancestor = ancestor.parent; + } + return false; + } + + /** + * Checks if a node is placed in tail call position. Once `return` arguments (or arrow function expressions) can be a complex expression, + * an `await` expression could or could not be unnecessary by the definition of this rule. So we're looking for `await` expressions that are in tail position. + * @param {ASTNode} node A node representing the `await` expression to check + * @returns {boolean} The checking result + */ + function isInTailCallPosition(node) { + if (node.parent.type === "ArrowFunctionExpression") { + return true; + } + if (node.parent.type === "ReturnStatement") { + return !hasErrorHandler(node.parent); + } + if (node.parent.type === "ConditionalExpression" && (node === node.parent.consequent || node === node.parent.alternate)) { + return isInTailCallPosition(node.parent); + } + if (node.parent.type === "LogicalExpression" && node === node.parent.right) { + return isInTailCallPosition(node.parent); + } + if (node.parent.type === "SequenceExpression" && node === node.parent.expressions[node.parent.expressions.length - 1]) { + return isInTailCallPosition(node.parent); + } + return false; + } + + return { + AwaitExpression(node) { + if (isInTailCallPosition(node) && !hasErrorHandler(node)) { + reportUnnecessaryAwait(node); + } + } + }; + } +}; + +/** + * @fileoverview Rule to flag when using javascript: urls + * @author Ilya Volodin + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noScriptUrl = { + meta: { + type: "suggestion", + + docs: { + description: "disallow `javascript:` urls", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-script-url" + }, + + schema: [], + + messages: { + unexpectedScriptURL: "Script URL is a form of eval." + } + }, + + create(context) { + + /** + * Check whether a node's static value starts with "javascript:" or not. + * And report an error for unexpected script URL. + * @param {ASTNode} node node to check + * @returns {void} + */ + function check(node) { + const value = astUtils.getStaticStringValue(node); + + if (typeof value === "string" && value.toLowerCase().indexOf("javascript:") === 0) { + context.report({ node, messageId: "unexpectedScriptURL" }); + } + } + return { + Literal(node) { + if (node.value && typeof node.value === "string") { + check(node); + } + }, + TemplateLiteral(node) { + if (!(node.parent && node.parent.type === "TaggedTemplateExpression")) { + check(node); + } + } + }; + } +}; + +/** + * @fileoverview Rule to disallow assignments where both sides are exactly the same + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const SPACES = /\s+/gu; + +/** + * Traverses 2 Pattern nodes in parallel, then reports self-assignments. + * @param {ASTNode|null} left A left node to traverse. This is a Pattern or + * a Property. + * @param {ASTNode|null} right A right node to traverse. This is a Pattern or + * a Property. + * @param {boolean} props The flag to check member expressions as well. + * @param {Function} report A callback function to report. + * @returns {void} + */ +function eachSelfAssignment(left, right, props, report) { + if (!left || !right) ; else if ( + left.type === "Identifier" && + right.type === "Identifier" && + left.name === right.name + ) { + report(right); + } else if ( + left.type === "ArrayPattern" && + right.type === "ArrayExpression" + ) { + const end = Math.min(left.elements.length, right.elements.length); + + for (let i = 0; i < end; ++i) { + const leftElement = left.elements[i]; + const rightElement = right.elements[i]; + + // Avoid cases such as [...a] = [...a, 1] + if ( + leftElement && + leftElement.type === "RestElement" && + i < right.elements.length - 1 + ) { + break; + } + + eachSelfAssignment(leftElement, rightElement, props, report); + + // After a spread element, those indices are unknown. + if (rightElement && rightElement.type === "SpreadElement") { + break; + } + } + } else if ( + left.type === "RestElement" && + right.type === "SpreadElement" + ) { + eachSelfAssignment(left.argument, right.argument, props, report); + } else if ( + left.type === "ObjectPattern" && + right.type === "ObjectExpression" && + right.properties.length >= 1 + ) { + + /* + * Gets the index of the last spread property. + * It's possible to overwrite properties followed by it. + */ + let startJ = 0; + + for (let i = right.properties.length - 1; i >= 0; --i) { + const propType = right.properties[i].type; + + if (propType === "SpreadElement" || propType === "ExperimentalSpreadProperty") { + startJ = i + 1; + break; + } + } + + for (let i = 0; i < left.properties.length; ++i) { + for (let j = startJ; j < right.properties.length; ++j) { + eachSelfAssignment( + left.properties[i], + right.properties[j], + props, + report + ); + } + } + } else if ( + left.type === "Property" && + right.type === "Property" && + right.kind === "init" && + !right.method + ) { + const leftName = astUtils.getStaticPropertyName(left); + + if (leftName !== null && leftName === astUtils.getStaticPropertyName(right)) { + eachSelfAssignment(left.value, right.value, props, report); + } + } else if ( + props && + astUtils.skipChainExpression(left).type === "MemberExpression" && + astUtils.skipChainExpression(right).type === "MemberExpression" && + astUtils.isSameReference(left, right) + ) { + report(right); + } +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noSelfAssign = { + meta: { + type: "problem", + + docs: { + description: "disallow assignments where both sides are exactly the same", + category: "Best Practices", + recommended: true, + url: "https://eslint.org/docs/rules/no-self-assign" + }, + + schema: [ + { + type: "object", + properties: { + props: { + type: "boolean", + default: true + } + }, + additionalProperties: false + } + ], + + messages: { + selfAssignment: "'{{name}}' is assigned to itself." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const [{ props = true } = {}] = context.options; + + /** + * Reports a given node as self assignments. + * @param {ASTNode} node A node to report. This is an Identifier node. + * @returns {void} + */ + function report(node) { + context.report({ + node, + messageId: "selfAssignment", + data: { + name: sourceCode.getText(node).replace(SPACES, "") + } + }); + } + + return { + AssignmentExpression(node) { + if (node.operator === "=") { + eachSelfAssignment(node.left, node.right, props, report); + } + } + }; + } +}; + +/** + * @fileoverview Rule to flag comparison where left part is the same as the right + * part. + * @author Ilya Volodin + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noSelfCompare = { + meta: { + type: "problem", + + docs: { + description: "disallow comparisons where both sides are exactly the same", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-self-compare" + }, + + schema: [], + + messages: { + comparingToSelf: "Comparing to itself is potentially pointless." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + /** + * Determines whether two nodes are composed of the same tokens. + * @param {ASTNode} nodeA The first node + * @param {ASTNode} nodeB The second node + * @returns {boolean} true if the nodes have identical token representations + */ + function hasSameTokens(nodeA, nodeB) { + const tokensA = sourceCode.getTokens(nodeA); + const tokensB = sourceCode.getTokens(nodeB); + + return tokensA.length === tokensB.length && + tokensA.every((token, index) => token.type === tokensB[index].type && token.value === tokensB[index].value); + } + + return { + + BinaryExpression(node) { + const operators = new Set(["===", "==", "!==", "!=", ">", "<", ">=", "<="]); + + if (operators.has(node.operator) && hasSameTokens(node.left, node.right)) { + context.report({ node, messageId: "comparingToSelf" }); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag use of comma operator + * @author Brandon Mills + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const DEFAULT_OPTIONS = { + allowInParentheses: true +}; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noSequences = { + meta: { + type: "suggestion", + + docs: { + description: "disallow comma operators", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-sequences" + }, + + schema: [{ + properties: { + allowInParentheses: { + type: "boolean", + default: true + } + }, + additionalProperties: false + }], + + messages: { + unexpectedCommaExpression: "Unexpected use of comma operator." + } + }, + + create(context) { + const options = Object.assign({}, DEFAULT_OPTIONS, context.options[0]); + const sourceCode = context.getSourceCode(); + + /** + * Parts of the grammar that are required to have parens. + */ + const parenthesized = { + DoWhileStatement: "test", + IfStatement: "test", + SwitchStatement: "discriminant", + WhileStatement: "test", + WithStatement: "object", + ArrowFunctionExpression: "body" + + /* + * Omitting CallExpression - commas are parsed as argument separators + * Omitting NewExpression - commas are parsed as argument separators + * Omitting ForInStatement - parts aren't individually parenthesised + * Omitting ForStatement - parts aren't individually parenthesised + */ + }; + + /** + * Determines whether a node is required by the grammar to be wrapped in + * parens, e.g. the test of an if statement. + * @param {ASTNode} node The AST node + * @returns {boolean} True if parens around node belong to parent node. + */ + function requiresExtraParens(node) { + return node.parent && parenthesized[node.parent.type] && + node === node.parent[parenthesized[node.parent.type]]; + } + + /** + * Check if a node is wrapped in parens. + * @param {ASTNode} node The AST node + * @returns {boolean} True if the node has a paren on each side. + */ + function isParenthesised(node) { + return astUtils.isParenthesised(sourceCode, node); + } + + /** + * Check if a node is wrapped in two levels of parens. + * @param {ASTNode} node The AST node + * @returns {boolean} True if two parens surround the node on each side. + */ + function isParenthesisedTwice(node) { + const previousToken = sourceCode.getTokenBefore(node, 1), + nextToken = sourceCode.getTokenAfter(node, 1); + + return isParenthesised(node) && previousToken && nextToken && + astUtils.isOpeningParenToken(previousToken) && previousToken.range[1] <= node.range[0] && + astUtils.isClosingParenToken(nextToken) && nextToken.range[0] >= node.range[1]; + } + + return { + SequenceExpression(node) { + + // Always allow sequences in for statement update + if (node.parent.type === "ForStatement" && + (node === node.parent.init || node === node.parent.update)) { + return; + } + + // Wrapping a sequence in extra parens indicates intent + if (options.allowInParentheses) { + if (requiresExtraParens(node)) { + if (isParenthesisedTwice(node)) { + return; + } + } else { + if (isParenthesised(node)) { + return; + } + } + } + + const firstCommaToken = sourceCode.getTokenAfter(node.expressions[0], astUtils.isCommaToken); + + context.report({ node, loc: firstCommaToken.loc, messageId: "unexpectedCommaExpression" }); + } + }; + + } +}; + +/** + * @fileoverview Rule to disallow returning values from setters + * @author Milos Djermanovic + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + +const { findVariable: findVariable$1 } = require$$0__default$1['default']; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Determines whether the given identifier node is a reference to a global variable. + * @param {ASTNode} node `Identifier` node to check. + * @param {Scope} scope Scope to which the node belongs. + * @returns {boolean} True if the identifier is a reference to a global variable. + */ +function isGlobalReference(node, scope) { + const variable = findVariable$1(scope, node); + + return variable !== null && variable.scope.type === "global" && variable.defs.length === 0; +} + +/** + * Determines whether the given node is an argument of the specified global method call, at the given `index` position. + * E.g., for given `index === 1`, this function checks for `objectName.methodName(foo, node)`, where objectName is a global variable. + * @param {ASTNode} node The node to check. + * @param {Scope} scope Scope to which the node belongs. + * @param {string} objectName Name of the global object. + * @param {string} methodName Name of the method. + * @param {number} index The given position. + * @returns {boolean} `true` if the node is argument at the given position. + */ +function isArgumentOfGlobalMethodCall(node, scope, objectName, methodName, index) { + const callNode = node.parent; + + return callNode.type === "CallExpression" && + callNode.arguments[index] === node && + astUtils.isSpecificMemberAccess(callNode.callee, objectName, methodName) && + isGlobalReference(astUtils.skipChainExpression(callNode.callee).object, scope); +} + +/** + * Determines whether the given node is used as a property descriptor. + * @param {ASTNode} node The node to check. + * @param {Scope} scope Scope to which the node belongs. + * @returns {boolean} `true` if the node is a property descriptor. + */ +function isPropertyDescriptor(node, scope) { + if ( + isArgumentOfGlobalMethodCall(node, scope, "Object", "defineProperty", 2) || + isArgumentOfGlobalMethodCall(node, scope, "Reflect", "defineProperty", 2) + ) { + return true; + } + + const parent = node.parent; + + if ( + parent.type === "Property" && + parent.value === node + ) { + const grandparent = parent.parent; + + if ( + grandparent.type === "ObjectExpression" && + ( + isArgumentOfGlobalMethodCall(grandparent, scope, "Object", "create", 1) || + isArgumentOfGlobalMethodCall(grandparent, scope, "Object", "defineProperties", 1) + ) + ) { + return true; + } + } + + return false; +} + +/** + * Determines whether the given function node is used as a setter function. + * @param {ASTNode} node The node to check. + * @param {Scope} scope Scope to which the node belongs. + * @returns {boolean} `true` if the node is a setter. + */ +function isSetter(node, scope) { + const parent = node.parent; + + if ( + parent.kind === "set" && + parent.value === node + ) { + + // Setter in an object literal or in a class + return true; + } + + if ( + parent.type === "Property" && + parent.value === node && + astUtils.getStaticPropertyName(parent) === "set" && + parent.parent.type === "ObjectExpression" && + isPropertyDescriptor(parent.parent, scope) + ) { + + // Setter in a property descriptor + return true; + } + + return false; +} + +/** + * Finds function's outer scope. + * @param {Scope} scope Function's own scope. + * @returns {Scope} Function's outer scope. + */ +function getOuterScope(scope) { + const upper = scope.upper; + + if (upper.type === "function-expression-name") { + return upper.upper; + } + + return upper; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noSetterReturn = { + meta: { + type: "problem", + + docs: { + description: "disallow returning values from setters", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-setter-return" + }, + + schema: [], + + messages: { + returnsValue: "Setter cannot return a value." + } + }, + + create(context) { + let funcInfo = null; + + /** + * Creates and pushes to the stack a function info object for the given function node. + * @param {ASTNode} node The function node. + * @returns {void} + */ + function enterFunction(node) { + const outerScope = getOuterScope(context.getScope()); + + funcInfo = { + upper: funcInfo, + isSetter: isSetter(node, outerScope) + }; + } + + /** + * Pops the current function info object from the stack. + * @returns {void} + */ + function exitFunction() { + funcInfo = funcInfo.upper; + } + + /** + * Reports the given node. + * @param {ASTNode} node Node to report. + * @returns {void} + */ + function report(node) { + context.report({ node, messageId: "returnsValue" }); + } + + return { + + /* + * Function declarations cannot be setters, but we still have to track them in the `funcInfo` stack to avoid + * false positives, because a ReturnStatement node can belong to a function declaration inside a setter. + * + * Note: A previously declared function can be referenced and actually used as a setter in a property descriptor, + * but that's out of scope for this rule. + */ + FunctionDeclaration: enterFunction, + FunctionExpression: enterFunction, + ArrowFunctionExpression(node) { + enterFunction(node); + + if (funcInfo.isSetter && node.expression) { + + // { set: foo => bar } property descriptor. Report implicit return 'bar' as the equivalent for a return statement. + report(node.body); + } + }, + + "FunctionDeclaration:exit": exitFunction, + "FunctionExpression:exit": exitFunction, + "ArrowFunctionExpression:exit": exitFunction, + + ReturnStatement(node) { + + // Global returns (e.g., at the top level of a Node module) don't have `funcInfo`. + if (funcInfo && funcInfo.isSetter && node.argument) { + report(node); + } + } + }; + } +}; + +/** + * @fileoverview Rule to flag on declaring variables already declared in the outer scope + * @author Ilya Volodin + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noShadow = { + meta: { + type: "suggestion", + + docs: { + description: "disallow variable declarations from shadowing variables declared in the outer scope", + category: "Variables", + recommended: false, + url: "https://eslint.org/docs/rules/no-shadow" + }, + + schema: [ + { + type: "object", + properties: { + builtinGlobals: { type: "boolean", default: false }, + hoist: { enum: ["all", "functions", "never"], default: "functions" }, + allow: { + type: "array", + items: { + type: "string" + } + } + }, + additionalProperties: false + } + ], + + messages: { + noShadow: "'{{name}}' is already declared in the upper scope on line {{shadowedLine}} column {{shadowedColumn}}.", + noShadowGlobal: "'{{name}}' is already a global variable." + } + }, + + create(context) { + + const options = { + builtinGlobals: context.options[0] && context.options[0].builtinGlobals, + hoist: (context.options[0] && context.options[0].hoist) || "functions", + allow: (context.options[0] && context.options[0].allow) || [] + }; + + /** + * Check if variable name is allowed. + * @param {ASTNode} variable The variable to check. + * @returns {boolean} Whether or not the variable name is allowed. + */ + function isAllowed(variable) { + return options.allow.indexOf(variable.name) !== -1; + } + + /** + * Checks if a variable of the class name in the class scope of ClassDeclaration. + * + * ClassDeclaration creates two variables of its name into its outer scope and its class scope. + * So we should ignore the variable in the class scope. + * @param {Object} variable The variable to check. + * @returns {boolean} Whether or not the variable of the class name in the class scope of ClassDeclaration. + */ + function isDuplicatedClassNameVariable(variable) { + const block = variable.scope.block; + + return block.type === "ClassDeclaration" && block.id === variable.identifiers[0]; + } + + /** + * Checks if a variable is inside the initializer of scopeVar. + * + * To avoid reporting at declarations such as `var a = function a() {};`. + * But it should report `var a = function(a) {};` or `var a = function() { function a() {} };`. + * @param {Object} variable The variable to check. + * @param {Object} scopeVar The scope variable to look for. + * @returns {boolean} Whether or not the variable is inside initializer of scopeVar. + */ + function isOnInitializer(variable, scopeVar) { + const outerScope = scopeVar.scope; + const outerDef = scopeVar.defs[0]; + const outer = outerDef && outerDef.parent && outerDef.parent.range; + const innerScope = variable.scope; + const innerDef = variable.defs[0]; + const inner = innerDef && innerDef.name.range; + + return ( + outer && + inner && + outer[0] < inner[0] && + inner[1] < outer[1] && + ((innerDef.type === "FunctionName" && innerDef.node.type === "FunctionExpression") || innerDef.node.type === "ClassExpression") && + outerScope === innerScope.upper + ); + } + + /** + * Get a range of a variable's identifier node. + * @param {Object} variable The variable to get. + * @returns {Array|undefined} The range of the variable's identifier node. + */ + function getNameRange(variable) { + const def = variable.defs[0]; + + return def && def.name.range; + } + + /** + * Get declared line and column of a variable. + * @param {eslint-scope.Variable} variable The variable to get. + * @returns {Object} The declared line and column of the variable. + */ + function getDeclaredLocation(variable) { + const identifier = variable.identifiers[0]; + let obj; + + if (identifier) { + obj = { + global: false, + line: identifier.loc.start.line, + column: identifier.loc.start.column + 1 + }; + } else { + obj = { + global: true + }; + } + return obj; + } + + /** + * Checks if a variable is in TDZ of scopeVar. + * @param {Object} variable The variable to check. + * @param {Object} scopeVar The variable of TDZ. + * @returns {boolean} Whether or not the variable is in TDZ of scopeVar. + */ + function isInTdz(variable, scopeVar) { + const outerDef = scopeVar.defs[0]; + const inner = getNameRange(variable); + const outer = getNameRange(scopeVar); + + return ( + inner && + outer && + inner[1] < outer[0] && + + // Excepts FunctionDeclaration if is {"hoist":"function"}. + (options.hoist !== "functions" || !outerDef || outerDef.node.type !== "FunctionDeclaration") + ); + } + + /** + * Checks the current context for shadowed variables. + * @param {Scope} scope Fixme + * @returns {void} + */ + function checkForShadows(scope) { + const variables = scope.variables; + + for (let i = 0; i < variables.length; ++i) { + const variable = variables[i]; + + // Skips "arguments" or variables of a class name in the class scope of ClassDeclaration. + if (variable.identifiers.length === 0 || + isDuplicatedClassNameVariable(variable) || + isAllowed(variable) + ) { + continue; + } + + // Gets shadowed variable. + const shadowed = astUtils.getVariableByName(scope.upper, variable.name); + + if (shadowed && + (shadowed.identifiers.length > 0 || (options.builtinGlobals && "writeable" in shadowed)) && + !isOnInitializer(variable, shadowed) && + !(options.hoist !== "all" && isInTdz(variable, shadowed)) + ) { + const location = getDeclaredLocation(shadowed); + const messageId = location.global ? "noShadowGlobal" : "noShadow"; + const data = { name: variable.name }; + + if (!location.global) { + data.shadowedLine = location.line; + data.shadowedColumn = location.column; + } + context.report({ + node: variable.identifiers[0], + messageId, + data + }); + } + } + } + + return { + "Program:exit"() { + const globalScope = context.getScope(); + const stack = globalScope.childScopes.slice(); + + while (stack.length) { + const scope = stack.pop(); + + stack.push(...scope.childScopes); + checkForShadows(scope); + } + } + }; + + } +}; + +/** + * @fileoverview Disallow shadowing of NaN, undefined, and Infinity (ES5 section 15.1.1) + * @author Michael Ficarra + */ + +/** + * Determines if a variable safely shadows undefined. + * This is the case when a variable named `undefined` is never assigned to a value (i.e. it always shares the same value + * as the global). + * @param {eslintScope.Variable} variable The variable to check + * @returns {boolean} true if this variable safely shadows `undefined` + */ +function safelyShadowsUndefined(variable) { + return variable.name === "undefined" && + variable.references.every(ref => !ref.isWrite()) && + variable.defs.every(def => def.node.type === "VariableDeclarator" && def.node.init === null); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noShadowRestrictedNames = { + meta: { + type: "suggestion", + + docs: { + description: "disallow identifiers from shadowing restricted names", + category: "Variables", + recommended: true, + url: "https://eslint.org/docs/rules/no-shadow-restricted-names" + }, + + schema: [], + + messages: { + shadowingRestrictedName: "Shadowing of global property '{{name}}'." + } + }, + + create(context) { + + + const RESTRICTED = new Set(["undefined", "NaN", "Infinity", "arguments", "eval"]); + + return { + "VariableDeclaration, :function, CatchClause"(node) { + for (const variable of context.getDeclaredVariables(node)) { + if (variable.defs.length > 0 && RESTRICTED.has(variable.name) && !safelyShadowsUndefined(variable)) { + context.report({ + node: variable.defs[0].name, + messageId: "shadowingRestrictedName", + data: { + name: variable.name + } + }); + } + } + } + }; + + } +}; + +/** + * @fileoverview Rule to check that spaced function application + * @author Matt DuVall + * @deprecated in ESLint v3.3.0 + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noSpacedFunc = { + meta: { + type: "layout", + + docs: { + description: "disallow spacing between function identifiers and their applications (deprecated)", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-spaced-func" + }, + + deprecated: true, + + replacedBy: ["func-call-spacing"], + + fixable: "whitespace", + schema: [], + + messages: { + noSpacedFunction: "Unexpected space between function name and paren." + } + }, + + create(context) { + + const sourceCode = context.getSourceCode(); + + /** + * Check if open space is present in a function name + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function detectOpenSpaces(node) { + const lastCalleeToken = sourceCode.getLastToken(node.callee); + let prevToken = lastCalleeToken, + parenToken = sourceCode.getTokenAfter(lastCalleeToken); + + // advances to an open parenthesis. + while ( + parenToken && + parenToken.range[1] < node.range[1] && + parenToken.value !== "(" + ) { + prevToken = parenToken; + parenToken = sourceCode.getTokenAfter(parenToken); + } + + // look for a space between the callee and the open paren + if (parenToken && + parenToken.range[1] < node.range[1] && + sourceCode.isSpaceBetweenTokens(prevToken, parenToken) + ) { + context.report({ + node, + loc: lastCalleeToken.loc.start, + messageId: "noSpacedFunction", + fix(fixer) { + return fixer.removeRange([prevToken.range[1], parenToken.range[0]]); + } + }); + } + } + + return { + CallExpression: detectOpenSpaces, + NewExpression: detectOpenSpaces + }; + + } +}; + +/** + * @fileoverview Disallow sparse arrays + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noSparseArrays = { + meta: { + type: "problem", + + docs: { + description: "disallow sparse arrays", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-sparse-arrays" + }, + + schema: [], + + messages: { + unexpectedSparseArray: "Unexpected comma in middle of array." + } + }, + + create(context) { + + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + ArrayExpression(node) { + + const emptySpot = node.elements.indexOf(null) > -1; + + if (emptySpot) { + context.report({ node, messageId: "unexpectedSparseArray" }); + } + } + + }; + + } +}; + +/** + * @fileoverview Rule to check for properties whose identifier ends with the string Sync + * @author Matt DuVall + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noSync = { + meta: { + deprecated: true, + + replacedBy: [], + + type: "suggestion", + + docs: { + description: "disallow synchronous methods", + category: "Node.js and CommonJS", + recommended: false, + url: "https://eslint.org/docs/rules/no-sync" + }, + + schema: [ + { + type: "object", + properties: { + allowAtRootLevel: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + messages: { + noSync: "Unexpected sync method: '{{propertyName}}'." + } + }, + + create(context) { + const selector = context.options[0] && context.options[0].allowAtRootLevel + ? ":function MemberExpression[property.name=/.*Sync$/]" + : "MemberExpression[property.name=/.*Sync$/]"; + + return { + [selector](node) { + context.report({ + node, + messageId: "noSync", + data: { + propertyName: node.property.name + } + }); + } + }; + + } +}; + +/** + * @fileoverview Rule to check for tabs inside a file + * @author Gyandeep Singh + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const tabRegex = /\t+/gu; +const anyNonWhitespaceRegex = /\S/u; + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +var noTabs = { + meta: { + type: "layout", + + docs: { + description: "disallow all tabs", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-tabs" + }, + schema: [{ + type: "object", + properties: { + allowIndentationTabs: { + type: "boolean", + default: false + } + }, + additionalProperties: false + }], + + messages: { + unexpectedTab: "Unexpected tab character." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const allowIndentationTabs = context.options && context.options[0] && context.options[0].allowIndentationTabs; + + return { + Program(node) { + sourceCode.getLines().forEach((line, index) => { + let match; + + while ((match = tabRegex.exec(line)) !== null) { + if (allowIndentationTabs && !anyNonWhitespaceRegex.test(line.slice(0, match.index))) { + continue; + } + + context.report({ + node, + loc: { + start: { + line: index + 1, + column: match.index + }, + end: { + line: index + 1, + column: match.index + match[0].length + } + }, + messageId: "unexpectedTab" + }); + } + }); + } + }; + } +}; + +/** + * @fileoverview Warn when using template string syntax in regular strings + * @author Jeroen Engels + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noTemplateCurlyInString = { + meta: { + type: "problem", + + docs: { + description: "disallow template literal placeholder syntax in regular strings", + category: "Possible Errors", + recommended: false, + url: "https://eslint.org/docs/rules/no-template-curly-in-string" + }, + + schema: [], + + messages: { + unexpectedTemplateExpression: "Unexpected template string expression." + } + }, + + create(context) { + const regex = /\$\{[^}]+\}/u; + + return { + Literal(node) { + if (typeof node.value === "string" && regex.test(node.value)) { + context.report({ + node, + messageId: "unexpectedTemplateExpression" + }); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag use of ternary operators. + * @author Ian Christian Myers + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noTernary = { + meta: { + type: "suggestion", + + docs: { + description: "disallow ternary operators", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-ternary" + }, + + schema: [], + + messages: { + noTernaryOperator: "Ternary operator used." + } + }, + + create(context) { + + return { + + ConditionalExpression(node) { + context.report({ node, messageId: "noTernaryOperator" }); + } + + }; + + } +}; + +/** + * @fileoverview A rule to disallow using `this`/`super` before `super()`. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a given node is a constructor. + * @param {ASTNode} node A node to check. This node type is one of + * `Program`, `FunctionDeclaration`, `FunctionExpression`, and + * `ArrowFunctionExpression`. + * @returns {boolean} `true` if the node is a constructor. + */ +function isConstructorFunction(node) { + return ( + node.type === "FunctionExpression" && + node.parent.type === "MethodDefinition" && + node.parent.kind === "constructor" + ); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noThisBeforeSuper = { + meta: { + type: "problem", + + docs: { + description: "disallow `this`/`super` before calling `super()` in constructors", + category: "ECMAScript 6", + recommended: true, + url: "https://eslint.org/docs/rules/no-this-before-super" + }, + + schema: [], + + messages: { + noBeforeSuper: "'{{kind}}' is not allowed before 'super()'." + } + }, + + create(context) { + + /* + * Information for each constructor. + * - upper: Information of the upper constructor. + * - hasExtends: A flag which shows whether the owner class has a valid + * `extends` part. + * - scope: The scope of the owner class. + * - codePath: The code path of this constructor. + */ + let funcInfo = null; + + /* + * Information for each code path segment. + * Each key is the id of a code path segment. + * Each value is an object: + * - superCalled: The flag which shows `super()` called in all code paths. + * - invalidNodes: The array of invalid ThisExpression and Super nodes. + */ + let segInfoMap = Object.create(null); + + /** + * Gets whether or not `super()` is called in a given code path segment. + * @param {CodePathSegment} segment A code path segment to get. + * @returns {boolean} `true` if `super()` is called. + */ + function isCalled(segment) { + return !segment.reachable || segInfoMap[segment.id].superCalled; + } + + /** + * Checks whether or not this is in a constructor. + * @returns {boolean} `true` if this is in a constructor. + */ + function isInConstructorOfDerivedClass() { + return Boolean(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends); + } + + /** + * Checks whether or not this is before `super()` is called. + * @returns {boolean} `true` if this is before `super()` is called. + */ + function isBeforeCallOfSuper() { + return ( + isInConstructorOfDerivedClass() && + !funcInfo.codePath.currentSegments.every(isCalled) + ); + } + + /** + * Sets a given node as invalid. + * @param {ASTNode} node A node to set as invalid. This is one of + * a ThisExpression and a Super. + * @returns {void} + */ + function setInvalid(node) { + const segments = funcInfo.codePath.currentSegments; + + for (let i = 0; i < segments.length; ++i) { + const segment = segments[i]; + + if (segment.reachable) { + segInfoMap[segment.id].invalidNodes.push(node); + } + } + } + + /** + * Sets the current segment as `super` was called. + * @returns {void} + */ + function setSuperCalled() { + const segments = funcInfo.codePath.currentSegments; + + for (let i = 0; i < segments.length; ++i) { + const segment = segments[i]; + + if (segment.reachable) { + segInfoMap[segment.id].superCalled = true; + } + } + } + + return { + + /** + * Adds information of a constructor into the stack. + * @param {CodePath} codePath A code path which was started. + * @param {ASTNode} node The current node. + * @returns {void} + */ + onCodePathStart(codePath, node) { + if (isConstructorFunction(node)) { + + // Class > ClassBody > MethodDefinition > FunctionExpression + const classNode = node.parent.parent.parent; + + funcInfo = { + upper: funcInfo, + isConstructor: true, + hasExtends: Boolean( + classNode.superClass && + !astUtils.isNullOrUndefined(classNode.superClass) + ), + codePath + }; + } else { + funcInfo = { + upper: funcInfo, + isConstructor: false, + hasExtends: false, + codePath + }; + } + }, + + /** + * Removes the top of stack item. + * + * And this traverses all segments of this code path then reports every + * invalid node. + * @param {CodePath} codePath A code path which was ended. + * @returns {void} + */ + onCodePathEnd(codePath) { + const isDerivedClass = funcInfo.hasExtends; + + funcInfo = funcInfo.upper; + if (!isDerivedClass) { + return; + } + + codePath.traverseSegments((segment, controller) => { + const info = segInfoMap[segment.id]; + + for (let i = 0; i < info.invalidNodes.length; ++i) { + const invalidNode = info.invalidNodes[i]; + + context.report({ + messageId: "noBeforeSuper", + node: invalidNode, + data: { + kind: invalidNode.type === "Super" ? "super" : "this" + } + }); + } + + if (info.superCalled) { + controller.skip(); + } + }); + }, + + /** + * Initialize information of a given code path segment. + * @param {CodePathSegment} segment A code path segment to initialize. + * @returns {void} + */ + onCodePathSegmentStart(segment) { + if (!isInConstructorOfDerivedClass()) { + return; + } + + // Initialize info. + segInfoMap[segment.id] = { + superCalled: ( + segment.prevSegments.length > 0 && + segment.prevSegments.every(isCalled) + ), + invalidNodes: [] + }; + }, + + /** + * Update information of the code path segment when a code path was + * looped. + * @param {CodePathSegment} fromSegment The code path segment of the + * end of a loop. + * @param {CodePathSegment} toSegment A code path segment of the head + * of a loop. + * @returns {void} + */ + onCodePathSegmentLoop(fromSegment, toSegment) { + if (!isInConstructorOfDerivedClass()) { + return; + } + + // Update information inside of the loop. + funcInfo.codePath.traverseSegments( + { first: toSegment, last: fromSegment }, + (segment, controller) => { + const info = segInfoMap[segment.id]; + + if (info.superCalled) { + info.invalidNodes = []; + controller.skip(); + } else if ( + segment.prevSegments.length > 0 && + segment.prevSegments.every(isCalled) + ) { + info.superCalled = true; + info.invalidNodes = []; + } + } + ); + }, + + /** + * Reports if this is before `super()`. + * @param {ASTNode} node A target node. + * @returns {void} + */ + ThisExpression(node) { + if (isBeforeCallOfSuper()) { + setInvalid(node); + } + }, + + /** + * Reports if this is before `super()`. + * @param {ASTNode} node A target node. + * @returns {void} + */ + Super(node) { + if (!astUtils.isCallee(node) && isBeforeCallOfSuper()) { + setInvalid(node); + } + }, + + /** + * Marks `super()` called. + * @param {ASTNode} node A target node. + * @returns {void} + */ + "CallExpression:exit"(node) { + if (node.callee.type === "Super" && isBeforeCallOfSuper()) { + setSuperCalled(); + } + }, + + /** + * Resets state. + * @returns {void} + */ + "Program:exit"() { + segInfoMap = Object.create(null); + } + }; + } +}; + +/** + * @fileoverview Rule to restrict what can be thrown as an exception. + * @author Dieter Oberkofler + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noThrowLiteral = { + meta: { + type: "suggestion", + + docs: { + description: "disallow throwing literals as exceptions", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-throw-literal" + }, + + schema: [], + + messages: { + object: "Expected an error object to be thrown.", + undef: "Do not throw undefined." + } + }, + + create(context) { + + return { + + ThrowStatement(node) { + if (!astUtils.couldBeError(node.argument)) { + context.report({ node, messageId: "object" }); + } else if (node.argument.type === "Identifier") { + if (node.argument.name === "undefined") { + context.report({ node, messageId: "undef" }); + } + } + + } + + }; + + } +}; + +/** + * @fileoverview Disallow trailing spaces at the end of lines. + * @author Nodeca Team + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noTrailingSpaces = { + meta: { + type: "layout", + + docs: { + description: "disallow trailing whitespace at the end of lines", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-trailing-spaces" + }, + + fixable: "whitespace", + + schema: [ + { + type: "object", + properties: { + skipBlankLines: { + type: "boolean", + default: false + }, + ignoreComments: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + messages: { + trailingSpace: "Trailing spaces not allowed." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + const BLANK_CLASS = "[ \t\u00a0\u2000-\u200b\u3000]", + SKIP_BLANK = `^${BLANK_CLASS}*$`, + NONBLANK = `${BLANK_CLASS}+$`; + + const options = context.options[0] || {}, + skipBlankLines = options.skipBlankLines || false, + ignoreComments = options.ignoreComments || false; + + /** + * Report the error message + * @param {ASTNode} node node to report + * @param {int[]} location range information + * @param {int[]} fixRange Range based on the whole program + * @returns {void} + */ + function report(node, location, fixRange) { + + /* + * Passing node is a bit dirty, because message data will contain big + * text in `source`. But... who cares :) ? + * One more kludge will not make worse the bloody wizardry of this + * plugin. + */ + context.report({ + node, + loc: location, + messageId: "trailingSpace", + fix(fixer) { + return fixer.removeRange(fixRange); + } + }); + } + + /** + * Given a list of comment nodes, return the line numbers for those comments. + * @param {Array} comments An array of comment nodes. + * @returns {number[]} An array of line numbers containing comments. + */ + function getCommentLineNumbers(comments) { + const lines = new Set(); + + comments.forEach(comment => { + const endLine = comment.type === "Block" + ? comment.loc.end.line - 1 + : comment.loc.end.line; + + for (let i = comment.loc.start.line; i <= endLine; i++) { + lines.add(i); + } + }); + + return lines; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + Program: function checkTrailingSpaces(node) { + + /* + * Let's hack. Since Espree does not return whitespace nodes, + * fetch the source code and do matching via regexps. + */ + + const re = new RegExp(NONBLANK, "u"), + skipMatch = new RegExp(SKIP_BLANK, "u"), + lines = sourceCode.lines, + linebreaks = sourceCode.getText().match(astUtils.createGlobalLinebreakMatcher()), + comments = sourceCode.getAllComments(), + commentLineNumbers = getCommentLineNumbers(comments); + + let totalLength = 0, + fixRange = []; + + for (let i = 0, ii = lines.length; i < ii; i++) { + const lineNumber = i + 1; + + /* + * Always add linebreak length to line length to accommodate for line break (\n or \r\n) + * Because during the fix time they also reserve one spot in the array. + * Usually linebreak length is 2 for \r\n (CRLF) and 1 for \n (LF) + */ + const linebreakLength = linebreaks && linebreaks[i] ? linebreaks[i].length : 1; + const lineLength = lines[i].length + linebreakLength; + + const matches = re.exec(lines[i]); + + if (matches) { + const location = { + start: { + line: lineNumber, + column: matches.index + }, + end: { + line: lineNumber, + column: lineLength - linebreakLength + } + }; + + const rangeStart = totalLength + location.start.column; + const rangeEnd = totalLength + location.end.column; + const containingNode = sourceCode.getNodeByRangeIndex(rangeStart); + + if (containingNode && containingNode.type === "TemplateElement" && + rangeStart > containingNode.parent.range[0] && + rangeEnd < containingNode.parent.range[1]) { + totalLength += lineLength; + continue; + } + + /* + * If the line has only whitespace, and skipBlankLines + * is true, don't report it + */ + if (skipBlankLines && skipMatch.test(lines[i])) { + totalLength += lineLength; + continue; + } + + fixRange = [rangeStart, rangeEnd]; + + if (!ignoreComments || !commentLineNumbers.has(lineNumber)) { + report(node, location, fixRange); + } + } + + totalLength += lineLength; + } + } + + }; + } +}; + +/** + * @fileoverview Rule to flag references to undeclared variables. + * @author Mark Macdonald + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks if the given node is the argument of a typeof operator. + * @param {ASTNode} node The AST node being checked. + * @returns {boolean} Whether or not the node is the argument of a typeof operator. + */ +function hasTypeOfOperator(node) { + const parent = node.parent; + + return parent.type === "UnaryExpression" && parent.operator === "typeof"; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUndef = { + meta: { + type: "problem", + + docs: { + description: "disallow the use of undeclared variables unless mentioned in `/*global */` comments", + category: "Variables", + recommended: true, + url: "https://eslint.org/docs/rules/no-undef" + }, + + schema: [ + { + type: "object", + properties: { + typeof: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + messages: { + undef: "'{{name}}' is not defined." + } + }, + + create(context) { + const options = context.options[0]; + const considerTypeOf = options && options.typeof === true || false; + + return { + "Program:exit"(/* node */) { + const globalScope = context.getScope(); + + globalScope.through.forEach(ref => { + const identifier = ref.identifier; + + if (!considerTypeOf && hasTypeOfOperator(identifier)) { + return; + } + + context.report({ + node: identifier, + messageId: "undef", + data: identifier + }); + }); + } + }; + } +}; + +/** + * @fileoverview Rule to flag when initializing to undefined + * @author Ilya Volodin + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUndefInit = { + meta: { + type: "suggestion", + + docs: { + description: "disallow initializing variables to `undefined`", + category: "Variables", + recommended: false, + url: "https://eslint.org/docs/rules/no-undef-init" + }, + + schema: [], + fixable: "code", + + messages: { + unnecessaryUndefinedInit: "It's not necessary to initialize '{{name}}' to undefined." + } + }, + + create(context) { + + const sourceCode = context.getSourceCode(); + + return { + + VariableDeclarator(node) { + const name = sourceCode.getText(node.id), + init = node.init && node.init.name, + scope = context.getScope(), + undefinedVar = astUtils.getVariableByName(scope, "undefined"), + shadowed = undefinedVar && undefinedVar.defs.length > 0, + lastToken = sourceCode.getLastToken(node); + + if (init === "undefined" && node.parent.kind !== "const" && !shadowed) { + context.report({ + node, + messageId: "unnecessaryUndefinedInit", + data: { name }, + fix(fixer) { + if (node.parent.kind === "var") { + return null; + } + + if (node.id.type === "ArrayPattern" || node.id.type === "ObjectPattern") { + + // Don't fix destructuring assignment to `undefined`. + return null; + } + + if (sourceCode.commentsExistBetween(node.id, lastToken)) { + return null; + } + + return fixer.removeRange([node.id.range[1], node.range[1]]); + } + }); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag references to the undefined variable. + * @author Michael Ficarra + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUndefined = { + meta: { + type: "suggestion", + + docs: { + description: "disallow the use of `undefined` as an identifier", + category: "Variables", + recommended: false, + url: "https://eslint.org/docs/rules/no-undefined" + }, + + schema: [], + + messages: { + unexpectedUndefined: "Unexpected use of undefined." + } + }, + + create(context) { + + /** + * Report an invalid "undefined" identifier node. + * @param {ASTNode} node The node to report. + * @returns {void} + */ + function report(node) { + context.report({ + node, + messageId: "unexpectedUndefined" + }); + } + + /** + * Checks the given scope for references to `undefined` and reports + * all references found. + * @param {eslint-scope.Scope} scope The scope to check. + * @returns {void} + */ + function checkScope(scope) { + const undefinedVar = scope.set.get("undefined"); + + if (!undefinedVar) { + return; + } + + const references = undefinedVar.references; + + const defs = undefinedVar.defs; + + // Report non-initializing references (those are covered in defs below) + references + .filter(ref => !ref.init) + .forEach(ref => report(ref.identifier)); + + defs.forEach(def => report(def.name)); + } + + return { + "Program:exit"() { + const globalScope = context.getScope(); + + const stack = [globalScope]; + + while (stack.length) { + const scope = stack.pop(); + + stack.push(...scope.childScopes); + checkScope(scope); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag dangling underscores in variable declarations. + * @author Matt DuVall + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUnderscoreDangle = { + meta: { + type: "suggestion", + + docs: { + description: "disallow dangling underscores in identifiers", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-underscore-dangle" + }, + + schema: [ + { + type: "object", + properties: { + allow: { + type: "array", + items: { + type: "string" + } + }, + allowAfterThis: { + type: "boolean", + default: false + }, + allowAfterSuper: { + type: "boolean", + default: false + }, + allowAfterThisConstructor: { + type: "boolean", + default: false + }, + enforceInMethodNames: { + type: "boolean", + default: false + }, + allowFunctionParams: { + type: "boolean", + default: true + } + }, + additionalProperties: false + } + ], + + messages: { + unexpectedUnderscore: "Unexpected dangling '_' in '{{identifier}}'." + } + }, + + create(context) { + + const options = context.options[0] || {}; + const ALLOWED_VARIABLES = options.allow ? options.allow : []; + const allowAfterThis = typeof options.allowAfterThis !== "undefined" ? options.allowAfterThis : false; + const allowAfterSuper = typeof options.allowAfterSuper !== "undefined" ? options.allowAfterSuper : false; + const allowAfterThisConstructor = typeof options.allowAfterThisConstructor !== "undefined" ? options.allowAfterThisConstructor : false; + const enforceInMethodNames = typeof options.enforceInMethodNames !== "undefined" ? options.enforceInMethodNames : false; + const allowFunctionParams = typeof options.allowFunctionParams !== "undefined" ? options.allowFunctionParams : true; + + //------------------------------------------------------------------------- + // Helpers + //------------------------------------------------------------------------- + + /** + * Check if identifier is present inside the allowed option + * @param {string} identifier name of the node + * @returns {boolean} true if its is present + * @private + */ + function isAllowed(identifier) { + return ALLOWED_VARIABLES.some(ident => ident === identifier); + } + + /** + * Check if identifier has a dangling underscore + * @param {string} identifier name of the node + * @returns {boolean} true if its is present + * @private + */ + function hasDanglingUnderscore(identifier) { + const len = identifier.length; + + return identifier !== "_" && (identifier[0] === "_" || identifier[len - 1] === "_"); + } + + /** + * Check if identifier is a special case member expression + * @param {string} identifier name of the node + * @returns {boolean} true if its is a special case + * @private + */ + function isSpecialCaseIdentifierForMemberExpression(identifier) { + return identifier === "__proto__"; + } + + /** + * Check if identifier is a special case variable expression + * @param {string} identifier name of the node + * @returns {boolean} true if its is a special case + * @private + */ + function isSpecialCaseIdentifierInVariableExpression(identifier) { + + // Checks for the underscore library usage here + return identifier === "_"; + } + + /** + * Check if a node is a member reference of this.constructor + * @param {ASTNode} node node to evaluate + * @returns {boolean} true if it is a reference on this.constructor + * @private + */ + function isThisConstructorReference(node) { + return node.object.type === "MemberExpression" && + node.object.property.name === "constructor" && + node.object.object.type === "ThisExpression"; + } + + /** + * Check if function parameter has a dangling underscore. + * @param {ASTNode} node function node to evaluate + * @returns {void} + * @private + */ + function checkForDanglingUnderscoreInFunctionParameters(node) { + if (!allowFunctionParams) { + node.params.forEach(param => { + const { type } = param; + let nodeToCheck; + + if (type === "RestElement") { + nodeToCheck = param.argument; + } else if (type === "AssignmentPattern") { + nodeToCheck = param.left; + } else { + nodeToCheck = param; + } + + if (nodeToCheck.type === "Identifier") { + const identifier = nodeToCheck.name; + + if (hasDanglingUnderscore(identifier) && !isAllowed(identifier)) { + context.report({ + node: param, + messageId: "unexpectedUnderscore", + data: { + identifier + } + }); + } + } + }); + } + } + + /** + * Check if function has a dangling underscore + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function checkForDanglingUnderscoreInFunction(node) { + if (node.type === "FunctionDeclaration" && node.id) { + const identifier = node.id.name; + + if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) && !isAllowed(identifier)) { + context.report({ + node, + messageId: "unexpectedUnderscore", + data: { + identifier + } + }); + } + } + checkForDanglingUnderscoreInFunctionParameters(node); + } + + /** + * Check if variable expression has a dangling underscore + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function checkForDanglingUnderscoreInVariableExpression(node) { + const identifier = node.id.name; + + if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) && + !isSpecialCaseIdentifierInVariableExpression(identifier) && !isAllowed(identifier)) { + context.report({ + node, + messageId: "unexpectedUnderscore", + data: { + identifier + } + }); + } + } + + /** + * Check if member expression has a dangling underscore + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function checkForDanglingUnderscoreInMemberExpression(node) { + const identifier = node.property.name, + isMemberOfThis = node.object.type === "ThisExpression", + isMemberOfSuper = node.object.type === "Super", + isMemberOfThisConstructor = isThisConstructorReference(node); + + if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) && + !(isMemberOfThis && allowAfterThis) && + !(isMemberOfSuper && allowAfterSuper) && + !(isMemberOfThisConstructor && allowAfterThisConstructor) && + !isSpecialCaseIdentifierForMemberExpression(identifier) && !isAllowed(identifier)) { + context.report({ + node, + messageId: "unexpectedUnderscore", + data: { + identifier + } + }); + } + } + + /** + * Check if method declaration or method property has a dangling underscore + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function checkForDanglingUnderscoreInMethod(node) { + const identifier = node.key.name; + const isMethod = node.type === "MethodDefinition" || node.type === "Property" && node.method; + + if (typeof identifier !== "undefined" && enforceInMethodNames && isMethod && hasDanglingUnderscore(identifier) && !isAllowed(identifier)) { + context.report({ + node, + messageId: "unexpectedUnderscore", + data: { + identifier + } + }); + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + FunctionDeclaration: checkForDanglingUnderscoreInFunction, + VariableDeclarator: checkForDanglingUnderscoreInVariableExpression, + MemberExpression: checkForDanglingUnderscoreInMemberExpression, + MethodDefinition: checkForDanglingUnderscoreInMethod, + Property: checkForDanglingUnderscoreInMethod, + FunctionExpression: checkForDanglingUnderscoreInFunction, + ArrowFunctionExpression: checkForDanglingUnderscoreInFunction + }; + + } +}; + +/** + * @fileoverview Rule to spot scenarios where a newline looks like it is ending a statement, but is not. + * @author Glen Mailer + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUnexpectedMultiline = { + meta: { + type: "problem", + + docs: { + description: "disallow confusing multiline expressions", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-unexpected-multiline" + }, + + schema: [], + messages: { + function: "Unexpected newline between function and ( of function call.", + property: "Unexpected newline between object and [ of property access.", + taggedTemplate: "Unexpected newline between template tag and template literal.", + division: "Unexpected newline between numerator and division operator." + } + }, + + create(context) { + + const REGEX_FLAG_MATCHER = /^[gimsuy]+$/u; + + const sourceCode = context.getSourceCode(); + + /** + * Check to see if there is a newline between the node and the following open bracket + * line's expression + * @param {ASTNode} node The node to check. + * @param {string} messageId The error messageId to use. + * @returns {void} + * @private + */ + function checkForBreakAfter(node, messageId) { + const openParen = sourceCode.getTokenAfter(node, astUtils.isNotClosingParenToken); + const nodeExpressionEnd = sourceCode.getTokenBefore(openParen); + + if (openParen.loc.start.line !== nodeExpressionEnd.loc.end.line) { + context.report({ + node, + loc: openParen.loc, + messageId + }); + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + + MemberExpression(node) { + if (!node.computed || node.optional) { + return; + } + checkForBreakAfter(node.object, "property"); + }, + + TaggedTemplateExpression(node) { + const { quasi } = node; + + // handles common tags, parenthesized tags, and typescript's generic type arguments + const tokenBefore = sourceCode.getTokenBefore(quasi); + + if (tokenBefore.loc.end.line !== quasi.loc.start.line) { + context.report({ + node, + loc: { + start: quasi.loc.start, + end: { + line: quasi.loc.start.line, + column: quasi.loc.start.column + 1 + } + }, + messageId: "taggedTemplate" + }); + } + }, + + CallExpression(node) { + if (node.arguments.length === 0 || node.optional) { + return; + } + checkForBreakAfter(node.callee, "function"); + }, + + "BinaryExpression[operator='/'] > BinaryExpression[operator='/'].left"(node) { + const secondSlash = sourceCode.getTokenAfter(node, token => token.value === "/"); + const tokenAfterOperator = sourceCode.getTokenAfter(secondSlash); + + if ( + tokenAfterOperator.type === "Identifier" && + REGEX_FLAG_MATCHER.test(tokenAfterOperator.value) && + secondSlash.range[1] === tokenAfterOperator.range[0] + ) { + checkForBreakAfter(node.left, "division"); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to disallow use of unmodified expressions in loop conditions + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const SENTINEL_PATTERN = /(?:(?:Call|Class|Function|Member|New|Yield)Expression|Statement|Declaration)$/u; +const LOOP_PATTERN = /^(?:DoWhile|For|While)Statement$/u; // for-in/of statements don't have `test` property. +const GROUP_PATTERN = /^(?:BinaryExpression|ConditionalExpression)$/u; +const SKIP_PATTERN = /^(?:ArrowFunction|Class|Function)Expression$/u; +const DYNAMIC_PATTERN = /^(?:Call|Member|New|TaggedTemplate|Yield)Expression$/u; + +/** + * @typedef {Object} LoopConditionInfo + * @property {eslint-scope.Reference} reference - The reference. + * @property {ASTNode} group - BinaryExpression or ConditionalExpression nodes + * that the reference is belonging to. + * @property {Function} isInLoop - The predicate which checks a given reference + * is in this loop. + * @property {boolean} modified - The flag that the reference is modified in + * this loop. + */ + +/** + * Checks whether or not a given reference is a write reference. + * @param {eslint-scope.Reference} reference A reference to check. + * @returns {boolean} `true` if the reference is a write reference. + */ +function isWriteReference(reference) { + if (reference.init) { + const def = reference.resolved && reference.resolved.defs[0]; + + if (!def || def.type !== "Variable" || def.parent.kind !== "var") { + return false; + } + } + return reference.isWrite(); +} + +/** + * Checks whether or not a given loop condition info does not have the modified + * flag. + * @param {LoopConditionInfo} condition A loop condition info to check. + * @returns {boolean} `true` if the loop condition info is "unmodified". + */ +function isUnmodified(condition) { + return !condition.modified; +} + +/** + * Checks whether or not a given loop condition info does not have the modified + * flag and does not have the group this condition belongs to. + * @param {LoopConditionInfo} condition A loop condition info to check. + * @returns {boolean} `true` if the loop condition info is "unmodified". + */ +function isUnmodifiedAndNotBelongToGroup(condition) { + return !(condition.modified || condition.group); +} + +/** + * Checks whether or not a given reference is inside of a given node. + * @param {ASTNode} node A node to check. + * @param {eslint-scope.Reference} reference A reference to check. + * @returns {boolean} `true` if the reference is inside of the node. + */ +function isInRange$1(node, reference) { + const or = node.range; + const ir = reference.identifier.range; + + return or[0] <= ir[0] && ir[1] <= or[1]; +} + +/** + * Checks whether or not a given reference is inside of a loop node's condition. + * @param {ASTNode} node A node to check. + * @param {eslint-scope.Reference} reference A reference to check. + * @returns {boolean} `true` if the reference is inside of the loop node's + * condition. + */ +const isInLoop = { + WhileStatement: isInRange$1, + DoWhileStatement: isInRange$1, + ForStatement(node, reference) { + return ( + isInRange$1(node, reference) && + !(node.init && isInRange$1(node.init, reference)) + ); + } +}; + +/** + * Gets the function which encloses a given reference. + * This supports only FunctionDeclaration. + * @param {eslint-scope.Reference} reference A reference to get. + * @returns {ASTNode|null} The function node or null. + */ +function getEncloseFunctionDeclaration(reference) { + let node = reference.identifier; + + while (node) { + if (node.type === "FunctionDeclaration") { + return node.id ? node : null; + } + + node = node.parent; + } + + return null; +} + +/** + * Updates the "modified" flags of given loop conditions with given modifiers. + * @param {LoopConditionInfo[]} conditions The loop conditions to be updated. + * @param {eslint-scope.Reference[]} modifiers The references to update. + * @returns {void} + */ +function updateModifiedFlag(conditions, modifiers) { + + for (let i = 0; i < conditions.length; ++i) { + const condition = conditions[i]; + + for (let j = 0; !condition.modified && j < modifiers.length; ++j) { + const modifier = modifiers[j]; + let funcNode, funcVar; + + /* + * Besides checking for the condition being in the loop, we want to + * check the function that this modifier is belonging to is called + * in the loop. + * FIXME: This should probably be extracted to a function. + */ + const inLoop = condition.isInLoop(modifier) || Boolean( + (funcNode = getEncloseFunctionDeclaration(modifier)) && + (funcVar = astUtils.getVariableByName(modifier.from.upper, funcNode.id.name)) && + funcVar.references.some(condition.isInLoop) + ); + + condition.modified = inLoop; + } + } +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUnmodifiedLoopCondition = { + meta: { + type: "problem", + + docs: { + description: "disallow unmodified loop conditions", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-unmodified-loop-condition" + }, + + schema: [], + + messages: { + loopConditionNotModified: "'{{name}}' is not modified in this loop." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + let groupMap = null; + + /** + * Reports a given condition info. + * @param {LoopConditionInfo} condition A loop condition info to report. + * @returns {void} + */ + function report(condition) { + const node = condition.reference.identifier; + + context.report({ + node, + messageId: "loopConditionNotModified", + data: node + }); + } + + /** + * Registers given conditions to the group the condition belongs to. + * @param {LoopConditionInfo[]} conditions A loop condition info to + * register. + * @returns {void} + */ + function registerConditionsToGroup(conditions) { + for (let i = 0; i < conditions.length; ++i) { + const condition = conditions[i]; + + if (condition.group) { + let group = groupMap.get(condition.group); + + if (!group) { + group = []; + groupMap.set(condition.group, group); + } + group.push(condition); + } + } + } + + /** + * Reports references which are inside of unmodified groups. + * @param {LoopConditionInfo[]} conditions A loop condition info to report. + * @returns {void} + */ + function checkConditionsInGroup(conditions) { + if (conditions.every(isUnmodified)) { + conditions.forEach(report); + } + } + + /** + * Checks whether or not a given group node has any dynamic elements. + * @param {ASTNode} root A node to check. + * This node is one of BinaryExpression or ConditionalExpression. + * @returns {boolean} `true` if the node is dynamic. + */ + function hasDynamicExpressions(root) { + let retv = false; + + traverser.traverse(root, { + visitorKeys: sourceCode.visitorKeys, + enter(node) { + if (DYNAMIC_PATTERN.test(node.type)) { + retv = true; + this.break(); + } else if (SKIP_PATTERN.test(node.type)) { + this.skip(); + } + } + }); + + return retv; + } + + /** + * Creates the loop condition information from a given reference. + * @param {eslint-scope.Reference} reference A reference to create. + * @returns {LoopConditionInfo|null} Created loop condition info, or null. + */ + function toLoopCondition(reference) { + if (reference.init) { + return null; + } + + let group = null; + let child = reference.identifier; + let node = child.parent; + + while (node) { + if (SENTINEL_PATTERN.test(node.type)) { + if (LOOP_PATTERN.test(node.type) && node.test === child) { + + // This reference is inside of a loop condition. + return { + reference, + group, + isInLoop: isInLoop[node.type].bind(null, node), + modified: false + }; + } + + // This reference is outside of a loop condition. + break; + } + + /* + * If it's inside of a group, OK if either operand is modified. + * So stores the group this reference belongs to. + */ + if (GROUP_PATTERN.test(node.type)) { + + // If this expression is dynamic, no need to check. + if (hasDynamicExpressions(node)) { + break; + } else { + group = node; + } + } + + child = node; + node = node.parent; + } + + return null; + } + + /** + * Finds unmodified references which are inside of a loop condition. + * Then reports the references which are outside of groups. + * @param {eslint-scope.Variable} variable A variable to report. + * @returns {void} + */ + function checkReferences(variable) { + + // Gets references that exist in loop conditions. + const conditions = variable + .references + .map(toLoopCondition) + .filter(Boolean); + + if (conditions.length === 0) { + return; + } + + // Registers the conditions to belonging groups. + registerConditionsToGroup(conditions); + + // Check the conditions are modified. + const modifiers = variable.references.filter(isWriteReference); + + if (modifiers.length > 0) { + updateModifiedFlag(conditions, modifiers); + } + + /* + * Reports the conditions which are not belonging to groups. + * Others will be reported after all variables are done. + */ + conditions + .filter(isUnmodifiedAndNotBelongToGroup) + .forEach(report); + } + + return { + "Program:exit"() { + const queue = [context.getScope()]; + + groupMap = new Map(); + + let scope; + + while ((scope = queue.pop())) { + queue.push(...scope.childScopes); + scope.variables.forEach(checkReferences); + } + + groupMap.forEach(checkConditionsInGroup); + groupMap = null; + } + }; + } +}; + +/** + * @fileoverview Rule to flag no-unneeded-ternary + * @author Gyandeep Singh + */ + + + +// Operators that always result in a boolean value +const BOOLEAN_OPERATORS = new Set(["==", "===", "!=", "!==", ">", ">=", "<", "<=", "in", "instanceof"]); +const OPERATOR_INVERSES = { + "==": "!=", + "!=": "==", + "===": "!==", + "!==": "===" + + // Operators like < and >= are not true inverses, since both will return false with NaN. +}; +const OR_PRECEDENCE = astUtils.getPrecedence({ type: "LogicalExpression", operator: "||" }); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUnneededTernary = { + meta: { + type: "suggestion", + + docs: { + description: "disallow ternary operators when simpler alternatives exist", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-unneeded-ternary" + }, + + schema: [ + { + type: "object", + properties: { + defaultAssignment: { + type: "boolean", + default: true + } + }, + additionalProperties: false + } + ], + + fixable: "code", + + messages: { + unnecessaryConditionalExpression: "Unnecessary use of boolean literals in conditional expression.", + unnecessaryConditionalAssignment: "Unnecessary use of conditional expression for default assignment." + } + }, + + create(context) { + const options = context.options[0] || {}; + const defaultAssignment = options.defaultAssignment !== false; + const sourceCode = context.getSourceCode(); + + /** + * Test if the node is a boolean literal + * @param {ASTNode} node The node to report. + * @returns {boolean} True if the its a boolean literal + * @private + */ + function isBooleanLiteral(node) { + return node.type === "Literal" && typeof node.value === "boolean"; + } + + /** + * Creates an expression that represents the boolean inverse of the expression represented by the original node + * @param {ASTNode} node A node representing an expression + * @returns {string} A string representing an inverted expression + */ + function invertExpression(node) { + if (node.type === "BinaryExpression" && Object.prototype.hasOwnProperty.call(OPERATOR_INVERSES, node.operator)) { + const operatorToken = sourceCode.getFirstTokenBetween( + node.left, + node.right, + token => token.value === node.operator + ); + const text = sourceCode.getText(); + + return text.slice(node.range[0], + operatorToken.range[0]) + OPERATOR_INVERSES[node.operator] + text.slice(operatorToken.range[1], node.range[1]); + } + + if (astUtils.getPrecedence(node) < astUtils.getPrecedence({ type: "UnaryExpression" })) { + return `!(${astUtils.getParenthesisedText(sourceCode, node)})`; + } + return `!${astUtils.getParenthesisedText(sourceCode, node)}`; + } + + /** + * Tests if a given node always evaluates to a boolean value + * @param {ASTNode} node An expression node + * @returns {boolean} True if it is determined that the node will always evaluate to a boolean value + */ + function isBooleanExpression(node) { + return node.type === "BinaryExpression" && BOOLEAN_OPERATORS.has(node.operator) || + node.type === "UnaryExpression" && node.operator === "!"; + } + + /** + * Test if the node matches the pattern id ? id : expression + * @param {ASTNode} node The ConditionalExpression to check. + * @returns {boolean} True if the pattern is matched, and false otherwise + * @private + */ + function matchesDefaultAssignment(node) { + return node.test.type === "Identifier" && + node.consequent.type === "Identifier" && + node.test.name === node.consequent.name; + } + + return { + + ConditionalExpression(node) { + if (isBooleanLiteral(node.alternate) && isBooleanLiteral(node.consequent)) { + context.report({ + node, + messageId: "unnecessaryConditionalExpression", + fix(fixer) { + if (node.consequent.value === node.alternate.value) { + + // Replace `foo ? true : true` with just `true`, but don't replace `foo() ? true : true` + return node.test.type === "Identifier" ? fixer.replaceText(node, node.consequent.value.toString()) : null; + } + if (node.alternate.value) { + + // Replace `foo() ? false : true` with `!(foo())` + return fixer.replaceText(node, invertExpression(node.test)); + } + + // Replace `foo ? true : false` with `foo` if `foo` is guaranteed to be a boolean, or `!!foo` otherwise. + + return fixer.replaceText(node, isBooleanExpression(node.test) ? astUtils.getParenthesisedText(sourceCode, node.test) : `!${invertExpression(node.test)}`); + } + }); + } else if (!defaultAssignment && matchesDefaultAssignment(node)) { + context.report({ + node, + messageId: "unnecessaryConditionalAssignment", + fix: fixer => { + const shouldParenthesizeAlternate = + ( + astUtils.getPrecedence(node.alternate) < OR_PRECEDENCE || + astUtils.isCoalesceExpression(node.alternate) + ) && + !astUtils.isParenthesised(sourceCode, node.alternate); + const alternateText = shouldParenthesizeAlternate + ? `(${sourceCode.getText(node.alternate)})` + : astUtils.getParenthesisedText(sourceCode, node.alternate); + const testText = astUtils.getParenthesisedText(sourceCode, node.test); + + return fixer.replaceText(node, `${testText} || ${alternateText}`); + } + }); + } + } + }; + } +}; + +/** + * @fileoverview Checks for unreachable code due to return, throws, break, and continue. + * @author Joel Feenstra + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a given variable declarator has the initializer. + * @param {ASTNode} node A VariableDeclarator node to check. + * @returns {boolean} `true` if the node has the initializer. + */ +function isInitialized(node) { + return Boolean(node.init); +} + +/** + * Checks whether or not a given code path segment is unreachable. + * @param {CodePathSegment} segment A CodePathSegment to check. + * @returns {boolean} `true` if the segment is unreachable. + */ +function isUnreachable(segment) { + return !segment.reachable; +} + +/** + * The class to distinguish consecutive unreachable statements. + */ +class ConsecutiveRange { + constructor(sourceCode) { + this.sourceCode = sourceCode; + this.startNode = null; + this.endNode = null; + } + + /** + * The location object of this range. + * @type {Object} + */ + get location() { + return { + start: this.startNode.loc.start, + end: this.endNode.loc.end + }; + } + + /** + * `true` if this range is empty. + * @type {boolean} + */ + get isEmpty() { + return !(this.startNode && this.endNode); + } + + /** + * Checks whether the given node is inside of this range. + * @param {ASTNode|Token} node The node to check. + * @returns {boolean} `true` if the node is inside of this range. + */ + contains(node) { + return ( + node.range[0] >= this.startNode.range[0] && + node.range[1] <= this.endNode.range[1] + ); + } + + /** + * Checks whether the given node is consecutive to this range. + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if the node is consecutive to this range. + */ + isConsecutive(node) { + return this.contains(this.sourceCode.getTokenBefore(node)); + } + + /** + * Merges the given node to this range. + * @param {ASTNode} node The node to merge. + * @returns {void} + */ + merge(node) { + this.endNode = node; + } + + /** + * Resets this range by the given node or null. + * @param {ASTNode|null} node The node to reset, or null. + * @returns {void} + */ + reset(node) { + this.startNode = this.endNode = node; + } +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUnreachable = { + meta: { + type: "problem", + + docs: { + description: "disallow unreachable code after `return`, `throw`, `continue`, and `break` statements", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-unreachable" + }, + + schema: [], + + messages: { + unreachableCode: "Unreachable code." + } + }, + + create(context) { + let currentCodePath = null; + + const range = new ConsecutiveRange(context.getSourceCode()); + + /** + * Reports a given node if it's unreachable. + * @param {ASTNode} node A statement node to report. + * @returns {void} + */ + function reportIfUnreachable(node) { + let nextNode = null; + + if (node && currentCodePath.currentSegments.every(isUnreachable)) { + + // Store this statement to distinguish consecutive statements. + if (range.isEmpty) { + range.reset(node); + return; + } + + // Skip if this statement is inside of the current range. + if (range.contains(node)) { + return; + } + + // Merge if this statement is consecutive to the current range. + if (range.isConsecutive(node)) { + range.merge(node); + return; + } + + nextNode = node; + } + + /* + * Report the current range since this statement is reachable or is + * not consecutive to the current range. + */ + if (!range.isEmpty) { + context.report({ + messageId: "unreachableCode", + loc: range.location, + node: range.startNode + }); + } + + // Update the current range. + range.reset(nextNode); + } + + return { + + // Manages the current code path. + onCodePathStart(codePath) { + currentCodePath = codePath; + }, + + onCodePathEnd() { + currentCodePath = currentCodePath.upper; + }, + + // Registers for all statement nodes (excludes FunctionDeclaration). + BlockStatement: reportIfUnreachable, + BreakStatement: reportIfUnreachable, + ClassDeclaration: reportIfUnreachable, + ContinueStatement: reportIfUnreachable, + DebuggerStatement: reportIfUnreachable, + DoWhileStatement: reportIfUnreachable, + ExpressionStatement: reportIfUnreachable, + ForInStatement: reportIfUnreachable, + ForOfStatement: reportIfUnreachable, + ForStatement: reportIfUnreachable, + IfStatement: reportIfUnreachable, + ImportDeclaration: reportIfUnreachable, + LabeledStatement: reportIfUnreachable, + ReturnStatement: reportIfUnreachable, + SwitchStatement: reportIfUnreachable, + ThrowStatement: reportIfUnreachable, + TryStatement: reportIfUnreachable, + + VariableDeclaration(node) { + if (node.kind !== "var" || node.declarations.some(isInitialized)) { + reportIfUnreachable(node); + } + }, + + WhileStatement: reportIfUnreachable, + WithStatement: reportIfUnreachable, + ExportNamedDeclaration: reportIfUnreachable, + ExportDefaultDeclaration: reportIfUnreachable, + ExportAllDeclaration: reportIfUnreachable, + + "Program:exit"() { + reportIfUnreachable(); + } + }; + } +}; + +/** + * @fileoverview Rule to disallow loops with a body that allows only one iteration + * @author Milos Djermanovic + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const allLoopTypes = ["WhileStatement", "DoWhileStatement", "ForStatement", "ForInStatement", "ForOfStatement"]; + +/** + * Determines whether the given node is the first node in the code path to which a loop statement + * 'loops' for the next iteration. + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if the node is a looping target. + */ +function isLoopingTarget(node) { + const parent = node.parent; + + if (parent) { + switch (parent.type) { + case "WhileStatement": + return node === parent.test; + case "DoWhileStatement": + return node === parent.body; + case "ForStatement": + return node === (parent.update || parent.test || parent.body); + case "ForInStatement": + case "ForOfStatement": + return node === parent.left; + + // no default + } + } + + return false; +} + +/** + * Creates an array with elements from the first given array that are not included in the second given array. + * @param {Array} arrA The array to compare from. + * @param {Array} arrB The array to compare against. + * @returns {Array} a new array that represents `arrA \ arrB`. + */ +function getDifference(arrA, arrB) { + return arrA.filter(a => !arrB.includes(a)); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUnreachableLoop = { + meta: { + type: "problem", + + docs: { + description: "disallow loops with a body that allows only one iteration", + category: "Possible Errors", + recommended: false, + url: "https://eslint.org/docs/rules/no-unreachable-loop" + }, + + schema: [{ + type: "object", + properties: { + ignore: { + type: "array", + items: { + enum: allLoopTypes + }, + uniqueItems: true + } + }, + additionalProperties: false + }], + + messages: { + invalid: "Invalid loop. Its body allows only one iteration." + } + }, + + create(context) { + const ignoredLoopTypes = context.options[0] && context.options[0].ignore || [], + loopTypesToCheck = getDifference(allLoopTypes, ignoredLoopTypes), + loopSelector = loopTypesToCheck.join(","), + loopsByTargetSegments = new Map(), + loopsToReport = new Set(); + + let currentCodePath = null; + + return { + onCodePathStart(codePath) { + currentCodePath = codePath; + }, + + onCodePathEnd() { + currentCodePath = currentCodePath.upper; + }, + + [loopSelector](node) { + + /** + * Ignore unreachable loop statements to avoid unnecessary complexity in the implementation, or false positives otherwise. + * For unreachable segments, the code path analysis does not raise events required for this implementation. + */ + if (currentCodePath.currentSegments.some(segment => segment.reachable)) { + loopsToReport.add(node); + } + }, + + onCodePathSegmentStart(segment, node) { + if (isLoopingTarget(node)) { + const loop = node.parent; + + loopsByTargetSegments.set(segment, loop); + } + }, + + onCodePathSegmentLoop(_, toSegment, node) { + const loop = loopsByTargetSegments.get(toSegment); + + /** + * The second iteration is reachable, meaning that the loop is valid by the logic of this rule, + * only if there is at least one loop event with the appropriate target (which has been already + * determined in the `loopsByTargetSegments` map), raised from either: + * + * - the end of the loop's body (in which case `node === loop`) + * - a `continue` statement + * + * This condition skips loop events raised from `ForInStatement > .right` and `ForOfStatement > .right` nodes. + */ + if (node === loop || node.type === "ContinueStatement") { + + // Removes loop if it exists in the set. Otherwise, `Set#delete` has no effect and doesn't throw. + loopsToReport.delete(loop); + } + }, + + "Program:exit"() { + loopsToReport.forEach( + node => context.report({ node, messageId: "invalid" }) + ); + } + }; + } +}; + +/** + * @fileoverview Rule to flag unsafe statements in finally block + * @author Onur Temizkan + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const SENTINEL_NODE_TYPE_RETURN_THROW = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression)$/u; +const SENTINEL_NODE_TYPE_BREAK = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|DoWhileStatement|WhileStatement|ForOfStatement|ForInStatement|ForStatement|SwitchStatement)$/u; +const SENTINEL_NODE_TYPE_CONTINUE = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|DoWhileStatement|WhileStatement|ForOfStatement|ForInStatement|ForStatement)$/u; + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUnsafeFinally = { + meta: { + type: "problem", + + docs: { + description: "disallow control flow statements in `finally` blocks", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-unsafe-finally" + }, + + schema: [], + + messages: { + unsafeUsage: "Unsafe usage of {{nodeType}}." + } + }, + create(context) { + + /** + * Checks if the node is the finalizer of a TryStatement + * @param {ASTNode} node node to check. + * @returns {boolean} - true if the node is the finalizer of a TryStatement + */ + function isFinallyBlock(node) { + return node.parent.type === "TryStatement" && node.parent.finalizer === node; + } + + /** + * Climbs up the tree if the node is not a sentinel node + * @param {ASTNode} node node to check. + * @param {string} label label of the break or continue statement + * @returns {boolean} - return whether the node is a finally block or a sentinel node + */ + function isInFinallyBlock(node, label) { + let labelInside = false; + let sentinelNodeType; + + if (node.type === "BreakStatement" && !node.label) { + sentinelNodeType = SENTINEL_NODE_TYPE_BREAK; + } else if (node.type === "ContinueStatement") { + sentinelNodeType = SENTINEL_NODE_TYPE_CONTINUE; + } else { + sentinelNodeType = SENTINEL_NODE_TYPE_RETURN_THROW; + } + + for ( + let currentNode = node; + currentNode && !sentinelNodeType.test(currentNode.type); + currentNode = currentNode.parent + ) { + if (currentNode.parent.label && label && (currentNode.parent.label.name === label.name)) { + labelInside = true; + } + if (isFinallyBlock(currentNode)) { + if (label && labelInside) { + return false; + } + return true; + } + } + return false; + } + + /** + * Checks whether the possibly-unsafe statement is inside a finally block. + * @param {ASTNode} node node to check. + * @returns {void} + */ + function check(node) { + if (isInFinallyBlock(node, node.label)) { + context.report({ + messageId: "unsafeUsage", + data: { + nodeType: node.type + }, + node, + line: node.loc.line, + column: node.loc.column + }); + } + } + + return { + ReturnStatement: check, + ThrowStatement: check, + BreakStatement: check, + ContinueStatement: check + }; + } +}; + +/** + * @fileoverview Rule to disallow negating the left operand of relational operators + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether the given operator is `in` or `instanceof` + * @param {string} op The operator type to check. + * @returns {boolean} `true` if the operator is `in` or `instanceof` + */ +function isInOrInstanceOfOperator(op) { + return op === "in" || op === "instanceof"; +} + +/** + * Checks whether the given operator is an ordering relational operator or not. + * @param {string} op The operator type to check. + * @returns {boolean} `true` if the operator is an ordering relational operator. + */ +function isOrderingRelationalOperator(op) { + return op === "<" || op === ">" || op === ">=" || op === "<="; +} + +/** + * Checks whether the given node is a logical negation expression or not. + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if the node is a logical negation expression. + */ +function isNegation(node) { + return node.type === "UnaryExpression" && node.operator === "!"; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUnsafeNegation = { + meta: { + type: "problem", + + docs: { + description: "disallow negating the left operand of relational operators", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/no-unsafe-negation", + suggestion: true + }, + + schema: [ + { + type: "object", + properties: { + enforceForOrderingRelations: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + fixable: null, + + messages: { + unexpected: "Unexpected negating the left operand of '{{operator}}' operator.", + suggestNegatedExpression: "Negate '{{operator}}' expression instead of its left operand. This changes the current behavior.", + suggestParenthesisedNegation: "Wrap negation in '()' to make the intention explicit. This preserves the current behavior." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const options = context.options[0] || {}; + const enforceForOrderingRelations = options.enforceForOrderingRelations === true; + + return { + BinaryExpression(node) { + const operator = node.operator; + const orderingRelationRuleApplies = enforceForOrderingRelations && isOrderingRelationalOperator(operator); + + if ( + (isInOrInstanceOfOperator(operator) || orderingRelationRuleApplies) && + isNegation(node.left) && + !astUtils.isParenthesised(sourceCode, node.left) + ) { + context.report({ + node, + loc: node.left.loc, + messageId: "unexpected", + data: { operator }, + suggest: [ + { + messageId: "suggestNegatedExpression", + data: { operator }, + fix(fixer) { + const negationToken = sourceCode.getFirstToken(node.left); + const fixRange = [negationToken.range[1], node.range[1]]; + const text = sourceCode.text.slice(fixRange[0], fixRange[1]); + + return fixer.replaceTextRange(fixRange, `(${text})`); + } + }, + { + messageId: "suggestParenthesisedNegation", + fix(fixer) { + return fixer.replaceText(node.left, `(${sourceCode.getText(node.left)})`); + } + } + ] + }); + } + } + }; + } +}; + +/** + * @fileoverview Rule to disallow unsafe optional chaining + * @author Yeon JuAn + */ + +const UNSAFE_ARITHMETIC_OPERATORS = new Set(["+", "-", "/", "*", "%", "**"]); +const UNSAFE_ASSIGNMENT_OPERATORS = new Set(["+=", "-=", "/=", "*=", "%=", "**="]); +const UNSAFE_RELATIONAL_OPERATORS = new Set(["in", "instanceof"]); + +/** + * Checks whether a node is a destructuring pattern or not + * @param {ASTNode} node node to check + * @returns {boolean} `true` if a node is a destructuring pattern, otherwise `false` + */ +function isDestructuringPattern(node) { + return node.type === "ObjectPattern" || node.type === "ArrayPattern"; +} + +var noUnsafeOptionalChaining = { + meta: { + type: "problem", + + docs: { + description: "disallow use of optional chaining in contexts where the `undefined` value is not allowed", + category: "Possible Errors", + recommended: false, + url: "https://eslint.org/docs/rules/no-unsafe-optional-chaining" + }, + schema: [{ + type: "object", + properties: { + disallowArithmeticOperators: { + type: "boolean", + default: false + } + }, + additionalProperties: false + }], + fixable: null, + messages: { + unsafeOptionalChain: "Unsafe usage of optional chaining. If it short-circuits with 'undefined' the evaluation will throw TypeError.", + unsafeArithmetic: "Unsafe arithmetic operation on optional chaining. It can result in NaN." + } + }, + + create(context) { + const options = context.options[0] || {}; + const disallowArithmeticOperators = (options.disallowArithmeticOperators) || false; + + /** + * Reports unsafe usage of optional chaining + * @param {ASTNode} node node to report + * @returns {void} + */ + function reportUnsafeUsage(node) { + context.report({ + messageId: "unsafeOptionalChain", + node + }); + } + + /** + * Reports unsafe arithmetic operation on optional chaining + * @param {ASTNode} node node to report + * @returns {void} + */ + function reportUnsafeArithmetic(node) { + context.report({ + messageId: "unsafeArithmetic", + node + }); + } + + /** + * Checks and reports if a node can short-circuit with `undefined` by optional chaining. + * @param {ASTNode} [node] node to check + * @param {Function} reportFunc report function + * @returns {void} + */ + function checkUndefinedShortCircuit(node, reportFunc) { + if (!node) { + return; + } + switch (node.type) { + case "LogicalExpression": + if (node.operator === "||" || node.operator === "??") { + checkUndefinedShortCircuit(node.right, reportFunc); + } else if (node.operator === "&&") { + checkUndefinedShortCircuit(node.left, reportFunc); + checkUndefinedShortCircuit(node.right, reportFunc); + } + break; + case "SequenceExpression": + checkUndefinedShortCircuit( + node.expressions[node.expressions.length - 1], + reportFunc + ); + break; + case "ConditionalExpression": + checkUndefinedShortCircuit(node.consequent, reportFunc); + checkUndefinedShortCircuit(node.alternate, reportFunc); + break; + case "AwaitExpression": + checkUndefinedShortCircuit(node.argument, reportFunc); + break; + case "ChainExpression": + reportFunc(node); + break; + } + } + + /** + * Checks unsafe usage of optional chaining + * @param {ASTNode} node node to check + * @returns {void} + */ + function checkUnsafeUsage(node) { + checkUndefinedShortCircuit(node, reportUnsafeUsage); + } + + /** + * Checks unsafe arithmetic operations on optional chaining + * @param {ASTNode} node node to check + * @returns {void} + */ + function checkUnsafeArithmetic(node) { + checkUndefinedShortCircuit(node, reportUnsafeArithmetic); + } + + return { + "AssignmentExpression, AssignmentPattern"(node) { + if (isDestructuringPattern(node.left)) { + checkUnsafeUsage(node.right); + } + }, + "ClassDeclaration, ClassExpression"(node) { + checkUnsafeUsage(node.superClass); + }, + CallExpression(node) { + if (!node.optional) { + checkUnsafeUsage(node.callee); + } + }, + NewExpression(node) { + checkUnsafeUsage(node.callee); + }, + VariableDeclarator(node) { + if (isDestructuringPattern(node.id)) { + checkUnsafeUsage(node.init); + } + }, + MemberExpression(node) { + if (!node.optional) { + checkUnsafeUsage(node.object); + } + }, + TaggedTemplateExpression(node) { + checkUnsafeUsage(node.tag); + }, + ForOfStatement(node) { + checkUnsafeUsage(node.right); + }, + SpreadElement(node) { + if (node.parent && node.parent.type !== "ObjectExpression") { + checkUnsafeUsage(node.argument); + } + }, + BinaryExpression(node) { + if (UNSAFE_RELATIONAL_OPERATORS.has(node.operator)) { + checkUnsafeUsage(node.right); + } + if ( + disallowArithmeticOperators && + UNSAFE_ARITHMETIC_OPERATORS.has(node.operator) + ) { + checkUnsafeArithmetic(node.right); + checkUnsafeArithmetic(node.left); + } + }, + WithStatement(node) { + checkUnsafeUsage(node.object); + }, + UnaryExpression(node) { + if ( + disallowArithmeticOperators && + UNSAFE_ARITHMETIC_OPERATORS.has(node.operator) + ) { + checkUnsafeArithmetic(node.argument); + } + }, + AssignmentExpression(node) { + if ( + disallowArithmeticOperators && + UNSAFE_ASSIGNMENT_OPERATORS.has(node.operator) + ) { + checkUnsafeArithmetic(node.right); + } + } + }; + } +}; + +/** + * @fileoverview Flag expressions in statement position that do not side effect + * @author Michael Ficarra + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +/** + * Returns `true`. + * @returns {boolean} `true`. + */ +function alwaysTrue() { + return true; +} + +/** + * Returns `false`. + * @returns {boolean} `false`. + */ +function alwaysFalse() { + return false; +} + +var noUnusedExpressions = { + meta: { + type: "suggestion", + + docs: { + description: "disallow unused expressions", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-unused-expressions" + }, + + schema: [ + { + type: "object", + properties: { + allowShortCircuit: { + type: "boolean", + default: false + }, + allowTernary: { + type: "boolean", + default: false + }, + allowTaggedTemplates: { + type: "boolean", + default: false + }, + enforceForJSX: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + messages: { + unusedExpression: "Expected an assignment or function call and instead saw an expression." + } + }, + + create(context) { + const config = context.options[0] || {}, + allowShortCircuit = config.allowShortCircuit || false, + allowTernary = config.allowTernary || false, + allowTaggedTemplates = config.allowTaggedTemplates || false, + enforceForJSX = config.enforceForJSX || false; + + // eslint-disable-next-line jsdoc/require-description + /** + * @param {ASTNode} node any node + * @returns {boolean} whether the given node structurally represents a directive + */ + function looksLikeDirective(node) { + return node.type === "ExpressionStatement" && + node.expression.type === "Literal" && typeof node.expression.value === "string"; + } + + // eslint-disable-next-line jsdoc/require-description + /** + * @param {Function} predicate ([a] -> Boolean) the function used to make the determination + * @param {a[]} list the input list + * @returns {a[]} the leading sequence of members in the given list that pass the given predicate + */ + function takeWhile(predicate, list) { + for (let i = 0; i < list.length; ++i) { + if (!predicate(list[i])) { + return list.slice(0, i); + } + } + return list.slice(); + } + + // eslint-disable-next-line jsdoc/require-description + /** + * @param {ASTNode} node a Program or BlockStatement node + * @returns {ASTNode[]} the leading sequence of directive nodes in the given node's body + */ + function directives(node) { + return takeWhile(looksLikeDirective, node.body); + } + + // eslint-disable-next-line jsdoc/require-description + /** + * @param {ASTNode} node any node + * @param {ASTNode[]} ancestors the given node's ancestors + * @returns {boolean} whether the given node is considered a directive in its current position + */ + function isDirective(node, ancestors) { + const parent = ancestors[ancestors.length - 1], + grandparent = ancestors[ancestors.length - 2]; + + return (parent.type === "Program" || parent.type === "BlockStatement" && + (/Function/u.test(grandparent.type))) && + directives(parent).indexOf(node) >= 0; + } + + /** + * The member functions return `true` if the type has no side-effects. + * Unknown nodes are handled as `false`, then this rule ignores those. + */ + const Checker = Object.assign(Object.create(null), { + isDisallowed(node) { + return (Checker[node.type] || alwaysFalse)(node); + }, + + ArrayExpression: alwaysTrue, + ArrowFunctionExpression: alwaysTrue, + BinaryExpression: alwaysTrue, + ChainExpression(node) { + return Checker.isDisallowed(node.expression); + }, + ClassExpression: alwaysTrue, + ConditionalExpression(node) { + if (allowTernary) { + return Checker.isDisallowed(node.consequent) || Checker.isDisallowed(node.alternate); + } + return true; + }, + FunctionExpression: alwaysTrue, + Identifier: alwaysTrue, + JSXElement() { + return enforceForJSX; + }, + JSXFragment() { + return enforceForJSX; + }, + Literal: alwaysTrue, + LogicalExpression(node) { + if (allowShortCircuit) { + return Checker.isDisallowed(node.right); + } + return true; + }, + MemberExpression: alwaysTrue, + MetaProperty: alwaysTrue, + ObjectExpression: alwaysTrue, + SequenceExpression: alwaysTrue, + TaggedTemplateExpression() { + return !allowTaggedTemplates; + }, + TemplateLiteral: alwaysTrue, + ThisExpression: alwaysTrue, + UnaryExpression(node) { + return node.operator !== "void" && node.operator !== "delete"; + } + }); + + return { + ExpressionStatement(node) { + if (Checker.isDisallowed(node.expression) && !isDirective(node, context.getAncestors())) { + context.report({ node, messageId: "unusedExpression" }); + } + } + }; + } +}; + +/** + * @fileoverview Rule to disallow unused labels. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUnusedLabels = { + meta: { + type: "suggestion", + + docs: { + description: "disallow unused labels", + category: "Best Practices", + recommended: true, + url: "https://eslint.org/docs/rules/no-unused-labels" + }, + + schema: [], + + fixable: "code", + + messages: { + unused: "'{{name}}:' is defined but never used." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + let scopeInfo = null; + + /** + * Adds a scope info to the stack. + * @param {ASTNode} node A node to add. This is a LabeledStatement. + * @returns {void} + */ + function enterLabeledScope(node) { + scopeInfo = { + label: node.label.name, + used: false, + upper: scopeInfo + }; + } + + /** + * Removes the top of the stack. + * At the same time, this reports the label if it's never used. + * @param {ASTNode} node A node to report. This is a LabeledStatement. + * @returns {void} + */ + function exitLabeledScope(node) { + if (!scopeInfo.used) { + context.report({ + node: node.label, + messageId: "unused", + data: node.label, + fix(fixer) { + + /* + * Only perform a fix if there are no comments between the label and the body. This will be the case + * when there is exactly one token/comment (the ":") between the label and the body. + */ + if (sourceCode.getTokenAfter(node.label, { includeComments: true }) === + sourceCode.getTokenBefore(node.body, { includeComments: true })) { + return fixer.removeRange([node.range[0], node.body.range[0]]); + } + + return null; + } + }); + } + + scopeInfo = scopeInfo.upper; + } + + /** + * Marks the label of a given node as used. + * @param {ASTNode} node A node to mark. This is a BreakStatement or + * ContinueStatement. + * @returns {void} + */ + function markAsUsed(node) { + if (!node.label) { + return; + } + + const label = node.label.name; + let info = scopeInfo; + + while (info) { + if (info.label === label) { + info.used = true; + break; + } + info = info.upper; + } + } + + return { + LabeledStatement: enterLabeledScope, + "LabeledStatement:exit": exitLabeledScope, + BreakStatement: markAsUsed, + ContinueStatement: markAsUsed + }; + } +}; + +/** + * @fileoverview Rule to flag declared but unused variables + * @author Ilya Volodin + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Typedefs +//------------------------------------------------------------------------------ + +/** + * Bag of data used for formatting the `unusedVar` lint message. + * @typedef {Object} UnusedVarMessageData + * @property {string} varName The name of the unused var. + * @property {'defined'|'assigned a value'} action Description of the vars state. + * @property {string} additional Any additional info to be appended at the end. + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUnusedVars = { + meta: { + type: "problem", + + docs: { + description: "disallow unused variables", + category: "Variables", + recommended: true, + url: "https://eslint.org/docs/rules/no-unused-vars" + }, + + schema: [ + { + oneOf: [ + { + enum: ["all", "local"] + }, + { + type: "object", + properties: { + vars: { + enum: ["all", "local"] + }, + varsIgnorePattern: { + type: "string" + }, + args: { + enum: ["all", "after-used", "none"] + }, + ignoreRestSiblings: { + type: "boolean" + }, + argsIgnorePattern: { + type: "string" + }, + caughtErrors: { + enum: ["all", "none"] + }, + caughtErrorsIgnorePattern: { + type: "string" + } + }, + additionalProperties: false + } + ] + } + ], + + messages: { + unusedVar: "'{{varName}}' is {{action}} but never used{{additional}}." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + const REST_PROPERTY_TYPE = /^(?:RestElement|(?:Experimental)?RestProperty)$/u; + + const config = { + vars: "all", + args: "after-used", + ignoreRestSiblings: false, + caughtErrors: "none" + }; + + const firstOption = context.options[0]; + + if (firstOption) { + if (typeof firstOption === "string") { + config.vars = firstOption; + } else { + config.vars = firstOption.vars || config.vars; + config.args = firstOption.args || config.args; + config.ignoreRestSiblings = firstOption.ignoreRestSiblings || config.ignoreRestSiblings; + config.caughtErrors = firstOption.caughtErrors || config.caughtErrors; + + if (firstOption.varsIgnorePattern) { + config.varsIgnorePattern = new RegExp(firstOption.varsIgnorePattern, "u"); + } + + if (firstOption.argsIgnorePattern) { + config.argsIgnorePattern = new RegExp(firstOption.argsIgnorePattern, "u"); + } + + if (firstOption.caughtErrorsIgnorePattern) { + config.caughtErrorsIgnorePattern = new RegExp(firstOption.caughtErrorsIgnorePattern, "u"); + } + } + } + + /** + * Generates the message data about the variable being defined and unused, + * including the ignore pattern if configured. + * @param {Variable} unusedVar eslint-scope variable object. + * @returns {UnusedVarMessageData} The message data to be used with this unused variable. + */ + function getDefinedMessageData(unusedVar) { + const defType = unusedVar.defs && unusedVar.defs[0] && unusedVar.defs[0].type; + let type; + let pattern; + + if (defType === "CatchClause" && config.caughtErrorsIgnorePattern) { + type = "args"; + pattern = config.caughtErrorsIgnorePattern.toString(); + } else if (defType === "Parameter" && config.argsIgnorePattern) { + type = "args"; + pattern = config.argsIgnorePattern.toString(); + } else if (defType !== "Parameter" && config.varsIgnorePattern) { + type = "vars"; + pattern = config.varsIgnorePattern.toString(); + } + + const additional = type ? `. Allowed unused ${type} must match ${pattern}` : ""; + + return { + varName: unusedVar.name, + action: "defined", + additional + }; + } + + /** + * Generate the warning message about the variable being + * assigned and unused, including the ignore pattern if configured. + * @param {Variable} unusedVar eslint-scope variable object. + * @returns {UnusedVarMessageData} The message data to be used with this unused variable. + */ + function getAssignedMessageData(unusedVar) { + const additional = config.varsIgnorePattern ? `. Allowed unused vars must match ${config.varsIgnorePattern.toString()}` : ""; + + return { + varName: unusedVar.name, + action: "assigned a value", + additional + }; + } + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + const STATEMENT_TYPE = /(?:Statement|Declaration)$/u; + + /** + * Determines if a given variable is being exported from a module. + * @param {Variable} variable eslint-scope variable object. + * @returns {boolean} True if the variable is exported, false if not. + * @private + */ + function isExported(variable) { + + const definition = variable.defs[0]; + + if (definition) { + + let node = definition.node; + + if (node.type === "VariableDeclarator") { + node = node.parent; + } else if (definition.type === "Parameter") { + return false; + } + + return node.parent.type.indexOf("Export") === 0; + } + return false; + + } + + /** + * Checks whether a node is a sibling of the rest property or not. + * @param {ASTNode} node a node to check + * @returns {boolean} True if the node is a sibling of the rest property, otherwise false. + */ + function hasRestSibling(node) { + return node.type === "Property" && + node.parent.type === "ObjectPattern" && + REST_PROPERTY_TYPE.test(node.parent.properties[node.parent.properties.length - 1].type); + } + + /** + * Determines if a variable has a sibling rest property + * @param {Variable} variable eslint-scope variable object. + * @returns {boolean} True if the variable is exported, false if not. + * @private + */ + function hasRestSpreadSibling(variable) { + if (config.ignoreRestSiblings) { + const hasRestSiblingDefinition = variable.defs.some(def => hasRestSibling(def.name.parent)); + const hasRestSiblingReference = variable.references.some(ref => hasRestSibling(ref.identifier.parent)); + + return hasRestSiblingDefinition || hasRestSiblingReference; + } + + return false; + } + + /** + * Determines if a reference is a read operation. + * @param {Reference} ref An eslint-scope Reference + * @returns {boolean} whether the given reference represents a read operation + * @private + */ + function isReadRef(ref) { + return ref.isRead(); + } + + /** + * Determine if an identifier is referencing an enclosing function name. + * @param {Reference} ref The reference to check. + * @param {ASTNode[]} nodes The candidate function nodes. + * @returns {boolean} True if it's a self-reference, false if not. + * @private + */ + function isSelfReference(ref, nodes) { + let scope = ref.from; + + while (scope) { + if (nodes.indexOf(scope.block) >= 0) { + return true; + } + + scope = scope.upper; + } + + return false; + } + + /** + * Gets a list of function definitions for a specified variable. + * @param {Variable} variable eslint-scope variable object. + * @returns {ASTNode[]} Function nodes. + * @private + */ + function getFunctionDefinitions(variable) { + const functionDefinitions = []; + + variable.defs.forEach(def => { + const { type, node } = def; + + // FunctionDeclarations + if (type === "FunctionName") { + functionDefinitions.push(node); + } + + // FunctionExpressions + if (type === "Variable" && node.init && + (node.init.type === "FunctionExpression" || node.init.type === "ArrowFunctionExpression")) { + functionDefinitions.push(node.init); + } + }); + return functionDefinitions; + } + + /** + * Checks the position of given nodes. + * @param {ASTNode} inner A node which is expected as inside. + * @param {ASTNode} outer A node which is expected as outside. + * @returns {boolean} `true` if the `inner` node exists in the `outer` node. + * @private + */ + function isInside(inner, outer) { + return ( + inner.range[0] >= outer.range[0] && + inner.range[1] <= outer.range[1] + ); + } + + /** + * If a given reference is left-hand side of an assignment, this gets + * the right-hand side node of the assignment. + * + * In the following cases, this returns null. + * + * - The reference is not the LHS of an assignment expression. + * - The reference is inside of a loop. + * - The reference is inside of a function scope which is different from + * the declaration. + * @param {eslint-scope.Reference} ref A reference to check. + * @param {ASTNode} prevRhsNode The previous RHS node. + * @returns {ASTNode|null} The RHS node or null. + * @private + */ + function getRhsNode(ref, prevRhsNode) { + const id = ref.identifier; + const parent = id.parent; + const grandparent = parent.parent; + const refScope = ref.from.variableScope; + const varScope = ref.resolved.scope.variableScope; + const canBeUsedLater = refScope !== varScope || astUtils.isInLoop(id); + + /* + * Inherits the previous node if this reference is in the node. + * This is for `a = a + a`-like code. + */ + if (prevRhsNode && isInside(id, prevRhsNode)) { + return prevRhsNode; + } + + if (parent.type === "AssignmentExpression" && + grandparent.type === "ExpressionStatement" && + id === parent.left && + !canBeUsedLater + ) { + return parent.right; + } + return null; + } + + /** + * Checks whether a given function node is stored to somewhere or not. + * If the function node is stored, the function can be used later. + * @param {ASTNode} funcNode A function node to check. + * @param {ASTNode} rhsNode The RHS node of the previous assignment. + * @returns {boolean} `true` if under the following conditions: + * - the funcNode is assigned to a variable. + * - the funcNode is bound as an argument of a function call. + * - the function is bound to a property and the object satisfies above conditions. + * @private + */ + function isStorableFunction(funcNode, rhsNode) { + let node = funcNode; + let parent = funcNode.parent; + + while (parent && isInside(parent, rhsNode)) { + switch (parent.type) { + case "SequenceExpression": + if (parent.expressions[parent.expressions.length - 1] !== node) { + return false; + } + break; + + case "CallExpression": + case "NewExpression": + return parent.callee !== node; + + case "AssignmentExpression": + case "TaggedTemplateExpression": + case "YieldExpression": + return true; + + default: + if (STATEMENT_TYPE.test(parent.type)) { + + /* + * If it encountered statements, this is a complex pattern. + * Since analyzing complex patterns is hard, this returns `true` to avoid false positive. + */ + return true; + } + } + + node = parent; + parent = parent.parent; + } + + return false; + } + + /** + * Checks whether a given Identifier node exists inside of a function node which can be used later. + * + * "can be used later" means: + * - the function is assigned to a variable. + * - the function is bound to a property and the object can be used later. + * - the function is bound as an argument of a function call. + * + * If a reference exists in a function which can be used later, the reference is read when the function is called. + * @param {ASTNode} id An Identifier node to check. + * @param {ASTNode} rhsNode The RHS node of the previous assignment. + * @returns {boolean} `true` if the `id` node exists inside of a function node which can be used later. + * @private + */ + function isInsideOfStorableFunction(id, rhsNode) { + const funcNode = astUtils.getUpperFunction(id); + + return ( + funcNode && + isInside(funcNode, rhsNode) && + isStorableFunction(funcNode, rhsNode) + ); + } + + /** + * Checks whether a given reference is a read to update itself or not. + * @param {eslint-scope.Reference} ref A reference to check. + * @param {ASTNode} rhsNode The RHS node of the previous assignment. + * @returns {boolean} The reference is a read to update itself. + * @private + */ + function isReadForItself(ref, rhsNode) { + const id = ref.identifier; + const parent = id.parent; + const grandparent = parent.parent; + + return ref.isRead() && ( + + // self update. e.g. `a += 1`, `a++` + (// in RHS of an assignment for itself. e.g. `a = a + 1` + (( + parent.type === "AssignmentExpression" && + grandparent.type === "ExpressionStatement" && + parent.left === id + ) || + ( + parent.type === "UpdateExpression" && + grandparent.type === "ExpressionStatement" + ) || rhsNode && + isInside(id, rhsNode) && + !isInsideOfStorableFunction(id, rhsNode))) + ); + } + + /** + * Determine if an identifier is used either in for-in loops. + * @param {Reference} ref The reference to check. + * @returns {boolean} whether reference is used in the for-in loops + * @private + */ + function isForInRef(ref) { + let target = ref.identifier.parent; + + + // "for (var ...) { return; }" + if (target.type === "VariableDeclarator") { + target = target.parent.parent; + } + + if (target.type !== "ForInStatement") { + return false; + } + + // "for (...) { return; }" + if (target.body.type === "BlockStatement") { + target = target.body.body[0]; + + // "for (...) return;" + } else { + target = target.body; + } + + // For empty loop body + if (!target) { + return false; + } + + return target.type === "ReturnStatement"; + } + + /** + * Determines if the variable is used. + * @param {Variable} variable The variable to check. + * @returns {boolean} True if the variable is used + * @private + */ + function isUsedVariable(variable) { + const functionNodes = getFunctionDefinitions(variable), + isFunctionDefinition = functionNodes.length > 0; + let rhsNode = null; + + return variable.references.some(ref => { + if (isForInRef(ref)) { + return true; + } + + const forItself = isReadForItself(ref, rhsNode); + + rhsNode = getRhsNode(ref, rhsNode); + + return ( + isReadRef(ref) && + !forItself && + !(isFunctionDefinition && isSelfReference(ref, functionNodes)) + ); + }); + } + + /** + * Checks whether the given variable is after the last used parameter. + * @param {eslint-scope.Variable} variable The variable to check. + * @returns {boolean} `true` if the variable is defined after the last + * used parameter. + */ + function isAfterLastUsedArg(variable) { + const def = variable.defs[0]; + const params = context.getDeclaredVariables(def.node); + const posteriorParams = params.slice(params.indexOf(variable) + 1); + + // If any used parameters occur after this parameter, do not report. + return !posteriorParams.some(v => v.references.length > 0 || v.eslintUsed); + } + + /** + * Gets an array of variables without read references. + * @param {Scope} scope an eslint-scope Scope object. + * @param {Variable[]} unusedVars an array that saving result. + * @returns {Variable[]} unused variables of the scope and descendant scopes. + * @private + */ + function collectUnusedVariables(scope, unusedVars) { + const variables = scope.variables; + const childScopes = scope.childScopes; + let i, l; + + if (scope.type !== "global" || config.vars === "all") { + for (i = 0, l = variables.length; i < l; ++i) { + const variable = variables[i]; + + // skip a variable of class itself name in the class scope + if (scope.type === "class" && scope.block.id === variable.identifiers[0]) { + continue; + } + + // skip function expression names and variables marked with markVariableAsUsed() + if (scope.functionExpressionScope || variable.eslintUsed) { + continue; + } + + // skip implicit "arguments" variable + if (scope.type === "function" && variable.name === "arguments" && variable.identifiers.length === 0) { + continue; + } + + // explicit global variables don't have definitions. + const def = variable.defs[0]; + + if (def) { + const type = def.type; + + // skip catch variables + if (type === "CatchClause") { + if (config.caughtErrors === "none") { + continue; + } + + // skip ignored parameters + if (config.caughtErrorsIgnorePattern && config.caughtErrorsIgnorePattern.test(def.name.name)) { + continue; + } + } + + if (type === "Parameter") { + + // skip any setter argument + if ((def.node.parent.type === "Property" || def.node.parent.type === "MethodDefinition") && def.node.parent.kind === "set") { + continue; + } + + // if "args" option is "none", skip any parameter + if (config.args === "none") { + continue; + } + + // skip ignored parameters + if (config.argsIgnorePattern && config.argsIgnorePattern.test(def.name.name)) { + continue; + } + + // if "args" option is "after-used", skip used variables + if (config.args === "after-used" && astUtils.isFunction(def.name.parent) && !isAfterLastUsedArg(variable)) { + continue; + } + } else { + + // skip ignored variables + if (config.varsIgnorePattern && config.varsIgnorePattern.test(def.name.name)) { + continue; + } + } + } + + if (!isUsedVariable(variable) && !isExported(variable) && !hasRestSpreadSibling(variable)) { + unusedVars.push(variable); + } + } + } + + for (i = 0, l = childScopes.length; i < l; ++i) { + collectUnusedVariables(childScopes[i], unusedVars); + } + + return unusedVars; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + "Program:exit"(programNode) { + const unusedVars = collectUnusedVariables(context.getScope(), []); + + for (let i = 0, l = unusedVars.length; i < l; ++i) { + const unusedVar = unusedVars[i]; + + // Report the first declaration. + if (unusedVar.defs.length > 0) { + context.report({ + node: unusedVar.references.length ? unusedVar.references[ + unusedVar.references.length - 1 + ].identifier : unusedVar.identifiers[0], + messageId: "unusedVar", + data: unusedVar.references.some(ref => ref.isWrite()) + ? getAssignedMessageData(unusedVar) + : getDefinedMessageData(unusedVar) + }); + + // If there are no regular declaration, report the first `/*globals*/` comment directive. + } else if (unusedVar.eslintExplicitGlobalComments) { + const directiveComment = unusedVar.eslintExplicitGlobalComments[0]; + + context.report({ + node: programNode, + loc: astUtils.getNameLocationInGlobalDirectiveComment(sourceCode, directiveComment, unusedVar.name), + messageId: "unusedVar", + data: getDefinedMessageData(unusedVar) + }); + } + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag use of variables before they are defined + * @author Ilya Volodin + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const SENTINEL_TYPE = /^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/u; +const FOR_IN_OF_TYPE = /^For(?:In|Of)Statement$/u; + +/** + * Parses a given value as options. + * @param {any} options A value to parse. + * @returns {Object} The parsed options. + */ +function parseOptions(options) { + let functions = true; + let classes = true; + let variables = true; + + if (typeof options === "string") { + functions = (options !== "nofunc"); + } else if (typeof options === "object" && options !== null) { + functions = options.functions !== false; + classes = options.classes !== false; + variables = options.variables !== false; + } + + return { functions, classes, variables }; +} + +/** + * Checks whether or not a given variable is a function declaration. + * @param {eslint-scope.Variable} variable A variable to check. + * @returns {boolean} `true` if the variable is a function declaration. + */ +function isFunction(variable) { + return variable.defs[0].type === "FunctionName"; +} + +/** + * Checks whether or not a given variable is a class declaration in an upper function scope. + * @param {eslint-scope.Variable} variable A variable to check. + * @param {eslint-scope.Reference} reference A reference to check. + * @returns {boolean} `true` if the variable is a class declaration. + */ +function isOuterClass(variable, reference) { + return ( + variable.defs[0].type === "ClassName" && + variable.scope.variableScope !== reference.from.variableScope + ); +} + +/** + * Checks whether or not a given variable is a variable declaration in an upper function scope. + * @param {eslint-scope.Variable} variable A variable to check. + * @param {eslint-scope.Reference} reference A reference to check. + * @returns {boolean} `true` if the variable is a variable declaration. + */ +function isOuterVariable(variable, reference) { + return ( + variable.defs[0].type === "Variable" && + variable.scope.variableScope !== reference.from.variableScope + ); +} + +/** + * Checks whether or not a given location is inside of the range of a given node. + * @param {ASTNode} node An node to check. + * @param {number} location A location to check. + * @returns {boolean} `true` if the location is inside of the range of the node. + */ +function isInRange(node, location) { + return node && node.range[0] <= location && location <= node.range[1]; +} + +/** + * Checks whether or not a given reference is inside of the initializers of a given variable. + * + * This returns `true` in the following cases: + * + * var a = a + * var [a = a] = list + * var {a = a} = obj + * for (var a in a) {} + * for (var a of a) {} + * @param {Variable} variable A variable to check. + * @param {Reference} reference A reference to check. + * @returns {boolean} `true` if the reference is inside of the initializers. + */ +function isInInitializer(variable, reference) { + if (variable.scope !== reference.from) { + return false; + } + + let node = variable.identifiers[0].parent; + const location = reference.identifier.range[1]; + + while (node) { + if (node.type === "VariableDeclarator") { + if (isInRange(node.init, location)) { + return true; + } + if (FOR_IN_OF_TYPE.test(node.parent.parent.type) && + isInRange(node.parent.parent.right, location) + ) { + return true; + } + break; + } else if (node.type === "AssignmentPattern") { + if (isInRange(node.right, location)) { + return true; + } + } else if (SENTINEL_TYPE.test(node.type)) { + break; + } + + node = node.parent; + } + + return false; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUseBeforeDefine = { + meta: { + type: "problem", + + docs: { + description: "disallow the use of variables before they are defined", + category: "Variables", + recommended: false, + url: "https://eslint.org/docs/rules/no-use-before-define" + }, + + schema: [ + { + oneOf: [ + { + enum: ["nofunc"] + }, + { + type: "object", + properties: { + functions: { type: "boolean" }, + classes: { type: "boolean" }, + variables: { type: "boolean" } + }, + additionalProperties: false + } + ] + } + ], + + messages: { + usedBeforeDefined: "'{{name}}' was used before it was defined." + } + }, + + create(context) { + const options = parseOptions(context.options[0]); + + /** + * Determines whether a given use-before-define case should be reported according to the options. + * @param {eslint-scope.Variable} variable The variable that gets used before being defined + * @param {eslint-scope.Reference} reference The reference to the variable + * @returns {boolean} `true` if the usage should be reported + */ + function isForbidden(variable, reference) { + if (isFunction(variable)) { + return options.functions; + } + if (isOuterClass(variable, reference)) { + return options.classes; + } + if (isOuterVariable(variable, reference)) { + return options.variables; + } + return true; + } + + /** + * Finds and validates all variables in a given scope. + * @param {Scope} scope The scope object. + * @returns {void} + * @private + */ + function findVariablesInScope(scope) { + scope.references.forEach(reference => { + const variable = reference.resolved; + + /* + * Skips when the reference is: + * - initialization's. + * - referring to an undefined variable. + * - referring to a global environment variable (there're no identifiers). + * - located preceded by the variable (except in initializers). + * - allowed by options. + */ + if (reference.init || + !variable || + variable.identifiers.length === 0 || + (variable.identifiers[0].range[1] < reference.identifier.range[1] && !isInInitializer(variable, reference)) || + !isForbidden(variable, reference) + ) { + return; + } + + // Reports. + context.report({ + node: reference.identifier, + messageId: "usedBeforeDefined", + data: reference.identifier + }); + }); + + scope.childScopes.forEach(findVariablesInScope); + } + + return { + Program() { + findVariablesInScope(context.getScope()); + } + }; + } +}; + +/** + * @fileoverview Rule to disallow useless backreferences in regular expressions + * @author Milos Djermanovic + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const { CALL: CALL$5, CONSTRUCT: CONSTRUCT$3, ReferenceTracker: ReferenceTracker$5, getStringIfConstant: getStringIfConstant$2 } = require$$0__default$1['default']; +const { RegExpParser, visitRegExpAST } = regexpp__default['default']; + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const parser$1 = new RegExpParser(); + +/** + * Finds the path from the given `regexpp` AST node to the root node. + * @param {regexpp.Node} node Node. + * @returns {regexpp.Node[]} Array that starts with the given node and ends with the root node. + */ +function getPathToRoot(node) { + const path = []; + let current = node; + + do { + path.push(current); + current = current.parent; + } while (current); + + return path; +} + +/** + * Determines whether the given `regexpp` AST node is a lookaround node. + * @param {regexpp.Node} node Node. + * @returns {boolean} `true` if it is a lookaround node. + */ +function isLookaround(node) { + return node.type === "Assertion" && + (node.kind === "lookahead" || node.kind === "lookbehind"); +} + +/** + * Determines whether the given `regexpp` AST node is a negative lookaround node. + * @param {regexpp.Node} node Node. + * @returns {boolean} `true` if it is a negative lookaround node. + */ +function isNegativeLookaround(node) { + return isLookaround(node) && node.negate; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUselessBackreference = { + meta: { + type: "problem", + + docs: { + description: "disallow useless backreferences in regular expressions", + category: "Possible Errors", + recommended: false, + url: "https://eslint.org/docs/rules/no-useless-backreference" + }, + + schema: [], + + messages: { + nested: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' from within that group.", + forward: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which appears later in the pattern.", + backward: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which appears before in the same lookbehind.", + disjunctive: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which is in another alternative.", + intoNegativeLookaround: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which is in a negative lookaround." + } + }, + + create(context) { + + /** + * Checks and reports useless backreferences in the given regular expression. + * @param {ASTNode} node Node that represents regular expression. A regex literal or RegExp constructor call. + * @param {string} pattern Regular expression pattern. + * @param {string} flags Regular expression flags. + * @returns {void} + */ + function checkRegex(node, pattern, flags) { + let regExpAST; + + try { + regExpAST = parser$1.parsePattern(pattern, 0, pattern.length, flags.includes("u")); + } catch { + + // Ignore regular expressions with syntax errors + return; + } + + visitRegExpAST(regExpAST, { + onBackreferenceEnter(bref) { + const group = bref.resolved, + brefPath = getPathToRoot(bref), + groupPath = getPathToRoot(group); + let messageId = null; + + if (brefPath.includes(group)) { + + // group is bref's ancestor => bref is nested ('nested reference') => group hasn't matched yet when bref starts to match. + messageId = "nested"; + } else { + + // Start from the root to find the lowest common ancestor. + let i = brefPath.length - 1, + j = groupPath.length - 1; + + do { + i--; + j--; + } while (brefPath[i] === groupPath[j]); + + const indexOfLowestCommonAncestor = j + 1, + groupCut = groupPath.slice(0, indexOfLowestCommonAncestor), + commonPath = groupPath.slice(indexOfLowestCommonAncestor), + lowestCommonLookaround = commonPath.find(isLookaround), + isMatchingBackward = lowestCommonLookaround && lowestCommonLookaround.kind === "lookbehind"; + + if (!isMatchingBackward && bref.end <= group.start) { + + // bref is left, group is right ('forward reference') => group hasn't matched yet when bref starts to match. + messageId = "forward"; + } else if (isMatchingBackward && group.end <= bref.start) { + + // the opposite of the previous when the regex is matching backward in a lookbehind context. + messageId = "backward"; + } else if (lodash__default['default'].last(groupCut).type === "Alternative") { + + // group's and bref's ancestor nodes below the lowest common ancestor are sibling alternatives => they're disjunctive. + messageId = "disjunctive"; + } else if (groupCut.some(isNegativeLookaround)) { + + // group is in a negative lookaround which isn't bref's ancestor => group has already failed when bref starts to match. + messageId = "intoNegativeLookaround"; + } + } + + if (messageId) { + context.report({ + node, + messageId, + data: { + bref: bref.raw, + group: group.raw + } + }); + } + } + }); + } + + return { + "Literal[regex]"(node) { + const { pattern, flags } = node.regex; + + checkRegex(node, pattern, flags); + }, + Program() { + const scope = context.getScope(), + tracker = new ReferenceTracker$5(scope), + traceMap = { + RegExp: { + [CALL$5]: true, + [CONSTRUCT$3]: true + } + }; + + for (const { node } of tracker.iterateGlobalReferences(traceMap)) { + const [patternNode, flagsNode] = node.arguments, + pattern = getStringIfConstant$2(patternNode, scope), + flags = getStringIfConstant$2(flagsNode, scope); + + if (typeof pattern === "string") { + checkRegex(node, pattern, flags || ""); + } + } + } + }; + } +}; + +/** + * @fileoverview A rule to disallow unnecessary `.call()` and `.apply()`. + * @author Toru Nagashima + */ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a node is a `.call()`/`.apply()`. + * @param {ASTNode} node A CallExpression node to check. + * @returns {boolean} Whether or not the node is a `.call()`/`.apply()`. + */ +function isCallOrNonVariadicApply(node) { + const callee = astUtils.skipChainExpression(node.callee); + + return ( + callee.type === "MemberExpression" && + callee.property.type === "Identifier" && + callee.computed === false && + ( + (callee.property.name === "call" && node.arguments.length >= 1) || + (callee.property.name === "apply" && node.arguments.length === 2 && node.arguments[1].type === "ArrayExpression") + ) + ); +} + + +/** + * Checks whether or not `thisArg` is not changed by `.call()`/`.apply()`. + * @param {ASTNode|null} expectedThis The node that is the owner of the applied function. + * @param {ASTNode} thisArg The node that is given to the first argument of the `.call()`/`.apply()`. + * @param {SourceCode} sourceCode The ESLint source code object. + * @returns {boolean} Whether or not `thisArg` is not changed by `.call()`/`.apply()`. + */ +function isValidThisArg$1(expectedThis, thisArg, sourceCode) { + if (!expectedThis) { + return astUtils.isNullOrUndefined(thisArg); + } + return astUtils.equalTokens(expectedThis, thisArg, sourceCode); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUselessCall = { + meta: { + type: "suggestion", + + docs: { + description: "disallow unnecessary calls to `.call()` and `.apply()`", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-useless-call" + }, + + schema: [], + + messages: { + unnecessaryCall: "Unnecessary '.{{name}}()'." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + CallExpression(node) { + if (!isCallOrNonVariadicApply(node)) { + return; + } + + const callee = astUtils.skipChainExpression(node.callee); + const applied = astUtils.skipChainExpression(callee.object); + const expectedThis = (applied.type === "MemberExpression") ? applied.object : null; + const thisArg = node.arguments[0]; + + if (isValidThisArg$1(expectedThis, thisArg, sourceCode)) { + context.report({ node, messageId: "unnecessaryCall", data: { name: callee.property.name } }); + } + } + }; + } +}; + +/** + * @fileoverview Reports useless `catch` clauses that just rethrow their error. + * @author Teddy Katz + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUselessCatch = { + meta: { + type: "suggestion", + + docs: { + description: "disallow unnecessary `catch` clauses", + category: "Best Practices", + recommended: true, + url: "https://eslint.org/docs/rules/no-useless-catch" + }, + + schema: [], + + messages: { + unnecessaryCatchClause: "Unnecessary catch clause.", + unnecessaryCatch: "Unnecessary try/catch wrapper." + } + }, + + create(context) { + return { + CatchClause(node) { + if ( + node.param && + node.param.type === "Identifier" && + node.body.body.length && + node.body.body[0].type === "ThrowStatement" && + node.body.body[0].argument.type === "Identifier" && + node.body.body[0].argument.name === node.param.name + ) { + if (node.parent.finalizer) { + context.report({ + node, + messageId: "unnecessaryCatchClause" + }); + } else { + context.report({ + node: node.parent, + messageId: "unnecessaryCatch" + }); + } + } + } + }; + } +}; + +/** + * @fileoverview Rule to disallow unnecessary computed property keys in object literals + * @author Burak Yigit Kaya + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUselessComputedKey = { + meta: { + type: "suggestion", + + docs: { + description: "disallow unnecessary computed property keys in objects and classes", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/no-useless-computed-key" + }, + + schema: [{ + type: "object", + properties: { + enforceForClassMembers: { + type: "boolean", + default: false + } + }, + additionalProperties: false + }], + fixable: "code", + + messages: { + unnecessarilyComputedProperty: "Unnecessarily computed property [{{property}}] found." + } + }, + create(context) { + const sourceCode = context.getSourceCode(); + const enforceForClassMembers = context.options[0] && context.options[0].enforceForClassMembers; + + /** + * Reports a given node if it violated this rule. + * @param {ASTNode} node The node to check. + * @returns {void} + */ + function check(node) { + if (!node.computed) { + return; + } + + const key = node.key, + nodeType = typeof key.value; + + let allowedKey; + + if (node.type === "MethodDefinition") { + allowedKey = node.static ? "prototype" : "constructor"; + } else { + allowedKey = "__proto__"; + } + + if (key.type === "Literal" && (nodeType === "string" || nodeType === "number") && key.value !== allowedKey) { + context.report({ + node, + messageId: "unnecessarilyComputedProperty", + data: { property: sourceCode.getText(key) }, + fix(fixer) { + const leftSquareBracket = sourceCode.getTokenBefore(key, astUtils.isOpeningBracketToken); + const rightSquareBracket = sourceCode.getTokenAfter(key, astUtils.isClosingBracketToken); + + // If there are comments between the brackets and the property name, don't do a fix. + if (sourceCode.commentsExistBetween(leftSquareBracket, rightSquareBracket)) { + return null; + } + + const tokenBeforeLeftBracket = sourceCode.getTokenBefore(leftSquareBracket); + + // Insert a space before the key to avoid changing identifiers, e.g. ({ get[2]() {} }) to ({ get2() {} }) + const needsSpaceBeforeKey = tokenBeforeLeftBracket.range[1] === leftSquareBracket.range[0] && + !astUtils.canTokensBeAdjacent(tokenBeforeLeftBracket, sourceCode.getFirstToken(key)); + + const replacementKey = (needsSpaceBeforeKey ? " " : "") + key.raw; + + return fixer.replaceTextRange([leftSquareBracket.range[0], rightSquareBracket.range[1]], replacementKey); + } + }); + } + } + + return { + Property: check, + MethodDefinition: enforceForClassMembers ? check : lodash__default['default'].noop + }; + } +}; + +/** + * @fileoverview disallow unnecessary concatenation of template strings + * @author Henry Zhu + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a given node is a concatenation. + * @param {ASTNode} node A node to check. + * @returns {boolean} `true` if the node is a concatenation. + */ +function isConcatenation$1(node) { + return node.type === "BinaryExpression" && node.operator === "+"; +} + +/** + * Checks if the given token is a `+` token or not. + * @param {Token} token The token to check. + * @returns {boolean} `true` if the token is a `+` token. + */ +function isConcatOperatorToken(token) { + return token.value === "+" && token.type === "Punctuator"; +} + +/** + * Get's the right most node on the left side of a BinaryExpression with + operator. + * @param {ASTNode} node A BinaryExpression node to check. + * @returns {ASTNode} node + */ +function getLeft(node) { + let left = node.left; + + while (isConcatenation$1(left)) { + left = left.right; + } + return left; +} + +/** + * Get's the left most node on the right side of a BinaryExpression with + operator. + * @param {ASTNode} node A BinaryExpression node to check. + * @returns {ASTNode} node + */ +function getRight(node) { + let right = node.right; + + while (isConcatenation$1(right)) { + right = right.left; + } + return right; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUselessConcat = { + meta: { + type: "suggestion", + + docs: { + description: "disallow unnecessary concatenation of literals or template literals", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-useless-concat" + }, + + schema: [], + + messages: { + unexpectedConcat: "Unexpected string concatenation of literals." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + BinaryExpression(node) { + + // check if not concatenation + if (node.operator !== "+") { + return; + } + + // account for the `foo + "a" + "b"` case + const left = getLeft(node); + const right = getRight(node); + + if (astUtils.isStringLiteral(left) && + astUtils.isStringLiteral(right) && + astUtils.isTokenOnSameLine(left, right) + ) { + const operatorToken = sourceCode.getFirstTokenBetween(left, right, isConcatOperatorToken); + + context.report({ + node, + loc: operatorToken.loc, + messageId: "unexpectedConcat" + }); + } + } + }; + } +}; + +/** + * @fileoverview Rule to flag the use of redundant constructors in classes. + * @author Alberto Rodríguez + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether a given array of statements is a single call of `super`. + * @param {ASTNode[]} body An array of statements to check. + * @returns {boolean} `true` if the body is a single call of `super`. + */ +function isSingleSuperCall(body) { + return ( + body.length === 1 && + body[0].type === "ExpressionStatement" && + body[0].expression.type === "CallExpression" && + body[0].expression.callee.type === "Super" + ); +} + +/** + * Checks whether a given node is a pattern which doesn't have any side effects. + * Default parameters and Destructuring parameters can have side effects. + * @param {ASTNode} node A pattern node. + * @returns {boolean} `true` if the node doesn't have any side effects. + */ +function isSimple(node) { + return node.type === "Identifier" || node.type === "RestElement"; +} + +/** + * Checks whether a given array of expressions is `...arguments` or not. + * `super(...arguments)` passes all arguments through. + * @param {ASTNode[]} superArgs An array of expressions to check. + * @returns {boolean} `true` if the superArgs is `...arguments`. + */ +function isSpreadArguments(superArgs) { + return ( + superArgs.length === 1 && + superArgs[0].type === "SpreadElement" && + superArgs[0].argument.type === "Identifier" && + superArgs[0].argument.name === "arguments" + ); +} + +/** + * Checks whether given 2 nodes are identifiers which have the same name or not. + * @param {ASTNode} ctorParam A node to check. + * @param {ASTNode} superArg A node to check. + * @returns {boolean} `true` if the nodes are identifiers which have the same + * name. + */ +function isValidIdentifierPair(ctorParam, superArg) { + return ( + ctorParam.type === "Identifier" && + superArg.type === "Identifier" && + ctorParam.name === superArg.name + ); +} + +/** + * Checks whether given 2 nodes are a rest/spread pair which has the same values. + * @param {ASTNode} ctorParam A node to check. + * @param {ASTNode} superArg A node to check. + * @returns {boolean} `true` if the nodes are a rest/spread pair which has the + * same values. + */ +function isValidRestSpreadPair(ctorParam, superArg) { + return ( + ctorParam.type === "RestElement" && + superArg.type === "SpreadElement" && + isValidIdentifierPair(ctorParam.argument, superArg.argument) + ); +} + +/** + * Checks whether given 2 nodes have the same value or not. + * @param {ASTNode} ctorParam A node to check. + * @param {ASTNode} superArg A node to check. + * @returns {boolean} `true` if the nodes have the same value or not. + */ +function isValidPair(ctorParam, superArg) { + return ( + isValidIdentifierPair(ctorParam, superArg) || + isValidRestSpreadPair(ctorParam, superArg) + ); +} + +/** + * Checks whether the parameters of a constructor and the arguments of `super()` + * have the same values or not. + * @param {ASTNode} ctorParams The parameters of a constructor to check. + * @param {ASTNode} superArgs The arguments of `super()` to check. + * @returns {boolean} `true` if those have the same values. + */ +function isPassingThrough(ctorParams, superArgs) { + if (ctorParams.length !== superArgs.length) { + return false; + } + + for (let i = 0; i < ctorParams.length; ++i) { + if (!isValidPair(ctorParams[i], superArgs[i])) { + return false; + } + } + + return true; +} + +/** + * Checks whether the constructor body is a redundant super call. + * @param {Array} body constructor body content. + * @param {Array} ctorParams The params to check against super call. + * @returns {boolean} true if the constructor body is redundant + */ +function isRedundantSuperCall(body, ctorParams) { + return ( + isSingleSuperCall(body) && + ctorParams.every(isSimple) && + ( + isSpreadArguments(body[0].expression.arguments) || + isPassingThrough(ctorParams, body[0].expression.arguments) + ) + ); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUselessConstructor = { + meta: { + type: "suggestion", + + docs: { + description: "disallow unnecessary constructors", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/no-useless-constructor" + }, + + schema: [], + + messages: { + noUselessConstructor: "Useless constructor." + } + }, + + create(context) { + + /** + * Checks whether a node is a redundant constructor + * @param {ASTNode} node node to check + * @returns {void} + */ + function checkForConstructor(node) { + if (node.kind !== "constructor") { + return; + } + + /* + * Prevent crashing on parsers which do not require class constructor + * to have a body, e.g. typescript and flow + */ + if (!node.value.body) { + return; + } + + const body = node.value.body.body; + const ctorParams = node.value.params; + const superClass = node.parent.parent.superClass; + + if (superClass ? isRedundantSuperCall(body, ctorParams) : (body.length === 0)) { + context.report({ + node, + messageId: "noUselessConstructor" + }); + } + } + + return { + MethodDefinition: checkForConstructor + }; + } +}; + +/** + * @fileoverview Look for useless escapes in strings and regexes + * @author Onur Temizkan + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +/** + * Returns the union of two sets. + * @param {Set} setA The first set + * @param {Set} setB The second set + * @returns {Set} The union of the two sets + */ +function union(setA, setB) { + return new Set(function *() { + yield* setA; + yield* setB; + }()); +} + +const VALID_STRING_ESCAPES = union(new Set("\\nrvtbfux"), astUtils.LINEBREAKS); +const REGEX_GENERAL_ESCAPES = new Set("\\bcdDfnpPrsStvwWxu0123456789]"); +const REGEX_NON_CHARCLASS_ESCAPES = union(REGEX_GENERAL_ESCAPES, new Set("^/.$*+?[{}|()Bk")); + +/** + * Parses a regular expression into a list of characters with character class info. + * @param {string} regExpText The raw text used to create the regular expression + * @returns {Object[]} A list of characters, each with info on escaping and whether they're in a character class. + * @example + * + * parseRegExp('a\\b[cd-]') + * + * returns: + * [ + * {text: 'a', index: 0, escaped: false, inCharClass: false, startsCharClass: false, endsCharClass: false}, + * {text: 'b', index: 2, escaped: true, inCharClass: false, startsCharClass: false, endsCharClass: false}, + * {text: 'c', index: 4, escaped: false, inCharClass: true, startsCharClass: true, endsCharClass: false}, + * {text: 'd', index: 5, escaped: false, inCharClass: true, startsCharClass: false, endsCharClass: false}, + * {text: '-', index: 6, escaped: false, inCharClass: true, startsCharClass: false, endsCharClass: false} + * ] + */ +function parseRegExp(regExpText) { + const charList = []; + + regExpText.split("").reduce((state, char, index) => { + if (!state.escapeNextChar) { + if (char === "\\") { + return Object.assign(state, { escapeNextChar: true }); + } + if (char === "[" && !state.inCharClass) { + return Object.assign(state, { inCharClass: true, startingCharClass: true }); + } + if (char === "]" && state.inCharClass) { + if (charList.length && charList[charList.length - 1].inCharClass) { + charList[charList.length - 1].endsCharClass = true; + } + return Object.assign(state, { inCharClass: false, startingCharClass: false }); + } + } + charList.push({ + text: char, + index, + escaped: state.escapeNextChar, + inCharClass: state.inCharClass, + startsCharClass: state.startingCharClass, + endsCharClass: false + }); + return Object.assign(state, { escapeNextChar: false, startingCharClass: false }); + }, { escapeNextChar: false, inCharClass: false, startingCharClass: false }); + + return charList; +} + +var noUselessEscape = { + meta: { + type: "suggestion", + + docs: { + description: "disallow unnecessary escape characters", + category: "Best Practices", + recommended: true, + url: "https://eslint.org/docs/rules/no-useless-escape", + suggestion: true + }, + + messages: { + unnecessaryEscape: "Unnecessary escape character: \\{{character}}.", + removeEscape: "Remove the `\\`. This maintains the current functionality.", + escapeBackslash: "Replace the `\\` with `\\\\` to include the actual backslash character." + }, + + schema: [] + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + /** + * Reports a node + * @param {ASTNode} node The node to report + * @param {number} startOffset The backslash's offset from the start of the node + * @param {string} character The uselessly escaped character (not including the backslash) + * @returns {void} + */ + function report(node, startOffset, character) { + const rangeStart = node.range[0] + startOffset; + const range = [rangeStart, rangeStart + 1]; + const start = sourceCode.getLocFromIndex(rangeStart); + + context.report({ + node, + loc: { + start, + end: { line: start.line, column: start.column + 1 } + }, + messageId: "unnecessaryEscape", + data: { character }, + suggest: [ + { + messageId: "removeEscape", + fix(fixer) { + return fixer.removeRange(range); + } + }, + { + messageId: "escapeBackslash", + fix(fixer) { + return fixer.insertTextBeforeRange(range, "\\"); + } + } + ] + }); + } + + /** + * Checks if the escape character in given string slice is unnecessary. + * @private + * @param {ASTNode} node node to validate. + * @param {string} match string slice to validate. + * @returns {void} + */ + function validateString(node, match) { + const isTemplateElement = node.type === "TemplateElement"; + const escapedChar = match[0][1]; + let isUnnecessaryEscape = !VALID_STRING_ESCAPES.has(escapedChar); + let isQuoteEscape; + + if (isTemplateElement) { + isQuoteEscape = escapedChar === "`"; + + if (escapedChar === "$") { + + // Warn if `\$` is not followed by `{` + isUnnecessaryEscape = match.input[match.index + 2] !== "{"; + } else if (escapedChar === "{") { + + /* + * Warn if `\{` is not preceded by `$`. If preceded by `$`, escaping + * is necessary and the rule should not warn. If preceded by `/$`, the rule + * will warn for the `/$` instead, as it is the first unnecessarily escaped character. + */ + isUnnecessaryEscape = match.input[match.index - 1] !== "$"; + } + } else { + isQuoteEscape = escapedChar === node.raw[0]; + } + + if (isUnnecessaryEscape && !isQuoteEscape) { + report(node, match.index, match[0].slice(1)); + } + } + + /** + * Checks if a node has an escape. + * @param {ASTNode} node node to check. + * @returns {void} + */ + function check(node) { + const isTemplateElement = node.type === "TemplateElement"; + + if ( + isTemplateElement && + node.parent && + node.parent.parent && + node.parent.parent.type === "TaggedTemplateExpression" && + node.parent === node.parent.parent.quasi + ) { + + // Don't report tagged template literals, because the backslash character is accessible to the tag function. + return; + } + + if (typeof node.value === "string" || isTemplateElement) { + + /* + * JSXAttribute doesn't have any escape sequence: https://facebook.github.io/jsx/. + * In addition, backticks are not supported by JSX yet: https://github.com/facebook/jsx/issues/25. + */ + if (node.parent.type === "JSXAttribute" || node.parent.type === "JSXElement" || node.parent.type === "JSXFragment") { + return; + } + + const value = isTemplateElement ? sourceCode.getText(node) : node.raw; + const pattern = /\\[^\d]/gu; + let match; + + while ((match = pattern.exec(value))) { + validateString(node, match); + } + } else if (node.regex) { + parseRegExp(node.regex.pattern) + + /* + * The '-' character is a special case, because it's only valid to escape it if it's in a character + * class, and is not at either edge of the character class. To account for this, don't consider '-' + * characters to be valid in general, and filter out '-' characters that appear in the middle of a + * character class. + */ + .filter(charInfo => !(charInfo.text === "-" && charInfo.inCharClass && !charInfo.startsCharClass && !charInfo.endsCharClass)) + + /* + * The '^' character is also a special case; it must always be escaped outside of character classes, but + * it only needs to be escaped in character classes if it's at the beginning of the character class. To + * account for this, consider it to be a valid escape character outside of character classes, and filter + * out '^' characters that appear at the start of a character class. + */ + .filter(charInfo => !(charInfo.text === "^" && charInfo.startsCharClass)) + + // Filter out characters that aren't escaped. + .filter(charInfo => charInfo.escaped) + + // Filter out characters that are valid to escape, based on their position in the regular expression. + .filter(charInfo => !(charInfo.inCharClass ? REGEX_GENERAL_ESCAPES : REGEX_NON_CHARCLASS_ESCAPES).has(charInfo.text)) + + // Report all the remaining characters. + .forEach(charInfo => report(node, charInfo.index, charInfo.text)); + } + + } + + return { + Literal: check, + TemplateElement: check + }; + } +}; + +/** + * @fileoverview Disallow renaming import, export, and destructured assignments to the same name. + * @author Kai Cataldo + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUselessRename = { + meta: { + type: "suggestion", + + docs: { + description: "disallow renaming import, export, and destructured assignments to the same name", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/no-useless-rename" + }, + + fixable: "code", + + schema: [ + { + type: "object", + properties: { + ignoreDestructuring: { type: "boolean", default: false }, + ignoreImport: { type: "boolean", default: false }, + ignoreExport: { type: "boolean", default: false } + }, + additionalProperties: false + } + ], + + messages: { + unnecessarilyRenamed: "{{type}} {{name}} unnecessarily renamed." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(), + options = context.options[0] || {}, + ignoreDestructuring = options.ignoreDestructuring === true, + ignoreImport = options.ignoreImport === true, + ignoreExport = options.ignoreExport === true; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Reports error for unnecessarily renamed assignments + * @param {ASTNode} node node to report + * @param {ASTNode} initial node with initial name value + * @param {string} type the type of the offending node + * @returns {void} + */ + function reportError(node, initial, type) { + const name = initial.type === "Identifier" ? initial.name : initial.value; + + return context.report({ + node, + messageId: "unnecessarilyRenamed", + data: { + name, + type + }, + fix(fixer) { + const replacementNode = node.type === "Property" ? node.value : node.local; + + if (sourceCode.getCommentsInside(node).length > sourceCode.getCommentsInside(replacementNode).length) { + return null; + } + + // Don't autofix code such as `({foo: (foo) = a} = obj);`, parens are not allowed in shorthand properties. + if ( + replacementNode.type === "AssignmentPattern" && + astUtils.isParenthesised(sourceCode, replacementNode.left) + ) { + return null; + } + + return fixer.replaceText(node, sourceCode.getText(replacementNode)); + } + }); + } + + /** + * Checks whether a destructured assignment is unnecessarily renamed + * @param {ASTNode} node node to check + * @returns {void} + */ + function checkDestructured(node) { + if (ignoreDestructuring) { + return; + } + + for (const property of node.properties) { + + /** + * Properties using shorthand syntax and rest elements can not be renamed. + * If the property is computed, we have no idea if a rename is useless or not. + */ + if (property.type !== "Property" || property.shorthand || property.computed) { + continue; + } + + const key = (property.key.type === "Identifier" && property.key.name) || (property.key.type === "Literal" && property.key.value); + const renamedKey = property.value.type === "AssignmentPattern" ? property.value.left.name : property.value.name; + + if (key === renamedKey) { + reportError(property, property.key, "Destructuring assignment"); + } + } + } + + /** + * Checks whether an import is unnecessarily renamed + * @param {ASTNode} node node to check + * @returns {void} + */ + function checkImport(node) { + if (ignoreImport) { + return; + } + + if (node.imported.name === node.local.name && + node.imported.range[0] !== node.local.range[0]) { + reportError(node, node.imported, "Import"); + } + } + + /** + * Checks whether an export is unnecessarily renamed + * @param {ASTNode} node node to check + * @returns {void} + */ + function checkExport(node) { + if (ignoreExport) { + return; + } + + if (node.local.name === node.exported.name && + node.local.range[0] !== node.exported.range[0]) { + reportError(node, node.local, "Export"); + } + + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + ObjectPattern: checkDestructured, + ImportSpecifier: checkImport, + ExportSpecifier: checkExport + }; + } +}; + +/** + * @fileoverview Disallow redundant return statements + * @author Teddy Katz + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Removes the given element from the array. + * @param {Array} array The source array to remove. + * @param {any} element The target item to remove. + * @returns {void} + */ +function remove(array, element) { + const index = array.indexOf(element); + + if (index !== -1) { + array.splice(index, 1); + } +} + +/** + * Checks whether it can remove the given return statement or not. + * @param {ASTNode} node The return statement node to check. + * @returns {boolean} `true` if the node is removable. + */ +function isRemovable(node) { + return astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type); +} + +/** + * Checks whether the given return statement is in a `finally` block or not. + * @param {ASTNode} node The return statement node to check. + * @returns {boolean} `true` if the node is in a `finally` block. + */ +function isInFinally(node) { + for ( + let currentNode = node; + currentNode && currentNode.parent && !astUtils.isFunction(currentNode); + currentNode = currentNode.parent + ) { + if (currentNode.parent.type === "TryStatement" && currentNode.parent.finalizer === currentNode) { + return true; + } + } + + return false; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noUselessReturn = { + meta: { + type: "suggestion", + + docs: { + description: "disallow redundant return statements", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-useless-return" + }, + + fixable: "code", + schema: [], + + messages: { + unnecessaryReturn: "Unnecessary return statement." + } + }, + + create(context) { + const segmentInfoMap = new WeakMap(); + const usedUnreachableSegments = new WeakSet(); + const sourceCode = context.getSourceCode(); + let scopeInfo = null; + + /** + * Checks whether the given segment is terminated by a return statement or not. + * @param {CodePathSegment} segment The segment to check. + * @returns {boolean} `true` if the segment is terminated by a return statement, or if it's still a part of unreachable. + */ + function isReturned(segment) { + const info = segmentInfoMap.get(segment); + + return !info || info.returned; + } + + /** + * Collects useless return statements from the given previous segments. + * + * A previous segment may be an unreachable segment. + * In that case, the information object of the unreachable segment is not + * initialized because `onCodePathSegmentStart` event is not notified for + * unreachable segments. + * This goes to the previous segments of the unreachable segment recursively + * if the unreachable segment was generated by a return statement. Otherwise, + * this ignores the unreachable segment. + * + * This behavior would simulate code paths for the case that the return + * statement does not exist. + * @param {ASTNode[]} uselessReturns The collected return statements. + * @param {CodePathSegment[]} prevSegments The previous segments to traverse. + * @param {WeakSet} [providedTraversedSegments] A set of segments that have already been traversed in this call + * @returns {ASTNode[]} `uselessReturns`. + */ + function getUselessReturns(uselessReturns, prevSegments, providedTraversedSegments) { + const traversedSegments = providedTraversedSegments || new WeakSet(); + + for (const segment of prevSegments) { + if (!segment.reachable) { + if (!traversedSegments.has(segment)) { + traversedSegments.add(segment); + getUselessReturns( + uselessReturns, + segment.allPrevSegments.filter(isReturned), + traversedSegments + ); + } + continue; + } + + uselessReturns.push(...segmentInfoMap.get(segment).uselessReturns); + } + + return uselessReturns; + } + + /** + * Removes the return statements on the given segment from the useless return + * statement list. + * + * This segment may be an unreachable segment. + * In that case, the information object of the unreachable segment is not + * initialized because `onCodePathSegmentStart` event is not notified for + * unreachable segments. + * This goes to the previous segments of the unreachable segment recursively + * if the unreachable segment was generated by a return statement. Otherwise, + * this ignores the unreachable segment. + * + * This behavior would simulate code paths for the case that the return + * statement does not exist. + * @param {CodePathSegment} segment The segment to get return statements. + * @returns {void} + */ + function markReturnStatementsOnSegmentAsUsed(segment) { + if (!segment.reachable) { + usedUnreachableSegments.add(segment); + segment.allPrevSegments + .filter(isReturned) + .filter(prevSegment => !usedUnreachableSegments.has(prevSegment)) + .forEach(markReturnStatementsOnSegmentAsUsed); + return; + } + + const info = segmentInfoMap.get(segment); + + for (const node of info.uselessReturns) { + remove(scopeInfo.uselessReturns, node); + } + info.uselessReturns = []; + } + + /** + * Removes the return statements on the current segments from the useless + * return statement list. + * + * This function will be called at every statement except FunctionDeclaration, + * BlockStatement, and BreakStatement. + * + * - FunctionDeclarations are always executed whether it's returned or not. + * - BlockStatements do nothing. + * - BreakStatements go the next merely. + * @returns {void} + */ + function markReturnStatementsOnCurrentSegmentsAsUsed() { + scopeInfo + .codePath + .currentSegments + .forEach(markReturnStatementsOnSegmentAsUsed); + } + + //---------------------------------------------------------------------- + // Public + //---------------------------------------------------------------------- + + return { + + // Makes and pushs a new scope information. + onCodePathStart(codePath) { + scopeInfo = { + upper: scopeInfo, + uselessReturns: [], + codePath + }; + }, + + // Reports useless return statements if exist. + onCodePathEnd() { + for (const node of scopeInfo.uselessReturns) { + context.report({ + node, + loc: node.loc, + messageId: "unnecessaryReturn", + fix(fixer) { + if (isRemovable(node) && !sourceCode.getCommentsInside(node).length) { + + /* + * Extend the replacement range to include the + * entire function to avoid conflicting with + * no-else-return. + * https://github.com/eslint/eslint/issues/8026 + */ + return new fixTracker(fixer, sourceCode) + .retainEnclosingFunction(node) + .remove(node); + } + return null; + } + }); + } + + scopeInfo = scopeInfo.upper; + }, + + /* + * Initializes segments. + * NOTE: This event is notified for only reachable segments. + */ + onCodePathSegmentStart(segment) { + const info = { + uselessReturns: getUselessReturns([], segment.allPrevSegments), + returned: false + }; + + // Stores the info. + segmentInfoMap.set(segment, info); + }, + + // Adds ReturnStatement node to check whether it's useless or not. + ReturnStatement(node) { + if (node.argument) { + markReturnStatementsOnCurrentSegmentsAsUsed(); + } + if ( + node.argument || + astUtils.isInLoop(node) || + isInFinally(node) || + + // Ignore `return` statements in unreachable places (https://github.com/eslint/eslint/issues/11647). + !scopeInfo.codePath.currentSegments.some(s => s.reachable) + ) { + return; + } + + for (const segment of scopeInfo.codePath.currentSegments) { + const info = segmentInfoMap.get(segment); + + if (info) { + info.uselessReturns.push(node); + info.returned = true; + } + } + scopeInfo.uselessReturns.push(node); + }, + + /* + * Registers for all statement nodes except FunctionDeclaration, BlockStatement, BreakStatement. + * Removes return statements of the current segments from the useless return statement list. + */ + ClassDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, + ContinueStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + DebuggerStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + DoWhileStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + EmptyStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ExpressionStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ForInStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ForOfStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ForStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + IfStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ImportDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, + LabeledStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + SwitchStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ThrowStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + TryStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + VariableDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, + WhileStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + WithStatement: markReturnStatementsOnCurrentSegmentsAsUsed, + ExportNamedDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, + ExportDefaultDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, + ExportAllDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed + }; + } +}; + +/** + * @fileoverview Rule to check for the usage of var. + * @author Jamund Ferguson + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Check whether a given variable is a global variable or not. + * @param {eslint-scope.Variable} variable The variable to check. + * @returns {boolean} `true` if the variable is a global variable. + */ +function isGlobal(variable) { + return Boolean(variable.scope) && variable.scope.type === "global"; +} + +/** + * Finds the nearest function scope or global scope walking up the scope + * hierarchy. + * @param {eslint-scope.Scope} scope The scope to traverse. + * @returns {eslint-scope.Scope} a function scope or global scope containing the given + * scope. + */ +function getEnclosingFunctionScope(scope) { + let currentScope = scope; + + while (currentScope.type !== "function" && currentScope.type !== "global") { + currentScope = currentScope.upper; + } + return currentScope; +} + +/** + * Checks whether the given variable has any references from a more specific + * function expression (i.e. a closure). + * @param {eslint-scope.Variable} variable A variable to check. + * @returns {boolean} `true` if the variable is used from a closure. + */ +function isReferencedInClosure(variable) { + const enclosingFunctionScope = getEnclosingFunctionScope(variable.scope); + + return variable.references.some(reference => + getEnclosingFunctionScope(reference.from) !== enclosingFunctionScope); +} + +/** + * Checks whether the given node is the assignee of a loop. + * @param {ASTNode} node A VariableDeclaration node to check. + * @returns {boolean} `true` if the declaration is assigned as part of loop + * iteration. + */ +function isLoopAssignee(node) { + return (node.parent.type === "ForOfStatement" || node.parent.type === "ForInStatement") && + node === node.parent.left; +} + +/** + * Checks whether the given variable declaration is immediately initialized. + * @param {ASTNode} node A VariableDeclaration node to check. + * @returns {boolean} `true` if the declaration has an initializer. + */ +function isDeclarationInitialized(node) { + return node.declarations.every(declarator => declarator.init !== null); +} + +const SCOPE_NODE_TYPE = /^(?:Program|BlockStatement|SwitchStatement|ForStatement|ForInStatement|ForOfStatement)$/u; + +/** + * Gets the scope node which directly contains a given node. + * @param {ASTNode} node A node to get. This is a `VariableDeclaration` or + * an `Identifier`. + * @returns {ASTNode} A scope node. This is one of `Program`, `BlockStatement`, + * `SwitchStatement`, `ForStatement`, `ForInStatement`, and + * `ForOfStatement`. + */ +function getScopeNode(node) { + for (let currentNode = node; currentNode; currentNode = currentNode.parent) { + if (SCOPE_NODE_TYPE.test(currentNode.type)) { + return currentNode; + } + } + + /* istanbul ignore next : unreachable */ + return null; +} + +/** + * Checks whether a given variable is redeclared or not. + * @param {eslint-scope.Variable} variable A variable to check. + * @returns {boolean} `true` if the variable is redeclared. + */ +function isRedeclared(variable) { + return variable.defs.length >= 2; +} + +/** + * Checks whether a given variable is used from outside of the specified scope. + * @param {ASTNode} scopeNode A scope node to check. + * @returns {Function} The predicate function which checks whether a given + * variable is used from outside of the specified scope. + */ +function isUsedFromOutsideOf(scopeNode) { + + /** + * Checks whether a given reference is inside of the specified scope or not. + * @param {eslint-scope.Reference} reference A reference to check. + * @returns {boolean} `true` if the reference is inside of the specified + * scope. + */ + function isOutsideOfScope(reference) { + const scope = scopeNode.range; + const id = reference.identifier.range; + + return id[0] < scope[0] || id[1] > scope[1]; + } + + return function(variable) { + return variable.references.some(isOutsideOfScope); + }; +} + +/** + * Creates the predicate function which checks whether a variable has their references in TDZ. + * + * The predicate function would return `true`: + * + * - if a reference is before the declarator. E.g. (var a = b, b = 1;)(var {a = b, b} = {};) + * - if a reference is in the expression of their default value. E.g. (var {a = a} = {};) + * - if a reference is in the expression of their initializer. E.g. (var a = a;) + * @param {ASTNode} node The initializer node of VariableDeclarator. + * @returns {Function} The predicate function. + * @private + */ +function hasReferenceInTDZ(node) { + const initStart = node.range[0]; + const initEnd = node.range[1]; + + return variable => { + const id = variable.defs[0].name; + const idStart = id.range[0]; + const defaultValue = (id.parent.type === "AssignmentPattern" ? id.parent.right : null); + const defaultStart = defaultValue && defaultValue.range[0]; + const defaultEnd = defaultValue && defaultValue.range[1]; + + return variable.references.some(reference => { + const start = reference.identifier.range[0]; + const end = reference.identifier.range[1]; + + return !reference.init && ( + start < idStart || + (defaultValue !== null && start >= defaultStart && end <= defaultEnd) || + (start >= initStart && end <= initEnd) + ); + }); + }; +} + +/** + * Checks whether a given variable has name that is allowed for 'var' declarations, + * but disallowed for `let` declarations. + * @param {eslint-scope.Variable} variable The variable to check. + * @returns {boolean} `true` if the variable has a disallowed name. + */ +function hasNameDisallowedForLetDeclarations(variable) { + return variable.name === "let"; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noVar = { + meta: { + type: "suggestion", + + docs: { + description: "require `let` or `const` instead of `var`", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/no-var" + }, + + schema: [], + fixable: "code", + + messages: { + unexpectedVar: "Unexpected var, use let or const instead." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + /** + * Checks whether the variables which are defined by the given declarator node have their references in TDZ. + * @param {ASTNode} declarator The VariableDeclarator node to check. + * @returns {boolean} `true` if one of the variables which are defined by the given declarator node have their references in TDZ. + */ + function hasSelfReferenceInTDZ(declarator) { + if (!declarator.init) { + return false; + } + const variables = context.getDeclaredVariables(declarator); + + return variables.some(hasReferenceInTDZ(declarator.init)); + } + + /** + * Checks whether it can fix a given variable declaration or not. + * It cannot fix if the following cases: + * + * - A variable is a global variable. + * - A variable is declared on a SwitchCase node. + * - A variable is redeclared. + * - A variable is used from outside the scope. + * - A variable is used from a closure within a loop. + * - A variable might be used before it is assigned within a loop. + * - A variable might be used in TDZ. + * - A variable is declared in statement position (e.g. a single-line `IfStatement`) + * - A variable has name that is disallowed for `let` declarations. + * + * ## A variable is declared on a SwitchCase node. + * + * If this rule modifies 'var' declarations on a SwitchCase node, it + * would generate the warnings of 'no-case-declarations' rule. And the + * 'eslint:recommended' preset includes 'no-case-declarations' rule, so + * this rule doesn't modify those declarations. + * + * ## A variable is redeclared. + * + * The language spec disallows redeclarations of `let` declarations. + * Those variables would cause syntax errors. + * + * ## A variable is used from outside the scope. + * + * The language spec disallows accesses from outside of the scope for + * `let` declarations. Those variables would cause reference errors. + * + * ## A variable is used from a closure within a loop. + * + * A `var` declaration within a loop shares the same variable instance + * across all loop iterations, while a `let` declaration creates a new + * instance for each iteration. This means if a variable in a loop is + * referenced by any closure, changing it from `var` to `let` would + * change the behavior in a way that is generally unsafe. + * + * ## A variable might be used before it is assigned within a loop. + * + * Within a loop, a `let` declaration without an initializer will be + * initialized to null, while a `var` declaration will retain its value + * from the previous iteration, so it is only safe to change `var` to + * `let` if we can statically determine that the variable is always + * assigned a value before its first access in the loop body. To keep + * the implementation simple, we only convert `var` to `let` within + * loops when the variable is a loop assignee or the declaration has an + * initializer. + * @param {ASTNode} node A variable declaration node to check. + * @returns {boolean} `true` if it can fix the node. + */ + function canFix(node) { + const variables = context.getDeclaredVariables(node); + const scopeNode = getScopeNode(node); + + if (node.parent.type === "SwitchCase" || + node.declarations.some(hasSelfReferenceInTDZ) || + variables.some(isGlobal) || + variables.some(isRedeclared) || + variables.some(isUsedFromOutsideOf(scopeNode)) || + variables.some(hasNameDisallowedForLetDeclarations) + ) { + return false; + } + + if (astUtils.isInLoop(node)) { + if (variables.some(isReferencedInClosure)) { + return false; + } + if (!isLoopAssignee(node) && !isDeclarationInitialized(node)) { + return false; + } + } + + if ( + !isLoopAssignee(node) && + !(node.parent.type === "ForStatement" && node.parent.init === node) && + !astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type) + ) { + + // If the declaration is not in a block, e.g. `if (foo) var bar = 1;`, then it can't be fixed. + return false; + } + + return true; + } + + /** + * Reports a given variable declaration node. + * @param {ASTNode} node A variable declaration node to report. + * @returns {void} + */ + function report(node) { + context.report({ + node, + messageId: "unexpectedVar", + + fix(fixer) { + const varToken = sourceCode.getFirstToken(node, { filter: t => t.value === "var" }); + + return canFix(node) + ? fixer.replaceText(varToken, "let") + : null; + } + }); + } + + return { + "VariableDeclaration:exit"(node) { + if (node.kind === "var") { + report(node); + } + } + }; + } +}; + +/** + * @fileoverview Rule to disallow use of void operator. + * @author Mike Sidorov + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noVoid = { + meta: { + type: "suggestion", + + docs: { + description: "disallow `void` operators", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-void" + }, + + messages: { + noVoid: "Expected 'undefined' and instead saw 'void'." + }, + + schema: [ + { + type: "object", + properties: { + allowAsStatement: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ] + }, + + create(context) { + const allowAsStatement = + context.options[0] && context.options[0].allowAsStatement; + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + 'UnaryExpression[operator="void"]'(node) { + if ( + allowAsStatement && + node.parent && + node.parent.type === "ExpressionStatement" + ) { + return; + } + context.report({ + node, + messageId: "noVoid" + }); + } + }; + } +}; + +/** + * @fileoverview Rule that warns about used warning comments + * @author Alexander Schmidt + */ + +const { escapeRegExp } = lodash__default['default']; + + +const CHAR_LIMIT = 40; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noWarningComments = { + meta: { + type: "suggestion", + + docs: { + description: "disallow specified warning terms in comments", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/no-warning-comments" + }, + + schema: [ + { + type: "object", + properties: { + terms: { + type: "array", + items: { + type: "string" + } + }, + location: { + enum: ["start", "anywhere"] + } + }, + additionalProperties: false + } + ], + + messages: { + unexpectedComment: "Unexpected '{{matchedTerm}}' comment: '{{comment}}'." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(), + configuration = context.options[0] || {}, + warningTerms = configuration.terms || ["todo", "fixme", "xxx"], + location = configuration.location || "start", + selfConfigRegEx = /\bno-warning-comments\b/u; + + /** + * Convert a warning term into a RegExp which will match a comment containing that whole word in the specified + * location ("start" or "anywhere"). If the term starts or ends with non word characters, then the match will not + * require word boundaries on that side. + * @param {string} term A term to convert to a RegExp + * @returns {RegExp} The term converted to a RegExp + */ + function convertToRegExp(term) { + const escaped = escapeRegExp(term); + const wordBoundary = "\\b"; + const eitherOrWordBoundary = `|${wordBoundary}`; + let prefix; + + /* + * If the term ends in a word character (a-z0-9_), ensure a word + * boundary at the end, so that substrings do not get falsely + * matched. eg "todo" in a string such as "mastodon". + * If the term ends in a non-word character, then \b won't match on + * the boundary to the next non-word character, which would likely + * be a space. For example `/\bFIX!\b/.test('FIX! blah') === false`. + * In these cases, use no bounding match. Same applies for the + * prefix, handled below. + */ + const suffix = /\w$/u.test(term) ? "\\b" : ""; + + if (location === "start") { + + /* + * When matching at the start, ignore leading whitespace, and + * there's no need to worry about word boundaries. + */ + prefix = "^\\s*"; + } else if (/^\w/u.test(term)) { + prefix = wordBoundary; + } else { + prefix = ""; + } + + if (location === "start") { + + /* + * For location "start" the regex should be + * ^\s*TERM\b. This checks the word boundary + * at the beginning of the comment. + */ + return new RegExp(prefix + escaped + suffix, "iu"); + } + + /* + * For location "anywhere" the regex should be + * \bTERM\b|\bTERM\b, this checks the entire comment + * for the term. + */ + return new RegExp( + prefix + + escaped + + suffix + + eitherOrWordBoundary + + term + + wordBoundary, + "iu" + ); + } + + const warningRegExps = warningTerms.map(convertToRegExp); + + /** + * Checks the specified comment for matches of the configured warning terms and returns the matches. + * @param {string} comment The comment which is checked. + * @returns {Array} All matched warning terms for this comment. + */ + function commentContainsWarningTerm(comment) { + const matches = []; + + warningRegExps.forEach((regex, index) => { + if (regex.test(comment)) { + matches.push(warningTerms[index]); + } + }); + + return matches; + } + + /** + * Checks the specified node for matching warning comments and reports them. + * @param {ASTNode} node The AST node being checked. + * @returns {void} undefined. + */ + function checkComment(node) { + const comment = node.value; + + if ( + astUtils.isDirectiveComment(node) && + selfConfigRegEx.test(comment) + ) { + return; + } + + const matches = commentContainsWarningTerm(comment); + + matches.forEach(matchedTerm => { + let commentToDisplay = ""; + let truncated = false; + + for (const c of comment.trim().split(/\s+/u)) { + const tmp = commentToDisplay ? `${commentToDisplay} ${c}` : c; + + if (tmp.length <= CHAR_LIMIT) { + commentToDisplay = tmp; + } else { + truncated = true; + break; + } + } + + context.report({ + node, + messageId: "unexpectedComment", + data: { + matchedTerm, + comment: `${commentToDisplay}${ + truncated ? "..." : "" + }` + } + }); + }); + } + + return { + Program() { + const comments = sourceCode.getAllComments(); + + comments + .filter(token => token.type !== "Shebang") + .forEach(checkComment); + } + }; + } +}; + +/** + * @fileoverview Rule to disallow whitespace before properties + * @author Kai Cataldo + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noWhitespaceBeforeProperty = { + meta: { + type: "layout", + + docs: { + description: "disallow whitespace before properties", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/no-whitespace-before-property" + }, + + fixable: "whitespace", + schema: [], + + messages: { + unexpectedWhitespace: "Unexpected whitespace before property {{propName}}." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Reports whitespace before property token + * @param {ASTNode} node the node to report in the event of an error + * @param {Token} leftToken the left token + * @param {Token} rightToken the right token + * @returns {void} + * @private + */ + function reportError(node, leftToken, rightToken) { + context.report({ + node, + messageId: "unexpectedWhitespace", + data: { + propName: sourceCode.getText(node.property) + }, + fix(fixer) { + let replacementText = ""; + + if (!node.computed && !node.optional && astUtils.isDecimalInteger(node.object)) { + + /* + * If the object is a number literal, fixing it to something like 5.toString() would cause a SyntaxError. + * Don't fix this case. + */ + return null; + } + + // Don't fix if comments exist. + if (sourceCode.commentsExistBetween(leftToken, rightToken)) { + return null; + } + + if (node.optional) { + replacementText = "?."; + } else if (!node.computed) { + replacementText = "."; + } + + return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], replacementText); + } + }); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + MemberExpression(node) { + let rightToken; + let leftToken; + + if (!astUtils.isTokenOnSameLine(node.object, node.property)) { + return; + } + + if (node.computed) { + rightToken = sourceCode.getTokenBefore(node.property, astUtils.isOpeningBracketToken); + leftToken = sourceCode.getTokenBefore(rightToken, node.optional ? 1 : 0); + } else { + rightToken = sourceCode.getFirstToken(node.property); + leftToken = sourceCode.getTokenBefore(rightToken, 1); + } + + if (sourceCode.isSpaceBetweenTokens(leftToken, rightToken)) { + reportError(node, leftToken, rightToken); + } + } + }; + } +}; + +/** + * @fileoverview Rule to flag use of with statement + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var noWith = { + meta: { + type: "suggestion", + + docs: { + description: "disallow `with` statements", + category: "Best Practices", + recommended: true, + url: "https://eslint.org/docs/rules/no-with" + }, + + schema: [], + + messages: { + unexpectedWith: "Unexpected use of 'with' statement." + } + }, + + create(context) { + + return { + WithStatement(node) { + context.report({ node, messageId: "unexpectedWith" }); + } + }; + + } +}; + +/** + * @fileoverview enforce the location of single-line statements + * @author Teddy Katz + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const POSITION_SCHEMA = { enum: ["beside", "below", "any"] }; + +var nonblockStatementBodyPosition = { + meta: { + type: "layout", + + docs: { + description: "enforce the location of single-line statements", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/nonblock-statement-body-position" + }, + + fixable: "whitespace", + + schema: [ + POSITION_SCHEMA, + { + properties: { + overrides: { + properties: { + if: POSITION_SCHEMA, + else: POSITION_SCHEMA, + while: POSITION_SCHEMA, + do: POSITION_SCHEMA, + for: POSITION_SCHEMA + }, + additionalProperties: false + } + }, + additionalProperties: false + } + ], + + messages: { + expectNoLinebreak: "Expected no linebreak before this statement.", + expectLinebreak: "Expected a linebreak before this statement." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + //---------------------------------------------------------------------- + // Helpers + //---------------------------------------------------------------------- + + /** + * Gets the applicable preference for a particular keyword + * @param {string} keywordName The name of a keyword, e.g. 'if' + * @returns {string} The applicable option for the keyword, e.g. 'beside' + */ + function getOption(keywordName) { + return context.options[1] && context.options[1].overrides && context.options[1].overrides[keywordName] || + context.options[0] || + "beside"; + } + + /** + * Validates the location of a single-line statement + * @param {ASTNode} node The single-line statement + * @param {string} keywordName The applicable keyword name for the single-line statement + * @returns {void} + */ + function validateStatement(node, keywordName) { + const option = getOption(keywordName); + + if (node.type === "BlockStatement" || option === "any") { + return; + } + + const tokenBefore = sourceCode.getTokenBefore(node); + + if (tokenBefore.loc.end.line === node.loc.start.line && option === "below") { + context.report({ + node, + messageId: "expectLinebreak", + fix: fixer => fixer.insertTextBefore(node, "\n") + }); + } else if (tokenBefore.loc.end.line !== node.loc.start.line && option === "beside") { + context.report({ + node, + messageId: "expectNoLinebreak", + fix(fixer) { + if (sourceCode.getText().slice(tokenBefore.range[1], node.range[0]).trim()) { + return null; + } + return fixer.replaceTextRange([tokenBefore.range[1], node.range[0]], " "); + } + }); + } + } + + //---------------------------------------------------------------------- + // Public + //---------------------------------------------------------------------- + + return { + IfStatement(node) { + validateStatement(node.consequent, "if"); + + // Check the `else` node, but don't check 'else if' statements. + if (node.alternate && node.alternate.type !== "IfStatement") { + validateStatement(node.alternate, "else"); + } + }, + WhileStatement: node => validateStatement(node.body, "while"), + DoWhileStatement: node => validateStatement(node.body, "do"), + ForStatement: node => validateStatement(node.body, "for"), + ForInStatement: node => validateStatement(node.body, "for"), + ForOfStatement: node => validateStatement(node.body, "for") + }; + } +}; + +/** + * @fileoverview Rule to require or disallow line breaks inside braces. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +// Schema objects. +const OPTION_VALUE = { + oneOf: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + multiline: { + type: "boolean" + }, + minProperties: { + type: "integer", + minimum: 0 + }, + consistent: { + type: "boolean" + } + }, + additionalProperties: false, + minProperties: 1 + } + ] +}; + +/** + * Normalizes a given option value. + * @param {string|Object|undefined} value An option value to parse. + * @returns {{multiline: boolean, minProperties: number, consistent: boolean}} Normalized option object. + */ +function normalizeOptionValue(value) { + let multiline = false; + let minProperties = Number.POSITIVE_INFINITY; + let consistent = false; + + if (value) { + if (value === "always") { + minProperties = 0; + } else if (value === "never") { + minProperties = Number.POSITIVE_INFINITY; + } else { + multiline = Boolean(value.multiline); + minProperties = value.minProperties || Number.POSITIVE_INFINITY; + consistent = Boolean(value.consistent); + } + } else { + consistent = true; + } + + return { multiline, minProperties, consistent }; +} + +/** + * Normalizes a given option value. + * @param {string|Object|undefined} options An option value to parse. + * @returns {{ + * ObjectExpression: {multiline: boolean, minProperties: number, consistent: boolean}, + * ObjectPattern: {multiline: boolean, minProperties: number, consistent: boolean}, + * ImportDeclaration: {multiline: boolean, minProperties: number, consistent: boolean}, + * ExportNamedDeclaration : {multiline: boolean, minProperties: number, consistent: boolean} + * }} Normalized option object. + */ +function normalizeOptions(options) { + const isNodeSpecificOption = lodash__default['default'].overSome([lodash__default['default'].isPlainObject, lodash__default['default'].isString]); + + if (lodash__default['default'].isPlainObject(options) && Object.values(options).some(isNodeSpecificOption)) { + return { + ObjectExpression: normalizeOptionValue(options.ObjectExpression), + ObjectPattern: normalizeOptionValue(options.ObjectPattern), + ImportDeclaration: normalizeOptionValue(options.ImportDeclaration), + ExportNamedDeclaration: normalizeOptionValue(options.ExportDeclaration) + }; + } + + const value = normalizeOptionValue(options); + + return { ObjectExpression: value, ObjectPattern: value, ImportDeclaration: value, ExportNamedDeclaration: value }; +} + +/** + * Determines if ObjectExpression, ObjectPattern, ImportDeclaration or ExportNamedDeclaration + * node needs to be checked for missing line breaks + * @param {ASTNode} node Node under inspection + * @param {Object} options option specific to node type + * @param {Token} first First object property + * @param {Token} last Last object property + * @returns {boolean} `true` if node needs to be checked for missing line breaks + */ +function areLineBreaksRequired(node, options, first, last) { + let objectProperties; + + if (node.type === "ObjectExpression" || node.type === "ObjectPattern") { + objectProperties = node.properties; + } else { + + // is ImportDeclaration or ExportNamedDeclaration + objectProperties = node.specifiers + .filter(s => s.type === "ImportSpecifier" || s.type === "ExportSpecifier"); + } + + return objectProperties.length >= options.minProperties || + ( + options.multiline && + objectProperties.length > 0 && + first.loc.start.line !== last.loc.end.line + ); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var objectCurlyNewline = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent line breaks after opening and before closing braces", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/object-curly-newline" + }, + + fixable: "whitespace", + + schema: [ + { + oneOf: [ + OPTION_VALUE, + { + type: "object", + properties: { + ObjectExpression: OPTION_VALUE, + ObjectPattern: OPTION_VALUE, + ImportDeclaration: OPTION_VALUE, + ExportDeclaration: OPTION_VALUE + }, + additionalProperties: false, + minProperties: 1 + } + ] + } + ], + + messages: { + unexpectedLinebreakBeforeClosingBrace: "Unexpected line break before this closing brace.", + unexpectedLinebreakAfterOpeningBrace: "Unexpected line break after this opening brace.", + expectedLinebreakBeforeClosingBrace: "Expected a line break before this closing brace.", + expectedLinebreakAfterOpeningBrace: "Expected a line break after this opening brace." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const normalizedOptions = normalizeOptions(context.options[0]); + + /** + * Reports a given node if it violated this rule. + * @param {ASTNode} node A node to check. This is an ObjectExpression, ObjectPattern, ImportDeclaration or ExportNamedDeclaration node. + * @returns {void} + */ + function check(node) { + const options = normalizedOptions[node.type]; + + if ( + (node.type === "ImportDeclaration" && + !node.specifiers.some(specifier => specifier.type === "ImportSpecifier")) || + (node.type === "ExportNamedDeclaration" && + !node.specifiers.some(specifier => specifier.type === "ExportSpecifier")) + ) { + return; + } + + const openBrace = sourceCode.getFirstToken(node, token => token.value === "{"); + + let closeBrace; + + if (node.typeAnnotation) { + closeBrace = sourceCode.getTokenBefore(node.typeAnnotation); + } else { + closeBrace = sourceCode.getLastToken(node, token => token.value === "}"); + } + + let first = sourceCode.getTokenAfter(openBrace, { includeComments: true }); + let last = sourceCode.getTokenBefore(closeBrace, { includeComments: true }); + + const needsLineBreaks = areLineBreaksRequired(node, options, first, last); + + const hasCommentsFirstToken = astUtils.isCommentToken(first); + const hasCommentsLastToken = astUtils.isCommentToken(last); + + /* + * Use tokens or comments to check multiline or not. + * But use only tokens to check whether line breaks are needed. + * This allows: + * var obj = { // eslint-disable-line foo + * a: 1 + * } + */ + first = sourceCode.getTokenAfter(openBrace); + last = sourceCode.getTokenBefore(closeBrace); + + if (needsLineBreaks) { + if (astUtils.isTokenOnSameLine(openBrace, first)) { + context.report({ + messageId: "expectedLinebreakAfterOpeningBrace", + node, + loc: openBrace.loc, + fix(fixer) { + if (hasCommentsFirstToken) { + return null; + } + + return fixer.insertTextAfter(openBrace, "\n"); + } + }); + } + if (astUtils.isTokenOnSameLine(last, closeBrace)) { + context.report({ + messageId: "expectedLinebreakBeforeClosingBrace", + node, + loc: closeBrace.loc, + fix(fixer) { + if (hasCommentsLastToken) { + return null; + } + + return fixer.insertTextBefore(closeBrace, "\n"); + } + }); + } + } else { + const consistent = options.consistent; + const hasLineBreakBetweenOpenBraceAndFirst = !astUtils.isTokenOnSameLine(openBrace, first); + const hasLineBreakBetweenCloseBraceAndLast = !astUtils.isTokenOnSameLine(last, closeBrace); + + if ( + (!consistent && hasLineBreakBetweenOpenBraceAndFirst) || + (consistent && hasLineBreakBetweenOpenBraceAndFirst && !hasLineBreakBetweenCloseBraceAndLast) + ) { + context.report({ + messageId: "unexpectedLinebreakAfterOpeningBrace", + node, + loc: openBrace.loc, + fix(fixer) { + if (hasCommentsFirstToken) { + return null; + } + + return fixer.removeRange([ + openBrace.range[1], + first.range[0] + ]); + } + }); + } + if ( + (!consistent && hasLineBreakBetweenCloseBraceAndLast) || + (consistent && !hasLineBreakBetweenOpenBraceAndFirst && hasLineBreakBetweenCloseBraceAndLast) + ) { + context.report({ + messageId: "unexpectedLinebreakBeforeClosingBrace", + node, + loc: closeBrace.loc, + fix(fixer) { + if (hasCommentsLastToken) { + return null; + } + + return fixer.removeRange([ + last.range[1], + closeBrace.range[0] + ]); + } + }); + } + } + } + + return { + ObjectExpression: check, + ObjectPattern: check, + ImportDeclaration: check, + ExportNamedDeclaration: check + }; + } +}; + +/** + * @fileoverview Disallows or enforces spaces inside of object literals. + * @author Jamund Ferguson + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var objectCurlySpacing = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent spacing inside braces", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/object-curly-spacing" + }, + + fixable: "whitespace", + + schema: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + arraysInObjects: { + type: "boolean" + }, + objectsInObjects: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + + messages: { + requireSpaceBefore: "A space is required before '{{token}}'.", + requireSpaceAfter: "A space is required after '{{token}}'.", + unexpectedSpaceBefore: "There should be no space before '{{token}}'.", + unexpectedSpaceAfter: "There should be no space after '{{token}}'." + } + }, + + create(context) { + const spaced = context.options[0] === "always", + sourceCode = context.getSourceCode(); + + /** + * Determines whether an option is set, relative to the spacing option. + * If spaced is "always", then check whether option is set to false. + * If spaced is "never", then check whether option is set to true. + * @param {Object} option The option to exclude. + * @returns {boolean} Whether or not the property is excluded. + */ + function isOptionSet(option) { + return context.options[1] ? context.options[1][option] === !spaced : false; + } + + const options = { + spaced, + arraysInObjectsException: isOptionSet("arraysInObjects"), + objectsInObjectsException: isOptionSet("objectsInObjects") + }; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Reports that there shouldn't be a space after the first token + * @param {ASTNode} node The node to report in the event of an error. + * @param {Token} token The token to use for the report. + * @returns {void} + */ + function reportNoBeginningSpace(node, token) { + const nextToken = context.getSourceCode().getTokenAfter(token, { includeComments: true }); + + context.report({ + node, + loc: { start: token.loc.end, end: nextToken.loc.start }, + messageId: "unexpectedSpaceAfter", + data: { + token: token.value + }, + fix(fixer) { + return fixer.removeRange([token.range[1], nextToken.range[0]]); + } + }); + } + + /** + * Reports that there shouldn't be a space before the last token + * @param {ASTNode} node The node to report in the event of an error. + * @param {Token} token The token to use for the report. + * @returns {void} + */ + function reportNoEndingSpace(node, token) { + const previousToken = context.getSourceCode().getTokenBefore(token, { includeComments: true }); + + context.report({ + node, + loc: { start: previousToken.loc.end, end: token.loc.start }, + messageId: "unexpectedSpaceBefore", + data: { + token: token.value + }, + fix(fixer) { + return fixer.removeRange([previousToken.range[1], token.range[0]]); + } + }); + } + + /** + * Reports that there should be a space after the first token + * @param {ASTNode} node The node to report in the event of an error. + * @param {Token} token The token to use for the report. + * @returns {void} + */ + function reportRequiredBeginningSpace(node, token) { + context.report({ + node, + loc: token.loc, + messageId: "requireSpaceAfter", + data: { + token: token.value + }, + fix(fixer) { + return fixer.insertTextAfter(token, " "); + } + }); + } + + /** + * Reports that there should be a space before the last token + * @param {ASTNode} node The node to report in the event of an error. + * @param {Token} token The token to use for the report. + * @returns {void} + */ + function reportRequiredEndingSpace(node, token) { + context.report({ + node, + loc: token.loc, + messageId: "requireSpaceBefore", + data: { + token: token.value + }, + fix(fixer) { + return fixer.insertTextBefore(token, " "); + } + }); + } + + /** + * Determines if spacing in curly braces is valid. + * @param {ASTNode} node The AST node to check. + * @param {Token} first The first token to check (should be the opening brace) + * @param {Token} second The second token to check (should be first after the opening brace) + * @param {Token} penultimate The penultimate token to check (should be last before closing brace) + * @param {Token} last The last token to check (should be closing brace) + * @returns {void} + */ + function validateBraceSpacing(node, first, second, penultimate, last) { + if (astUtils.isTokenOnSameLine(first, second)) { + const firstSpaced = sourceCode.isSpaceBetweenTokens(first, second); + + if (options.spaced && !firstSpaced) { + reportRequiredBeginningSpace(node, first); + } + if (!options.spaced && firstSpaced && second.type !== "Line") { + reportNoBeginningSpace(node, first); + } + } + + if (astUtils.isTokenOnSameLine(penultimate, last)) { + const shouldCheckPenultimate = ( + options.arraysInObjectsException && astUtils.isClosingBracketToken(penultimate) || + options.objectsInObjectsException && astUtils.isClosingBraceToken(penultimate) + ); + const penultimateType = shouldCheckPenultimate && sourceCode.getNodeByRangeIndex(penultimate.range[0]).type; + + const closingCurlyBraceMustBeSpaced = ( + options.arraysInObjectsException && penultimateType === "ArrayExpression" || + options.objectsInObjectsException && (penultimateType === "ObjectExpression" || penultimateType === "ObjectPattern") + ) ? !options.spaced : options.spaced; + + const lastSpaced = sourceCode.isSpaceBetweenTokens(penultimate, last); + + if (closingCurlyBraceMustBeSpaced && !lastSpaced) { + reportRequiredEndingSpace(node, last); + } + if (!closingCurlyBraceMustBeSpaced && lastSpaced) { + reportNoEndingSpace(node, last); + } + } + } + + /** + * Gets '}' token of an object node. + * + * Because the last token of object patterns might be a type annotation, + * this traverses tokens preceded by the last property, then returns the + * first '}' token. + * @param {ASTNode} node The node to get. This node is an + * ObjectExpression or an ObjectPattern. And this node has one or + * more properties. + * @returns {Token} '}' token. + */ + function getClosingBraceOfObject(node) { + const lastProperty = node.properties[node.properties.length - 1]; + + return sourceCode.getTokenAfter(lastProperty, astUtils.isClosingBraceToken); + } + + /** + * Reports a given object node if spacing in curly braces is invalid. + * @param {ASTNode} node An ObjectExpression or ObjectPattern node to check. + * @returns {void} + */ + function checkForObject(node) { + if (node.properties.length === 0) { + return; + } + + const first = sourceCode.getFirstToken(node), + last = getClosingBraceOfObject(node), + second = sourceCode.getTokenAfter(first, { includeComments: true }), + penultimate = sourceCode.getTokenBefore(last, { includeComments: true }); + + validateBraceSpacing(node, first, second, penultimate, last); + } + + /** + * Reports a given import node if spacing in curly braces is invalid. + * @param {ASTNode} node An ImportDeclaration node to check. + * @returns {void} + */ + function checkForImport(node) { + if (node.specifiers.length === 0) { + return; + } + + let firstSpecifier = node.specifiers[0]; + const lastSpecifier = node.specifiers[node.specifiers.length - 1]; + + if (lastSpecifier.type !== "ImportSpecifier") { + return; + } + if (firstSpecifier.type !== "ImportSpecifier") { + firstSpecifier = node.specifiers[1]; + } + + const first = sourceCode.getTokenBefore(firstSpecifier), + last = sourceCode.getTokenAfter(lastSpecifier, astUtils.isNotCommaToken), + second = sourceCode.getTokenAfter(first, { includeComments: true }), + penultimate = sourceCode.getTokenBefore(last, { includeComments: true }); + + validateBraceSpacing(node, first, second, penultimate, last); + } + + /** + * Reports a given export node if spacing in curly braces is invalid. + * @param {ASTNode} node An ExportNamedDeclaration node to check. + * @returns {void} + */ + function checkForExport(node) { + if (node.specifiers.length === 0) { + return; + } + + const firstSpecifier = node.specifiers[0], + lastSpecifier = node.specifiers[node.specifiers.length - 1], + first = sourceCode.getTokenBefore(firstSpecifier), + last = sourceCode.getTokenAfter(lastSpecifier, astUtils.isNotCommaToken), + second = sourceCode.getTokenAfter(first, { includeComments: true }), + penultimate = sourceCode.getTokenBefore(last, { includeComments: true }); + + validateBraceSpacing(node, first, second, penultimate, last); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + // var {x} = y; + ObjectPattern: checkForObject, + + // var y = {x: 'y'} + ObjectExpression: checkForObject, + + // import {y} from 'x'; + ImportDeclaration: checkForImport, + + // export {name} from 'yo'; + ExportNamedDeclaration: checkForExport + }; + + } +}; + +/** + * @fileoverview Rule to enforce placing object properties on separate lines. + * @author Vitor Balocco + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var objectPropertyNewline = { + meta: { + type: "layout", + + docs: { + description: "enforce placing object properties on separate lines", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/object-property-newline" + }, + + schema: [ + { + type: "object", + properties: { + allowAllPropertiesOnSameLine: { + type: "boolean", + default: false + }, + allowMultiplePropertiesPerLine: { // Deprecated + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + fixable: "whitespace", + + messages: { + propertiesOnNewlineAll: "Object properties must go on a new line if they aren't all on the same line.", + propertiesOnNewline: "Object properties must go on a new line." + } + }, + + create(context) { + const allowSameLine = context.options[0] && ( + (context.options[0].allowAllPropertiesOnSameLine || context.options[0].allowMultiplePropertiesPerLine /* Deprecated */) + ); + const messageId = allowSameLine + ? "propertiesOnNewlineAll" + : "propertiesOnNewline"; + + const sourceCode = context.getSourceCode(); + + return { + ObjectExpression(node) { + if (allowSameLine) { + if (node.properties.length > 1) { + const firstTokenOfFirstProperty = sourceCode.getFirstToken(node.properties[0]); + const lastTokenOfLastProperty = sourceCode.getLastToken(node.properties[node.properties.length - 1]); + + if (firstTokenOfFirstProperty.loc.end.line === lastTokenOfLastProperty.loc.start.line) { + + // All keys and values are on the same line + return; + } + } + } + + for (let i = 1; i < node.properties.length; i++) { + const lastTokenOfPreviousProperty = sourceCode.getLastToken(node.properties[i - 1]); + const firstTokenOfCurrentProperty = sourceCode.getFirstToken(node.properties[i]); + + if (lastTokenOfPreviousProperty.loc.end.line === firstTokenOfCurrentProperty.loc.start.line) { + context.report({ + node, + loc: firstTokenOfCurrentProperty.loc, + messageId, + fix(fixer) { + const comma = sourceCode.getTokenBefore(firstTokenOfCurrentProperty); + const rangeAfterComma = [comma.range[1], firstTokenOfCurrentProperty.range[0]]; + + // Don't perform a fix if there are any comments between the comma and the next property. + if (sourceCode.text.slice(rangeAfterComma[0], rangeAfterComma[1]).trim()) { + return null; + } + + return fixer.replaceTextRange(rangeAfterComma, "\n"); + } + }); + } + } + } + }; + } +}; + +/** + * @fileoverview Rule to enforce concise object methods and properties. + * @author Jamund Ferguson + */ + +const OPTIONS = { + always: "always", + never: "never", + methods: "methods", + properties: "properties", + consistent: "consistent", + consistentAsNeeded: "consistent-as-needed" +}; + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ +var objectShorthand = { + meta: { + type: "suggestion", + + docs: { + description: "require or disallow method and property shorthand syntax for object literals", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/object-shorthand" + }, + + fixable: "code", + + schema: { + anyOf: [ + { + type: "array", + items: [ + { + enum: ["always", "methods", "properties", "never", "consistent", "consistent-as-needed"] + } + ], + minItems: 0, + maxItems: 1 + }, + { + type: "array", + items: [ + { + enum: ["always", "methods", "properties"] + }, + { + type: "object", + properties: { + avoidQuotes: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + minItems: 0, + maxItems: 2 + }, + { + type: "array", + items: [ + { + enum: ["always", "methods"] + }, + { + type: "object", + properties: { + ignoreConstructors: { + type: "boolean" + }, + avoidQuotes: { + type: "boolean" + }, + avoidExplicitReturnArrows: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + minItems: 0, + maxItems: 2 + } + ] + }, + + messages: { + expectedAllPropertiesShorthanded: "Expected shorthand for all properties.", + expectedLiteralMethodLongform: "Expected longform method syntax for string literal keys.", + expectedPropertyShorthand: "Expected property shorthand.", + expectedPropertyLongform: "Expected longform property syntax.", + expectedMethodShorthand: "Expected method shorthand.", + expectedMethodLongform: "Expected longform method syntax.", + unexpectedMix: "Unexpected mix of shorthand and non-shorthand properties." + } + }, + + create(context) { + const APPLY = context.options[0] || OPTIONS.always; + const APPLY_TO_METHODS = APPLY === OPTIONS.methods || APPLY === OPTIONS.always; + const APPLY_TO_PROPS = APPLY === OPTIONS.properties || APPLY === OPTIONS.always; + const APPLY_NEVER = APPLY === OPTIONS.never; + const APPLY_CONSISTENT = APPLY === OPTIONS.consistent; + const APPLY_CONSISTENT_AS_NEEDED = APPLY === OPTIONS.consistentAsNeeded; + + const PARAMS = context.options[1] || {}; + const IGNORE_CONSTRUCTORS = PARAMS.ignoreConstructors; + const AVOID_QUOTES = PARAMS.avoidQuotes; + const AVOID_EXPLICIT_RETURN_ARROWS = !!PARAMS.avoidExplicitReturnArrows; + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + const CTOR_PREFIX_REGEX = /[^_$0-9]/u; + + /** + * Determines if the first character of the name is a capital letter. + * @param {string} name The name of the node to evaluate. + * @returns {boolean} True if the first character of the property name is a capital letter, false if not. + * @private + */ + function isConstructor(name) { + const match = CTOR_PREFIX_REGEX.exec(name); + + // Not a constructor if name has no characters apart from '_', '$' and digits e.g. '_', '$$', '_8' + if (!match) { + return false; + } + + const firstChar = name.charAt(match.index); + + return firstChar === firstChar.toUpperCase(); + } + + /** + * Determines if the property can have a shorthand form. + * @param {ASTNode} property Property AST node + * @returns {boolean} True if the property can have a shorthand form + * @private + * + */ + function canHaveShorthand(property) { + return (property.kind !== "set" && property.kind !== "get" && property.type !== "SpreadElement" && property.type !== "SpreadProperty" && property.type !== "ExperimentalSpreadProperty"); + } + + /** + * Checks whether a node is a string literal. + * @param {ASTNode} node Any AST node. + * @returns {boolean} `true` if it is a string literal. + */ + function isStringLiteral(node) { + return node.type === "Literal" && typeof node.value === "string"; + } + + /** + * Determines if the property is a shorthand or not. + * @param {ASTNode} property Property AST node + * @returns {boolean} True if the property is considered shorthand, false if not. + * @private + * + */ + function isShorthand(property) { + + // property.method is true when `{a(){}}`. + return (property.shorthand || property.method); + } + + /** + * Determines if the property's key and method or value are named equally. + * @param {ASTNode} property Property AST node + * @returns {boolean} True if the key and value are named equally, false if not. + * @private + * + */ + function isRedundant(property) { + const value = property.value; + + if (value.type === "FunctionExpression") { + return !value.id; // Only anonymous should be shorthand method. + } + if (value.type === "Identifier") { + return astUtils.getStaticPropertyName(property) === value.name; + } + + return false; + } + + /** + * Ensures that an object's properties are consistently shorthand, or not shorthand at all. + * @param {ASTNode} node Property AST node + * @param {boolean} checkRedundancy Whether to check longform redundancy + * @returns {void} + * + */ + function checkConsistency(node, checkRedundancy) { + + // We are excluding getters/setters and spread properties as they are considered neither longform nor shorthand. + const properties = node.properties.filter(canHaveShorthand); + + // Do we still have properties left after filtering the getters and setters? + if (properties.length > 0) { + const shorthandProperties = properties.filter(isShorthand); + + /* + * If we do not have an equal number of longform properties as + * shorthand properties, we are using the annotations inconsistently + */ + if (shorthandProperties.length !== properties.length) { + + // We have at least 1 shorthand property + if (shorthandProperties.length > 0) { + context.report({ node, messageId: "unexpectedMix" }); + } else if (checkRedundancy) { + + /* + * If all properties of the object contain a method or value with a name matching it's key, + * all the keys are redundant. + */ + const canAlwaysUseShorthand = properties.every(isRedundant); + + if (canAlwaysUseShorthand) { + context.report({ node, messageId: "expectedAllPropertiesShorthanded" }); + } + } + } + } + } + + /** + * Fixes a FunctionExpression node by making it into a shorthand property. + * @param {SourceCodeFixer} fixer The fixer object + * @param {ASTNode} node A `Property` node that has a `FunctionExpression` or `ArrowFunctionExpression` as its value + * @returns {Object} A fix for this node + */ + function makeFunctionShorthand(fixer, node) { + const firstKeyToken = node.computed + ? sourceCode.getFirstToken(node, astUtils.isOpeningBracketToken) + : sourceCode.getFirstToken(node.key); + const lastKeyToken = node.computed + ? sourceCode.getFirstTokenBetween(node.key, node.value, astUtils.isClosingBracketToken) + : sourceCode.getLastToken(node.key); + const keyText = sourceCode.text.slice(firstKeyToken.range[0], lastKeyToken.range[1]); + let keyPrefix = ""; + + // key: /* */ () => {} + if (sourceCode.commentsExistBetween(lastKeyToken, node.value)) { + return null; + } + + if (node.value.async) { + keyPrefix += "async "; + } + if (node.value.generator) { + keyPrefix += "*"; + } + + const fixRange = [firstKeyToken.range[0], node.range[1]]; + const methodPrefix = keyPrefix + keyText; + + if (node.value.type === "FunctionExpression") { + const functionToken = sourceCode.getTokens(node.value).find(token => token.type === "Keyword" && token.value === "function"); + const tokenBeforeParams = node.value.generator ? sourceCode.getTokenAfter(functionToken) : functionToken; + + return fixer.replaceTextRange( + fixRange, + methodPrefix + sourceCode.text.slice(tokenBeforeParams.range[1], node.value.range[1]) + ); + } + + const arrowToken = sourceCode.getTokenBefore(node.value.body, astUtils.isArrowToken); + const fnBody = sourceCode.text.slice(arrowToken.range[1], node.value.range[1]); + + let shouldAddParensAroundParameters = false; + let tokenBeforeParams; + + if (node.value.params.length === 0) { + tokenBeforeParams = sourceCode.getFirstToken(node.value, astUtils.isOpeningParenToken); + } else { + tokenBeforeParams = sourceCode.getTokenBefore(node.value.params[0]); + } + + if (node.value.params.length === 1) { + const hasParen = astUtils.isOpeningParenToken(tokenBeforeParams); + const isTokenOutsideNode = tokenBeforeParams.range[0] < node.range[0]; + + shouldAddParensAroundParameters = !hasParen || isTokenOutsideNode; + } + + const sliceStart = shouldAddParensAroundParameters + ? node.value.params[0].range[0] + : tokenBeforeParams.range[0]; + const sliceEnd = sourceCode.getTokenBefore(arrowToken).range[1]; + + const oldParamText = sourceCode.text.slice(sliceStart, sliceEnd); + const newParamText = shouldAddParensAroundParameters ? `(${oldParamText})` : oldParamText; + + return fixer.replaceTextRange( + fixRange, + methodPrefix + newParamText + fnBody + ); + + } + + /** + * Fixes a FunctionExpression node by making it into a longform property. + * @param {SourceCodeFixer} fixer The fixer object + * @param {ASTNode} node A `Property` node that has a `FunctionExpression` as its value + * @returns {Object} A fix for this node + */ + function makeFunctionLongform(fixer, node) { + const firstKeyToken = node.computed ? sourceCode.getTokens(node).find(token => token.value === "[") : sourceCode.getFirstToken(node.key); + const lastKeyToken = node.computed ? sourceCode.getTokensBetween(node.key, node.value).find(token => token.value === "]") : sourceCode.getLastToken(node.key); + const keyText = sourceCode.text.slice(firstKeyToken.range[0], lastKeyToken.range[1]); + let functionHeader = "function"; + + if (node.value.async) { + functionHeader = `async ${functionHeader}`; + } + if (node.value.generator) { + functionHeader = `${functionHeader}*`; + } + + return fixer.replaceTextRange([node.range[0], lastKeyToken.range[1]], `${keyText}: ${functionHeader}`); + } + + /* + * To determine whether a given arrow function has a lexical identifier (`this`, `arguments`, `super`, or `new.target`), + * create a stack of functions that define these identifiers (i.e. all functions except arrow functions) as the AST is + * traversed. Whenever a new function is encountered, create a new entry on the stack (corresponding to a different lexical + * scope of `this`), and whenever a function is exited, pop that entry off the stack. When an arrow function is entered, + * keep a reference to it on the current stack entry, and remove that reference when the arrow function is exited. + * When a lexical identifier is encountered, mark all the arrow functions on the current stack entry by adding them + * to an `arrowsWithLexicalIdentifiers` set. Any arrow function in that set will not be reported by this rule, + * because converting it into a method would change the value of one of the lexical identifiers. + */ + const lexicalScopeStack = []; + const arrowsWithLexicalIdentifiers = new WeakSet(); + const argumentsIdentifiers = new WeakSet(); + + /** + * Enters a function. This creates a new lexical identifier scope, so a new Set of arrow functions is pushed onto the stack. + * Also, this marks all `arguments` identifiers so that they can be detected later. + * @returns {void} + */ + function enterFunction() { + lexicalScopeStack.unshift(new Set()); + context.getScope().variables.filter(variable => variable.name === "arguments").forEach(variable => { + variable.references.map(ref => ref.identifier).forEach(identifier => argumentsIdentifiers.add(identifier)); + }); + } + + /** + * Exits a function. This pops the current set of arrow functions off the lexical scope stack. + * @returns {void} + */ + function exitFunction() { + lexicalScopeStack.shift(); + } + + /** + * Marks the current function as having a lexical keyword. This implies that all arrow functions + * in the current lexical scope contain a reference to this lexical keyword. + * @returns {void} + */ + function reportLexicalIdentifier() { + lexicalScopeStack[0].forEach(arrowFunction => arrowsWithLexicalIdentifiers.add(arrowFunction)); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + Program: enterFunction, + FunctionDeclaration: enterFunction, + FunctionExpression: enterFunction, + "Program:exit": exitFunction, + "FunctionDeclaration:exit": exitFunction, + "FunctionExpression:exit": exitFunction, + + ArrowFunctionExpression(node) { + lexicalScopeStack[0].add(node); + }, + "ArrowFunctionExpression:exit"(node) { + lexicalScopeStack[0].delete(node); + }, + + ThisExpression: reportLexicalIdentifier, + Super: reportLexicalIdentifier, + MetaProperty(node) { + if (node.meta.name === "new" && node.property.name === "target") { + reportLexicalIdentifier(); + } + }, + Identifier(node) { + if (argumentsIdentifiers.has(node)) { + reportLexicalIdentifier(); + } + }, + + ObjectExpression(node) { + if (APPLY_CONSISTENT) { + checkConsistency(node, false); + } else if (APPLY_CONSISTENT_AS_NEEDED) { + checkConsistency(node, true); + } + }, + + "Property:exit"(node) { + const isConciseProperty = node.method || node.shorthand; + + // Ignore destructuring assignment + if (node.parent.type === "ObjectPattern") { + return; + } + + // getters and setters are ignored + if (node.kind === "get" || node.kind === "set") { + return; + } + + // only computed methods can fail the following checks + if (node.computed && node.value.type !== "FunctionExpression" && node.value.type !== "ArrowFunctionExpression") { + return; + } + + //-------------------------------------------------------------- + // Checks for property/method shorthand. + if (isConciseProperty) { + if (node.method && (APPLY_NEVER || AVOID_QUOTES && isStringLiteral(node.key))) { + const messageId = APPLY_NEVER ? "expectedMethodLongform" : "expectedLiteralMethodLongform"; + + // { x() {} } should be written as { x: function() {} } + context.report({ + node, + messageId, + fix: fixer => makeFunctionLongform(fixer, node) + }); + } else if (APPLY_NEVER) { + + // { x } should be written as { x: x } + context.report({ + node, + messageId: "expectedPropertyLongform", + fix: fixer => fixer.insertTextAfter(node.key, `: ${node.key.name}`) + }); + } + } else if (APPLY_TO_METHODS && !node.value.id && (node.value.type === "FunctionExpression" || node.value.type === "ArrowFunctionExpression")) { + if (IGNORE_CONSTRUCTORS && node.key.type === "Identifier" && isConstructor(node.key.name)) { + return; + } + if (AVOID_QUOTES && isStringLiteral(node.key)) { + return; + } + + // {[x]: function(){}} should be written as {[x]() {}} + if (node.value.type === "FunctionExpression" || + node.value.type === "ArrowFunctionExpression" && + node.value.body.type === "BlockStatement" && + AVOID_EXPLICIT_RETURN_ARROWS && + !arrowsWithLexicalIdentifiers.has(node.value) + ) { + context.report({ + node, + messageId: "expectedMethodShorthand", + fix: fixer => makeFunctionShorthand(fixer, node) + }); + } + } else if (node.value.type === "Identifier" && node.key.name === node.value.name && APPLY_TO_PROPS) { + + // {x: x} should be written as {x} + context.report({ + node, + messageId: "expectedPropertyShorthand", + fix(fixer) { + return fixer.replaceText(node, node.value.name); + } + }); + } else if (node.value.type === "Identifier" && node.key.type === "Literal" && node.key.value === node.value.name && APPLY_TO_PROPS) { + if (AVOID_QUOTES) { + return; + } + + // {"x": x} should be written as {x} + context.report({ + node, + messageId: "expectedPropertyShorthand", + fix(fixer) { + return fixer.replaceText(node, node.value.name); + } + }); + } + } + }; + } +}; + +/** + * @fileoverview A rule to control the use of single variable declarations. + * @author Ian Christian Myers + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Determines whether the given node is in a statement list. + * @param {ASTNode} node node to check + * @returns {boolean} `true` if the given node is in a statement list + */ +function isInStatementList(node) { + return astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var oneVar = { + meta: { + type: "suggestion", + + docs: { + description: "enforce variables to be declared either together or separately in functions", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/one-var" + }, + + fixable: "code", + + schema: [ + { + oneOf: [ + { + enum: ["always", "never", "consecutive"] + }, + { + type: "object", + properties: { + separateRequires: { + type: "boolean" + }, + var: { + enum: ["always", "never", "consecutive"] + }, + let: { + enum: ["always", "never", "consecutive"] + }, + const: { + enum: ["always", "never", "consecutive"] + } + }, + additionalProperties: false + }, + { + type: "object", + properties: { + initialized: { + enum: ["always", "never", "consecutive"] + }, + uninitialized: { + enum: ["always", "never", "consecutive"] + } + }, + additionalProperties: false + } + ] + } + ], + + messages: { + combineUninitialized: "Combine this with the previous '{{type}}' statement with uninitialized variables.", + combineInitialized: "Combine this with the previous '{{type}}' statement with initialized variables.", + splitUninitialized: "Split uninitialized '{{type}}' declarations into multiple statements.", + splitInitialized: "Split initialized '{{type}}' declarations into multiple statements.", + splitRequires: "Split requires to be separated into a single block.", + combine: "Combine this with the previous '{{type}}' statement.", + split: "Split '{{type}}' declarations into multiple statements." + } + }, + + create(context) { + const MODE_ALWAYS = "always"; + const MODE_NEVER = "never"; + const MODE_CONSECUTIVE = "consecutive"; + const mode = context.options[0] || MODE_ALWAYS; + + const options = {}; + + if (typeof mode === "string") { // simple options configuration with just a string + options.var = { uninitialized: mode, initialized: mode }; + options.let = { uninitialized: mode, initialized: mode }; + options.const = { uninitialized: mode, initialized: mode }; + } else if (typeof mode === "object") { // options configuration is an object + options.separateRequires = !!mode.separateRequires; + options.var = { uninitialized: mode.var, initialized: mode.var }; + options.let = { uninitialized: mode.let, initialized: mode.let }; + options.const = { uninitialized: mode.const, initialized: mode.const }; + if (Object.prototype.hasOwnProperty.call(mode, "uninitialized")) { + options.var.uninitialized = mode.uninitialized; + options.let.uninitialized = mode.uninitialized; + options.const.uninitialized = mode.uninitialized; + } + if (Object.prototype.hasOwnProperty.call(mode, "initialized")) { + options.var.initialized = mode.initialized; + options.let.initialized = mode.initialized; + options.const.initialized = mode.initialized; + } + } + + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + const functionStack = []; + const blockStack = []; + + /** + * Increments the blockStack counter. + * @returns {void} + * @private + */ + function startBlock() { + blockStack.push({ + let: { initialized: false, uninitialized: false }, + const: { initialized: false, uninitialized: false } + }); + } + + /** + * Increments the functionStack counter. + * @returns {void} + * @private + */ + function startFunction() { + functionStack.push({ initialized: false, uninitialized: false }); + startBlock(); + } + + /** + * Decrements the blockStack counter. + * @returns {void} + * @private + */ + function endBlock() { + blockStack.pop(); + } + + /** + * Decrements the functionStack counter. + * @returns {void} + * @private + */ + function endFunction() { + functionStack.pop(); + endBlock(); + } + + /** + * Check if a variable declaration is a require. + * @param {ASTNode} decl variable declaration Node + * @returns {bool} if decl is a require, return true; else return false. + * @private + */ + function isRequire(decl) { + return decl.init && decl.init.type === "CallExpression" && decl.init.callee.name === "require"; + } + + /** + * Records whether initialized/uninitialized/required variables are defined in current scope. + * @param {string} statementType node.kind, one of: "var", "let", or "const" + * @param {ASTNode[]} declarations List of declarations + * @param {Object} currentScope The scope being investigated + * @returns {void} + * @private + */ + function recordTypes(statementType, declarations, currentScope) { + for (let i = 0; i < declarations.length; i++) { + if (declarations[i].init === null) { + if (options[statementType] && options[statementType].uninitialized === MODE_ALWAYS) { + currentScope.uninitialized = true; + } + } else { + if (options[statementType] && options[statementType].initialized === MODE_ALWAYS) { + if (options.separateRequires && isRequire(declarations[i])) { + currentScope.required = true; + } else { + currentScope.initialized = true; + } + } + } + } + } + + /** + * Determines the current scope (function or block) + * @param {string} statementType node.kind, one of: "var", "let", or "const" + * @returns {Object} The scope associated with statementType + */ + function getCurrentScope(statementType) { + let currentScope; + + if (statementType === "var") { + currentScope = functionStack[functionStack.length - 1]; + } else if (statementType === "let") { + currentScope = blockStack[blockStack.length - 1].let; + } else if (statementType === "const") { + currentScope = blockStack[blockStack.length - 1].const; + } + return currentScope; + } + + /** + * Counts the number of initialized and uninitialized declarations in a list of declarations + * @param {ASTNode[]} declarations List of declarations + * @returns {Object} Counts of 'uninitialized' and 'initialized' declarations + * @private + */ + function countDeclarations(declarations) { + const counts = { uninitialized: 0, initialized: 0 }; + + for (let i = 0; i < declarations.length; i++) { + if (declarations[i].init === null) { + counts.uninitialized++; + } else { + counts.initialized++; + } + } + return counts; + } + + /** + * Determines if there is more than one var statement in the current scope. + * @param {string} statementType node.kind, one of: "var", "let", or "const" + * @param {ASTNode[]} declarations List of declarations + * @returns {boolean} Returns true if it is the first var declaration, false if not. + * @private + */ + function hasOnlyOneStatement(statementType, declarations) { + + const declarationCounts = countDeclarations(declarations); + const currentOptions = options[statementType] || {}; + const currentScope = getCurrentScope(statementType); + const hasRequires = declarations.some(isRequire); + + if (currentOptions.uninitialized === MODE_ALWAYS && currentOptions.initialized === MODE_ALWAYS) { + if (currentScope.uninitialized || currentScope.initialized) { + if (!hasRequires) { + return false; + } + } + } + + if (declarationCounts.uninitialized > 0) { + if (currentOptions.uninitialized === MODE_ALWAYS && currentScope.uninitialized) { + return false; + } + } + if (declarationCounts.initialized > 0) { + if (currentOptions.initialized === MODE_ALWAYS && currentScope.initialized) { + if (!hasRequires) { + return false; + } + } + } + if (currentScope.required && hasRequires) { + return false; + } + recordTypes(statementType, declarations, currentScope); + return true; + } + + /** + * Fixer to join VariableDeclaration's into a single declaration + * @param {VariableDeclarator[]} declarations The `VariableDeclaration` to join + * @returns {Function} The fixer function + */ + function joinDeclarations(declarations) { + const declaration = declarations[0]; + const body = Array.isArray(declaration.parent.parent.body) ? declaration.parent.parent.body : []; + const currentIndex = body.findIndex(node => node.range[0] === declaration.parent.range[0]); + const previousNode = body[currentIndex - 1]; + + return fixer => { + const type = sourceCode.getTokenBefore(declaration); + const prevSemi = sourceCode.getTokenBefore(type); + const res = []; + + if (previousNode && previousNode.kind === sourceCode.getText(type)) { + if (prevSemi.value === ";") { + res.push(fixer.replaceText(prevSemi, ",")); + } else { + res.push(fixer.insertTextAfter(prevSemi, ",")); + } + res.push(fixer.replaceText(type, "")); + } + + return res; + }; + } + + /** + * Fixer to split a VariableDeclaration into individual declarations + * @param {VariableDeclaration} declaration The `VariableDeclaration` to split + * @returns {Function|null} The fixer function + */ + function splitDeclarations(declaration) { + const { parent } = declaration; + + // don't autofix code such as: if (foo) var x, y; + if (!isInStatementList(parent.type === "ExportNamedDeclaration" ? parent : declaration)) { + return null; + } + + return fixer => declaration.declarations.map(declarator => { + const tokenAfterDeclarator = sourceCode.getTokenAfter(declarator); + + if (tokenAfterDeclarator === null) { + return null; + } + + const afterComma = sourceCode.getTokenAfter(tokenAfterDeclarator, { includeComments: true }); + + if (tokenAfterDeclarator.value !== ",") { + return null; + } + + const exportPlacement = declaration.parent.type === "ExportNamedDeclaration" ? "export " : ""; + + /* + * `var x,y` + * tokenAfterDeclarator ^^ afterComma + */ + if (afterComma.range[0] === tokenAfterDeclarator.range[1]) { + return fixer.replaceText(tokenAfterDeclarator, `; ${exportPlacement}${declaration.kind} `); + } + + /* + * `var x, + * tokenAfterDeclarator ^ + * y` + * ^ afterComma + */ + if ( + afterComma.loc.start.line > tokenAfterDeclarator.loc.end.line || + afterComma.type === "Line" || + afterComma.type === "Block" + ) { + let lastComment = afterComma; + + while (lastComment.type === "Line" || lastComment.type === "Block") { + lastComment = sourceCode.getTokenAfter(lastComment, { includeComments: true }); + } + + return fixer.replaceTextRange( + [tokenAfterDeclarator.range[0], lastComment.range[0]], + `;${sourceCode.text.slice(tokenAfterDeclarator.range[1], lastComment.range[0])}${exportPlacement}${declaration.kind} ` + ); + } + + return fixer.replaceText(tokenAfterDeclarator, `; ${exportPlacement}${declaration.kind}`); + }).filter(x => x); + } + + /** + * Checks a given VariableDeclaration node for errors. + * @param {ASTNode} node The VariableDeclaration node to check + * @returns {void} + * @private + */ + function checkVariableDeclaration(node) { + const parent = node.parent; + const type = node.kind; + + if (!options[type]) { + return; + } + + const declarations = node.declarations; + const declarationCounts = countDeclarations(declarations); + const mixedRequires = declarations.some(isRequire) && !declarations.every(isRequire); + + if (options[type].initialized === MODE_ALWAYS) { + if (options.separateRequires && mixedRequires) { + context.report({ + node, + messageId: "splitRequires" + }); + } + } + + // consecutive + const nodeIndex = (parent.body && parent.body.length > 0 && parent.body.indexOf(node)) || 0; + + if (nodeIndex > 0) { + const previousNode = parent.body[nodeIndex - 1]; + const isPreviousNodeDeclaration = previousNode.type === "VariableDeclaration"; + const declarationsWithPrevious = declarations.concat(previousNode.declarations || []); + + if ( + isPreviousNodeDeclaration && + previousNode.kind === type && + !(declarationsWithPrevious.some(isRequire) && !declarationsWithPrevious.every(isRequire)) + ) { + const previousDeclCounts = countDeclarations(previousNode.declarations); + + if (options[type].initialized === MODE_CONSECUTIVE && options[type].uninitialized === MODE_CONSECUTIVE) { + context.report({ + node, + messageId: "combine", + data: { + type + }, + fix: joinDeclarations(declarations) + }); + } else if (options[type].initialized === MODE_CONSECUTIVE && declarationCounts.initialized > 0 && previousDeclCounts.initialized > 0) { + context.report({ + node, + messageId: "combineInitialized", + data: { + type + }, + fix: joinDeclarations(declarations) + }); + } else if (options[type].uninitialized === MODE_CONSECUTIVE && + declarationCounts.uninitialized > 0 && + previousDeclCounts.uninitialized > 0) { + context.report({ + node, + messageId: "combineUninitialized", + data: { + type + }, + fix: joinDeclarations(declarations) + }); + } + } + } + + // always + if (!hasOnlyOneStatement(type, declarations)) { + if (options[type].initialized === MODE_ALWAYS && options[type].uninitialized === MODE_ALWAYS) { + context.report({ + node, + messageId: "combine", + data: { + type + }, + fix: joinDeclarations(declarations) + }); + } else { + if (options[type].initialized === MODE_ALWAYS && declarationCounts.initialized > 0) { + context.report({ + node, + messageId: "combineInitialized", + data: { + type + }, + fix: joinDeclarations(declarations) + }); + } + if (options[type].uninitialized === MODE_ALWAYS && declarationCounts.uninitialized > 0) { + if (node.parent.left === node && (node.parent.type === "ForInStatement" || node.parent.type === "ForOfStatement")) { + return; + } + context.report({ + node, + messageId: "combineUninitialized", + data: { + type + }, + fix: joinDeclarations(declarations) + }); + } + } + } + + // never + if (parent.type !== "ForStatement" || parent.init !== node) { + const totalDeclarations = declarationCounts.uninitialized + declarationCounts.initialized; + + if (totalDeclarations > 1) { + if (options[type].initialized === MODE_NEVER && options[type].uninitialized === MODE_NEVER) { + + // both initialized and uninitialized + context.report({ + node, + messageId: "split", + data: { + type + }, + fix: splitDeclarations(node) + }); + } else if (options[type].initialized === MODE_NEVER && declarationCounts.initialized > 0) { + + // initialized + context.report({ + node, + messageId: "splitInitialized", + data: { + type + }, + fix: splitDeclarations(node) + }); + } else if (options[type].uninitialized === MODE_NEVER && declarationCounts.uninitialized > 0) { + + // uninitialized + context.report({ + node, + messageId: "splitUninitialized", + data: { + type + }, + fix: splitDeclarations(node) + }); + } + } + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + Program: startFunction, + FunctionDeclaration: startFunction, + FunctionExpression: startFunction, + ArrowFunctionExpression: startFunction, + BlockStatement: startBlock, + ForStatement: startBlock, + ForInStatement: startBlock, + ForOfStatement: startBlock, + SwitchStatement: startBlock, + VariableDeclaration: checkVariableDeclaration, + "ForStatement:exit": endBlock, + "ForOfStatement:exit": endBlock, + "ForInStatement:exit": endBlock, + "SwitchStatement:exit": endBlock, + "BlockStatement:exit": endBlock, + "Program:exit": endFunction, + "FunctionDeclaration:exit": endFunction, + "FunctionExpression:exit": endFunction, + "ArrowFunctionExpression:exit": endFunction + }; + + } +}; + +/** + * @fileoverview Rule to check multiple var declarations per line + * @author Alberto Rodríguez + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var oneVarDeclarationPerLine = { + meta: { + type: "suggestion", + + docs: { + description: "require or disallow newlines around variable declarations", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/one-var-declaration-per-line" + }, + + schema: [ + { + enum: ["always", "initializations"] + } + ], + + fixable: "whitespace", + + messages: { + expectVarOnNewline: "Expected variable declaration to be on a new line." + } + }, + + create(context) { + + const always = context.options[0] === "always"; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + + /** + * Determine if provided keyword is a variant of for specifiers + * @private + * @param {string} keyword keyword to test + * @returns {boolean} True if `keyword` is a variant of for specifier + */ + function isForTypeSpecifier(keyword) { + return keyword === "ForStatement" || keyword === "ForInStatement" || keyword === "ForOfStatement"; + } + + /** + * Checks newlines around variable declarations. + * @private + * @param {ASTNode} node `VariableDeclaration` node to test + * @returns {void} + */ + function checkForNewLine(node) { + if (isForTypeSpecifier(node.parent.type)) { + return; + } + + const declarations = node.declarations; + let prev; + + declarations.forEach(current => { + if (prev && prev.loc.end.line === current.loc.start.line) { + if (always || prev.init || current.init) { + context.report({ + node, + messageId: "expectVarOnNewline", + loc: current.loc, + fix: fixer => fixer.insertTextBefore(current, "\n") + }); + } + } + prev = current; + }); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + VariableDeclaration: checkForNewLine + }; + + } +}; + +/** + * @fileoverview Rule to replace assignment expressions with operator assignment + * @author Brandon Mills + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether an operator is commutative and has an operator assignment + * shorthand form. + * @param {string} operator Operator to check. + * @returns {boolean} True if the operator is commutative and has a + * shorthand form. + */ +function isCommutativeOperatorWithShorthand(operator) { + return ["*", "&", "^", "|"].indexOf(operator) >= 0; +} + +/** + * Checks whether an operator is not commutative and has an operator assignment + * shorthand form. + * @param {string} operator Operator to check. + * @returns {boolean} True if the operator is not commutative and has + * a shorthand form. + */ +function isNonCommutativeOperatorWithShorthand(operator) { + return ["+", "-", "/", "%", "<<", ">>", ">>>", "**"].indexOf(operator) >= 0; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +/** + * Determines if the left side of a node can be safely fixed (i.e. if it activates the same getters/setters and) + * toString calls regardless of whether assignment shorthand is used) + * @param {ASTNode} node The node on the left side of the expression + * @returns {boolean} `true` if the node can be fixed + */ +function canBeFixed(node) { + return ( + node.type === "Identifier" || + ( + node.type === "MemberExpression" && + (node.object.type === "Identifier" || node.object.type === "ThisExpression") && + (!node.computed || node.property.type === "Literal") + ) + ); +} + +var operatorAssignment = { + meta: { + type: "suggestion", + + docs: { + description: "require or disallow assignment operator shorthand where possible", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/operator-assignment" + }, + + schema: [ + { + enum: ["always", "never"] + } + ], + + fixable: "code", + messages: { + replaced: "Assignment can be replaced with operator assignment.", + unexpected: "Unexpected operator assignment shorthand." + } + }, + + create(context) { + + const sourceCode = context.getSourceCode(); + + /** + * Returns the operator token of an AssignmentExpression or BinaryExpression + * @param {ASTNode} node An AssignmentExpression or BinaryExpression node + * @returns {Token} The operator token in the node + */ + function getOperatorToken(node) { + return sourceCode.getFirstTokenBetween(node.left, node.right, token => token.value === node.operator); + } + + /** + * Ensures that an assignment uses the shorthand form where possible. + * @param {ASTNode} node An AssignmentExpression node. + * @returns {void} + */ + function verify(node) { + if (node.operator !== "=" || node.right.type !== "BinaryExpression") { + return; + } + + const left = node.left; + const expr = node.right; + const operator = expr.operator; + + if (isCommutativeOperatorWithShorthand(operator) || isNonCommutativeOperatorWithShorthand(operator)) { + if (astUtils.isSameReference(left, expr.left, true)) { + context.report({ + node, + messageId: "replaced", + fix(fixer) { + if (canBeFixed(left) && canBeFixed(expr.left)) { + const equalsToken = getOperatorToken(node); + const operatorToken = getOperatorToken(expr); + const leftText = sourceCode.getText().slice(node.range[0], equalsToken.range[0]); + const rightText = sourceCode.getText().slice(operatorToken.range[1], node.right.range[1]); + + // Check for comments that would be removed. + if (sourceCode.commentsExistBetween(equalsToken, operatorToken)) { + return null; + } + + return fixer.replaceText(node, `${leftText}${expr.operator}=${rightText}`); + } + return null; + } + }); + } else if (astUtils.isSameReference(left, expr.right, true) && isCommutativeOperatorWithShorthand(operator)) { + + /* + * This case can't be fixed safely. + * If `a` and `b` both have custom valueOf() behavior, then fixing `a = b * a` to `a *= b` would + * change the execution order of the valueOf() functions. + */ + context.report({ + node, + messageId: "replaced" + }); + } + } + } + + /** + * Warns if an assignment expression uses operator assignment shorthand. + * @param {ASTNode} node An AssignmentExpression node. + * @returns {void} + */ + function prohibit(node) { + if (node.operator !== "=" && !astUtils.isLogicalAssignmentOperator(node.operator)) { + context.report({ + node, + messageId: "unexpected", + fix(fixer) { + if (canBeFixed(node.left)) { + const firstToken = sourceCode.getFirstToken(node); + const operatorToken = getOperatorToken(node); + const leftText = sourceCode.getText().slice(node.range[0], operatorToken.range[0]); + const newOperator = node.operator.slice(0, -1); + let rightText; + + // Check for comments that would be duplicated. + if (sourceCode.commentsExistBetween(firstToken, operatorToken)) { + return null; + } + + // If this change would modify precedence (e.g. `foo *= bar + 1` => `foo = foo * (bar + 1)`), parenthesize the right side. + if ( + astUtils.getPrecedence(node.right) <= astUtils.getPrecedence({ type: "BinaryExpression", operator: newOperator }) && + !astUtils.isParenthesised(sourceCode, node.right) + ) { + rightText = `${sourceCode.text.slice(operatorToken.range[1], node.right.range[0])}(${sourceCode.getText(node.right)})`; + } else { + const tokenAfterOperator = sourceCode.getTokenAfter(operatorToken, { includeComments: true }); + let rightTextPrefix = ""; + + if ( + operatorToken.range[1] === tokenAfterOperator.range[0] && + !astUtils.canTokensBeAdjacent({ type: "Punctuator", value: newOperator }, tokenAfterOperator) + ) { + rightTextPrefix = " "; // foo+=+bar -> foo= foo+ +bar + } + + rightText = `${rightTextPrefix}${sourceCode.text.slice(operatorToken.range[1], node.range[1])}`; + } + + return fixer.replaceText(node, `${leftText}= ${leftText}${newOperator}${rightText}`); + } + return null; + } + }); + } + } + + return { + AssignmentExpression: context.options[0] !== "never" ? verify : prohibit + }; + + } +}; + +/** + * @fileoverview Operator linebreak - enforces operator linebreak style of two types: after and before + * @author Benoît Zugmeyer + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var operatorLinebreak = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent linebreak style for operators", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/operator-linebreak" + }, + + schema: [ + { + enum: ["after", "before", "none", null] + }, + { + type: "object", + properties: { + overrides: { + type: "object", + additionalProperties: { + enum: ["after", "before", "none", "ignore"] + } + } + }, + additionalProperties: false + } + ], + + fixable: "code", + + messages: { + operatorAtBeginning: "'{{operator}}' should be placed at the beginning of the line.", + operatorAtEnd: "'{{operator}}' should be placed at the end of the line.", + badLinebreak: "Bad line breaking before and after '{{operator}}'.", + noLinebreak: "There should be no line break before or after '{{operator}}'." + } + }, + + create(context) { + + const usedDefaultGlobal = !context.options[0]; + const globalStyle = context.options[0] || "after"; + const options = context.options[1] || {}; + const styleOverrides = options.overrides ? Object.assign({}, options.overrides) : {}; + + if (usedDefaultGlobal && !styleOverrides["?"]) { + styleOverrides["?"] = "before"; + } + + if (usedDefaultGlobal && !styleOverrides[":"]) { + styleOverrides[":"] = "before"; + } + + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Gets a fixer function to fix rule issues + * @param {Token} operatorToken The operator token of an expression + * @param {string} desiredStyle The style for the rule. One of 'before', 'after', 'none' + * @returns {Function} A fixer function + */ + function getFixer(operatorToken, desiredStyle) { + return fixer => { + const tokenBefore = sourceCode.getTokenBefore(operatorToken); + const tokenAfter = sourceCode.getTokenAfter(operatorToken); + const textBefore = sourceCode.text.slice(tokenBefore.range[1], operatorToken.range[0]); + const textAfter = sourceCode.text.slice(operatorToken.range[1], tokenAfter.range[0]); + const hasLinebreakBefore = !astUtils.isTokenOnSameLine(tokenBefore, operatorToken); + const hasLinebreakAfter = !astUtils.isTokenOnSameLine(operatorToken, tokenAfter); + let newTextBefore, newTextAfter; + + if (hasLinebreakBefore !== hasLinebreakAfter && desiredStyle !== "none") { + + // If there is a comment before and after the operator, don't do a fix. + if (sourceCode.getTokenBefore(operatorToken, { includeComments: true }) !== tokenBefore && + sourceCode.getTokenAfter(operatorToken, { includeComments: true }) !== tokenAfter) { + + return null; + } + + /* + * If there is only one linebreak and it's on the wrong side of the operator, swap the text before and after the operator. + * foo && + * bar + * would get fixed to + * foo + * && bar + */ + newTextBefore = textAfter; + newTextAfter = textBefore; + } else { + const LINEBREAK_REGEX = astUtils.createGlobalLinebreakMatcher(); + + // Otherwise, if no linebreak is desired and no comments interfere, replace the linebreaks with empty strings. + newTextBefore = desiredStyle === "before" || textBefore.trim() ? textBefore : textBefore.replace(LINEBREAK_REGEX, ""); + newTextAfter = desiredStyle === "after" || textAfter.trim() ? textAfter : textAfter.replace(LINEBREAK_REGEX, ""); + + // If there was no change (due to interfering comments), don't output a fix. + if (newTextBefore === textBefore && newTextAfter === textAfter) { + return null; + } + } + + if (newTextAfter === "" && tokenAfter.type === "Punctuator" && "+-".includes(operatorToken.value) && tokenAfter.value === operatorToken.value) { + + // To avoid accidentally creating a ++ or -- operator, insert a space if the operator is a +/- and the following token is a unary +/-. + newTextAfter += " "; + } + + return fixer.replaceTextRange([tokenBefore.range[1], tokenAfter.range[0]], newTextBefore + operatorToken.value + newTextAfter); + }; + } + + /** + * Checks the operator placement + * @param {ASTNode} node The node to check + * @param {ASTNode} leftSide The node that comes before the operator in `node` + * @private + * @returns {void} + */ + function validateNode(node, leftSide) { + + /* + * When the left part of a binary expression is a single expression wrapped in + * parentheses (ex: `(a) + b`), leftToken will be the last token of the expression + * and operatorToken will be the closing parenthesis. + * The leftToken should be the last closing parenthesis, and the operatorToken + * should be the token right after that. + */ + const operatorToken = sourceCode.getTokenAfter(leftSide, astUtils.isNotClosingParenToken); + const leftToken = sourceCode.getTokenBefore(operatorToken); + const rightToken = sourceCode.getTokenAfter(operatorToken); + const operator = operatorToken.value; + const operatorStyleOverride = styleOverrides[operator]; + const style = operatorStyleOverride || globalStyle; + const fix = getFixer(operatorToken, style); + + // if single line + if (astUtils.isTokenOnSameLine(leftToken, operatorToken) && + astUtils.isTokenOnSameLine(operatorToken, rightToken)) ; else if (operatorStyleOverride !== "ignore" && !astUtils.isTokenOnSameLine(leftToken, operatorToken) && + !astUtils.isTokenOnSameLine(operatorToken, rightToken)) { + + // lone operator + context.report({ + node, + loc: operatorToken.loc, + messageId: "badLinebreak", + data: { + operator + }, + fix + }); + + } else if (style === "before" && astUtils.isTokenOnSameLine(leftToken, operatorToken)) { + + context.report({ + node, + loc: operatorToken.loc, + messageId: "operatorAtBeginning", + data: { + operator + }, + fix + }); + + } else if (style === "after" && astUtils.isTokenOnSameLine(operatorToken, rightToken)) { + + context.report({ + node, + loc: operatorToken.loc, + messageId: "operatorAtEnd", + data: { + operator + }, + fix + }); + + } else if (style === "none") { + + context.report({ + node, + loc: operatorToken.loc, + messageId: "noLinebreak", + data: { + operator + }, + fix + }); + + } + } + + /** + * Validates a binary expression using `validateNode` + * @param {BinaryExpression|LogicalExpression|AssignmentExpression} node node to be validated + * @returns {void} + */ + function validateBinaryExpression(node) { + validateNode(node, node.left); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + BinaryExpression: validateBinaryExpression, + LogicalExpression: validateBinaryExpression, + AssignmentExpression: validateBinaryExpression, + VariableDeclarator(node) { + if (node.init) { + validateNode(node, node.id); + } + }, + ConditionalExpression(node) { + validateNode(node, node.test); + validateNode(node, node.consequent); + } + }; + } +}; + +/** + * @fileoverview A rule to ensure blank lines within blocks. + * @author Mathias Schreck + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var paddedBlocks = { + meta: { + type: "layout", + + docs: { + description: "require or disallow padding within blocks", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/padded-blocks" + }, + + fixable: "whitespace", + + schema: [ + { + oneOf: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + blocks: { + enum: ["always", "never"] + }, + switches: { + enum: ["always", "never"] + }, + classes: { + enum: ["always", "never"] + } + }, + additionalProperties: false, + minProperties: 1 + } + ] + }, + { + type: "object", + properties: { + allowSingleLineBlocks: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + + messages: { + alwaysPadBlock: "Block must be padded by blank lines.", + neverPadBlock: "Block must not be padded by blank lines." + } + }, + + create(context) { + const options = {}; + const typeOptions = context.options[0] || "always"; + const exceptOptions = context.options[1] || {}; + + if (typeof typeOptions === "string") { + const shouldHavePadding = typeOptions === "always"; + + options.blocks = shouldHavePadding; + options.switches = shouldHavePadding; + options.classes = shouldHavePadding; + } else { + if (Object.prototype.hasOwnProperty.call(typeOptions, "blocks")) { + options.blocks = typeOptions.blocks === "always"; + } + if (Object.prototype.hasOwnProperty.call(typeOptions, "switches")) { + options.switches = typeOptions.switches === "always"; + } + if (Object.prototype.hasOwnProperty.call(typeOptions, "classes")) { + options.classes = typeOptions.classes === "always"; + } + } + + if (Object.prototype.hasOwnProperty.call(exceptOptions, "allowSingleLineBlocks")) { + options.allowSingleLineBlocks = exceptOptions.allowSingleLineBlocks === true; + } + + const sourceCode = context.getSourceCode(); + + /** + * Gets the open brace token from a given node. + * @param {ASTNode} node A BlockStatement or SwitchStatement node from which to get the open brace. + * @returns {Token} The token of the open brace. + */ + function getOpenBrace(node) { + if (node.type === "SwitchStatement") { + return sourceCode.getTokenBefore(node.cases[0]); + } + return sourceCode.getFirstToken(node); + } + + /** + * Checks if the given parameter is a comment node + * @param {ASTNode|Token} node An AST node or token + * @returns {boolean} True if node is a comment + */ + function isComment(node) { + return node.type === "Line" || node.type === "Block"; + } + + /** + * Checks if there is padding between two tokens + * @param {Token} first The first token + * @param {Token} second The second token + * @returns {boolean} True if there is at least a line between the tokens + */ + function isPaddingBetweenTokens(first, second) { + return second.loc.start.line - first.loc.end.line >= 2; + } + + + /** + * Checks if the given token has a blank line after it. + * @param {Token} token The token to check. + * @returns {boolean} Whether or not the token is followed by a blank line. + */ + function getFirstBlockToken(token) { + let prev, + first = token; + + do { + prev = first; + first = sourceCode.getTokenAfter(first, { includeComments: true }); + } while (isComment(first) && first.loc.start.line === prev.loc.end.line); + + return first; + } + + /** + * Checks if the given token is preceded by a blank line. + * @param {Token} token The token to check + * @returns {boolean} Whether or not the token is preceded by a blank line + */ + function getLastBlockToken(token) { + let last = token, + next; + + do { + next = last; + last = sourceCode.getTokenBefore(last, { includeComments: true }); + } while (isComment(last) && last.loc.end.line === next.loc.start.line); + + return last; + } + + /** + * Checks if a node should be padded, according to the rule config. + * @param {ASTNode} node The AST node to check. + * @returns {boolean} True if the node should be padded, false otherwise. + */ + function requirePaddingFor(node) { + switch (node.type) { + case "BlockStatement": + return options.blocks; + case "SwitchStatement": + return options.switches; + case "ClassBody": + return options.classes; + + /* istanbul ignore next */ + default: + throw new Error("unreachable"); + } + } + + /** + * Checks the given BlockStatement node to be padded if the block is not empty. + * @param {ASTNode} node The AST node of a BlockStatement. + * @returns {void} undefined. + */ + function checkPadding(node) { + const openBrace = getOpenBrace(node), + firstBlockToken = getFirstBlockToken(openBrace), + tokenBeforeFirst = sourceCode.getTokenBefore(firstBlockToken, { includeComments: true }), + closeBrace = sourceCode.getLastToken(node), + lastBlockToken = getLastBlockToken(closeBrace), + tokenAfterLast = sourceCode.getTokenAfter(lastBlockToken, { includeComments: true }), + blockHasTopPadding = isPaddingBetweenTokens(tokenBeforeFirst, firstBlockToken), + blockHasBottomPadding = isPaddingBetweenTokens(lastBlockToken, tokenAfterLast); + + if (options.allowSingleLineBlocks && astUtils.isTokenOnSameLine(tokenBeforeFirst, tokenAfterLast)) { + return; + } + + if (requirePaddingFor(node)) { + + if (!blockHasTopPadding) { + context.report({ + node, + loc: { + start: tokenBeforeFirst.loc.start, + end: firstBlockToken.loc.start + }, + fix(fixer) { + return fixer.insertTextAfter(tokenBeforeFirst, "\n"); + }, + messageId: "alwaysPadBlock" + }); + } + if (!blockHasBottomPadding) { + context.report({ + node, + loc: { + end: tokenAfterLast.loc.start, + start: lastBlockToken.loc.end + }, + fix(fixer) { + return fixer.insertTextBefore(tokenAfterLast, "\n"); + }, + messageId: "alwaysPadBlock" + }); + } + } else { + if (blockHasTopPadding) { + + context.report({ + node, + loc: { + start: tokenBeforeFirst.loc.start, + end: firstBlockToken.loc.start + }, + fix(fixer) { + return fixer.replaceTextRange([tokenBeforeFirst.range[1], firstBlockToken.range[0] - firstBlockToken.loc.start.column], "\n"); + }, + messageId: "neverPadBlock" + }); + } + + if (blockHasBottomPadding) { + + context.report({ + node, + loc: { + end: tokenAfterLast.loc.start, + start: lastBlockToken.loc.end + }, + messageId: "neverPadBlock", + fix(fixer) { + return fixer.replaceTextRange([lastBlockToken.range[1], tokenAfterLast.range[0] - tokenAfterLast.loc.start.column], "\n"); + } + }); + } + } + } + + const rule = {}; + + if (Object.prototype.hasOwnProperty.call(options, "switches")) { + rule.SwitchStatement = function(node) { + if (node.cases.length === 0) { + return; + } + checkPadding(node); + }; + } + + if (Object.prototype.hasOwnProperty.call(options, "blocks")) { + rule.BlockStatement = function(node) { + if (node.body.length === 0) { + return; + } + checkPadding(node); + }; + } + + if (Object.prototype.hasOwnProperty.call(options, "classes")) { + rule.ClassBody = function(node) { + if (node.body.length === 0) { + return; + } + checkPadding(node); + }; + } + + return rule; + } +}; + +/** + * @fileoverview Rule to require or disallow newlines between statements + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const LT = `[${Array.from(astUtils.LINEBREAKS).join("")}]`; +const PADDING_LINE_SEQUENCE = new RegExp( + String.raw`^(\s*?${LT})\s*${LT}(\s*;?)$`, + "u" +); +const CJS_EXPORT = /^(?:module\s*\.\s*)?exports(?:\s*\.|\s*\[|$)/u; +const CJS_IMPORT = /^require\(/u; + +/** + * Creates tester which check if a node starts with specific keyword. + * @param {string} keyword The keyword to test. + * @returns {Object} the created tester. + * @private + */ +function newKeywordTester(keyword) { + return { + test: (node, sourceCode) => + sourceCode.getFirstToken(node).value === keyword + }; +} + +/** + * Creates tester which check if a node starts with specific keyword and spans a single line. + * @param {string} keyword The keyword to test. + * @returns {Object} the created tester. + * @private + */ +function newSinglelineKeywordTester(keyword) { + return { + test: (node, sourceCode) => + node.loc.start.line === node.loc.end.line && + sourceCode.getFirstToken(node).value === keyword + }; +} + +/** + * Creates tester which check if a node starts with specific keyword and spans multiple lines. + * @param {string} keyword The keyword to test. + * @returns {Object} the created tester. + * @private + */ +function newMultilineKeywordTester(keyword) { + return { + test: (node, sourceCode) => + node.loc.start.line !== node.loc.end.line && + sourceCode.getFirstToken(node).value === keyword + }; +} + +/** + * Creates tester which check if a node is specific type. + * @param {string} type The node type to test. + * @returns {Object} the created tester. + * @private + */ +function newNodeTypeTester(type) { + return { + test: node => + node.type === type + }; +} + +/** + * Checks the given node is an expression statement of IIFE. + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if the node is an expression statement of IIFE. + * @private + */ +function isIIFEStatement(node) { + if (node.type === "ExpressionStatement") { + let call = astUtils.skipChainExpression(node.expression); + + if (call.type === "UnaryExpression") { + call = astUtils.skipChainExpression(call.argument); + } + return call.type === "CallExpression" && astUtils.isFunction(call.callee); + } + return false; +} + +/** + * Checks whether the given node is a block-like statement. + * This checks the last token of the node is the closing brace of a block. + * @param {SourceCode} sourceCode The source code to get tokens. + * @param {ASTNode} node The node to check. + * @returns {boolean} `true` if the node is a block-like statement. + * @private + */ +function isBlockLikeStatement(sourceCode, node) { + + // do-while with a block is a block-like statement. + if (node.type === "DoWhileStatement" && node.body.type === "BlockStatement") { + return true; + } + + /* + * IIFE is a block-like statement specially from + * JSCS#disallowPaddingNewLinesAfterBlocks. + */ + if (isIIFEStatement(node)) { + return true; + } + + // Checks the last token is a closing brace of blocks. + const lastToken = sourceCode.getLastToken(node, astUtils.isNotSemicolonToken); + const belongingNode = lastToken && astUtils.isClosingBraceToken(lastToken) + ? sourceCode.getNodeByRangeIndex(lastToken.range[0]) + : null; + + return Boolean(belongingNode) && ( + belongingNode.type === "BlockStatement" || + belongingNode.type === "SwitchStatement" + ); +} + +/** + * Check whether the given node is a directive or not. + * @param {ASTNode} node The node to check. + * @param {SourceCode} sourceCode The source code object to get tokens. + * @returns {boolean} `true` if the node is a directive. + */ +function isDirective(node, sourceCode) { + return ( + node.type === "ExpressionStatement" && + ( + node.parent.type === "Program" || + ( + node.parent.type === "BlockStatement" && + astUtils.isFunction(node.parent.parent) + ) + ) && + node.expression.type === "Literal" && + typeof node.expression.value === "string" && + !astUtils.isParenthesised(sourceCode, node.expression) + ); +} + +/** + * Check whether the given node is a part of directive prologue or not. + * @param {ASTNode} node The node to check. + * @param {SourceCode} sourceCode The source code object to get tokens. + * @returns {boolean} `true` if the node is a part of directive prologue. + */ +function isDirectivePrologue(node, sourceCode) { + if (isDirective(node, sourceCode)) { + for (const sibling of node.parent.body) { + if (sibling === node) { + break; + } + if (!isDirective(sibling, sourceCode)) { + return false; + } + } + return true; + } + return false; +} + +/** + * Gets the actual last token. + * + * If a semicolon is semicolon-less style's semicolon, this ignores it. + * For example: + * + * foo() + * ;[1, 2, 3].forEach(bar) + * @param {SourceCode} sourceCode The source code to get tokens. + * @param {ASTNode} node The node to get. + * @returns {Token} The actual last token. + * @private + */ +function getActualLastToken(sourceCode, node) { + const semiToken = sourceCode.getLastToken(node); + const prevToken = sourceCode.getTokenBefore(semiToken); + const nextToken = sourceCode.getTokenAfter(semiToken); + const isSemicolonLessStyle = Boolean( + prevToken && + nextToken && + prevToken.range[0] >= node.range[0] && + astUtils.isSemicolonToken(semiToken) && + semiToken.loc.start.line !== prevToken.loc.end.line && + semiToken.loc.end.line === nextToken.loc.start.line + ); + + return isSemicolonLessStyle ? prevToken : semiToken; +} + +/** + * This returns the concatenation of the first 2 captured strings. + * @param {string} _ Unused. Whole matched string. + * @param {string} trailingSpaces The trailing spaces of the first line. + * @param {string} indentSpaces The indentation spaces of the last line. + * @returns {string} The concatenation of trailingSpaces and indentSpaces. + * @private + */ +function replacerToRemovePaddingLines(_, trailingSpaces, indentSpaces) { + return trailingSpaces + indentSpaces; +} + +/** + * Check and report statements for `any` configuration. + * It does nothing. + * @returns {void} + * @private + */ +function verifyForAny() { +} + +/** + * Check and report statements for `never` configuration. + * This autofix removes blank lines between the given 2 statements. + * However, if comments exist between 2 blank lines, it does not remove those + * blank lines automatically. + * @param {RuleContext} context The rule context to report. + * @param {ASTNode} _ Unused. The previous node to check. + * @param {ASTNode} nextNode The next node to check. + * @param {Array} paddingLines The array of token pairs that blank + * lines exist between the pair. + * @returns {void} + * @private + */ +function verifyForNever(context, _, nextNode, paddingLines) { + if (paddingLines.length === 0) { + return; + } + + context.report({ + node: nextNode, + messageId: "unexpectedBlankLine", + fix(fixer) { + if (paddingLines.length >= 2) { + return null; + } + + const prevToken = paddingLines[0][0]; + const nextToken = paddingLines[0][1]; + const start = prevToken.range[1]; + const end = nextToken.range[0]; + const text = context.getSourceCode().text + .slice(start, end) + .replace(PADDING_LINE_SEQUENCE, replacerToRemovePaddingLines); + + return fixer.replaceTextRange([start, end], text); + } + }); +} + +/** + * Check and report statements for `always` configuration. + * This autofix inserts a blank line between the given 2 statements. + * If the `prevNode` has trailing comments, it inserts a blank line after the + * trailing comments. + * @param {RuleContext} context The rule context to report. + * @param {ASTNode} prevNode The previous node to check. + * @param {ASTNode} nextNode The next node to check. + * @param {Array} paddingLines The array of token pairs that blank + * lines exist between the pair. + * @returns {void} + * @private + */ +function verifyForAlways(context, prevNode, nextNode, paddingLines) { + if (paddingLines.length > 0) { + return; + } + + context.report({ + node: nextNode, + messageId: "expectedBlankLine", + fix(fixer) { + const sourceCode = context.getSourceCode(); + let prevToken = getActualLastToken(sourceCode, prevNode); + const nextToken = sourceCode.getFirstTokenBetween( + prevToken, + nextNode, + { + includeComments: true, + + /** + * Skip the trailing comments of the previous node. + * This inserts a blank line after the last trailing comment. + * + * For example: + * + * foo(); // trailing comment. + * // comment. + * bar(); + * + * Get fixed to: + * + * foo(); // trailing comment. + * + * // comment. + * bar(); + * @param {Token} token The token to check. + * @returns {boolean} `true` if the token is not a trailing comment. + * @private + */ + filter(token) { + if (astUtils.isTokenOnSameLine(prevToken, token)) { + prevToken = token; + return false; + } + return true; + } + } + ) || nextNode; + const insertText = astUtils.isTokenOnSameLine(prevToken, nextToken) + ? "\n\n" + : "\n"; + + return fixer.insertTextAfter(prevToken, insertText); + } + }); +} + +/** + * Types of blank lines. + * `any`, `never`, and `always` are defined. + * Those have `verify` method to check and report statements. + * @private + */ +const PaddingTypes = { + any: { verify: verifyForAny }, + never: { verify: verifyForNever }, + always: { verify: verifyForAlways } +}; + +/** + * Types of statements. + * Those have `test` method to check it matches to the given statement. + * @private + */ +const StatementTypes = { + "*": { test: () => true }, + "block-like": { + test: (node, sourceCode) => isBlockLikeStatement(sourceCode, node) + }, + "cjs-export": { + test: (node, sourceCode) => + node.type === "ExpressionStatement" && + node.expression.type === "AssignmentExpression" && + CJS_EXPORT.test(sourceCode.getText(node.expression.left)) + }, + "cjs-import": { + test: (node, sourceCode) => + node.type === "VariableDeclaration" && + node.declarations.length > 0 && + Boolean(node.declarations[0].init) && + CJS_IMPORT.test(sourceCode.getText(node.declarations[0].init)) + }, + directive: { + test: isDirectivePrologue + }, + expression: { + test: (node, sourceCode) => + node.type === "ExpressionStatement" && + !isDirectivePrologue(node, sourceCode) + }, + iife: { + test: isIIFEStatement + }, + "multiline-block-like": { + test: (node, sourceCode) => + node.loc.start.line !== node.loc.end.line && + isBlockLikeStatement(sourceCode, node) + }, + "multiline-expression": { + test: (node, sourceCode) => + node.loc.start.line !== node.loc.end.line && + node.type === "ExpressionStatement" && + !isDirectivePrologue(node, sourceCode) + }, + + "multiline-const": newMultilineKeywordTester("const"), + "multiline-let": newMultilineKeywordTester("let"), + "multiline-var": newMultilineKeywordTester("var"), + "singleline-const": newSinglelineKeywordTester("const"), + "singleline-let": newSinglelineKeywordTester("let"), + "singleline-var": newSinglelineKeywordTester("var"), + + block: newNodeTypeTester("BlockStatement"), + empty: newNodeTypeTester("EmptyStatement"), + function: newNodeTypeTester("FunctionDeclaration"), + + break: newKeywordTester("break"), + case: newKeywordTester("case"), + class: newKeywordTester("class"), + const: newKeywordTester("const"), + continue: newKeywordTester("continue"), + debugger: newKeywordTester("debugger"), + default: newKeywordTester("default"), + do: newKeywordTester("do"), + export: newKeywordTester("export"), + for: newKeywordTester("for"), + if: newKeywordTester("if"), + import: newKeywordTester("import"), + let: newKeywordTester("let"), + return: newKeywordTester("return"), + switch: newKeywordTester("switch"), + throw: newKeywordTester("throw"), + try: newKeywordTester("try"), + var: newKeywordTester("var"), + while: newKeywordTester("while"), + with: newKeywordTester("with") +}; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var paddingLineBetweenStatements = { + meta: { + type: "layout", + + docs: { + description: "require or disallow padding lines between statements", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/padding-line-between-statements" + }, + + fixable: "whitespace", + + schema: { + definitions: { + paddingType: { + enum: Object.keys(PaddingTypes) + }, + statementType: { + anyOf: [ + { enum: Object.keys(StatementTypes) }, + { + type: "array", + items: { enum: Object.keys(StatementTypes) }, + minItems: 1, + uniqueItems: true, + additionalItems: false + } + ] + } + }, + type: "array", + items: { + type: "object", + properties: { + blankLine: { $ref: "#/definitions/paddingType" }, + prev: { $ref: "#/definitions/statementType" }, + next: { $ref: "#/definitions/statementType" } + }, + additionalProperties: false, + required: ["blankLine", "prev", "next"] + }, + additionalItems: false + }, + + messages: { + unexpectedBlankLine: "Unexpected blank line before this statement.", + expectedBlankLine: "Expected blank line before this statement." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const configureList = context.options || []; + let scopeInfo = null; + + /** + * Processes to enter to new scope. + * This manages the current previous statement. + * @returns {void} + * @private + */ + function enterScope() { + scopeInfo = { + upper: scopeInfo, + prevNode: null + }; + } + + /** + * Processes to exit from the current scope. + * @returns {void} + * @private + */ + function exitScope() { + scopeInfo = scopeInfo.upper; + } + + /** + * Checks whether the given node matches the given type. + * @param {ASTNode} node The statement node to check. + * @param {string|string[]} type The statement type to check. + * @returns {boolean} `true` if the statement node matched the type. + * @private + */ + function match(node, type) { + let innerStatementNode = node; + + while (innerStatementNode.type === "LabeledStatement") { + innerStatementNode = innerStatementNode.body; + } + if (Array.isArray(type)) { + return type.some(match.bind(null, innerStatementNode)); + } + return StatementTypes[type].test(innerStatementNode, sourceCode); + } + + /** + * Finds the last matched configure from configureList. + * @param {ASTNode} prevNode The previous statement to match. + * @param {ASTNode} nextNode The current statement to match. + * @returns {Object} The tester of the last matched configure. + * @private + */ + function getPaddingType(prevNode, nextNode) { + for (let i = configureList.length - 1; i >= 0; --i) { + const configure = configureList[i]; + const matched = + match(prevNode, configure.prev) && + match(nextNode, configure.next); + + if (matched) { + return PaddingTypes[configure.blankLine]; + } + } + return PaddingTypes.any; + } + + /** + * Gets padding line sequences between the given 2 statements. + * Comments are separators of the padding line sequences. + * @param {ASTNode} prevNode The previous statement to count. + * @param {ASTNode} nextNode The current statement to count. + * @returns {Array} The array of token pairs. + * @private + */ + function getPaddingLineSequences(prevNode, nextNode) { + const pairs = []; + let prevToken = getActualLastToken(sourceCode, prevNode); + + if (nextNode.loc.start.line - prevToken.loc.end.line >= 2) { + do { + const token = sourceCode.getTokenAfter( + prevToken, + { includeComments: true } + ); + + if (token.loc.start.line - prevToken.loc.end.line >= 2) { + pairs.push([prevToken, token]); + } + prevToken = token; + + } while (prevToken.range[0] < nextNode.range[0]); + } + + return pairs; + } + + /** + * Verify padding lines between the given node and the previous node. + * @param {ASTNode} node The node to verify. + * @returns {void} + * @private + */ + function verify(node) { + const parentType = node.parent.type; + const validParent = + astUtils.STATEMENT_LIST_PARENTS.has(parentType) || + parentType === "SwitchStatement"; + + if (!validParent) { + return; + } + + // Save this node as the current previous statement. + const prevNode = scopeInfo.prevNode; + + // Verify. + if (prevNode) { + const type = getPaddingType(prevNode, node); + const paddingLines = getPaddingLineSequences(prevNode, node); + + type.verify(context, prevNode, node, paddingLines); + } + + scopeInfo.prevNode = node; + } + + /** + * Verify padding lines between the given node and the previous node. + * Then process to enter to new scope. + * @param {ASTNode} node The node to verify. + * @returns {void} + * @private + */ + function verifyThenEnterScope(node) { + verify(node); + enterScope(); + } + + return { + Program: enterScope, + BlockStatement: enterScope, + SwitchStatement: enterScope, + "Program:exit": exitScope, + "BlockStatement:exit": exitScope, + "SwitchStatement:exit": exitScope, + + ":statement": verify, + + SwitchCase: verifyThenEnterScope, + "SwitchCase:exit": exitScope + }; + } +}; + +/** + * @fileoverview A rule to suggest using arrow functions as callbacks. + * @author Toru Nagashima + */ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a given variable is a function name. + * @param {eslint-scope.Variable} variable A variable to check. + * @returns {boolean} `true` if the variable is a function name. + */ +function isFunctionName(variable) { + return variable && variable.defs[0].type === "FunctionName"; +} + +/** + * Checks whether or not a given MetaProperty node equals to a given value. + * @param {ASTNode} node A MetaProperty node to check. + * @param {string} metaName The name of `MetaProperty.meta`. + * @param {string} propertyName The name of `MetaProperty.property`. + * @returns {boolean} `true` if the node is the specific value. + */ +function checkMetaProperty(node, metaName, propertyName) { + return node.meta.name === metaName && node.property.name === propertyName; +} + +/** + * Gets the variable object of `arguments` which is defined implicitly. + * @param {eslint-scope.Scope} scope A scope to get. + * @returns {eslint-scope.Variable} The found variable object. + */ +function getVariableOfArguments$1(scope) { + const variables = scope.variables; + + for (let i = 0; i < variables.length; ++i) { + const variable = variables[i]; + + if (variable.name === "arguments") { + + /* + * If there was a parameter which is named "arguments", the + * implicit "arguments" is not defined. + * So does fast return with null. + */ + return (variable.identifiers.length === 0) ? variable : null; + } + } + + /* istanbul ignore next */ + return null; +} + +/** + * Checks whether or not a given node is a callback. + * @param {ASTNode} node A node to check. + * @returns {Object} + * {boolean} retv.isCallback - `true` if the node is a callback. + * {boolean} retv.isLexicalThis - `true` if the node is with `.bind(this)`. + */ +function getCallbackInfo(node) { + const retv = { isCallback: false, isLexicalThis: false }; + let currentNode = node; + let parent = node.parent; + let bound = false; + + while (currentNode) { + switch (parent.type) { + + // Checks parents recursively. + + case "LogicalExpression": + case "ChainExpression": + case "ConditionalExpression": + break; + + // Checks whether the parent node is `.bind(this)` call. + case "MemberExpression": + if ( + parent.object === currentNode && + !parent.property.computed && + parent.property.type === "Identifier" && + parent.property.name === "bind" + ) { + const maybeCallee = parent.parent.type === "ChainExpression" + ? parent.parent + : parent; + + if (astUtils.isCallee(maybeCallee)) { + if (!bound) { + bound = true; // Use only the first `.bind()` to make `isLexicalThis` value. + retv.isLexicalThis = ( + maybeCallee.parent.arguments.length === 1 && + maybeCallee.parent.arguments[0].type === "ThisExpression" + ); + } + parent = maybeCallee.parent; + } else { + return retv; + } + } else { + return retv; + } + break; + + // Checks whether the node is a callback. + case "CallExpression": + case "NewExpression": + if (parent.callee !== currentNode) { + retv.isCallback = true; + } + return retv; + + default: + return retv; + } + + currentNode = parent; + parent = parent.parent; + } + + /* istanbul ignore next */ + throw new Error("unreachable"); +} + +/** + * Checks whether a simple list of parameters contains any duplicates. This does not handle complex + * parameter lists (e.g. with destructuring), since complex parameter lists are a SyntaxError with duplicate + * parameter names anyway. Instead, it always returns `false` for complex parameter lists. + * @param {ASTNode[]} paramsList The list of parameters for a function + * @returns {boolean} `true` if the list of parameters contains any duplicates + */ +function hasDuplicateParams(paramsList) { + return paramsList.every(param => param.type === "Identifier") && paramsList.length !== new Set(paramsList.map(param => param.name)).size; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var preferArrowCallback = { + meta: { + type: "suggestion", + + docs: { + description: "require using arrow functions for callbacks", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/prefer-arrow-callback" + }, + + schema: [ + { + type: "object", + properties: { + allowNamedFunctions: { + type: "boolean", + default: false + }, + allowUnboundThis: { + type: "boolean", + default: true + } + }, + additionalProperties: false + } + ], + + fixable: "code", + + messages: { + preferArrowCallback: "Unexpected function expression." + } + }, + + create(context) { + const options = context.options[0] || {}; + + const allowUnboundThis = options.allowUnboundThis !== false; // default to true + const allowNamedFunctions = options.allowNamedFunctions; + const sourceCode = context.getSourceCode(); + + /* + * {Array<{this: boolean, super: boolean, meta: boolean}>} + * - this - A flag which shows there are one or more ThisExpression. + * - super - A flag which shows there are one or more Super. + * - meta - A flag which shows there are one or more MethProperty. + */ + let stack = []; + + /** + * Pushes new function scope with all `false` flags. + * @returns {void} + */ + function enterScope() { + stack.push({ this: false, super: false, meta: false }); + } + + /** + * Pops a function scope from the stack. + * @returns {{this: boolean, super: boolean, meta: boolean}} The information of the last scope. + */ + function exitScope() { + return stack.pop(); + } + + return { + + // Reset internal state. + Program() { + stack = []; + }, + + // If there are below, it cannot replace with arrow functions merely. + ThisExpression() { + const info = stack[stack.length - 1]; + + if (info) { + info.this = true; + } + }, + + Super() { + const info = stack[stack.length - 1]; + + if (info) { + info.super = true; + } + }, + + MetaProperty(node) { + const info = stack[stack.length - 1]; + + if (info && checkMetaProperty(node, "new", "target")) { + info.meta = true; + } + }, + + // To skip nested scopes. + FunctionDeclaration: enterScope, + "FunctionDeclaration:exit": exitScope, + + // Main. + FunctionExpression: enterScope, + "FunctionExpression:exit"(node) { + const scopeInfo = exitScope(); + + // Skip named function expressions + if (allowNamedFunctions && node.id && node.id.name) { + return; + } + + // Skip generators. + if (node.generator) { + return; + } + + // Skip recursive functions. + const nameVar = context.getDeclaredVariables(node)[0]; + + if (isFunctionName(nameVar) && nameVar.references.length > 0) { + return; + } + + // Skip if it's using arguments. + const variable = getVariableOfArguments$1(context.getScope()); + + if (variable && variable.references.length > 0) { + return; + } + + // Reports if it's a callback which can replace with arrows. + const callbackInfo = getCallbackInfo(node); + + if (callbackInfo.isCallback && + (!allowUnboundThis || !scopeInfo.this || callbackInfo.isLexicalThis) && + !scopeInfo.super && + !scopeInfo.meta + ) { + context.report({ + node, + messageId: "preferArrowCallback", + *fix(fixer) { + if ((!callbackInfo.isLexicalThis && scopeInfo.this) || hasDuplicateParams(node.params)) { + + /* + * If the callback function does not have .bind(this) and contains a reference to `this`, there + * is no way to determine what `this` should be, so don't perform any fixes. + * If the callback function has duplicates in its list of parameters (possible in sloppy mode), + * don't replace it with an arrow function, because this is a SyntaxError with arrow functions. + */ + return; // eslint-disable-line eslint-plugin/fixer-return -- false positive + } + + // Remove `.bind(this)` if exists. + if (callbackInfo.isLexicalThis) { + const memberNode = node.parent; + + /* + * If `.bind(this)` exists but the parent is not `.bind(this)`, don't remove it automatically. + * E.g. `(foo || function(){}).bind(this)` + */ + if (memberNode.type !== "MemberExpression") { + return; // eslint-disable-line eslint-plugin/fixer-return -- false positive + } + + const callNode = memberNode.parent; + const firstTokenToRemove = sourceCode.getTokenAfter(memberNode.object, astUtils.isNotClosingParenToken); + const lastTokenToRemove = sourceCode.getLastToken(callNode); + + /* + * If the member expression is parenthesized, don't remove the right paren. + * E.g. `(function(){}.bind)(this)` + * ^^^^^^^^^^^^ + */ + if (astUtils.isParenthesised(sourceCode, memberNode)) { + return; // eslint-disable-line eslint-plugin/fixer-return -- false positive + } + + // If comments exist in the `.bind(this)`, don't remove those. + if (sourceCode.commentsExistBetween(firstTokenToRemove, lastTokenToRemove)) { + return; // eslint-disable-line eslint-plugin/fixer-return -- false positive + } + + yield fixer.removeRange([firstTokenToRemove.range[0], lastTokenToRemove.range[1]]); + } + + // Convert the function expression to an arrow function. + const functionToken = sourceCode.getFirstToken(node, node.async ? 1 : 0); + const leftParenToken = sourceCode.getTokenAfter(functionToken, astUtils.isOpeningParenToken); + + if (sourceCode.commentsExistBetween(functionToken, leftParenToken)) { + + // Remove only extra tokens to keep comments. + yield fixer.remove(functionToken); + if (node.id) { + yield fixer.remove(node.id); + } + } else { + + // Remove extra tokens and spaces. + yield fixer.removeRange([functionToken.range[0], leftParenToken.range[0]]); + } + yield fixer.insertTextBefore(node.body, "=> "); + + // Get the node that will become the new arrow function. + let replacedNode = callbackInfo.isLexicalThis ? node.parent.parent : node; + + if (replacedNode.type === "ChainExpression") { + replacedNode = replacedNode.parent; + } + + /* + * If the replaced node is part of a BinaryExpression, LogicalExpression, or MemberExpression, then + * the arrow function needs to be parenthesized, because `foo || () => {}` is invalid syntax even + * though `foo || function() {}` is valid. + */ + if ( + replacedNode.parent.type !== "CallExpression" && + replacedNode.parent.type !== "ConditionalExpression" && + !astUtils.isParenthesised(sourceCode, replacedNode) && + !astUtils.isParenthesised(sourceCode, node) + ) { + yield fixer.insertTextBefore(replacedNode, "("); + yield fixer.insertTextAfter(replacedNode, ")"); + } + } + }); + } + } + }; + } +}; + +/** + * @fileoverview A rule to suggest using of const declaration for variables that are never reassigned after declared. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const PATTERN_TYPE = /^(?:.+?Pattern|RestElement|SpreadProperty|ExperimentalRestProperty|Property)$/u; +const DECLARATION_HOST_TYPE = /^(?:Program|BlockStatement|SwitchCase)$/u; +const DESTRUCTURING_HOST_TYPE = /^(?:VariableDeclarator|AssignmentExpression)$/u; + +/** + * Checks whether a given node is located at `ForStatement.init` or not. + * @param {ASTNode} node A node to check. + * @returns {boolean} `true` if the node is located at `ForStatement.init`. + */ +function isInitOfForStatement(node) { + return node.parent.type === "ForStatement" && node.parent.init === node; +} + +/** + * Checks whether a given Identifier node becomes a VariableDeclaration or not. + * @param {ASTNode} identifier An Identifier node to check. + * @returns {boolean} `true` if the node can become a VariableDeclaration. + */ +function canBecomeVariableDeclaration(identifier) { + let node = identifier.parent; + + while (PATTERN_TYPE.test(node.type)) { + node = node.parent; + } + + return ( + node.type === "VariableDeclarator" || + ( + node.type === "AssignmentExpression" && + node.parent.type === "ExpressionStatement" && + DECLARATION_HOST_TYPE.test(node.parent.parent.type) + ) + ); +} + +/** + * Checks if an property or element is from outer scope or function parameters + * in destructing pattern. + * @param {string} name A variable name to be checked. + * @param {eslint-scope.Scope} initScope A scope to start find. + * @returns {boolean} Indicates if the variable is from outer scope or function parameters. + */ +function isOuterVariableInDestructing(name, initScope) { + + if (initScope.through.find(ref => ref.resolved && ref.resolved.name === name)) { + return true; + } + + const variable = astUtils.getVariableByName(initScope, name); + + if (variable !== null) { + return variable.defs.some(def => def.type === "Parameter"); + } + + return false; +} + +/** + * Gets the VariableDeclarator/AssignmentExpression node that a given reference + * belongs to. + * This is used to detect a mix of reassigned and never reassigned in a + * destructuring. + * @param {eslint-scope.Reference} reference A reference to get. + * @returns {ASTNode|null} A VariableDeclarator/AssignmentExpression node or + * null. + */ +function getDestructuringHost(reference) { + if (!reference.isWrite()) { + return null; + } + let node = reference.identifier.parent; + + while (PATTERN_TYPE.test(node.type)) { + node = node.parent; + } + + if (!DESTRUCTURING_HOST_TYPE.test(node.type)) { + return null; + } + return node; +} + +/** + * Determines if a destructuring assignment node contains + * any MemberExpression nodes. This is used to determine if a + * variable that is only written once using destructuring can be + * safely converted into a const declaration. + * @param {ASTNode} node The ObjectPattern or ArrayPattern node to check. + * @returns {boolean} True if the destructuring pattern contains + * a MemberExpression, false if not. + */ +function hasMemberExpressionAssignment(node) { + switch (node.type) { + case "ObjectPattern": + return node.properties.some(prop => { + if (prop) { + + /* + * Spread elements have an argument property while + * others have a value property. Because different + * parsers use different node types for spread elements, + * we just check if there is an argument property. + */ + return hasMemberExpressionAssignment(prop.argument || prop.value); + } + + return false; + }); + + case "ArrayPattern": + return node.elements.some(element => { + if (element) { + return hasMemberExpressionAssignment(element); + } + + return false; + }); + + case "AssignmentPattern": + return hasMemberExpressionAssignment(node.left); + + case "MemberExpression": + return true; + + // no default + } + + return false; +} + +/** + * Gets an identifier node of a given variable. + * + * If the initialization exists or one or more reading references exist before + * the first assignment, the identifier node is the node of the declaration. + * Otherwise, the identifier node is the node of the first assignment. + * + * If the variable should not change to const, this function returns null. + * - If the variable is reassigned. + * - If the variable is never initialized nor assigned. + * - If the variable is initialized in a different scope from the declaration. + * - If the unique assignment of the variable cannot change to a declaration. + * e.g. `if (a) b = 1` / `return (b = 1)` + * - If the variable is declared in the global scope and `eslintUsed` is `true`. + * `/*exported foo` directive comment makes such variables. This rule does not + * warn such variables because this rule cannot distinguish whether the + * exported variables are reassigned or not. + * @param {eslint-scope.Variable} variable A variable to get. + * @param {boolean} ignoreReadBeforeAssign + * The value of `ignoreReadBeforeAssign` option. + * @returns {ASTNode|null} + * An Identifier node if the variable should change to const. + * Otherwise, null. + */ +function getIdentifierIfShouldBeConst(variable, ignoreReadBeforeAssign) { + if (variable.eslintUsed && variable.scope.type === "global") { + return null; + } + + // Finds the unique WriteReference. + let writer = null; + let isReadBeforeInit = false; + const references = variable.references; + + for (let i = 0; i < references.length; ++i) { + const reference = references[i]; + + if (reference.isWrite()) { + const isReassigned = ( + writer !== null && + writer.identifier !== reference.identifier + ); + + if (isReassigned) { + return null; + } + + const destructuringHost = getDestructuringHost(reference); + + if (destructuringHost !== null && destructuringHost.left !== void 0) { + const leftNode = destructuringHost.left; + let hasOuterVariables = false, + hasNonIdentifiers = false; + + if (leftNode.type === "ObjectPattern") { + const properties = leftNode.properties; + + hasOuterVariables = properties + .filter(prop => prop.value) + .map(prop => prop.value.name) + .some(name => isOuterVariableInDestructing(name, variable.scope)); + + hasNonIdentifiers = hasMemberExpressionAssignment(leftNode); + + } else if (leftNode.type === "ArrayPattern") { + const elements = leftNode.elements; + + hasOuterVariables = elements + .map(element => element && element.name) + .some(name => isOuterVariableInDestructing(name, variable.scope)); + + hasNonIdentifiers = hasMemberExpressionAssignment(leftNode); + } + + if (hasOuterVariables || hasNonIdentifiers) { + return null; + } + + } + + writer = reference; + + } else if (reference.isRead() && writer === null) { + if (ignoreReadBeforeAssign) { + return null; + } + isReadBeforeInit = true; + } + } + + /* + * If the assignment is from a different scope, ignore it. + * If the assignment cannot change to a declaration, ignore it. + */ + const shouldBeConst = ( + writer !== null && + writer.from === variable.scope && + canBecomeVariableDeclaration(writer.identifier) + ); + + if (!shouldBeConst) { + return null; + } + + if (isReadBeforeInit) { + return variable.defs[0].name; + } + + return writer.identifier; +} + +/** + * Groups by the VariableDeclarator/AssignmentExpression node that each + * reference of given variables belongs to. + * This is used to detect a mix of reassigned and never reassigned in a + * destructuring. + * @param {eslint-scope.Variable[]} variables Variables to group by destructuring. + * @param {boolean} ignoreReadBeforeAssign + * The value of `ignoreReadBeforeAssign` option. + * @returns {Map} Grouped identifier nodes. + */ +function groupByDestructuring(variables, ignoreReadBeforeAssign) { + const identifierMap = new Map(); + + for (let i = 0; i < variables.length; ++i) { + const variable = variables[i]; + const references = variable.references; + const identifier = getIdentifierIfShouldBeConst(variable, ignoreReadBeforeAssign); + let prevId = null; + + for (let j = 0; j < references.length; ++j) { + const reference = references[j]; + const id = reference.identifier; + + /* + * Avoid counting a reference twice or more for default values of + * destructuring. + */ + if (id === prevId) { + continue; + } + prevId = id; + + // Add the identifier node into the destructuring group. + const group = getDestructuringHost(reference); + + if (group) { + if (identifierMap.has(group)) { + identifierMap.get(group).push(identifier); + } else { + identifierMap.set(group, [identifier]); + } + } + } + } + + return identifierMap; +} + +/** + * Finds the nearest parent of node with a given type. + * @param {ASTNode} node The node to search from. + * @param {string} type The type field of the parent node. + * @param {Function} shouldStop A predicate that returns true if the traversal should stop, and false otherwise. + * @returns {ASTNode} The closest ancestor with the specified type; null if no such ancestor exists. + */ +function findUp(node, type, shouldStop) { + if (!node || shouldStop(node)) { + return null; + } + if (node.type === type) { + return node; + } + return findUp(node.parent, type, shouldStop); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var preferConst = { + meta: { + type: "suggestion", + + docs: { + description: "require `const` declarations for variables that are never reassigned after declared", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/prefer-const" + }, + + fixable: "code", + + schema: [ + { + type: "object", + properties: { + destructuring: { enum: ["any", "all"], default: "any" }, + ignoreReadBeforeAssign: { type: "boolean", default: false } + }, + additionalProperties: false + } + ], + messages: { + useConst: "'{{name}}' is never reassigned. Use 'const' instead." + } + }, + + create(context) { + const options = context.options[0] || {}; + const sourceCode = context.getSourceCode(); + const shouldMatchAnyDestructuredVariable = options.destructuring !== "all"; + const ignoreReadBeforeAssign = options.ignoreReadBeforeAssign === true; + const variables = []; + let reportCount = 0; + let checkedId = null; + let checkedName = ""; + + + /** + * Reports given identifier nodes if all of the nodes should be declared + * as const. + * + * The argument 'nodes' is an array of Identifier nodes. + * This node is the result of 'getIdentifierIfShouldBeConst()', so it's + * nullable. In simple declaration or assignment cases, the length of + * the array is 1. In destructuring cases, the length of the array can + * be 2 or more. + * @param {(eslint-scope.Reference|null)[]} nodes + * References which are grouped by destructuring to report. + * @returns {void} + */ + function checkGroup(nodes) { + const nodesToReport = nodes.filter(Boolean); + + if (nodes.length && (shouldMatchAnyDestructuredVariable || nodesToReport.length === nodes.length)) { + const varDeclParent = findUp(nodes[0], "VariableDeclaration", parentNode => parentNode.type.endsWith("Statement")); + const isVarDecParentNull = varDeclParent === null; + + if (!isVarDecParentNull && varDeclParent.declarations.length > 0) { + const firstDeclaration = varDeclParent.declarations[0]; + + if (firstDeclaration.init) { + const firstDecParent = firstDeclaration.init.parent; + + /* + * First we check the declaration type and then depending on + * if the type is a "VariableDeclarator" or its an "ObjectPattern" + * we compare the name and id from the first identifier, if the names are different + * we assign the new name, id and reset the count of reportCount and nodeCount in + * order to check each block for the number of reported errors and base our fix + * based on comparing nodes.length and nodesToReport.length. + */ + + if (firstDecParent.type === "VariableDeclarator") { + + if (firstDecParent.id.name !== checkedName) { + checkedName = firstDecParent.id.name; + reportCount = 0; + } + + if (firstDecParent.id.type === "ObjectPattern") { + if (firstDecParent.init.name !== checkedName) { + checkedName = firstDecParent.init.name; + reportCount = 0; + } + } + + if (firstDecParent.id !== checkedId) { + checkedId = firstDecParent.id; + reportCount = 0; + } + } + } + } + + let shouldFix = varDeclParent && + + // Don't do a fix unless all variables in the declarations are initialized (or it's in a for-in or for-of loop) + (varDeclParent.parent.type === "ForInStatement" || varDeclParent.parent.type === "ForOfStatement" || + varDeclParent.declarations.every(declaration => declaration.init)) && + + /* + * If options.destructuring is "all", then this warning will not occur unless + * every assignment in the destructuring should be const. In that case, it's safe + * to apply the fix. + */ + nodesToReport.length === nodes.length; + + if (!isVarDecParentNull && varDeclParent.declarations && varDeclParent.declarations.length !== 1) { + + if (varDeclParent && varDeclParent.declarations && varDeclParent.declarations.length >= 1) { + + /* + * Add nodesToReport.length to a count, then comparing the count to the length + * of the declarations in the current block. + */ + + reportCount += nodesToReport.length; + + shouldFix = shouldFix && (reportCount === varDeclParent.declarations.length); + } + } + + nodesToReport.forEach(node => { + context.report({ + node, + messageId: "useConst", + data: node, + fix: shouldFix + ? fixer => { + const letKeywordToken = sourceCode.getFirstToken(varDeclParent, t => t.value === varDeclParent.kind); + + /** + * Extend the replacement range to the whole declaration, + * in order to prevent other fixes in the same pass + * https://github.com/eslint/eslint/issues/13899 + */ + return new fixTracker(fixer, sourceCode) + .retainRange(varDeclParent.range) + .replaceTextRange(letKeywordToken.range, "const"); + } + : null + }); + }); + } + } + + return { + "Program:exit"() { + groupByDestructuring(variables, ignoreReadBeforeAssign).forEach(checkGroup); + }, + + VariableDeclaration(node) { + if (node.kind === "let" && !isInitOfForStatement(node)) { + variables.push(...context.getDeclaredVariables(node)); + } + } + }; + } +}; + +/** + * @fileoverview Prefer destructuring from arrays and objects + * @author Alex LaFroscia + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const PRECEDENCE_OF_ASSIGNMENT_EXPR = astUtils.getPrecedence({ type: "AssignmentExpression" }); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var preferDestructuring = { + meta: { + type: "suggestion", + + docs: { + description: "require destructuring from arrays and/or objects", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/prefer-destructuring" + }, + + fixable: "code", + + schema: [ + { + + /* + * old support {array: Boolean, object: Boolean} + * new support {VariableDeclarator: {}, AssignmentExpression: {}} + */ + oneOf: [ + { + type: "object", + properties: { + VariableDeclarator: { + type: "object", + properties: { + array: { + type: "boolean" + }, + object: { + type: "boolean" + } + }, + additionalProperties: false + }, + AssignmentExpression: { + type: "object", + properties: { + array: { + type: "boolean" + }, + object: { + type: "boolean" + } + }, + additionalProperties: false + } + }, + additionalProperties: false + }, + { + type: "object", + properties: { + array: { + type: "boolean" + }, + object: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + }, + { + type: "object", + properties: { + enforceForRenamedProperties: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + + messages: { + preferDestructuring: "Use {{type}} destructuring." + } + }, + create(context) { + + const enabledTypes = context.options[0]; + const enforceForRenamedProperties = context.options[1] && context.options[1].enforceForRenamedProperties; + let normalizedOptions = { + VariableDeclarator: { array: true, object: true }, + AssignmentExpression: { array: true, object: true } + }; + + if (enabledTypes) { + normalizedOptions = typeof enabledTypes.array !== "undefined" || typeof enabledTypes.object !== "undefined" + ? { VariableDeclarator: enabledTypes, AssignmentExpression: enabledTypes } + : enabledTypes; + } + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + // eslint-disable-next-line jsdoc/require-description + /** + * @param {string} nodeType "AssignmentExpression" or "VariableDeclarator" + * @param {string} destructuringType "array" or "object" + * @returns {boolean} `true` if the destructuring type should be checked for the given node + */ + function shouldCheck(nodeType, destructuringType) { + return normalizedOptions && + normalizedOptions[nodeType] && + normalizedOptions[nodeType][destructuringType]; + } + + /** + * Determines if the given node is accessing an array index + * + * This is used to differentiate array index access from object property + * access. + * @param {ASTNode} node the node to evaluate + * @returns {boolean} whether or not the node is an integer + */ + function isArrayIndexAccess(node) { + return Number.isInteger(node.property.value); + } + + /** + * Report that the given node should use destructuring + * @param {ASTNode} reportNode the node to report + * @param {string} type the type of destructuring that should have been done + * @param {Function|null} fix the fix function or null to pass to context.report + * @returns {void} + */ + function report(reportNode, type, fix) { + context.report({ + node: reportNode, + messageId: "preferDestructuring", + data: { type }, + fix + }); + } + + /** + * Determines if a node should be fixed into object destructuring + * + * The fixer only fixes the simplest case of object destructuring, + * like: `let x = a.x`; + * + * Assignment expression is not fixed. + * Array destructuring is not fixed. + * Renamed property is not fixed. + * @param {ASTNode} node the node to evaluate + * @returns {boolean} whether or not the node should be fixed + */ + function shouldFix(node) { + return node.type === "VariableDeclarator" && + node.id.type === "Identifier" && + node.init.type === "MemberExpression" && + !node.init.computed && + node.init.property.type === "Identifier" && + node.id.name === node.init.property.name; + } + + /** + * Fix a node into object destructuring. + * This function only handles the simplest case of object destructuring, + * see {@link shouldFix}. + * @param {SourceCodeFixer} fixer the fixer object + * @param {ASTNode} node the node to be fixed. + * @returns {Object} a fix for the node + */ + function fixIntoObjectDestructuring(fixer, node) { + const rightNode = node.init; + const sourceCode = context.getSourceCode(); + + // Don't fix if that would remove any comments. Only comments inside `rightNode.object` can be preserved. + if (sourceCode.getCommentsInside(node).length > sourceCode.getCommentsInside(rightNode.object).length) { + return null; + } + + let objectText = sourceCode.getText(rightNode.object); + + if (astUtils.getPrecedence(rightNode.object) < PRECEDENCE_OF_ASSIGNMENT_EXPR) { + objectText = `(${objectText})`; + } + + return fixer.replaceText( + node, + `{${rightNode.property.name}} = ${objectText}` + ); + } + + /** + * Check that the `prefer-destructuring` rules are followed based on the + * given left- and right-hand side of the assignment. + * + * Pulled out into a separate method so that VariableDeclarators and + * AssignmentExpressions can share the same verification logic. + * @param {ASTNode} leftNode the left-hand side of the assignment + * @param {ASTNode} rightNode the right-hand side of the assignment + * @param {ASTNode} reportNode the node to report the error on + * @returns {void} + */ + function performCheck(leftNode, rightNode, reportNode) { + if (rightNode.type !== "MemberExpression" || rightNode.object.type === "Super") { + return; + } + + if (isArrayIndexAccess(rightNode)) { + if (shouldCheck(reportNode.type, "array")) { + report(reportNode, "array", null); + } + return; + } + + const fix = shouldFix(reportNode) + ? fixer => fixIntoObjectDestructuring(fixer, reportNode) + : null; + + if (shouldCheck(reportNode.type, "object") && enforceForRenamedProperties) { + report(reportNode, "object", fix); + return; + } + + if (shouldCheck(reportNode.type, "object")) { + const property = rightNode.property; + + if ( + (property.type === "Literal" && leftNode.name === property.value) || + (property.type === "Identifier" && leftNode.name === property.name && !rightNode.computed) + ) { + report(reportNode, "object", fix); + } + } + } + + /** + * Check if a given variable declarator is coming from an property access + * that should be using destructuring instead + * @param {ASTNode} node the variable declarator to check + * @returns {void} + */ + function checkVariableDeclarator(node) { + + // Skip if variable is declared without assignment + if (!node.init) { + return; + } + + // We only care about member expressions past this point + if (node.init.type !== "MemberExpression") { + return; + } + + performCheck(node.id, node.init, node); + } + + /** + * Run the `prefer-destructuring` check on an AssignmentExpression + * @param {ASTNode} node the AssignmentExpression node + * @returns {void} + */ + function checkAssignmentExpression(node) { + if (node.operator === "=") { + performCheck(node.left, node.right, node); + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + VariableDeclarator: checkVariableDeclarator, + AssignmentExpression: checkAssignmentExpression + }; + } +}; + +/** + * @fileoverview Rule to disallow Math.pow in favor of the ** operator + * @author Milos Djermanovic + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + +const { CALL: CALL$4, ReferenceTracker: ReferenceTracker$4 } = require$$0__default$1['default']; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const PRECEDENCE_OF_EXPONENTIATION_EXPR = astUtils.getPrecedence({ type: "BinaryExpression", operator: "**" }); + +/** + * Determines whether the given node needs parens if used as the base in an exponentiation binary expression. + * @param {ASTNode} base The node to check. + * @returns {boolean} `true` if the node needs to be parenthesised. + */ +function doesBaseNeedParens(base) { + return ( + + // '**' is right-associative, parens are needed when Math.pow(a ** b, c) is converted to (a ** b) ** c + astUtils.getPrecedence(base) <= PRECEDENCE_OF_EXPONENTIATION_EXPR || + + // An unary operator cannot be used immediately before an exponentiation expression + base.type === "AwaitExpression" || + base.type === "UnaryExpression" + ); +} + +/** + * Determines whether the given node needs parens if used as the exponent in an exponentiation binary expression. + * @param {ASTNode} exponent The node to check. + * @returns {boolean} `true` if the node needs to be parenthesised. + */ +function doesExponentNeedParens(exponent) { + + // '**' is right-associative, there is no need for parens when Math.pow(a, b ** c) is converted to a ** b ** c + return astUtils.getPrecedence(exponent) < PRECEDENCE_OF_EXPONENTIATION_EXPR; +} + +/** + * Determines whether an exponentiation binary expression at the place of the given node would need parens. + * @param {ASTNode} node A node that would be replaced by an exponentiation binary expression. + * @param {SourceCode} sourceCode A SourceCode object. + * @returns {boolean} `true` if the expression needs to be parenthesised. + */ +function doesExponentiationExpressionNeedParens(node, sourceCode) { + const parent = node.parent.type === "ChainExpression" ? node.parent.parent : node.parent; + + const needsParens = ( + parent.type === "ClassDeclaration" || + ( + parent.type.endsWith("Expression") && + astUtils.getPrecedence(parent) >= PRECEDENCE_OF_EXPONENTIATION_EXPR && + !(parent.type === "BinaryExpression" && parent.operator === "**" && parent.right === node) && + !((parent.type === "CallExpression" || parent.type === "NewExpression") && parent.arguments.includes(node)) && + !(parent.type === "MemberExpression" && parent.computed && parent.property === node) && + !(parent.type === "ArrayExpression") + ) + ); + + return needsParens && !astUtils.isParenthesised(sourceCode, node); +} + +/** + * Optionally parenthesizes given text. + * @param {string} text The text to parenthesize. + * @param {boolean} shouldParenthesize If `true`, the text will be parenthesised. + * @returns {string} parenthesised or unchanged text. + */ +function parenthesizeIfShould(text, shouldParenthesize) { + return shouldParenthesize ? `(${text})` : text; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var preferExponentiationOperator = { + meta: { + type: "suggestion", + + docs: { + description: "disallow the use of `Math.pow` in favor of the `**` operator", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/prefer-exponentiation-operator" + }, + + schema: [], + fixable: "code", + + messages: { + useExponentiation: "Use the '**' operator instead of 'Math.pow'." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + /** + * Reports the given node. + * @param {ASTNode} node 'Math.pow()' node to report. + * @returns {void} + */ + function report(node) { + context.report({ + node, + messageId: "useExponentiation", + fix(fixer) { + if ( + node.arguments.length !== 2 || + node.arguments.some(arg => arg.type === "SpreadElement") || + sourceCode.getCommentsInside(node).length > 0 + ) { + return null; + } + + const base = node.arguments[0], + exponent = node.arguments[1], + baseText = sourceCode.getText(base), + exponentText = sourceCode.getText(exponent), + shouldParenthesizeBase = doesBaseNeedParens(base), + shouldParenthesizeExponent = doesExponentNeedParens(exponent), + shouldParenthesizeAll = doesExponentiationExpressionNeedParens(node, sourceCode); + + let prefix = "", + suffix = ""; + + if (!shouldParenthesizeAll) { + if (!shouldParenthesizeBase) { + const firstReplacementToken = sourceCode.getFirstToken(base), + tokenBefore = sourceCode.getTokenBefore(node); + + if ( + tokenBefore && + tokenBefore.range[1] === node.range[0] && + !astUtils.canTokensBeAdjacent(tokenBefore, firstReplacementToken) + ) { + prefix = " "; // a+Math.pow(++b, c) -> a+ ++b**c + } + } + if (!shouldParenthesizeExponent) { + const lastReplacementToken = sourceCode.getLastToken(exponent), + tokenAfter = sourceCode.getTokenAfter(node); + + if ( + tokenAfter && + node.range[1] === tokenAfter.range[0] && + !astUtils.canTokensBeAdjacent(lastReplacementToken, tokenAfter) + ) { + suffix = " "; // Math.pow(a, b)in c -> a**b in c + } + } + } + + const baseReplacement = parenthesizeIfShould(baseText, shouldParenthesizeBase), + exponentReplacement = parenthesizeIfShould(exponentText, shouldParenthesizeExponent), + replacement = parenthesizeIfShould(`${baseReplacement}**${exponentReplacement}`, shouldParenthesizeAll); + + return fixer.replaceText(node, `${prefix}${replacement}${suffix}`); + } + }); + } + + return { + Program() { + const scope = context.getScope(); + const tracker = new ReferenceTracker$4(scope); + const trackMap = { + Math: { + pow: { [CALL$4]: true } + } + }; + + for (const { node } of tracker.iterateGlobalReferences(trackMap)) { + report(node); + } + } + }; + } +}; + +/** + * @fileoverview Rule to enforce requiring named capture groups in regular expression. + * @author Pig Fang + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const { + CALL: CALL$3, + CONSTRUCT: CONSTRUCT$2, + ReferenceTracker: ReferenceTracker$3, + getStringIfConstant: getStringIfConstant$1 +} = require$$0__default$1['default']; + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const parser = new regexpp__default['default'].RegExpParser(); + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var preferNamedCaptureGroup = { + meta: { + type: "suggestion", + + docs: { + description: "enforce using named capture group in regular expression", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/prefer-named-capture-group" + }, + + schema: [], + + messages: { + required: "Capture group '{{group}}' should be converted to a named or non-capturing group." + } + }, + + create(context) { + + /** + * Function to check regular expression. + * @param {string} pattern The regular expression pattern to be check. + * @param {ASTNode} node AST node which contains regular expression. + * @param {boolean} uFlag Flag indicates whether unicode mode is enabled or not. + * @returns {void} + */ + function checkRegex(pattern, node, uFlag) { + let ast; + + try { + ast = parser.parsePattern(pattern, 0, pattern.length, uFlag); + } catch { + + // ignore regex syntax errors + return; + } + + regexpp__default['default'].visitRegExpAST(ast, { + onCapturingGroupEnter(group) { + if (!group.name) { + context.report({ + node, + messageId: "required", + data: { + group: group.raw + } + }); + } + } + }); + } + + return { + Literal(node) { + if (node.regex) { + checkRegex(node.regex.pattern, node, node.regex.flags.includes("u")); + } + }, + Program() { + const scope = context.getScope(); + const tracker = new ReferenceTracker$3(scope); + const traceMap = { + RegExp: { + [CALL$3]: true, + [CONSTRUCT$2]: true + } + }; + + for (const { node } of tracker.iterateGlobalReferences(traceMap)) { + const regex = getStringIfConstant$1(node.arguments[0]); + const flags = getStringIfConstant$1(node.arguments[1]); + + if (regex) { + checkRegex(regex, node, flags && flags.includes("u")); + } + } + } + }; + } +}; + +/** + * @fileoverview Rule to disallow `parseInt()` in favor of binary, octal, and hexadecimal literals + * @author Annie Zhang, Henry Zhu + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const radixMap = new Map([ + [2, { system: "binary", literalPrefix: "0b" }], + [8, { system: "octal", literalPrefix: "0o" }], + [16, { system: "hexadecimal", literalPrefix: "0x" }] +]); + +/** + * Checks to see if a CallExpression's callee node is `parseInt` or + * `Number.parseInt`. + * @param {ASTNode} calleeNode The callee node to evaluate. + * @returns {boolean} True if the callee is `parseInt` or `Number.parseInt`, + * false otherwise. + */ +function isParseInt(calleeNode) { + return ( + astUtils.isSpecificId(calleeNode, "parseInt") || + astUtils.isSpecificMemberAccess(calleeNode, "Number", "parseInt") + ); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var preferNumericLiterals = { + meta: { + type: "suggestion", + + docs: { + description: "disallow `parseInt()` and `Number.parseInt()` in favor of binary, octal, and hexadecimal literals", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/prefer-numeric-literals" + }, + + schema: [], + + messages: { + useLiteral: "Use {{system}} literals instead of {{functionName}}()." + }, + + fixable: "code" + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + //---------------------------------------------------------------------- + // Public + //---------------------------------------------------------------------- + + return { + + "CallExpression[arguments.length=2]"(node) { + const [strNode, radixNode] = node.arguments, + str = astUtils.getStaticStringValue(strNode), + radix = radixNode.value; + + if ( + str !== null && + astUtils.isStringLiteral(strNode) && + radixNode.type === "Literal" && + typeof radix === "number" && + radixMap.has(radix) && + isParseInt(node.callee) + ) { + + const { system, literalPrefix } = radixMap.get(radix); + + context.report({ + node, + messageId: "useLiteral", + data: { + system, + functionName: sourceCode.getText(node.callee) + }, + fix(fixer) { + if (sourceCode.getCommentsInside(node).length) { + return null; + } + + const replacement = `${literalPrefix}${str}`; + + if (+replacement !== parseInt(str, radix)) { + + /* + * If the newly-produced literal would be invalid, (e.g. 0b1234), + * or it would yield an incorrect parseInt result for some other reason, don't make a fix. + * + * If `str` had numeric separators, `+replacement` will evaluate to `NaN` because unary `+` + * per the specification doesn't support numeric separators. Thus, the above condition will be `true` + * (`NaN !== anything` is always `true`) regardless of the `parseInt(str, radix)` value. + * Consequently, no autofixes will be made. This is correct behavior because `parseInt` also + * doesn't support numeric separators, but it does parse part of the string before the first `_`, + * so the autofix would be invalid: + * + * parseInt("1_1", 2) // === 1 + * 0b1_1 // === 3 + */ + return null; + } + + const tokenBefore = sourceCode.getTokenBefore(node), + tokenAfter = sourceCode.getTokenAfter(node); + let prefix = "", + suffix = ""; + + if ( + tokenBefore && + tokenBefore.range[1] === node.range[0] && + !astUtils.canTokensBeAdjacent(tokenBefore, replacement) + ) { + prefix = " "; + } + + if ( + tokenAfter && + node.range[1] === tokenAfter.range[0] && + !astUtils.canTokensBeAdjacent(replacement, tokenAfter) + ) { + suffix = " "; + } + + return fixer.replaceText(node, `${prefix}${replacement}${suffix}`); + } + }); + } + } + }; + } +}; + +/** + * @fileoverview Prefers object spread property over Object.assign + * @author Sharmila Jesupaul + * See LICENSE file in root directory for full license. + */ + +const { CALL: CALL$2, ReferenceTracker: ReferenceTracker$2 } = require$$0__default$1['default']; +const { + isCommaToken, + isOpeningParenToken, + isClosingParenToken, + isParenthesised +} = astUtils; + +const ANY_SPACE = /\s/u; + +/** + * Helper that checks if the Object.assign call has array spread + * @param {ASTNode} node The node that the rule warns on + * @returns {boolean} - Returns true if the Object.assign call has array spread + */ +function hasArraySpread(node) { + return node.arguments.some(arg => arg.type === "SpreadElement"); +} + +/** + * Determines whether the given node is an accessor property (getter/setter). + * @param {ASTNode} node Node to check. + * @returns {boolean} `true` if the node is a getter or a setter. + */ +function isAccessorProperty(node) { + return node.type === "Property" && + (node.kind === "get" || node.kind === "set"); +} + +/** + * Determines whether the given object expression node has accessor properties (getters/setters). + * @param {ASTNode} node `ObjectExpression` node to check. + * @returns {boolean} `true` if the node has at least one getter/setter. + */ +function hasAccessors(node) { + return node.properties.some(isAccessorProperty); +} + +/** + * Determines whether the given call expression node has object expression arguments with accessor properties (getters/setters). + * @param {ASTNode} node `CallExpression` node to check. + * @returns {boolean} `true` if the node has at least one argument that is an object expression with at least one getter/setter. + */ +function hasArgumentsWithAccessors(node) { + return node.arguments + .filter(arg => arg.type === "ObjectExpression") + .some(hasAccessors); +} + +/** + * Helper that checks if the node needs parentheses to be valid JS. + * The default is to wrap the node in parentheses to avoid parsing errors. + * @param {ASTNode} node The node that the rule warns on + * @param {Object} sourceCode in context sourcecode object + * @returns {boolean} - Returns true if the node needs parentheses + */ +function needsParens(node, sourceCode) { + const parent = node.parent; + + switch (parent.type) { + case "VariableDeclarator": + case "ArrayExpression": + case "ReturnStatement": + case "CallExpression": + case "Property": + return false; + case "AssignmentExpression": + return parent.left === node && !isParenthesised(sourceCode, node); + default: + return !isParenthesised(sourceCode, node); + } +} + +/** + * Determines if an argument needs parentheses. The default is to not add parens. + * @param {ASTNode} node The node to be checked. + * @param {Object} sourceCode in context sourcecode object + * @returns {boolean} True if the node needs parentheses + */ +function argNeedsParens(node, sourceCode) { + switch (node.type) { + case "AssignmentExpression": + case "ArrowFunctionExpression": + case "ConditionalExpression": + return !isParenthesised(sourceCode, node); + default: + return false; + } +} + +/** + * Get the parenthesis tokens of a given ObjectExpression node. + * This includes the braces of the object literal and enclosing parentheses. + * @param {ASTNode} node The node to get. + * @param {Token} leftArgumentListParen The opening paren token of the argument list. + * @param {SourceCode} sourceCode The source code object to get tokens. + * @returns {Token[]} The parenthesis tokens of the node. This is sorted by the location. + */ +function getParenTokens(node, leftArgumentListParen, sourceCode) { + const parens = [sourceCode.getFirstToken(node), sourceCode.getLastToken(node)]; + let leftNext = sourceCode.getTokenBefore(node); + let rightNext = sourceCode.getTokenAfter(node); + + // Note: don't include the parens of the argument list. + while ( + leftNext && + rightNext && + leftNext.range[0] > leftArgumentListParen.range[0] && + isOpeningParenToken(leftNext) && + isClosingParenToken(rightNext) + ) { + parens.push(leftNext, rightNext); + leftNext = sourceCode.getTokenBefore(leftNext); + rightNext = sourceCode.getTokenAfter(rightNext); + } + + return parens.sort((a, b) => a.range[0] - b.range[0]); +} + +/** + * Get the range of a given token and around whitespaces. + * @param {Token} token The token to get range. + * @param {SourceCode} sourceCode The source code object to get tokens. + * @returns {number} The end of the range of the token and around whitespaces. + */ +function getStartWithSpaces(token, sourceCode) { + const text = sourceCode.text; + let start = token.range[0]; + + // If the previous token is a line comment then skip this step to avoid commenting this token out. + { + const prevToken = sourceCode.getTokenBefore(token, { includeComments: true }); + + if (prevToken && prevToken.type === "Line") { + return start; + } + } + + // Detect spaces before the token. + while (ANY_SPACE.test(text[start - 1] || "")) { + start -= 1; + } + + return start; +} + +/** + * Get the range of a given token and around whitespaces. + * @param {Token} token The token to get range. + * @param {SourceCode} sourceCode The source code object to get tokens. + * @returns {number} The start of the range of the token and around whitespaces. + */ +function getEndWithSpaces(token, sourceCode) { + const text = sourceCode.text; + let end = token.range[1]; + + // Detect spaces after the token. + while (ANY_SPACE.test(text[end] || "")) { + end += 1; + } + + return end; +} + +/** + * Autofixes the Object.assign call to use an object spread instead. + * @param {ASTNode|null} node The node that the rule warns on, i.e. the Object.assign call + * @param {string} sourceCode sourceCode of the Object.assign call + * @returns {Function} autofixer - replaces the Object.assign with a spread object. + */ +function defineFixer(node, sourceCode) { + return function *(fixer) { + const leftParen = sourceCode.getTokenAfter(node.callee, isOpeningParenToken); + const rightParen = sourceCode.getLastToken(node); + + // Remove everything before the opening paren: callee `Object.assign`, type arguments, and whitespace between the callee and the paren. + yield fixer.removeRange([node.range[0], leftParen.range[0]]); + + // Replace the parens of argument list to braces. + if (needsParens(node, sourceCode)) { + yield fixer.replaceText(leftParen, "({"); + yield fixer.replaceText(rightParen, "})"); + } else { + yield fixer.replaceText(leftParen, "{"); + yield fixer.replaceText(rightParen, "}"); + } + + // Process arguments. + for (const argNode of node.arguments) { + const innerParens = getParenTokens(argNode, leftParen, sourceCode); + const left = innerParens.shift(); + const right = innerParens.pop(); + + if (argNode.type === "ObjectExpression") { + const maybeTrailingComma = sourceCode.getLastToken(argNode, 1); + const maybeArgumentComma = sourceCode.getTokenAfter(right); + + /* + * Make bare this object literal. + * And remove spaces inside of the braces for better formatting. + */ + for (const innerParen of innerParens) { + yield fixer.remove(innerParen); + } + const leftRange = [left.range[0], getEndWithSpaces(left, sourceCode)]; + const rightRange = [ + Math.max(getStartWithSpaces(right, sourceCode), leftRange[1]), // Ensure ranges don't overlap + right.range[1] + ]; + + yield fixer.removeRange(leftRange); + yield fixer.removeRange(rightRange); + + // Remove the comma of this argument if it's duplication. + if ( + (argNode.properties.length === 0 || isCommaToken(maybeTrailingComma)) && + isCommaToken(maybeArgumentComma) + ) { + yield fixer.remove(maybeArgumentComma); + } + } else { + + // Make spread. + if (argNeedsParens(argNode, sourceCode)) { + yield fixer.insertTextBefore(left, "...("); + yield fixer.insertTextAfter(right, ")"); + } else { + yield fixer.insertTextBefore(left, "..."); + } + } + } + }; +} + +var preferObjectSpread = { + meta: { + type: "suggestion", + + docs: { + description: + "disallow using Object.assign with an object literal as the first argument and prefer the use of object spread instead.", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/prefer-object-spread" + }, + + schema: [], + fixable: "code", + + messages: { + useSpreadMessage: "Use an object spread instead of `Object.assign` eg: `{ ...foo }`.", + useLiteralMessage: "Use an object literal instead of `Object.assign`. eg: `{ foo: bar }`." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + Program() { + const scope = context.getScope(); + const tracker = new ReferenceTracker$2(scope); + const trackMap = { + Object: { + assign: { [CALL$2]: true } + } + }; + + // Iterate all calls of `Object.assign` (only of the global variable `Object`). + for (const { node } of tracker.iterateGlobalReferences(trackMap)) { + if ( + node.arguments.length >= 1 && + node.arguments[0].type === "ObjectExpression" && + !hasArraySpread(node) && + !( + node.arguments.length > 1 && + hasArgumentsWithAccessors(node) + ) + ) { + const messageId = node.arguments.length === 1 + ? "useLiteralMessage" + : "useSpreadMessage"; + const fix = defineFixer(node, sourceCode); + + context.report({ node, messageId, fix }); + } + } + } + }; + } +}; + +/** + * @fileoverview restrict values that can be used as Promise rejection reasons + * @author Teddy Katz + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var preferPromiseRejectErrors = { + meta: { + type: "suggestion", + + docs: { + description: "require using Error objects as Promise rejection reasons", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/prefer-promise-reject-errors" + }, + + fixable: null, + + schema: [ + { + type: "object", + properties: { + allowEmptyReject: { type: "boolean", default: false } + }, + additionalProperties: false + } + ], + + messages: { + rejectAnError: "Expected the Promise rejection reason to be an Error." + } + }, + + create(context) { + + const ALLOW_EMPTY_REJECT = context.options.length && context.options[0].allowEmptyReject; + + //---------------------------------------------------------------------- + // Helpers + //---------------------------------------------------------------------- + + /** + * Checks the argument of a reject() or Promise.reject() CallExpression, and reports it if it can't be an Error + * @param {ASTNode} callExpression A CallExpression node which is used to reject a Promise + * @returns {void} + */ + function checkRejectCall(callExpression) { + if (!callExpression.arguments.length && ALLOW_EMPTY_REJECT) { + return; + } + if ( + !callExpression.arguments.length || + !astUtils.couldBeError(callExpression.arguments[0]) || + callExpression.arguments[0].type === "Identifier" && callExpression.arguments[0].name === "undefined" + ) { + context.report({ + node: callExpression, + messageId: "rejectAnError" + }); + } + } + + /** + * Determines whether a function call is a Promise.reject() call + * @param {ASTNode} node A CallExpression node + * @returns {boolean} `true` if the call is a Promise.reject() call + */ + function isPromiseRejectCall(node) { + return astUtils.isSpecificMemberAccess(node.callee, "Promise", "reject"); + } + + //---------------------------------------------------------------------- + // Public + //---------------------------------------------------------------------- + + return { + + // Check `Promise.reject(value)` calls. + CallExpression(node) { + if (isPromiseRejectCall(node)) { + checkRejectCall(node); + } + }, + + /* + * Check for `new Promise((resolve, reject) => {})`, and check for reject() calls. + * This function is run on "NewExpression:exit" instead of "NewExpression" to ensure that + * the nodes in the expression already have the `parent` property. + */ + "NewExpression:exit"(node) { + if ( + node.callee.type === "Identifier" && node.callee.name === "Promise" && + node.arguments.length && astUtils.isFunction(node.arguments[0]) && + node.arguments[0].params.length > 1 && node.arguments[0].params[1].type === "Identifier" + ) { + context.getDeclaredVariables(node.arguments[0]) + + /* + * Find the first variable that matches the second parameter's name. + * If the first parameter has the same name as the second parameter, then the variable will actually + * be "declared" when the first parameter is evaluated, but then it will be immediately overwritten + * by the second parameter. It's not possible for an expression with the variable to be evaluated before + * the variable is overwritten, because functions with duplicate parameters cannot have destructuring or + * default assignments in their parameter lists. Therefore, it's not necessary to explicitly account for + * this case. + */ + .find(variable => variable.name === node.arguments[0].params[1].name) + + // Get the references to that variable. + .references + + // Only check the references that read the parameter's value. + .filter(ref => ref.isRead()) + + // Only check the references that are used as the callee in a function call, e.g. `reject(foo)`. + .filter(ref => ref.identifier.parent.type === "CallExpression" && ref.identifier === ref.identifier.parent.callee) + + // Check the argument of the function call to determine whether it's an Error. + .forEach(ref => checkRejectCall(ref.identifier.parent)); + } + } + }; + } +}; + +/** + * @fileoverview Rule to suggest using "Reflect" api over Function/Object methods + * @author Keith Cirkel + * @deprecated in ESLint v3.9.0 + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var preferReflect = { + meta: { + type: "suggestion", + + docs: { + description: "require `Reflect` methods where applicable", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/prefer-reflect" + }, + + deprecated: true, + + replacedBy: [], + + schema: [ + { + type: "object", + properties: { + exceptions: { + type: "array", + items: { + enum: [ + "apply", + "call", + "delete", + "defineProperty", + "getOwnPropertyDescriptor", + "getPrototypeOf", + "setPrototypeOf", + "isExtensible", + "getOwnPropertyNames", + "preventExtensions" + ] + }, + uniqueItems: true + } + }, + additionalProperties: false + } + ], + + messages: { + preferReflect: "Avoid using {{existing}}, instead use {{substitute}}." + } + }, + + create(context) { + const existingNames = { + apply: "Function.prototype.apply", + call: "Function.prototype.call", + defineProperty: "Object.defineProperty", + getOwnPropertyDescriptor: "Object.getOwnPropertyDescriptor", + getPrototypeOf: "Object.getPrototypeOf", + setPrototypeOf: "Object.setPrototypeOf", + isExtensible: "Object.isExtensible", + getOwnPropertyNames: "Object.getOwnPropertyNames", + preventExtensions: "Object.preventExtensions" + }; + + const reflectSubstitutes = { + apply: "Reflect.apply", + call: "Reflect.apply", + defineProperty: "Reflect.defineProperty", + getOwnPropertyDescriptor: "Reflect.getOwnPropertyDescriptor", + getPrototypeOf: "Reflect.getPrototypeOf", + setPrototypeOf: "Reflect.setPrototypeOf", + isExtensible: "Reflect.isExtensible", + getOwnPropertyNames: "Reflect.getOwnPropertyNames", + preventExtensions: "Reflect.preventExtensions" + }; + + const exceptions = (context.options[0] || {}).exceptions || []; + + /** + * Reports the Reflect violation based on the `existing` and `substitute` + * @param {Object} node The node that violates the rule. + * @param {string} existing The existing method name that has been used. + * @param {string} substitute The Reflect substitute that should be used. + * @returns {void} + */ + function report(node, existing, substitute) { + context.report({ + node, + messageId: "preferReflect", + data: { + existing, + substitute + } + }); + } + + return { + CallExpression(node) { + const methodName = (node.callee.property || {}).name; + const isReflectCall = (node.callee.object || {}).name === "Reflect"; + const hasReflectSubstitute = Object.prototype.hasOwnProperty.call(reflectSubstitutes, methodName); + const userConfiguredException = exceptions.indexOf(methodName) !== -1; + + if (hasReflectSubstitute && !isReflectCall && !userConfiguredException) { + report(node, existingNames[methodName], reflectSubstitutes[methodName]); + } + }, + UnaryExpression(node) { + const isDeleteOperator = node.operator === "delete"; + const targetsIdentifier = node.argument.type === "Identifier"; + const userConfiguredException = exceptions.indexOf("delete") !== -1; + + if (isDeleteOperator && !targetsIdentifier && !userConfiguredException) { + report(node, "the delete keyword", "Reflect.deleteProperty"); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to disallow use of the `RegExp` constructor in favor of regular expression literals + * @author Milos Djermanovic + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + +const { CALL: CALL$1, CONSTRUCT: CONSTRUCT$1, ReferenceTracker: ReferenceTracker$1, findVariable } = require$$0__default$1['default']; + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Determines whether the given node is a string literal. + * @param {ASTNode} node Node to check. + * @returns {boolean} True if the node is a string literal. + */ +function isStringLiteral(node) { + return node.type === "Literal" && typeof node.value === "string"; +} + +/** + * Determines whether the given node is a regex literal. + * @param {ASTNode} node Node to check. + * @returns {boolean} True if the node is a regex literal. + */ +function isRegexLiteral(node) { + return node.type === "Literal" && Object.prototype.hasOwnProperty.call(node, "regex"); +} + +/** + * Determines whether the given node is a template literal without expressions. + * @param {ASTNode} node Node to check. + * @returns {boolean} True if the node is a template literal without expressions. + */ +function isStaticTemplateLiteral$1(node) { + return node.type === "TemplateLiteral" && node.expressions.length === 0; +} + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var preferRegexLiterals = { + meta: { + type: "suggestion", + + docs: { + description: "disallow use of the `RegExp` constructor in favor of regular expression literals", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/prefer-regex-literals" + }, + + schema: [ + { + type: "object", + properties: { + disallowRedundantWrapping: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + messages: { + unexpectedRegExp: "Use a regular expression literal instead of the 'RegExp' constructor.", + unexpectedRedundantRegExp: "Regular expression literal is unnecessarily wrapped within a 'RegExp' constructor.", + unexpectedRedundantRegExpWithFlags: "Use regular expression literal with flags instead of the 'RegExp' constructor." + } + }, + + create(context) { + const [{ disallowRedundantWrapping = false } = {}] = context.options; + + /** + * Determines whether the given identifier node is a reference to a global variable. + * @param {ASTNode} node `Identifier` node to check. + * @returns {boolean} True if the identifier is a reference to a global variable. + */ + function isGlobalReference(node) { + const scope = context.getScope(); + const variable = findVariable(scope, node); + + return variable !== null && variable.scope.type === "global" && variable.defs.length === 0; + } + + /** + * Determines whether the given node is a String.raw`` tagged template expression + * with a static template literal. + * @param {ASTNode} node Node to check. + * @returns {boolean} True if the node is String.raw`` with a static template. + */ + function isStringRawTaggedStaticTemplateLiteral(node) { + return node.type === "TaggedTemplateExpression" && + astUtils.isSpecificMemberAccess(node.tag, "String", "raw") && + isGlobalReference(astUtils.skipChainExpression(node.tag).object) && + isStaticTemplateLiteral$1(node.quasi); + } + + /** + * Determines whether the given node is considered to be a static string by the logic of this rule. + * @param {ASTNode} node Node to check. + * @returns {boolean} True if the node is a static string. + */ + function isStaticString(node) { + return isStringLiteral(node) || + isStaticTemplateLiteral$1(node) || + isStringRawTaggedStaticTemplateLiteral(node); + } + + /** + * Determines whether the relevant arguments of the given are all static string literals. + * @param {ASTNode} node Node to check. + * @returns {boolean} True if all arguments are static strings. + */ + function hasOnlyStaticStringArguments(node) { + const args = node.arguments; + + if ((args.length === 1 || args.length === 2) && args.every(isStaticString)) { + return true; + } + + return false; + } + + /** + * Determines whether the arguments of the given node indicate that a regex literal is unnecessarily wrapped. + * @param {ASTNode} node Node to check. + * @returns {boolean} True if the node already contains a regex literal argument. + */ + function isUnnecessarilyWrappedRegexLiteral(node) { + const args = node.arguments; + + if (args.length === 1 && isRegexLiteral(args[0])) { + return true; + } + + if (args.length === 2 && isRegexLiteral(args[0]) && isStaticString(args[1])) { + return true; + } + + return false; + } + + return { + Program() { + const scope = context.getScope(); + const tracker = new ReferenceTracker$1(scope); + const traceMap = { + RegExp: { + [CALL$1]: true, + [CONSTRUCT$1]: true + } + }; + + for (const { node } of tracker.iterateGlobalReferences(traceMap)) { + if (disallowRedundantWrapping && isUnnecessarilyWrappedRegexLiteral(node)) { + if (node.arguments.length === 2) { + context.report({ node, messageId: "unexpectedRedundantRegExpWithFlags" }); + } else { + context.report({ node, messageId: "unexpectedRedundantRegExp" }); + } + } else if (hasOnlyStaticStringArguments(node)) { + context.report({ node, messageId: "unexpectedRegExp" }); + } + } + } + }; + } +}; + +/** + * @fileoverview Rule to + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Gets the variable object of `arguments` which is defined implicitly. + * @param {eslint-scope.Scope} scope A scope to get. + * @returns {eslint-scope.Variable} The found variable object. + */ +function getVariableOfArguments(scope) { + const variables = scope.variables; + + for (let i = 0; i < variables.length; ++i) { + const variable = variables[i]; + + if (variable.name === "arguments") { + + /* + * If there was a parameter which is named "arguments", the implicit "arguments" is not defined. + * So does fast return with null. + */ + return (variable.identifiers.length === 0) ? variable : null; + } + } + + /* istanbul ignore next : unreachable */ + return null; +} + +/** + * Checks if the given reference is not normal member access. + * + * - arguments .... true // not member access + * - arguments[i] .... true // computed member access + * - arguments[0] .... true // computed member access + * - arguments.length .... false // normal member access + * @param {eslint-scope.Reference} reference The reference to check. + * @returns {boolean} `true` if the reference is not normal member access. + */ +function isNotNormalMemberAccess(reference) { + const id = reference.identifier; + const parent = id.parent; + + return !( + parent.type === "MemberExpression" && + parent.object === id && + !parent.computed + ); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var preferRestParams = { + meta: { + type: "suggestion", + + docs: { + description: "require rest parameters instead of `arguments`", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/prefer-rest-params" + }, + + schema: [], + + messages: { + preferRestParams: "Use the rest parameters instead of 'arguments'." + } + }, + + create(context) { + + /** + * Reports a given reference. + * @param {eslint-scope.Reference} reference A reference to report. + * @returns {void} + */ + function report(reference) { + context.report({ + node: reference.identifier, + loc: reference.identifier.loc, + messageId: "preferRestParams" + }); + } + + /** + * Reports references of the implicit `arguments` variable if exist. + * @returns {void} + */ + function checkForArguments() { + const argumentsVar = getVariableOfArguments(context.getScope()); + + if (argumentsVar) { + argumentsVar + .references + .filter(isNotNormalMemberAccess) + .forEach(report); + } + } + + return { + "FunctionDeclaration:exit": checkForArguments, + "FunctionExpression:exit": checkForArguments + }; + } +}; + +/** + * @fileoverview A rule to suggest using of the spread operator instead of `.apply()`. + * @author Toru Nagashima + */ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a node is a `.apply()` for variadic. + * @param {ASTNode} node A CallExpression node to check. + * @returns {boolean} Whether or not the node is a `.apply()` for variadic. + */ +function isVariadicApplyCalling(node) { + return ( + astUtils.isSpecificMemberAccess(node.callee, null, "apply") && + node.arguments.length === 2 && + node.arguments[1].type !== "ArrayExpression" && + node.arguments[1].type !== "SpreadElement" + ); +} + +/** + * Checks whether or not `thisArg` is not changed by `.apply()`. + * @param {ASTNode|null} expectedThis The node that is the owner of the applied function. + * @param {ASTNode} thisArg The node that is given to the first argument of the `.apply()`. + * @param {RuleContext} context The ESLint rule context object. + * @returns {boolean} Whether or not `thisArg` is not changed by `.apply()`. + */ +function isValidThisArg(expectedThis, thisArg, context) { + if (!expectedThis) { + return astUtils.isNullOrUndefined(thisArg); + } + return astUtils.equalTokens(expectedThis, thisArg, context); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var preferSpread = { + meta: { + type: "suggestion", + + docs: { + description: "require spread operators instead of `.apply()`", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/prefer-spread" + }, + + schema: [], + fixable: null, + + messages: { + preferSpread: "Use the spread operator instead of '.apply()'." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + CallExpression(node) { + if (!isVariadicApplyCalling(node)) { + return; + } + + const applied = astUtils.skipChainExpression(astUtils.skipChainExpression(node.callee).object); + const expectedThis = (applied.type === "MemberExpression") ? applied.object : null; + const thisArg = node.arguments[0]; + + if (isValidThisArg(expectedThis, thisArg, sourceCode)) { + context.report({ + node, + messageId: "preferSpread" + }); + } + } + }; + } +}; + +/** + * @fileoverview A rule to suggest using template literals instead of string concatenation. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether or not a given node is a concatenation. + * @param {ASTNode} node A node to check. + * @returns {boolean} `true` if the node is a concatenation. + */ +function isConcatenation(node) { + return node.type === "BinaryExpression" && node.operator === "+"; +} + +/** + * Gets the top binary expression node for concatenation in parents of a given node. + * @param {ASTNode} node A node to get. + * @returns {ASTNode} the top binary expression node in parents of a given node. + */ +function getTopConcatBinaryExpression(node) { + let currentNode = node; + + while (isConcatenation(currentNode.parent)) { + currentNode = currentNode.parent; + } + return currentNode; +} + +/** + * Checks whether or not a node contains a string literal with an octal or non-octal decimal escape sequence + * @param {ASTNode} node A node to check + * @returns {boolean} `true` if at least one string literal within the node contains + * an octal or non-octal decimal escape sequence + */ +function hasOctalOrNonOctalDecimalEscapeSequence(node) { + if (isConcatenation(node)) { + return ( + hasOctalOrNonOctalDecimalEscapeSequence(node.left) || + hasOctalOrNonOctalDecimalEscapeSequence(node.right) + ); + } + + // No need to check TemplateLiterals – would throw parsing error + if (node.type === "Literal" && typeof node.value === "string") { + return astUtils.hasOctalOrNonOctalDecimalEscapeSequence(node.raw); + } + + return false; +} + +/** + * Checks whether or not a given binary expression has string literals. + * @param {ASTNode} node A node to check. + * @returns {boolean} `true` if the node has string literals. + */ +function hasStringLiteral(node) { + if (isConcatenation(node)) { + + // `left` is deeper than `right` normally. + return hasStringLiteral(node.right) || hasStringLiteral(node.left); + } + return astUtils.isStringLiteral(node); +} + +/** + * Checks whether or not a given binary expression has non string literals. + * @param {ASTNode} node A node to check. + * @returns {boolean} `true` if the node has non string literals. + */ +function hasNonStringLiteral(node) { + if (isConcatenation(node)) { + + // `left` is deeper than `right` normally. + return hasNonStringLiteral(node.right) || hasNonStringLiteral(node.left); + } + return !astUtils.isStringLiteral(node); +} + +/** + * Determines whether a given node will start with a template curly expression (`${}`) when being converted to a template literal. + * @param {ASTNode} node The node that will be fixed to a template literal + * @returns {boolean} `true` if the node will start with a template curly. + */ +function startsWithTemplateCurly(node) { + if (node.type === "BinaryExpression") { + return startsWithTemplateCurly(node.left); + } + if (node.type === "TemplateLiteral") { + return node.expressions.length && node.quasis.length && node.quasis[0].range[0] === node.quasis[0].range[1]; + } + return node.type !== "Literal" || typeof node.value !== "string"; +} + +/** + * Determines whether a given node end with a template curly expression (`${}`) when being converted to a template literal. + * @param {ASTNode} node The node that will be fixed to a template literal + * @returns {boolean} `true` if the node will end with a template curly. + */ +function endsWithTemplateCurly(node) { + if (node.type === "BinaryExpression") { + return startsWithTemplateCurly(node.right); + } + if (node.type === "TemplateLiteral") { + return node.expressions.length && node.quasis.length && node.quasis[node.quasis.length - 1].range[0] === node.quasis[node.quasis.length - 1].range[1]; + } + return node.type !== "Literal" || typeof node.value !== "string"; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var preferTemplate = { + meta: { + type: "suggestion", + + docs: { + description: "require template literals instead of string concatenation", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/prefer-template" + }, + + schema: [], + fixable: "code", + + messages: { + unexpectedStringConcatenation: "Unexpected string concatenation." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + let done = Object.create(null); + + /** + * Gets the non-token text between two nodes, ignoring any other tokens that appear between the two tokens. + * @param {ASTNode} node1 The first node + * @param {ASTNode} node2 The second node + * @returns {string} The text between the nodes, excluding other tokens + */ + function getTextBetween(node1, node2) { + const allTokens = [node1].concat(sourceCode.getTokensBetween(node1, node2)).concat(node2); + const sourceText = sourceCode.getText(); + + return allTokens.slice(0, -1).reduce((accumulator, token, index) => accumulator + sourceText.slice(token.range[1], allTokens[index + 1].range[0]), ""); + } + + /** + * Returns a template literal form of the given node. + * @param {ASTNode} currentNode A node that should be converted to a template literal + * @param {string} textBeforeNode Text that should appear before the node + * @param {string} textAfterNode Text that should appear after the node + * @returns {string} A string form of this node, represented as a template literal + */ + function getTemplateLiteral(currentNode, textBeforeNode, textAfterNode) { + if (currentNode.type === "Literal" && typeof currentNode.value === "string") { + + /* + * If the current node is a string literal, escape any instances of ${ or ` to prevent them from being interpreted + * as a template placeholder. However, if the code already contains a backslash before the ${ or ` + * for some reason, don't add another backslash, because that would change the meaning of the code (it would cause + * an actual backslash character to appear before the dollar sign). + */ + return `\`${currentNode.raw.slice(1, -1).replace(/\\*(\$\{|`)/gu, matched => { + if (matched.lastIndexOf("\\") % 2) { + return `\\${matched}`; + } + return matched; + + // Unescape any quotes that appear in the original Literal that no longer need to be escaped. + }).replace(new RegExp(`\\\\${currentNode.raw[0]}`, "gu"), currentNode.raw[0])}\``; + } + + if (currentNode.type === "TemplateLiteral") { + return sourceCode.getText(currentNode); + } + + if (isConcatenation(currentNode) && hasStringLiteral(currentNode) && hasNonStringLiteral(currentNode)) { + const plusSign = sourceCode.getFirstTokenBetween(currentNode.left, currentNode.right, token => token.value === "+"); + const textBeforePlus = getTextBetween(currentNode.left, plusSign); + const textAfterPlus = getTextBetween(plusSign, currentNode.right); + const leftEndsWithCurly = endsWithTemplateCurly(currentNode.left); + const rightStartsWithCurly = startsWithTemplateCurly(currentNode.right); + + if (leftEndsWithCurly) { + + // If the left side of the expression ends with a template curly, add the extra text to the end of the curly bracket. + // `foo${bar}` /* comment */ + 'baz' --> `foo${bar /* comment */ }${baz}` + return getTemplateLiteral(currentNode.left, textBeforeNode, textBeforePlus + textAfterPlus).slice(0, -1) + + getTemplateLiteral(currentNode.right, null, textAfterNode).slice(1); + } + if (rightStartsWithCurly) { + + // Otherwise, if the right side of the expression starts with a template curly, add the text there. + // 'foo' /* comment */ + `${bar}baz` --> `foo${ /* comment */ bar}baz` + return getTemplateLiteral(currentNode.left, textBeforeNode, null).slice(0, -1) + + getTemplateLiteral(currentNode.right, textBeforePlus + textAfterPlus, textAfterNode).slice(1); + } + + /* + * Otherwise, these nodes should not be combined into a template curly, since there is nowhere to put + * the text between them. + */ + return `${getTemplateLiteral(currentNode.left, textBeforeNode, null)}${textBeforePlus}+${textAfterPlus}${getTemplateLiteral(currentNode.right, textAfterNode, null)}`; + } + + return `\`\${${textBeforeNode || ""}${sourceCode.getText(currentNode)}${textAfterNode || ""}}\``; + } + + /** + * Returns a fixer object that converts a non-string binary expression to a template literal + * @param {SourceCodeFixer} fixer The fixer object + * @param {ASTNode} node A node that should be converted to a template literal + * @returns {Object} A fix for this binary expression + */ + function fixNonStringBinaryExpression(fixer, node) { + const topBinaryExpr = getTopConcatBinaryExpression(node.parent); + + if (hasOctalOrNonOctalDecimalEscapeSequence(topBinaryExpr)) { + return null; + } + + return fixer.replaceText(topBinaryExpr, getTemplateLiteral(topBinaryExpr, null, null)); + } + + /** + * Reports if a given node is string concatenation with non string literals. + * @param {ASTNode} node A node to check. + * @returns {void} + */ + function checkForStringConcat(node) { + if (!astUtils.isStringLiteral(node) || !isConcatenation(node.parent)) { + return; + } + + const topBinaryExpr = getTopConcatBinaryExpression(node.parent); + + // Checks whether or not this node had been checked already. + if (done[topBinaryExpr.range[0]]) { + return; + } + done[topBinaryExpr.range[0]] = true; + + if (hasNonStringLiteral(topBinaryExpr)) { + context.report({ + node: topBinaryExpr, + messageId: "unexpectedStringConcatenation", + fix: fixer => fixNonStringBinaryExpression(fixer, node) + }); + } + } + + return { + Program() { + done = Object.create(null); + }, + + Literal: checkForStringConcat, + TemplateLiteral: checkForStringConcat + }; + } +}; + +/** + * @fileoverview Rule to flag non-quoted property names in object literals. + * @author Mathias Bynens + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var quoteProps = { + meta: { + type: "suggestion", + + docs: { + description: "require quotes around object literal property names", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/quote-props" + }, + + schema: { + anyOf: [ + { + type: "array", + items: [ + { + enum: ["always", "as-needed", "consistent", "consistent-as-needed"] + } + ], + minItems: 0, + maxItems: 1 + }, + { + type: "array", + items: [ + { + enum: ["always", "as-needed", "consistent", "consistent-as-needed"] + }, + { + type: "object", + properties: { + keywords: { + type: "boolean" + }, + unnecessary: { + type: "boolean" + }, + numbers: { + type: "boolean" + } + }, + additionalProperties: false + } + ], + minItems: 0, + maxItems: 2 + } + ] + }, + + fixable: "code", + messages: { + requireQuotesDueToReservedWord: "Properties should be quoted as '{{property}}' is a reserved word.", + inconsistentlyQuotedProperty: "Inconsistently quoted property '{{key}}' found.", + unnecessarilyQuotedProperty: "Unnecessarily quoted property '{{property}}' found.", + unquotedReservedProperty: "Unquoted reserved word '{{property}}' used as key.", + unquotedNumericProperty: "Unquoted number literal '{{property}}' used as key.", + unquotedPropertyFound: "Unquoted property '{{property}}' found.", + redundantQuoting: "Properties shouldn't be quoted as all quotes are redundant." + } + }, + + create(context) { + + const MODE = context.options[0], + KEYWORDS = context.options[1] && context.options[1].keywords, + CHECK_UNNECESSARY = !context.options[1] || context.options[1].unnecessary !== false, + NUMBERS = context.options[1] && context.options[1].numbers, + + sourceCode = context.getSourceCode(); + + + /** + * Checks whether a certain string constitutes an ES3 token + * @param {string} tokenStr The string to be checked. + * @returns {boolean} `true` if it is an ES3 token. + */ + function isKeyword(tokenStr) { + return keywords.indexOf(tokenStr) >= 0; + } + + /** + * Checks if an espree-tokenized key has redundant quotes (i.e. whether quotes are unnecessary) + * @param {string} rawKey The raw key value from the source + * @param {espreeTokens} tokens The espree-tokenized node key + * @param {boolean} [skipNumberLiterals=false] Indicates whether number literals should be checked + * @returns {boolean} Whether or not a key has redundant quotes. + * @private + */ + function areQuotesRedundant(rawKey, tokens, skipNumberLiterals) { + return tokens.length === 1 && tokens[0].start === 0 && tokens[0].end === rawKey.length && + (["Identifier", "Keyword", "Null", "Boolean"].indexOf(tokens[0].type) >= 0 || + (tokens[0].type === "Numeric" && !skipNumberLiterals && String(+tokens[0].value) === tokens[0].value)); + } + + /** + * Returns a string representation of a property node with quotes removed + * @param {ASTNode} key Key AST Node, which may or may not be quoted + * @returns {string} A replacement string for this property + */ + function getUnquotedKey(key) { + return key.type === "Identifier" ? key.name : key.value; + } + + /** + * Returns a string representation of a property node with quotes added + * @param {ASTNode} key Key AST Node, which may or may not be quoted + * @returns {string} A replacement string for this property + */ + function getQuotedKey(key) { + if (key.type === "Literal" && typeof key.value === "string") { + + // If the key is already a string literal, don't replace the quotes with double quotes. + return sourceCode.getText(key); + } + + // Otherwise, the key is either an identifier or a number literal. + return `"${key.type === "Identifier" ? key.name : key.value}"`; + } + + /** + * Ensures that a property's key is quoted only when necessary + * @param {ASTNode} node Property AST node + * @returns {void} + */ + function checkUnnecessaryQuotes(node) { + const key = node.key; + + if (node.method || node.computed || node.shorthand) { + return; + } + + if (key.type === "Literal" && typeof key.value === "string") { + let tokens; + + try { + tokens = espree__default['default'].tokenize(key.value); + } catch { + return; + } + + if (tokens.length !== 1) { + return; + } + + const isKeywordToken = isKeyword(tokens[0].value); + + if (isKeywordToken && KEYWORDS) { + return; + } + + if (CHECK_UNNECESSARY && areQuotesRedundant(key.value, tokens, NUMBERS)) { + context.report({ + node, + messageId: "unnecessarilyQuotedProperty", + data: { property: key.value }, + fix: fixer => fixer.replaceText(key, getUnquotedKey(key)) + }); + } + } else if (KEYWORDS && key.type === "Identifier" && isKeyword(key.name)) { + context.report({ + node, + messageId: "unquotedReservedProperty", + data: { property: key.name }, + fix: fixer => fixer.replaceText(key, getQuotedKey(key)) + }); + } else if (NUMBERS && key.type === "Literal" && astUtils.isNumericLiteral(key)) { + context.report({ + node, + messageId: "unquotedNumericProperty", + data: { property: key.value }, + fix: fixer => fixer.replaceText(key, getQuotedKey(key)) + }); + } + } + + /** + * Ensures that a property's key is quoted + * @param {ASTNode} node Property AST node + * @returns {void} + */ + function checkOmittedQuotes(node) { + const key = node.key; + + if (!node.method && !node.computed && !node.shorthand && !(key.type === "Literal" && typeof key.value === "string")) { + context.report({ + node, + messageId: "unquotedPropertyFound", + data: { property: key.name || key.value }, + fix: fixer => fixer.replaceText(key, getQuotedKey(key)) + }); + } + } + + /** + * Ensures that an object's keys are consistently quoted, optionally checks for redundancy of quotes + * @param {ASTNode} node Property AST node + * @param {boolean} checkQuotesRedundancy Whether to check quotes' redundancy + * @returns {void} + */ + function checkConsistency(node, checkQuotesRedundancy) { + const quotedProps = [], + unquotedProps = []; + let keywordKeyName = null, + necessaryQuotes = false; + + node.properties.forEach(property => { + const key = property.key; + + if (!key || property.method || property.computed || property.shorthand) { + return; + } + + if (key.type === "Literal" && typeof key.value === "string") { + + quotedProps.push(property); + + if (checkQuotesRedundancy) { + let tokens; + + try { + tokens = espree__default['default'].tokenize(key.value); + } catch { + necessaryQuotes = true; + return; + } + + necessaryQuotes = necessaryQuotes || !areQuotesRedundant(key.value, tokens) || KEYWORDS && isKeyword(tokens[0].value); + } + } else if (KEYWORDS && checkQuotesRedundancy && key.type === "Identifier" && isKeyword(key.name)) { + unquotedProps.push(property); + necessaryQuotes = true; + keywordKeyName = key.name; + } else { + unquotedProps.push(property); + } + }); + + if (checkQuotesRedundancy && quotedProps.length && !necessaryQuotes) { + quotedProps.forEach(property => { + context.report({ + node: property, + messageId: "redundantQuoting", + fix: fixer => fixer.replaceText(property.key, getUnquotedKey(property.key)) + }); + }); + } else if (unquotedProps.length && keywordKeyName) { + unquotedProps.forEach(property => { + context.report({ + node: property, + messageId: "requireQuotesDueToReservedWord", + data: { property: keywordKeyName }, + fix: fixer => fixer.replaceText(property.key, getQuotedKey(property.key)) + }); + }); + } else if (quotedProps.length && unquotedProps.length) { + unquotedProps.forEach(property => { + context.report({ + node: property, + messageId: "inconsistentlyQuotedProperty", + data: { key: property.key.name || property.key.value }, + fix: fixer => fixer.replaceText(property.key, getQuotedKey(property.key)) + }); + }); + } + } + + return { + Property(node) { + if (MODE === "always" || !MODE) { + checkOmittedQuotes(node); + } + if (MODE === "as-needed") { + checkUnnecessaryQuotes(node); + } + }, + ObjectExpression(node) { + if (MODE === "consistent") { + checkConsistency(node, false); + } + if (MODE === "consistent-as-needed") { + checkConsistency(node, true); + } + } + }; + + } +}; + +/** + * @fileoverview A rule to choose between single and double quote marks + * @author Matt DuVall , Brandon Payton + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Constants +//------------------------------------------------------------------------------ + +const QUOTE_SETTINGS = { + double: { + quote: "\"", + alternateQuote: "'", + description: "doublequote" + }, + single: { + quote: "'", + alternateQuote: "\"", + description: "singlequote" + }, + backtick: { + quote: "`", + alternateQuote: "\"", + description: "backtick" + } +}; + +// An unescaped newline is a newline preceded by an even number of backslashes. +const UNESCAPED_LINEBREAK_PATTERN = new RegExp(String.raw`(^|[^\\])(\\\\)*[${Array.from(astUtils.LINEBREAKS).join("")}]`, "u"); + +/** + * Switches quoting of javascript string between ' " and ` + * escaping and unescaping as necessary. + * Only escaping of the minimal set of characters is changed. + * Note: escaping of newlines when switching from backtick to other quotes is not handled. + * @param {string} str A string to convert. + * @returns {string} The string with changed quotes. + * @private + */ +QUOTE_SETTINGS.double.convert = +QUOTE_SETTINGS.single.convert = +QUOTE_SETTINGS.backtick.convert = function(str) { + const newQuote = this.quote; + const oldQuote = str[0]; + + if (newQuote === oldQuote) { + return str; + } + return newQuote + str.slice(1, -1).replace(/\\(\$\{|\r\n?|\n|.)|["'`]|\$\{|(\r\n?|\n)/gu, (match, escaped, newline) => { + if (escaped === oldQuote || oldQuote === "`" && escaped === "${") { + return escaped; // unescape + } + if (match === newQuote || newQuote === "`" && match === "${") { + return `\\${match}`; // escape + } + if (newline && oldQuote === "`") { + return "\\n"; // escape newlines + } + return match; + }) + newQuote; +}; + +const AVOID_ESCAPE = "avoid-escape"; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var quotes = { + meta: { + type: "layout", + + docs: { + description: "enforce the consistent use of either backticks, double, or single quotes", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/quotes" + }, + + fixable: "code", + + schema: [ + { + enum: ["single", "double", "backtick"] + }, + { + anyOf: [ + { + enum: ["avoid-escape"] + }, + { + type: "object", + properties: { + avoidEscape: { + type: "boolean" + }, + allowTemplateLiterals: { + type: "boolean" + } + }, + additionalProperties: false + } + ] + } + ], + + messages: { + wrongQuotes: "Strings must use {{description}}." + } + }, + + create(context) { + + const quoteOption = context.options[0], + settings = QUOTE_SETTINGS[quoteOption || "double"], + options = context.options[1], + allowTemplateLiterals = options && options.allowTemplateLiterals === true, + sourceCode = context.getSourceCode(); + let avoidEscape = options && options.avoidEscape === true; + + // deprecated + if (options === AVOID_ESCAPE) { + avoidEscape = true; + } + + /** + * Determines if a given node is part of JSX syntax. + * + * This function returns `true` in the following cases: + * + * - `
` ... If the literal is an attribute value, the parent of the literal is `JSXAttribute`. + * - `
foo
` ... If the literal is a text content, the parent of the literal is `JSXElement`. + * - `<>foo` ... If the literal is a text content, the parent of the literal is `JSXFragment`. + * + * In particular, this function returns `false` in the following cases: + * + * - `
` + * - `
{"foo"}
` + * + * In both cases, inside of the braces is handled as normal JavaScript. + * The braces are `JSXExpressionContainer` nodes. + * @param {ASTNode} node The Literal node to check. + * @returns {boolean} True if the node is a part of JSX, false if not. + * @private + */ + function isJSXLiteral(node) { + return node.parent.type === "JSXAttribute" || node.parent.type === "JSXElement" || node.parent.type === "JSXFragment"; + } + + /** + * Checks whether or not a given node is a directive. + * The directive is a `ExpressionStatement` which has only a string literal. + * @param {ASTNode} node A node to check. + * @returns {boolean} Whether or not the node is a directive. + * @private + */ + function isDirective(node) { + return ( + node.type === "ExpressionStatement" && + node.expression.type === "Literal" && + typeof node.expression.value === "string" + ); + } + + /** + * Checks whether or not a given node is a part of directive prologues. + * See also: http://www.ecma-international.org/ecma-262/6.0/#sec-directive-prologues-and-the-use-strict-directive + * @param {ASTNode} node A node to check. + * @returns {boolean} Whether or not the node is a part of directive prologues. + * @private + */ + function isPartOfDirectivePrologue(node) { + const block = node.parent.parent; + + if (block.type !== "Program" && (block.type !== "BlockStatement" || !astUtils.isFunction(block.parent))) { + return false; + } + + // Check the node is at a prologue. + for (let i = 0; i < block.body.length; ++i) { + const statement = block.body[i]; + + if (statement === node.parent) { + return true; + } + if (!isDirective(statement)) { + break; + } + } + + return false; + } + + /** + * Checks whether or not a given node is allowed as non backtick. + * @param {ASTNode} node A node to check. + * @returns {boolean} Whether or not the node is allowed as non backtick. + * @private + */ + function isAllowedAsNonBacktick(node) { + const parent = node.parent; + + switch (parent.type) { + + // Directive Prologues. + case "ExpressionStatement": + return isPartOfDirectivePrologue(node); + + // LiteralPropertyName. + case "Property": + case "MethodDefinition": + return parent.key === node && !parent.computed; + + // ModuleSpecifier. + case "ImportDeclaration": + case "ExportNamedDeclaration": + case "ExportAllDeclaration": + return parent.source === node; + + // Others don't allow. + default: + return false; + } + } + + /** + * Checks whether or not a given TemplateLiteral node is actually using any of the special features provided by template literal strings. + * @param {ASTNode} node A TemplateLiteral node to check. + * @returns {boolean} Whether or not the TemplateLiteral node is using any of the special features provided by template literal strings. + * @private + */ + function isUsingFeatureOfTemplateLiteral(node) { + const hasTag = node.parent.type === "TaggedTemplateExpression" && node === node.parent.quasi; + + if (hasTag) { + return true; + } + + const hasStringInterpolation = node.expressions.length > 0; + + if (hasStringInterpolation) { + return true; + } + + const isMultilineString = node.quasis.length >= 1 && UNESCAPED_LINEBREAK_PATTERN.test(node.quasis[0].value.raw); + + if (isMultilineString) { + return true; + } + + return false; + } + + return { + + Literal(node) { + const val = node.value, + rawVal = node.raw; + + if (settings && typeof val === "string") { + let isValid = (quoteOption === "backtick" && isAllowedAsNonBacktick(node)) || + isJSXLiteral(node) || + astUtils.isSurroundedBy(rawVal, settings.quote); + + if (!isValid && avoidEscape) { + isValid = astUtils.isSurroundedBy(rawVal, settings.alternateQuote) && rawVal.indexOf(settings.quote) >= 0; + } + + if (!isValid) { + context.report({ + node, + messageId: "wrongQuotes", + data: { + description: settings.description + }, + fix(fixer) { + if (quoteOption === "backtick" && astUtils.hasOctalOrNonOctalDecimalEscapeSequence(rawVal)) { + + /* + * An octal or non-octal decimal escape sequence in a template literal would + * produce syntax error, even in non-strict mode. + */ + return null; + } + + return fixer.replaceText(node, settings.convert(node.raw)); + } + }); + } + } + }, + + TemplateLiteral(node) { + + // Don't throw an error if backticks are expected or a template literal feature is in use. + if ( + allowTemplateLiterals || + quoteOption === "backtick" || + isUsingFeatureOfTemplateLiteral(node) + ) { + return; + } + + context.report({ + node, + messageId: "wrongQuotes", + data: { + description: settings.description + }, + fix(fixer) { + if (isPartOfDirectivePrologue(node)) { + + /* + * TemplateLiterals in a directive prologue aren't actually directives, but if they're + * in the directive prologue, then fixing them might turn them into directives and change + * the behavior of the code. + */ + return null; + } + return fixer.replaceText(node, settings.convert(sourceCode.getText(node))); + } + }); + } + }; + + } +}; + +/** + * @fileoverview Rule to flag use of parseInt without a radix argument + * @author James Allardice + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const MODE_ALWAYS = "always", + MODE_AS_NEEDED = "as-needed"; + +const validRadixValues = new Set(Array.from({ length: 37 - 2 }, (_, index) => index + 2)); + +/** + * Checks whether a given variable is shadowed or not. + * @param {eslint-scope.Variable} variable A variable to check. + * @returns {boolean} `true` if the variable is shadowed. + */ +function isShadowed(variable) { + return variable.defs.length >= 1; +} + +/** + * Checks whether a given node is a MemberExpression of `parseInt` method or not. + * @param {ASTNode} node A node to check. + * @returns {boolean} `true` if the node is a MemberExpression of `parseInt` + * method. + */ +function isParseIntMethod(node) { + return ( + node.type === "MemberExpression" && + !node.computed && + node.property.type === "Identifier" && + node.property.name === "parseInt" + ); +} + +/** + * Checks whether a given node is a valid value of radix or not. + * + * The following values are invalid. + * + * - A literal except integers between 2 and 36. + * - undefined. + * @param {ASTNode} radix A node of radix to check. + * @returns {boolean} `true` if the node is valid. + */ +function isValidRadix(radix) { + return !( + (radix.type === "Literal" && !validRadixValues.has(radix.value)) || + (radix.type === "Identifier" && radix.name === "undefined") + ); +} + +/** + * Checks whether a given node is a default value of radix or not. + * @param {ASTNode} radix A node of radix to check. + * @returns {boolean} `true` if the node is the literal node of `10`. + */ +function isDefaultRadix(radix) { + return radix.type === "Literal" && radix.value === 10; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var radix = { + meta: { + type: "suggestion", + + docs: { + description: "enforce the consistent use of the radix argument when using `parseInt()`", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/radix" + }, + + schema: [ + { + enum: ["always", "as-needed"] + } + ], + + messages: { + missingParameters: "Missing parameters.", + redundantRadix: "Redundant radix parameter.", + missingRadix: "Missing radix parameter.", + invalidRadix: "Invalid radix parameter, must be an integer between 2 and 36." + } + }, + + create(context) { + const mode = context.options[0] || MODE_ALWAYS; + + /** + * Checks the arguments of a given CallExpression node and reports it if it + * offends this rule. + * @param {ASTNode} node A CallExpression node to check. + * @returns {void} + */ + function checkArguments(node) { + const args = node.arguments; + + switch (args.length) { + case 0: + context.report({ + node, + messageId: "missingParameters" + }); + break; + + case 1: + if (mode === MODE_ALWAYS) { + context.report({ + node, + messageId: "missingRadix" + }); + } + break; + + default: + if (mode === MODE_AS_NEEDED && isDefaultRadix(args[1])) { + context.report({ + node, + messageId: "redundantRadix" + }); + } else if (!isValidRadix(args[1])) { + context.report({ + node, + messageId: "invalidRadix" + }); + } + break; + } + } + + return { + "Program:exit"() { + const scope = context.getScope(); + let variable; + + // Check `parseInt()` + variable = astUtils.getVariableByName(scope, "parseInt"); + if (variable && !isShadowed(variable)) { + variable.references.forEach(reference => { + const node = reference.identifier; + + if (astUtils.isCallee(node)) { + checkArguments(node.parent); + } + }); + } + + // Check `Number.parseInt()` + variable = astUtils.getVariableByName(scope, "Number"); + if (variable && !isShadowed(variable)) { + variable.references.forEach(reference => { + const node = reference.identifier.parent; + const maybeCallee = node.parent.type === "ChainExpression" + ? node.parent + : node; + + if (isParseIntMethod(node) && astUtils.isCallee(maybeCallee)) { + checkArguments(maybeCallee.parent); + } + }); + } + } + }; + } +}; + +/** + * @fileoverview disallow assignments that can lead to race conditions due to usage of `await` or `yield` + * @author Teddy Katz + * @author Toru Nagashima + */ + +/** + * Make the map from identifiers to each reference. + * @param {escope.Scope} scope The scope to get references. + * @param {Map} [outReferenceMap] The map from identifier nodes to each reference object. + * @returns {Map} `referenceMap`. + */ +function createReferenceMap(scope, outReferenceMap = new Map()) { + for (const reference of scope.references) { + outReferenceMap.set(reference.identifier, reference); + } + for (const childScope of scope.childScopes) { + if (childScope.type !== "function") { + createReferenceMap(childScope, outReferenceMap); + } + } + + return outReferenceMap; +} + +/** + * Get `reference.writeExpr` of a given reference. + * If it's the read reference of MemberExpression in LHS, returns RHS in order to address `a.b = await a` + * @param {escope.Reference} reference The reference to get. + * @returns {Expression|null} The `reference.writeExpr`. + */ +function getWriteExpr(reference) { + if (reference.writeExpr) { + return reference.writeExpr; + } + let node = reference.identifier; + + while (node) { + const t = node.parent.type; + + if (t === "AssignmentExpression" && node.parent.left === node) { + return node.parent.right; + } + if (t === "MemberExpression" && node.parent.object === node) { + node = node.parent; + continue; + } + + break; + } + + return null; +} + +/** + * Checks if an expression is a variable that can only be observed within the given function. + * @param {Variable|null} variable The variable to check + * @param {boolean} isMemberAccess If `true` then this is a member access. + * @returns {boolean} `true` if the variable is local to the given function, and is never referenced in a closure. + */ +function isLocalVariableWithoutEscape(variable, isMemberAccess) { + if (!variable) { + return false; // A global variable which was not defined. + } + + // If the reference is a property access and the variable is a parameter, it handles the variable is not local. + if (isMemberAccess && variable.defs.some(d => d.type === "Parameter")) { + return false; + } + + const functionScope = variable.scope.variableScope; + + return variable.references.every(reference => + reference.from.variableScope === functionScope); +} + +class SegmentInfo { + constructor() { + this.info = new WeakMap(); + } + + /** + * Initialize the segment information. + * @param {PathSegment} segment The segment to initialize. + * @returns {void} + */ + initialize(segment) { + const outdatedReadVariableNames = new Set(); + const freshReadVariableNames = new Set(); + + for (const prevSegment of segment.prevSegments) { + const info = this.info.get(prevSegment); + + if (info) { + info.outdatedReadVariableNames.forEach(Set.prototype.add, outdatedReadVariableNames); + info.freshReadVariableNames.forEach(Set.prototype.add, freshReadVariableNames); + } + } + + this.info.set(segment, { outdatedReadVariableNames, freshReadVariableNames }); + } + + /** + * Mark a given variable as read on given segments. + * @param {PathSegment[]} segments The segments that it read the variable on. + * @param {string} variableName The variable name to be read. + * @returns {void} + */ + markAsRead(segments, variableName) { + for (const segment of segments) { + const info = this.info.get(segment); + + if (info) { + info.freshReadVariableNames.add(variableName); + + // If a variable is freshly read again, then it's no more out-dated. + info.outdatedReadVariableNames.delete(variableName); + } + } + } + + /** + * Move `freshReadVariableNames` to `outdatedReadVariableNames`. + * @param {PathSegment[]} segments The segments to process. + * @returns {void} + */ + makeOutdated(segments) { + for (const segment of segments) { + const info = this.info.get(segment); + + if (info) { + info.freshReadVariableNames.forEach(Set.prototype.add, info.outdatedReadVariableNames); + info.freshReadVariableNames.clear(); + } + } + } + + /** + * Check if a given variable is outdated on the current segments. + * @param {PathSegment[]} segments The current segments. + * @param {string} variableName The variable name to check. + * @returns {boolean} `true` if the variable is outdated on the segments. + */ + isOutdated(segments, variableName) { + for (const segment of segments) { + const info = this.info.get(segment); + + if (info && info.outdatedReadVariableNames.has(variableName)) { + return true; + } + } + return false; + } +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var requireAtomicUpdates = { + meta: { + type: "problem", + + docs: { + description: "disallow assignments that can lead to race conditions due to usage of `await` or `yield`", + category: "Possible Errors", + recommended: false, + url: "https://eslint.org/docs/rules/require-atomic-updates" + }, + + fixable: null, + schema: [], + + messages: { + nonAtomicUpdate: "Possible race condition: `{{value}}` might be reassigned based on an outdated value of `{{value}}`." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const assignmentReferences = new Map(); + const segmentInfo = new SegmentInfo(); + let stack = null; + + return { + onCodePathStart(codePath) { + const scope = context.getScope(); + const shouldVerify = + scope.type === "function" && + (scope.block.async || scope.block.generator); + + stack = { + upper: stack, + codePath, + referenceMap: shouldVerify ? createReferenceMap(scope) : null + }; + }, + onCodePathEnd() { + stack = stack.upper; + }, + + // Initialize the segment information. + onCodePathSegmentStart(segment) { + segmentInfo.initialize(segment); + }, + + // Handle references to prepare verification. + Identifier(node) { + const { codePath, referenceMap } = stack; + const reference = referenceMap && referenceMap.get(node); + + // Ignore if this is not a valid variable reference. + if (!reference) { + return; + } + const name = reference.identifier.name; + const variable = reference.resolved; + const writeExpr = getWriteExpr(reference); + const isMemberAccess = reference.identifier.parent.type === "MemberExpression"; + + // Add a fresh read variable. + if (reference.isRead() && !(writeExpr && writeExpr.parent.operator === "=")) { + segmentInfo.markAsRead(codePath.currentSegments, name); + } + + /* + * Register the variable to verify after ESLint traversed the `writeExpr` node + * if this reference is an assignment to a variable which is referred from other closure. + */ + if (writeExpr && + writeExpr.parent.right === writeExpr && // ← exclude variable declarations. + !isLocalVariableWithoutEscape(variable, isMemberAccess) + ) { + let refs = assignmentReferences.get(writeExpr); + + if (!refs) { + refs = []; + assignmentReferences.set(writeExpr, refs); + } + + refs.push(reference); + } + }, + + /* + * Verify assignments. + * If the reference exists in `outdatedReadVariableNames` list, report it. + */ + ":expression:exit"(node) { + const { codePath, referenceMap } = stack; + + // referenceMap exists if this is in a resumable function scope. + if (!referenceMap) { + return; + } + + // Mark the read variables on this code path as outdated. + if (node.type === "AwaitExpression" || node.type === "YieldExpression") { + segmentInfo.makeOutdated(codePath.currentSegments); + } + + // Verify. + const references = assignmentReferences.get(node); + + if (references) { + assignmentReferences.delete(node); + + for (const reference of references) { + const name = reference.identifier.name; + + if (segmentInfo.isOutdated(codePath.currentSegments, name)) { + context.report({ + node: node.parent, + messageId: "nonAtomicUpdate", + data: { + value: sourceCode.getText(node.parent.left) + } + }); + } + } + } + } + }; + } +}; + +/** + * @fileoverview Rule to disallow async functions which have no `await` expression. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Capitalize the 1st letter of the given text. + * @param {string} text The text to capitalize. + * @returns {string} The text that the 1st letter was capitalized. + */ +function capitalizeFirstLetter(text) { + return text[0].toUpperCase() + text.slice(1); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var requireAwait = { + meta: { + type: "suggestion", + + docs: { + description: "disallow async functions which have no `await` expression", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/require-await" + }, + + schema: [], + + messages: { + missingAwait: "{{name}} has no 'await' expression." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + let scopeInfo = null; + + /** + * Push the scope info object to the stack. + * @returns {void} + */ + function enterFunction() { + scopeInfo = { + upper: scopeInfo, + hasAwait: false + }; + } + + /** + * Pop the top scope info object from the stack. + * Also, it reports the function if needed. + * @param {ASTNode} node The node to report. + * @returns {void} + */ + function exitFunction(node) { + if (!node.generator && node.async && !scopeInfo.hasAwait && !astUtils.isEmptyFunction(node)) { + context.report({ + node, + loc: astUtils.getFunctionHeadLoc(node, sourceCode), + messageId: "missingAwait", + data: { + name: capitalizeFirstLetter( + astUtils.getFunctionNameWithKind(node) + ) + } + }); + } + + scopeInfo = scopeInfo.upper; + } + + return { + FunctionDeclaration: enterFunction, + FunctionExpression: enterFunction, + ArrowFunctionExpression: enterFunction, + "FunctionDeclaration:exit": exitFunction, + "FunctionExpression:exit": exitFunction, + "ArrowFunctionExpression:exit": exitFunction, + + AwaitExpression() { + if (!scopeInfo) { + return; + } + + scopeInfo.hasAwait = true; + }, + ForOfStatement(node) { + if (!scopeInfo) { + return; + } + + if (node.await) { + scopeInfo.hasAwait = true; + } + } + }; + } +}; + +/** + * @fileoverview Rule to check for jsdoc presence. + * @author Gyandeep Singh + */ + +var requireJsdoc$1 = { + meta: { + type: "suggestion", + + docs: { + description: "require JSDoc comments", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/require-jsdoc" + }, + + schema: [ + { + type: "object", + properties: { + require: { + type: "object", + properties: { + ClassDeclaration: { + type: "boolean", + default: false + }, + MethodDefinition: { + type: "boolean", + default: false + }, + FunctionDeclaration: { + type: "boolean", + default: true + }, + ArrowFunctionExpression: { + type: "boolean", + default: false + }, + FunctionExpression: { + type: "boolean", + default: false + } + }, + additionalProperties: false, + default: {} + } + }, + additionalProperties: false + } + ], + + deprecated: true, + replacedBy: [], + + messages: { + missingJSDocComment: "Missing JSDoc comment." + } + }, + + create(context) { + const source = context.getSourceCode(); + const DEFAULT_OPTIONS = { + FunctionDeclaration: true, + MethodDefinition: false, + ClassDeclaration: false, + ArrowFunctionExpression: false, + FunctionExpression: false + }; + const options = Object.assign(DEFAULT_OPTIONS, context.options[0] && context.options[0].require); + + /** + * Report the error message + * @param {ASTNode} node node to report + * @returns {void} + */ + function report(node) { + context.report({ node, messageId: "missingJSDocComment" }); + } + + /** + * Check if the jsdoc comment is present or not. + * @param {ASTNode} node node to examine + * @returns {void} + */ + function checkJsDoc(node) { + const jsdocComment = source.getJSDocComment(node); + + if (!jsdocComment) { + report(node); + } + } + + return { + FunctionDeclaration(node) { + if (options.FunctionDeclaration) { + checkJsDoc(node); + } + }, + FunctionExpression(node) { + if ( + (options.MethodDefinition && node.parent.type === "MethodDefinition") || + (options.FunctionExpression && (node.parent.type === "VariableDeclarator" || (node.parent.type === "Property" && node === node.parent.value))) + ) { + checkJsDoc(node); + } + }, + ClassDeclaration(node) { + if (options.ClassDeclaration) { + checkJsDoc(node); + } + }, + ArrowFunctionExpression(node) { + if (options.ArrowFunctionExpression && node.parent.type === "VariableDeclarator") { + checkJsDoc(node); + } + } + }; + } +}; + +/** + * @fileoverview Rule to enforce the use of `u` flag on RegExp. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const { + CALL, + CONSTRUCT, + ReferenceTracker, + getStringIfConstant +} = require$$0__default$1['default']; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var requireUnicodeRegexp = { + meta: { + type: "suggestion", + + docs: { + description: "enforce the use of `u` flag on RegExp", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/require-unicode-regexp" + }, + + messages: { + requireUFlag: "Use the 'u' flag." + }, + + schema: [] + }, + + create(context) { + return { + "Literal[regex]"(node) { + const flags = node.regex.flags || ""; + + if (!flags.includes("u")) { + context.report({ node, messageId: "requireUFlag" }); + } + }, + + Program() { + const scope = context.getScope(); + const tracker = new ReferenceTracker(scope); + const trackMap = { + RegExp: { [CALL]: true, [CONSTRUCT]: true } + }; + + for (const { node } of tracker.iterateGlobalReferences(trackMap)) { + const flagsNode = node.arguments[1]; + const flags = getStringIfConstant(flagsNode, scope); + + if (!flagsNode || (typeof flags === "string" && !flags.includes("u"))) { + context.report({ node, messageId: "requireUFlag" }); + } + } + } + }; + } +}; + +/** + * @fileoverview Rule to flag the generator functions that does not have yield. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var requireYield = { + meta: { + type: "suggestion", + + docs: { + description: "require generator functions to contain `yield`", + category: "ECMAScript 6", + recommended: true, + url: "https://eslint.org/docs/rules/require-yield" + }, + + schema: [], + + messages: { + missingYield: "This generator function does not have 'yield'." + } + }, + + create(context) { + const stack = []; + + /** + * If the node is a generator function, start counting `yield` keywords. + * @param {Node} node A function node to check. + * @returns {void} + */ + function beginChecking(node) { + if (node.generator) { + stack.push(0); + } + } + + /** + * If the node is a generator function, end counting `yield` keywords, then + * reports result. + * @param {Node} node A function node to check. + * @returns {void} + */ + function endChecking(node) { + if (!node.generator) { + return; + } + + const countYield = stack.pop(); + + if (countYield === 0 && node.body.body.length > 0) { + context.report({ node, messageId: "missingYield" }); + } + } + + return { + FunctionDeclaration: beginChecking, + "FunctionDeclaration:exit": endChecking, + FunctionExpression: beginChecking, + "FunctionExpression:exit": endChecking, + + // Increases the count of `yield` keyword. + YieldExpression() { + + /* istanbul ignore else */ + if (stack.length > 0) { + stack[stack.length - 1] += 1; + } + } + }; + } +}; + +/** + * @fileoverview Enforce spacing between rest and spread operators and their expressions. + * @author Kai Cataldo + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var restSpreadSpacing = { + meta: { + type: "layout", + + docs: { + description: "enforce spacing between rest and spread operators and their expressions", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/rest-spread-spacing" + }, + + fixable: "whitespace", + + schema: [ + { + enum: ["always", "never"] + } + ], + + messages: { + unexpectedWhitespace: "Unexpected whitespace after {{type}} operator.", + expectedWhitespace: "Expected whitespace after {{type}} operator." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(), + alwaysSpace = context.options[0] === "always"; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Checks whitespace between rest/spread operators and their expressions + * @param {ASTNode} node The node to check + * @returns {void} + */ + function checkWhiteSpace(node) { + const operator = sourceCode.getFirstToken(node), + nextToken = sourceCode.getTokenAfter(operator), + hasWhitespace = sourceCode.isSpaceBetweenTokens(operator, nextToken); + let type; + + switch (node.type) { + case "SpreadElement": + type = "spread"; + if (node.parent.type === "ObjectExpression") { + type += " property"; + } + break; + case "RestElement": + type = "rest"; + if (node.parent.type === "ObjectPattern") { + type += " property"; + } + break; + case "ExperimentalSpreadProperty": + type = "spread property"; + break; + case "ExperimentalRestProperty": + type = "rest property"; + break; + default: + return; + } + + if (alwaysSpace && !hasWhitespace) { + context.report({ + node, + loc: operator.loc, + messageId: "expectedWhitespace", + data: { + type + }, + fix(fixer) { + return fixer.replaceTextRange([operator.range[1], nextToken.range[0]], " "); + } + }); + } else if (!alwaysSpace && hasWhitespace) { + context.report({ + node, + loc: { + start: operator.loc.end, + end: nextToken.loc.start + }, + messageId: "unexpectedWhitespace", + data: { + type + }, + fix(fixer) { + return fixer.removeRange([operator.range[1], nextToken.range[0]]); + } + }); + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + SpreadElement: checkWhiteSpace, + RestElement: checkWhiteSpace, + ExperimentalSpreadProperty: checkWhiteSpace, + ExperimentalRestProperty: checkWhiteSpace + }; + } +}; + +/** + * @fileoverview Rule to flag missing semicolons. + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var semi = { + meta: { + type: "layout", + + docs: { + description: "require or disallow semicolons instead of ASI", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/semi" + }, + + fixable: "code", + + schema: { + anyOf: [ + { + type: "array", + items: [ + { + enum: ["never"] + }, + { + type: "object", + properties: { + beforeStatementContinuationChars: { + enum: ["always", "any", "never"] + } + }, + additionalProperties: false + } + ], + minItems: 0, + maxItems: 2 + }, + { + type: "array", + items: [ + { + enum: ["always"] + }, + { + type: "object", + properties: { + omitLastInOneLineBlock: { type: "boolean" } + }, + additionalProperties: false + } + ], + minItems: 0, + maxItems: 2 + } + ] + }, + + messages: { + missingSemi: "Missing semicolon.", + extraSemi: "Extra semicolon." + } + }, + + create(context) { + + const OPT_OUT_PATTERN = /^[-[(/+`]/u; // One of [(/+-` + const options = context.options[1]; + const never = context.options[0] === "never"; + const exceptOneLine = Boolean(options && options.omitLastInOneLineBlock); + const beforeStatementContinuationChars = options && options.beforeStatementContinuationChars || "any"; + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Reports a semicolon error with appropriate location and message. + * @param {ASTNode} node The node with an extra or missing semicolon. + * @param {boolean} missing True if the semicolon is missing. + * @returns {void} + */ + function report(node, missing) { + const lastToken = sourceCode.getLastToken(node); + let messageId, + fix, + loc; + + if (!missing) { + messageId = "missingSemi"; + loc = { + start: lastToken.loc.end, + end: astUtils.getNextLocation(sourceCode, lastToken.loc.end) + }; + fix = function(fixer) { + return fixer.insertTextAfter(lastToken, ";"); + }; + } else { + messageId = "extraSemi"; + loc = lastToken.loc; + fix = function(fixer) { + + /* + * Expand the replacement range to include the surrounding + * tokens to avoid conflicting with no-extra-semi. + * https://github.com/eslint/eslint/issues/7928 + */ + return new fixTracker(fixer, sourceCode) + .retainSurroundingTokens(lastToken) + .remove(lastToken); + }; + } + + context.report({ + node, + loc, + messageId, + fix + }); + + } + + /** + * Check whether a given semicolon token is redundant. + * @param {Token} semiToken A semicolon token to check. + * @returns {boolean} `true` if the next token is `;` or `}`. + */ + function isRedundantSemi(semiToken) { + const nextToken = sourceCode.getTokenAfter(semiToken); + + return ( + !nextToken || + astUtils.isClosingBraceToken(nextToken) || + astUtils.isSemicolonToken(nextToken) + ); + } + + /** + * Check whether a given token is the closing brace of an arrow function. + * @param {Token} lastToken A token to check. + * @returns {boolean} `true` if the token is the closing brace of an arrow function. + */ + function isEndOfArrowBlock(lastToken) { + if (!astUtils.isClosingBraceToken(lastToken)) { + return false; + } + const node = sourceCode.getNodeByRangeIndex(lastToken.range[0]); + + return ( + node.type === "BlockStatement" && + node.parent.type === "ArrowFunctionExpression" + ); + } + + /** + * Check whether a given node is on the same line with the next token. + * @param {Node} node A statement node to check. + * @returns {boolean} `true` if the node is on the same line with the next token. + */ + function isOnSameLineWithNextToken(node) { + const prevToken = sourceCode.getLastToken(node, 1); + const nextToken = sourceCode.getTokenAfter(node); + + return !!nextToken && astUtils.isTokenOnSameLine(prevToken, nextToken); + } + + /** + * Check whether a given node can connect the next line if the next line is unreliable. + * @param {Node} node A statement node to check. + * @returns {boolean} `true` if the node can connect the next line. + */ + function maybeAsiHazardAfter(node) { + const t = node.type; + + if (t === "DoWhileStatement" || + t === "BreakStatement" || + t === "ContinueStatement" || + t === "DebuggerStatement" || + t === "ImportDeclaration" || + t === "ExportAllDeclaration" + ) { + return false; + } + if (t === "ReturnStatement") { + return Boolean(node.argument); + } + if (t === "ExportNamedDeclaration") { + return Boolean(node.declaration); + } + if (isEndOfArrowBlock(sourceCode.getLastToken(node, 1))) { + return false; + } + + return true; + } + + /** + * Check whether a given token can connect the previous statement. + * @param {Token} token A token to check. + * @returns {boolean} `true` if the token is one of `[`, `(`, `/`, `+`, `-`, ```, `++`, and `--`. + */ + function maybeAsiHazardBefore(token) { + return ( + Boolean(token) && + OPT_OUT_PATTERN.test(token.value) && + token.value !== "++" && + token.value !== "--" + ); + } + + /** + * Check if the semicolon of a given node is unnecessary, only true if: + * - next token is a valid statement divider (`;` or `}`). + * - next token is on a new line and the node is not connectable to the new line. + * @param {Node} node A statement node to check. + * @returns {boolean} whether the semicolon is unnecessary. + */ + function canRemoveSemicolon(node) { + if (isRedundantSemi(sourceCode.getLastToken(node))) { + return true; // `;;` or `;}` + } + if (isOnSameLineWithNextToken(node)) { + return false; // One liner. + } + if (beforeStatementContinuationChars === "never" && !maybeAsiHazardAfter(node)) { + return true; // ASI works. This statement doesn't connect to the next. + } + if (!maybeAsiHazardBefore(sourceCode.getTokenAfter(node))) { + return true; // ASI works. The next token doesn't connect to this statement. + } + + return false; + } + + /** + * Checks a node to see if it's in a one-liner block statement. + * @param {ASTNode} node The node to check. + * @returns {boolean} whether the node is in a one-liner block statement. + */ + function isOneLinerBlock(node) { + const parent = node.parent; + const nextToken = sourceCode.getTokenAfter(node); + + if (!nextToken || nextToken.value !== "}") { + return false; + } + return ( + !!parent && + parent.type === "BlockStatement" && + parent.loc.start.line === parent.loc.end.line + ); + } + + /** + * Checks a node to see if it's followed by a semicolon. + * @param {ASTNode} node The node to check. + * @returns {void} + */ + function checkForSemicolon(node) { + const isSemi = astUtils.isSemicolonToken(sourceCode.getLastToken(node)); + + if (never) { + if (isSemi && canRemoveSemicolon(node)) { + report(node, true); + } else if (!isSemi && beforeStatementContinuationChars === "always" && maybeAsiHazardBefore(sourceCode.getTokenAfter(node))) { + report(node); + } + } else { + const oneLinerBlock = (exceptOneLine && isOneLinerBlock(node)); + + if (isSemi && oneLinerBlock) { + report(node, true); + } else if (!isSemi && !oneLinerBlock) { + report(node); + } + } + } + + /** + * Checks to see if there's a semicolon after a variable declaration. + * @param {ASTNode} node The node to check. + * @returns {void} + */ + function checkForSemicolonForVariableDeclaration(node) { + const parent = node.parent; + + if ((parent.type !== "ForStatement" || parent.init !== node) && + (!/^For(?:In|Of)Statement/u.test(parent.type) || parent.left !== node) + ) { + checkForSemicolon(node); + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + VariableDeclaration: checkForSemicolonForVariableDeclaration, + ExpressionStatement: checkForSemicolon, + ReturnStatement: checkForSemicolon, + ThrowStatement: checkForSemicolon, + DoWhileStatement: checkForSemicolon, + DebuggerStatement: checkForSemicolon, + BreakStatement: checkForSemicolon, + ContinueStatement: checkForSemicolon, + ImportDeclaration: checkForSemicolon, + ExportAllDeclaration: checkForSemicolon, + ExportNamedDeclaration(node) { + if (!node.declaration) { + checkForSemicolon(node); + } + }, + ExportDefaultDeclaration(node) { + if (!/(?:Class|Function)Declaration/u.test(node.declaration.type)) { + checkForSemicolon(node); + } + } + }; + + } +}; + +/** + * @fileoverview Validates spacing before and after semicolon + * @author Mathias Schreck + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var semiSpacing = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent spacing before and after semicolons", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/semi-spacing" + }, + + fixable: "whitespace", + + schema: [ + { + type: "object", + properties: { + before: { + type: "boolean", + default: false + }, + after: { + type: "boolean", + default: true + } + }, + additionalProperties: false + } + ], + + messages: { + unexpectedWhitespaceBefore: "Unexpected whitespace before semicolon.", + unexpectedWhitespaceAfter: "Unexpected whitespace after semicolon.", + missingWhitespaceBefore: "Missing whitespace before semicolon.", + missingWhitespaceAfter: "Missing whitespace after semicolon." + } + }, + + create(context) { + + const config = context.options[0], + sourceCode = context.getSourceCode(); + let requireSpaceBefore = false, + requireSpaceAfter = true; + + if (typeof config === "object") { + requireSpaceBefore = config.before; + requireSpaceAfter = config.after; + } + + /** + * Checks if a given token has leading whitespace. + * @param {Object} token The token to check. + * @returns {boolean} True if the given token has leading space, false if not. + */ + function hasLeadingSpace(token) { + const tokenBefore = sourceCode.getTokenBefore(token); + + return tokenBefore && astUtils.isTokenOnSameLine(tokenBefore, token) && sourceCode.isSpaceBetweenTokens(tokenBefore, token); + } + + /** + * Checks if a given token has trailing whitespace. + * @param {Object} token The token to check. + * @returns {boolean} True if the given token has trailing space, false if not. + */ + function hasTrailingSpace(token) { + const tokenAfter = sourceCode.getTokenAfter(token); + + return tokenAfter && astUtils.isTokenOnSameLine(token, tokenAfter) && sourceCode.isSpaceBetweenTokens(token, tokenAfter); + } + + /** + * Checks if the given token is the last token in its line. + * @param {Token} token The token to check. + * @returns {boolean} Whether or not the token is the last in its line. + */ + function isLastTokenInCurrentLine(token) { + const tokenAfter = sourceCode.getTokenAfter(token); + + return !(tokenAfter && astUtils.isTokenOnSameLine(token, tokenAfter)); + } + + /** + * Checks if the given token is the first token in its line + * @param {Token} token The token to check. + * @returns {boolean} Whether or not the token is the first in its line. + */ + function isFirstTokenInCurrentLine(token) { + const tokenBefore = sourceCode.getTokenBefore(token); + + return !(tokenBefore && astUtils.isTokenOnSameLine(token, tokenBefore)); + } + + /** + * Checks if the next token of a given token is a closing parenthesis. + * @param {Token} token The token to check. + * @returns {boolean} Whether or not the next token of a given token is a closing parenthesis. + */ + function isBeforeClosingParen(token) { + const nextToken = sourceCode.getTokenAfter(token); + + return (nextToken && astUtils.isClosingBraceToken(nextToken) || astUtils.isClosingParenToken(nextToken)); + } + + /** + * Report location example : + * + * for unexpected space `before` + * + * var a = 'b' ; + * ^^^ + * + * for unexpected space `after` + * + * var a = 'b'; c = 10; + * ^^ + * + * Reports if the given token has invalid spacing. + * @param {Token} token The semicolon token to check. + * @param {ASTNode} node The corresponding node of the token. + * @returns {void} + */ + function checkSemicolonSpacing(token, node) { + if (astUtils.isSemicolonToken(token)) { + if (hasLeadingSpace(token)) { + if (!requireSpaceBefore) { + const tokenBefore = sourceCode.getTokenBefore(token); + const loc = { + start: tokenBefore.loc.end, + end: token.loc.start + }; + + context.report({ + node, + loc, + messageId: "unexpectedWhitespaceBefore", + fix(fixer) { + + return fixer.removeRange([tokenBefore.range[1], token.range[0]]); + } + }); + } + } else { + if (requireSpaceBefore) { + const loc = token.loc; + + context.report({ + node, + loc, + messageId: "missingWhitespaceBefore", + fix(fixer) { + return fixer.insertTextBefore(token, " "); + } + }); + } + } + + if (!isFirstTokenInCurrentLine(token) && !isLastTokenInCurrentLine(token) && !isBeforeClosingParen(token)) { + if (hasTrailingSpace(token)) { + if (!requireSpaceAfter) { + const tokenAfter = sourceCode.getTokenAfter(token); + const loc = { + start: token.loc.end, + end: tokenAfter.loc.start + }; + + context.report({ + node, + loc, + messageId: "unexpectedWhitespaceAfter", + fix(fixer) { + + return fixer.removeRange([token.range[1], tokenAfter.range[0]]); + } + }); + } + } else { + if (requireSpaceAfter) { + const loc = token.loc; + + context.report({ + node, + loc, + messageId: "missingWhitespaceAfter", + fix(fixer) { + return fixer.insertTextAfter(token, " "); + } + }); + } + } + } + } + } + + /** + * Checks the spacing of the semicolon with the assumption that the last token is the semicolon. + * @param {ASTNode} node The node to check. + * @returns {void} + */ + function checkNode(node) { + const token = sourceCode.getLastToken(node); + + checkSemicolonSpacing(token, node); + } + + return { + VariableDeclaration: checkNode, + ExpressionStatement: checkNode, + BreakStatement: checkNode, + ContinueStatement: checkNode, + DebuggerStatement: checkNode, + DoWhileStatement: checkNode, + ReturnStatement: checkNode, + ThrowStatement: checkNode, + ImportDeclaration: checkNode, + ExportNamedDeclaration: checkNode, + ExportAllDeclaration: checkNode, + ExportDefaultDeclaration: checkNode, + ForStatement(node) { + if (node.init) { + checkSemicolonSpacing(sourceCode.getTokenAfter(node.init), node); + } + + if (node.test) { + checkSemicolonSpacing(sourceCode.getTokenAfter(node.test), node); + } + } + }; + } +}; + +/** + * @fileoverview Rule to enforce location of semicolons. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +const SELECTOR = `:matches(${ + [ + "BreakStatement", "ContinueStatement", "DebuggerStatement", + "DoWhileStatement", "ExportAllDeclaration", + "ExportDefaultDeclaration", "ExportNamedDeclaration", + "ExpressionStatement", "ImportDeclaration", "ReturnStatement", + "ThrowStatement", "VariableDeclaration" + ].join(",") +})`; + +/** + * Get the child node list of a given node. + * This returns `Program#body`, `BlockStatement#body`, or `SwitchCase#consequent`. + * This is used to check whether a node is the first/last child. + * @param {Node} node A node to get child node list. + * @returns {Node[]|null} The child node list. + */ +function getChildren(node) { + const t = node.type; + + if (t === "BlockStatement" || t === "Program") { + return node.body; + } + if (t === "SwitchCase") { + return node.consequent; + } + return null; +} + +/** + * Check whether a given node is the last statement in the parent block. + * @param {Node} node A node to check. + * @returns {boolean} `true` if the node is the last statement in the parent block. + */ +function isLastChild(node) { + const t = node.parent.type; + + if (t === "IfStatement" && node.parent.consequent === node && node.parent.alternate) { // before `else` keyword. + return true; + } + if (t === "DoWhileStatement") { // before `while` keyword. + return true; + } + const nodeList = getChildren(node.parent); + + return nodeList !== null && nodeList[nodeList.length - 1] === node; // before `}` or etc. +} + +var semiStyle = { + meta: { + type: "layout", + + docs: { + description: "enforce location of semicolons", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/semi-style" + }, + + schema: [{ enum: ["last", "first"] }], + fixable: "whitespace", + + messages: { + expectedSemiColon: "Expected this semicolon to be at {{pos}}." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const option = context.options[0] || "last"; + + /** + * Check the given semicolon token. + * @param {Token} semiToken The semicolon token to check. + * @param {"first"|"last"} expected The expected location to check. + * @returns {void} + */ + function check(semiToken, expected) { + const prevToken = sourceCode.getTokenBefore(semiToken); + const nextToken = sourceCode.getTokenAfter(semiToken); + const prevIsSameLine = !prevToken || astUtils.isTokenOnSameLine(prevToken, semiToken); + const nextIsSameLine = !nextToken || astUtils.isTokenOnSameLine(semiToken, nextToken); + + if ((expected === "last" && !prevIsSameLine) || (expected === "first" && !nextIsSameLine)) { + context.report({ + loc: semiToken.loc, + messageId: "expectedSemiColon", + data: { + pos: (expected === "last") + ? "the end of the previous line" + : "the beginning of the next line" + }, + fix(fixer) { + if (prevToken && nextToken && sourceCode.commentsExistBetween(prevToken, nextToken)) { + return null; + } + + const start = prevToken ? prevToken.range[1] : semiToken.range[0]; + const end = nextToken ? nextToken.range[0] : semiToken.range[1]; + const text = (expected === "last") ? ";\n" : "\n;"; + + return fixer.replaceTextRange([start, end], text); + } + }); + } + } + + return { + [SELECTOR](node) { + if (option === "first" && isLastChild(node)) { + return; + } + + const lastToken = sourceCode.getLastToken(node); + + if (astUtils.isSemicolonToken(lastToken)) { + check(lastToken, option); + } + }, + + ForStatement(node) { + const firstSemi = node.init && sourceCode.getTokenAfter(node.init, astUtils.isSemicolonToken); + const secondSemi = node.test && sourceCode.getTokenAfter(node.test, astUtils.isSemicolonToken); + + if (firstSemi) { + check(firstSemi, "last"); + } + if (secondSemi) { + check(secondSemi, "last"); + } + } + }; + } +}; + +/** + * @fileoverview Rule to require sorting of import declarations + * @author Christian Schuller + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var sortImports = { + meta: { + type: "suggestion", + + docs: { + description: "enforce sorted import declarations within modules", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/sort-imports" + }, + + schema: [ + { + type: "object", + properties: { + ignoreCase: { + type: "boolean", + default: false + }, + memberSyntaxSortOrder: { + type: "array", + items: { + enum: ["none", "all", "multiple", "single"] + }, + uniqueItems: true, + minItems: 4, + maxItems: 4 + }, + ignoreDeclarationSort: { + type: "boolean", + default: false + }, + ignoreMemberSort: { + type: "boolean", + default: false + }, + allowSeparatedGroups: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + fixable: "code", + + messages: { + sortImportsAlphabetically: "Imports should be sorted alphabetically.", + sortMembersAlphabetically: "Member '{{memberName}}' of the import declaration should be sorted alphabetically.", + unexpectedSyntaxOrder: "Expected '{{syntaxA}}' syntax before '{{syntaxB}}' syntax." + } + }, + + create(context) { + + const configuration = context.options[0] || {}, + ignoreCase = configuration.ignoreCase || false, + ignoreDeclarationSort = configuration.ignoreDeclarationSort || false, + ignoreMemberSort = configuration.ignoreMemberSort || false, + memberSyntaxSortOrder = configuration.memberSyntaxSortOrder || ["none", "all", "multiple", "single"], + allowSeparatedGroups = configuration.allowSeparatedGroups || false, + sourceCode = context.getSourceCode(); + let previousDeclaration = null; + + /** + * Gets the used member syntax style. + * + * import "my-module.js" --> none + * import * as myModule from "my-module.js" --> all + * import {myMember} from "my-module.js" --> single + * import {foo, bar} from "my-module.js" --> multiple + * @param {ASTNode} node the ImportDeclaration node. + * @returns {string} used member parameter style, ["all", "multiple", "single"] + */ + function usedMemberSyntax(node) { + if (node.specifiers.length === 0) { + return "none"; + } + if (node.specifiers[0].type === "ImportNamespaceSpecifier") { + return "all"; + } + if (node.specifiers.length === 1) { + return "single"; + } + return "multiple"; + + } + + /** + * Gets the group by member parameter index for given declaration. + * @param {ASTNode} node the ImportDeclaration node. + * @returns {number} the declaration group by member index. + */ + function getMemberParameterGroupIndex(node) { + return memberSyntaxSortOrder.indexOf(usedMemberSyntax(node)); + } + + /** + * Gets the local name of the first imported module. + * @param {ASTNode} node the ImportDeclaration node. + * @returns {?string} the local name of the first imported module. + */ + function getFirstLocalMemberName(node) { + if (node.specifiers[0]) { + return node.specifiers[0].local.name; + } + return null; + + } + + /** + * Calculates number of lines between two nodes. It is assumed that the given `left` node appears before + * the given `right` node in the source code. Lines are counted from the end of the `left` node till the + * start of the `right` node. If the given nodes are on the same line, it returns `0`, same as if they were + * on two consecutive lines. + * @param {ASTNode} left node that appears before the given `right` node. + * @param {ASTNode} right node that appears after the given `left` node. + * @returns {number} number of lines between nodes. + */ + function getNumberOfLinesBetween(left, right) { + return Math.max(right.loc.start.line - left.loc.end.line - 1, 0); + } + + return { + ImportDeclaration(node) { + if (!ignoreDeclarationSort) { + if ( + previousDeclaration && + allowSeparatedGroups && + getNumberOfLinesBetween(previousDeclaration, node) > 0 + ) { + + // reset declaration sort + previousDeclaration = null; + } + + if (previousDeclaration) { + const currentMemberSyntaxGroupIndex = getMemberParameterGroupIndex(node), + previousMemberSyntaxGroupIndex = getMemberParameterGroupIndex(previousDeclaration); + let currentLocalMemberName = getFirstLocalMemberName(node), + previousLocalMemberName = getFirstLocalMemberName(previousDeclaration); + + if (ignoreCase) { + previousLocalMemberName = previousLocalMemberName && previousLocalMemberName.toLowerCase(); + currentLocalMemberName = currentLocalMemberName && currentLocalMemberName.toLowerCase(); + } + + /* + * When the current declaration uses a different member syntax, + * then check if the ordering is correct. + * Otherwise, make a default string compare (like rule sort-vars to be consistent) of the first used local member name. + */ + if (currentMemberSyntaxGroupIndex !== previousMemberSyntaxGroupIndex) { + if (currentMemberSyntaxGroupIndex < previousMemberSyntaxGroupIndex) { + context.report({ + node, + messageId: "unexpectedSyntaxOrder", + data: { + syntaxA: memberSyntaxSortOrder[currentMemberSyntaxGroupIndex], + syntaxB: memberSyntaxSortOrder[previousMemberSyntaxGroupIndex] + } + }); + } + } else { + if (previousLocalMemberName && + currentLocalMemberName && + currentLocalMemberName < previousLocalMemberName + ) { + context.report({ + node, + messageId: "sortImportsAlphabetically" + }); + } + } + } + + previousDeclaration = node; + } + + if (!ignoreMemberSort) { + const importSpecifiers = node.specifiers.filter(specifier => specifier.type === "ImportSpecifier"); + const getSortableName = ignoreCase ? specifier => specifier.local.name.toLowerCase() : specifier => specifier.local.name; + const firstUnsortedIndex = importSpecifiers.map(getSortableName).findIndex((name, index, array) => array[index - 1] > name); + + if (firstUnsortedIndex !== -1) { + context.report({ + node: importSpecifiers[firstUnsortedIndex], + messageId: "sortMembersAlphabetically", + data: { memberName: importSpecifiers[firstUnsortedIndex].local.name }, + fix(fixer) { + if (importSpecifiers.some(specifier => + sourceCode.getCommentsBefore(specifier).length || sourceCode.getCommentsAfter(specifier).length)) { + + // If there are comments in the ImportSpecifier list, don't rearrange the specifiers. + return null; + } + + return fixer.replaceTextRange( + [importSpecifiers[0].range[0], importSpecifiers[importSpecifiers.length - 1].range[1]], + importSpecifiers + + // Clone the importSpecifiers array to avoid mutating it + .slice() + + // Sort the array into the desired order + .sort((specifierA, specifierB) => { + const aName = getSortableName(specifierA); + const bName = getSortableName(specifierB); + + return aName > bName ? 1 : -1; + }) + + // Build a string out of the sorted list of import specifiers and the text between the originals + .reduce((sourceText, specifier, index) => { + const textAfterSpecifier = index === importSpecifiers.length - 1 + ? "" + : sourceCode.getText().slice(importSpecifiers[index].range[1], importSpecifiers[index + 1].range[0]); + + return sourceText + sourceCode.getText(specifier) + textAfterSpecifier; + }, "") + ); + } + }); + } + } + } + }; + } +}; + +/** + * @fileoverview Rule to require object keys to be sorted + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Gets the property name of the given `Property` node. + * + * - If the property's key is an `Identifier` node, this returns the key's name + * whether it's a computed property or not. + * - If the property has a static name, this returns the static name. + * - Otherwise, this returns null. + * @param {ASTNode} node The `Property` node to get. + * @returns {string|null} The property name or null. + * @private + */ +function getPropertyName(node) { + const staticName = astUtils.getStaticPropertyName(node); + + if (staticName !== null) { + return staticName; + } + + return node.key.name || null; +} + +/** + * Functions which check that the given 2 names are in specific order. + * + * Postfix `I` is meant insensitive. + * Postfix `N` is meant natural. + * @private + */ +const isValidOrders = { + asc(a, b) { + return a <= b; + }, + ascI(a, b) { + return a.toLowerCase() <= b.toLowerCase(); + }, + ascN(a, b) { + return naturalCompare__default['default'](a, b) <= 0; + }, + ascIN(a, b) { + return naturalCompare__default['default'](a.toLowerCase(), b.toLowerCase()) <= 0; + }, + desc(a, b) { + return isValidOrders.asc(b, a); + }, + descI(a, b) { + return isValidOrders.ascI(b, a); + }, + descN(a, b) { + return isValidOrders.ascN(b, a); + }, + descIN(a, b) { + return isValidOrders.ascIN(b, a); + } +}; + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var sortKeys = { + meta: { + type: "suggestion", + + docs: { + description: "require object keys to be sorted", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/sort-keys" + }, + + schema: [ + { + enum: ["asc", "desc"] + }, + { + type: "object", + properties: { + caseSensitive: { + type: "boolean", + default: true + }, + natural: { + type: "boolean", + default: false + }, + minKeys: { + type: "integer", + minimum: 2, + default: 2 + } + }, + additionalProperties: false + } + ], + + messages: { + sortKeys: "Expected object keys to be in {{natural}}{{insensitive}}{{order}}ending order. '{{thisName}}' should be before '{{prevName}}'." + } + }, + + create(context) { + + // Parse options. + const order = context.options[0] || "asc"; + const options = context.options[1]; + const insensitive = options && options.caseSensitive === false; + const natural = options && options.natural; + const minKeys = options && options.minKeys; + const isValidOrder = isValidOrders[ + order + (insensitive ? "I" : "") + (natural ? "N" : "") + ]; + + // The stack to save the previous property's name for each object literals. + let stack = null; + + return { + ObjectExpression(node) { + stack = { + upper: stack, + prevName: null, + numKeys: node.properties.length + }; + }, + + "ObjectExpression:exit"() { + stack = stack.upper; + }, + + SpreadElement(node) { + if (node.parent.type === "ObjectExpression") { + stack.prevName = null; + } + }, + + Property(node) { + if (node.parent.type === "ObjectPattern") { + return; + } + + const prevName = stack.prevName; + const numKeys = stack.numKeys; + const thisName = getPropertyName(node); + + if (thisName !== null) { + stack.prevName = thisName; + } + + if (prevName === null || thisName === null || numKeys < minKeys) { + return; + } + + if (!isValidOrder(prevName, thisName)) { + context.report({ + node, + loc: node.key.loc, + messageId: "sortKeys", + data: { + thisName, + prevName, + order, + insensitive: insensitive ? "insensitive " : "", + natural: natural ? "natural " : "" + } + }); + } + } + }; + } +}; + +/** + * @fileoverview Rule to require sorting of variables within a single Variable Declaration block + * @author Ilya Volodin + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var sortVars = { + meta: { + type: "suggestion", + + docs: { + description: "require variables within the same declaration block to be sorted", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/sort-vars" + }, + + schema: [ + { + type: "object", + properties: { + ignoreCase: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + fixable: "code", + + messages: { + sortVars: "Variables within the same declaration block should be sorted alphabetically." + } + }, + + create(context) { + + const configuration = context.options[0] || {}, + ignoreCase = configuration.ignoreCase || false, + sourceCode = context.getSourceCode(); + + return { + VariableDeclaration(node) { + const idDeclarations = node.declarations.filter(decl => decl.id.type === "Identifier"); + const getSortableName = ignoreCase ? decl => decl.id.name.toLowerCase() : decl => decl.id.name; + const unfixable = idDeclarations.some(decl => decl.init !== null && decl.init.type !== "Literal"); + let fixed = false; + + idDeclarations.slice(1).reduce((memo, decl) => { + const lastVariableName = getSortableName(memo), + currentVariableName = getSortableName(decl); + + if (currentVariableName < lastVariableName) { + context.report({ + node: decl, + messageId: "sortVars", + fix(fixer) { + if (unfixable || fixed) { + return null; + } + return fixer.replaceTextRange( + [idDeclarations[0].range[0], idDeclarations[idDeclarations.length - 1].range[1]], + idDeclarations + + // Clone the idDeclarations array to avoid mutating it + .slice() + + // Sort the array into the desired order + .sort((declA, declB) => { + const aName = getSortableName(declA); + const bName = getSortableName(declB); + + return aName > bName ? 1 : -1; + }) + + // Build a string out of the sorted list of identifier declarations and the text between the originals + .reduce((sourceText, identifier, index) => { + const textAfterIdentifier = index === idDeclarations.length - 1 + ? "" + : sourceCode.getText().slice(idDeclarations[index].range[1], idDeclarations[index + 1].range[0]); + + return sourceText + sourceCode.getText(identifier) + textAfterIdentifier; + }, "") + + ); + } + }); + fixed = true; + return memo; + } + return decl; + + }, idDeclarations[0]); + } + }; + } +}; + +/** + * @fileoverview A rule to ensure whitespace before blocks. + * @author Mathias Schreck + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Checks whether the given node represents the body of a function. + * @param {ASTNode} node the node to check. + * @returns {boolean} `true` if the node is function body. + */ +function isFunctionBody(node) { + const parent = node.parent; + + return ( + node.type === "BlockStatement" && + astUtils.isFunction(parent) && + parent.body === node + ); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var spaceBeforeBlocks = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent spacing before blocks", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/space-before-blocks" + }, + + fixable: "whitespace", + + schema: [ + { + oneOf: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + keywords: { + enum: ["always", "never", "off"] + }, + functions: { + enum: ["always", "never", "off"] + }, + classes: { + enum: ["always", "never", "off"] + } + }, + additionalProperties: false + } + ] + } + ], + + messages: { + unexpectedSpace: "Unexpected space before opening brace.", + missingSpace: "Missing space before opening brace." + } + }, + + create(context) { + const config = context.options[0], + sourceCode = context.getSourceCode(); + let alwaysFunctions = true, + alwaysKeywords = true, + alwaysClasses = true, + neverFunctions = false, + neverKeywords = false, + neverClasses = false; + + if (typeof config === "object") { + alwaysFunctions = config.functions === "always"; + alwaysKeywords = config.keywords === "always"; + alwaysClasses = config.classes === "always"; + neverFunctions = config.functions === "never"; + neverKeywords = config.keywords === "never"; + neverClasses = config.classes === "never"; + } else if (config === "never") { + alwaysFunctions = false; + alwaysKeywords = false; + alwaysClasses = false; + neverFunctions = true; + neverKeywords = true; + neverClasses = true; + } + + /** + * Checks whether the spacing before the given block is already controlled by another rule: + * - `arrow-spacing` checks spaces after `=>`. + * - `keyword-spacing` checks spaces after keywords in certain contexts. + * @param {Token} precedingToken first token before the block. + * @param {ASTNode|Token} node `BlockStatement` node or `{` token of a `SwitchStatement` node. + * @returns {boolean} `true` if requiring or disallowing spaces before the given block could produce conflicts with other rules. + */ + function isConflicted(precedingToken, node) { + return astUtils.isArrowToken(precedingToken) || + astUtils.isKeywordToken(precedingToken) && !isFunctionBody(node); + } + + /** + * Checks the given BlockStatement node has a preceding space if it doesn’t start on a new line. + * @param {ASTNode|Token} node The AST node of a BlockStatement. + * @returns {void} undefined. + */ + function checkPrecedingSpace(node) { + const precedingToken = sourceCode.getTokenBefore(node); + + if (precedingToken && !isConflicted(precedingToken, node) && astUtils.isTokenOnSameLine(precedingToken, node)) { + const hasSpace = sourceCode.isSpaceBetweenTokens(precedingToken, node); + let requireSpace; + let requireNoSpace; + + if (isFunctionBody(node)) { + requireSpace = alwaysFunctions; + requireNoSpace = neverFunctions; + } else if (node.type === "ClassBody") { + requireSpace = alwaysClasses; + requireNoSpace = neverClasses; + } else { + requireSpace = alwaysKeywords; + requireNoSpace = neverKeywords; + } + + if (requireSpace && !hasSpace) { + context.report({ + node, + messageId: "missingSpace", + fix(fixer) { + return fixer.insertTextBefore(node, " "); + } + }); + } else if (requireNoSpace && hasSpace) { + context.report({ + node, + messageId: "unexpectedSpace", + fix(fixer) { + return fixer.removeRange([precedingToken.range[1], node.range[0]]); + } + }); + } + } + } + + /** + * Checks if the CaseBlock of an given SwitchStatement node has a preceding space. + * @param {ASTNode} node The node of a SwitchStatement. + * @returns {void} undefined. + */ + function checkSpaceBeforeCaseBlock(node) { + const cases = node.cases; + let openingBrace; + + if (cases.length > 0) { + openingBrace = sourceCode.getTokenBefore(cases[0]); + } else { + openingBrace = sourceCode.getLastToken(node, 1); + } + + checkPrecedingSpace(openingBrace); + } + + return { + BlockStatement: checkPrecedingSpace, + ClassBody: checkPrecedingSpace, + SwitchStatement: checkSpaceBeforeCaseBlock + }; + + } +}; + +/** + * @fileoverview Rule to validate spacing before function paren. + * @author Mathias Schreck + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var spaceBeforeFunctionParen = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent spacing before `function` definition opening parenthesis", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/space-before-function-paren" + }, + + fixable: "whitespace", + + schema: [ + { + oneOf: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + anonymous: { + enum: ["always", "never", "ignore"] + }, + named: { + enum: ["always", "never", "ignore"] + }, + asyncArrow: { + enum: ["always", "never", "ignore"] + } + }, + additionalProperties: false + } + ] + } + ], + + messages: { + unexpectedSpace: "Unexpected space before function parentheses.", + missingSpace: "Missing space before function parentheses." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const baseConfig = typeof context.options[0] === "string" ? context.options[0] : "always"; + const overrideConfig = typeof context.options[0] === "object" ? context.options[0] : {}; + + /** + * Determines whether a function has a name. + * @param {ASTNode} node The function node. + * @returns {boolean} Whether the function has a name. + */ + function isNamedFunction(node) { + if (node.id) { + return true; + } + + const parent = node.parent; + + return parent.type === "MethodDefinition" || + (parent.type === "Property" && + ( + parent.kind === "get" || + parent.kind === "set" || + parent.method + ) + ); + } + + /** + * Gets the config for a given function + * @param {ASTNode} node The function node + * @returns {string} "always", "never", or "ignore" + */ + function getConfigForFunction(node) { + if (node.type === "ArrowFunctionExpression") { + + // Always ignore non-async functions and arrow functions without parens, e.g. async foo => bar + if (node.async && astUtils.isOpeningParenToken(sourceCode.getFirstToken(node, { skip: 1 }))) { + return overrideConfig.asyncArrow || baseConfig; + } + } else if (isNamedFunction(node)) { + return overrideConfig.named || baseConfig; + + // `generator-star-spacing` should warn anonymous generators. E.g. `function* () {}` + } else if (!node.generator) { + return overrideConfig.anonymous || baseConfig; + } + + return "ignore"; + } + + /** + * Checks the parens of a function node + * @param {ASTNode} node A function node + * @returns {void} + */ + function checkFunction(node) { + const functionConfig = getConfigForFunction(node); + + if (functionConfig === "ignore") { + return; + } + + const rightToken = sourceCode.getFirstToken(node, astUtils.isOpeningParenToken); + const leftToken = sourceCode.getTokenBefore(rightToken); + const hasSpacing = sourceCode.isSpaceBetweenTokens(leftToken, rightToken); + + if (hasSpacing && functionConfig === "never") { + context.report({ + node, + loc: { + start: leftToken.loc.end, + end: rightToken.loc.start + }, + messageId: "unexpectedSpace", + fix(fixer) { + const comments = sourceCode.getCommentsBefore(rightToken); + + // Don't fix anything if there's a single line comment between the left and the right token + if (comments.some(comment => comment.type === "Line")) { + return null; + } + return fixer.replaceTextRange( + [leftToken.range[1], rightToken.range[0]], + comments.reduce((text, comment) => text + sourceCode.getText(comment), "") + ); + } + }); + } else if (!hasSpacing && functionConfig === "always") { + context.report({ + node, + loc: rightToken.loc, + messageId: "missingSpace", + fix: fixer => fixer.insertTextAfter(leftToken, " ") + }); + } + } + + return { + ArrowFunctionExpression: checkFunction, + FunctionDeclaration: checkFunction, + FunctionExpression: checkFunction + }; + } +}; + +/** + * @fileoverview Disallows or enforces spaces inside of parentheses. + * @author Jonathan Rajavuori + */ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var spaceInParens = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent spacing inside parentheses", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/space-in-parens" + }, + + fixable: "whitespace", + + schema: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + exceptions: { + type: "array", + items: { + enum: ["{}", "[]", "()", "empty"] + }, + uniqueItems: true + } + }, + additionalProperties: false + } + ], + + messages: { + missingOpeningSpace: "There must be a space after this paren.", + missingClosingSpace: "There must be a space before this paren.", + rejectedOpeningSpace: "There should be no space after this paren.", + rejectedClosingSpace: "There should be no space before this paren." + } + }, + + create(context) { + const ALWAYS = context.options[0] === "always", + exceptionsArrayOptions = (context.options[1] && context.options[1].exceptions) || [], + options = {}; + + let exceptions; + + if (exceptionsArrayOptions.length) { + options.braceException = exceptionsArrayOptions.includes("{}"); + options.bracketException = exceptionsArrayOptions.includes("[]"); + options.parenException = exceptionsArrayOptions.includes("()"); + options.empty = exceptionsArrayOptions.includes("empty"); + } + + /** + * Produces an object with the opener and closer exception values + * @returns {Object} `openers` and `closers` exception values + * @private + */ + function getExceptions() { + const openers = [], + closers = []; + + if (options.braceException) { + openers.push("{"); + closers.push("}"); + } + + if (options.bracketException) { + openers.push("["); + closers.push("]"); + } + + if (options.parenException) { + openers.push("("); + closers.push(")"); + } + + if (options.empty) { + openers.push(")"); + closers.push("("); + } + + return { + openers, + closers + }; + } + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + const sourceCode = context.getSourceCode(); + + /** + * Determines if a token is one of the exceptions for the opener paren + * @param {Object} token The token to check + * @returns {boolean} True if the token is one of the exceptions for the opener paren + */ + function isOpenerException(token) { + return exceptions.openers.includes(token.value); + } + + /** + * Determines if a token is one of the exceptions for the closer paren + * @param {Object} token The token to check + * @returns {boolean} True if the token is one of the exceptions for the closer paren + */ + function isCloserException(token) { + return exceptions.closers.includes(token.value); + } + + /** + * Determines if an opening paren is immediately followed by a required space + * @param {Object} openingParenToken The paren token + * @param {Object} tokenAfterOpeningParen The token after it + * @returns {boolean} True if the opening paren is missing a required space + */ + function openerMissingSpace(openingParenToken, tokenAfterOpeningParen) { + if (sourceCode.isSpaceBetweenTokens(openingParenToken, tokenAfterOpeningParen)) { + return false; + } + + if (!options.empty && astUtils.isClosingParenToken(tokenAfterOpeningParen)) { + return false; + } + + if (ALWAYS) { + return !isOpenerException(tokenAfterOpeningParen); + } + return isOpenerException(tokenAfterOpeningParen); + } + + /** + * Determines if an opening paren is immediately followed by a disallowed space + * @param {Object} openingParenToken The paren token + * @param {Object} tokenAfterOpeningParen The token after it + * @returns {boolean} True if the opening paren has a disallowed space + */ + function openerRejectsSpace(openingParenToken, tokenAfterOpeningParen) { + if (!astUtils.isTokenOnSameLine(openingParenToken, tokenAfterOpeningParen)) { + return false; + } + + if (tokenAfterOpeningParen.type === "Line") { + return false; + } + + if (!sourceCode.isSpaceBetweenTokens(openingParenToken, tokenAfterOpeningParen)) { + return false; + } + + if (ALWAYS) { + return isOpenerException(tokenAfterOpeningParen); + } + return !isOpenerException(tokenAfterOpeningParen); + } + + /** + * Determines if a closing paren is immediately preceded by a required space + * @param {Object} tokenBeforeClosingParen The token before the paren + * @param {Object} closingParenToken The paren token + * @returns {boolean} True if the closing paren is missing a required space + */ + function closerMissingSpace(tokenBeforeClosingParen, closingParenToken) { + if (sourceCode.isSpaceBetweenTokens(tokenBeforeClosingParen, closingParenToken)) { + return false; + } + + if (!options.empty && astUtils.isOpeningParenToken(tokenBeforeClosingParen)) { + return false; + } + + if (ALWAYS) { + return !isCloserException(tokenBeforeClosingParen); + } + return isCloserException(tokenBeforeClosingParen); + } + + /** + * Determines if a closer paren is immediately preceded by a disallowed space + * @param {Object} tokenBeforeClosingParen The token before the paren + * @param {Object} closingParenToken The paren token + * @returns {boolean} True if the closing paren has a disallowed space + */ + function closerRejectsSpace(tokenBeforeClosingParen, closingParenToken) { + if (!astUtils.isTokenOnSameLine(tokenBeforeClosingParen, closingParenToken)) { + return false; + } + + if (!sourceCode.isSpaceBetweenTokens(tokenBeforeClosingParen, closingParenToken)) { + return false; + } + + if (ALWAYS) { + return isCloserException(tokenBeforeClosingParen); + } + return !isCloserException(tokenBeforeClosingParen); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + Program: function checkParenSpaces(node) { + exceptions = getExceptions(); + const tokens = sourceCode.tokensAndComments; + + tokens.forEach((token, i) => { + const prevToken = tokens[i - 1]; + const nextToken = tokens[i + 1]; + + // if token is not an opening or closing paren token, do nothing + if (!astUtils.isOpeningParenToken(token) && !astUtils.isClosingParenToken(token)) { + return; + } + + // if token is an opening paren and is not followed by a required space + if (token.value === "(" && openerMissingSpace(token, nextToken)) { + context.report({ + node, + loc: token.loc, + messageId: "missingOpeningSpace", + fix(fixer) { + return fixer.insertTextAfter(token, " "); + } + }); + } + + // if token is an opening paren and is followed by a disallowed space + if (token.value === "(" && openerRejectsSpace(token, nextToken)) { + context.report({ + node, + loc: { start: token.loc.end, end: nextToken.loc.start }, + messageId: "rejectedOpeningSpace", + fix(fixer) { + return fixer.removeRange([token.range[1], nextToken.range[0]]); + } + }); + } + + // if token is a closing paren and is not preceded by a required space + if (token.value === ")" && closerMissingSpace(prevToken, token)) { + context.report({ + node, + loc: token.loc, + messageId: "missingClosingSpace", + fix(fixer) { + return fixer.insertTextBefore(token, " "); + } + }); + } + + // if token is a closing paren and is preceded by a disallowed space + if (token.value === ")" && closerRejectsSpace(prevToken, token)) { + context.report({ + node, + loc: { start: prevToken.loc.end, end: token.loc.start }, + messageId: "rejectedClosingSpace", + fix(fixer) { + return fixer.removeRange([prevToken.range[1], token.range[0]]); + } + }); + } + }); + } + }; + } +}; + +/** + * @fileoverview Require spaces around infix operators + * @author Michael Ficarra + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var spaceInfixOps = { + meta: { + type: "layout", + + docs: { + description: "require spacing around infix operators", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/space-infix-ops" + }, + + fixable: "whitespace", + + schema: [ + { + type: "object", + properties: { + int32Hint: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + messages: { + missingSpace: "Operator '{{operator}}' must be spaced." + } + }, + + create(context) { + const int32Hint = context.options[0] ? context.options[0].int32Hint === true : false; + const sourceCode = context.getSourceCode(); + + /** + * Returns the first token which violates the rule + * @param {ASTNode} left The left node of the main node + * @param {ASTNode} right The right node of the main node + * @param {string} op The operator of the main node + * @returns {Object} The violator token or null + * @private + */ + function getFirstNonSpacedToken(left, right, op) { + const operator = sourceCode.getFirstTokenBetween(left, right, token => token.value === op); + const prev = sourceCode.getTokenBefore(operator); + const next = sourceCode.getTokenAfter(operator); + + if (!sourceCode.isSpaceBetweenTokens(prev, operator) || !sourceCode.isSpaceBetweenTokens(operator, next)) { + return operator; + } + + return null; + } + + /** + * Reports an AST node as a rule violation + * @param {ASTNode} mainNode The node to report + * @param {Object} culpritToken The token which has a problem + * @returns {void} + * @private + */ + function report(mainNode, culpritToken) { + context.report({ + node: mainNode, + loc: culpritToken.loc, + messageId: "missingSpace", + data: { + operator: culpritToken.value + }, + fix(fixer) { + const previousToken = sourceCode.getTokenBefore(culpritToken); + const afterToken = sourceCode.getTokenAfter(culpritToken); + let fixString = ""; + + if (culpritToken.range[0] - previousToken.range[1] === 0) { + fixString = " "; + } + + fixString += culpritToken.value; + + if (afterToken.range[0] - culpritToken.range[1] === 0) { + fixString += " "; + } + + return fixer.replaceText(culpritToken, fixString); + } + }); + } + + /** + * Check if the node is binary then report + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function checkBinary(node) { + const leftNode = (node.left.typeAnnotation) ? node.left.typeAnnotation : node.left; + const rightNode = node.right; + + // search for = in AssignmentPattern nodes + const operator = node.operator || "="; + + const nonSpacedNode = getFirstNonSpacedToken(leftNode, rightNode, operator); + + if (nonSpacedNode) { + if (!(int32Hint && sourceCode.getText(node).endsWith("|0"))) { + report(node, nonSpacedNode); + } + } + } + + /** + * Check if the node is conditional + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function checkConditional(node) { + const nonSpacedConsequentNode = getFirstNonSpacedToken(node.test, node.consequent, "?"); + const nonSpacedAlternateNode = getFirstNonSpacedToken(node.consequent, node.alternate, ":"); + + if (nonSpacedConsequentNode) { + report(node, nonSpacedConsequentNode); + } + + if (nonSpacedAlternateNode) { + report(node, nonSpacedAlternateNode); + } + } + + /** + * Check if the node is a variable + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function checkVar(node) { + const leftNode = (node.id.typeAnnotation) ? node.id.typeAnnotation : node.id; + const rightNode = node.init; + + if (rightNode) { + const nonSpacedNode = getFirstNonSpacedToken(leftNode, rightNode, "="); + + if (nonSpacedNode) { + report(node, nonSpacedNode); + } + } + } + + return { + AssignmentExpression: checkBinary, + AssignmentPattern: checkBinary, + BinaryExpression: checkBinary, + LogicalExpression: checkBinary, + ConditionalExpression: checkConditional, + VariableDeclarator: checkVar + }; + + } +}; + +/** + * @fileoverview This rule should require or disallow spaces before or after unary operations. + * @author Marcin Kumorek + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var spaceUnaryOps = { + meta: { + type: "layout", + + docs: { + description: "enforce consistent spacing before or after unary operators", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/space-unary-ops" + }, + + fixable: "whitespace", + + schema: [ + { + type: "object", + properties: { + words: { + type: "boolean", + default: true + }, + nonwords: { + type: "boolean", + default: false + }, + overrides: { + type: "object", + additionalProperties: { + type: "boolean" + } + } + }, + additionalProperties: false + } + ], + messages: { + unexpectedBefore: "Unexpected space before unary operator '{{operator}}'.", + unexpectedAfter: "Unexpected space after unary operator '{{operator}}'.", + unexpectedAfterWord: "Unexpected space after unary word operator '{{word}}'.", + wordOperator: "Unary word operator '{{word}}' must be followed by whitespace.", + operator: "Unary operator '{{operator}}' must be followed by whitespace.", + beforeUnaryExpressions: "Space is required before unary expressions '{{token}}'." + } + }, + + create(context) { + const options = context.options[0] || { words: true, nonwords: false }; + + const sourceCode = context.getSourceCode(); + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + /** + * Check if the node is the first "!" in a "!!" convert to Boolean expression + * @param {ASTnode} node AST node + * @returns {boolean} Whether or not the node is first "!" in "!!" + */ + function isFirstBangInBangBangExpression(node) { + return node && node.type === "UnaryExpression" && node.argument.operator === "!" && + node.argument && node.argument.type === "UnaryExpression" && node.argument.operator === "!"; + } + + /** + * Checks if an override exists for a given operator. + * @param {string} operator Operator + * @returns {boolean} Whether or not an override has been provided for the operator + */ + function overrideExistsForOperator(operator) { + return options.overrides && Object.prototype.hasOwnProperty.call(options.overrides, operator); + } + + /** + * Gets the value that the override was set to for this operator + * @param {string} operator Operator + * @returns {boolean} Whether or not an override enforces a space with this operator + */ + function overrideEnforcesSpaces(operator) { + return options.overrides[operator]; + } + + /** + * Verify Unary Word Operator has spaces after the word operator + * @param {ASTnode} node AST node + * @param {Object} firstToken first token from the AST node + * @param {Object} secondToken second token from the AST node + * @param {string} word The word to be used for reporting + * @returns {void} + */ + function verifyWordHasSpaces(node, firstToken, secondToken, word) { + if (secondToken.range[0] === firstToken.range[1]) { + context.report({ + node, + messageId: "wordOperator", + data: { + word + }, + fix(fixer) { + return fixer.insertTextAfter(firstToken, " "); + } + }); + } + } + + /** + * Verify Unary Word Operator doesn't have spaces after the word operator + * @param {ASTnode} node AST node + * @param {Object} firstToken first token from the AST node + * @param {Object} secondToken second token from the AST node + * @param {string} word The word to be used for reporting + * @returns {void} + */ + function verifyWordDoesntHaveSpaces(node, firstToken, secondToken, word) { + if (astUtils.canTokensBeAdjacent(firstToken, secondToken)) { + if (secondToken.range[0] > firstToken.range[1]) { + context.report({ + node, + messageId: "unexpectedAfterWord", + data: { + word + }, + fix(fixer) { + return fixer.removeRange([firstToken.range[1], secondToken.range[0]]); + } + }); + } + } + } + + /** + * Check Unary Word Operators for spaces after the word operator + * @param {ASTnode} node AST node + * @param {Object} firstToken first token from the AST node + * @param {Object} secondToken second token from the AST node + * @param {string} word The word to be used for reporting + * @returns {void} + */ + function checkUnaryWordOperatorForSpaces(node, firstToken, secondToken, word) { + if (overrideExistsForOperator(word)) { + if (overrideEnforcesSpaces(word)) { + verifyWordHasSpaces(node, firstToken, secondToken, word); + } else { + verifyWordDoesntHaveSpaces(node, firstToken, secondToken, word); + } + } else if (options.words) { + verifyWordHasSpaces(node, firstToken, secondToken, word); + } else { + verifyWordDoesntHaveSpaces(node, firstToken, secondToken, word); + } + } + + /** + * Verifies YieldExpressions satisfy spacing requirements + * @param {ASTnode} node AST node + * @returns {void} + */ + function checkForSpacesAfterYield(node) { + const tokens = sourceCode.getFirstTokens(node, 3), + word = "yield"; + + if (!node.argument || node.delegate) { + return; + } + + checkUnaryWordOperatorForSpaces(node, tokens[0], tokens[1], word); + } + + /** + * Verifies AwaitExpressions satisfy spacing requirements + * @param {ASTNode} node AwaitExpression AST node + * @returns {void} + */ + function checkForSpacesAfterAwait(node) { + const tokens = sourceCode.getFirstTokens(node, 3); + + checkUnaryWordOperatorForSpaces(node, tokens[0], tokens[1], "await"); + } + + /** + * Verifies UnaryExpression, UpdateExpression and NewExpression have spaces before or after the operator + * @param {ASTnode} node AST node + * @param {Object} firstToken First token in the expression + * @param {Object} secondToken Second token in the expression + * @returns {void} + */ + function verifyNonWordsHaveSpaces(node, firstToken, secondToken) { + if (node.prefix) { + if (isFirstBangInBangBangExpression(node)) { + return; + } + if (firstToken.range[1] === secondToken.range[0]) { + context.report({ + node, + messageId: "operator", + data: { + operator: firstToken.value + }, + fix(fixer) { + return fixer.insertTextAfter(firstToken, " "); + } + }); + } + } else { + if (firstToken.range[1] === secondToken.range[0]) { + context.report({ + node, + messageId: "beforeUnaryExpressions", + data: { + token: secondToken.value + }, + fix(fixer) { + return fixer.insertTextBefore(secondToken, " "); + } + }); + } + } + } + + /** + * Verifies UnaryExpression, UpdateExpression and NewExpression don't have spaces before or after the operator + * @param {ASTnode} node AST node + * @param {Object} firstToken First token in the expression + * @param {Object} secondToken Second token in the expression + * @returns {void} + */ + function verifyNonWordsDontHaveSpaces(node, firstToken, secondToken) { + if (node.prefix) { + if (secondToken.range[0] > firstToken.range[1]) { + context.report({ + node, + messageId: "unexpectedAfter", + data: { + operator: firstToken.value + }, + fix(fixer) { + if (astUtils.canTokensBeAdjacent(firstToken, secondToken)) { + return fixer.removeRange([firstToken.range[1], secondToken.range[0]]); + } + return null; + } + }); + } + } else { + if (secondToken.range[0] > firstToken.range[1]) { + context.report({ + node, + messageId: "unexpectedBefore", + data: { + operator: secondToken.value + }, + fix(fixer) { + return fixer.removeRange([firstToken.range[1], secondToken.range[0]]); + } + }); + } + } + } + + /** + * Verifies UnaryExpression, UpdateExpression and NewExpression satisfy spacing requirements + * @param {ASTnode} node AST node + * @returns {void} + */ + function checkForSpaces(node) { + const tokens = node.type === "UpdateExpression" && !node.prefix + ? sourceCode.getLastTokens(node, 2) + : sourceCode.getFirstTokens(node, 2); + const firstToken = tokens[0]; + const secondToken = tokens[1]; + + if ((node.type === "NewExpression" || node.prefix) && firstToken.type === "Keyword") { + checkUnaryWordOperatorForSpaces(node, firstToken, secondToken, firstToken.value); + return; + } + + const operator = node.prefix ? tokens[0].value : tokens[1].value; + + if (overrideExistsForOperator(operator)) { + if (overrideEnforcesSpaces(operator)) { + verifyNonWordsHaveSpaces(node, firstToken, secondToken); + } else { + verifyNonWordsDontHaveSpaces(node, firstToken, secondToken); + } + } else if (options.nonwords) { + verifyNonWordsHaveSpaces(node, firstToken, secondToken); + } else { + verifyNonWordsDontHaveSpaces(node, firstToken, secondToken); + } + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + UnaryExpression: checkForSpaces, + UpdateExpression: checkForSpaces, + NewExpression: checkForSpaces, + YieldExpression: checkForSpacesAfterYield, + AwaitExpression: checkForSpacesAfterAwait + }; + + } +}; + +/** + * @fileoverview Source code for spaced-comments rule + * @author Gyandeep Singh + */ + + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Escapes the control characters of a given string. + * @param {string} s A string to escape. + * @returns {string} An escaped string. + */ +function escape(s) { + return `(?:${lodash__default['default'].escapeRegExp(s)})`; +} + +/** + * Escapes the control characters of a given string. + * And adds a repeat flag. + * @param {string} s A string to escape. + * @returns {string} An escaped string. + */ +function escapeAndRepeat(s) { + return `${escape(s)}+`; +} + +/** + * Parses `markers` option. + * If markers don't include `"*"`, this adds `"*"` to allow JSDoc comments. + * @param {string[]} [markers] A marker list. + * @returns {string[]} A marker list. + */ +function parseMarkersOption(markers) { + + // `*` is a marker for JSDoc comments. + if (markers.indexOf("*") === -1) { + return markers.concat("*"); + } + + return markers; +} + +/** + * Creates string pattern for exceptions. + * Generated pattern: + * + * 1. A space or an exception pattern sequence. + * @param {string[]} exceptions An exception pattern list. + * @returns {string} A regular expression string for exceptions. + */ +function createExceptionsPattern(exceptions) { + let pattern = ""; + + /* + * A space or an exception pattern sequence. + * [] ==> "\s" + * ["-"] ==> "(?:\s|\-+$)" + * ["-", "="] ==> "(?:\s|(?:\-+|=+)$)" + * ["-", "=", "--=="] ==> "(?:\s|(?:\-+|=+|(?:\-\-==)+)$)" ==> https://jex.im/regulex/#!embed=false&flags=&re=(%3F%3A%5Cs%7C(%3F%3A%5C-%2B%7C%3D%2B%7C(%3F%3A%5C-%5C-%3D%3D)%2B)%24) + */ + if (exceptions.length === 0) { + + // a space. + pattern += "\\s"; + } else { + + // a space or... + pattern += "(?:\\s|"; + + if (exceptions.length === 1) { + + // a sequence of the exception pattern. + pattern += escapeAndRepeat(exceptions[0]); + } else { + + // a sequence of one of the exception patterns. + pattern += "(?:"; + pattern += exceptions.map(escapeAndRepeat).join("|"); + pattern += ")"; + } + pattern += `(?:$|[${Array.from(astUtils.LINEBREAKS).join("")}]))`; + } + + return pattern; +} + +/** + * Creates RegExp object for `always` mode. + * Generated pattern for beginning of comment: + * + * 1. First, a marker or nothing. + * 2. Next, a space or an exception pattern sequence. + * @param {string[]} markers A marker list. + * @param {string[]} exceptions An exception pattern list. + * @returns {RegExp} A RegExp object for the beginning of a comment in `always` mode. + */ +function createAlwaysStylePattern(markers, exceptions) { + let pattern = "^"; + + /* + * A marker or nothing. + * ["*"] ==> "\*?" + * ["*", "!"] ==> "(?:\*|!)?" + * ["*", "/", "!<"] ==> "(?:\*|\/|(?:!<))?" ==> https://jex.im/regulex/#!embed=false&flags=&re=(%3F%3A%5C*%7C%5C%2F%7C(%3F%3A!%3C))%3F + */ + if (markers.length === 1) { + + // the marker. + pattern += escape(markers[0]); + } else { + + // one of markers. + pattern += "(?:"; + pattern += markers.map(escape).join("|"); + pattern += ")"; + } + + pattern += "?"; // or nothing. + pattern += createExceptionsPattern(exceptions); + + return new RegExp(pattern, "u"); +} + +/** + * Creates RegExp object for `never` mode. + * Generated pattern for beginning of comment: + * + * 1. First, a marker or nothing (captured). + * 2. Next, a space or a tab. + * @param {string[]} markers A marker list. + * @returns {RegExp} A RegExp object for `never` mode. + */ +function createNeverStylePattern(markers) { + const pattern = `^(${markers.map(escape).join("|")})?[ \t]+`; + + return new RegExp(pattern, "u"); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var spacedComment = { + meta: { + type: "suggestion", + + docs: { + description: "enforce consistent spacing after the `//` or `/*` in a comment", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/spaced-comment" + }, + + fixable: "whitespace", + + schema: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + exceptions: { + type: "array", + items: { + type: "string" + } + }, + markers: { + type: "array", + items: { + type: "string" + } + }, + line: { + type: "object", + properties: { + exceptions: { + type: "array", + items: { + type: "string" + } + }, + markers: { + type: "array", + items: { + type: "string" + } + } + }, + additionalProperties: false + }, + block: { + type: "object", + properties: { + exceptions: { + type: "array", + items: { + type: "string" + } + }, + markers: { + type: "array", + items: { + type: "string" + } + }, + balanced: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + }, + additionalProperties: false + } + ], + + messages: { + unexpectedSpaceAfterMarker: "Unexpected space or tab after marker ({{refChar}}) in comment.", + expectedExceptionAfter: "Expected exception block, space or tab after '{{refChar}}' in comment.", + unexpectedSpaceBefore: "Unexpected space or tab before '*/' in comment.", + unexpectedSpaceAfter: "Unexpected space or tab after '{{refChar}}' in comment.", + expectedSpaceBefore: "Expected space or tab before '*/' in comment.", + expectedSpaceAfter: "Expected space or tab after '{{refChar}}' in comment." + } + }, + + create(context) { + + const sourceCode = context.getSourceCode(); + + // Unless the first option is never, require a space + const requireSpace = context.options[0] !== "never"; + + /* + * Parse the second options. + * If markers don't include `"*"`, it's added automatically for JSDoc + * comments. + */ + const config = context.options[1] || {}; + const balanced = config.block && config.block.balanced; + + const styleRules = ["block", "line"].reduce((rule, type) => { + const markers = parseMarkersOption(config[type] && config[type].markers || config.markers || []); + const exceptions = config[type] && config[type].exceptions || config.exceptions || []; + const endNeverPattern = "[ \t]+$"; + + // Create RegExp object for valid patterns. + rule[type] = { + beginRegex: requireSpace ? createAlwaysStylePattern(markers, exceptions) : createNeverStylePattern(markers), + endRegex: balanced && requireSpace ? new RegExp(`${createExceptionsPattern(exceptions)}$`, "u") : new RegExp(endNeverPattern, "u"), + hasExceptions: exceptions.length > 0, + captureMarker: new RegExp(`^(${markers.map(escape).join("|")})`, "u"), + markers: new Set(markers) + }; + + return rule; + }, {}); + + /** + * Reports a beginning spacing error with an appropriate message. + * @param {ASTNode} node A comment node to check. + * @param {string} messageId An error message to report. + * @param {Array} match An array of match results for markers. + * @param {string} refChar Character used for reference in the error message. + * @returns {void} + */ + function reportBegin(node, messageId, match, refChar) { + const type = node.type.toLowerCase(), + commentIdentifier = type === "block" ? "/*" : "//"; + + context.report({ + node, + fix(fixer) { + const start = node.range[0]; + let end = start + 2; + + if (requireSpace) { + if (match) { + end += match[0].length; + } + return fixer.insertTextAfterRange([start, end], " "); + } + end += match[0].length; + return fixer.replaceTextRange([start, end], commentIdentifier + (match[1] ? match[1] : "")); + + }, + messageId, + data: { refChar } + }); + } + + /** + * Reports an ending spacing error with an appropriate message. + * @param {ASTNode} node A comment node to check. + * @param {string} messageId An error message to report. + * @param {string} match An array of the matched whitespace characters. + * @returns {void} + */ + function reportEnd(node, messageId, match) { + context.report({ + node, + fix(fixer) { + if (requireSpace) { + return fixer.insertTextAfterRange([node.range[0], node.range[1] - 2], " "); + } + const end = node.range[1] - 2, + start = end - match[0].length; + + return fixer.replaceTextRange([start, end], ""); + + }, + messageId + }); + } + + /** + * Reports a given comment if it's invalid. + * @param {ASTNode} node a comment node to check. + * @returns {void} + */ + function checkCommentForSpace(node) { + const type = node.type.toLowerCase(), + rule = styleRules[type], + commentIdentifier = type === "block" ? "/*" : "//"; + + // Ignores empty comments and comments that consist only of a marker. + if (node.value.length === 0 || rule.markers.has(node.value)) { + return; + } + + const beginMatch = rule.beginRegex.exec(node.value); + const endMatch = rule.endRegex.exec(node.value); + + // Checks. + if (requireSpace) { + if (!beginMatch) { + const hasMarker = rule.captureMarker.exec(node.value); + const marker = hasMarker ? commentIdentifier + hasMarker[0] : commentIdentifier; + + if (rule.hasExceptions) { + reportBegin(node, "expectedExceptionAfter", hasMarker, marker); + } else { + reportBegin(node, "expectedSpaceAfter", hasMarker, marker); + } + } + + if (balanced && type === "block" && !endMatch) { + reportEnd(node, "expectedSpaceBefore"); + } + } else { + if (beginMatch) { + if (!beginMatch[1]) { + reportBegin(node, "unexpectedSpaceAfter", beginMatch, commentIdentifier); + } else { + reportBegin(node, "unexpectedSpaceAfterMarker", beginMatch, beginMatch[1]); + } + } + + if (balanced && type === "block" && endMatch) { + reportEnd(node, "unexpectedSpaceBefore", endMatch); + } + } + } + + return { + Program() { + const comments = sourceCode.getAllComments(); + + comments.filter(token => token.type !== "Shebang").forEach(checkCommentForSpace); + } + }; + } +}; + +/** + * @fileoverview Rule to control usage of strict mode directives. + * @author Brandon Mills + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Gets all of the Use Strict Directives in the Directive Prologue of a group of + * statements. + * @param {ASTNode[]} statements Statements in the program or function body. + * @returns {ASTNode[]} All of the Use Strict Directives. + */ +function getUseStrictDirectives(statements) { + const directives = []; + + for (let i = 0; i < statements.length; i++) { + const statement = statements[i]; + + if ( + statement.type === "ExpressionStatement" && + statement.expression.type === "Literal" && + statement.expression.value === "use strict" + ) { + directives[i] = statement; + } else { + break; + } + } + + return directives; +} + +/** + * Checks whether a given parameter is a simple parameter. + * @param {ASTNode} node A pattern node to check. + * @returns {boolean} `true` if the node is an Identifier node. + */ +function isSimpleParameter(node) { + return node.type === "Identifier"; +} + +/** + * Checks whether a given parameter list is a simple parameter list. + * @param {ASTNode[]} params A parameter list to check. + * @returns {boolean} `true` if the every parameter is an Identifier node. + */ +function isSimpleParameterList(params) { + return params.every(isSimpleParameter); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var strict = { + meta: { + type: "suggestion", + + docs: { + description: "require or disallow strict mode directives", + category: "Strict Mode", + recommended: false, + url: "https://eslint.org/docs/rules/strict" + }, + + schema: [ + { + enum: ["never", "global", "function", "safe"] + } + ], + + fixable: "code", + messages: { + function: "Use the function form of 'use strict'.", + global: "Use the global form of 'use strict'.", + multiple: "Multiple 'use strict' directives.", + never: "Strict mode is not permitted.", + unnecessary: "Unnecessary 'use strict' directive.", + module: "'use strict' is unnecessary inside of modules.", + implied: "'use strict' is unnecessary when implied strict mode is enabled.", + unnecessaryInClasses: "'use strict' is unnecessary inside of classes.", + nonSimpleParameterList: "'use strict' directive inside a function with non-simple parameter list throws a syntax error since ES2016.", + wrap: "Wrap {{name}} in a function with 'use strict' directive." + } + }, + + create(context) { + + const ecmaFeatures = context.parserOptions.ecmaFeatures || {}, + scopes = [], + classScopes = []; + let mode = context.options[0] || "safe"; + + if (ecmaFeatures.impliedStrict) { + mode = "implied"; + } else if (mode === "safe") { + mode = ecmaFeatures.globalReturn ? "global" : "function"; + } + + /** + * Determines whether a reported error should be fixed, depending on the error type. + * @param {string} errorType The type of error + * @returns {boolean} `true` if the reported error should be fixed + */ + function shouldFix(errorType) { + return errorType === "multiple" || errorType === "unnecessary" || errorType === "module" || errorType === "implied" || errorType === "unnecessaryInClasses"; + } + + /** + * Gets a fixer function to remove a given 'use strict' directive. + * @param {ASTNode} node The directive that should be removed + * @returns {Function} A fixer function + */ + function getFixFunction(node) { + return fixer => fixer.remove(node); + } + + /** + * Report a slice of an array of nodes with a given message. + * @param {ASTNode[]} nodes Nodes. + * @param {string} start Index to start from. + * @param {string} end Index to end before. + * @param {string} messageId Message to display. + * @param {boolean} fix `true` if the directive should be fixed (i.e. removed) + * @returns {void} + */ + function reportSlice(nodes, start, end, messageId, fix) { + nodes.slice(start, end).forEach(node => { + context.report({ node, messageId, fix: fix ? getFixFunction(node) : null }); + }); + } + + /** + * Report all nodes in an array with a given message. + * @param {ASTNode[]} nodes Nodes. + * @param {string} messageId Message id to display. + * @param {boolean} fix `true` if the directive should be fixed (i.e. removed) + * @returns {void} + */ + function reportAll(nodes, messageId, fix) { + reportSlice(nodes, 0, nodes.length, messageId, fix); + } + + /** + * Report all nodes in an array, except the first, with a given message. + * @param {ASTNode[]} nodes Nodes. + * @param {string} messageId Message id to display. + * @param {boolean} fix `true` if the directive should be fixed (i.e. removed) + * @returns {void} + */ + function reportAllExceptFirst(nodes, messageId, fix) { + reportSlice(nodes, 1, nodes.length, messageId, fix); + } + + /** + * Entering a function in 'function' mode pushes a new nested scope onto the + * stack. The new scope is true if the nested function is strict mode code. + * @param {ASTNode} node The function declaration or expression. + * @param {ASTNode[]} useStrictDirectives The Use Strict Directives of the node. + * @returns {void} + */ + function enterFunctionInFunctionMode(node, useStrictDirectives) { + const isInClass = classScopes.length > 0, + isParentGlobal = scopes.length === 0 && classScopes.length === 0, + isParentStrict = scopes.length > 0 && scopes[scopes.length - 1], + isStrict = useStrictDirectives.length > 0; + + if (isStrict) { + if (!isSimpleParameterList(node.params)) { + context.report({ node: useStrictDirectives[0], messageId: "nonSimpleParameterList" }); + } else if (isParentStrict) { + context.report({ node: useStrictDirectives[0], messageId: "unnecessary", fix: getFixFunction(useStrictDirectives[0]) }); + } else if (isInClass) { + context.report({ node: useStrictDirectives[0], messageId: "unnecessaryInClasses", fix: getFixFunction(useStrictDirectives[0]) }); + } + + reportAllExceptFirst(useStrictDirectives, "multiple", true); + } else if (isParentGlobal) { + if (isSimpleParameterList(node.params)) { + context.report({ node, messageId: "function" }); + } else { + context.report({ + node, + messageId: "wrap", + data: { name: astUtils.getFunctionNameWithKind(node) } + }); + } + } + + scopes.push(isParentStrict || isStrict); + } + + /** + * Exiting a function in 'function' mode pops its scope off the stack. + * @returns {void} + */ + function exitFunctionInFunctionMode() { + scopes.pop(); + } + + /** + * Enter a function and either: + * - Push a new nested scope onto the stack (in 'function' mode). + * - Report all the Use Strict Directives (in the other modes). + * @param {ASTNode} node The function declaration or expression. + * @returns {void} + */ + function enterFunction(node) { + const isBlock = node.body.type === "BlockStatement", + useStrictDirectives = isBlock + ? getUseStrictDirectives(node.body.body) : []; + + if (mode === "function") { + enterFunctionInFunctionMode(node, useStrictDirectives); + } else if (useStrictDirectives.length > 0) { + if (isSimpleParameterList(node.params)) { + reportAll(useStrictDirectives, mode, shouldFix(mode)); + } else { + context.report({ node: useStrictDirectives[0], messageId: "nonSimpleParameterList" }); + reportAllExceptFirst(useStrictDirectives, "multiple", true); + } + } + } + + const rule = { + Program(node) { + const useStrictDirectives = getUseStrictDirectives(node.body); + + if (node.sourceType === "module") { + mode = "module"; + } + + if (mode === "global") { + if (node.body.length > 0 && useStrictDirectives.length === 0) { + context.report({ node, messageId: "global" }); + } + reportAllExceptFirst(useStrictDirectives, "multiple", true); + } else { + reportAll(useStrictDirectives, mode, shouldFix(mode)); + } + }, + FunctionDeclaration: enterFunction, + FunctionExpression: enterFunction, + ArrowFunctionExpression: enterFunction + }; + + if (mode === "function") { + Object.assign(rule, { + + // Inside of class bodies are always strict mode. + ClassBody() { + classScopes.push(true); + }, + "ClassBody:exit"() { + classScopes.pop(); + }, + + "FunctionDeclaration:exit": exitFunctionInFunctionMode, + "FunctionExpression:exit": exitFunctionInFunctionMode, + "ArrowFunctionExpression:exit": exitFunctionInFunctionMode + }); + } + + return rule; + } +}; + +/** + * @fileoverview Rule to enforce spacing around colons of switch statements. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var switchColonSpacing = { + meta: { + type: "layout", + + docs: { + description: "enforce spacing around colons of switch statements", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/switch-colon-spacing" + }, + + schema: [ + { + type: "object", + properties: { + before: { type: "boolean", default: false }, + after: { type: "boolean", default: true } + }, + additionalProperties: false + } + ], + fixable: "whitespace", + messages: { + expectedBefore: "Expected space(s) before this colon.", + expectedAfter: "Expected space(s) after this colon.", + unexpectedBefore: "Unexpected space(s) before this colon.", + unexpectedAfter: "Unexpected space(s) after this colon." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const options = context.options[0] || {}; + const beforeSpacing = options.before === true; // false by default + const afterSpacing = options.after !== false; // true by default + + /** + * Get the colon token of the given SwitchCase node. + * @param {ASTNode} node The SwitchCase node to get. + * @returns {Token} The colon token of the node. + */ + function getColonToken(node) { + if (node.test) { + return sourceCode.getTokenAfter(node.test, astUtils.isColonToken); + } + return sourceCode.getFirstToken(node, 1); + } + + /** + * Check whether the spacing between the given 2 tokens is valid or not. + * @param {Token} left The left token to check. + * @param {Token} right The right token to check. + * @param {boolean} expected The expected spacing to check. `true` if there should be a space. + * @returns {boolean} `true` if the spacing between the tokens is valid. + */ + function isValidSpacing(left, right, expected) { + return ( + astUtils.isClosingBraceToken(right) || + !astUtils.isTokenOnSameLine(left, right) || + sourceCode.isSpaceBetweenTokens(left, right) === expected + ); + } + + /** + * Check whether comments exist between the given 2 tokens. + * @param {Token} left The left token to check. + * @param {Token} right The right token to check. + * @returns {boolean} `true` if comments exist between the given 2 tokens. + */ + function commentsExistBetween(left, right) { + return sourceCode.getFirstTokenBetween( + left, + right, + { + includeComments: true, + filter: astUtils.isCommentToken + } + ) !== null; + } + + /** + * Fix the spacing between the given 2 tokens. + * @param {RuleFixer} fixer The fixer to fix. + * @param {Token} left The left token of fix range. + * @param {Token} right The right token of fix range. + * @param {boolean} spacing The spacing style. `true` if there should be a space. + * @returns {Fix|null} The fix object. + */ + function fix(fixer, left, right, spacing) { + if (commentsExistBetween(left, right)) { + return null; + } + if (spacing) { + return fixer.insertTextAfter(left, " "); + } + return fixer.removeRange([left.range[1], right.range[0]]); + } + + return { + SwitchCase(node) { + const colonToken = getColonToken(node); + const beforeToken = sourceCode.getTokenBefore(colonToken); + const afterToken = sourceCode.getTokenAfter(colonToken); + + if (!isValidSpacing(beforeToken, colonToken, beforeSpacing)) { + context.report({ + node, + loc: colonToken.loc, + messageId: beforeSpacing ? "expectedBefore" : "unexpectedBefore", + fix: fixer => fix(fixer, beforeToken, colonToken, beforeSpacing) + }); + } + if (!isValidSpacing(colonToken, afterToken, afterSpacing)) { + context.report({ + node, + loc: colonToken.loc, + messageId: afterSpacing ? "expectedAfter" : "unexpectedAfter", + fix: fixer => fix(fixer, colonToken, afterToken, afterSpacing) + }); + } + } + }; + } +}; + +/** + * @fileoverview Rule to enforce description with the `Symbol` object + * @author Jarek Rencz + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + + +var symbolDescription = { + meta: { + type: "suggestion", + + docs: { + description: "require symbol descriptions", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/symbol-description" + }, + fixable: null, + schema: [], + messages: { + expected: "Expected Symbol to have a description." + } + }, + + create(context) { + + /** + * Reports if node does not conform the rule in case rule is set to + * report missing description + * @param {ASTNode} node A CallExpression node to check. + * @returns {void} + */ + function checkArgument(node) { + if (node.arguments.length === 0) { + context.report({ + node, + messageId: "expected" + }); + } + } + + return { + "Program:exit"() { + const scope = context.getScope(); + const variable = astUtils.getVariableByName(scope, "Symbol"); + + if (variable && variable.defs.length === 0) { + variable.references.forEach(reference => { + const node = reference.identifier; + + if (astUtils.isCallee(node)) { + checkArgument(node.parent); + } + }); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to enforce spacing around embedded expressions of template strings + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var templateCurlySpacing = { + meta: { + type: "layout", + + docs: { + description: "require or disallow spacing around embedded expressions of template strings", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/template-curly-spacing" + }, + + fixable: "whitespace", + + schema: [ + { enum: ["always", "never"] } + ], + messages: { + expectedBefore: "Expected space(s) before '}'.", + expectedAfter: "Expected space(s) after '${'.", + unexpectedBefore: "Unexpected space(s) before '}'.", + unexpectedAfter: "Unexpected space(s) after '${'." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + const always = context.options[0] === "always"; + + /** + * Checks spacing before `}` of a given token. + * @param {Token} token A token to check. This is a Template token. + * @returns {void} + */ + function checkSpacingBefore(token) { + if (!token.value.startsWith("}")) { + return; // starts with a backtick, this is the first template element in the template literal + } + + const prevToken = sourceCode.getTokenBefore(token, { includeComments: true }), + hasSpace = sourceCode.isSpaceBetween(prevToken, token); + + if (!astUtils.isTokenOnSameLine(prevToken, token)) { + return; + } + + if (always && !hasSpace) { + context.report({ + loc: { + start: token.loc.start, + end: { + line: token.loc.start.line, + column: token.loc.start.column + 1 + } + }, + messageId: "expectedBefore", + fix: fixer => fixer.insertTextBefore(token, " ") + }); + } + + if (!always && hasSpace) { + context.report({ + loc: { + start: prevToken.loc.end, + end: token.loc.start + }, + messageId: "unexpectedBefore", + fix: fixer => fixer.removeRange([prevToken.range[1], token.range[0]]) + }); + } + } + + /** + * Checks spacing after `${` of a given token. + * @param {Token} token A token to check. This is a Template token. + * @returns {void} + */ + function checkSpacingAfter(token) { + if (!token.value.endsWith("${")) { + return; // ends with a backtick, this is the last template element in the template literal + } + + const nextToken = sourceCode.getTokenAfter(token, { includeComments: true }), + hasSpace = sourceCode.isSpaceBetween(token, nextToken); + + if (!astUtils.isTokenOnSameLine(token, nextToken)) { + return; + } + + if (always && !hasSpace) { + context.report({ + loc: { + start: { + line: token.loc.end.line, + column: token.loc.end.column - 2 + }, + end: token.loc.end + }, + messageId: "expectedAfter", + fix: fixer => fixer.insertTextAfter(token, " ") + }); + } + + if (!always && hasSpace) { + context.report({ + loc: { + start: token.loc.end, + end: nextToken.loc.start + }, + messageId: "unexpectedAfter", + fix: fixer => fixer.removeRange([token.range[1], nextToken.range[0]]) + }); + } + } + + return { + TemplateElement(node) { + const token = sourceCode.getFirstToken(node); + + checkSpacingBefore(token); + checkSpacingAfter(token); + } + }; + } +}; + +/** + * @fileoverview Rule to check spacing between template tags and their literals + * @author Jonathan Wilsson + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var templateTagSpacing = { + meta: { + type: "layout", + + docs: { + description: "require or disallow spacing between template tags and their literals", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/template-tag-spacing" + }, + + fixable: "whitespace", + + schema: [ + { enum: ["always", "never"] } + ], + messages: { + unexpected: "Unexpected space between template tag and template literal.", + missing: "Missing space between template tag and template literal." + } + }, + + create(context) { + const never = context.options[0] !== "always"; + const sourceCode = context.getSourceCode(); + + /** + * Check if a space is present between a template tag and its literal + * @param {ASTNode} node node to evaluate + * @returns {void} + * @private + */ + function checkSpacing(node) { + const tagToken = sourceCode.getTokenBefore(node.quasi); + const literalToken = sourceCode.getFirstToken(node.quasi); + const hasWhitespace = sourceCode.isSpaceBetweenTokens(tagToken, literalToken); + + if (never && hasWhitespace) { + context.report({ + node, + loc: { + start: tagToken.loc.end, + end: literalToken.loc.start + }, + messageId: "unexpected", + fix(fixer) { + const comments = sourceCode.getCommentsBefore(node.quasi); + + // Don't fix anything if there's a single line comment after the template tag + if (comments.some(comment => comment.type === "Line")) { + return null; + } + + return fixer.replaceTextRange( + [tagToken.range[1], literalToken.range[0]], + comments.reduce((text, comment) => text + sourceCode.getText(comment), "") + ); + } + }); + } else if (!never && !hasWhitespace) { + context.report({ + node, + loc: { + start: node.loc.start, + end: literalToken.loc.start + }, + messageId: "missing", + fix(fixer) { + return fixer.insertTextAfter(tagToken, " "); + } + }); + } + } + + return { + TaggedTemplateExpression: checkSpacing + }; + } +}; + +/** + * @fileoverview Require or disallow Unicode BOM + * @author Andrew Johnston + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var unicodeBom = { + meta: { + type: "layout", + + docs: { + description: "require or disallow Unicode byte order mark (BOM)", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/unicode-bom" + }, + + fixable: "whitespace", + + schema: [ + { + enum: ["always", "never"] + } + ], + messages: { + expected: "Expected Unicode BOM (Byte Order Mark).", + unexpected: "Unexpected Unicode BOM (Byte Order Mark)." + } + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + Program: function checkUnicodeBOM(node) { + + const sourceCode = context.getSourceCode(), + location = { column: 0, line: 1 }, + requireBOM = context.options[0] || "never"; + + if (!sourceCode.hasBOM && (requireBOM === "always")) { + context.report({ + node, + loc: location, + messageId: "expected", + fix(fixer) { + return fixer.insertTextBeforeRange([0, 1], "\uFEFF"); + } + }); + } else if (sourceCode.hasBOM && (requireBOM === "never")) { + context.report({ + node, + loc: location, + messageId: "unexpected", + fix(fixer) { + return fixer.removeRange([-1, 0]); + } + }); + } + } + + }; + + } +}; + +/** + * @fileoverview Rule to flag comparisons to the value NaN + * @author James Allardice + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Determines if the given node is a NaN `Identifier` node. + * @param {ASTNode|null} node The node to check. + * @returns {boolean} `true` if the node is 'NaN' identifier. + */ +function isNaNIdentifier(node) { + return Boolean(node) && node.type === "Identifier" && node.name === "NaN"; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var useIsnan = { + meta: { + type: "problem", + + docs: { + description: "require calls to `isNaN()` when checking for `NaN`", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/use-isnan" + }, + + schema: [ + { + type: "object", + properties: { + enforceForSwitchCase: { + type: "boolean", + default: true + }, + enforceForIndexOf: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + messages: { + comparisonWithNaN: "Use the isNaN function to compare with NaN.", + switchNaN: "'switch(NaN)' can never match a case clause. Use Number.isNaN instead of the switch.", + caseNaN: "'case NaN' can never match. Use Number.isNaN before the switch.", + indexOfNaN: "Array prototype method '{{ methodName }}' cannot find NaN." + } + }, + + create(context) { + + const enforceForSwitchCase = !context.options[0] || context.options[0].enforceForSwitchCase; + const enforceForIndexOf = context.options[0] && context.options[0].enforceForIndexOf; + + /** + * Checks the given `BinaryExpression` node for `foo === NaN` and other comparisons. + * @param {ASTNode} node The node to check. + * @returns {void} + */ + function checkBinaryExpression(node) { + if ( + /^(?:[<>]|[!=]=)=?$/u.test(node.operator) && + (isNaNIdentifier(node.left) || isNaNIdentifier(node.right)) + ) { + context.report({ node, messageId: "comparisonWithNaN" }); + } + } + + /** + * Checks the discriminant and all case clauses of the given `SwitchStatement` node for `switch(NaN)` and `case NaN:` + * @param {ASTNode} node The node to check. + * @returns {void} + */ + function checkSwitchStatement(node) { + if (isNaNIdentifier(node.discriminant)) { + context.report({ node, messageId: "switchNaN" }); + } + + for (const switchCase of node.cases) { + if (isNaNIdentifier(switchCase.test)) { + context.report({ node: switchCase, messageId: "caseNaN" }); + } + } + } + + /** + * Checks the given `CallExpression` node for `.indexOf(NaN)` and `.lastIndexOf(NaN)`. + * @param {ASTNode} node The node to check. + * @returns {void} + */ + function checkCallExpression(node) { + const callee = astUtils.skipChainExpression(node.callee); + + if (callee.type === "MemberExpression") { + const methodName = astUtils.getStaticPropertyName(callee); + + if ( + (methodName === "indexOf" || methodName === "lastIndexOf") && + node.arguments.length === 1 && + isNaNIdentifier(node.arguments[0]) + ) { + context.report({ node, messageId: "indexOfNaN", data: { methodName } }); + } + } + } + + const listeners = { + BinaryExpression: checkBinaryExpression + }; + + if (enforceForSwitchCase) { + listeners.SwitchStatement = checkSwitchStatement; + } + + if (enforceForIndexOf) { + listeners.CallExpression = checkCallExpression; + } + + return listeners; + } +}; + +/** + * @fileoverview Validates JSDoc comments are syntactically correct + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var validJsdoc = { + meta: { + type: "suggestion", + + docs: { + description: "enforce valid JSDoc comments", + category: "Possible Errors", + recommended: false, + url: "https://eslint.org/docs/rules/valid-jsdoc" + }, + + schema: [ + { + type: "object", + properties: { + prefer: { + type: "object", + additionalProperties: { + type: "string" + } + }, + preferType: { + type: "object", + additionalProperties: { + type: "string" + } + }, + requireReturn: { + type: "boolean", + default: true + }, + requireParamDescription: { + type: "boolean", + default: true + }, + requireReturnDescription: { + type: "boolean", + default: true + }, + matchDescription: { + type: "string" + }, + requireReturnType: { + type: "boolean", + default: true + }, + requireParamType: { + type: "boolean", + default: true + } + }, + additionalProperties: false + } + ], + + fixable: "code", + messages: { + unexpectedTag: "Unexpected @{{title}} tag; function has no return statement.", + expected: "Expected JSDoc for '{{name}}' but found '{{jsdocName}}'.", + use: "Use @{{name}} instead.", + useType: "Use '{{expectedTypeName}}' instead of '{{currentTypeName}}'.", + syntaxError: "JSDoc syntax error.", + missingBrace: "JSDoc type missing brace.", + missingParamDesc: "Missing JSDoc parameter description for '{{name}}'.", + missingParamType: "Missing JSDoc parameter type for '{{name}}'.", + missingReturnType: "Missing JSDoc return type.", + missingReturnDesc: "Missing JSDoc return description.", + missingReturn: "Missing JSDoc @{{returns}} for function.", + missingParam: "Missing JSDoc for parameter '{{name}}'.", + duplicateParam: "Duplicate JSDoc parameter '{{name}}'.", + unsatisfiedDesc: "JSDoc description does not satisfy the regex pattern." + }, + + deprecated: true, + replacedBy: [] + }, + + create(context) { + + const options = context.options[0] || {}, + prefer = options.prefer || {}, + sourceCode = context.getSourceCode(), + + // these both default to true, so you have to explicitly make them false + requireReturn = options.requireReturn !== false, + requireParamDescription = options.requireParamDescription !== false, + requireReturnDescription = options.requireReturnDescription !== false, + requireReturnType = options.requireReturnType !== false, + requireParamType = options.requireParamType !== false, + preferType = options.preferType || {}, + checkPreferType = Object.keys(preferType).length !== 0; + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + // Using a stack to store if a function returns or not (handling nested functions) + const fns = []; + + /** + * Check if node type is a Class + * @param {ASTNode} node node to check. + * @returns {boolean} True is its a class + * @private + */ + function isTypeClass(node) { + return node.type === "ClassExpression" || node.type === "ClassDeclaration"; + } + + /** + * When parsing a new function, store it in our function stack. + * @param {ASTNode} node A function node to check. + * @returns {void} + * @private + */ + function startFunction(node) { + fns.push({ + returnPresent: (node.type === "ArrowFunctionExpression" && node.body.type !== "BlockStatement") || + isTypeClass(node) || node.async + }); + } + + /** + * Indicate that return has been found in the current function. + * @param {ASTNode} node The return node. + * @returns {void} + * @private + */ + function addReturn(node) { + const functionState = fns[fns.length - 1]; + + if (functionState && node.argument !== null) { + functionState.returnPresent = true; + } + } + + /** + * Check if return tag type is void or undefined + * @param {Object} tag JSDoc tag + * @returns {boolean} True if its of type void or undefined + * @private + */ + function isValidReturnType(tag) { + return tag.type === null || tag.type.name === "void" || tag.type.type === "UndefinedLiteral"; + } + + /** + * Check if type should be validated based on some exceptions + * @param {Object} type JSDoc tag + * @returns {boolean} True if it can be validated + * @private + */ + function canTypeBeValidated(type) { + return type !== "UndefinedLiteral" && // {undefined} as there is no name property available. + type !== "NullLiteral" && // {null} + type !== "NullableLiteral" && // {?} + type !== "FunctionType" && // {function(a)} + type !== "AllLiteral"; // {*} + } + + /** + * Extract the current and expected type based on the input type object + * @param {Object} type JSDoc tag + * @returns {{currentType: Doctrine.Type, expectedTypeName: string}} The current type annotation and + * the expected name of the annotation + * @private + */ + function getCurrentExpectedTypes(type) { + let currentType; + + if (type.name) { + currentType = type; + } else if (type.expression) { + currentType = type.expression; + } + + return { + currentType, + expectedTypeName: currentType && preferType[currentType.name] + }; + } + + /** + * Gets the location of a JSDoc node in a file + * @param {Token} jsdocComment The comment that this node is parsed from + * @param {{range: number[]}} parsedJsdocNode A tag or other node which was parsed from this comment + * @returns {{start: SourceLocation, end: SourceLocation}} The 0-based source location for the tag + */ + function getAbsoluteRange(jsdocComment, parsedJsdocNode) { + return { + start: sourceCode.getLocFromIndex(jsdocComment.range[0] + 2 + parsedJsdocNode.range[0]), + end: sourceCode.getLocFromIndex(jsdocComment.range[0] + 2 + parsedJsdocNode.range[1]) + }; + } + + /** + * Validate type for a given JSDoc node + * @param {Object} jsdocNode JSDoc node + * @param {Object} type JSDoc tag + * @returns {void} + * @private + */ + function validateType(jsdocNode, type) { + if (!type || !canTypeBeValidated(type.type)) { + return; + } + + const typesToCheck = []; + let elements = []; + + switch (type.type) { + case "TypeApplication": // {Array.} + elements = type.applications[0].type === "UnionType" ? type.applications[0].elements : type.applications; + typesToCheck.push(getCurrentExpectedTypes(type)); + break; + case "RecordType": // {{20:String}} + elements = type.fields; + break; + case "UnionType": // {String|number|Test} + case "ArrayType": // {[String, number, Test]} + elements = type.elements; + break; + case "FieldType": // Array.<{count: number, votes: number}> + if (type.value) { + typesToCheck.push(getCurrentExpectedTypes(type.value)); + } + break; + default: + typesToCheck.push(getCurrentExpectedTypes(type)); + } + + elements.forEach(validateType.bind(null, jsdocNode)); + + typesToCheck.forEach(typeToCheck => { + if (typeToCheck.expectedTypeName && + typeToCheck.expectedTypeName !== typeToCheck.currentType.name) { + context.report({ + node: jsdocNode, + messageId: "useType", + loc: getAbsoluteRange(jsdocNode, typeToCheck.currentType), + data: { + currentTypeName: typeToCheck.currentType.name, + expectedTypeName: typeToCheck.expectedTypeName + }, + fix(fixer) { + return fixer.replaceTextRange( + typeToCheck.currentType.range.map(indexInComment => jsdocNode.range[0] + 2 + indexInComment), + typeToCheck.expectedTypeName + ); + } + }); + } + }); + } + + /** + * Validate the JSDoc node and output warnings if anything is wrong. + * @param {ASTNode} node The AST node to check. + * @returns {void} + * @private + */ + function checkJSDoc(node) { + const jsdocNode = sourceCode.getJSDocComment(node), + functionData = fns.pop(), + paramTagsByName = Object.create(null), + paramTags = []; + let hasReturns = false, + returnsTag, + hasConstructor = false, + isInterface = false, + isOverride = false, + isAbstract = false; + + // make sure only to validate JSDoc comments + if (jsdocNode) { + let jsdoc; + + try { + jsdoc = doctrine__default['default'].parse(jsdocNode.value, { + strict: true, + unwrap: true, + sloppy: true, + range: true + }); + } catch (ex) { + + if (/braces/iu.test(ex.message)) { + context.report({ node: jsdocNode, messageId: "missingBrace" }); + } else { + context.report({ node: jsdocNode, messageId: "syntaxError" }); + } + + return; + } + + jsdoc.tags.forEach(tag => { + + switch (tag.title.toLowerCase()) { + + case "param": + case "arg": + case "argument": + paramTags.push(tag); + break; + + case "return": + case "returns": + hasReturns = true; + returnsTag = tag; + break; + + case "constructor": + case "class": + hasConstructor = true; + break; + + case "override": + case "inheritdoc": + isOverride = true; + break; + + case "abstract": + case "virtual": + isAbstract = true; + break; + + case "interface": + isInterface = true; + break; + + // no default + } + + // check tag preferences + if (Object.prototype.hasOwnProperty.call(prefer, tag.title) && tag.title !== prefer[tag.title]) { + const entireTagRange = getAbsoluteRange(jsdocNode, tag); + + context.report({ + node: jsdocNode, + messageId: "use", + loc: { + start: entireTagRange.start, + end: { + line: entireTagRange.start.line, + column: entireTagRange.start.column + `@${tag.title}`.length + } + }, + data: { name: prefer[tag.title] }, + fix(fixer) { + return fixer.replaceTextRange( + [ + jsdocNode.range[0] + tag.range[0] + 3, + jsdocNode.range[0] + tag.range[0] + tag.title.length + 3 + ], + prefer[tag.title] + ); + } + }); + } + + // validate the types + if (checkPreferType && tag.type) { + validateType(jsdocNode, tag.type); + } + }); + + paramTags.forEach(param => { + if (requireParamType && !param.type) { + context.report({ + node: jsdocNode, + messageId: "missingParamType", + loc: getAbsoluteRange(jsdocNode, param), + data: { name: param.name } + }); + } + if (!param.description && requireParamDescription) { + context.report({ + node: jsdocNode, + messageId: "missingParamDesc", + loc: getAbsoluteRange(jsdocNode, param), + data: { name: param.name } + }); + } + if (paramTagsByName[param.name]) { + context.report({ + node: jsdocNode, + messageId: "duplicateParam", + loc: getAbsoluteRange(jsdocNode, param), + data: { name: param.name } + }); + } else if (param.name.indexOf(".") === -1) { + paramTagsByName[param.name] = param; + } + }); + + if (hasReturns) { + if (!requireReturn && !functionData.returnPresent && (returnsTag.type === null || !isValidReturnType(returnsTag)) && !isAbstract) { + context.report({ + node: jsdocNode, + messageId: "unexpectedTag", + loc: getAbsoluteRange(jsdocNode, returnsTag), + data: { + title: returnsTag.title + } + }); + } else { + if (requireReturnType && !returnsTag.type) { + context.report({ node: jsdocNode, messageId: "missingReturnType" }); + } + + if (!isValidReturnType(returnsTag) && !returnsTag.description && requireReturnDescription) { + context.report({ node: jsdocNode, messageId: "missingReturnDesc" }); + } + } + } + + // check for functions missing @returns + if (!isOverride && !hasReturns && !hasConstructor && !isInterface && + node.parent.kind !== "get" && node.parent.kind !== "constructor" && + node.parent.kind !== "set" && !isTypeClass(node)) { + if (requireReturn || (functionData.returnPresent && !node.async)) { + context.report({ + node: jsdocNode, + messageId: "missingReturn", + data: { + returns: prefer.returns || "returns" + } + }); + } + } + + // check the parameters + const jsdocParamNames = Object.keys(paramTagsByName); + + if (node.params) { + node.params.forEach((param, paramsIndex) => { + const bindingParam = param.type === "AssignmentPattern" + ? param.left + : param; + + // TODO(nzakas): Figure out logical things to do with destructured, default, rest params + if (bindingParam.type === "Identifier") { + const name = bindingParam.name; + + if (jsdocParamNames[paramsIndex] && (name !== jsdocParamNames[paramsIndex])) { + context.report({ + node: jsdocNode, + messageId: "expected", + loc: getAbsoluteRange(jsdocNode, paramTagsByName[jsdocParamNames[paramsIndex]]), + data: { + name, + jsdocName: jsdocParamNames[paramsIndex] + } + }); + } else if (!paramTagsByName[name] && !isOverride) { + context.report({ + node: jsdocNode, + messageId: "missingParam", + data: { + name + } + }); + } + } + }); + } + + if (options.matchDescription) { + const regex = new RegExp(options.matchDescription, "u"); + + if (!regex.test(jsdoc.description)) { + context.report({ node: jsdocNode, messageId: "unsatisfiedDesc" }); + } + } + + } + + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + ArrowFunctionExpression: startFunction, + FunctionExpression: startFunction, + FunctionDeclaration: startFunction, + ClassExpression: startFunction, + ClassDeclaration: startFunction, + "ArrowFunctionExpression:exit": checkJSDoc, + "FunctionExpression:exit": checkJSDoc, + "FunctionDeclaration:exit": checkJSDoc, + "ClassExpression:exit": checkJSDoc, + "ClassDeclaration:exit": checkJSDoc, + ReturnStatement: addReturn + }; + + } +}; + +/** + * @fileoverview Ensures that the results of typeof are compared against a valid string + * @author Ian Christian Myers + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var validTypeof = { + meta: { + type: "problem", + + docs: { + description: "enforce comparing `typeof` expressions against valid strings", + category: "Possible Errors", + recommended: true, + url: "https://eslint.org/docs/rules/valid-typeof" + }, + + schema: [ + { + type: "object", + properties: { + requireStringLiterals: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + messages: { + invalidValue: "Invalid typeof comparison value.", + notString: "Typeof comparisons should be to string literals." + } + }, + + create(context) { + + const VALID_TYPES = ["symbol", "undefined", "object", "boolean", "number", "string", "function", "bigint"], + OPERATORS = ["==", "===", "!=", "!=="]; + + const requireStringLiterals = context.options[0] && context.options[0].requireStringLiterals; + + /** + * Determines whether a node is a typeof expression. + * @param {ASTNode} node The node + * @returns {boolean} `true` if the node is a typeof expression + */ + function isTypeofExpression(node) { + return node.type === "UnaryExpression" && node.operator === "typeof"; + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + + UnaryExpression(node) { + if (isTypeofExpression(node)) { + const parent = context.getAncestors().pop(); + + if (parent.type === "BinaryExpression" && OPERATORS.indexOf(parent.operator) !== -1) { + const sibling = parent.left === node ? parent.right : parent.left; + + if (sibling.type === "Literal" || sibling.type === "TemplateLiteral" && !sibling.expressions.length) { + const value = sibling.type === "Literal" ? sibling.value : sibling.quasis[0].value.cooked; + + if (VALID_TYPES.indexOf(value) === -1) { + context.report({ node: sibling, messageId: "invalidValue" }); + } + } else if (requireStringLiterals && !isTypeofExpression(sibling)) { + context.report({ node: sibling, messageId: "notString" }); + } + } + } + } + + }; + + } +}; + +/** + * @fileoverview Rule to enforce var declarations are only at the top of a function. + * @author Danny Fritz + * @author Gyandeep Singh + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var varsOnTop = { + meta: { + type: "suggestion", + + docs: { + description: "require `var` declarations be placed at the top of their containing scope", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/vars-on-top" + }, + + schema: [], + messages: { + top: "All 'var' declarations must be at the top of the function scope." + } + }, + + create(context) { + + //-------------------------------------------------------------------------- + // Helpers + //-------------------------------------------------------------------------- + + // eslint-disable-next-line jsdoc/require-description + /** + * @param {ASTNode} node any node + * @returns {boolean} whether the given node structurally represents a directive + */ + function looksLikeDirective(node) { + return node.type === "ExpressionStatement" && + node.expression.type === "Literal" && typeof node.expression.value === "string"; + } + + /** + * Check to see if its a ES6 import declaration + * @param {ASTNode} node any node + * @returns {boolean} whether the given node represents a import declaration + */ + function looksLikeImport(node) { + return node.type === "ImportDeclaration" || node.type === "ImportSpecifier" || + node.type === "ImportDefaultSpecifier" || node.type === "ImportNamespaceSpecifier"; + } + + /** + * Checks whether a given node is a variable declaration or not. + * @param {ASTNode} node any node + * @returns {boolean} `true` if the node is a variable declaration. + */ + function isVariableDeclaration(node) { + return ( + node.type === "VariableDeclaration" || + ( + node.type === "ExportNamedDeclaration" && + node.declaration && + node.declaration.type === "VariableDeclaration" + ) + ); + } + + /** + * Checks whether this variable is on top of the block body + * @param {ASTNode} node The node to check + * @param {ASTNode[]} statements collection of ASTNodes for the parent node block + * @returns {boolean} True if var is on top otherwise false + */ + function isVarOnTop(node, statements) { + const l = statements.length; + let i = 0; + + // skip over directives + for (; i < l; ++i) { + if (!looksLikeDirective(statements[i]) && !looksLikeImport(statements[i])) { + break; + } + } + + for (; i < l; ++i) { + if (!isVariableDeclaration(statements[i])) { + return false; + } + if (statements[i] === node) { + return true; + } + } + + return false; + } + + /** + * Checks whether variable is on top at the global level + * @param {ASTNode} node The node to check + * @param {ASTNode} parent Parent of the node + * @returns {void} + */ + function globalVarCheck(node, parent) { + if (!isVarOnTop(node, parent.body)) { + context.report({ node, messageId: "top" }); + } + } + + /** + * Checks whether variable is on top at functional block scope level + * @param {ASTNode} node The node to check + * @param {ASTNode} parent Parent of the node + * @param {ASTNode} grandParent Parent of the node's parent + * @returns {void} + */ + function blockScopeVarCheck(node, parent, grandParent) { + if (!(/Function/u.test(grandParent.type) && + parent.type === "BlockStatement" && + isVarOnTop(node, parent.body))) { + context.report({ node, messageId: "top" }); + } + } + + //-------------------------------------------------------------------------- + // Public API + //-------------------------------------------------------------------------- + + return { + "VariableDeclaration[kind='var']"(node) { + if (node.parent.type === "ExportNamedDeclaration") { + globalVarCheck(node.parent, node.parent.parent); + } else if (node.parent.type === "Program") { + globalVarCheck(node, node.parent); + } else { + blockScopeVarCheck(node, node.parent, node.parent.parent); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag when IIFE is not wrapped in parens + * @author Ilya Volodin + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//---------------------------------------------------------------------- +// Helpers +//---------------------------------------------------------------------- + +/** + * Check if the given node is callee of a `NewExpression` node + * @param {ASTNode} node node to check + * @returns {boolean} True if the node is callee of a `NewExpression` node + * @private + */ +function isCalleeOfNewExpression(node) { + const maybeCallee = node.parent.type === "ChainExpression" + ? node.parent + : node; + + return ( + maybeCallee.parent.type === "NewExpression" && + maybeCallee.parent.callee === maybeCallee + ); +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var wrapIife = { + meta: { + type: "layout", + + docs: { + description: "require parentheses around immediate `function` invocations", + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/wrap-iife" + }, + + schema: [ + { + enum: ["outside", "inside", "any"] + }, + { + type: "object", + properties: { + functionPrototypeMethods: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + fixable: "code", + messages: { + wrapInvocation: "Wrap an immediate function invocation in parentheses.", + wrapExpression: "Wrap only the function expression in parens.", + moveInvocation: "Move the invocation into the parens that contain the function." + } + }, + + create(context) { + + const style = context.options[0] || "outside"; + const includeFunctionPrototypeMethods = context.options[1] && context.options[1].functionPrototypeMethods; + + const sourceCode = context.getSourceCode(); + + /** + * Check if the node is wrapped in any (). All parens count: grouping parens and parens for constructs such as if() + * @param {ASTNode} node node to evaluate + * @returns {boolean} True if it is wrapped in any parens + * @private + */ + function isWrappedInAnyParens(node) { + return astUtils.isParenthesised(sourceCode, node); + } + + /** + * Check if the node is wrapped in grouping (). Parens for constructs such as if() don't count + * @param {ASTNode} node node to evaluate + * @returns {boolean} True if it is wrapped in grouping parens + * @private + */ + function isWrappedInGroupingParens(node) { + return require$$0__default$1['default'].isParenthesized(1, node, sourceCode); + } + + /** + * Get the function node from an IIFE + * @param {ASTNode} node node to evaluate + * @returns {ASTNode} node that is the function expression of the given IIFE, or null if none exist + */ + function getFunctionNodeFromIIFE(node) { + const callee = astUtils.skipChainExpression(node.callee); + + if (callee.type === "FunctionExpression") { + return callee; + } + + if (includeFunctionPrototypeMethods && + callee.type === "MemberExpression" && + callee.object.type === "FunctionExpression" && + (astUtils.getStaticPropertyName(callee) === "call" || astUtils.getStaticPropertyName(callee) === "apply") + ) { + return callee.object; + } + + return null; + } + + + return { + CallExpression(node) { + const innerNode = getFunctionNodeFromIIFE(node); + + if (!innerNode) { + return; + } + + const isCallExpressionWrapped = isWrappedInAnyParens(node), + isFunctionExpressionWrapped = isWrappedInAnyParens(innerNode); + + if (!isCallExpressionWrapped && !isFunctionExpressionWrapped) { + context.report({ + node, + messageId: "wrapInvocation", + fix(fixer) { + const nodeToSurround = style === "inside" ? innerNode : node; + + return fixer.replaceText(nodeToSurround, `(${sourceCode.getText(nodeToSurround)})`); + } + }); + } else if (style === "inside" && !isFunctionExpressionWrapped) { + context.report({ + node, + messageId: "wrapExpression", + fix(fixer) { + + // The outer call expression will always be wrapped at this point. + + if (isWrappedInGroupingParens(node) && !isCalleeOfNewExpression(node)) { + + /* + * Parenthesize the function expression and remove unnecessary grouping parens around the call expression. + * Replace the range between the end of the function expression and the end of the call expression. + * for example, in `(function(foo) {}(bar))`, the range `(bar))` should get replaced with `)(bar)`. + */ + + const parenAfter = sourceCode.getTokenAfter(node); + + return fixer.replaceTextRange( + [innerNode.range[1], parenAfter.range[1]], + `)${sourceCode.getText().slice(innerNode.range[1], parenAfter.range[0])}` + ); + } + + /* + * Call expression is wrapped in mandatory parens such as if(), or in necessary grouping parens. + * These parens cannot be removed, so just parenthesize the function expression. + */ + + return fixer.replaceText(innerNode, `(${sourceCode.getText(innerNode)})`); + } + }); + } else if (style === "outside" && !isCallExpressionWrapped) { + context.report({ + node, + messageId: "moveInvocation", + fix(fixer) { + + /* + * The inner function expression will always be wrapped at this point. + * It's only necessary to replace the range between the end of the function expression + * and the call expression. For example, in `(function(foo) {})(bar)`, the range `)(bar)` + * should get replaced with `(bar))`. + */ + const parenAfter = sourceCode.getTokenAfter(innerNode); + + return fixer.replaceTextRange( + [parenAfter.range[0], node.range[1]], + `${sourceCode.getText().slice(parenAfter.range[1], node.range[1])})` + ); + } + }); + } + } + }; + + } +}; + +/** + * @fileoverview Rule to flag when regex literals are not wrapped in parens + * @author Matt DuVall + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var wrapRegex = { + meta: { + type: "layout", + + docs: { + description: "require parenthesis around regex literals", + category: "Stylistic Issues", + recommended: false, + url: "https://eslint.org/docs/rules/wrap-regex" + }, + + schema: [], + fixable: "code", + + messages: { + requireParens: "Wrap the regexp literal in parens to disambiguate the slash." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + return { + + Literal(node) { + const token = sourceCode.getFirstToken(node), + nodeType = token.type; + + if (nodeType === "RegularExpression") { + const beforeToken = sourceCode.getTokenBefore(node); + const afterToken = sourceCode.getTokenAfter(node); + const ancestors = context.getAncestors(); + const grandparent = ancestors[ancestors.length - 1]; + + if (grandparent.type === "MemberExpression" && grandparent.object === node && + !(beforeToken && beforeToken.value === "(" && afterToken && afterToken.value === ")")) { + context.report({ + node, + messageId: "requireParens", + fix: fixer => fixer.replaceText(node, `(${sourceCode.getText(node)})`) + }); + } + } + } + }; + + } +}; + +/** + * @fileoverview Rule to check the spacing around the * in yield* expressions. + * @author Bryan Smith + */ + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var yieldStarSpacing = { + meta: { + type: "layout", + + docs: { + description: "require or disallow spacing around the `*` in `yield*` expressions", + category: "ECMAScript 6", + recommended: false, + url: "https://eslint.org/docs/rules/yield-star-spacing" + }, + + fixable: "whitespace", + + schema: [ + { + oneOf: [ + { + enum: ["before", "after", "both", "neither"] + }, + { + type: "object", + properties: { + before: { type: "boolean" }, + after: { type: "boolean" } + }, + additionalProperties: false + } + ] + } + ], + messages: { + missingBefore: "Missing space before *.", + missingAfter: "Missing space after *.", + unexpectedBefore: "Unexpected space before *.", + unexpectedAfter: "Unexpected space after *." + } + }, + + create(context) { + const sourceCode = context.getSourceCode(); + + const mode = (function(option) { + if (!option || typeof option === "string") { + return { + before: { before: true, after: false }, + after: { before: false, after: true }, + both: { before: true, after: true }, + neither: { before: false, after: false } + }[option || "after"]; + } + return option; + }(context.options[0])); + + /** + * Checks the spacing between two tokens before or after the star token. + * @param {string} side Either "before" or "after". + * @param {Token} leftToken `function` keyword token if side is "before", or + * star token if side is "after". + * @param {Token} rightToken Star token if side is "before", or identifier + * token if side is "after". + * @returns {void} + */ + function checkSpacing(side, leftToken, rightToken) { + if (sourceCode.isSpaceBetweenTokens(leftToken, rightToken) !== mode[side]) { + const after = leftToken.value === "*"; + const spaceRequired = mode[side]; + const node = after ? leftToken : rightToken; + let messageId = ""; + + if (spaceRequired) { + messageId = side === "before" ? "missingBefore" : "missingAfter"; + } else { + messageId = side === "before" ? "unexpectedBefore" : "unexpectedAfter"; + } + + context.report({ + node, + messageId, + fix(fixer) { + if (spaceRequired) { + if (after) { + return fixer.insertTextAfter(node, " "); + } + return fixer.insertTextBefore(node, " "); + } + return fixer.removeRange([leftToken.range[1], rightToken.range[0]]); + } + }); + } + } + + /** + * Enforces the spacing around the star if node is a yield* expression. + * @param {ASTNode} node A yield expression node. + * @returns {void} + */ + function checkExpression(node) { + if (!node.delegate) { + return; + } + + const tokens = sourceCode.getFirstTokens(node, 3); + const yieldToken = tokens[0]; + const starToken = tokens[1]; + const nextToken = tokens[2]; + + checkSpacing("before", yieldToken, starToken); + checkSpacing("after", starToken, nextToken); + } + + return { + YieldExpression: checkExpression + }; + + } +}; + +/** + * @fileoverview Rule to require or disallow yoda comparisons + * @author Nicholas C. Zakas + */ + +//-------------------------------------------------------------------------- +// Requirements +//-------------------------------------------------------------------------- + + + +//-------------------------------------------------------------------------- +// Helpers +//-------------------------------------------------------------------------- + +/** + * Determines whether an operator is a comparison operator. + * @param {string} operator The operator to check. + * @returns {boolean} Whether or not it is a comparison operator. + */ +function isComparisonOperator(operator) { + return /^(==|===|!=|!==|<|>|<=|>=)$/u.test(operator); +} + +/** + * Determines whether an operator is an equality operator. + * @param {string} operator The operator to check. + * @returns {boolean} Whether or not it is an equality operator. + */ +function isEqualityOperator(operator) { + return /^(==|===)$/u.test(operator); +} + +/** + * Determines whether an operator is one used in a range test. + * Allowed operators are `<` and `<=`. + * @param {string} operator The operator to check. + * @returns {boolean} Whether the operator is used in range tests. + */ +function isRangeTestOperator(operator) { + return ["<", "<="].indexOf(operator) >= 0; +} + +/** + * Determines whether a non-Literal node is a negative number that should be + * treated as if it were a single Literal node. + * @param {ASTNode} node Node to test. + * @returns {boolean} True if the node is a negative number that looks like a + * real literal and should be treated as such. + */ +function isNegativeNumericLiteral(node) { + return ( + node.type === "UnaryExpression" && + node.operator === "-" && + node.prefix && + astUtils.isNumericLiteral(node.argument) + ); +} + +/** + * Determines whether a node is a Template Literal which can be determined statically. + * @param {ASTNode} node Node to test + * @returns {boolean} True if the node is a Template Literal without expression. + */ +function isStaticTemplateLiteral(node) { + return node.type === "TemplateLiteral" && node.expressions.length === 0; +} + +/** + * Determines whether a non-Literal node should be treated as a single Literal node. + * @param {ASTNode} node Node to test + * @returns {boolean} True if the node should be treated as a single Literal node. + */ +function looksLikeLiteral(node) { + return isNegativeNumericLiteral(node) || isStaticTemplateLiteral(node); +} + +/** + * Attempts to derive a Literal node from nodes that are treated like literals. + * @param {ASTNode} node Node to normalize. + * @returns {ASTNode} One of the following options. + * 1. The original node if the node is already a Literal + * 2. A normalized Literal node with the negative number as the value if the + * node represents a negative number literal. + * 3. A normalized Literal node with the string as the value if the node is + * a Template Literal without expression. + * 4. Otherwise `null`. + */ +function getNormalizedLiteral(node) { + if (node.type === "Literal") { + return node; + } + + if (isNegativeNumericLiteral(node)) { + return { + type: "Literal", + value: -node.argument.value, + raw: `-${node.argument.value}` + }; + } + + if (isStaticTemplateLiteral(node)) { + return { + type: "Literal", + value: node.quasis[0].value.cooked, + raw: node.quasis[0].value.raw + }; + } + + return null; +} + +//------------------------------------------------------------------------------ +// Rule Definition +//------------------------------------------------------------------------------ + +var yoda = { + meta: { + type: "suggestion", + + docs: { + description: 'require or disallow "Yoda" conditions', + category: "Best Practices", + recommended: false, + url: "https://eslint.org/docs/rules/yoda" + }, + + schema: [ + { + enum: ["always", "never"] + }, + { + type: "object", + properties: { + exceptRange: { + type: "boolean", + default: false + }, + onlyEquality: { + type: "boolean", + default: false + } + }, + additionalProperties: false + } + ], + + fixable: "code", + messages: { + expected: + "Expected literal to be on the {{expectedSide}} side of {{operator}}." + } + }, + + create(context) { + + // Default to "never" (!always) if no option + const always = context.options[0] === "always"; + const exceptRange = + context.options[1] && context.options[1].exceptRange; + const onlyEquality = + context.options[1] && context.options[1].onlyEquality; + + const sourceCode = context.getSourceCode(); + + /** + * Determines whether node represents a range test. + * A range test is a "between" test like `(0 <= x && x < 1)` or an "outside" + * test like `(x < 0 || 1 <= x)`. It must be wrapped in parentheses, and + * both operators must be `<` or `<=`. Finally, the literal on the left side + * must be less than or equal to the literal on the right side so that the + * test makes any sense. + * @param {ASTNode} node LogicalExpression node to test. + * @returns {boolean} Whether node is a range test. + */ + function isRangeTest(node) { + const left = node.left, + right = node.right; + + /** + * Determines whether node is of the form `0 <= x && x < 1`. + * @returns {boolean} Whether node is a "between" range test. + */ + function isBetweenTest() { + if (node.operator === "&&" && astUtils.isSameReference(left.right, right.left)) { + const leftLiteral = getNormalizedLiteral(left.left); + const rightLiteral = getNormalizedLiteral(right.right); + + if (leftLiteral === null && rightLiteral === null) { + return false; + } + + if (rightLiteral === null || leftLiteral === null) { + return true; + } + + if (leftLiteral.value <= rightLiteral.value) { + return true; + } + } + return false; + } + + /** + * Determines whether node is of the form `x < 0 || 1 <= x`. + * @returns {boolean} Whether node is an "outside" range test. + */ + function isOutsideTest() { + if (node.operator === "||" && astUtils.isSameReference(left.left, right.right)) { + const leftLiteral = getNormalizedLiteral(left.right); + const rightLiteral = getNormalizedLiteral(right.left); + + if (leftLiteral === null && rightLiteral === null) { + return false; + } + + if (rightLiteral === null || leftLiteral === null) { + return true; + } + + if (leftLiteral.value <= rightLiteral.value) { + return true; + } + } + + return false; + } + + /** + * Determines whether node is wrapped in parentheses. + * @returns {boolean} Whether node is preceded immediately by an open + * paren token and followed immediately by a close + * paren token. + */ + function isParenWrapped() { + return astUtils.isParenthesised(sourceCode, node); + } + + return ( + node.type === "LogicalExpression" && + left.type === "BinaryExpression" && + right.type === "BinaryExpression" && + isRangeTestOperator(left.operator) && + isRangeTestOperator(right.operator) && + (isBetweenTest() || isOutsideTest()) && + isParenWrapped() + ); + } + + const OPERATOR_FLIP_MAP = { + "===": "===", + "!==": "!==", + "==": "==", + "!=": "!=", + "<": ">", + ">": "<", + "<=": ">=", + ">=": "<=" + }; + + /** + * Returns a string representation of a BinaryExpression node with its sides/operator flipped around. + * @param {ASTNode} node The BinaryExpression node + * @returns {string} A string representation of the node with the sides and operator flipped + */ + function getFlippedString(node) { + const operatorToken = sourceCode.getFirstTokenBetween( + node.left, + node.right, + token => token.value === node.operator + ); + const lastLeftToken = sourceCode.getTokenBefore(operatorToken); + const firstRightToken = sourceCode.getTokenAfter(operatorToken); + + const source = sourceCode.getText(); + + const leftText = source.slice( + node.range[0], + lastLeftToken.range[1] + ); + const textBeforeOperator = source.slice( + lastLeftToken.range[1], + operatorToken.range[0] + ); + const textAfterOperator = source.slice( + operatorToken.range[1], + firstRightToken.range[0] + ); + const rightText = source.slice( + firstRightToken.range[0], + node.range[1] + ); + + const tokenBefore = sourceCode.getTokenBefore(node); + const tokenAfter = sourceCode.getTokenAfter(node); + let prefix = ""; + let suffix = ""; + + if ( + tokenBefore && + tokenBefore.range[1] === node.range[0] && + !astUtils.canTokensBeAdjacent(tokenBefore, firstRightToken) + ) { + prefix = " "; + } + + if ( + tokenAfter && + node.range[1] === tokenAfter.range[0] && + !astUtils.canTokensBeAdjacent(lastLeftToken, tokenAfter) + ) { + suffix = " "; + } + + return ( + prefix + + rightText + + textBeforeOperator + + OPERATOR_FLIP_MAP[operatorToken.value] + + textAfterOperator + + leftText + + suffix + ); + } + + //-------------------------------------------------------------------------- + // Public + //-------------------------------------------------------------------------- + + return { + BinaryExpression(node) { + const expectedLiteral = always ? node.left : node.right; + const expectedNonLiteral = always ? node.right : node.left; + + // If `expectedLiteral` is not a literal, and `expectedNonLiteral` is a literal, raise an error. + if ( + (expectedNonLiteral.type === "Literal" || + looksLikeLiteral(expectedNonLiteral)) && + !( + expectedLiteral.type === "Literal" || + looksLikeLiteral(expectedLiteral) + ) && + !(!isEqualityOperator(node.operator) && onlyEquality) && + isComparisonOperator(node.operator) && + !(exceptRange && isRangeTest(context.getAncestors().pop())) + ) { + context.report({ + node, + messageId: "expected", + data: { + operator: node.operator, + expectedSide: always ? "left" : "right" + }, + fix: fixer => + fixer.replaceText(node, getFlippedString(node)) + }); + } + } + }; + } +}; + +/** + * @fileoverview Collects the built-in rules into a map structure so that they can be imported all at once and without + * using the file-system directly. + * @author Peter (Somogyvari) Metz + */ + +/* eslint sort-keys: ["error", "asc"] */ + +const { LazyLoadingRuleMap } = lazyLoadingRuleMap; + +/** @type {Map} */ +var rules$2 = new LazyLoadingRuleMap(Object.entries({ + "accessor-pairs": () => accessorPairs, + "array-bracket-newline": () => arrayBracketNewline, + "array-bracket-spacing": () => arrayBracketSpacing, + "array-callback-return": () => arrayCallbackReturn, + "array-element-newline": () => arrayElementNewline, + "arrow-body-style": () => arrowBodyStyle, + "arrow-parens": () => arrowParens, + "arrow-spacing": () => arrowSpacing, + "block-scoped-var": () => blockScopedVar, + "block-spacing": () => blockSpacing, + "brace-style": () => braceStyle, + "callback-return": () => callbackReturn, + camelcase: () => camelcase, + "capitalized-comments": () => capitalizedComments, + "class-methods-use-this": () => classMethodsUseThis, + "comma-dangle": () => commaDangle, + "comma-spacing": () => commaSpacing, + "comma-style": () => commaStyle, + complexity: () => complexity, + "computed-property-spacing": () => computedPropertySpacing, + "consistent-return": () => consistentReturn, + "consistent-this": () => consistentThis, + "constructor-super": () => constructorSuper, + curly: () => curly, + "default-case": () => defaultCase, + "default-case-last": () => defaultCaseLast, + "default-param-last": () => defaultParamLast, + "dot-location": () => dotLocation, + "dot-notation": () => dotNotation, + "eol-last": () => eolLast, + eqeqeq: () => eqeqeq, + "for-direction": () => forDirection, + "func-call-spacing": () => funcCallSpacing, + "func-name-matching": () => funcNameMatching, + "func-names": () => funcNames, + "func-style": () => funcStyle, + "function-call-argument-newline": () => functionCallArgumentNewline, + "function-paren-newline": () => functionParenNewline, + "generator-star-spacing": () => generatorStarSpacing, + "getter-return": () => getterReturn, + "global-require": () => globalRequire, + "grouped-accessor-pairs": () => groupedAccessorPairs, + "guard-for-in": () => guardForIn, + "handle-callback-err": () => handleCallbackErr, + "id-blacklist": () => idBlacklist, + "id-denylist": () => idDenylist, + "id-length": () => idLength, + "id-match": () => idMatch, + "implicit-arrow-linebreak": () => implicitArrowLinebreak, + indent: () => indent, + "indent-legacy": () => indentLegacy, + "init-declarations": () => initDeclarations, + "jsx-quotes": () => jsxQuotes, + "key-spacing": () => keySpacing, + "keyword-spacing": () => keywordSpacing, + "line-comment-position": () => lineCommentPosition, + "linebreak-style": () => linebreakStyle, + "lines-around-comment": () => linesAroundComment, + "lines-around-directive": () => linesAroundDirective, + "lines-between-class-members": () => linesBetweenClassMembers, + "max-classes-per-file": () => maxClassesPerFile, + "max-depth": () => maxDepth, + "max-len": () => maxLen, + "max-lines": () => maxLines, + "max-lines-per-function": () => maxLinesPerFunction, + "max-nested-callbacks": () => maxNestedCallbacks, + "max-params": () => maxParams, + "max-statements": () => maxStatements, + "max-statements-per-line": () => maxStatementsPerLine, + "multiline-comment-style": () => multilineCommentStyle, + "multiline-ternary": () => multilineTernary, + "new-cap": () => newCap, + "new-parens": () => newParens, + "newline-after-var": () => newlineAfterVar, + "newline-before-return": () => newlineBeforeReturn, + "newline-per-chained-call": () => newlinePerChainedCall, + "no-alert": () => noAlert, + "no-array-constructor": () => noArrayConstructor, + "no-async-promise-executor": () => noAsyncPromiseExecutor, + "no-await-in-loop": () => noAwaitInLoop, + "no-bitwise": () => noBitwise, + "no-buffer-constructor": () => noBufferConstructor, + "no-caller": () => noCaller, + "no-case-declarations": () => noCaseDeclarations, + "no-catch-shadow": () => noCatchShadow, + "no-class-assign": () => noClassAssign, + "no-compare-neg-zero": () => noCompareNegZero, + "no-cond-assign": () => noCondAssign, + "no-confusing-arrow": () => noConfusingArrow, + "no-console": () => noConsole, + "no-const-assign": () => noConstAssign, + "no-constant-condition": () => noConstantCondition, + "no-constructor-return": () => noConstructorReturn, + "no-continue": () => noContinue, + "no-control-regex": () => noControlRegex, + "no-debugger": () => noDebugger, + "no-delete-var": () => noDeleteVar, + "no-div-regex": () => noDivRegex, + "no-dupe-args": () => noDupeArgs, + "no-dupe-class-members": () => noDupeClassMembers, + "no-dupe-else-if": () => noDupeElseIf, + "no-dupe-keys": () => noDupeKeys, + "no-duplicate-case": () => noDuplicateCase, + "no-duplicate-imports": () => noDuplicateImports, + "no-else-return": () => noElseReturn, + "no-empty": () => noEmpty, + "no-empty-character-class": () => noEmptyCharacterClass, + "no-empty-function": () => noEmptyFunction, + "no-empty-pattern": () => noEmptyPattern, + "no-eq-null": () => noEqNull, + "no-eval": () => noEval, + "no-ex-assign": () => noExAssign, + "no-extend-native": () => noExtendNative, + "no-extra-bind": () => noExtraBind, + "no-extra-boolean-cast": () => noExtraBooleanCast, + "no-extra-label": () => noExtraLabel, + "no-extra-parens": () => noExtraParens, + "no-extra-semi": () => noExtraSemi, + "no-fallthrough": () => noFallthrough, + "no-floating-decimal": () => noFloatingDecimal, + "no-func-assign": () => noFuncAssign, + "no-global-assign": () => noGlobalAssign, + "no-implicit-coercion": () => noImplicitCoercion, + "no-implicit-globals": () => noImplicitGlobals, + "no-implied-eval": () => noImpliedEval, + "no-import-assign": () => noImportAssign, + "no-inline-comments": () => noInlineComments, + "no-inner-declarations": () => noInnerDeclarations, + "no-invalid-regexp": () => noInvalidRegexp, + "no-invalid-this": () => noInvalidThis, + "no-irregular-whitespace": () => noIrregularWhitespace, + "no-iterator": () => noIterator, + "no-label-var": () => noLabelVar, + "no-labels": () => noLabels, + "no-lone-blocks": () => noLoneBlocks, + "no-lonely-if": () => noLonelyIf, + "no-loop-func": () => noLoopFunc, + "no-loss-of-precision": () => noLossOfPrecision, + "no-magic-numbers": () => noMagicNumbers, + "no-misleading-character-class": () => noMisleadingCharacterClass, + "no-mixed-operators": () => noMixedOperators, + "no-mixed-requires": () => noMixedRequires, + "no-mixed-spaces-and-tabs": () => noMixedSpacesAndTabs, + "no-multi-assign": () => noMultiAssign, + "no-multi-spaces": () => noMultiSpaces, + "no-multi-str": () => noMultiStr, + "no-multiple-empty-lines": () => noMultipleEmptyLines, + "no-native-reassign": () => noNativeReassign, + "no-negated-condition": () => noNegatedCondition, + "no-negated-in-lhs": () => noNegatedInLhs, + "no-nested-ternary": () => noNestedTernary, + "no-new": () => noNew, + "no-new-func": () => noNewFunc, + "no-new-object": () => noNewObject, + "no-new-require": () => noNewRequire, + "no-new-symbol": () => noNewSymbol, + "no-new-wrappers": () => noNewWrappers, + "no-nonoctal-decimal-escape": () => noNonoctalDecimalEscape, + "no-obj-calls": () => noObjCalls, + "no-octal": () => noOctal, + "no-octal-escape": () => noOctalEscape, + "no-param-reassign": () => noParamReassign, + "no-path-concat": () => noPathConcat, + "no-plusplus": () => noPlusplus, + "no-process-env": () => noProcessEnv, + "no-process-exit": () => noProcessExit, + "no-promise-executor-return": () => noPromiseExecutorReturn, + "no-proto": () => noProto, + "no-prototype-builtins": () => noPrototypeBuiltins, + "no-redeclare": () => noRedeclare, + "no-regex-spaces": () => noRegexSpaces, + "no-restricted-exports": () => noRestrictedExports, + "no-restricted-globals": () => noRestrictedGlobals, + "no-restricted-imports": () => noRestrictedImports, + "no-restricted-modules": () => noRestrictedModules, + "no-restricted-properties": () => noRestrictedProperties, + "no-restricted-syntax": () => noRestrictedSyntax, + "no-return-assign": () => noReturnAssign, + "no-return-await": () => noReturnAwait, + "no-script-url": () => noScriptUrl, + "no-self-assign": () => noSelfAssign, + "no-self-compare": () => noSelfCompare, + "no-sequences": () => noSequences, + "no-setter-return": () => noSetterReturn, + "no-shadow": () => noShadow, + "no-shadow-restricted-names": () => noShadowRestrictedNames, + "no-spaced-func": () => noSpacedFunc, + "no-sparse-arrays": () => noSparseArrays, + "no-sync": () => noSync, + "no-tabs": () => noTabs, + "no-template-curly-in-string": () => noTemplateCurlyInString, + "no-ternary": () => noTernary, + "no-this-before-super": () => noThisBeforeSuper, + "no-throw-literal": () => noThrowLiteral, + "no-trailing-spaces": () => noTrailingSpaces, + "no-undef": () => noUndef, + "no-undef-init": () => noUndefInit, + "no-undefined": () => noUndefined, + "no-underscore-dangle": () => noUnderscoreDangle, + "no-unexpected-multiline": () => noUnexpectedMultiline, + "no-unmodified-loop-condition": () => noUnmodifiedLoopCondition, + "no-unneeded-ternary": () => noUnneededTernary, + "no-unreachable": () => noUnreachable, + "no-unreachable-loop": () => noUnreachableLoop, + "no-unsafe-finally": () => noUnsafeFinally, + "no-unsafe-negation": () => noUnsafeNegation, + "no-unsafe-optional-chaining": () => noUnsafeOptionalChaining, + "no-unused-expressions": () => noUnusedExpressions, + "no-unused-labels": () => noUnusedLabels, + "no-unused-vars": () => noUnusedVars, + "no-use-before-define": () => noUseBeforeDefine, + "no-useless-backreference": () => noUselessBackreference, + "no-useless-call": () => noUselessCall, + "no-useless-catch": () => noUselessCatch, + "no-useless-computed-key": () => noUselessComputedKey, + "no-useless-concat": () => noUselessConcat, + "no-useless-constructor": () => noUselessConstructor, + "no-useless-escape": () => noUselessEscape, + "no-useless-rename": () => noUselessRename, + "no-useless-return": () => noUselessReturn, + "no-var": () => noVar, + "no-void": () => noVoid, + "no-warning-comments": () => noWarningComments, + "no-whitespace-before-property": () => noWhitespaceBeforeProperty, + "no-with": () => noWith, + "nonblock-statement-body-position": () => nonblockStatementBodyPosition, + "object-curly-newline": () => objectCurlyNewline, + "object-curly-spacing": () => objectCurlySpacing, + "object-property-newline": () => objectPropertyNewline, + "object-shorthand": () => objectShorthand, + "one-var": () => oneVar, + "one-var-declaration-per-line": () => oneVarDeclarationPerLine, + "operator-assignment": () => operatorAssignment, + "operator-linebreak": () => operatorLinebreak, + "padded-blocks": () => paddedBlocks, + "padding-line-between-statements": () => paddingLineBetweenStatements, + "prefer-arrow-callback": () => preferArrowCallback, + "prefer-const": () => preferConst, + "prefer-destructuring": () => preferDestructuring, + "prefer-exponentiation-operator": () => preferExponentiationOperator, + "prefer-named-capture-group": () => preferNamedCaptureGroup, + "prefer-numeric-literals": () => preferNumericLiterals, + "prefer-object-spread": () => preferObjectSpread, + "prefer-promise-reject-errors": () => preferPromiseRejectErrors, + "prefer-reflect": () => preferReflect, + "prefer-regex-literals": () => preferRegexLiterals, + "prefer-rest-params": () => preferRestParams, + "prefer-spread": () => preferSpread, + "prefer-template": () => preferTemplate, + "quote-props": () => quoteProps, + quotes: () => quotes, + radix: () => radix, + "require-atomic-updates": () => requireAtomicUpdates, + "require-await": () => requireAwait, + "require-jsdoc": () => requireJsdoc$1, + "require-unicode-regexp": () => requireUnicodeRegexp, + "require-yield": () => requireYield, + "rest-spread-spacing": () => restSpreadSpacing, + semi: () => semi, + "semi-spacing": () => semiSpacing, + "semi-style": () => semiStyle, + "sort-imports": () => sortImports, + "sort-keys": () => sortKeys, + "sort-vars": () => sortVars, + "space-before-blocks": () => spaceBeforeBlocks, + "space-before-function-paren": () => spaceBeforeFunctionParen, + "space-in-parens": () => spaceInParens, + "space-infix-ops": () => spaceInfixOps, + "space-unary-ops": () => spaceUnaryOps, + "spaced-comment": () => spacedComment, + strict: () => strict, + "switch-colon-spacing": () => switchColonSpacing, + "symbol-description": () => symbolDescription, + "template-curly-spacing": () => templateCurlySpacing, + "template-tag-spacing": () => templateTagSpacing, + "unicode-bom": () => unicodeBom, + "use-isnan": () => useIsnan, + "valid-jsdoc": () => validJsdoc, + "valid-typeof": () => validTypeof, + "vars-on-top": () => varsOnTop, + "wrap-iife": () => wrapIife, + "wrap-regex": () => wrapRegex, + "yield-star-spacing": () => yieldStarSpacing, + yoda: () => yoda +})); + +/** + * @fileoverview Defines a storage for rules. + * @author Nicholas C. Zakas + * @author aladdin-add + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Normalizes a rule module to the new-style API + * @param {(Function|{create: Function})} rule A rule object, which can either be a function + * ("old-style") or an object with a `create` method ("new-style") + * @returns {{create: Function}} A new-style rule. + */ +function normalizeRule(rule) { + return typeof rule === "function" ? Object.assign({ create: rule }, rule) : rule; +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +class Rules { + constructor() { + this._rules = Object.create(null); + } + + /** + * Registers a rule module for rule id in storage. + * @param {string} ruleId Rule id (file name). + * @param {Function} ruleModule Rule handler. + * @returns {void} + */ + define(ruleId, ruleModule) { + this._rules[ruleId] = normalizeRule(ruleModule); + } + + /** + * Access rule handler by id (file name). + * @param {string} ruleId Rule id (file name). + * @returns {{create: Function, schema: JsonSchema[]}} + * A rule. This is normalized to always have the new-style shape with a `create` method. + */ + get(ruleId) { + if (typeof this._rules[ruleId] === "string") { + this.define(ruleId, commonjsRequire(this._rules[ruleId])); + } + if (this._rules[ruleId]) { + return this._rules[ruleId]; + } + if (rules$2.has(ruleId)) { + return rules$2.get(ruleId); + } + + return null; + } + + *[Symbol.iterator]() { + yield* rules$2; + + for (const ruleId of Object.keys(this._rules)) { + yield [ruleId, this.get(ruleId)]; + } + } +} + +var rules$1 = Rules; + +/** + * @fileoverview A variant of EventEmitter which does not give listeners information about each other + * @author Teddy Katz + */ + +//------------------------------------------------------------------------------ +// Typedefs +//------------------------------------------------------------------------------ + +/** + * An event emitter + * @typedef {Object} SafeEmitter + * @property {function(eventName: string, listenerFunc: Function): void} on Adds a listener for a given event name + * @property {function(eventName: string, arg1?: any, arg2?: any, arg3?: any)} emit Emits an event with a given name. + * This calls all the listeners that were listening for that name, with `arg1`, `arg2`, and `arg3` as arguments. + * @property {function(): string[]} eventNames Gets the list of event names that have registered listeners. + */ + +/** + * Creates an object which can listen for and emit events. + * This is similar to the EventEmitter API in Node's standard library, but it has a few differences. + * The goal is to allow multiple modules to attach arbitrary listeners to the same emitter, without + * letting the modules know about each other at all. + * 1. It has no special keys like `error` and `newListener`, which would allow modules to detect when + * another module throws an error or registers a listener. + * 2. It calls listener functions without any `this` value. (`EventEmitter` calls listeners with a + * `this` value of the emitter instance, which would give listeners access to other listeners.) + * @returns {SafeEmitter} An emitter + */ +var safeEmitter = () => { + const listeners = Object.create(null); + + return Object.freeze({ + on(eventName, listener) { + if (eventName in listeners) { + listeners[eventName].push(listener); + } else { + listeners[eventName] = [listener]; + } + }, + emit(eventName, ...args) { + if (eventName in listeners) { + listeners[eventName].forEach(listener => listener(...args)); + } + }, + eventNames() { + return Object.keys(listeners); + } + }); +}; + +/** + * @fileoverview An object that caches and applies source code fixes. + * @author Nicholas C. Zakas + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const debug$3 = require$$0__default['default']("eslint:source-code-fixer"); + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const BOM = "\uFEFF"; + +/** + * Compares items in a messages array by range. + * @param {Message} a The first message. + * @param {Message} b The second message. + * @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal. + * @private + */ +function compareMessagesByFixRange(a, b) { + return a.fix.range[0] - b.fix.range[0] || a.fix.range[1] - b.fix.range[1]; +} + +/** + * Compares items in a messages array by line and column. + * @param {Message} a The first message. + * @param {Message} b The second message. + * @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal. + * @private + */ +function compareMessagesByLocation(a, b) { + return a.line - b.line || a.column - b.column; +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * Utility for apply fixes to source code. + * @constructor + */ +function SourceCodeFixer$1() { + Object.freeze(this); +} + +/** + * Applies the fixes specified by the messages to the given text. Tries to be + * smart about the fixes and won't apply fixes over the same area in the text. + * @param {string} sourceText The text to apply the changes to. + * @param {Message[]} messages The array of messages reported by ESLint. + * @param {boolean|Function} [shouldFix=true] Determines whether each message should be fixed + * @returns {Object} An object containing the fixed text and any unfixed messages. + */ +SourceCodeFixer$1.applyFixes = function(sourceText, messages, shouldFix) { + debug$3("Applying fixes"); + + if (shouldFix === false) { + debug$3("shouldFix parameter was false, not attempting fixes"); + return { + fixed: false, + messages, + output: sourceText + }; + } + + // clone the array + const remainingMessages = [], + fixes = [], + bom = sourceText.startsWith(BOM) ? BOM : "", + text = bom ? sourceText.slice(1) : sourceText; + let lastPos = Number.NEGATIVE_INFINITY, + output = bom; + + /** + * Try to use the 'fix' from a problem. + * @param {Message} problem The message object to apply fixes from + * @returns {boolean} Whether fix was successfully applied + */ + function attemptFix(problem) { + const fix = problem.fix; + const start = fix.range[0]; + const end = fix.range[1]; + + // Remain it as a problem if it's overlapped or it's a negative range + if (lastPos >= start || start > end) { + remainingMessages.push(problem); + return false; + } + + // Remove BOM. + if ((start < 0 && end >= 0) || (start === 0 && fix.text.startsWith(BOM))) { + output = ""; + } + + // Make output to this fix. + output += text.slice(Math.max(0, lastPos), Math.max(0, start)); + output += fix.text; + lastPos = end; + return true; + } + + messages.forEach(problem => { + if (Object.prototype.hasOwnProperty.call(problem, "fix")) { + fixes.push(problem); + } else { + remainingMessages.push(problem); + } + }); + + if (fixes.length) { + debug$3("Found fixes to apply"); + let fixesWereApplied = false; + + for (const problem of fixes.sort(compareMessagesByFixRange)) { + if (typeof shouldFix !== "function" || shouldFix(problem)) { + attemptFix(problem); + + /* + * The only time attemptFix will fail is if a previous fix was + * applied which conflicts with it. So we can mark this as true. + */ + fixesWereApplied = true; + } else { + remainingMessages.push(problem); + } + } + output += text.slice(Math.max(0, lastPos)); + + return { + fixed: fixesWereApplied, + messages: remainingMessages.sort(compareMessagesByLocation), + output + }; + } + + debug$3("No fixes to apply"); + return { + fixed: false, + messages, + output: bom + text + }; + +}; + +var sourceCodeFixer = SourceCodeFixer$1; + +/** + * @fileoverview Tracks performance of individual rules. + * @author Brandon Mills + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/* istanbul ignore next */ +/** + * Align the string to left + * @param {string} str string to evaluate + * @param {int} len length of the string + * @param {string} ch delimiter character + * @returns {string} modified string + * @private + */ +function alignLeft(str, len, ch) { + return str + new Array(len - str.length + 1).join(ch || " "); +} + +/* istanbul ignore next */ +/** + * Align the string to right + * @param {string} str string to evaluate + * @param {int} len length of the string + * @param {string} ch delimiter character + * @returns {string} modified string + * @private + */ +function alignRight(str, len, ch) { + return new Array(len - str.length + 1).join(ch || " ") + str; +} + +//------------------------------------------------------------------------------ +// Module definition +//------------------------------------------------------------------------------ + +const enabled = !!process.env.TIMING; + +const HEADERS = ["Rule", "Time (ms)", "Relative"]; +const ALIGN = [alignLeft, alignRight, alignRight]; + +/** + * Decide how many rules to show in the output list. + * @returns {number} the number of rules to show + */ +function getListSize() { + const MINIMUM_SIZE = 10; + + if (typeof process.env.TIMING !== "string") { + return MINIMUM_SIZE; + } + + if (process.env.TIMING.toLowerCase() === "all") { + return Number.POSITIVE_INFINITY; + } + + const TIMING_ENV_VAR_AS_INTEGER = Number.parseInt(process.env.TIMING, 10); + + return TIMING_ENV_VAR_AS_INTEGER > 10 ? TIMING_ENV_VAR_AS_INTEGER : MINIMUM_SIZE; +} + +/* istanbul ignore next */ +/** + * display the data + * @param {Object} data Data object to be displayed + * @returns {void} prints modified string with console.log + * @private + */ +function display(data) { + let total = 0; + const rows = Object.keys(data) + .map(key => { + const time = data[key]; + + total += time; + return [key, time]; + }) + .sort((a, b) => b[1] - a[1]) + .slice(0, getListSize()); + + rows.forEach(row => { + row.push(`${(row[1] * 100 / total).toFixed(1)}%`); + row[1] = row[1].toFixed(3); + }); + + rows.unshift(HEADERS); + + const widths = []; + + rows.forEach(row => { + const len = row.length; + + for (let i = 0; i < len; i++) { + const n = row[i].length; + + if (!widths[i] || n > widths[i]) { + widths[i] = n; + } + } + }); + + const table = rows.map(row => ( + row + .map((cell, index) => ALIGN[index](cell, widths[index])) + .join(" | ") + )); + + table.splice(1, 0, widths.map((width, index) => { + const extraAlignment = index !== 0 && index !== widths.length - 1 ? 2 : 1; + + return ALIGN[index](":", width + extraAlignment, "-"); + }).join("|")); + + console.log(table.join("\n")); // eslint-disable-line no-console +} + +/* istanbul ignore next */ +var timing = (function() { + + const data = Object.create(null); + + /** + * Time the run + * @param {*} key key from the data object + * @param {Function} fn function to be called + * @returns {Function} function to be executed + * @private + */ + function time(key, fn) { + if (typeof data[key] === "undefined") { + data[key] = 0; + } + + return function(...args) { + let t = process.hrtime(); + + fn(...args); + t = process.hrtime(t); + data[key] += t[0] * 1e3 + t[1] / 1e6; + }; + } + + if (enabled) { + process.on("exit", () => { + display(data); + }); + } + + return { + time, + enabled, + getListSize + }; + +}()); + +var rules = { + "generator-star": [ + "generator-star-spacing" + ], + "global-strict": [ + "strict" + ], + "no-arrow-condition": [ + "no-confusing-arrow", + "no-constant-condition" + ], + "no-comma-dangle": [ + "comma-dangle" + ], + "no-empty-class": [ + "no-empty-character-class" + ], + "no-empty-label": [ + "no-labels" + ], + "no-extra-strict": [ + "strict" + ], + "no-reserved-keys": [ + "quote-props" + ], + "no-space-before-semi": [ + "semi-spacing" + ], + "no-wrap-func": [ + "no-extra-parens" + ], + "space-after-function-name": [ + "space-before-function-paren" + ], + "space-after-keywords": [ + "keyword-spacing" + ], + "space-before-function-parentheses": [ + "space-before-function-paren" + ], + "space-before-keywords": [ + "keyword-spacing" + ], + "space-in-brackets": [ + "object-curly-spacing", + "array-bracket-spacing", + "computed-property-spacing" + ], + "space-return-throw-case": [ + "keyword-spacing" + ], + "space-unary-word-ops": [ + "space-unary-ops" + ], + "spaced-line-comment": [ + "spaced-comment" + ] +}; +var ruleReplacements = { + rules: rules +}; + +/** + * @fileoverview Main Linter Class + * @author Gyandeep Singh + * @author aladdin-add + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const + { SourceCode } = sourceCode; + +const debug$2 = require$$0__default['default']("eslint:linter"); +const MAX_AUTOFIX_PASSES = 10; +const DEFAULT_PARSER_NAME = "espree"; +const commentParser = new configCommentParser(); +const DEFAULT_ERROR_LOC = { start: { line: 1, column: 0 }, end: { line: 1, column: 1 } }; + +//------------------------------------------------------------------------------ +// Typedefs +//------------------------------------------------------------------------------ + +/** @typedef {InstanceType} ConfigArray */ +/** @typedef {InstanceType} ExtractedConfig */ +/** @typedef {import("../shared/types").ConfigData} ConfigData */ +/** @typedef {import("../shared/types").Environment} Environment */ +/** @typedef {import("../shared/types").GlobalConf} GlobalConf */ +/** @typedef {import("../shared/types").LintMessage} LintMessage */ +/** @typedef {import("../shared/types").ParserOptions} ParserOptions */ +/** @typedef {import("../shared/types").Processor} Processor */ +/** @typedef {import("../shared/types").Rule} Rule */ + +/** + * @template T + * @typedef {{ [P in keyof T]-?: T[P] }} Required + */ + +/** + * @typedef {Object} DisableDirective + * @property {("disable"|"enable"|"disable-line"|"disable-next-line")} type + * @property {number} line + * @property {number} column + * @property {(string|null)} ruleId + */ + +/** + * The private data for `Linter` instance. + * @typedef {Object} LinterInternalSlots + * @property {ConfigArray|null} lastConfigArray The `ConfigArray` instance that the last `verify()` call used. + * @property {SourceCode|null} lastSourceCode The `SourceCode` instance that the last `verify()` call used. + * @property {Map} parserMap The loaded parsers. + * @property {Rules} ruleMap The loaded rules. + */ + +/** + * @typedef {Object} VerifyOptions + * @property {boolean} [allowInlineConfig] Allow/disallow inline comments' ability + * to change config once it is set. Defaults to true if not supplied. + * Useful if you want to validate JS without comments overriding rules. + * @property {boolean} [disableFixes] if `true` then the linter doesn't make `fix` + * properties into the lint result. + * @property {string} [filename] the filename of the source code. + * @property {boolean | "off" | "warn" | "error"} [reportUnusedDisableDirectives] Adds reported errors for + * unused `eslint-disable` directives. + */ + +/** + * @typedef {Object} ProcessorOptions + * @property {(filename:string, text:string) => boolean} [filterCodeBlock] the + * predicate function that selects adopt code blocks. + * @property {Processor["postprocess"]} [postprocess] postprocessor for report + * messages. If provided, this should accept an array of the message lists + * for each code block returned from the preprocessor, apply a mapping to + * the messages as appropriate, and return a one-dimensional array of + * messages. + * @property {Processor["preprocess"]} [preprocess] preprocessor for source text. + * If provided, this should accept a string of source text, and return an + * array of code blocks to lint. + */ + +/** + * @typedef {Object} FixOptions + * @property {boolean | ((message: LintMessage) => boolean)} [fix] Determines + * whether fixes should be applied. + */ + +/** + * @typedef {Object} InternalOptions + * @property {string | null} warnInlineConfig The config name what `noInlineConfig` setting came from. If `noInlineConfig` setting didn't exist, this is null. If this is a config name, then the linter warns directive comments. + * @property {"off" | "warn" | "error"} reportUnusedDisableDirectives (boolean values were normalized) + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** + * Ensures that variables representing built-in properties of the Global Object, + * and any globals declared by special block comments, are present in the global + * scope. + * @param {Scope} globalScope The global scope. + * @param {Object} configGlobals The globals declared in configuration + * @param {{exportedVariables: Object, enabledGlobals: Object}} commentDirectives Directives from comment configuration + * @returns {void} + */ +function addDeclaredGlobals(globalScope, configGlobals, { exportedVariables, enabledGlobals }) { + + // Define configured global variables. + for (const id of new Set([...Object.keys(configGlobals), ...Object.keys(enabledGlobals)])) { + + /* + * `ConfigOps.normalizeConfigGlobal` will throw an error if a configured global value is invalid. However, these errors would + * typically be caught when validating a config anyway (validity for inline global comments is checked separately). + */ + const configValue = configGlobals[id] === void 0 ? void 0 : configOps.normalizeConfigGlobal(configGlobals[id]); + const commentValue = enabledGlobals[id] && enabledGlobals[id].value; + const value = commentValue || configValue; + const sourceComments = enabledGlobals[id] && enabledGlobals[id].comments; + + if (value === "off") { + continue; + } + + let variable = globalScope.set.get(id); + + if (!variable) { + variable = new eslintScope__default['default'].Variable(id, globalScope); + + globalScope.variables.push(variable); + globalScope.set.set(id, variable); + } + + variable.eslintImplicitGlobalSetting = configValue; + variable.eslintExplicitGlobal = sourceComments !== void 0; + variable.eslintExplicitGlobalComments = sourceComments; + variable.writeable = (value === "writable"); + } + + // mark all exported variables as such + Object.keys(exportedVariables).forEach(name => { + const variable = globalScope.set.get(name); + + if (variable) { + variable.eslintUsed = true; + } + }); + + /* + * "through" contains all references which definitions cannot be found. + * Since we augment the global scope using configuration, we need to update + * references and remove the ones that were added by configuration. + */ + globalScope.through = globalScope.through.filter(reference => { + const name = reference.identifier.name; + const variable = globalScope.set.get(name); + + if (variable) { + + /* + * Links the variable and the reference. + * And this reference is removed from `Scope#through`. + */ + reference.resolved = variable; + variable.references.push(reference); + + return false; + } + + return true; + }); +} + +/** + * creates a missing-rule message. + * @param {string} ruleId the ruleId to create + * @returns {string} created error message + * @private + */ +function createMissingRuleMessage(ruleId) { + return Object.prototype.hasOwnProperty.call(ruleReplacements.rules, ruleId) + ? `Rule '${ruleId}' was removed and replaced by: ${ruleReplacements.rules[ruleId].join(", ")}` + : `Definition for rule '${ruleId}' was not found.`; +} + +/** + * creates a linting problem + * @param {Object} options to create linting error + * @param {string} [options.ruleId] the ruleId to report + * @param {Object} [options.loc] the loc to report + * @param {string} [options.message] the error message to report + * @param {string} [options.severity] the error message to report + * @returns {LintMessage} created problem, returns a missing-rule problem if only provided ruleId. + * @private + */ +function createLintingProblem(options) { + const { + ruleId = null, + loc = DEFAULT_ERROR_LOC, + message = createMissingRuleMessage(options.ruleId), + severity = 2 + } = options; + + return { + ruleId, + message, + line: loc.start.line, + column: loc.start.column + 1, + endLine: loc.end.line, + endColumn: loc.end.column + 1, + severity, + nodeType: null + }; +} + +/** + * Creates a collection of disable directives from a comment + * @param {Object} options to create disable directives + * @param {("disable"|"enable"|"disable-line"|"disable-next-line")} options.type The type of directive comment + * @param {{line: number, column: number}} options.loc The 0-based location of the comment token + * @param {string} options.value The value after the directive in the comment + * comment specified no specific rules, so it applies to all rules (e.g. `eslint-disable`) + * @param {function(string): {create: Function}} options.ruleMapper A map from rule IDs to defined rules + * @returns {Object} Directives and problems from the comment + */ +function createDisableDirectives(options) { + const { type, loc, value, ruleMapper } = options; + const ruleIds = Object.keys(commentParser.parseListConfig(value)); + const directiveRules = ruleIds.length ? ruleIds : [null]; + const result = { + directives: [], // valid disable directives + directiveProblems: [] // problems in directives + }; + + for (const ruleId of directiveRules) { + + // push to directives, if the rule is defined(including null, e.g. /*eslint enable*/) + if (ruleId === null || ruleMapper(ruleId) !== null) { + result.directives.push({ type, line: loc.start.line, column: loc.start.column + 1, ruleId }); + } else { + result.directiveProblems.push(createLintingProblem({ ruleId, loc })); + } + } + return result; +} + +/** + * Remove the ignored part from a given directive comment and trim it. + * @param {string} value The comment text to strip. + * @returns {string} The stripped text. + */ +function stripDirectiveComment(value) { + return value.split(/\s-{2,}\s/u)[0].trim(); +} + +/** + * Parses comments in file to extract file-specific config of rules, globals + * and environments and merges them with global config; also code blocks + * where reporting is disabled or enabled and merges them with reporting config. + * @param {string} filename The file being checked. + * @param {ASTNode} ast The top node of the AST. + * @param {function(string): {create: Function}} ruleMapper A map from rule IDs to defined rules + * @param {string|null} warnInlineConfig If a string then it should warn directive comments as disabled. The string value is the config name what the setting came from. + * @returns {{configuredRules: Object, enabledGlobals: {value:string,comment:Token}[], exportedVariables: Object, problems: Problem[], disableDirectives: DisableDirective[]}} + * A collection of the directive comments that were found, along with any problems that occurred when parsing + */ +function getDirectiveComments(filename, ast, ruleMapper, warnInlineConfig) { + const configuredRules = {}; + const enabledGlobals = Object.create(null); + const exportedVariables = {}; + const problems = []; + const disableDirectives = []; + const validator = new configValidator$1({ + builtInRules: rules$1 + }); + + ast.comments.filter(token => token.type !== "Shebang").forEach(comment => { + const trimmedCommentText = stripDirectiveComment(comment.value); + const match = /^(eslint(?:-env|-enable|-disable(?:(?:-next)?-line)?)?|exported|globals?)(?:\s|$)/u.exec(trimmedCommentText); + + if (!match) { + return; + } + const directiveText = match[1]; + const lineCommentSupported = /^eslint-disable-(next-)?line$/u.test(directiveText); + + if (comment.type === "Line" && !lineCommentSupported) { + return; + } + + if (warnInlineConfig) { + const kind = comment.type === "Block" ? `/*${directiveText}*/` : `//${directiveText}`; + + problems.push(createLintingProblem({ + ruleId: null, + message: `'${kind}' has no effect because you have 'noInlineConfig' setting in ${warnInlineConfig}.`, + loc: comment.loc, + severity: 1 + })); + return; + } + + if (lineCommentSupported && comment.loc.start.line !== comment.loc.end.line) { + const message = `${directiveText} comment should not span multiple lines.`; + + problems.push(createLintingProblem({ + ruleId: null, + message, + loc: comment.loc + })); + return; + } + + const directiveValue = trimmedCommentText.slice(match.index + directiveText.length); + + switch (directiveText) { + case "eslint-disable": + case "eslint-enable": + case "eslint-disable-next-line": + case "eslint-disable-line": { + const directiveType = directiveText.slice("eslint-".length); + const options = { type: directiveType, loc: comment.loc, value: directiveValue, ruleMapper }; + const { directives, directiveProblems } = createDisableDirectives(options); + + disableDirectives.push(...directives); + problems.push(...directiveProblems); + break; + } + + case "exported": + Object.assign(exportedVariables, commentParser.parseStringConfig(directiveValue, comment)); + break; + + case "globals": + case "global": + for (const [id, { value }] of Object.entries(commentParser.parseStringConfig(directiveValue, comment))) { + let normalizedValue; + + try { + normalizedValue = configOps.normalizeConfigGlobal(value); + } catch (err) { + problems.push(createLintingProblem({ + ruleId: null, + loc: comment.loc, + message: err.message + })); + continue; + } + + if (enabledGlobals[id]) { + enabledGlobals[id].comments.push(comment); + enabledGlobals[id].value = normalizedValue; + } else { + enabledGlobals[id] = { + comments: [comment], + value: normalizedValue + }; + } + } + break; + + case "eslint": { + const parseResult = commentParser.parseJsonConfig(directiveValue, comment.loc); + + if (parseResult.success) { + Object.keys(parseResult.config).forEach(name => { + const rule = ruleMapper(name); + const ruleValue = parseResult.config[name]; + + if (rule === null) { + problems.push(createLintingProblem({ ruleId: name, loc: comment.loc })); + return; + } + + try { + validator.validateRuleOptions(rule, name, ruleValue); + } catch (err) { + problems.push(createLintingProblem({ + ruleId: name, + message: err.message, + loc: comment.loc + })); + + // do not apply the config, if found invalid options. + return; + } + + configuredRules[name] = ruleValue; + }); + } else { + problems.push(parseResult.error); + } + + break; + } + + // no default + } + }); + + return { + configuredRules, + enabledGlobals, + exportedVariables, + problems, + disableDirectives + }; +} + +/** + * Normalize ECMAScript version from the initial config + * @param {number} ecmaVersion ECMAScript version from the initial config + * @returns {number} normalized ECMAScript version + */ +function normalizeEcmaVersion(ecmaVersion) { + + /* + * Calculate ECMAScript edition number from official year version starting with + * ES2015, which corresponds with ES6 (or a difference of 2009). + */ + return ecmaVersion >= 2015 ? ecmaVersion - 2009 : ecmaVersion; +} + +const eslintEnvPattern = /\/\*\s*eslint-env\s(.+?)\*\//gu; + +/** + * Checks whether or not there is a comment which has "eslint-env *" in a given text. + * @param {string} text A source code text to check. + * @returns {Object|null} A result of parseListConfig() with "eslint-env *" comment. + */ +function findEslintEnv(text) { + let match, retv; + + eslintEnvPattern.lastIndex = 0; + + while ((match = eslintEnvPattern.exec(text)) !== null) { + retv = Object.assign( + retv || {}, + commentParser.parseListConfig(stripDirectiveComment(match[1])) + ); + } + + return retv; +} + +/** + * Convert "/path/to/" to "". + * `CLIEngine#executeOnText()` method gives "/path/to/" if the filename + * was omitted because `configArray.extractConfig()` requires an absolute path. + * But the linter should pass `` to `RuleContext#getFilename()` in that + * case. + * Also, code blocks can have their virtual filename. If the parent filename was + * ``, the virtual filename is `/0_foo.js` or something like (i.e., + * it's not an absolute path). + * @param {string} filename The filename to normalize. + * @returns {string} The normalized filename. + */ +function normalizeFilename(filename) { + const parts = filename.split(path__default['default'].sep); + const index = parts.lastIndexOf(""); + + return index === -1 ? filename : parts.slice(index).join(path__default['default'].sep); +} + +/** + * Normalizes the possible options for `linter.verify` and `linter.verifyAndFix` to a + * consistent shape. + * @param {VerifyOptions} providedOptions Options + * @param {ConfigData} config Config. + * @returns {Required & InternalOptions} Normalized options + */ +function normalizeVerifyOptions(providedOptions, config) { + const disableInlineConfig = config.noInlineConfig === true; + const ignoreInlineConfig = providedOptions.allowInlineConfig === false; + const configNameOfNoInlineConfig = config.configNameOfNoInlineConfig + ? ` (${config.configNameOfNoInlineConfig})` + : ""; + + let reportUnusedDisableDirectives = providedOptions.reportUnusedDisableDirectives; + + if (typeof reportUnusedDisableDirectives === "boolean") { + reportUnusedDisableDirectives = reportUnusedDisableDirectives ? "error" : "off"; + } + if (typeof reportUnusedDisableDirectives !== "string") { + reportUnusedDisableDirectives = config.reportUnusedDisableDirectives ? "warn" : "off"; + } + + return { + filename: normalizeFilename(providedOptions.filename || ""), + allowInlineConfig: !ignoreInlineConfig, + warnInlineConfig: disableInlineConfig && !ignoreInlineConfig + ? `your config${configNameOfNoInlineConfig}` + : null, + reportUnusedDisableDirectives, + disableFixes: Boolean(providedOptions.disableFixes) + }; +} + +/** + * Combines the provided parserOptions with the options from environments + * @param {string} parserName The parser name which uses this options. + * @param {ParserOptions} providedOptions The provided 'parserOptions' key in a config + * @param {Environment[]} enabledEnvironments The environments enabled in configuration and with inline comments + * @returns {ParserOptions} Resulting parser options after merge + */ +function resolveParserOptions(parserName, providedOptions, enabledEnvironments) { + const parserOptionsFromEnv = enabledEnvironments + .filter(env => env.parserOptions) + .reduce((parserOptions, env) => lodash__default['default'].merge(parserOptions, env.parserOptions), {}); + const mergedParserOptions = lodash__default['default'].merge(parserOptionsFromEnv, providedOptions || {}); + const isModule = mergedParserOptions.sourceType === "module"; + + if (isModule) { + + /* + * can't have global return inside of modules + * TODO: espree validate parserOptions.globalReturn when sourceType is setting to module.(@aladdin-add) + */ + mergedParserOptions.ecmaFeatures = Object.assign({}, mergedParserOptions.ecmaFeatures, { globalReturn: false }); + } + + /* + * TODO: @aladdin-add + * 1. for a 3rd-party parser, do not normalize parserOptions + * 2. for espree, no need to do this (espree will do it) + */ + mergedParserOptions.ecmaVersion = normalizeEcmaVersion(mergedParserOptions.ecmaVersion); + + return mergedParserOptions; +} + +/** + * Combines the provided globals object with the globals from environments + * @param {Record} providedGlobals The 'globals' key in a config + * @param {Environment[]} enabledEnvironments The environments enabled in configuration and with inline comments + * @returns {Record} The resolved globals object + */ +function resolveGlobals(providedGlobals, enabledEnvironments) { + return Object.assign( + {}, + ...enabledEnvironments.filter(env => env.globals).map(env => env.globals), + providedGlobals + ); +} + +/** + * Strips Unicode BOM from a given text. + * @param {string} text A text to strip. + * @returns {string} The stripped text. + */ +function stripUnicodeBOM(text) { + + /* + * Check Unicode BOM. + * In JavaScript, string data is stored as UTF-16, so BOM is 0xFEFF. + * http://www.ecma-international.org/ecma-262/6.0/#sec-unicode-format-control-characters + */ + if (text.charCodeAt(0) === 0xFEFF) { + return text.slice(1); + } + return text; +} + +/** + * Get the options for a rule (not including severity), if any + * @param {Array|number} ruleConfig rule configuration + * @returns {Array} of rule options, empty Array if none + */ +function getRuleOptions(ruleConfig) { + if (Array.isArray(ruleConfig)) { + return ruleConfig.slice(1); + } + return []; + +} + +/** + * Analyze scope of the given AST. + * @param {ASTNode} ast The `Program` node to analyze. + * @param {ParserOptions} parserOptions The parser options. + * @param {Record} visitorKeys The visitor keys. + * @returns {ScopeManager} The analysis result. + */ +function analyzeScope(ast, parserOptions, visitorKeys) { + const ecmaFeatures = parserOptions.ecmaFeatures || {}; + const ecmaVersion = parserOptions.ecmaVersion || 5; + + return eslintScope__default['default'].analyze(ast, { + ignoreEval: true, + nodejsScope: ecmaFeatures.globalReturn, + impliedStrict: ecmaFeatures.impliedStrict, + ecmaVersion, + sourceType: parserOptions.sourceType || "script", + childVisitorKeys: visitorKeys || vk__default['default'].KEYS, + fallback: traverser.getKeys + }); +} + +/** + * Parses text into an AST. Moved out here because the try-catch prevents + * optimization of functions, so it's best to keep the try-catch as isolated + * as possible + * @param {string} text The text to parse. + * @param {Parser} parser The parser to parse. + * @param {ParserOptions} providedParserOptions Options to pass to the parser + * @param {string} filePath The path to the file being parsed. + * @returns {{success: false, error: Problem}|{success: true, sourceCode: SourceCode}} + * An object containing the AST and parser services if parsing was successful, or the error if parsing failed + * @private + */ +function parse$3(text, parser, providedParserOptions, filePath) { + const textToParse = stripUnicodeBOM(text).replace(astUtils$1.shebangPattern, (match, captured) => `//${captured}`); + const parserOptions = Object.assign({}, providedParserOptions, { + loc: true, + range: true, + raw: true, + tokens: true, + comment: true, + eslintVisitorKeys: true, + eslintScopeManager: true, + filePath + }); + + /* + * Check for parsing errors first. If there's a parsing error, nothing + * else can happen. However, a parsing error does not throw an error + * from this method - it's just considered a fatal error message, a + * problem that ESLint identified just like any other. + */ + try { + const parseResult = (typeof parser.parseForESLint === "function") + ? parser.parseForESLint(textToParse, parserOptions) + : { ast: parser.parse(textToParse, parserOptions) }; + const ast = parseResult.ast; + const parserServices = parseResult.services || {}; + const visitorKeys = parseResult.visitorKeys || vk__default['default'].KEYS; + const scopeManager = parseResult.scopeManager || analyzeScope(ast, parserOptions, visitorKeys); + + return { + success: true, + + /* + * Save all values that `parseForESLint()` returned. + * If a `SourceCode` object is given as the first parameter instead of source code text, + * linter skips the parsing process and reuses the source code object. + * In that case, linter needs all the values that `parseForESLint()` returned. + */ + sourceCode: new SourceCode({ + text, + ast, + parserServices, + scopeManager, + visitorKeys + }) + }; + } catch (ex) { + + // If the message includes a leading line number, strip it: + const message = `Parsing error: ${ex.message.replace(/^line \d+:/iu, "").trim()}`; + + debug$2("%s\n%s", message, ex.stack); + + return { + success: false, + error: { + ruleId: null, + fatal: true, + severity: 2, + message, + line: ex.lineNumber, + column: ex.column + } + }; + } +} + +/** + * Gets the scope for the current node + * @param {ScopeManager} scopeManager The scope manager for this AST + * @param {ASTNode} currentNode The node to get the scope of + * @returns {eslint-scope.Scope} The scope information for this node + */ +function getScope(scopeManager, currentNode) { + + // On Program node, get the outermost scope to avoid return Node.js special function scope or ES modules scope. + const inner = currentNode.type !== "Program"; + + for (let node = currentNode; node; node = node.parent) { + const scope = scopeManager.acquire(node, inner); + + if (scope) { + if (scope.type === "function-expression-name") { + return scope.childScopes[0]; + } + return scope; + } + } + + return scopeManager.scopes[0]; +} + +/** + * Marks a variable as used in the current scope + * @param {ScopeManager} scopeManager The scope manager for this AST. The scope may be mutated by this function. + * @param {ASTNode} currentNode The node currently being traversed + * @param {Object} parserOptions The options used to parse this text + * @param {string} name The name of the variable that should be marked as used. + * @returns {boolean} True if the variable was found and marked as used, false if not. + */ +function markVariableAsUsed(scopeManager, currentNode, parserOptions, name) { + const hasGlobalReturn = parserOptions.ecmaFeatures && parserOptions.ecmaFeatures.globalReturn; + const specialScope = hasGlobalReturn || parserOptions.sourceType === "module"; + const currentScope = getScope(scopeManager, currentNode); + + // Special Node.js scope means we need to start one level deeper + const initialScope = currentScope.type === "global" && specialScope ? currentScope.childScopes[0] : currentScope; + + for (let scope = initialScope; scope; scope = scope.upper) { + const variable = scope.variables.find(scopeVar => scopeVar.name === name); + + if (variable) { + variable.eslintUsed = true; + return true; + } + } + + return false; +} + +/** + * Runs a rule, and gets its listeners + * @param {Rule} rule A normalized rule with a `create` method + * @param {Context} ruleContext The context that should be passed to the rule + * @returns {Object} A map of selector listeners provided by the rule + */ +function createRuleListeners(rule, ruleContext) { + try { + return rule.create(ruleContext); + } catch (ex) { + ex.message = `Error while loading rule '${ruleContext.id}': ${ex.message}`; + throw ex; + } +} + +/** + * Gets all the ancestors of a given node + * @param {ASTNode} node The node + * @returns {ASTNode[]} All the ancestor nodes in the AST, not including the provided node, starting + * from the root node and going inwards to the parent node. + */ +function getAncestors(node) { + const ancestorsStartingAtParent = []; + + for (let ancestor = node.parent; ancestor; ancestor = ancestor.parent) { + ancestorsStartingAtParent.push(ancestor); + } + + return ancestorsStartingAtParent.reverse(); +} + +// methods that exist on SourceCode object +const DEPRECATED_SOURCECODE_PASSTHROUGHS = { + getSource: "getText", + getSourceLines: "getLines", + getAllComments: "getAllComments", + getNodeByRangeIndex: "getNodeByRangeIndex", + getComments: "getComments", + getCommentsBefore: "getCommentsBefore", + getCommentsAfter: "getCommentsAfter", + getCommentsInside: "getCommentsInside", + getJSDocComment: "getJSDocComment", + getFirstToken: "getFirstToken", + getFirstTokens: "getFirstTokens", + getLastToken: "getLastToken", + getLastTokens: "getLastTokens", + getTokenAfter: "getTokenAfter", + getTokenBefore: "getTokenBefore", + getTokenByRangeStart: "getTokenByRangeStart", + getTokens: "getTokens", + getTokensAfter: "getTokensAfter", + getTokensBefore: "getTokensBefore", + getTokensBetween: "getTokensBetween" +}; + +const BASE_TRAVERSAL_CONTEXT = Object.freeze( + Object.keys(DEPRECATED_SOURCECODE_PASSTHROUGHS).reduce( + (contextInfo, methodName) => + Object.assign(contextInfo, { + [methodName](...args) { + return this.getSourceCode()[DEPRECATED_SOURCECODE_PASSTHROUGHS[methodName]](...args); + } + }), + {} + ) +); + +/** + * Runs the given rules on the given SourceCode object + * @param {SourceCode} sourceCode A SourceCode object for the given text + * @param {Object} configuredRules The rules configuration + * @param {function(string): Rule} ruleMapper A mapper function from rule names to rules + * @param {Object} parserOptions The options that were passed to the parser + * @param {string} parserName The name of the parser in the config + * @param {Object} settings The settings that were enabled in the config + * @param {string} filename The reported filename of the code + * @param {boolean} disableFixes If true, it doesn't make `fix` properties. + * @param {string | undefined} cwd cwd of the cli + * @returns {Problem[]} An array of reported problems + */ +function runRules(sourceCode, configuredRules, ruleMapper, parserOptions, parserName, settings, filename, disableFixes, cwd) { + const emitter = safeEmitter(); + const nodeQueue = []; + let currentNode = sourceCode.ast; + + traverser.traverse(sourceCode.ast, { + enter(node, parent) { + node.parent = parent; + nodeQueue.push({ isEntering: true, node }); + }, + leave(node) { + nodeQueue.push({ isEntering: false, node }); + }, + visitorKeys: sourceCode.visitorKeys + }); + + /* + * Create a frozen object with the ruleContext properties and methods that are shared by all rules. + * All rule contexts will inherit from this object. This avoids the performance penalty of copying all the + * properties once for each rule. + */ + const sharedTraversalContext = Object.freeze( + Object.assign( + Object.create(BASE_TRAVERSAL_CONTEXT), + { + getAncestors: () => getAncestors(currentNode), + getDeclaredVariables: sourceCode.scopeManager.getDeclaredVariables.bind(sourceCode.scopeManager), + getCwd: () => cwd, + getFilename: () => filename, + getScope: () => getScope(sourceCode.scopeManager, currentNode), + getSourceCode: () => sourceCode, + markVariableAsUsed: name => markVariableAsUsed(sourceCode.scopeManager, currentNode, parserOptions, name), + parserOptions, + parserPath: parserName, + parserServices: sourceCode.parserServices, + settings + } + ) + ); + + + const lintingProblems = []; + + Object.keys(configuredRules).forEach(ruleId => { + const severity = configOps.getRuleSeverity(configuredRules[ruleId]); + + // not load disabled rules + if (severity === 0) { + return; + } + + const rule = ruleMapper(ruleId); + + if (rule === null) { + lintingProblems.push(createLintingProblem({ ruleId })); + return; + } + + const messageIds = rule.meta && rule.meta.messages; + let reportTranslator$1 = null; + const ruleContext = Object.freeze( + Object.assign( + Object.create(sharedTraversalContext), + { + id: ruleId, + options: getRuleOptions(configuredRules[ruleId]), + report(...args) { + + /* + * Create a report translator lazily. + * In a vast majority of cases, any given rule reports zero errors on a given + * piece of code. Creating a translator lazily avoids the performance cost of + * creating a new translator function for each rule that usually doesn't get + * called. + * + * Using lazy report translators improves end-to-end performance by about 3% + * with Node 8.4.0. + */ + if (reportTranslator$1 === null) { + reportTranslator$1 = reportTranslator({ + ruleId, + severity, + sourceCode, + messageIds, + disableFixes + }); + } + const problem = reportTranslator$1(...args); + + if (problem.fix && rule.meta && !rule.meta.fixable) { + throw new Error("Fixable rules should export a `meta.fixable` property."); + } + lintingProblems.push(problem); + } + } + ) + ); + + const ruleListeners = createRuleListeners(rule, ruleContext); + + // add all the selectors from the rule as listeners + Object.keys(ruleListeners).forEach(selector => { + emitter.on( + selector, + timing.enabled + ? timing.time(ruleId, ruleListeners[selector]) + : ruleListeners[selector] + ); + }); + }); + + // only run code path analyzer if the top level node is "Program", skip otherwise + const eventGenerator = nodeQueue[0].node.type === "Program" + ? new codePathAnalyzer(new nodeEventGenerator(emitter, { visitorKeys: sourceCode.visitorKeys, fallback: traverser.getKeys })) + : new nodeEventGenerator(emitter, { visitorKeys: sourceCode.visitorKeys, fallback: traverser.getKeys }); + + nodeQueue.forEach(traversalInfo => { + currentNode = traversalInfo.node; + + try { + if (traversalInfo.isEntering) { + eventGenerator.enterNode(currentNode); + } else { + eventGenerator.leaveNode(currentNode); + } + } catch (err) { + err.currentNode = currentNode; + throw err; + } + }); + + return lintingProblems; +} + +/** + * Ensure the source code to be a string. + * @param {string|SourceCode} textOrSourceCode The text or source code object. + * @returns {string} The source code text. + */ +function ensureText(textOrSourceCode) { + if (typeof textOrSourceCode === "object") { + const { hasBOM, text } = textOrSourceCode; + const bom = hasBOM ? "\uFEFF" : ""; + + return bom + text; + } + + return String(textOrSourceCode); +} + +/** + * Get an environment. + * @param {LinterInternalSlots} slots The internal slots of Linter. + * @param {string} envId The environment ID to get. + * @returns {Environment|null} The environment. + */ +function getEnv(slots, envId) { + return ( + (slots.lastConfigArray && slots.lastConfigArray.pluginEnvironments.get(envId)) || + environments.get(envId) || + null + ); +} + +/** + * Get a rule. + * @param {LinterInternalSlots} slots The internal slots of Linter. + * @param {string} ruleId The rule ID to get. + * @returns {Rule|null} The rule. + */ +function getRule$1(slots, ruleId) { + return ( + (slots.lastConfigArray && slots.lastConfigArray.pluginRules.get(ruleId)) || + slots.ruleMap.get(ruleId) + ); +} + +/** + * Normalize the value of the cwd + * @param {string | undefined} cwd raw value of the cwd, path to a directory that should be considered as the current working directory, can be undefined. + * @returns {string | undefined} normalized cwd + */ +function normalizeCwd(cwd) { + if (cwd) { + return cwd; + } + if (typeof process === "object") { + return process.cwd(); + } + + // It's more explicit to assign the undefined + // eslint-disable-next-line no-undefined + return undefined; +} + +/** + * The map to store private data. + * @type {WeakMap} + */ +const internalSlotsMap$1 = new WeakMap(); + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * Object that is responsible for verifying JavaScript text + * @name eslint + */ +class Linter$3 { + + /** + * Initialize the Linter. + * @param {Object} [config] the config object + * @param {string} [config.cwd] path to a directory that should be considered as the current working directory, can be undefined. + */ + constructor({ cwd } = {}) { + internalSlotsMap$1.set(this, { + cwd: normalizeCwd(cwd), + lastConfigArray: null, + lastSourceCode: null, + parserMap: new Map([["espree", espree__default['default']]]), + ruleMap: new rules$1() + }); + + this.version = require$$3.version; + } + + /** + * Getter for package version. + * @static + * @returns {string} The version from package.json. + */ + static get version() { + return require$$3.version; + } + + /** + * Same as linter.verify, except without support for processors. + * @param {string|SourceCode} textOrSourceCode The text to parse or a SourceCode object. + * @param {ConfigData} providedConfig An ESLintConfig instance to configure everything. + * @param {VerifyOptions} [providedOptions] The optional filename of the file being checked. + * @returns {LintMessage[]} The results as an array of messages or an empty array if no messages. + */ + _verifyWithoutProcessors(textOrSourceCode, providedConfig, providedOptions) { + const slots = internalSlotsMap$1.get(this); + const config = providedConfig || {}; + const options = normalizeVerifyOptions(providedOptions, config); + let text; + + // evaluate arguments + if (typeof textOrSourceCode === "string") { + slots.lastSourceCode = null; + text = textOrSourceCode; + } else { + slots.lastSourceCode = textOrSourceCode; + text = textOrSourceCode.text; + } + + // Resolve parser. + let parserName = DEFAULT_PARSER_NAME; + let parser = espree__default['default']; + + if (typeof config.parser === "object" && config.parser !== null) { + parserName = config.parser.filePath; + parser = config.parser.definition; + } else if (typeof config.parser === "string") { + if (!slots.parserMap.has(config.parser)) { + return [{ + ruleId: null, + fatal: true, + severity: 2, + message: `Configured parser '${config.parser}' was not found.`, + line: 0, + column: 0 + }]; + } + parserName = config.parser; + parser = slots.parserMap.get(config.parser); + } + + // search and apply "eslint-env *". + const envInFile = options.allowInlineConfig && !options.warnInlineConfig + ? findEslintEnv(text) + : {}; + const resolvedEnvConfig = Object.assign({ builtin: true }, config.env, envInFile); + const enabledEnvs = Object.keys(resolvedEnvConfig) + .filter(envName => resolvedEnvConfig[envName]) + .map(envName => getEnv(slots, envName)) + .filter(env => env); + + const parserOptions = resolveParserOptions(parserName, config.parserOptions || {}, enabledEnvs); + const configuredGlobals = resolveGlobals(config.globals || {}, enabledEnvs); + const settings = config.settings || {}; + + if (!slots.lastSourceCode) { + const parseResult = parse$3( + text, + parser, + parserOptions, + options.filename + ); + + if (!parseResult.success) { + return [parseResult.error]; + } + + slots.lastSourceCode = parseResult.sourceCode; + } else { + + /* + * If the given source code object as the first argument does not have scopeManager, analyze the scope. + * This is for backward compatibility (SourceCode is frozen so it cannot rebind). + */ + if (!slots.lastSourceCode.scopeManager) { + slots.lastSourceCode = new SourceCode({ + text: slots.lastSourceCode.text, + ast: slots.lastSourceCode.ast, + parserServices: slots.lastSourceCode.parserServices, + visitorKeys: slots.lastSourceCode.visitorKeys, + scopeManager: analyzeScope(slots.lastSourceCode.ast, parserOptions) + }); + } + } + + const sourceCode = slots.lastSourceCode; + const commentDirectives = options.allowInlineConfig + ? getDirectiveComments(options.filename, sourceCode.ast, ruleId => getRule$1(slots, ruleId), options.warnInlineConfig) + : { configuredRules: {}, enabledGlobals: {}, exportedVariables: {}, problems: [], disableDirectives: [] }; + + // augment global scope with declared global variables + addDeclaredGlobals( + sourceCode.scopeManager.scopes[0], + configuredGlobals, + { exportedVariables: commentDirectives.exportedVariables, enabledGlobals: commentDirectives.enabledGlobals } + ); + + const configuredRules = Object.assign({}, config.rules, commentDirectives.configuredRules); + + let lintingProblems; + + try { + lintingProblems = runRules( + sourceCode, + configuredRules, + ruleId => getRule$1(slots, ruleId), + parserOptions, + parserName, + settings, + options.filename, + options.disableFixes, + slots.cwd + ); + } catch (err) { + err.message += `\nOccurred while linting ${options.filename}`; + debug$2("An error occurred while traversing"); + debug$2("Filename:", options.filename); + if (err.currentNode) { + const { line } = err.currentNode.loc.start; + + debug$2("Line:", line); + err.message += `:${line}`; + } + debug$2("Parser Options:", parserOptions); + debug$2("Parser Path:", parserName); + debug$2("Settings:", settings); + throw err; + } + + return applyDisableDirectives({ + directives: commentDirectives.disableDirectives, + problems: lintingProblems + .concat(commentDirectives.problems) + .sort((problemA, problemB) => problemA.line - problemB.line || problemA.column - problemB.column), + reportUnusedDisableDirectives: options.reportUnusedDisableDirectives + }); + } + + /** + * Verifies the text against the rules specified by the second argument. + * @param {string|SourceCode} textOrSourceCode The text to parse or a SourceCode object. + * @param {ConfigData|ConfigArray} config An ESLintConfig instance to configure everything. + * @param {(string|(VerifyOptions&ProcessorOptions))} [filenameOrOptions] The optional filename of the file being checked. + * If this is not set, the filename will default to '' in the rule context. If + * an object, then it has "filename", "allowInlineConfig", and some properties. + * @returns {LintMessage[]} The results as an array of messages or an empty array if no messages. + */ + verify(textOrSourceCode, config, filenameOrOptions) { + debug$2("Verify"); + const options = typeof filenameOrOptions === "string" + ? { filename: filenameOrOptions } + : filenameOrOptions || {}; + + // CLIEngine passes a `ConfigArray` object. + if (config && typeof config.extractConfig === "function") { + return this._verifyWithConfigArray(textOrSourceCode, config, options); + } + + /* + * `Linter` doesn't support `overrides` property in configuration. + * So we cannot apply multiple processors. + */ + if (options.preprocess || options.postprocess) { + return this._verifyWithProcessor(textOrSourceCode, config, options); + } + return this._verifyWithoutProcessors(textOrSourceCode, config, options); + } + + /** + * Verify a given code with `ConfigArray`. + * @param {string|SourceCode} textOrSourceCode The source code. + * @param {ConfigArray} configArray The config array. + * @param {VerifyOptions&ProcessorOptions} options The options. + * @returns {LintMessage[]} The found problems. + */ + _verifyWithConfigArray(textOrSourceCode, configArray, options) { + debug$2("With ConfigArray: %s", options.filename); + + // Store the config array in order to get plugin envs and rules later. + internalSlotsMap$1.get(this).lastConfigArray = configArray; + + // Extract the final config for this file. + const config = configArray.extractConfig(options.filename); + const processor = + config.processor && + configArray.pluginProcessors.get(config.processor); + + // Verify. + if (processor) { + debug$2("Apply the processor: %o", config.processor); + const { preprocess, postprocess, supportsAutofix } = processor; + const disableFixes = options.disableFixes || !supportsAutofix; + + return this._verifyWithProcessor( + textOrSourceCode, + config, + { ...options, disableFixes, postprocess, preprocess }, + configArray + ); + } + return this._verifyWithoutProcessors(textOrSourceCode, config, options); + } + + /** + * Verify with a processor. + * @param {string|SourceCode} textOrSourceCode The source code. + * @param {ConfigData|ExtractedConfig} config The config array. + * @param {VerifyOptions&ProcessorOptions} options The options. + * @param {ConfigArray} [configForRecursive] The `ConfigArray` object to apply multiple processors recursively. + * @returns {LintMessage[]} The found problems. + */ + _verifyWithProcessor(textOrSourceCode, config, options, configForRecursive) { + const filename = options.filename || ""; + const filenameToExpose = normalizeFilename(filename); + const text = ensureText(textOrSourceCode); + const preprocess = options.preprocess || (rawText => [rawText]); + const postprocess = options.postprocess || lodash__default['default'].flatten; + const filterCodeBlock = + options.filterCodeBlock || + (blockFilename => blockFilename.endsWith(".js")); + const originalExtname = path__default['default'].extname(filename); + const messageLists = preprocess(text, filenameToExpose).map((block, i) => { + debug$2("A code block was found: %o", block.filename || "(unnamed)"); + + // Keep the legacy behavior. + if (typeof block === "string") { + return this._verifyWithoutProcessors(block, config, options); + } + + const blockText = block.text; + const blockName = path__default['default'].join(filename, `${i}_${block.filename}`); + + // Skip this block if filtered. + if (!filterCodeBlock(blockName, blockText)) { + debug$2("This code block was skipped."); + return []; + } + + // Resolve configuration again if the file extension was changed. + if (configForRecursive && path__default['default'].extname(blockName) !== originalExtname) { + debug$2("Resolving configuration again because the file extension was changed."); + return this._verifyWithConfigArray( + blockText, + configForRecursive, + { ...options, filename: blockName } + ); + } + + // Does lint. + return this._verifyWithoutProcessors( + blockText, + config, + { ...options, filename: blockName } + ); + }); + + return postprocess(messageLists, filenameToExpose); + } + + /** + * Gets the SourceCode object representing the parsed source. + * @returns {SourceCode} The SourceCode object. + */ + getSourceCode() { + return internalSlotsMap$1.get(this).lastSourceCode; + } + + /** + * Defines a new linting rule. + * @param {string} ruleId A unique rule identifier + * @param {Function | Rule} ruleModule Function from context to object mapping AST node types to event handlers + * @returns {void} + */ + defineRule(ruleId, ruleModule) { + internalSlotsMap$1.get(this).ruleMap.define(ruleId, ruleModule); + } + + /** + * Defines many new linting rules. + * @param {Record} rulesToDefine map from unique rule identifier to rule + * @returns {void} + */ + defineRules(rulesToDefine) { + Object.getOwnPropertyNames(rulesToDefine).forEach(ruleId => { + this.defineRule(ruleId, rulesToDefine[ruleId]); + }); + } + + /** + * Gets an object with all loaded rules. + * @returns {Map} All loaded rules + */ + getRules() { + const { lastConfigArray, ruleMap } = internalSlotsMap$1.get(this); + + return new Map(function *() { + yield* ruleMap; + + if (lastConfigArray) { + yield* lastConfigArray.pluginRules; + } + }()); + } + + /** + * Define a new parser module + * @param {string} parserId Name of the parser + * @param {Parser} parserModule The parser object + * @returns {void} + */ + defineParser(parserId, parserModule) { + internalSlotsMap$1.get(this).parserMap.set(parserId, parserModule); + } + + /** + * Performs multiple autofix passes over the text until as many fixes as possible + * have been applied. + * @param {string} text The source text to apply fixes to. + * @param {ConfigData|ConfigArray} config The ESLint config object to use. + * @param {VerifyOptions&ProcessorOptions&FixOptions} options The ESLint options object to use. + * @returns {{fixed:boolean,messages:LintMessage[],output:string}} The result of the fix operation as returned from the + * SourceCodeFixer. + */ + verifyAndFix(text, config, options) { + let messages = [], + fixedResult, + fixed = false, + passNumber = 0, + currentText = text; + const debugTextDescription = options && options.filename || `${text.slice(0, 10)}...`; + const shouldFix = options && typeof options.fix !== "undefined" ? options.fix : true; + + /** + * This loop continues until one of the following is true: + * + * 1. No more fixes have been applied. + * 2. Ten passes have been made. + * + * That means anytime a fix is successfully applied, there will be another pass. + * Essentially, guaranteeing a minimum of two passes. + */ + do { + passNumber++; + + debug$2(`Linting code for ${debugTextDescription} (pass ${passNumber})`); + messages = this.verify(currentText, config, options); + + debug$2(`Generating fixed text for ${debugTextDescription} (pass ${passNumber})`); + fixedResult = sourceCodeFixer.applyFixes(currentText, messages, shouldFix); + + /* + * stop if there are any syntax errors. + * 'fixedResult.output' is a empty string. + */ + if (messages.length === 1 && messages[0].fatal) { + break; + } + + // keep track if any fixes were ever applied - important for return value + fixed = fixed || fixedResult.fixed; + + // update to use the fixed output instead of the original text + currentText = fixedResult.output; + + } while ( + fixedResult.fixed && + passNumber < MAX_AUTOFIX_PASSES + ); + + /* + * If the last result had fixes, we need to lint again to be sure we have + * the most up-to-date information. + */ + if (fixedResult.fixed) { + fixedResult.messages = this.verify(currentText, config, options); + } + + // ensure the last result properly reflects if fixes were done + fixedResult.fixed = fixed; + fixedResult.output = currentText; + + return fixedResult; + } +} + +var linter$1 = { + Linter: Linter$3, + + /** + * Get the internal slots of a given Linter instance for tests. + * @param {Linter} instance The Linter instance to get. + * @returns {LinterInternalSlots} The internal slots. + */ + getLinterInternalSlots(instance) { + return internalSlotsMap$1.get(instance); + } +}; + +const { Linter: Linter$2 } = linter$1; + + + +var linter = { + Linter: Linter$2, + + // For testers. + SourceCodeFixer: sourceCodeFixer, + interpolate: interpolate$1 +}; + +/** + * @fileoverview Module for loading rules from files and directories. + * @author Michael Ficarra + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +const rulesDirCache = {}; + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +/** + * Load all rule modules from specified directory. + * @param {string} relativeRulesDir Path to rules directory, may be relative. + * @param {string} cwd Current working directory + * @returns {Object} Loaded rule modules. + */ +var loadRules = function(relativeRulesDir, cwd) { + const rulesDir = path__default['default'].resolve(cwd, relativeRulesDir); + + // cache will help performance as IO operation are expensive + if (rulesDirCache[rulesDir]) { + return rulesDirCache[rulesDir]; + } + + const rules = Object.create(null); + + fs__default['default'].readdirSync(rulesDir).forEach(file => { + if (path__default['default'].extname(file) !== ".js") { + return; + } + rules[file.slice(0, -3)] = commonjsRequire(path__default['default'].join(rulesDir, file)); + }); + rulesDirCache[rulesDir] = rules; + + return rules; +}; + +/** + * @fileoverview Defining the hashing function in one place. + * @author Michael Ficarra + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +//------------------------------------------------------------------------------ +// Private +//------------------------------------------------------------------------------ + +/** + * hash the given string + * @param {string} str the string to hash + * @returns {string} the hash + */ +function hash(str) { + return murmur__default['default'](str).result().toString(36); +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +var hash_1 = hash; + +/** + * @fileoverview Utility for caching lint results. + * @author Kevin Partington + */ + +//----------------------------------------------------------------------------- +// Requirements +//----------------------------------------------------------------------------- + + + + + + + + +const debug$1 = require$$0__default['default']("eslint:lint-result-cache"); + +//----------------------------------------------------------------------------- +// Helpers +//----------------------------------------------------------------------------- + +const configHashCache = new WeakMap(); +const nodeVersion = process && process.version; + +const validCacheStrategies = ["metadata", "content"]; +const invalidCacheStrategyErrorMessage = `Cache strategy must be one of: ${validCacheStrategies + .map(strategy => `"${strategy}"`) + .join(", ")}`; + +/** + * Tests whether a provided cacheStrategy is valid + * @param {string} cacheStrategy The cache strategy to use + * @returns {boolean} true if `cacheStrategy` is one of `validCacheStrategies`; false otherwise + */ +function isValidCacheStrategy(cacheStrategy) { + return ( + validCacheStrategies.indexOf(cacheStrategy) !== -1 + ); +} + +/** + * Calculates the hash of the config + * @param {ConfigArray} config The config. + * @returns {string} The hash of the config + */ +function hashOfConfigFor(config) { + if (!configHashCache.has(config)) { + configHashCache.set(config, hash_1(`${require$$3.version}_${nodeVersion}_${stringify__default['default'](config)}`)); + } + + return configHashCache.get(config); +} + +//----------------------------------------------------------------------------- +// Public Interface +//----------------------------------------------------------------------------- + +/** + * Lint result cache. This wraps around the file-entry-cache module, + * transparently removing properties that are difficult or expensive to + * serialize and adding them back in on retrieval. + */ +class LintResultCache { + + /** + * Creates a new LintResultCache instance. + * @param {string} cacheFileLocation The cache file location. + * @param {"metadata" | "content"} cacheStrategy The cache strategy to use. + */ + constructor(cacheFileLocation, cacheStrategy) { + assert__default['default'](cacheFileLocation, "Cache file location is required"); + assert__default['default'](cacheStrategy, "Cache strategy is required"); + assert__default['default']( + isValidCacheStrategy(cacheStrategy), + invalidCacheStrategyErrorMessage + ); + + debug$1(`Caching results to ${cacheFileLocation}`); + + const useChecksum = cacheStrategy === "content"; + + debug$1( + `Using "${cacheStrategy}" strategy to detect changes` + ); + + this.fileEntryCache = fileEntryCache__default['default'].create( + cacheFileLocation, + void 0, + useChecksum + ); + this.cacheFileLocation = cacheFileLocation; + } + + /** + * Retrieve cached lint results for a given file path, if present in the + * cache. If the file is present and has not been changed, rebuild any + * missing result information. + * @param {string} filePath The file for which to retrieve lint results. + * @param {ConfigArray} config The config of the file. + * @returns {Object|null} The rebuilt lint results, or null if the file is + * changed or not in the filesystem. + */ + getCachedLintResults(filePath, config) { + + /* + * Cached lint results are valid if and only if: + * 1. The file is present in the filesystem + * 2. The file has not changed since the time it was previously linted + * 3. The ESLint configuration has not changed since the time the file + * was previously linted + * If any of these are not true, we will not reuse the lint results. + */ + const fileDescriptor = this.fileEntryCache.getFileDescriptor(filePath); + const hashOfConfig = hashOfConfigFor(config); + const changed = + fileDescriptor.changed || + fileDescriptor.meta.hashOfConfig !== hashOfConfig; + + if (fileDescriptor.notFound) { + debug$1(`File not found on the file system: ${filePath}`); + return null; + } + + if (changed) { + debug$1(`Cache entry not found or no longer valid: ${filePath}`); + return null; + } + + // If source is present but null, need to reread the file from the filesystem. + if ( + fileDescriptor.meta.results && + fileDescriptor.meta.results.source === null + ) { + debug$1(`Rereading cached result source from filesystem: ${filePath}`); + fileDescriptor.meta.results.source = fs__default['default'].readFileSync(filePath, "utf-8"); + } + + return fileDescriptor.meta.results; + } + + /** + * Set the cached lint results for a given file path, after removing any + * information that will be both unnecessary and difficult to serialize. + * Avoids caching results with an "output" property (meaning fixes were + * applied), to prevent potentially incorrect results if fixes are not + * written to disk. + * @param {string} filePath The file for which to set lint results. + * @param {ConfigArray} config The config of the file. + * @param {Object} result The lint result to be set for the file. + * @returns {void} + */ + setCachedLintResults(filePath, config, result) { + if (result && Object.prototype.hasOwnProperty.call(result, "output")) { + return; + } + + const fileDescriptor = this.fileEntryCache.getFileDescriptor(filePath); + + if (fileDescriptor && !fileDescriptor.notFound) { + debug$1(`Updating cached result: ${filePath}`); + + // Serialize the result, except that we want to remove the file source if present. + const resultToSerialize = Object.assign({}, result); + + /* + * Set result.source to null. + * In `getCachedLintResults`, if source is explicitly null, we will + * read the file from the filesystem to set the value again. + */ + if (Object.prototype.hasOwnProperty.call(resultToSerialize, "source")) { + resultToSerialize.source = null; + } + + fileDescriptor.meta.results = resultToSerialize; + fileDescriptor.meta.hashOfConfig = hashOfConfigFor(config); + } + } + + /** + * Persists the in-memory cache to disk. + * @returns {void} + */ + reconcile() { + debug$1(`Persisting cached results: ${this.cacheFileLocation}`); + this.fileEntryCache.reconcile(); + } +} + +var lintResultCache = LintResultCache; + +/** + * @fileoverview Main CLI object. + * @author Nicholas C. Zakas + */ + +/* + * The CLI object should *not* call process.exit() directly. It should only return + * exit codes. This allows other programs to use the CLI object and still control + * when the program exits. + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + + + + +const { + Legacy: { + ConfigOps, + naming, + CascadingConfigArrayFactory, + IgnorePattern, + getUsedExtractedConfigs + } +} = require$$2__default['default']; + +/* + * For some reason, ModuleResolver must be included via filepath instead of by + * API exports in order to work properly. That's why this is separated out onto + * its own require() statement. + */ + +const { FileEnumerator } = fileEnumerator; + +const { Linter: Linter$1 } = linter; + + + + + +const debug = require$$0__default['default']("eslint:cli-engine"); +const validFixTypes = new Set(["problem", "suggestion", "layout"]); + +//------------------------------------------------------------------------------ +// Typedefs +//------------------------------------------------------------------------------ + +// For VSCode IntelliSense +/** @typedef {import("../shared/types").ConfigData} ConfigData */ +/** @typedef {import("../shared/types").DeprecatedRuleInfo} DeprecatedRuleInfo */ +/** @typedef {import("../shared/types").LintMessage} LintMessage */ +/** @typedef {import("../shared/types").ParserOptions} ParserOptions */ +/** @typedef {import("../shared/types").Plugin} Plugin */ +/** @typedef {import("../shared/types").RuleConf} RuleConf */ +/** @typedef {import("../shared/types").Rule} Rule */ +/** @typedef {ReturnType} ConfigArray */ +/** @typedef {ReturnType} ExtractedConfig */ + +/** + * The options to configure a CLI engine with. + * @typedef {Object} CLIEngineOptions + * @property {boolean} [allowInlineConfig] Enable or disable inline configuration comments. + * @property {ConfigData} [baseConfig] Base config object, extended by all configs used with this CLIEngine instance + * @property {boolean} [cache] Enable result caching. + * @property {string} [cacheLocation] The cache file to use instead of .eslintcache. + * @property {string} [configFile] The configuration file to use. + * @property {string} [cwd] The value to use for the current working directory. + * @property {string[]} [envs] An array of environments to load. + * @property {string[]|null} [extensions] An array of file extensions to check. + * @property {boolean|Function} [fix] Execute in autofix mode. If a function, should return a boolean. + * @property {string[]} [fixTypes] Array of rule types to apply fixes for. + * @property {string[]} [globals] An array of global variables to declare. + * @property {boolean} [ignore] False disables use of .eslintignore. + * @property {string} [ignorePath] The ignore file to use instead of .eslintignore. + * @property {string|string[]} [ignorePattern] One or more glob patterns to ignore. + * @property {boolean} [useEslintrc] False disables looking for .eslintrc + * @property {string} [parser] The name of the parser to use. + * @property {ParserOptions} [parserOptions] An object of parserOption settings to use. + * @property {string[]} [plugins] An array of plugins to load. + * @property {Record} [rules] An object of rules to use. + * @property {string[]} [rulePaths] An array of directories to load custom rules from. + * @property {boolean} [reportUnusedDisableDirectives] `true` adds reports for unused eslint-disable directives + * @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file. + * @property {string} [resolvePluginsRelativeTo] The folder where plugins should be resolved from, defaulting to the CWD + */ + +/** + * A linting result. + * @typedef {Object} LintResult + * @property {string} filePath The path to the file that was linted. + * @property {LintMessage[]} messages All of the messages for the result. + * @property {number} errorCount Number of errors for the result. + * @property {number} warningCount Number of warnings for the result. + * @property {number} fixableErrorCount Number of fixable errors for the result. + * @property {number} fixableWarningCount Number of fixable warnings for the result. + * @property {string} [source] The source code of the file that was linted. + * @property {string} [output] The source code of the file that was linted, with as many fixes applied as possible. + */ + +/** + * Linting results. + * @typedef {Object} LintReport + * @property {LintResult[]} results All of the result. + * @property {number} errorCount Number of errors for the result. + * @property {number} warningCount Number of warnings for the result. + * @property {number} fixableErrorCount Number of fixable errors for the result. + * @property {number} fixableWarningCount Number of fixable warnings for the result. + * @property {DeprecatedRuleInfo[]} usedDeprecatedRules The list of used deprecated rules. + */ + +/** + * Private data for CLIEngine. + * @typedef {Object} CLIEngineInternalSlots + * @property {Map} additionalPluginPool The map for additional plugins. + * @property {string} cacheFilePath The path to the cache of lint results. + * @property {CascadingConfigArrayFactory} configArrayFactory The factory of configs. + * @property {(filePath: string) => boolean} defaultIgnores The default predicate function to check if a file ignored or not. + * @property {FileEnumerator} fileEnumerator The file enumerator. + * @property {ConfigArray[]} lastConfigArrays The list of config arrays that the last `executeOnFiles` or `executeOnText` used. + * @property {LintResultCache|null} lintResultCache The cache of lint results. + * @property {Linter} linter The linter instance which has loaded rules. + * @property {CLIEngineOptions} options The normalized options of this instance. + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +/** @type {WeakMap} */ +const internalSlotsMap = new WeakMap(); + +/** + * Determines if each fix type in an array is supported by ESLint and throws + * an error if not. + * @param {string[]} fixTypes An array of fix types to check. + * @returns {void} + * @throws {Error} If an invalid fix type is found. + */ +function validateFixTypes(fixTypes) { + for (const fixType of fixTypes) { + if (!validFixTypes.has(fixType)) { + throw new Error(`Invalid fix type "${fixType}" found.`); + } + } +} + +/** + * It will calculate the error and warning count for collection of messages per file + * @param {LintMessage[]} messages Collection of messages + * @returns {Object} Contains the stats + * @private + */ +function calculateStatsPerFile(messages) { + return messages.reduce((stat, message) => { + if (message.fatal || message.severity === 2) { + stat.errorCount++; + if (message.fix) { + stat.fixableErrorCount++; + } + } else { + stat.warningCount++; + if (message.fix) { + stat.fixableWarningCount++; + } + } + return stat; + }, { + errorCount: 0, + warningCount: 0, + fixableErrorCount: 0, + fixableWarningCount: 0 + }); +} + +/** + * It will calculate the error and warning count for collection of results from all files + * @param {LintResult[]} results Collection of messages from all the files + * @returns {Object} Contains the stats + * @private + */ +function calculateStatsPerRun(results) { + return results.reduce((stat, result) => { + stat.errorCount += result.errorCount; + stat.warningCount += result.warningCount; + stat.fixableErrorCount += result.fixableErrorCount; + stat.fixableWarningCount += result.fixableWarningCount; + return stat; + }, { + errorCount: 0, + warningCount: 0, + fixableErrorCount: 0, + fixableWarningCount: 0 + }); +} + +/** + * Processes an source code using ESLint. + * @param {Object} config The config object. + * @param {string} config.text The source code to verify. + * @param {string} config.cwd The path to the current working directory. + * @param {string|undefined} config.filePath The path to the file of `text`. If this is undefined, it uses ``. + * @param {ConfigArray} config.config The config. + * @param {boolean} config.fix If `true` then it does fix. + * @param {boolean} config.allowInlineConfig If `true` then it uses directive comments. + * @param {boolean} config.reportUnusedDisableDirectives If `true` then it reports unused `eslint-disable` comments. + * @param {FileEnumerator} config.fileEnumerator The file enumerator to check if a path is a target or not. + * @param {Linter} config.linter The linter instance to verify. + * @returns {LintResult} The result of linting. + * @private + */ +function verifyText({ + text, + cwd, + filePath: providedFilePath, + config, + fix, + allowInlineConfig, + reportUnusedDisableDirectives, + fileEnumerator, + linter +}) { + const filePath = providedFilePath || ""; + + debug(`Lint ${filePath}`); + + /* + * Verify. + * `config.extractConfig(filePath)` requires an absolute path, but `linter` + * doesn't know CWD, so it gives `linter` an absolute path always. + */ + const filePathToVerify = filePath === "" ? path__default['default'].join(cwd, filePath) : filePath; + const { fixed, messages, output } = linter.verifyAndFix( + text, + config, + { + allowInlineConfig, + filename: filePathToVerify, + fix, + reportUnusedDisableDirectives, + + /** + * Check if the linter should adopt a given code block or not. + * @param {string} blockFilename The virtual filename of a code block. + * @returns {boolean} `true` if the linter should adopt the code block. + */ + filterCodeBlock(blockFilename) { + return fileEnumerator.isTargetPath(blockFilename); + } + } + ); + + // Tweak and return. + const result = { + filePath, + messages, + ...calculateStatsPerFile(messages) + }; + + if (fixed) { + result.output = output; + } + if ( + result.errorCount + result.warningCount > 0 && + typeof result.output === "undefined" + ) { + result.source = text; + } + + return result; +} + +/** + * Returns result with warning by ignore settings + * @param {string} filePath File path of checked code + * @param {string} baseDir Absolute path of base directory + * @returns {LintResult} Result with single warning + * @private + */ +function createIgnoreResult(filePath, baseDir) { + let message; + const isHidden = filePath.split(path__default['default'].sep) + .find(segment => /^\./u.test(segment)); + const isInNodeModules = baseDir && path__default['default'].relative(baseDir, filePath).startsWith("node_modules"); + + if (isHidden) { + message = "File ignored by default. Use a negated ignore pattern (like \"--ignore-pattern '!'\") to override."; + } else if (isInNodeModules) { + message = "File ignored by default. Use \"--ignore-pattern '!node_modules/*'\" to override."; + } else { + message = "File ignored because of a matching ignore pattern. Use \"--no-ignore\" to override."; + } + + return { + filePath: path__default['default'].resolve(filePath), + messages: [ + { + fatal: false, + severity: 1, + message + } + ], + errorCount: 0, + warningCount: 1, + fixableErrorCount: 0, + fixableWarningCount: 0 + }; +} + +/** + * Get a rule. + * @param {string} ruleId The rule ID to get. + * @param {ConfigArray[]} configArrays The config arrays that have plugin rules. + * @returns {Rule|null} The rule or null. + */ +function getRule(ruleId, configArrays) { + for (const configArray of configArrays) { + const rule = configArray.pluginRules.get(ruleId); + + if (rule) { + return rule; + } + } + return rules$2.get(ruleId) || null; +} + +/** + * Collect used deprecated rules. + * @param {ConfigArray[]} usedConfigArrays The config arrays which were used. + * @returns {IterableIterator} Used deprecated rules. + */ +function *iterateRuleDeprecationWarnings(usedConfigArrays) { + const processedRuleIds = new Set(); + + // Flatten used configs. + /** @type {ExtractedConfig[]} */ + const configs = [].concat( + ...usedConfigArrays.map(getUsedExtractedConfigs) + ); + + // Traverse rule configs. + for (const config of configs) { + for (const [ruleId, ruleConfig] of Object.entries(config.rules)) { + + // Skip if it was processed. + if (processedRuleIds.has(ruleId)) { + continue; + } + processedRuleIds.add(ruleId); + + // Skip if it's not used. + if (!ConfigOps.getRuleSeverity(ruleConfig)) { + continue; + } + const rule = getRule(ruleId, usedConfigArrays); + + // Skip if it's not deprecated. + if (!(rule && rule.meta && rule.meta.deprecated)) { + continue; + } + + // This rule was used and deprecated. + yield { + ruleId, + replacedBy: rule.meta.replacedBy || [] + }; + } + } +} + +/** + * Checks if the given message is an error message. + * @param {LintMessage} message The message to check. + * @returns {boolean} Whether or not the message is an error message. + * @private + */ +function isErrorMessage(message) { + return message.severity === 2; +} + + +/** + * return the cacheFile to be used by eslint, based on whether the provided parameter is + * a directory or looks like a directory (ends in `path.sep`), in which case the file + * name will be the `cacheFile/.cache_hashOfCWD` + * + * if cacheFile points to a file or looks like a file then in will just use that file + * @param {string} cacheFile The name of file to be used to store the cache + * @param {string} cwd Current working directory + * @returns {string} the resolved path to the cache file + */ +function getCacheFile(cacheFile, cwd) { + + /* + * make sure the path separators are normalized for the environment/os + * keeping the trailing path separator if present + */ + const normalizedCacheFile = path__default['default'].normalize(cacheFile); + + const resolvedCacheFile = path__default['default'].resolve(cwd, normalizedCacheFile); + const looksLikeADirectory = normalizedCacheFile.slice(-1) === path__default['default'].sep; + + /** + * return the name for the cache file in case the provided parameter is a directory + * @returns {string} the resolved path to the cacheFile + */ + function getCacheFileForDirectory() { + return path__default['default'].join(resolvedCacheFile, `.cache_${hash_1(cwd)}`); + } + + let fileStats; + + try { + fileStats = fs__default['default'].lstatSync(resolvedCacheFile); + } catch { + fileStats = null; + } + + + /* + * in case the file exists we need to verify if the provided path + * is a directory or a file. If it is a directory we want to create a file + * inside that directory + */ + if (fileStats) { + + /* + * is a directory or is a file, but the original file the user provided + * looks like a directory but `path.resolve` removed the `last path.sep` + * so we need to still treat this like a directory + */ + if (fileStats.isDirectory() || looksLikeADirectory) { + return getCacheFileForDirectory(); + } + + // is file so just use that file + return resolvedCacheFile; + } + + /* + * here we known the file or directory doesn't exist, + * so we will try to infer if its a directory if it looks like a directory + * for the current operating system. + */ + + // if the last character passed is a path separator we assume is a directory + if (looksLikeADirectory) { + return getCacheFileForDirectory(); + } + + return resolvedCacheFile; +} + +/** + * Convert a string array to a boolean map. + * @param {string[]|null} keys The keys to assign true. + * @param {boolean} defaultValue The default value for each property. + * @param {string} displayName The property name which is used in error message. + * @returns {Record} The boolean map. + */ +function toBooleanMap(keys, defaultValue, displayName) { + if (keys && !Array.isArray(keys)) { + throw new Error(`${displayName} must be an array.`); + } + if (keys && keys.length > 0) { + return keys.reduce((map, def) => { + const [key, value] = def.split(":"); + + if (key !== "__proto__") { + map[key] = value === void 0 + ? defaultValue + : value === "true"; + } + + return map; + }, {}); + } + return void 0; +} + +/** + * Create a config data from CLI options. + * @param {CLIEngineOptions} options The options + * @returns {ConfigData|null} The created config data. + */ +function createConfigDataFromOptions(options) { + const { + ignorePattern, + parser, + parserOptions, + plugins, + rules + } = options; + const env = toBooleanMap(options.envs, true, "envs"); + const globals = toBooleanMap(options.globals, false, "globals"); + + if ( + env === void 0 && + globals === void 0 && + (ignorePattern === void 0 || ignorePattern.length === 0) && + parser === void 0 && + parserOptions === void 0 && + plugins === void 0 && + rules === void 0 + ) { + return null; + } + return { + env, + globals, + ignorePatterns: ignorePattern, + parser, + parserOptions, + plugins, + rules + }; +} + +/** + * Checks whether a directory exists at the given location + * @param {string} resolvedPath A path from the CWD + * @returns {boolean} `true` if a directory exists + */ +function directoryExists(resolvedPath) { + try { + return fs__default['default'].statSync(resolvedPath).isDirectory(); + } catch (error) { + if (error && (error.code === "ENOENT" || error.code === "ENOTDIR")) { + return false; + } + throw error; + } +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +class CLIEngine$2 { + + /** + * Creates a new instance of the core CLI engine. + * @param {CLIEngineOptions} providedOptions The options for this instance. + */ + constructor(providedOptions) { + const options = Object.assign( + Object.create(null), + defaultCliOptions, + { cwd: process.cwd() }, + providedOptions + ); + + if (options.fix === void 0) { + options.fix = false; + } + + const additionalPluginPool = new Map(); + const cacheFilePath = getCacheFile( + options.cacheLocation || options.cacheFile, + options.cwd + ); + const configArrayFactory = new CascadingConfigArrayFactory({ + additionalPluginPool, + baseConfig: options.baseConfig || null, + cliConfig: createConfigDataFromOptions(options), + cwd: options.cwd, + ignorePath: options.ignorePath, + resolvePluginsRelativeTo: options.resolvePluginsRelativeTo, + rulePaths: options.rulePaths, + specificConfigPath: options.configFile, + useEslintrc: options.useEslintrc, + builtInRules: rules$2, + loadRules, + eslintRecommendedPath: path__default['default'].resolve(__dirname, "../../conf/eslint-recommended.js"), + eslintAllPath: path__default['default'].resolve(__dirname, "../../conf/eslint-all.js") + }); + const fileEnumerator = new FileEnumerator({ + configArrayFactory, + cwd: options.cwd, + extensions: options.extensions, + globInputPaths: options.globInputPaths, + errorOnUnmatchedPattern: options.errorOnUnmatchedPattern, + ignore: options.ignore + }); + const lintResultCache$1 = + options.cache ? new lintResultCache(cacheFilePath, options.cacheStrategy) : null; + const linter = new Linter$1({ cwd: options.cwd }); + + /** @type {ConfigArray[]} */ + const lastConfigArrays = [configArrayFactory.getConfigArrayForFile()]; + + // Store private data. + internalSlotsMap.set(this, { + additionalPluginPool, + cacheFilePath, + configArrayFactory, + defaultIgnores: IgnorePattern.createDefaultIgnore(options.cwd), + fileEnumerator, + lastConfigArrays, + lintResultCache: lintResultCache$1, + linter, + options + }); + + // setup special filter for fixes + if (options.fix && options.fixTypes && options.fixTypes.length > 0) { + debug(`Using fix types ${options.fixTypes}`); + + // throw an error if any invalid fix types are found + validateFixTypes(options.fixTypes); + + // convert to Set for faster lookup + const fixTypes = new Set(options.fixTypes); + + // save original value of options.fix in case it's a function + const originalFix = (typeof options.fix === "function") + ? options.fix : () => true; + + options.fix = message => { + const rule = message.ruleId && getRule(message.ruleId, lastConfigArrays); + const matches = rule && rule.meta && fixTypes.has(rule.meta.type); + + return matches && originalFix(message); + }; + } + } + + getRules() { + const { lastConfigArrays } = internalSlotsMap.get(this); + + return new Map(function *() { + yield* rules$2; + + for (const configArray of lastConfigArrays) { + yield* configArray.pluginRules; + } + }()); + } + + /** + * Returns results that only contains errors. + * @param {LintResult[]} results The results to filter. + * @returns {LintResult[]} The filtered results. + */ + static getErrorResults(results) { + const filtered = []; + + results.forEach(result => { + const filteredMessages = result.messages.filter(isErrorMessage); + + if (filteredMessages.length > 0) { + filtered.push({ + ...result, + messages: filteredMessages, + errorCount: filteredMessages.length, + warningCount: 0, + fixableErrorCount: result.fixableErrorCount, + fixableWarningCount: 0 + }); + } + }); + + return filtered; + } + + /** + * Outputs fixes from the given results to files. + * @param {LintReport} report The report object created by CLIEngine. + * @returns {void} + */ + static outputFixes(report) { + report.results.filter(result => Object.prototype.hasOwnProperty.call(result, "output")).forEach(result => { + fs__default['default'].writeFileSync(result.filePath, result.output); + }); + } + + + /** + * Add a plugin by passing its configuration + * @param {string} name Name of the plugin. + * @param {Plugin} pluginObject Plugin configuration object. + * @returns {void} + */ + addPlugin(name, pluginObject) { + const { + additionalPluginPool, + configArrayFactory, + lastConfigArrays + } = internalSlotsMap.get(this); + + additionalPluginPool.set(name, pluginObject); + configArrayFactory.clearCache(); + lastConfigArrays.length = 1; + lastConfigArrays[0] = configArrayFactory.getConfigArrayForFile(); + } + + /** + * Resolves the patterns passed into executeOnFiles() into glob-based patterns + * for easier handling. + * @param {string[]} patterns The file patterns passed on the command line. + * @returns {string[]} The equivalent glob patterns. + */ + resolveFileGlobPatterns(patterns) { + const { options } = internalSlotsMap.get(this); + + if (options.globInputPaths === false) { + return patterns.filter(Boolean); + } + + const extensions = (options.extensions || [".js"]).map(ext => ext.replace(/^\./u, "")); + const dirSuffix = `/**/*.{${extensions.join(",")}}`; + + return patterns.filter(Boolean).map(pathname => { + const resolvedPath = path__default['default'].resolve(options.cwd, pathname); + const newPath = directoryExists(resolvedPath) + ? pathname.replace(/[/\\]$/u, "") + dirSuffix + : pathname; + + return path__default['default'].normalize(newPath).replace(/\\/gu, "/"); + }); + } + + /** + * Executes the current configuration on an array of file and directory names. + * @param {string[]} patterns An array of file and directory names. + * @returns {LintReport} The results for all files that were linted. + */ + executeOnFiles(patterns) { + const { + cacheFilePath, + fileEnumerator, + lastConfigArrays, + lintResultCache, + linter, + options: { + allowInlineConfig, + cache, + cwd, + fix, + reportUnusedDisableDirectives + } + } = internalSlotsMap.get(this); + const results = []; + const startTime = Date.now(); + + // Clear the last used config arrays. + lastConfigArrays.length = 0; + + // Delete cache file; should this do here? + if (!cache) { + try { + fs__default['default'].unlinkSync(cacheFilePath); + } catch (error) { + const errorCode = error && error.code; + + // Ignore errors when no such file exists or file system is read only (and cache file does not exist) + if (errorCode !== "ENOENT" && !(errorCode === "EROFS" && !fs__default['default'].existsSync(cacheFilePath))) { + throw error; + } + } + } + + // Iterate source code files. + for (const { config, filePath, ignored } of fileEnumerator.iterateFiles(patterns)) { + if (ignored) { + results.push(createIgnoreResult(filePath, cwd)); + continue; + } + + /* + * Store used configs for: + * - this method uses to collect used deprecated rules. + * - `getRules()` method uses to collect all loaded rules. + * - `--fix-type` option uses to get the loaded rule's meta data. + */ + if (!lastConfigArrays.includes(config)) { + lastConfigArrays.push(config); + } + + // Skip if there is cached result. + if (lintResultCache) { + const cachedResult = + lintResultCache.getCachedLintResults(filePath, config); + + if (cachedResult) { + const hadMessages = + cachedResult.messages && + cachedResult.messages.length > 0; + + if (hadMessages && fix) { + debug(`Reprocessing cached file to allow autofix: ${filePath}`); + } else { + debug(`Skipping file since it hasn't changed: ${filePath}`); + results.push(cachedResult); + continue; + } + } + } + + // Do lint. + const result = verifyText({ + text: fs__default['default'].readFileSync(filePath, "utf8"), + filePath, + config, + cwd, + fix, + allowInlineConfig, + reportUnusedDisableDirectives, + fileEnumerator, + linter + }); + + results.push(result); + + /* + * Store the lint result in the LintResultCache. + * NOTE: The LintResultCache will remove the file source and any + * other properties that are difficult to serialize, and will + * hydrate those properties back in on future lint runs. + */ + if (lintResultCache) { + lintResultCache.setCachedLintResults(filePath, config, result); + } + } + + // Persist the cache to disk. + if (lintResultCache) { + lintResultCache.reconcile(); + } + + debug(`Linting complete in: ${Date.now() - startTime}ms`); + let usedDeprecatedRules; + + return { + results, + ...calculateStatsPerRun(results), + + // Initialize it lazily because CLI and `ESLint` API don't use it. + get usedDeprecatedRules() { + if (!usedDeprecatedRules) { + usedDeprecatedRules = Array.from( + iterateRuleDeprecationWarnings(lastConfigArrays) + ); + } + return usedDeprecatedRules; + } + }; + } + + /** + * Executes the current configuration on text. + * @param {string} text A string of JavaScript code to lint. + * @param {string} [filename] An optional string representing the texts filename. + * @param {boolean} [warnIgnored] Always warn when a file is ignored + * @returns {LintReport} The results for the linting. + */ + executeOnText(text, filename, warnIgnored) { + const { + configArrayFactory, + fileEnumerator, + lastConfigArrays, + linter, + options: { + allowInlineConfig, + cwd, + fix, + reportUnusedDisableDirectives + } + } = internalSlotsMap.get(this); + const results = []; + const startTime = Date.now(); + const resolvedFilename = filename && path__default['default'].resolve(cwd, filename); + + + // Clear the last used config arrays. + lastConfigArrays.length = 0; + if (resolvedFilename && this.isPathIgnored(resolvedFilename)) { + if (warnIgnored) { + results.push(createIgnoreResult(resolvedFilename, cwd)); + } + } else { + const config = configArrayFactory.getConfigArrayForFile( + resolvedFilename || "__placeholder__.js" + ); + + /* + * Store used configs for: + * - this method uses to collect used deprecated rules. + * - `getRules()` method uses to collect all loaded rules. + * - `--fix-type` option uses to get the loaded rule's meta data. + */ + lastConfigArrays.push(config); + + // Do lint. + results.push(verifyText({ + text, + filePath: resolvedFilename, + config, + cwd, + fix, + allowInlineConfig, + reportUnusedDisableDirectives, + fileEnumerator, + linter + })); + } + + debug(`Linting complete in: ${Date.now() - startTime}ms`); + let usedDeprecatedRules; + + return { + results, + ...calculateStatsPerRun(results), + + // Initialize it lazily because CLI and `ESLint` API don't use it. + get usedDeprecatedRules() { + if (!usedDeprecatedRules) { + usedDeprecatedRules = Array.from( + iterateRuleDeprecationWarnings(lastConfigArrays) + ); + } + return usedDeprecatedRules; + } + }; + } + + /** + * Returns a configuration object for the given file based on the CLI options. + * This is the same logic used by the ESLint CLI executable to determine + * configuration for each file it processes. + * @param {string} filePath The path of the file to retrieve a config object for. + * @returns {ConfigData} A configuration object for the file. + */ + getConfigForFile(filePath) { + const { configArrayFactory, options } = internalSlotsMap.get(this); + const absolutePath = path__default['default'].resolve(options.cwd, filePath); + + if (directoryExists(absolutePath)) { + throw Object.assign( + new Error("'filePath' should not be a directory path."), + { messageTemplate: "print-config-with-directory-path" } + ); + } + + return configArrayFactory + .getConfigArrayForFile(absolutePath) + .extractConfig(absolutePath) + .toCompatibleObjectAsConfigFileContent(); + } + + /** + * Checks if a given path is ignored by ESLint. + * @param {string} filePath The path of the file to check. + * @returns {boolean} Whether or not the given path is ignored. + */ + isPathIgnored(filePath) { + const { + configArrayFactory, + defaultIgnores, + options: { cwd, ignore } + } = internalSlotsMap.get(this); + const absolutePath = path__default['default'].resolve(cwd, filePath); + + if (ignore) { + const config = configArrayFactory + .getConfigArrayForFile(absolutePath) + .extractConfig(absolutePath); + const ignores = config.ignores || defaultIgnores; + + return ignores(absolutePath); + } + + return defaultIgnores(absolutePath); + } + + /** + * Returns the formatter representing the given format or null if the `format` is not a string. + * @param {string} [format] The name of the format to load or the path to a + * custom formatter. + * @returns {(Function|null)} The formatter function or null if the `format` is not a string. + */ + getFormatter(format) { + + // default is stylish + const resolvedFormatName = format || "stylish"; + + // only strings are valid formatters + if (typeof resolvedFormatName === "string") { + + // replace \ with / for Windows compatibility + const normalizedFormatName = resolvedFormatName.replace(/\\/gu, "/"); + + const slots = internalSlotsMap.get(this); + const cwd = slots ? slots.options.cwd : process.cwd(); + const namespace = naming.getNamespaceFromTerm(normalizedFormatName); + + let formatterPath; + + // if there's a slash, then it's a file (TODO: this check seems dubious for scoped npm packages) + if (!namespace && normalizedFormatName.indexOf("/") > -1) { + formatterPath = path__default['default'].resolve(cwd, normalizedFormatName); + } else { + try { + const npmFormat = naming.normalizePackageName(normalizedFormatName, "eslint-formatter"); + + formatterPath = relativeModuleResolver.resolve(npmFormat, path__default['default'].join(cwd, "__placeholder__.js")); + } catch { + formatterPath = path__default['default'].resolve(__dirname, "formatters", normalizedFormatName); + } + } + + try { + return commonjsRequire(formatterPath); + } catch (ex) { + ex.message = `There was a problem loading formatter: ${formatterPath}\nError: ${ex.message}`; + throw ex; + } + + } else { + return null; + } + } +} + +CLIEngine$2.version = require$$3.version; +CLIEngine$2.getFormatter = CLIEngine$2.prototype.getFormatter; + +var cliEngine$1 = { + CLIEngine: CLIEngine$2, + + /** + * Get the internal slots of a given CLIEngine instance for tests. + * @param {CLIEngine} instance The CLIEngine instance to get. + * @returns {CLIEngineInternalSlots} The internal slots. + */ + getCLIEngineInternalSlots(instance) { + return internalSlotsMap.get(instance); + } +}; + +const { CLIEngine: CLIEngine$1 } = cliEngine$1; + +var cliEngine = { + CLIEngine: CLIEngine$1 +}; + +/** + * @fileoverview Main API Class + * @author Kai Cataldo + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +const { promisify } = util__default['default']; +const { CLIEngine, getCLIEngineInternalSlots } = cliEngine$1; + +const { + Legacy: { + ConfigOps: { + getRuleSeverity + } + } +} = require$$2__default['default']; +const { version } = require$$3; + +//------------------------------------------------------------------------------ +// Typedefs +//------------------------------------------------------------------------------ + +/** @typedef {import("../cli-engine/cli-engine").LintReport} CLIEngineLintReport */ +/** @typedef {import("../shared/types").DeprecatedRuleInfo} DeprecatedRuleInfo */ +/** @typedef {import("../shared/types").ConfigData} ConfigData */ +/** @typedef {import("../shared/types").LintMessage} LintMessage */ +/** @typedef {import("../shared/types").Plugin} Plugin */ +/** @typedef {import("../shared/types").Rule} Rule */ +/** @typedef {import("./load-formatter").Formatter} Formatter */ + +/** + * The options with which to configure the ESLint instance. + * @typedef {Object} ESLintOptions + * @property {boolean} [allowInlineConfig] Enable or disable inline configuration comments. + * @property {ConfigData} [baseConfig] Base config object, extended by all configs used with this instance + * @property {boolean} [cache] Enable result caching. + * @property {string} [cacheLocation] The cache file to use instead of .eslintcache. + * @property {"metadata" | "content"} [cacheStrategy] The strategy used to detect changed files. + * @property {string} [cwd] The value to use for the current working directory. + * @property {boolean} [errorOnUnmatchedPattern] If `false` then `ESLint#lintFiles()` doesn't throw even if no target files found. Defaults to `true`. + * @property {string[]} [extensions] An array of file extensions to check. + * @property {boolean|Function} [fix] Execute in autofix mode. If a function, should return a boolean. + * @property {string[]} [fixTypes] Array of rule types to apply fixes for. + * @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file. + * @property {boolean} [ignore] False disables use of .eslintignore. + * @property {string} [ignorePath] The ignore file to use instead of .eslintignore. + * @property {ConfigData} [overrideConfig] Override config object, overrides all configs used with this instance + * @property {string} [overrideConfigFile] The configuration file to use. + * @property {Record} [plugins] An array of plugin implementations. + * @property {"error" | "warn" | "off"} [reportUnusedDisableDirectives] the severity to report unused eslint-disable directives. + * @property {string} [resolvePluginsRelativeTo] The folder where plugins should be resolved from, defaulting to the CWD. + * @property {string[]} [rulePaths] An array of directories to load custom rules from. + * @property {boolean} [useEslintrc] False disables looking for .eslintrc.* files. + */ + +/** + * A rules metadata object. + * @typedef {Object} RulesMeta + * @property {string} id The plugin ID. + * @property {Object} definition The plugin definition. + */ + +/** + * A linting result. + * @typedef {Object} LintResult + * @property {string} filePath The path to the file that was linted. + * @property {LintMessage[]} messages All of the messages for the result. + * @property {number} errorCount Number of errors for the result. + * @property {number} warningCount Number of warnings for the result. + * @property {number} fixableErrorCount Number of fixable errors for the result. + * @property {number} fixableWarningCount Number of fixable warnings for the result. + * @property {string} [source] The source code of the file that was linted. + * @property {string} [output] The source code of the file that was linted, with as many fixes applied as possible. + * @property {DeprecatedRuleInfo[]} usedDeprecatedRules The list of used deprecated rules. + */ + +/** + * Private members for the `ESLint` instance. + * @typedef {Object} ESLintPrivateMembers + * @property {CLIEngine} cliEngine The wrapped CLIEngine instance. + * @property {ESLintOptions} options The options used to instantiate the ESLint instance. + */ + +//------------------------------------------------------------------------------ +// Helpers +//------------------------------------------------------------------------------ + +const writeFile = promisify(fs__default['default'].writeFile); + +/** + * The map with which to store private class members. + * @type {WeakMap} + */ +const privateMembersMap = new WeakMap(); + +/** + * Check if a given value is a non-empty string or not. + * @param {any} x The value to check. + * @returns {boolean} `true` if `x` is a non-empty string. + */ +function isNonEmptyString(x) { + return typeof x === "string" && x.trim() !== ""; +} + +/** + * Check if a given value is an array of non-empty stringss or not. + * @param {any} x The value to check. + * @returns {boolean} `true` if `x` is an array of non-empty stringss. + */ +function isArrayOfNonEmptyString(x) { + return Array.isArray(x) && x.every(isNonEmptyString); +} + +/** + * Check if a given value is a valid fix type or not. + * @param {any} x The value to check. + * @returns {boolean} `true` if `x` is valid fix type. + */ +function isFixType(x) { + return x === "problem" || x === "suggestion" || x === "layout"; +} + +/** + * Check if a given value is an array of fix types or not. + * @param {any} x The value to check. + * @returns {boolean} `true` if `x` is an array of fix types. + */ +function isFixTypeArray(x) { + return Array.isArray(x) && x.every(isFixType); +} + +/** + * The error for invalid options. + */ +class ESLintInvalidOptionsError extends Error { + constructor(messages) { + super(`Invalid Options:\n- ${messages.join("\n- ")}`); + this.code = "ESLINT_INVALID_OPTIONS"; + Error.captureStackTrace(this, ESLintInvalidOptionsError); + } +} + +/** + * Validates and normalizes options for the wrapped CLIEngine instance. + * @param {ESLintOptions} options The options to process. + * @returns {ESLintOptions} The normalized options. + */ +function processOptions({ + allowInlineConfig = true, // ← we cannot use `overrideConfig.noInlineConfig` instead because `allowInlineConfig` has side-effect that suppress warnings that show inline configs are ignored. + baseConfig = null, + cache = false, + cacheLocation = ".eslintcache", + cacheStrategy = "metadata", + cwd = process.cwd(), + errorOnUnmatchedPattern = true, + extensions = null, // ← should be null by default because if it's an array then it suppresses RFC20 feature. + fix = false, + fixTypes = null, // ← should be null by default because if it's an array then it suppresses rules that don't have the `meta.type` property. + globInputPaths = true, + ignore = true, + ignorePath = null, // ← should be null by default because if it's a string then it may throw ENOENT. + overrideConfig = null, + overrideConfigFile = null, + plugins = {}, + reportUnusedDisableDirectives = null, // ← should be null by default because if it's a string then it overrides the 'reportUnusedDisableDirectives' setting in config files. And we cannot use `overrideConfig.reportUnusedDisableDirectives` instead because we cannot configure the `error` severity with that. + resolvePluginsRelativeTo = null, // ← should be null by default because if it's a string then it suppresses RFC47 feature. + rulePaths = [], + useEslintrc = true, + ...unknownOptions +}) { + const errors = []; + const unknownOptionKeys = Object.keys(unknownOptions); + + if (unknownOptionKeys.length >= 1) { + errors.push(`Unknown options: ${unknownOptionKeys.join(", ")}`); + if (unknownOptionKeys.includes("cacheFile")) { + errors.push("'cacheFile' has been removed. Please use the 'cacheLocation' option instead."); + } + if (unknownOptionKeys.includes("configFile")) { + errors.push("'configFile' has been removed. Please use the 'overrideConfigFile' option instead."); + } + if (unknownOptionKeys.includes("envs")) { + errors.push("'envs' has been removed. Please use the 'overrideConfig.env' option instead."); + } + if (unknownOptionKeys.includes("globals")) { + errors.push("'globals' has been removed. Please use the 'overrideConfig.globals' option instead."); + } + if (unknownOptionKeys.includes("ignorePattern")) { + errors.push("'ignorePattern' has been removed. Please use the 'overrideConfig.ignorePatterns' option instead."); + } + if (unknownOptionKeys.includes("parser")) { + errors.push("'parser' has been removed. Please use the 'overrideConfig.parser' option instead."); + } + if (unknownOptionKeys.includes("parserOptions")) { + errors.push("'parserOptions' has been removed. Please use the 'overrideConfig.parserOptions' option instead."); + } + if (unknownOptionKeys.includes("rules")) { + errors.push("'rules' has been removed. Please use the 'overrideConfig.rules' option instead."); + } + } + if (typeof allowInlineConfig !== "boolean") { + errors.push("'allowInlineConfig' must be a boolean."); + } + if (typeof baseConfig !== "object") { + errors.push("'baseConfig' must be an object or null."); + } + if (typeof cache !== "boolean") { + errors.push("'cache' must be a boolean."); + } + if (!isNonEmptyString(cacheLocation)) { + errors.push("'cacheLocation' must be a non-empty string."); + } + if ( + cacheStrategy !== "metadata" && + cacheStrategy !== "content" + ) { + errors.push("'cacheStrategy' must be any of \"metadata\", \"content\"."); + } + if (!isNonEmptyString(cwd) || !path__default['default'].isAbsolute(cwd)) { + errors.push("'cwd' must be an absolute path."); + } + if (typeof errorOnUnmatchedPattern !== "boolean") { + errors.push("'errorOnUnmatchedPattern' must be a boolean."); + } + if (!isArrayOfNonEmptyString(extensions) && extensions !== null) { + errors.push("'extensions' must be an array of non-empty strings or null."); + } + if (typeof fix !== "boolean" && typeof fix !== "function") { + errors.push("'fix' must be a boolean or a function."); + } + if (fixTypes !== null && !isFixTypeArray(fixTypes)) { + errors.push("'fixTypes' must be an array of any of \"problem\", \"suggestion\", and \"layout\"."); + } + if (typeof globInputPaths !== "boolean") { + errors.push("'globInputPaths' must be a boolean."); + } + if (typeof ignore !== "boolean") { + errors.push("'ignore' must be a boolean."); + } + if (!isNonEmptyString(ignorePath) && ignorePath !== null) { + errors.push("'ignorePath' must be a non-empty string or null."); + } + if (typeof overrideConfig !== "object") { + errors.push("'overrideConfig' must be an object or null."); + } + if (!isNonEmptyString(overrideConfigFile) && overrideConfigFile !== null) { + errors.push("'overrideConfigFile' must be a non-empty string or null."); + } + if (typeof plugins !== "object") { + errors.push("'plugins' must be an object or null."); + } else if (plugins !== null && Object.keys(plugins).includes("")) { + errors.push("'plugins' must not include an empty string."); + } + if (Array.isArray(plugins)) { + errors.push("'plugins' doesn't add plugins to configuration to load. Please use the 'overrideConfig.plugins' option instead."); + } + if ( + reportUnusedDisableDirectives !== "error" && + reportUnusedDisableDirectives !== "warn" && + reportUnusedDisableDirectives !== "off" && + reportUnusedDisableDirectives !== null + ) { + errors.push("'reportUnusedDisableDirectives' must be any of \"error\", \"warn\", \"off\", and null."); + } + if ( + !isNonEmptyString(resolvePluginsRelativeTo) && + resolvePluginsRelativeTo !== null + ) { + errors.push("'resolvePluginsRelativeTo' must be a non-empty string or null."); + } + if (!isArrayOfNonEmptyString(rulePaths)) { + errors.push("'rulePaths' must be an array of non-empty strings."); + } + if (typeof useEslintrc !== "boolean") { + errors.push("'useEslintrc' must be a boolean."); + } + + if (errors.length > 0) { + throw new ESLintInvalidOptionsError(errors); + } + + return { + allowInlineConfig, + baseConfig, + cache, + cacheLocation, + cacheStrategy, + configFile: overrideConfigFile, + cwd, + errorOnUnmatchedPattern, + extensions, + fix, + fixTypes, + globInputPaths, + ignore, + ignorePath, + reportUnusedDisableDirectives, + resolvePluginsRelativeTo, + rulePaths, + useEslintrc + }; +} + +/** + * Check if a value has one or more properties and that value is not undefined. + * @param {any} obj The value to check. + * @returns {boolean} `true` if `obj` has one or more properties that that value is not undefined. + */ +function hasDefinedProperty(obj) { + if (typeof obj === "object" && obj !== null) { + for (const key in obj) { + if (typeof obj[key] !== "undefined") { + return true; + } + } + } + return false; +} + +/** + * Create rulesMeta object. + * @param {Map} rules a map of rules from which to generate the object. + * @returns {Object} metadata for all enabled rules. + */ +function createRulesMeta(rules) { + return Array.from(rules).reduce((retVal, [id, rule]) => { + retVal[id] = rule.meta; + return retVal; + }, {}); +} + +/** @type {WeakMap} */ +const usedDeprecatedRulesCache = new WeakMap(); + +/** + * Create used deprecated rule list. + * @param {CLIEngine} cliEngine The CLIEngine instance. + * @param {string} maybeFilePath The absolute path to a lint target file or `""`. + * @returns {DeprecatedRuleInfo[]} The used deprecated rule list. + */ +function getOrFindUsedDeprecatedRules(cliEngine, maybeFilePath) { + const { + configArrayFactory, + options: { cwd } + } = getCLIEngineInternalSlots(cliEngine); + const filePath = path__default['default'].isAbsolute(maybeFilePath) + ? maybeFilePath + : path__default['default'].join(cwd, "__placeholder__.js"); + const configArray = configArrayFactory.getConfigArrayForFile(filePath); + const config = configArray.extractConfig(filePath); + + // Most files use the same config, so cache it. + if (!usedDeprecatedRulesCache.has(config)) { + const pluginRules = configArray.pluginRules; + const retv = []; + + for (const [ruleId, ruleConf] of Object.entries(config.rules)) { + if (getRuleSeverity(ruleConf) === 0) { + continue; + } + const rule = pluginRules.get(ruleId) || rules$2.get(ruleId); + const meta = rule && rule.meta; + + if (meta && meta.deprecated) { + retv.push({ ruleId, replacedBy: meta.replacedBy || [] }); + } + } + + usedDeprecatedRulesCache.set(config, Object.freeze(retv)); + } + + return usedDeprecatedRulesCache.get(config); +} + +/** + * Processes the linting results generated by a CLIEngine linting report to + * match the ESLint class's API. + * @param {CLIEngine} cliEngine The CLIEngine instance. + * @param {CLIEngineLintReport} report The CLIEngine linting report to process. + * @returns {LintResult[]} The processed linting results. + */ +function processCLIEngineLintReport(cliEngine, { results }) { + const descriptor = { + configurable: true, + enumerable: true, + get() { + return getOrFindUsedDeprecatedRules(cliEngine, this.filePath); + } + }; + + for (const result of results) { + Object.defineProperty(result, "usedDeprecatedRules", descriptor); + } + + return results; +} + +/** + * An Array.prototype.sort() compatible compare function to order results by their file path. + * @param {LintResult} a The first lint result. + * @param {LintResult} b The second lint result. + * @returns {number} An integer representing the order in which the two results should occur. + */ +function compareResultsByFilePath(a, b) { + if (a.filePath < b.filePath) { + return -1; + } + + if (a.filePath > b.filePath) { + return 1; + } + + return 0; +} + +class ESLint$1 { + + /** + * Creates a new instance of the main ESLint API. + * @param {ESLintOptions} options The options for this instance. + */ + constructor(options = {}) { + const processedOptions = processOptions(options); + const cliEngine = new CLIEngine(processedOptions); + const { + additionalPluginPool, + configArrayFactory, + lastConfigArrays + } = getCLIEngineInternalSlots(cliEngine); + let updated = false; + + /* + * Address `plugins` to add plugin implementations. + * Operate the `additionalPluginPool` internal slot directly to avoid + * using `addPlugin(id, plugin)` method that resets cache everytime. + */ + if (options.plugins) { + for (const [id, plugin] of Object.entries(options.plugins)) { + additionalPluginPool.set(id, plugin); + updated = true; + } + } + + /* + * Address `overrideConfig` to set override config. + * Operate the `configArrayFactory` internal slot directly because this + * functionality doesn't exist as the public API of CLIEngine. + */ + if (hasDefinedProperty(options.overrideConfig)) { + configArrayFactory.setOverrideConfig(options.overrideConfig); + updated = true; + } + + // Update caches. + if (updated) { + configArrayFactory.clearCache(); + lastConfigArrays[0] = configArrayFactory.getConfigArrayForFile(); + } + + // Initialize private properties. + privateMembersMap.set(this, { + cliEngine, + options: processedOptions + }); + } + + /** + * The version text. + * @type {string} + */ + static get version() { + return version; + } + + /** + * Outputs fixes from the given results to files. + * @param {LintResult[]} results The lint results. + * @returns {Promise} Returns a promise that is used to track side effects. + */ + static async outputFixes(results) { + if (!Array.isArray(results)) { + throw new Error("'results' must be an array"); + } + + await Promise.all( + results + .filter(result => { + if (typeof result !== "object" || result === null) { + throw new Error("'results' must include only objects"); + } + return ( + typeof result.output === "string" && + path__default['default'].isAbsolute(result.filePath) + ); + }) + .map(r => writeFile(r.filePath, r.output)) + ); + } + + /** + * Returns results that only contains errors. + * @param {LintResult[]} results The results to filter. + * @returns {LintResult[]} The filtered results. + */ + static getErrorResults(results) { + return CLIEngine.getErrorResults(results); + } + + /** + * Executes the current configuration on an array of file and directory names. + * @param {string[]} patterns An array of file and directory names. + * @returns {Promise} The results of linting the file patterns given. + */ + async lintFiles(patterns) { + if (!isNonEmptyString(patterns) && !isArrayOfNonEmptyString(patterns)) { + throw new Error("'patterns' must be a non-empty string or an array of non-empty strings"); + } + const { cliEngine } = privateMembersMap.get(this); + + return processCLIEngineLintReport( + cliEngine, + cliEngine.executeOnFiles(patterns) + ); + } + + /** + * Executes the current configuration on text. + * @param {string} code A string of JavaScript code to lint. + * @param {Object} [options] The options. + * @param {string} [options.filePath] The path to the file of the source code. + * @param {boolean} [options.warnIgnored] When set to true, warn if given filePath is an ignored path. + * @returns {Promise} The results of linting the string of code given. + */ + async lintText(code, options = {}) { + if (typeof code !== "string") { + throw new Error("'code' must be a string"); + } + if (typeof options !== "object") { + throw new Error("'options' must be an object, null, or undefined"); + } + const { + filePath, + warnIgnored = false, + ...unknownOptions + } = options || {}; + + for (const key of Object.keys(unknownOptions)) { + throw new Error(`'options' must not include the unknown option '${key}'`); + } + if (filePath !== void 0 && !isNonEmptyString(filePath)) { + throw new Error("'options.filePath' must be a non-empty string or undefined"); + } + if (typeof warnIgnored !== "boolean") { + throw new Error("'options.warnIgnored' must be a boolean or undefined"); + } + + const { cliEngine } = privateMembersMap.get(this); + + return processCLIEngineLintReport( + cliEngine, + cliEngine.executeOnText(code, filePath, warnIgnored) + ); + } + + /** + * Returns the formatter representing the given formatter name. + * @param {string} [name] The name of the formatter to load. + * The following values are allowed: + * - `undefined` ... Load `stylish` builtin formatter. + * - A builtin formatter name ... Load the builtin formatter. + * - A thirdparty formatter name: + * - `foo` → `eslint-formatter-foo` + * - `@foo` → `@foo/eslint-formatter` + * - `@foo/bar` → `@foo/eslint-formatter-bar` + * - A file path ... Load the file. + * @returns {Promise} A promise resolving to the formatter object. + * This promise will be rejected if the given formatter was not found or not + * a function. + */ + async loadFormatter(name = "stylish") { + if (typeof name !== "string") { + throw new Error("'name' must be a string"); + } + + const { cliEngine } = privateMembersMap.get(this); + const formatter = cliEngine.getFormatter(name); + + if (typeof formatter !== "function") { + throw new Error(`Formatter must be a function, but got a ${typeof formatter}.`); + } + + return { + + /** + * The main formatter method. + * @param {LintResults[]} results The lint results to format. + * @returns {string} The formatted lint results. + */ + format(results) { + let rulesMeta = null; + + results.sort(compareResultsByFilePath); + + return formatter(results, { + get rulesMeta() { + if (!rulesMeta) { + rulesMeta = createRulesMeta(cliEngine.getRules()); + } + + return rulesMeta; + } + }); + } + }; + } + + /** + * Returns a configuration object for the given file based on the CLI options. + * This is the same logic used by the ESLint CLI executable to determine + * configuration for each file it processes. + * @param {string} filePath The path of the file to retrieve a config object for. + * @returns {Promise} A configuration object for the file. + */ + async calculateConfigForFile(filePath) { + if (!isNonEmptyString(filePath)) { + throw new Error("'filePath' must be a non-empty string"); + } + const { cliEngine } = privateMembersMap.get(this); + + return cliEngine.getConfigForFile(filePath); + } + + /** + * Checks if a given path is ignored by ESLint. + * @param {string} filePath The path of the file to check. + * @returns {Promise} Whether or not the given path is ignored. + */ + async isPathIgnored(filePath) { + if (!isNonEmptyString(filePath)) { + throw new Error("'filePath' must be a non-empty string"); + } + const { cliEngine } = privateMembersMap.get(this); + + return cliEngine.isPathIgnored(filePath); + } +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +var eslint$1 = { + ESLint: ESLint$1, + + /** + * Get the private class members of a given ESLint instance for tests. + * @param {ESLint} instance The ESLint instance to get. + * @returns {ESLintPrivateMembers} The instance's private class members. + */ + getESLintPrivateMembers(instance) { + return privateMembersMap.get(instance); + } +}; + +const { ESLint } = eslint$1; + +var eslint = { + ESLint +}; + +/* + * STOP!!! DO NOT MODIFY. + * + * This file is part of the ongoing work to move the eslintrc-style config + * system into the @eslint/eslintrc package. This file needs to remain + * unchanged in order for this work to proceed. + * + * If you think you need to change this file, please contact @nzakas first. + * + * Thanks in advance for your cooperation. + */ + +const baseConfigProperties = { + $schema: { type: "string" }, + env: { type: "object" }, + extends: { $ref: "#/definitions/stringOrStrings" }, + globals: { type: "object" }, + overrides: { + type: "array", + items: { $ref: "#/definitions/overrideConfig" }, + additionalItems: false + }, + parser: { type: ["string", "null"] }, + parserOptions: { type: "object" }, + plugins: { type: "array" }, + processor: { type: "string" }, + rules: { type: "object" }, + settings: { type: "object" }, + noInlineConfig: { type: "boolean" }, + reportUnusedDisableDirectives: { type: "boolean" }, + + ecmaFeatures: { type: "object" } // deprecated; logs a warning when used +}; + +const configSchema = { + definitions: { + stringOrStrings: { + oneOf: [ + { type: "string" }, + { + type: "array", + items: { type: "string" }, + additionalItems: false + } + ] + }, + stringOrStringsRequired: { + oneOf: [ + { type: "string" }, + { + type: "array", + items: { type: "string" }, + additionalItems: false, + minItems: 1 + } + ] + }, + + // Config at top-level. + objectConfig: { + type: "object", + properties: { + root: { type: "boolean" }, + ignorePatterns: { $ref: "#/definitions/stringOrStrings" }, + ...baseConfigProperties + }, + additionalProperties: false + }, + + // Config in `overrides`. + overrideConfig: { + type: "object", + properties: { + excludedFiles: { $ref: "#/definitions/stringOrStrings" }, + files: { $ref: "#/definitions/stringOrStringsRequired" }, + ...baseConfigProperties + }, + required: ["files"], + additionalProperties: false + } + }, + + $ref: "#/definitions/objectConfig" +}; + +var configSchema_1 = configSchema; + +/** + * @fileoverview Provide the function that emits deprecation warnings. + * @author Toru Nagashima + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + + +//------------------------------------------------------------------------------ +// Private +//------------------------------------------------------------------------------ + +// Definitions for deprecation warnings. +const deprecationWarningMessages = { + ESLINT_LEGACY_ECMAFEATURES: + "The 'ecmaFeatures' config file property is deprecated and has no effect.", + ESLINT_PERSONAL_CONFIG_LOAD: + "'~/.eslintrc.*' config files have been deprecated. " + + "Please use a config file per project or the '--config' option.", + ESLINT_PERSONAL_CONFIG_SUPPRESS: + "'~/.eslintrc.*' config files have been deprecated. " + + "Please remove it or add 'root:true' to the config files in your " + + "projects in order to avoid loading '~/.eslintrc.*' accidentally." +}; + +/** + * Emits a deprecation warning containing a given filepath. A new deprecation warning is emitted + * for each unique file path, but repeated invocations with the same file path have no effect. + * No warnings are emitted if the `--no-deprecation` or `--no-warnings` Node runtime flags are active. + * @param {string} source The name of the configuration source to report the warning for. + * @param {string} errorCode The warning message to show. + * @returns {void} + */ +const emitDeprecationWarning$1 = lodash__default['default'].memoize((source, errorCode) => { + const rel = path__default['default'].relative(process.cwd(), source); + const message = deprecationWarningMessages[errorCode]; + + process.emitWarning( + `${message} (found in "${rel}")`, + "DeprecationWarning", + errorCode + ); +}, (...args) => JSON.stringify(args)); + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +var deprecationWarnings = { + emitDeprecationWarning: emitDeprecationWarning$1 +}; + +/** + * @fileoverview The instance of Ajv validator. + * @author Evgeny Poberezkin + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + + + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +var ajv$2 = (additionalOptions = {}) => { + const ajv = new Ajv__default['default']({ + meta: false, + useDefaults: true, + validateSchema: false, + missingRefs: "ignore", + verbose: true, + schemaId: "auto", + ...additionalOptions + }); + + ajv.addMetaSchema(metaSchema); + // eslint-disable-next-line no-underscore-dangle + ajv._opts.defaultMeta = metaSchema.id; + + return ajv; +}; + +/* + * STOP!!! DO NOT MODIFY. + * + * This file is part of the ongoing work to move the eslintrc-style config + * system into the @eslint/eslintrc package. This file needs to remain + * unchanged in order for this work to proceed. + * + * If you think you need to change this file, please contact @nzakas first. + * + * Thanks in advance for your cooperation. + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const + { emitDeprecationWarning } = deprecationWarnings; + +const ajv$1 = ajv$2(); +const ruleValidators = new WeakMap(); +const noop = Function.prototype; + +//------------------------------------------------------------------------------ +// Private +//------------------------------------------------------------------------------ +let validateSchema; +const severityMap = { + error: 2, + warn: 1, + off: 0 +}; + +/** + * Gets a complete options schema for a rule. + * @param {{create: Function, schema: (Array|null)}} rule A new-style rule object + * @returns {Object} JSON Schema for the rule's options. + */ +function getRuleOptionsSchema$1(rule) { + if (!rule) { + return null; + } + + const schema = rule.schema || rule.meta && rule.meta.schema; + + // Given a tuple of schemas, insert warning level at the beginning + if (Array.isArray(schema)) { + if (schema.length) { + return { + type: "array", + items: schema, + minItems: 0, + maxItems: schema.length + }; + } + return { + type: "array", + minItems: 0, + maxItems: 0 + }; + + } + + // Given a full schema, leave it alone + return schema || null; +} + +/** + * Validates a rule's severity and returns the severity value. Throws an error if the severity is invalid. + * @param {options} options The given options for the rule. + * @returns {number|string} The rule's severity value + */ +function validateRuleSeverity(options) { + const severity = Array.isArray(options) ? options[0] : options; + const normSeverity = typeof severity === "string" ? severityMap[severity.toLowerCase()] : severity; + + if (normSeverity === 0 || normSeverity === 1 || normSeverity === 2) { + return normSeverity; + } + + throw new Error(`\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '${util__default['default'].inspect(severity).replace(/'/gu, "\"").replace(/\n/gu, "")}').\n`); + +} + +/** + * Validates the non-severity options passed to a rule, based on its schema. + * @param {{create: Function}} rule The rule to validate + * @param {Array} localOptions The options for the rule, excluding severity + * @returns {void} + */ +function validateRuleSchema(rule, localOptions) { + if (!ruleValidators.has(rule)) { + const schema = getRuleOptionsSchema$1(rule); + + if (schema) { + ruleValidators.set(rule, ajv$1.compile(schema)); + } + } + + const validateRule = ruleValidators.get(rule); + + if (validateRule) { + validateRule(localOptions); + if (validateRule.errors) { + throw new Error(validateRule.errors.map( + error => `\tValue ${JSON.stringify(error.data)} ${error.message}.\n` + ).join("")); + } + } +} + +/** + * Validates a rule's options against its schema. + * @param {{create: Function}|null} rule The rule that the config is being validated for + * @param {string} ruleId The rule's unique name. + * @param {Array|number} options The given options for the rule. + * @param {string|null} source The name of the configuration source to report in any errors. If null or undefined, + * no source is prepended to the message. + * @returns {void} + */ +function validateRuleOptions(rule, ruleId, options, source = null) { + try { + const severity = validateRuleSeverity(options); + + if (severity !== 0) { + validateRuleSchema(rule, Array.isArray(options) ? options.slice(1) : []); + } + } catch (err) { + const enhancedMessage = `Configuration for rule "${ruleId}" is invalid:\n${err.message}`; + + if (typeof source === "string") { + throw new Error(`${source}:\n\t${enhancedMessage}`); + } else { + throw new Error(enhancedMessage); + } + } +} + +/** + * Validates an environment object + * @param {Object} environment The environment config object to validate. + * @param {string} source The name of the configuration source to report in any errors. + * @param {function(envId:string): Object} [getAdditionalEnv] A map from strings to loaded environments. + * @returns {void} + */ +function validateEnvironment( + environment, + source, + getAdditionalEnv = noop +) { + + // not having an environment is ok + if (!environment) { + return; + } + + Object.keys(environment).forEach(id => { + const env = getAdditionalEnv(id) || environments.get(id) || null; + + if (!env) { + const message = `${source}:\n\tEnvironment key "${id}" is unknown\n`; + + throw new Error(message); + } + }); +} + +/** + * Validates a rules config object + * @param {Object} rulesConfig The rules config object to validate. + * @param {string} source The name of the configuration source to report in any errors. + * @param {function(ruleId:string): Object} getAdditionalRule A map from strings to loaded rules + * @returns {void} + */ +function validateRules( + rulesConfig, + source, + getAdditionalRule = noop +) { + if (!rulesConfig) { + return; + } + + Object.keys(rulesConfig).forEach(id => { + const rule = getAdditionalRule(id) || rules$2.get(id) || null; + + validateRuleOptions(rule, id, rulesConfig[id], source); + }); +} + +/** + * Validates a `globals` section of a config file + * @param {Object} globalsConfig The `globals` section + * @param {string|null} source The name of the configuration source to report in the event of an error. + * @returns {void} + */ +function validateGlobals(globalsConfig, source = null) { + if (!globalsConfig) { + return; + } + + Object.entries(globalsConfig) + .forEach(([configuredGlobal, configuredValue]) => { + try { + configOps.normalizeConfigGlobal(configuredValue); + } catch (err) { + throw new Error(`ESLint configuration of global '${configuredGlobal}' in ${source} is invalid:\n${err.message}`); + } + }); +} + +/** + * Validate `processor` configuration. + * @param {string|undefined} processorName The processor name. + * @param {string} source The name of config file. + * @param {function(id:string): Processor} getProcessor The getter of defined processors. + * @returns {void} + */ +function validateProcessor(processorName, source, getProcessor) { + if (processorName && !getProcessor(processorName)) { + throw new Error(`ESLint configuration of processor in '${source}' is invalid: '${processorName}' was not found.`); + } +} + +/** + * Formats an array of schema validation errors. + * @param {Array} errors An array of error messages to format. + * @returns {string} Formatted error message + */ +function formatErrors(errors) { + return errors.map(error => { + if (error.keyword === "additionalProperties") { + const formattedPropertyPath = error.dataPath.length ? `${error.dataPath.slice(1)}.${error.params.additionalProperty}` : error.params.additionalProperty; + + return `Unexpected top-level property "${formattedPropertyPath}"`; + } + if (error.keyword === "type") { + const formattedField = error.dataPath.slice(1); + const formattedExpectedType = Array.isArray(error.schema) ? error.schema.join("/") : error.schema; + const formattedValue = JSON.stringify(error.data); + + return `Property "${formattedField}" is the wrong type (expected ${formattedExpectedType} but got \`${formattedValue}\`)`; + } + + const field = error.dataPath[0] === "." ? error.dataPath.slice(1) : error.dataPath; + + return `"${field}" ${error.message}. Value: ${JSON.stringify(error.data)}`; + }).map(message => `\t- ${message}.\n`).join(""); +} + +/** + * Validates the top level properties of the config object. + * @param {Object} config The config object to validate. + * @param {string} source The name of the configuration source to report in any errors. + * @returns {void} + */ +function validateConfigSchema(config, source = null) { + validateSchema = validateSchema || ajv$1.compile(configSchema_1); + + if (!validateSchema(config)) { + throw new Error(`ESLint configuration in ${source} is invalid:\n${formatErrors(validateSchema.errors)}`); + } + + if (Object.hasOwnProperty.call(config, "ecmaFeatures")) { + emitDeprecationWarning(source, "ESLINT_LEGACY_ECMAFEATURES"); + } +} + +/** + * Validates an entire config object. + * @param {Object} config The config object to validate. + * @param {string} source The name of the configuration source to report in any errors. + * @param {function(ruleId:string): Object} [getAdditionalRule] A map from strings to loaded rules. + * @param {function(envId:string): Object} [getAdditionalEnv] A map from strings to loaded envs. + * @returns {void} + */ +function validate$1(config, source, getAdditionalRule, getAdditionalEnv) { + validateConfigSchema(config, source); + validateRules(config.rules, source, getAdditionalRule); + validateEnvironment(config.env, source, getAdditionalEnv); + validateGlobals(config.globals, source); + + for (const override of config.overrides || []) { + validateRules(override.rules, source, getAdditionalRule); + validateEnvironment(override.env, source, getAdditionalEnv); + validateGlobals(config.globals, source); + } +} + +const validated = new WeakSet(); + +/** + * Validate config array object. + * @param {ConfigArray} configArray The config array to validate. + * @returns {void} + */ +function validateConfigArray(configArray) { + const getPluginEnv = Map.prototype.get.bind(configArray.pluginEnvironments); + const getPluginProcessor = Map.prototype.get.bind(configArray.pluginProcessors); + const getPluginRule = Map.prototype.get.bind(configArray.pluginRules); + + // Validate. + for (const element of configArray) { + if (validated.has(element)) { + continue; + } + validated.add(element); + + validateEnvironment(element.env, element.name, getPluginEnv); + validateGlobals(element.globals, element.name); + validateProcessor(element.processor, element.name, getPluginProcessor); + validateRules(element.rules, element.name, getPluginRule); + } +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +var configValidator = { + getRuleOptionsSchema: getRuleOptionsSchema$1, + validate: validate$1, + validateConfigArray, + validateConfigSchema, + validateRuleOptions +}; + +/** + * @fileoverview Mocha test wrapper + * @author Ilya Volodin + */ + +/* global describe, it */ + +/* + * This is a wrapper around mocha to allow for DRY unittests for eslint + * Format: + * RuleTester.run("{ruleName}", { + * valid: [ + * "{code}", + * { code: "{code}", options: {options}, globals: {globals}, parser: "{parser}", settings: {settings} } + * ], + * invalid: [ + * { code: "{code}", errors: {numErrors} }, + * { code: "{code}", errors: ["{errorMessage}"] }, + * { code: "{code}", options: {options}, globals: {globals}, parser: "{parser}", settings: {settings}, errors: [{ message: "{errorMessage}", type: "{errorNodeType}"}] } + * ] + * }); + * + * Variables: + * {code} - String that represents the code to be tested + * {options} - Arguments that are passed to the configurable rules. + * {globals} - An object representing a list of variables that are + * registered as globals + * {parser} - String representing the parser to use + * {settings} - An object representing global settings for all rules + * {numErrors} - If failing case doesn't need to check error message, + * this integer will specify how many errors should be + * received + * {errorMessage} - Message that is returned by the rule on failure + * {errorNodeType} - AST node type that is returned by they rule as + * a cause of the failure. + */ + +//------------------------------------------------------------------------------ +// Requirements +//------------------------------------------------------------------------------ + +const + { getRuleOptionsSchema, validate } = configValidator, + { Linter, SourceCodeFixer, interpolate } = linter; + +const ajv = ajv$2({ strictDefaults: true }); + +const espreePath = require.resolve("espree"); + +//------------------------------------------------------------------------------ +// Typedefs +//------------------------------------------------------------------------------ + +/** @typedef {import("../shared/types").Parser} Parser */ + +/** + * A test case that is expected to pass lint. + * @typedef {Object} ValidTestCase + * @property {string} code Code for the test case. + * @property {any[]} [options] Options for the test case. + * @property {{ [name: string]: any }} [settings] Settings for the test case. + * @property {string} [filename] The fake filename for the test case. Useful for rules that make assertion about filenames. + * @property {string} [parser] The absolute path for the parser. + * @property {{ [name: string]: any }} [parserOptions] Options for the parser. + * @property {{ [name: string]: "readonly" | "writable" | "off" }} [globals] The additional global variables. + * @property {{ [name: string]: boolean }} [env] Environments for the test case. + */ + +/** + * A test case that is expected to fail lint. + * @typedef {Object} InvalidTestCase + * @property {string} code Code for the test case. + * @property {number | Array} errors Expected errors. + * @property {string | null} [output] The expected code after autofixes are applied. If set to `null`, the test runner will assert that no autofix is suggested. + * @property {any[]} [options] Options for the test case. + * @property {{ [name: string]: any }} [settings] Settings for the test case. + * @property {string} [filename] The fake filename for the test case. Useful for rules that make assertion about filenames. + * @property {string} [parser] The absolute path for the parser. + * @property {{ [name: string]: any }} [parserOptions] Options for the parser. + * @property {{ [name: string]: "readonly" | "writable" | "off" }} [globals] The additional global variables. + * @property {{ [name: string]: boolean }} [env] Environments for the test case. + */ + +/** + * A description of a reported error used in a rule tester test. + * @typedef {Object} TestCaseError + * @property {string | RegExp} [message] Message. + * @property {string} [messageId] Message ID. + * @property {string} [type] The type of the reported AST node. + * @property {{ [name: string]: string }} [data] The data used to fill the message template. + * @property {number} [line] The 1-based line number of the reported start location. + * @property {number} [column] The 1-based column number of the reported start location. + * @property {number} [endLine] The 1-based line number of the reported end location. + * @property {number} [endColumn] The 1-based column number of the reported end location. + */ + +//------------------------------------------------------------------------------ +// Private Members +//------------------------------------------------------------------------------ + +/* + * testerDefaultConfig must not be modified as it allows to reset the tester to + * the initial default configuration + */ +const testerDefaultConfig = { rules: {} }; +let defaultConfig = { rules: {} }; + +/* + * List every parameters possible on a test case that are not related to eslint + * configuration + */ +const RuleTesterParameters = [ + "code", + "filename", + "options", + "errors", + "output" +]; + +/* + * All allowed property names in error objects. + */ +const errorObjectParameters = new Set([ + "message", + "messageId", + "data", + "type", + "line", + "column", + "endLine", + "endColumn", + "suggestions" +]); +const friendlyErrorObjectParameterList = `[${[...errorObjectParameters].map(key => `'${key}'`).join(", ")}]`; + +/* + * All allowed property names in suggestion objects. + */ +const suggestionObjectParameters = new Set([ + "desc", + "messageId", + "data", + "output" +]); +const friendlySuggestionObjectParameterList = `[${[...suggestionObjectParameters].map(key => `'${key}'`).join(", ")}]`; + +const hasOwnProperty = Function.call.bind(Object.hasOwnProperty); + +/** + * Clones a given value deeply. + * Note: This ignores `parent` property. + * @param {any} x A value to clone. + * @returns {any} A cloned value. + */ +function cloneDeeplyExcludesParent(x) { + if (typeof x === "object" && x !== null) { + if (Array.isArray(x)) { + return x.map(cloneDeeplyExcludesParent); + } + + const retv = {}; + + for (const key in x) { + if (key !== "parent" && hasOwnProperty(x, key)) { + retv[key] = cloneDeeplyExcludesParent(x[key]); + } + } + + return retv; + } + + return x; +} + +/** + * Freezes a given value deeply. + * @param {any} x A value to freeze. + * @returns {void} + */ +function freezeDeeply(x) { + if (typeof x === "object" && x !== null) { + if (Array.isArray(x)) { + x.forEach(freezeDeeply); + } else { + for (const key in x) { + if (key !== "parent" && hasOwnProperty(x, key)) { + freezeDeeply(x[key]); + } + } + } + Object.freeze(x); + } +} + +/** + * Replace control characters by `\u00xx` form. + * @param {string} text The text to sanitize. + * @returns {string} The sanitized text. + */ +function sanitize(text) { + return text.replace( + /[\u0000-\u0009\u000b-\u001a]/gu, // eslint-disable-line no-control-regex + c => `\\u${c.codePointAt(0).toString(16).padStart(4, "0")}` + ); +} + +/** + * Define `start`/`end` properties as throwing error. + * @param {string} objName Object name used for error messages. + * @param {ASTNode} node The node to define. + * @returns {void} + */ +function defineStartEndAsError(objName, node) { + Object.defineProperties(node, { + start: { + get() { + throw new Error(`Use ${objName}.range[0] instead of ${objName}.start`); + }, + configurable: true, + enumerable: false + }, + end: { + get() { + throw new Error(`Use ${objName}.range[1] instead of ${objName}.end`); + }, + configurable: true, + enumerable: false + } + }); +} + +/** + * Define `start`/`end` properties of all nodes of the given AST as throwing error. + * @param {ASTNode} ast The root node to errorize `start`/`end` properties. + * @param {Object} [visitorKeys] Visitor keys to be used for traversing the given ast. + * @returns {void} + */ +function defineStartEndAsErrorInTree(ast, visitorKeys) { + traverser.traverse(ast, { visitorKeys, enter: defineStartEndAsError.bind(null, "node") }); + ast.tokens.forEach(defineStartEndAsError.bind(null, "token")); + ast.comments.forEach(defineStartEndAsError.bind(null, "token")); +} + +/** + * Wraps the given parser in order to intercept and modify return values from the `parse` and `parseForESLint` methods, for test purposes. + * In particular, to modify ast nodes, tokens and comments to throw on access to their `start` and `end` properties. + * @param {Parser} parser Parser object. + * @returns {Parser} Wrapped parser object. + */ +function wrapParser(parser) { + if (typeof parser.parseForESLint === "function") { + return { + parseForESLint(...args) { + const ret = parser.parseForESLint(...args); + + defineStartEndAsErrorInTree(ret.ast, ret.visitorKeys); + return ret; + } + }; + } + return { + parse(...args) { + const ast = parser.parse(...args); + + defineStartEndAsErrorInTree(ast); + return ast; + } + }; +} + +//------------------------------------------------------------------------------ +// Public Interface +//------------------------------------------------------------------------------ + +// default separators for testing +const DESCRIBE = Symbol("describe"); +const IT = Symbol("it"); + +/** + * This is `it` default handler if `it` don't exist. + * @this {Mocha} + * @param {string} text The description of the test case. + * @param {Function} method The logic of the test case. + * @returns {any} Returned value of `method`. + */ +function itDefaultHandler(text, method) { + try { + return method.call(this); + } catch (err) { + if (err instanceof assert__default['default'].AssertionError) { + err.message += ` (${util__default['default'].inspect(err.actual)} ${err.operator} ${util__default['default'].inspect(err.expected)})`; + } + throw err; + } +} + +/** + * This is `describe` default handler if `describe` don't exist. + * @this {Mocha} + * @param {string} text The description of the test case. + * @param {Function} method The logic of the test case. + * @returns {any} Returned value of `method`. + */ +function describeDefaultHandler(text, method) { + return method.call(this); +} + +class RuleTester { + + /** + * Creates a new instance of RuleTester. + * @param {Object} [testerConfig] Optional, extra configuration for the tester + */ + constructor(testerConfig) { + + /** + * The configuration to use for this tester. Combination of the tester + * configuration and the default configuration. + * @type {Object} + */ + this.testerConfig = lodash__default['default'].merge( + + // we have to clone because merge uses the first argument for recipient + lodash__default['default'].cloneDeep(defaultConfig), + testerConfig, + { rules: { "rule-tester/validate-ast": "error" } } + ); + + /** + * Rule definitions to define before tests. + * @type {Object} + */ + this.rules = {}; + this.linter = new Linter(); + } + + /** + * Set the configuration to use for all future tests + * @param {Object} config the configuration to use. + * @returns {void} + */ + static setDefaultConfig(config) { + if (typeof config !== "object") { + throw new TypeError("RuleTester.setDefaultConfig: config must be an object"); + } + defaultConfig = config; + + // Make sure the rules object exists since it is assumed to exist later + defaultConfig.rules = defaultConfig.rules || {}; + } + + /** + * Get the current configuration used for all tests + * @returns {Object} the current configuration + */ + static getDefaultConfig() { + return defaultConfig; + } + + /** + * Reset the configuration to the initial configuration of the tester removing + * any changes made until now. + * @returns {void} + */ + static resetDefaultConfig() { + defaultConfig = lodash__default['default'].cloneDeep(testerDefaultConfig); + } + + + /* + * If people use `mocha test.js --watch` command, `describe` and `it` function + * instances are different for each execution. So `describe` and `it` should get fresh instance + * always. + */ + static get describe() { + return ( + this[DESCRIBE] || + (typeof describe === "function" ? describe : describeDefaultHandler) + ); + } + + static set describe(value) { + this[DESCRIBE] = value; + } + + static get it() { + return ( + this[IT] || + (typeof it === "function" ? it : itDefaultHandler) + ); + } + + static set it(value) { + this[IT] = value; + } + + /** + * Define a rule for one particular run of tests. + * @param {string} name The name of the rule to define. + * @param {Function} rule The rule definition. + * @returns {void} + */ + defineRule(name, rule) { + this.rules[name] = rule; + } + + /** + * Adds a new rule test to execute. + * @param {string} ruleName The name of the rule to run. + * @param {Function} rule The rule to test. + * @param {{ + * valid: (ValidTestCase | string)[], + * invalid: InvalidTestCase[] + * }} test The collection of tests to run. + * @returns {void} + */ + run(ruleName, rule, test) { + + const testerConfig = this.testerConfig, + requiredScenarios = ["valid", "invalid"], + scenarioErrors = [], + linter = this.linter; + + if (!test || typeof test !== "object") { + throw new TypeError(`Test Scenarios for rule ${ruleName} : Could not find test scenario object`); + } + + requiredScenarios.forEach(scenarioType => { + if (!test[scenarioType]) { + scenarioErrors.push(`Could not find any ${scenarioType} test scenarios`); + } + }); + + if (scenarioErrors.length > 0) { + throw new Error([ + `Test Scenarios for rule ${ruleName} is invalid:` + ].concat(scenarioErrors).join("\n")); + } + + + linter.defineRule(ruleName, Object.assign({}, rule, { + + // Create a wrapper rule that freezes the `context` properties. + create(context) { + freezeDeeply(context.options); + freezeDeeply(context.settings); + freezeDeeply(context.parserOptions); + + return (typeof rule === "function" ? rule : rule.create)(context); + } + })); + + linter.defineRules(this.rules); + + /** + * Run the rule for the given item + * @param {string|Object} item Item to run the rule against + * @returns {Object} Eslint run result + * @private + */ + function runRuleForItem(item) { + let config = lodash__default['default'].cloneDeep(testerConfig), + code, filename, output, beforeAST, afterAST; + + if (typeof item === "string") { + code = item; + } else { + code = item.code; + + /* + * Assumes everything on the item is a config except for the + * parameters used by this tester + */ + const itemConfig = lodash__default['default'].omit(item, RuleTesterParameters); + + /* + * Create the config object from the tester config and this item + * specific configurations. + */ + config = lodash__default['default'].merge( + config, + itemConfig + ); + } + + if (item.filename) { + filename = item.filename; + } + + if (hasOwnProperty(item, "options")) { + assert__default['default'](Array.isArray(item.options), "options must be an array"); + config.rules[ruleName] = [1].concat(item.options); + } else { + config.rules[ruleName] = 1; + } + + const schema = getRuleOptionsSchema(rule); + + /* + * Setup AST getters. + * The goal is to check whether or not AST was modified when + * running the rule under test. + */ + linter.defineRule("rule-tester/validate-ast", () => ({ + Program(node) { + beforeAST = cloneDeeplyExcludesParent(node); + }, + "Program:exit"(node) { + afterAST = node; + } + })); + + if (typeof config.parser === "string") { + assert__default['default'](path__default['default'].isAbsolute(config.parser), "Parsers provided as strings to RuleTester must be absolute paths"); + } else { + config.parser = espreePath; + } + + linter.defineParser(config.parser, wrapParser(commonjsRequire(config.parser))); + + if (schema) { + ajv.validateSchema(schema); + + if (ajv.errors) { + const errors = ajv.errors.map(error => { + const field = error.dataPath[0] === "." ? error.dataPath.slice(1) : error.dataPath; + + return `\t${field}: ${error.message}`; + }).join("\n"); + + throw new Error([`Schema for rule ${ruleName} is invalid:`, errors]); + } + + /* + * `ajv.validateSchema` checks for errors in the structure of the schema (by comparing the schema against a "meta-schema"), + * and it reports those errors individually. However, there are other types of schema errors that only occur when compiling + * the schema (e.g. using invalid defaults in a schema), and only one of these errors can be reported at a time. As a result, + * the schema is compiled here separately from checking for `validateSchema` errors. + */ + try { + ajv.compile(schema); + } catch (err) { + throw new Error(`Schema for rule ${ruleName} is invalid: ${err.message}`); + } + } + + validate(config, "rule-tester", id => (id === ruleName ? rule : null)); + + // Verify the code. + const messages = linter.verify(code, config, filename); + const fatalErrorMessage = messages.find(m => m.fatal); + + assert__default['default'](!fatalErrorMessage, `A fatal parsing error occurred: ${fatalErrorMessage && fatalErrorMessage.message}`); + + // Verify if autofix makes a syntax error or not. + if (messages.some(m => m.fix)) { + output = SourceCodeFixer.applyFixes(code, messages).output; + const errorMessageInFix = linter.verify(output, config, filename).find(m => m.fatal); + + assert__default['default'](!errorMessageInFix, [ + "A fatal parsing error occurred in autofix.", + `Error: ${errorMessageInFix && errorMessageInFix.message}`, + "Autofix output:", + output + ].join("\n")); + } else { + output = code; + } + + return { + messages, + output, + beforeAST, + afterAST: cloneDeeplyExcludesParent(afterAST) + }; + } + + /** + * Check if the AST was changed + * @param {ASTNode} beforeAST AST node before running + * @param {ASTNode} afterAST AST node after running + * @returns {void} + * @private + */ + function assertASTDidntChange(beforeAST, afterAST) { + if (!lodash__default['default'].isEqual(beforeAST, afterAST)) { + assert__default['default'].fail("Rule should not modify AST."); + } + } + + /** + * Check if the template is valid or not + * all valid cases go through this + * @param {string|Object} item Item to run the rule against + * @returns {void} + * @private + */ + function testValidTemplate(item) { + const result = runRuleForItem(item); + const messages = result.messages; + + assert__default['default'].strictEqual(messages.length, 0, util__default['default'].format("Should have no errors but had %d: %s", + messages.length, util__default['default'].inspect(messages))); + + assertASTDidntChange(result.beforeAST, result.afterAST); + } + + /** + * Asserts that the message matches its expected value. If the expected + * value is a regular expression, it is checked against the actual + * value. + * @param {string} actual Actual value + * @param {string|RegExp} expected Expected value + * @returns {void} + * @private + */ + function assertMessageMatches(actual, expected) { + if (expected instanceof RegExp) { + + // assert.js doesn't have a built-in RegExp match function + assert__default['default'].ok( + expected.test(actual), + `Expected '${actual}' to match ${expected}` + ); + } else { + assert__default['default'].strictEqual(actual, expected); + } + } + + /** + * Check if the template is invalid or not + * all invalid cases go through this. + * @param {string|Object} item Item to run the rule against + * @returns {void} + * @private + */ + function testInvalidTemplate(item) { + assert__default['default'].ok(item.errors || item.errors === 0, + `Did not specify errors for an invalid test of ${ruleName}`); + + if (Array.isArray(item.errors) && item.errors.length === 0) { + assert__default['default'].fail("Invalid cases must have at least one error"); + } + + const ruleHasMetaMessages = hasOwnProperty(rule, "meta") && hasOwnProperty(rule.meta, "messages"); + const friendlyIDList = ruleHasMetaMessages ? `[${Object.keys(rule.meta.messages).map(key => `'${key}'`).join(", ")}]` : null; + + const result = runRuleForItem(item); + const messages = result.messages; + + if (typeof item.errors === "number") { + + if (item.errors === 0) { + assert__default['default'].fail("Invalid cases must have 'error' value greater than 0"); + } + + assert__default['default'].strictEqual(messages.length, item.errors, util__default['default'].format("Should have %d error%s but had %d: %s", + item.errors, item.errors === 1 ? "" : "s", messages.length, util__default['default'].inspect(messages))); + } else { + assert__default['default'].strictEqual( + messages.length, item.errors.length, + util__default['default'].format( + "Should have %d error%s but had %d: %s", + item.errors.length, item.errors.length === 1 ? "" : "s", messages.length, util__default['default'].inspect(messages) + ) + ); + + const hasMessageOfThisRule = messages.some(m => m.ruleId === ruleName); + + for (let i = 0, l = item.errors.length; i < l; i++) { + const error = item.errors[i]; + const message = messages[i]; + + assert__default['default'](hasMessageOfThisRule, "Error rule name should be the same as the name of the rule being tested"); + + if (typeof error === "string" || error instanceof RegExp) { + + // Just an error message. + assertMessageMatches(message.message, error); + } else if (typeof error === "object" && error !== null) { + + /* + * Error object. + * This may have a message, messageId, data, node type, line, and/or + * column. + */ + + Object.keys(error).forEach(propertyName => { + assert__default['default'].ok( + errorObjectParameters.has(propertyName), + `Invalid error property name '${propertyName}'. Expected one of ${friendlyErrorObjectParameterList}.` + ); + }); + + if (hasOwnProperty(error, "message")) { + assert__default['default'].ok(!hasOwnProperty(error, "messageId"), "Error should not specify both 'message' and a 'messageId'."); + assert__default['default'].ok(!hasOwnProperty(error, "data"), "Error should not specify both 'data' and 'message'."); + assertMessageMatches(message.message, error.message); + } else if (hasOwnProperty(error, "messageId")) { + assert__default['default'].ok( + ruleHasMetaMessages, + "Error can not use 'messageId' if rule under test doesn't define 'meta.messages'." + ); + if (!hasOwnProperty(rule.meta.messages, error.messageId)) { + assert__default['default'](false, `Invalid messageId '${error.messageId}'. Expected one of ${friendlyIDList}.`); + } + assert__default['default'].strictEqual( + message.messageId, + error.messageId, + `messageId '${message.messageId}' does not match expected messageId '${error.messageId}'.` + ); + if (hasOwnProperty(error, "data")) { + + /* + * if data was provided, then directly compare the returned message to a synthetic + * interpolated message using the same message ID and data provided in the test. + * See https://github.com/eslint/eslint/issues/9890 for context. + */ + const unformattedOriginalMessage = rule.meta.messages[error.messageId]; + const rehydratedMessage = interpolate(unformattedOriginalMessage, error.data); + + assert__default['default'].strictEqual( + message.message, + rehydratedMessage, + `Hydrated message "${rehydratedMessage}" does not match "${message.message}"` + ); + } + } + + assert__default['default'].ok( + hasOwnProperty(error, "data") ? hasOwnProperty(error, "messageId") : true, + "Error must specify 'messageId' if 'data' is used." + ); + + if (error.type) { + assert__default['default'].strictEqual(message.nodeType, error.type, `Error type should be ${error.type}, found ${message.nodeType}`); + } + + if (hasOwnProperty(error, "line")) { + assert__default['default'].strictEqual(message.line, error.line, `Error line should be ${error.line}`); + } + + if (hasOwnProperty(error, "column")) { + assert__default['default'].strictEqual(message.column, error.column, `Error column should be ${error.column}`); + } + + if (hasOwnProperty(error, "endLine")) { + assert__default['default'].strictEqual(message.endLine, error.endLine, `Error endLine should be ${error.endLine}`); + } + + if (hasOwnProperty(error, "endColumn")) { + assert__default['default'].strictEqual(message.endColumn, error.endColumn, `Error endColumn should be ${error.endColumn}`); + } + + if (hasOwnProperty(error, "suggestions")) { + + // Support asserting there are no suggestions + if (!error.suggestions || (Array.isArray(error.suggestions) && error.suggestions.length === 0)) { + if (Array.isArray(message.suggestions) && message.suggestions.length > 0) { + assert__default['default'].fail(`Error should have no suggestions on error with message: "${message.message}"`); + } + } else { + assert__default['default'].strictEqual(Array.isArray(message.suggestions), true, `Error should have an array of suggestions. Instead received "${message.suggestions}" on error with message: "${message.message}"`); + assert__default['default'].strictEqual(message.suggestions.length, error.suggestions.length, `Error should have ${error.suggestions.length} suggestions. Instead found ${message.suggestions.length} suggestions`); + + error.suggestions.forEach((expectedSuggestion, index) => { + assert__default['default'].ok( + typeof expectedSuggestion === "object" && expectedSuggestion !== null, + "Test suggestion in 'suggestions' array must be an object." + ); + Object.keys(expectedSuggestion).forEach(propertyName => { + assert__default['default'].ok( + suggestionObjectParameters.has(propertyName), + `Invalid suggestion property name '${propertyName}'. Expected one of ${friendlySuggestionObjectParameterList}.` + ); + }); + + const actualSuggestion = message.suggestions[index]; + const suggestionPrefix = `Error Suggestion at index ${index} :`; + + if (hasOwnProperty(expectedSuggestion, "desc")) { + assert__default['default'].ok( + !hasOwnProperty(expectedSuggestion, "data"), + `${suggestionPrefix} Test should not specify both 'desc' and 'data'.` + ); + assert__default['default'].strictEqual( + actualSuggestion.desc, + expectedSuggestion.desc, + `${suggestionPrefix} desc should be "${expectedSuggestion.desc}" but got "${actualSuggestion.desc}" instead.` + ); + } + + if (hasOwnProperty(expectedSuggestion, "messageId")) { + assert__default['default'].ok( + ruleHasMetaMessages, + `${suggestionPrefix} Test can not use 'messageId' if rule under test doesn't define 'meta.messages'.` + ); + assert__default['default'].ok( + hasOwnProperty(rule.meta.messages, expectedSuggestion.messageId), + `${suggestionPrefix} Test has invalid messageId '${expectedSuggestion.messageId}', the rule under test allows only one of ${friendlyIDList}.` + ); + assert__default['default'].strictEqual( + actualSuggestion.messageId, + expectedSuggestion.messageId, + `${suggestionPrefix} messageId should be '${expectedSuggestion.messageId}' but got '${actualSuggestion.messageId}' instead.` + ); + if (hasOwnProperty(expectedSuggestion, "data")) { + const unformattedMetaMessage = rule.meta.messages[expectedSuggestion.messageId]; + const rehydratedDesc = interpolate(unformattedMetaMessage, expectedSuggestion.data); + + assert__default['default'].strictEqual( + actualSuggestion.desc, + rehydratedDesc, + `${suggestionPrefix} Hydrated test desc "${rehydratedDesc}" does not match received desc "${actualSuggestion.desc}".` + ); + } + } else { + assert__default['default'].ok( + !hasOwnProperty(expectedSuggestion, "data"), + `${suggestionPrefix} Test must specify 'messageId' if 'data' is used.` + ); + } + + if (hasOwnProperty(expectedSuggestion, "output")) { + const codeWithAppliedSuggestion = SourceCodeFixer.applyFixes(item.code, [actualSuggestion]).output; + + assert__default['default'].strictEqual(codeWithAppliedSuggestion, expectedSuggestion.output, `Expected the applied suggestion fix to match the test suggestion output for suggestion at index: ${index} on error with message: "${message.message}"`); + } + }); + } + } + } else { + + // Message was an unexpected type + assert__default['default'].fail(`Error should be a string, object, or RegExp, but found (${util__default['default'].inspect(message)})`); + } + } + } + + if (hasOwnProperty(item, "output")) { + if (item.output === null) { + assert__default['default'].strictEqual( + result.output, + item.code, + "Expected no autofixes to be suggested" + ); + } else { + assert__default['default'].strictEqual(result.output, item.output, "Output is incorrect."); + } + } else { + assert__default['default'].strictEqual( + result.output, + item.code, + "The rule fixed the code. Please add 'output' property." + ); + } + + // Rules that produce fixes must have `meta.fixable` property. + if (result.output !== item.code) { + assert__default['default'].ok( + hasOwnProperty(rule, "meta"), + "Fixable rules should export a `meta.fixable` property." + ); + + // Linter throws if a rule that produced a fix has `meta` but doesn't have `meta.fixable`. + } + + assertASTDidntChange(result.beforeAST, result.afterAST); + } + + /* + * This creates a mocha test suite and pipes all supplied info through + * one of the templates above. + */ + RuleTester.describe(ruleName, () => { + RuleTester.describe("valid", () => { + test.valid.forEach(valid => { + RuleTester.it(sanitize(typeof valid === "object" ? valid.code : valid), () => { + testValidTemplate(valid); + }); + }); + }); + + RuleTester.describe("invalid", () => { + test.invalid.forEach(invalid => { + RuleTester.it(sanitize(invalid.code), () => { + testInvalidTemplate(invalid); + }); + }); + }); + }); + } +} + +RuleTester[DESCRIBE] = RuleTester[IT] = null; + +var ruleTester$1 = RuleTester; + +var ruleTester = { + RuleTester: ruleTester$1 +}; + +/** + * @fileoverview Expose out ESLint and CLI to require. + * @author Ian Christian Myers + */ + +var api = createCommonjsModule(function (module) { + +const { CLIEngine } = cliEngine; +const { ESLint } = eslint; +const { Linter } = linter; +const { RuleTester } = ruleTester; +const { SourceCode } = sourceCode; + +module.exports = { + Linter, + CLIEngine, + ESLint, + RuleTester, + SourceCode +}; + +// DOTO: remove deprecated API. +let deprecatedLinterInstance = null; + +Object.defineProperty(module.exports, "linter", { + enumerable: false, + get() { + if (!deprecatedLinterInstance) { + deprecatedLinterInstance = new Linter(); + } + + return deprecatedLinterInstance; + } +}); +}); + +var checkExamples = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + + + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// Todo: When peerDeps bump to ESLint 7, see about replacing `CLIEngine` +// with non-deprecated `ESLint` class: +// https://github.com/eslint/eslint/blob/master/docs/user-guide/migrating-to-7.0.0.md#-the-cliengine-class-has-been-deprecated +const zeroBasedLineIndexAdjust = -1; +const likelyNestedJSDocIndentSpace = 1; +const preTagSpaceLength = 1; // If a space is present, we should ignore it + +const firstLinePrefixLength = preTagSpaceLength; +const hasCaptionRegex = /^\s*([\s\S]*?)<\/caption>/u; + +const escapeStringRegexp = str => { + return str.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&'); +}; + +const countChars = (str, ch) => { + return (str.match(new RegExp(escapeStringRegexp(ch), 'gu')) || []).length; +}; + +const defaultMdRules = { + // "always" newline rule at end unlikely in sample code + 'eol-last': 0, + // Wouldn't generally expect example paths to resolve relative to JS file + 'import/no-unresolved': 0, + // Snippets likely too short to always include import/export info + 'import/unambiguous': 0, + 'jsdoc/require-file-overview': 0, + // The end of a multiline comment would end the comment the example is in. + 'jsdoc/require-jsdoc': 0, + // Unlikely to have inadvertent debugging within examples + 'no-console': 0, + // Often wish to start `@example` code after newline; also may use + // empty lines for spacing + 'no-multiple-empty-lines': 0, + // Many variables in examples will be `undefined` + 'no-undef': 0, + // Common to define variables for clarity without always using them + 'no-unused-vars': 0, + // See import/no-unresolved + 'node/no-missing-import': 0, + 'node/no-missing-require': 0, + // Can generally look nicer to pad a little even if code imposes more stringency + 'padded-blocks': 0 +}; +const defaultExpressionRules = { ...defaultMdRules, + 'no-new': 'off', + 'no-unused-expressions': 'off', + quotes: ['error', 'double'], + semi: ['error', 'never'], + strict: 'off' +}; + +const getLinesCols = text => { + const matchLines = countChars(text, '\n'); + const colDelta = matchLines ? text.slice(text.lastIndexOf('\n') + 1).length : text.length; + return [matchLines, colDelta]; +}; + +var _default = (0, _iterateJsdoc.default)(({ + report, + utils, + context, + globalState +}) => { + if (!globalState.has('checkExamples-matchingFileName')) { + globalState.set('checkExamples-matchingFileName', new Map()); + } + + const matchingFileNameMap = globalState.get('checkExamples-matchingFileName'); + const options = context.options[0] || {}; + let { + exampleCodeRegex = null, + rejectExampleCodeRegex = null + } = options; + const { + checkDefaults = false, + checkParams = false, + checkProperties = false, + noDefaultExampleRules = false, + checkEslintrc = true, + matchingFileName = null, + matchingFileNameDefaults = null, + matchingFileNameParams = null, + matchingFileNameProperties = null, + paddedIndent = 0, + baseConfig = {}, + configFile, + allowInlineConfig = true, + reportUnusedDisableDirectives = true, + captionRequired = false + } = options; // Make this configurable? + + const rulePaths = []; + const mdRules = noDefaultExampleRules ? undefined : defaultMdRules; + const expressionRules = noDefaultExampleRules ? undefined : defaultExpressionRules; + + if (exampleCodeRegex) { + exampleCodeRegex = utils.getRegexFromString(exampleCodeRegex); + } + + if (rejectExampleCodeRegex) { + rejectExampleCodeRegex = utils.getRegexFromString(rejectExampleCodeRegex); + } + + const checkSource = ({ + filename, + defaultFileName, + rules = expressionRules, + lines = 0, + cols = 0, + skipInit, + source, + targetTagName, + sources = [], + tag = { + line: 0 + } + }) => { + if (!skipInit) { + sources.push({ + nonJSPrefacingCols: cols, + nonJSPrefacingLines: lines, + string: source + }); + } // Todo: Make fixable + // Todo: Fix whitespace indent + + + const checkRules = function ({ + nonJSPrefacingCols, + nonJSPrefacingLines, + string + }) { + const cliConfig = { + allowInlineConfig, + baseConfig, + configFile, + reportUnusedDisableDirectives, + rulePaths, + rules, + useEslintrc: checkEslintrc + }; + const cliConfigStr = JSON.stringify(cliConfig); + const src = paddedIndent ? string.replace(new RegExp(`(^|\n) {${paddedIndent}}(?!$)`, 'gu'), '\n') : string; // Programmatic ESLint API: https://eslint.org/docs/developer-guide/nodejs-api + + const fileNameMapKey = filename ? 'a' + cliConfigStr + filename : 'b' + cliConfigStr + defaultFileName; + const file = filename || defaultFileName; + let cliFile; + + if (matchingFileNameMap.has(fileNameMapKey)) { + cliFile = matchingFileNameMap.get(fileNameMapKey); + } else { + const cli = new api.CLIEngine(cliConfig); + let config; + + if (filename || checkEslintrc) { + config = cli.getConfigForFile(file); + } // We need a new instance to ensure that the rules that may only + // be available to `file` (if it has its own `.eslintrc`), + // will be defined. + + + cliFile = new api.CLIEngine({ + allowInlineConfig, + baseConfig: { ...baseConfig, + ...config + }, + configFile, + reportUnusedDisableDirectives, + rulePaths, + rules, + useEslintrc: false + }); + matchingFileNameMap.set(fileNameMapKey, cliFile); + } + + const { + results: [{ + messages + }] + } = cliFile.executeOnText(src); + + if (!('line' in tag)) { + tag.line = tag.source[0].number; + } // NOTE: `tag.line` can be 0 if of form `/** @tag ... */` + + + const codeStartLine = tag.line + nonJSPrefacingLines; + const codeStartCol = likelyNestedJSDocIndentSpace; + messages.forEach(({ + message, + line, + column, + severity, + ruleId + }) => { + const startLine = codeStartLine + line + zeroBasedLineIndexAdjust; + const startCol = codeStartCol + ( // This might not work for line 0, but line 0 is unlikely for examples + line <= 1 ? nonJSPrefacingCols + firstLinePrefixLength : preTagSpaceLength) + column; + report('@' + targetTagName + ' ' + (severity === 2 ? 'error' : 'warning') + (ruleId ? ' (' + ruleId + ')' : '') + ': ' + message, null, { + column: startCol, + line: startLine + }); + }); + }; + + sources.forEach(checkRules); + }; + /** + * + * @param {string} filename + * @param {string} [ext="md/*.js"] Since `eslint-plugin-markdown` v2, and + * ESLint 7, this is the default which other JS-fenced rules will used. + * Formerly "md" was the default. + * @returns {{defaultFileName: string, fileName: string}} + */ + + + const getFilenameInfo = (filename, ext = 'md/*.js') => { + let defaultFileName; + + if (!filename) { + const jsFileName = context.getFilename(); + + if (typeof jsFileName === 'string' && jsFileName.includes('.')) { + defaultFileName = jsFileName.replace(/\..*?$/, `.${ext}`); + } else { + defaultFileName = `dummy.${ext}`; + } + } + + return { + defaultFileName, + filename + }; + }; + + if (checkDefaults) { + const filenameInfo = getFilenameInfo(matchingFileNameDefaults, 'jsdoc-defaults'); + utils.forEachPreferredTag('default', (tag, targetTagName) => { + if (!tag.description.trim()) { + return; + } + + checkSource({ + source: `(${tag.description})`, + targetTagName, + ...filenameInfo + }); + }); + } + + if (checkParams) { + const filenameInfo = getFilenameInfo(matchingFileNameParams, 'jsdoc-params'); + utils.forEachPreferredTag('param', (tag, targetTagName) => { + if (!tag.default || !tag.default.trim()) { + return; + } + + checkSource({ + source: `(${tag.default})`, + targetTagName, + ...filenameInfo + }); + }); + } + + if (checkProperties) { + const filenameInfo = getFilenameInfo(matchingFileNameProperties, 'jsdoc-properties'); + utils.forEachPreferredTag('property', (tag, targetTagName) => { + if (!tag.default || !tag.default.trim()) { + return; + } + + checkSource({ + source: `(${tag.default})`, + targetTagName, + ...filenameInfo + }); + }); + } + + const tagName = utils.getPreferredTagName({ + tagName: 'example' + }); + + if (!utils.hasTag(tagName)) { + return; + } + + const matchingFilenameInfo = getFilenameInfo(matchingFileName); + utils.forEachPreferredTag('example', (tag, targetTagName) => { + let source = tag.source[0].tokens.postTag.slice(1) + tag.description; + const match = source.match(hasCaptionRegex); + + if (captionRequired && (!match || !match[1].trim())) { + report('Caption is expected for examples.', null, tag); + } + + source = source.replace(hasCaptionRegex, ''); + const [lines, cols] = match ? getLinesCols(match[0]) : [0, 0]; + + if (exampleCodeRegex && !exampleCodeRegex.test(source) || rejectExampleCodeRegex && rejectExampleCodeRegex.test(source)) { + return; + } + + const sources = []; + let skipInit = false; + + if (exampleCodeRegex) { + let nonJSPrefacingCols = 0; + let nonJSPrefacingLines = 0; + let startingIndex = 0; + let lastStringCount = 0; + let exampleCode; + exampleCodeRegex.lastIndex = 0; + + while ((exampleCode = exampleCodeRegex.exec(source)) !== null) { + const { + index, + 0: n0, + 1: n1 + } = exampleCode; // Count anything preceding user regex match (can affect line numbering) + + const preMatch = source.slice(startingIndex, index); + const [preMatchLines, colDelta] = getLinesCols(preMatch); + let nonJSPreface; + let nonJSPrefaceLineCount; + + if (n1) { + const idx = n0.indexOf(n1); + nonJSPreface = n0.slice(0, idx); + nonJSPrefaceLineCount = countChars(nonJSPreface, '\n'); + } else { + nonJSPreface = ''; + nonJSPrefaceLineCount = 0; + } + + nonJSPrefacingLines += lastStringCount + preMatchLines + nonJSPrefaceLineCount; // Ignore `preMatch` delta if newlines here + + if (nonJSPrefaceLineCount) { + const charsInLastLine = nonJSPreface.slice(nonJSPreface.lastIndexOf('\n') + 1).length; + nonJSPrefacingCols += charsInLastLine; + } else { + nonJSPrefacingCols += colDelta + nonJSPreface.length; + } + + const string = n1 || n0; + sources.push({ + nonJSPrefacingCols, + nonJSPrefacingLines, + string + }); + startingIndex = exampleCodeRegex.lastIndex; + lastStringCount = countChars(string, '\n'); + + if (!exampleCodeRegex.global) { + break; + } + } + + skipInit = true; + } + + checkSource({ + cols, + lines, + rules: mdRules, + skipInit, + source, + sources, + tag, + targetTagName, + ...matchingFilenameInfo + }); + }); +}, { + iterateAllJsdocs: true, + meta: { + docs: { + description: 'Ensures that (JavaScript) examples within JSDoc adhere to ESLint rules.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-examples' + }, + schema: [{ + additionalProperties: false, + properties: { + allowInlineConfig: { + default: true, + type: 'boolean' + }, + baseConfig: { + type: 'object' + }, + captionRequired: { + default: false, + type: 'boolean' + }, + checkDefaults: { + default: false, + type: 'boolean' + }, + checkEslintrc: { + default: true, + type: 'boolean' + }, + checkParams: { + default: false, + type: 'boolean' + }, + checkProperties: { + default: false, + type: 'boolean' + }, + configFile: { + type: 'string' + }, + exampleCodeRegex: { + type: 'string' + }, + matchingFileName: { + type: 'string' + }, + matchingFileNameDefaults: { + type: 'string' + }, + matchingFileNameParams: { + type: 'string' + }, + matchingFileNameProperties: { + type: 'string' + }, + noDefaultExampleRules: { + default: false, + type: 'boolean' + }, + paddedIndent: { + default: 0, + type: 'integer' + }, + rejectExampleCodeRegex: { + type: 'string' + }, + reportUnusedDisableDirectives: { + default: true, + type: 'boolean' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=checkExamples.js.map +}); + +var checkIndentation = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const maskExcludedContent = (str, excludeTags) => { + const regContent = new RegExp(`([ \\t]+\\*)[ \\t]@(?:${excludeTags.join('|')})(?=[ \\n])([\\w|\\W]*?\\n)(?=[ \\t]*\\*(?:[ \\t]*@|\\/))`, 'gu'); + return str.replace(regContent, (_match, margin, code) => { + return new Array(code.match(/\n/gu).length + 1).join(margin + '\n'); + }); +}; + +const maskCodeBlocks = str => { + const regContent = /([ \t]+\*)[ \t]```[^\n]*?([\w|\W]*?\n)(?=[ \t]*\*(?:[ \t]*(?:```|@)|\/))/gu; + return str.replace(regContent, (_match, margin, code) => { + return new Array(code.match(/\n/gu).length + 1).join(margin + '\n'); + }); +}; + +var _default = (0, _iterateJsdoc.default)(({ + sourceCode, + jsdocNode, + report, + context +}) => { + const options = context.options[0] || {}; + const { + excludeTags = ['example'] + } = options; + const reg = new RegExp(/^(?:\/?\**|[ \t]*)\*[ \t]{2}/gmu); + const textWithoutCodeBlocks = maskCodeBlocks(sourceCode.getText(jsdocNode)); + const text = excludeTags.length ? maskExcludedContent(textWithoutCodeBlocks, excludeTags) : textWithoutCodeBlocks; + + if (reg.test(text)) { + const lineBreaks = text.slice(0, reg.lastIndex).match(/\n/gu) || []; + report('There must be no indentation.', null, { + line: lineBreaks.length + }); + } +}, { + iterateAllJsdocs: true, + meta: { + docs: { + description: 'Reports invalid padding inside JSDoc blocks.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-indentation' + }, + schema: [{ + additionalProperties: false, + properties: { + excludeTags: { + items: { + pattern: '^\\S+$', + type: 'string' + }, + type: 'array' + } + }, + type: 'object' + }], + type: 'layout' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=checkIndentation.js.map +}); + +var checkLineAlignment = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + + + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const { + flow: commentFlow, + align: commentAlign, + indent: commentIndent +} = lib.transforms; + +const checkNotAlignedPerTag = (utils, tag) => { + /* + start + + delimiter + + postDelimiter + + tag + + postTag + + type + + postType + + name + + postName + + description + + end + */ + let spacerProps; + let contentProps; + const mightHaveNamepath = utils.tagMightHaveNamepath(tag.tag); + + if (mightHaveNamepath) { + spacerProps = ['postDelimiter', 'postTag', 'postType', 'postName']; + contentProps = ['tag', 'type', 'name', 'description']; + } else { + spacerProps = ['postDelimiter', 'postTag', 'postType']; + contentProps = ['tag', 'type', 'description']; + } + + const { + tokens + } = tag.source[0]; + + const followedBySpace = (idx, callbck) => { + const nextIndex = idx + 1; + return spacerProps.slice(nextIndex).some((spacerProp, innerIdx) => { + const contentProp = contentProps[nextIndex + innerIdx]; + const spacePropVal = tokens[spacerProp]; + const ret = spacePropVal; + + if (callbck) { + callbck(!ret, contentProp); + } + + return ret; + }); + }; // If checking alignment on multiple lines, need to check other `source` + // items + // Go through `post*` spacing properties and exit to indicate problem if + // extra spacing detected + + + const ok = !spacerProps.some((spacerProp, idx) => { + const contentProp = contentProps[idx]; + const contentPropVal = tokens[contentProp]; + const spacerPropVal = tokens[spacerProp]; // There will be extra alignment if... + // 1. There is extra whitespace within a single spacer segment OR + + return spacerPropVal.length > 1 || // 2. There is a (single) space, no immediate content, and yet another + // space is found subsequently (not separated by intervening content) + spacerPropVal && !contentPropVal && followedBySpace(idx); + }); + + if (ok) { + return; + } + + const fix = () => { + spacerProps.forEach((spacerProp, idx) => { + const contentProp = contentProps[idx]; + const contentPropVal = tokens[contentProp]; + + if (contentPropVal) { + tokens[spacerProp] = ' '; + followedBySpace(idx, (hasSpace, contentPrp) => { + if (hasSpace) { + tokens[contentPrp] = ''; + } + }); + } else { + tokens[spacerProp] = ''; + } + }); + utils.setTag(tag, tokens); + }; + + utils.reportJSDoc('Expected JSDoc block lines to not be aligned.', tag, fix, true); +}; + +const checkAlignment = ({ + indent, + jsdoc, + jsdocNode, + report, + utils +}) => { + const transform = commentFlow(commentAlign(), commentIndent(indent.length)); + const transformedJsdoc = transform(jsdoc); + const comment = '/*' + jsdocNode.value + '*/'; + const formatted = utils.stringify(transformedJsdoc).trimStart(); + + if (comment !== formatted) { + report('Expected JSDoc block lines to be aligned.', fixer => { + return fixer.replaceText(jsdocNode, formatted); + }); + } +}; + +var _default = (0, _iterateJsdoc.default)(({ + indent, + jsdoc, + jsdocNode, + report, + context, + utils +}) => { + const { + tags: applicableTags = ['param', 'arg', 'argument', 'property', 'prop', 'returns', 'return'] + } = context.options[1] || {}; + + if (context.options[0] === 'always') { + // Skip if it contains only a single line. + if (!jsdocNode.value.includes('\n')) { + return; + } + + checkAlignment({ + indent, + jsdoc, + jsdocNode, + report, + utils + }); + return; + } + + const foundTags = utils.getPresentTags(applicableTags); + foundTags.forEach(tag => { + checkNotAlignedPerTag(utils, tag); + }); +}, { + iterateAllJsdocs: true, + meta: { + docs: { + description: 'Reports invalid alignment of JSDoc block lines.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-line-alignment' + }, + fixable: 'whitespace', + schema: [{ + enum: ['always', 'never'], + type: 'string' + }, { + additionalProperties: false, + properties: { + tags: { + items: { + type: 'string' + }, + type: 'array' + } + }, + type: 'object' + }], + type: 'layout' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=checkLineAlignment.js.map +}); + +var checkParamNames = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const validateParameterNames = (targetTagName, allowExtraTrailingParamDocs, checkDestructured, checkRestProperty, checkTypesRegex, disableExtraPropertyReporting, enableFixer, functionParameterNames, jsdoc, _jsdocNode, utils, report) => { + const paramTags = Object.entries(jsdoc.tags).filter(([, tag]) => { + return tag.tag === targetTagName; + }); + const paramTagsNonNested = paramTags.filter(([, tag]) => { + return !tag.name.includes('.'); + }); + let dotted = 0; + return paramTags.some(([, tag], index) => { + let tagsIndex; + const dupeTagInfo = paramTags.find(([tgsIndex, tg], idx) => { + tagsIndex = tgsIndex; + return tg.name === tag.name && idx !== index; + }); + + if (dupeTagInfo) { + utils.reportJSDoc(`Duplicate @${targetTagName} "${tag.name}"`, dupeTagInfo[1], enableFixer ? () => { + utils.removeTag(tagsIndex); + } : null); + return true; + } + + if (tag.name.includes('.')) { + dotted++; + return false; + } + + const functionParameterName = functionParameterNames[index - dotted]; + + if (!functionParameterName) { + if (allowExtraTrailingParamDocs) { + return false; + } + + report(`@${targetTagName} "${tag.name}" does not match an existing function parameter.`, null, tag); + return true; + } + + if (Array.isArray(functionParameterName)) { + if (!checkDestructured) { + return false; + } + + if (tag.type && tag.type.search(checkTypesRegex) === -1) { + return false; + } + + const [parameterName, { + names: properties, + hasPropertyRest, + rests, + annotationParamName + }] = functionParameterName; + + if (annotationParamName !== undefined) { + const name = tag.name.trim(); + + if (name !== annotationParamName) { + report(`@${targetTagName} "${name}" does not match parameter name "${annotationParamName}"`, null, tag); + } + } + + const tagName = parameterName === undefined ? tag.name.trim() : parameterName; + const expectedNames = properties.map(name => { + return `${tagName}.${name}`; + }); + const actualNames = paramTags.map(([, paramTag]) => { + return paramTag.name.trim(); + }); + const actualTypes = paramTags.map(([, paramTag]) => { + return paramTag.type; + }); + const missingProperties = []; + const notCheckingNames = []; + expectedNames.forEach((name, idx) => { + if (notCheckingNames.some(notCheckingName => { + return name.startsWith(notCheckingName); + })) { + return; + } + + const actualNameIdx = actualNames.findIndex(actualName => { + return utils.comparePaths(name)(actualName); + }); + + if (actualNameIdx === -1) { + if (!checkRestProperty && rests[idx]) { + return; + } + + missingProperties.push(name); + } else if (actualTypes[actualNameIdx].search(checkTypesRegex) === -1 && actualTypes[actualNameIdx] !== '') { + notCheckingNames.push(name); + } + }); + const hasMissing = missingProperties.length; + + if (hasMissing) { + missingProperties.forEach(missingProperty => { + report(`Missing @${targetTagName} "${missingProperty}"`, null, tag); + }); + } + + if (!hasPropertyRest || checkRestProperty) { + const extraProperties = []; + actualNames.forEach((name, idx) => { + const match = name.startsWith(tag.name.trim() + '.'); + + if (match && !expectedNames.some(utils.comparePaths(name)) && !utils.comparePaths(name)(tag.name) && (!disableExtraPropertyReporting || properties.some(prop => { + return prop.split('.').length >= name.split('.').length - 1; + }))) { + extraProperties.push([name, paramTags[idx][1]]); + } + }); + + if (extraProperties.length) { + extraProperties.forEach(([extraProperty, tg]) => { + report(`@${targetTagName} "${extraProperty}" does not exist on ${tag.name}`, null, tg); + }); + return true; + } + } + + return hasMissing; + } + + let funcParamName; + + if (typeof functionParameterName === 'object') { + const { + name + } = functionParameterName; + funcParamName = name; + } else { + funcParamName = functionParameterName; + } + + if (funcParamName !== tag.name.trim()) { + // Todo: Improve for array or object child items + const actualNames = paramTagsNonNested.map(([, { + name + }]) => { + return name.trim(); + }); + const expectedNames = functionParameterNames.map((item, idx) => { + var _item$; + + if (item !== null && item !== void 0 && (_item$ = item[1]) !== null && _item$ !== void 0 && _item$.names) { + return actualNames[idx]; + } + + return item; + }).join(', '); + report(`Expected @${targetTagName} names to be "${expectedNames}". Got "${actualNames.join(', ')}".`, null, tag); + return true; + } + + return false; + }); +}; + +const validateParameterNamesDeep = (targetTagName, _allowExtraTrailingParamDocs, jsdocParameterNames, jsdoc, report) => { + let lastRealParameter; + return jsdocParameterNames.some(({ + name: jsdocParameterName, + idx + }) => { + const isPropertyPath = jsdocParameterName.includes('.'); + + if (isPropertyPath) { + if (!lastRealParameter) { + report(`@${targetTagName} path declaration ("${jsdocParameterName}") appears before any real parameter.`, null, jsdoc.tags[idx]); + return true; + } + + let pathRootNodeName = jsdocParameterName.slice(0, jsdocParameterName.indexOf('.')); + + if (pathRootNodeName.endsWith('[]')) { + pathRootNodeName = pathRootNodeName.slice(0, -2); + } + + if (pathRootNodeName !== lastRealParameter) { + report(`@${targetTagName} path declaration ("${jsdocParameterName}") root node name ("${pathRootNodeName}") ` + `does not match previous real parameter name ("${lastRealParameter}").`, null, jsdoc.tags[idx]); + return true; + } + } else { + lastRealParameter = jsdocParameterName; + } + + return false; + }); +}; + +var _default = (0, _iterateJsdoc.default)(({ + context, + jsdoc, + jsdocNode, + report, + utils +}) => { + const { + allowExtraTrailingParamDocs, + checkDestructured = true, + checkRestProperty = false, + checkTypesPattern = '/^(?:[oO]bject|[aA]rray|PlainObject|Generic(?:Object|Array))$/', + enableFixer = false, + useDefaultObjectProperties = false, + disableExtraPropertyReporting = false + } = context.options[0] || {}; + const checkTypesRegex = utils.getRegexFromString(checkTypesPattern); + const jsdocParameterNamesDeep = utils.getJsdocTagsDeep('param'); + + if (!jsdocParameterNamesDeep.length) { + return; + } + + const functionParameterNames = utils.getFunctionParameterNames(useDefaultObjectProperties); + const targetTagName = utils.getPreferredTagName({ + tagName: 'param' + }); + const isError = validateParameterNames(targetTagName, allowExtraTrailingParamDocs, checkDestructured, checkRestProperty, checkTypesRegex, disableExtraPropertyReporting, enableFixer, functionParameterNames, jsdoc, jsdocNode, utils, report); + + if (isError || !checkDestructured) { + return; + } + + validateParameterNamesDeep(targetTagName, allowExtraTrailingParamDocs, jsdocParameterNamesDeep, jsdoc, report); +}, { + meta: { + docs: { + description: 'Ensures that parameter names in JSDoc match those in the function declaration.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-param-names' + }, + fixable: 'code', + schema: [{ + additionalProperties: false, + properties: { + allowExtraTrailingParamDocs: { + type: 'boolean' + }, + checkDestructured: { + type: 'boolean' + }, + checkRestProperty: { + type: 'boolean' + }, + checkTypesPattern: { + type: 'string' + }, + disableExtraPropertyReporting: { + type: 'boolean' + }, + enableFixer: { + type: 'boolean' + }, + useDefaultObjectProperties: { + type: 'boolean' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=checkParamNames.js.map +}); + +var checkPropertyNames = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const validatePropertyNames = (targetTagName, enableFixer, jsdoc, jsdocNode, utils) => { + const propertyTags = Object.entries(jsdoc.tags).filter(([, tag]) => { + return tag.tag === targetTagName; + }); + return propertyTags.some(([, tag], index) => { + let tagsIndex; + const dupeTagInfo = propertyTags.find(([tgsIndex, tg], idx) => { + tagsIndex = tgsIndex; + return tg.name === tag.name && idx !== index; + }); + + if (dupeTagInfo) { + utils.reportJSDoc(`Duplicate @${targetTagName} "${tag.name}"`, dupeTagInfo[1], enableFixer ? () => { + utils.removeTag(tagsIndex); + } : null); + return true; + } + + return false; + }); +}; + +const validatePropertyNamesDeep = (targetTagName, jsdocPropertyNames, jsdoc, report) => { + let lastRealProperty; + return jsdocPropertyNames.some(({ + name: jsdocPropertyName, + idx + }) => { + const isPropertyPath = jsdocPropertyName.includes('.'); + + if (isPropertyPath) { + if (!lastRealProperty) { + report(`@${targetTagName} path declaration ("${jsdocPropertyName}") appears before any real property.`, null, jsdoc.tags[idx]); + return true; + } + + let pathRootNodeName = jsdocPropertyName.slice(0, jsdocPropertyName.indexOf('.')); + + if (pathRootNodeName.endsWith('[]')) { + pathRootNodeName = pathRootNodeName.slice(0, -2); + } + + if (pathRootNodeName !== lastRealProperty) { + report(`@${targetTagName} path declaration ("${jsdocPropertyName}") root node name ("${pathRootNodeName}") ` + `does not match previous real property name ("${lastRealProperty}").`, null, jsdoc.tags[idx]); + return true; + } + } else { + lastRealProperty = jsdocPropertyName; + } + + return false; + }); +}; + +var _default = (0, _iterateJsdoc.default)(({ + context, + jsdoc, + jsdocNode, + report, + utils +}) => { + const { + enableFixer = false + } = context.options[0] || {}; + const jsdocPropertyNamesDeep = utils.getJsdocTagsDeep('property'); + + if (!jsdocPropertyNamesDeep.length) { + return; + } + + const targetTagName = utils.getPreferredTagName({ + tagName: 'property' + }); + const isError = validatePropertyNames(targetTagName, enableFixer, jsdoc, jsdocNode, utils); + + if (isError) { + return; + } + + validatePropertyNamesDeep(targetTagName, jsdocPropertyNamesDeep, jsdoc, report); +}, { + iterateAllJsdocs: true, + meta: { + docs: { + description: 'Ensures that property names in JSDoc are not duplicated on the same block and that nested properties have defined roots.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-property-names' + }, + fixable: 'code', + schema: [{ + additionalProperties: false, + properties: { + enableFixer: { + type: 'boolean' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=checkPropertyNames.js.map +}); + +var checkSyntax = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _default = (0, _iterateJsdoc.default)(({ + jsdoc, + report, + settings +}) => { + const { + mode + } = settings; // Don't check for "permissive" and "closure" + + if (mode === 'jsdoc' || mode === 'typescript') { + for (const tag of jsdoc.tags) { + if (tag.type.slice(-1) === '=') { + report('Syntax should not be Google Closure Compiler style.', null, tag); + break; + } + } + } +}, { + iterateAllJsdocs: true, + meta: { + docs: { + description: 'Reports against syntax not valid for the mode (e.g., Google Closure Compiler in non-Closure mode).', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-syntax' + }, + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=checkSyntax.js.map +}); + +var checkTagNames = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _lodash = _interopRequireDefault(lodash__default['default']); + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// https://babeljs.io/docs/en/babel-plugin-transform-react-jsx/ +const jsxTagNames = new Set(['jsx', 'jsxFrag', 'jsxImportSource', 'jsxRuntime']); + +var _default = (0, _iterateJsdoc.default)(({ + sourceCode, + jsdoc, + report, + utils, + context, + settings, + jsdocNode +}) => { + const { + definedTags = [], + jsxTags + } = context.options[0] || {}; + let definedPreferredTags = []; + const { + tagNamePreference, + structuredTags + } = settings; + const definedStructuredTags = Object.keys(structuredTags); + const definedNonPreferredTags = Object.keys(tagNamePreference); + + if (definedNonPreferredTags.length) { + definedPreferredTags = Object.values(tagNamePreference).map(preferredTag => { + if (typeof preferredTag === 'string') { + // May become an empty string but will be filtered out below + return preferredTag; + } + + if (!preferredTag) { + return undefined; + } + + if (typeof preferredTag !== 'object') { + utils.reportSettings('Invalid `settings.jsdoc.tagNamePreference`. Values must be falsy, a string, or an object.'); + } + + return preferredTag.replacement; + }).filter(preferredType => { + return preferredType; + }); + } + + jsdoc.tags.forEach(jsdocTag => { + const tagName = jsdocTag.tag; + + if (jsxTags && jsxTagNames.has(tagName)) { + return; + } + + if (utils.isValidTag(tagName, [...definedTags, ...definedPreferredTags, ...definedNonPreferredTags, ...definedStructuredTags])) { + let preferredTagName = utils.getPreferredTagName({ + allowObjectReturn: true, + defaultMessage: `Blacklisted tag found (\`@${tagName}\`)`, + tagName + }); + + if (!preferredTagName) { + return; + } + + let message; + + if (typeof preferredTagName === 'object') { + ({ + message, + replacement: preferredTagName + } = preferredTagName); + } + + if (!message) { + message = `Invalid JSDoc tag (preference). Replace "${tagName}" JSDoc tag with "${preferredTagName}".`; + } + + if (preferredTagName !== tagName) { + report(message, fixer => { + const replacement = sourceCode.getText(jsdocNode).replace(new RegExp(`@${_lodash.default.escapeRegExp(tagName)}\\b`, 'u'), `@${preferredTagName}`); + return fixer.replaceText(jsdocNode, replacement); + }, jsdocTag); + } + } else { + report(`Invalid JSDoc tag name "${tagName}".`, null, jsdocTag); + } + }); +}, { + iterateAllJsdocs: true, + meta: { + docs: { + description: 'Reports invalid block tag names.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-tag-names' + }, + fixable: 'code', + schema: [{ + additionalProperties: false, + properties: { + definedTags: { + items: { + type: 'string' + }, + type: 'array' + }, + jsxTags: { + type: 'boolean' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=checkTagNames.js.map +}); + +/** + * Syntax types for generic types. + * @enum {string} + */ +const GenericTypeSyntax = { + /** + * From TypeScript and Closure Library. + * Example: {@code Array} + */ + ANGLE_BRACKET: 'ANGLE_BRACKET', + + /** + * From JSDoc and Legacy Closure Library. + * Example: {@code Array.} + */ + ANGLE_BRACKET_WITH_DOT: 'ANGLE_BRACKET_WITH_DOT', + + /** + * From JSDoc. + * Example: {@code String[]} + */ + SQUARE_BRACKET: 'SQUARE_BRACKET', +}; + +const VariadicTypeSyntax$1 = { + /** + * From Closure Library. + * Example: {@code ...Type} + */ + PREFIX_DOTS: 'PREFIX_DOTS', + + /** + * From JSDuck. + * Example: {@code Type...} + */ + SUFFIX_DOTS: 'SUFFIX_DOTS', + + /** + * From Closure Library. + * Example: {@code ...} + */ + ONLY_DOTS: 'ONLY_DOTS', +}; + +const OptionalTypeSyntax$1 = { + PREFIX_EQUALS_SIGN: 'PREFIX_EQUALS_SIGN', + SUFFIX_EQUALS_SIGN: 'SUFFIX_EQUALS_SIGN', + SUFFIX_KEY_QUESTION_MARK: 'SUFFIX_KEY_QUESTION_MARK', +}; + +const NullableTypeSyntax = { + PREFIX_QUESTION_MARK: 'PREFIX_QUESTION_MARK', + SUFFIX_QUESTION_MARK: 'SUFFIX_QUESTION_MARK', +}; + +const NotNullableTypeSyntax = { + PREFIX_BANG: 'PREFIX_BANG', + SUFFIX_BANG: 'SUFFIX_BANG', +}; + +var SyntaxType = { + GenericTypeSyntax, + VariadicTypeSyntax: VariadicTypeSyntax$1, + OptionalTypeSyntax: OptionalTypeSyntax$1, + NullableTypeSyntax, + NotNullableTypeSyntax, +}; + +const NodeType = { + NAME: 'NAME', + MEMBER: 'MEMBER', + UNION: 'UNION', + INTERSECTION: 'INTERSECTION', + VARIADIC: 'VARIADIC', + RECORD: 'RECORD', + RECORD_ENTRY: 'RECORD_ENTRY', + TUPLE: 'TUPLE', + GENERIC: 'GENERIC', + MODULE: 'MODULE', + OPTIONAL: 'OPTIONAL', + NULLABLE: 'NULLABLE', + NOT_NULLABLE: 'NOT_NULLABLE', + FUNCTION: 'FUNCTION', + ARROW: 'ARROW', + NAMED_PARAMETER: 'NAMED_PARAMETER', + ANY: 'ANY', + UNKNOWN: 'UNKNOWN', + INNER_MEMBER: 'INNER_MEMBER', + INSTANCE_MEMBER: 'INSTANCE_MEMBER', + STRING_VALUE: 'STRING_VALUE', + NUMBER_VALUE: 'NUMBER_VALUE', + EXTERNAL: 'EXTERNAL', + FILE_PATH: 'FILE_PATH', + PARENTHESIS: 'PARENTHESIS', + TYPE_QUERY: 'TYPE_QUERY', + KEY_QUERY: 'KEY_QUERY', + IMPORT: 'IMPORT', +}; + +/** @typedef {keyof typeof NodeType} Type */ + +var NodeType_1 = /** @type {{readonly [T in Type]: T}} */ (NodeType); + +/* + * Generated by PEG.js 0.10.0. + * + * http://pegjs.org/ + */ + +function peg$subclass$3(child, parent) { + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); +} + +function peg$SyntaxError$3(message, expected, found, location) { + this.message = message; + this.expected = expected; + this.found = found; + this.location = location; + this.name = "SyntaxError"; + + if (typeof Error.captureStackTrace === "function") { + Error.captureStackTrace(this, peg$SyntaxError$3); + } +} + +peg$subclass$3(peg$SyntaxError$3, Error); + +peg$SyntaxError$3.buildMessage = function(expected, found) { + var DESCRIBE_EXPECTATION_FNS = { + literal: function(expectation) { + return "\"" + literalEscape(expectation.text) + "\""; + }, + + "class": function(expectation) { + var escapedParts = "", + i; + + for (i = 0; i < expectation.parts.length; i++) { + escapedParts += expectation.parts[i] instanceof Array + ? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1]) + : classEscape(expectation.parts[i]); + } + + return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]"; + }, + + any: function(expectation) { + return "any character"; + }, + + end: function(expectation) { + return "end of input"; + }, + + other: function(expectation) { + return expectation.description; + } + }; + + function hex(ch) { + return ch.charCodeAt(0).toString(16).toUpperCase(); + } + + function literalEscape(s) { + return s + .replace(/\\/g, '\\\\') + .replace(/"/g, '\\"') + .replace(/\0/g, '\\0') + .replace(/\t/g, '\\t') + .replace(/\n/g, '\\n') + .replace(/\r/g, '\\r') + .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); }); + } + + function classEscape(s) { + return s + .replace(/\\/g, '\\\\') + .replace(/\]/g, '\\]') + .replace(/\^/g, '\\^') + .replace(/-/g, '\\-') + .replace(/\0/g, '\\0') + .replace(/\t/g, '\\t') + .replace(/\n/g, '\\n') + .replace(/\r/g, '\\r') + .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); }); + } + + function describeExpectation(expectation) { + return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); + } + + function describeExpected(expected) { + var descriptions = new Array(expected.length), + i, j; + + for (i = 0; i < expected.length; i++) { + descriptions[i] = describeExpectation(expected[i]); + } + + descriptions.sort(); + + if (descriptions.length > 0) { + for (i = 1, j = 1; i < descriptions.length; i++) { + if (descriptions[i - 1] !== descriptions[i]) { + descriptions[j] = descriptions[i]; + j++; + } + } + descriptions.length = j; + } + + switch (descriptions.length) { + case 1: + return descriptions[0]; + + case 2: + return descriptions[0] + " or " + descriptions[1]; + + default: + return descriptions.slice(0, -1).join(", ") + + ", or " + + descriptions[descriptions.length - 1]; + } + } + + function describeFound(found) { + return found ? "\"" + literalEscape(found) + "\"" : "end of input"; + } + + return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; +}; + +function peg$parse$3(input, options) { + options = options !== void 0 ? options : {}; + + var peg$FAILED = {}, + + peg$startRuleFunctions = { TopTypeExpr: peg$parseTopTypeExpr, NamepathExpr: peg$parseNamepathExpr, BroadNamepathExpr: peg$parseBroadNamepathExpr, ExternalNameExpr: peg$parseExternalNameExpr, ModuleNameExpr: peg$parseModuleNameExpr }, + peg$startRuleFunction = peg$parseTopTypeExpr, + + peg$c0 = function(expr) { + return expr; + }, + peg$c1 = /^[ \t]/, + peg$c2 = peg$classExpectation([" ", "\t"], false, false), + peg$c3 = /^[\r]/, + peg$c4 = peg$classExpectation(["\r"], false, false), + peg$c5 = /^[\n]/, + peg$c6 = peg$classExpectation(["\n"], false, false), + peg$c7 = /^[a-zA-Z_$]/, + peg$c8 = peg$classExpectation([["a", "z"], ["A", "Z"], "_", "$"], false, false), + peg$c9 = /^[a-zA-Z0-9_$]/, + peg$c10 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$"], false, false), + peg$c11 = "event:", + peg$c12 = peg$literalExpectation("event:", false), + peg$c13 = function(rootOwner, memberPartWithOperators) { + return memberPartWithOperators.reduce(function(owner, tokens) { + const operatorType = tokens[1]; + const eventNamespace = tokens[3]; + const MemberName = tokens[5]; + const {quoteStyle, name: memberName} = MemberName; + + switch (operatorType) { + case NamepathOperatorType.MEMBER: + return { + type: NodeType.MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + case NamepathOperatorType.INSTANCE_MEMBER: + return { + type: NodeType.INSTANCE_MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + case NamepathOperatorType.INNER_MEMBER: + return { + type: NodeType.INNER_MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + /* istanbul ignore next */ + default: + throw new Error('Unexpected operator type: "' + operatorType + '"'); + } + }, rootOwner); + }, + peg$c14 = /^[a-zA-Z0-9_$\-]/, + peg$c15 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$", "-"], false, false), + peg$c16 = function(name) { + return { + type: NodeType.NAME, + name + }; + }, + peg$c17 = "'", + peg$c18 = peg$literalExpectation("'", false), + peg$c19 = /^[^\\']/, + peg$c20 = peg$classExpectation(["\\", "'"], true, false), + peg$c21 = "\\", + peg$c22 = peg$literalExpectation("\\", false), + peg$c23 = peg$anyExpectation(), + peg$c24 = function(name) { + return { + quoteStyle: 'single', + name: name.replace(/\\'/g, "'") + .replace(/\\\\/gu, '\\') + }; + }, + peg$c25 = "\"", + peg$c26 = peg$literalExpectation("\"", false), + peg$c27 = /^[^\\"]/, + peg$c28 = peg$classExpectation(["\\", "\""], true, false), + peg$c29 = function(name) { + return { + quoteStyle: 'double', + name: name.replace(/\\"/gu, '"') + .replace(/\\\\/gu, '\\') + }; + }, + peg$c30 = function(name) { + return { + quoteStyle: 'none', + name + }; + }, + peg$c31 = ".", + peg$c32 = peg$literalExpectation(".", false), + peg$c33 = function(rootOwner, memberPart) { + return memberPart.reduce(function(owner, tokens) { + return { + type: NodeType.MEMBER, + owner, + name: tokens[3] + } + }, rootOwner); + }, + peg$c34 = function() { + return NamepathOperatorType.MEMBER; + }, + peg$c35 = "~", + peg$c36 = peg$literalExpectation("~", false), + peg$c37 = function() { + return NamepathOperatorType.INNER_MEMBER; + }, + peg$c38 = "#", + peg$c39 = peg$literalExpectation("#", false), + peg$c40 = function() { + return NamepathOperatorType.INSTANCE_MEMBER; + }, + peg$c41 = "external", + peg$c42 = peg$literalExpectation("external", false), + peg$c43 = ":", + peg$c44 = peg$literalExpectation(":", false), + peg$c45 = function(external, memberPartWithOperators) { + return memberPartWithOperators.reduce(function(owner, tokens) { + const operatorType = tokens[1]; + const eventNamespace = tokens[3]; + const MemberName = tokens[5]; + const {quoteStyle, name: memberName} = MemberName; + + switch (operatorType) { + case NamepathOperatorType.MEMBER: + return { + type: NodeType.MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + case NamepathOperatorType.INSTANCE_MEMBER: + return { + type: NodeType.INSTANCE_MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + case NamepathOperatorType.INNER_MEMBER: + return { + type: NodeType.INNER_MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + /* istanbul ignore next */ + default: + throw new Error('Unexpected operator type: "' + operatorType + '"'); + } + }, Object.assign({ + type: NodeType.EXTERNAL + }, external)); + }, + peg$c46 = "module", + peg$c47 = peg$literalExpectation("module", false), + peg$c48 = function(value) { + return { + type: NodeType.MODULE, + value, + }; + }, + peg$c49 = function(rootOwner, memberPartWithOperators) { + return memberPartWithOperators.reduce(function(owner, tokens) { + const operatorType = tokens[1]; + const eventNamespace = tokens[3]; + const MemberName = tokens[5]; + const {quoteStyle, name: memberName} = MemberName; + + switch (operatorType) { + case NamepathOperatorType.MEMBER: + return { + type: NodeType.MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + case NamepathOperatorType.INSTANCE_MEMBER: + return { + type: NodeType.INSTANCE_MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + case NamepathOperatorType.INNER_MEMBER: + return { + type: NodeType.INNER_MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + /* istanbul ignore next */ + default: + throw new Error('Unexpected operator type: "' + operatorType + '"'); + } + }, rootOwner); + }, + peg$c50 = function(path) { + return { + quoteStyle: 'single', + type: NodeType.FILE_PATH, + path: path.replace(/\\'/g, "'") + .replace(/\\\\/gu, '\\') + }; + }, + peg$c51 = function(path) { + return { + quoteStyle: 'double', + type: NodeType.FILE_PATH, + path: path.replace(/\\"/gu, '"') + .replace(/\\\\/gu, '\\') + }; + }, + peg$c52 = /^[a-zA-Z0-9_$\/\-]/, + peg$c53 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$", "/", "-"], false, false), + peg$c54 = function(path) { + return { + quoteStyle: 'none', + type: NodeType.FILE_PATH, + path, + }; + }, + peg$c55 = "*", + peg$c56 = peg$literalExpectation("*", false), + peg$c57 = function() { + return { type: NodeType.ANY }; + }, + peg$c58 = "?", + peg$c59 = peg$literalExpectation("?", false), + peg$c60 = function() { + return { type: NodeType.UNKNOWN }; + }, + peg$c61 = function(value) { + return { + type: NodeType.STRING_VALUE, + quoteStyle: 'double', + string: value.replace(/\\"/gu, '"') + .replace(/\\\\/gu, '\\') + }; + }, + peg$c62 = function(value) { + return { + type: NodeType.STRING_VALUE, + quoteStyle: 'single', + string: value.replace(/\\'/g, "'") + .replace(/\\\\/gu, '\\') + }; + }, + peg$c63 = function(value) { + return { + type: NodeType.NUMBER_VALUE, + number: value + }; + }, + peg$c64 = "+", + peg$c65 = peg$literalExpectation("+", false), + peg$c66 = "-", + peg$c67 = peg$literalExpectation("-", false), + peg$c68 = /^[0-9]/, + peg$c69 = peg$classExpectation([["0", "9"]], false, false), + peg$c70 = "e", + peg$c71 = peg$literalExpectation("e", false), + peg$c72 = "0b", + peg$c73 = peg$literalExpectation("0b", false), + peg$c74 = /^[01]/, + peg$c75 = peg$classExpectation(["0", "1"], false, false), + peg$c76 = "0o", + peg$c77 = peg$literalExpectation("0o", false), + peg$c78 = /^[0-7]/, + peg$c79 = peg$classExpectation([["0", "7"]], false, false), + peg$c80 = "0x", + peg$c81 = peg$literalExpectation("0x", false), + peg$c82 = /^[0-9a-fA-F]/, + peg$c83 = peg$classExpectation([["0", "9"], ["a", "f"], ["A", "F"]], false, false), + peg$c84 = "&", + peg$c85 = peg$literalExpectation("&", false), + peg$c86 = function(left, right) { + return { + type: NodeType.INTERSECTION, + left, + right, + }; + }, + peg$c87 = "|", + peg$c88 = peg$literalExpectation("|", false), + peg$c89 = function(left, right) { + return { + type: NodeType.UNION, + left, + right, + }; + }, + peg$c90 = "typeof", + peg$c91 = peg$literalExpectation("typeof", false), + peg$c92 = function(operator, name) { + return { + type: NodeType.TYPE_QUERY, + name, + }; + }, + peg$c93 = "keyof", + peg$c94 = peg$literalExpectation("keyof", false), + peg$c95 = function(operator, operand) { + return { + type: NodeType.KEY_QUERY, + value: operand, + } + }, + peg$c96 = "import", + peg$c97 = peg$literalExpectation("import", false), + peg$c98 = "(", + peg$c99 = peg$literalExpectation("(", false), + peg$c100 = ")", + peg$c101 = peg$literalExpectation(")", false), + peg$c102 = function(operator, path) { + return { type: NodeType.IMPORT, path }; + }, + peg$c103 = function(operator, operand) { + return { + type: NodeType.NULLABLE, + value: operand, + meta: { syntax: NullableTypeSyntax.PREFIX_QUESTION_MARK }, + }; + }, + peg$c104 = "!", + peg$c105 = peg$literalExpectation("!", false), + peg$c106 = function(operator, operand) { + return { + type: NodeType.NOT_NULLABLE, + value: operand, + meta: { syntax: NotNullableTypeSyntax.PREFIX_BANG }, + }; + }, + peg$c107 = "=", + peg$c108 = peg$literalExpectation("=", false), + peg$c109 = function(operator, operand) { + return { + type: NodeType.OPTIONAL, + value: operand, + meta: { syntax: OptionalTypeSyntax.PREFIX_EQUALS_SIGN }, + }; + }, + peg$c110 = function(operand, operator) { + return { + type: NodeType.NULLABLE, + value: operand, + meta: { syntax: NullableTypeSyntax.SUFFIX_QUESTION_MARK }, + }; + }, + peg$c111 = function(operand, operator) { + return { + type: NodeType.NOT_NULLABLE, + value: operand, + meta: { syntax: NotNullableTypeSyntax.SUFFIX_BANG }, + }; + }, + peg$c112 = function(operand, operator) { + return { + type: NodeType.OPTIONAL, + value: operand, + meta: { syntax: OptionalTypeSyntax.SUFFIX_EQUALS_SIGN }, + }; + }, + peg$c113 = function(operand, syntax, params) { + return { + type: NodeType.GENERIC, + subject: operand, + objects: params, + meta: { syntax }, + }; + }, + peg$c114 = ",", + peg$c115 = peg$literalExpectation(",", false), + peg$c116 = function(first, restsWithComma) { + return restsWithComma.reduce(function(params, tokens) { + return params.concat([tokens[3]]); + }, [first]); + }, + peg$c117 = ".<", + peg$c118 = peg$literalExpectation(".<", false), + peg$c119 = function() { + return GenericTypeSyntax.ANGLE_BRACKET_WITH_DOT; + }, + peg$c120 = "<", + peg$c121 = peg$literalExpectation("<", false), + peg$c122 = function() { + return GenericTypeSyntax.ANGLE_BRACKET; + }, + peg$c123 = ">", + peg$c124 = peg$literalExpectation(">", false), + peg$c125 = "[", + peg$c126 = peg$literalExpectation("[", false), + peg$c127 = "]", + peg$c128 = peg$literalExpectation("]", false), + peg$c129 = function(operand, brackets) { + return brackets.reduce(function(operand) { + return { + type: NodeType.GENERIC, + subject: { + type: NodeType.NAME, + name: 'Array' + }, + objects: [ operand ], + meta: { syntax: GenericTypeSyntax.SQUARE_BRACKET }, + }; + }, operand); + }, + peg$c130 = "new", + peg$c131 = peg$literalExpectation("new", false), + peg$c132 = "=>", + peg$c133 = peg$literalExpectation("=>", false), + peg$c134 = function(newModifier, paramsPart, returnedTypeNode) { + return { + type: NodeType.ARROW, + params: paramsPart, + returns: returnedTypeNode, + new: newModifier + }; + }, + peg$c135 = function() { + return []; + }, + peg$c136 = function(params) { + return params; + }, + peg$c137 = function(paramsWithComma, lastParam) { + return paramsWithComma.reduceRight(function(params, tokens) { + const param = { type: NodeType.NAMED_PARAMETER, name: tokens[0], typeName: tokens[4] }; + return [param].concat(params); + }, lastParam ? [lastParam] : []); + }, + peg$c138 = "...", + peg$c139 = peg$literalExpectation("...", false), + peg$c140 = function(spread, id, type) { + const operand = { type: NodeType.NAMED_PARAMETER, name: id, typeName: type }; + if (spread) { + return { + type: NodeType.VARIADIC, + value: operand, + meta: { syntax: VariadicTypeSyntax.PREFIX_DOTS }, + }; + } + else { + return operand; + } + }, + peg$c141 = "function", + peg$c142 = peg$literalExpectation("function", false), + peg$c143 = function(paramsPart, returnedTypePart) { + const returnedTypeNode = returnedTypePart ? returnedTypePart[2] : null; + + return { + type: NodeType.FUNCTION, + params: paramsPart.params, + returns: returnedTypeNode, + this: paramsPart.modifier.nodeThis, + new: paramsPart.modifier.nodeNew, + }; + }, + peg$c144 = function(modifier, params) { + return { params, modifier }; + }, + peg$c145 = function(modifier) { + return { params: [], modifier }; + }, + peg$c146 = function() { + return { params: [], modifier: { nodeThis: null, nodeNew: null } }; + }, + peg$c147 = function(params) { + return { params, modifier: { nodeThis: null, nodeNew: null } }; + }, + peg$c148 = "this", + peg$c149 = peg$literalExpectation("this", false), + peg$c150 = function(modifierThis) { + return { nodeThis: modifierThis[4], nodeNew: null }; + }, + peg$c151 = function(modifierNew) { + return { nodeThis: null, nodeNew: modifierNew[4] }; + }, + peg$c152 = function(paramsWithComma, lastParam) { + return paramsWithComma.reduceRight(function(params, tokens) { + const [param] = tokens; + return [param].concat(params); + }, lastParam ? [lastParam] : []); + }, + peg$c153 = "{", + peg$c154 = peg$literalExpectation("{", false), + peg$c155 = "}", + peg$c156 = peg$literalExpectation("}", false), + peg$c157 = function(entries) { + return { + type: NodeType.RECORD, + entries: entries || [], + }; + }, + peg$c158 = ";", + peg$c159 = peg$literalExpectation(";", false), + peg$c160 = function(first, restWithComma) { + return restWithComma.reduce(function(entries, tokens) { + const entry = tokens[2]; + return entries.concat([entry]); + }, [first]); + }, + peg$c161 = "readonly", + peg$c162 = peg$literalExpectation("readonly", false), + peg$c163 = function(readonly, keyInfo, optional, value) { + const {quoteStyle, key} = keyInfo; + return { + type: NodeType.RECORD_ENTRY, + key, + quoteStyle, + value: + optional === '?' ? { + type: NodeType.OPTIONAL, + value, + meta: { syntax: OptionalTypeSyntax.SUFFIX_KEY_QUESTION_MARK }, + } : + value, + readonly: Boolean(readonly) + }; + }, + peg$c164 = function(readonly, keyInfo) { + const {quoteStyle, key} = keyInfo; + return { + type: NodeType.RECORD_ENTRY, + key, + quoteStyle, + value: null, + readonly: Boolean(readonly) + }; + }, + peg$c165 = function(key) { + return { + quoteStyle: 'double', + key: key.replace(/\\"/gu, '"') + .replace(/\\\\/gu, '\\') + }; + }, + peg$c166 = function(key) { + return { + quoteStyle: 'single', + key: key.replace(/\\'/g, "'") + .replace(/\\\\/gu, '\\') + }; + }, + peg$c167 = function(key) { + return { + quoteStyle: 'none', + key + }; + }, + peg$c168 = function(entries) { + return { + type: NodeType.TUPLE, + entries, + } + }, + peg$c169 = function(restWithComma, last) { + return restWithComma.reduceRight((entries, tokens) => { + let [entry] = tokens; + return [entry].concat(entries); + }, last ? [last] : []); + }, + peg$c170 = function(wrapped) { + return { + type: NodeType.PARENTHESIS, + value: wrapped, + }; + }, + peg$c171 = function(operand) { + return { + type: NodeType.VARIADIC, + value: operand, + meta: { syntax: VariadicTypeSyntax.PREFIX_DOTS }, + }; + }, + peg$c172 = function(operand) { + return { + type: NodeType.VARIADIC, + value: operand, + meta: { syntax: VariadicTypeSyntax.SUFFIX_DOTS }, + }; + }, + peg$c173 = function() { + return { + type: NodeType.VARIADIC, + value: { type: NodeType.ANY }, + meta: { syntax: VariadicTypeSyntax.ONLY_DOTS }, + }; + }, + + peg$currPos = 0, + peg$posDetailsCache = [{ line: 1, column: 1 }], + peg$maxFailPos = 0, + peg$maxFailExpected = [], + peg$resultsCache = {}, + + peg$result; + + if ("startRule" in options) { + if (!(options.startRule in peg$startRuleFunctions)) { + throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); + } + + peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; + } + + function peg$literalExpectation(text, ignoreCase) { + return { type: "literal", text: text, ignoreCase: ignoreCase }; + } + + function peg$classExpectation(parts, inverted, ignoreCase) { + return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase }; + } + + function peg$anyExpectation() { + return { type: "any" }; + } + + function peg$endExpectation() { + return { type: "end" }; + } + + function peg$computePosDetails(pos) { + var details = peg$posDetailsCache[pos], p; + + if (details) { + return details; + } else { + p = pos - 1; + while (!peg$posDetailsCache[p]) { + p--; + } + + details = peg$posDetailsCache[p]; + details = { + line: details.line, + column: details.column + }; + + while (p < pos) { + if (input.charCodeAt(p) === 10) { + details.line++; + details.column = 1; + } else { + details.column++; + } + + p++; + } + + peg$posDetailsCache[pos] = details; + return details; + } + } + + function peg$computeLocation(startPos, endPos) { + var startPosDetails = peg$computePosDetails(startPos), + endPosDetails = peg$computePosDetails(endPos); + + return { + start: { + offset: startPos, + line: startPosDetails.line, + column: startPosDetails.column + }, + end: { + offset: endPos, + line: endPosDetails.line, + column: endPosDetails.column + } + }; + } + + function peg$fail(expected) { + if (peg$currPos < peg$maxFailPos) { return; } + + if (peg$currPos > peg$maxFailPos) { + peg$maxFailPos = peg$currPos; + peg$maxFailExpected = []; + } + + peg$maxFailExpected.push(expected); + } + + function peg$buildStructuredError(expected, found, location) { + return new peg$SyntaxError$3( + peg$SyntaxError$3.buildMessage(expected, found), + expected, + found, + location + ); + } + + function peg$parseTopTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 82 + 0, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parse_(); + if (s1 !== peg$FAILED) { + s2 = peg$parseVariadicTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseUnionTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseIntersectionTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseUnaryUnionTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseArrayTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseGenericTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseRecordTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseTupleTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseArrowTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseFunctionTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseTypeQueryExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseKeyQueryExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseBroadNamepathExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseParenthesizedExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseValueExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseAnyTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + if (s2 !== peg$FAILED) { + s3 = peg$parse_(); + if (s3 !== peg$FAILED) { + s1 = peg$c0(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseWS() { + var s0, s1, s2; + + var key = peg$currPos * 82 + 1, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + if (peg$c1.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + { peg$fail(peg$c2); } + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (peg$c3.test(input.charAt(peg$currPos))) { + s1 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c4); } + } + if (s1 === peg$FAILED) { + s1 = null; + } + if (s1 !== peg$FAILED) { + if (peg$c5.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c6); } + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parse_() { + var s0, s1; + + var key = peg$currPos * 82 + 2, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = []; + s1 = peg$parseWS(); + while (s1 !== peg$FAILED) { + s0.push(s1); + s1 = peg$parseWS(); + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parse__() { + var s0, s1; + + var key = peg$currPos * 82 + 3, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = []; + s1 = peg$parseWS(); + if (s1 !== peg$FAILED) { + while (s1 !== peg$FAILED) { + s0.push(s1); + s1 = peg$parseWS(); + } + } else { + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseJsIdentifier() { + var s0, s1, s2, s3, s4; + + var key = peg$currPos * 82 + 4, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (peg$c7.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c8); } + } + if (s2 !== peg$FAILED) { + s3 = []; + if (peg$c9.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c10); } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c9.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c10); } + } + } + if (s3 !== peg$FAILED) { + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseNamepathExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + var key = peg$currPos * 82 + 5, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseParenthesizedExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseImportTypeExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseTypeNameExprJsDocFlavored(); + } + } + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseInfixNamepathOperator(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c11) { + s7 = peg$c11; + peg$currPos += 6; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c12); } + } + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseMemberName(); + if (s9 !== peg$FAILED) { + s4 = [s4, s5, s6, s7, s8, s9]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseInfixNamepathOperator(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c11) { + s7 = peg$c11; + peg$currPos += 6; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c12); } + } + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseMemberName(); + if (s9 !== peg$FAILED) { + s4 = [s4, s5, s6, s7, s8, s9]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s1 = peg$c13(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseTypeNameExprJsDocFlavored() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 82 + 6, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + s2 = peg$currPos; + if (peg$c7.test(input.charAt(peg$currPos))) { + s3 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c8); } + } + if (s3 !== peg$FAILED) { + s4 = []; + if (peg$c14.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c15); } + } + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c14.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c15); } + } + } + if (s4 !== peg$FAILED) { + s3 = [s3, s4]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = input.substring(s1, peg$currPos); + } else { + s1 = s2; + } + if (s1 !== peg$FAILED) { + s1 = peg$c16(s1); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseMemberName() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 82 + 7, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 39) { + s1 = peg$c17; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 39) { + s3 = peg$c17; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c24(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 34) { + s1 = peg$c25; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 34) { + s3 = peg$c25; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c29(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parseJsIdentifier(); + if (s1 !== peg$FAILED) { + s1 = peg$c30(s1); + } + s0 = s1; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseInfixNamepathOperator() { + var s0; + + var key = peg$currPos * 82 + 8, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseMemberTypeOperator(); + if (s0 === peg$FAILED) { + s0 = peg$parseInstanceMemberTypeOperator(); + if (s0 === peg$FAILED) { + s0 = peg$parseInnerMemberTypeOperator(); + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseQualifiedMemberName() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 82 + 9, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseTypeNameExprJsDocFlavored(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 46) { + s5 = peg$c31; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c32); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseTypeNameExprJsDocFlavored(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 46) { + s5 = peg$c31; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c32); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseTypeNameExprJsDocFlavored(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s1 = peg$c33(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseMemberTypeOperator() { + var s0, s1; + + var key = peg$currPos * 82 + 10, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 46) { + s1 = peg$c31; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c32); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c34(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseInnerMemberTypeOperator() { + var s0, s1; + + var key = peg$currPos * 82 + 11, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 126) { + s1 = peg$c35; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c36); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c37(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseInstanceMemberTypeOperator() { + var s0, s1; + + var key = peg$currPos * 82 + 12, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 35) { + s1 = peg$c38; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c39); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c40(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseBroadNamepathExpr() { + var s0; + + var key = peg$currPos * 82 + 13, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseExternalNameExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseModuleNameExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNamepathExpr(); + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseExternalNameExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13; + + var key = peg$currPos * 82 + 14, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c41) { + s1 = peg$c41; + peg$currPos += 8; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c42); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c43; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseMemberName(); + if (s5 !== peg$FAILED) { + s6 = []; + s7 = peg$currPos; + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseInfixNamepathOperator(); + if (s9 !== peg$FAILED) { + s10 = peg$parse_(); + if (s10 !== peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c11) { + s11 = peg$c11; + peg$currPos += 6; + } else { + s11 = peg$FAILED; + { peg$fail(peg$c12); } + } + if (s11 === peg$FAILED) { + s11 = null; + } + if (s11 !== peg$FAILED) { + s12 = peg$parse_(); + if (s12 !== peg$FAILED) { + s13 = peg$parseMemberName(); + if (s13 !== peg$FAILED) { + s8 = [s8, s9, s10, s11, s12, s13]; + s7 = s8; + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + while (s7 !== peg$FAILED) { + s6.push(s7); + s7 = peg$currPos; + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseInfixNamepathOperator(); + if (s9 !== peg$FAILED) { + s10 = peg$parse_(); + if (s10 !== peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c11) { + s11 = peg$c11; + peg$currPos += 6; + } else { + s11 = peg$FAILED; + { peg$fail(peg$c12); } + } + if (s11 === peg$FAILED) { + s11 = null; + } + if (s11 !== peg$FAILED) { + s12 = peg$parse_(); + if (s12 !== peg$FAILED) { + s13 = peg$parseMemberName(); + if (s13 !== peg$FAILED) { + s8 = [s8, s9, s10, s11, s12, s13]; + s7 = s8; + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } + if (s6 !== peg$FAILED) { + s1 = peg$c45(s5, s6); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseModuleNameExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 82 + 15, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 6) === peg$c46) { + s1 = peg$c46; + peg$currPos += 6; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c47); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c43; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseModulePathExpr(); + if (s5 !== peg$FAILED) { + s1 = peg$c48(s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseModulePathExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + var key = peg$currPos * 82 + 16, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseFilePathExpr(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseInfixNamepathOperator(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c11) { + s7 = peg$c11; + peg$currPos += 6; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c12); } + } + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseMemberName(); + if (s9 !== peg$FAILED) { + s4 = [s4, s5, s6, s7, s8, s9]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseInfixNamepathOperator(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c11) { + s7 = peg$c11; + peg$currPos += 6; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c12); } + } + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseMemberName(); + if (s9 !== peg$FAILED) { + s4 = [s4, s5, s6, s7, s8, s9]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s1 = peg$c49(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFilePathExpr() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 82 + 17, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 39) { + s1 = peg$c17; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 39) { + s3 = peg$c17; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c50(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 34) { + s1 = peg$c25; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 34) { + s3 = peg$c25; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c51(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$currPos; + s2 = []; + if (peg$c52.test(input.charAt(peg$currPos))) { + s3 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c53); } + } + if (s3 !== peg$FAILED) { + while (s3 !== peg$FAILED) { + s2.push(s3); + if (peg$c52.test(input.charAt(peg$currPos))) { + s3 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c53); } + } + } + } else { + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = input.substring(s1, peg$currPos); + } else { + s1 = s2; + } + if (s1 !== peg$FAILED) { + s1 = peg$c54(s1); + } + s0 = s1; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseAnyTypeExpr() { + var s0, s1; + + var key = peg$currPos * 82 + 18, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 42) { + s1 = peg$c55; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c56); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c57(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseUnknownTypeExpr() { + var s0, s1; + + var key = peg$currPos * 82 + 19, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 63) { + s1 = peg$c58; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c59); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c60(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseValueExpr() { + var s0; + + var key = peg$currPos * 82 + 20, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseStringLiteralExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNumberLiteralExpr(); + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseStringLiteralExpr() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 82 + 21, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 34) { + s1 = peg$c25; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 34) { + s3 = peg$c25; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c61(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 39) { + s1 = peg$c17; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 39) { + s3 = peg$c17; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c62(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseNumberLiteralExpr() { + var s0, s1; + + var key = peg$currPos * 82 + 22, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseBinNumberLiteralExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseOctNumberLiteralExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseHexNumberLiteralExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseDecimalNumberLiteralExpr(); + } + } + } + if (s1 !== peg$FAILED) { + s1 = peg$c63(s1); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseDecimalNumberLiteralExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 82 + 23, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 43) { + s2 = peg$c64; + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c65); } + } + if (s2 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 45) { + s2 = peg$c66; + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c67); } + } + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + s3 = peg$parseUnsignedDecimalNumberLiteralExpr(); + if (s3 !== peg$FAILED) { + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseUnsignedDecimalNumberLiteralExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 82 + 24, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + s2 = peg$currPos; + s3 = []; + if (peg$c68.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c69); } + } + if (s4 !== peg$FAILED) { + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c68.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c69); } + } + } + } else { + s3 = peg$FAILED; + } + if (s3 !== peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 46) { + s5 = peg$c31; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c32); } + } + if (s5 !== peg$FAILED) { + s6 = []; + if (peg$c68.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c69); } + } + if (s7 !== peg$FAILED) { + while (s7 !== peg$FAILED) { + s6.push(s7); + if (peg$c68.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c69); } + } + } + } else { + s6 = peg$FAILED; + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = null; + } + if (s4 !== peg$FAILED) { + s3 = [s3, s4]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 === peg$FAILED) { + s2 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 46) { + s3 = peg$c31; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c32); } + } + if (s3 !== peg$FAILED) { + s4 = []; + if (peg$c68.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c69); } + } + if (s5 !== peg$FAILED) { + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c68.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c69); } + } + } + } else { + s4 = peg$FAILED; + } + if (s4 !== peg$FAILED) { + s3 = [s3, s4]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s3 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 101) { + s4 = peg$c70; + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c71); } + } + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 43) { + s5 = peg$c64; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c65); } + } + if (s5 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 45) { + s5 = peg$c66; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c67); } + } + } + if (s5 === peg$FAILED) { + s5 = null; + } + if (s5 !== peg$FAILED) { + s6 = []; + if (peg$c68.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c69); } + } + if (s7 !== peg$FAILED) { + while (s7 !== peg$FAILED) { + s6.push(s7); + if (peg$c68.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c69); } + } + } + } else { + s6 = peg$FAILED; + } + if (s6 !== peg$FAILED) { + s4 = [s4, s5, s6]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = null; + } + if (s3 !== peg$FAILED) { + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseBinNumberLiteralExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 82 + 25, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 45) { + s2 = peg$c66; + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c67); } + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c72) { + s3 = peg$c72; + peg$currPos += 2; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c73); } + } + if (s3 !== peg$FAILED) { + s4 = []; + if (peg$c74.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c75); } + } + if (s5 !== peg$FAILED) { + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c74.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c75); } + } + } + } else { + s4 = peg$FAILED; + } + if (s4 !== peg$FAILED) { + s2 = [s2, s3, s4]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseOctNumberLiteralExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 82 + 26, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 45) { + s2 = peg$c66; + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c67); } + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c76) { + s3 = peg$c76; + peg$currPos += 2; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c77); } + } + if (s3 !== peg$FAILED) { + s4 = []; + if (peg$c78.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c79); } + } + if (s5 !== peg$FAILED) { + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c78.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c79); } + } + } + } else { + s4 = peg$FAILED; + } + if (s4 !== peg$FAILED) { + s2 = [s2, s3, s4]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseHexNumberLiteralExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 82 + 27, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 45) { + s2 = peg$c66; + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c67); } + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c80) { + s3 = peg$c80; + peg$currPos += 2; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c81); } + } + if (s3 !== peg$FAILED) { + s4 = []; + if (peg$c82.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c83); } + } + if (s5 !== peg$FAILED) { + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c82.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c83); } + } + } + } else { + s4 = peg$FAILED; + } + if (s4 !== peg$FAILED) { + s2 = [s2, s3, s4]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseIntersectionTypeExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 82 + 28, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseIntersectionTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 38) { + s3 = peg$c84; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c85); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseIntersectionTypeExpr(); + if (s5 === peg$FAILED) { + s5 = peg$parseIntersectionTypeExprOperand(); + } + if (s5 !== peg$FAILED) { + s1 = peg$c86(s1, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseIntersectionTypeExprOperand() { + var s0; + + var key = peg$currPos * 82 + 29, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseKeyQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseUnionTypeExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 82 + 30, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseUnionTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 124) { + s3 = peg$c87; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c88); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseUnionTypeExpr(); + if (s5 === peg$FAILED) { + s5 = peg$parseUnionTypeExprOperand(); + } + if (s5 !== peg$FAILED) { + s1 = peg$c89(s1, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseUnionTypeExprOperand() { + var s0; + + var key = peg$currPos * 82 + 31, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseKeyQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseUnaryUnionTypeExpr() { + var s0; + + var key = peg$currPos * 82 + 32, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseSuffixUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parsePrefixUnaryUnionTypeExpr(); + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixUnaryUnionTypeExpr() { + var s0; + + var key = peg$currPos * 82 + 33, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parsePrefixOptionalTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parsePrefixNotNullableTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parsePrefixNullableTypeExpr(); + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixUnaryUnionTypeExprOperand() { + var s0; + + var key = peg$currPos * 82 + 34, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseTypeQueryExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 82 + 35, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 6) === peg$c90) { + s1 = peg$c90; + peg$currPos += 6; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c91); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse__(); + if (s2 !== peg$FAILED) { + s3 = peg$parseQualifiedMemberName(); + if (s3 !== peg$FAILED) { + s1 = peg$c92(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseKeyQueryExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 82 + 36, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 5) === peg$c93) { + s1 = peg$c93; + peg$currPos += 5; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c94); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse__(); + if (s2 !== peg$FAILED) { + s3 = peg$parseKeyQueryExprOperand(); + if (s3 !== peg$FAILED) { + s1 = peg$c95(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 5) === peg$c93) { + s1 = peg$c93; + peg$currPos += 5; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c94); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseParenthesizedExpr(); + if (s2 !== peg$FAILED) { + s1 = peg$c95(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseKeyQueryExprOperand() { + var s0; + + var key = peg$currPos * 82 + 37, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseIntersectionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseKeyQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseImportTypeExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 82 + 38, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 6) === peg$c96) { + s1 = peg$c96; + peg$currPos += 6; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c97); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 40) { + s3 = peg$c98; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c99); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseStringLiteralExpr(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s7 = peg$c100; + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c101); } + } + if (s7 !== peg$FAILED) { + s1 = peg$c102(s1, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixNullableTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 82 + 39, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 63) { + s1 = peg$c58; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c59); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); + if (s3 !== peg$FAILED) { + s1 = peg$c103(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixNotNullableTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 82 + 40, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 33) { + s1 = peg$c104; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c105); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); + if (s3 !== peg$FAILED) { + s1 = peg$c106(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixOptionalTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 82 + 41, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 61) { + s1 = peg$c107; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c108); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); + if (s3 !== peg$FAILED) { + s1 = peg$c109(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixUnaryUnionTypeExpr() { + var s0; + + var key = peg$currPos * 82 + 42, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseSuffixOptionalTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseSuffixNullableTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseSuffixNotNullableTypeExpr(); + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixUnaryUnionTypeExprOperand() { + var s0; + + var key = peg$currPos * 82 + 43, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parsePrefixUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixNullableTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 82 + 44, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 63) { + s3 = peg$c58; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c59); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c110(s1); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixNotNullableTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 82 + 45, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 33) { + s3 = peg$c104; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c105); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c111(s1); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixOptionalTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 82 + 46, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseSuffixNullableTypeExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseSuffixNotNullableTypeExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 61) { + s3 = peg$c107; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c108); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c112(s1); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 82 + 47, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseGenericTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseGenericTypeStartToken(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseGenericTypeExprTypeParamList(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseGenericTypeEndToken(); + if (s7 !== peg$FAILED) { + s1 = peg$c113(s1, s3, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeExprOperand() { + var s0; + + var key = peg$currPos * 82 + 48, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeExprTypeParamOperand() { + var s0; + + var key = peg$currPos * 82 + 49, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseIntersectionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseKeyQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeExprTypeParamList() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 82 + 50, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseGenericTypeExprTypeParamOperand(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c114; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c115); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseGenericTypeExprTypeParamOperand(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c114; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c115); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseGenericTypeExprTypeParamOperand(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s1 = peg$c116(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeStartToken() { + var s0; + + var key = peg$currPos * 82 + 51, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseGenericTypeEcmaScriptFlavoredStartToken(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeTypeScriptFlavoredStartToken(); + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeEcmaScriptFlavoredStartToken() { + var s0, s1; + + var key = peg$currPos * 82 + 52, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 2) === peg$c117) { + s1 = peg$c117; + peg$currPos += 2; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c118); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c119(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeTypeScriptFlavoredStartToken() { + var s0, s1; + + var key = peg$currPos * 82 + 53, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 60) { + s1 = peg$c120; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c121); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c122(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeEndToken() { + var s0; + + var key = peg$currPos * 82 + 54, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + if (input.charCodeAt(peg$currPos) === 62) { + s0 = peg$c123; + peg$currPos++; + } else { + s0 = peg$FAILED; + { peg$fail(peg$c124); } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseArrayTypeExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 82 + 55, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseArrayTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 91) { + s5 = peg$c125; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c126); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s7 = peg$c127; + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c128); } + } + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 !== peg$FAILED) { + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 91) { + s5 = peg$c125; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c126); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s7 = peg$c127; + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c128); } + } + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + } else { + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = peg$c129(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseArrayTypeExprOperand() { + var s0; + + var key = peg$currPos * 82 + 56, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseKeyQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseArrowTypeExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 82 + 57, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 3) === peg$c130) { + s1 = peg$c130; + peg$currPos += 3; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c131); } + } + if (s1 === peg$FAILED) { + s1 = null; + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseArrowTypeExprParamsList(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c132) { + s5 = peg$c132; + peg$currPos += 2; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c133); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseFunctionTypeExprReturnableOperand(); + if (s7 !== peg$FAILED) { + s1 = peg$c134(s1, s3, s7); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseArrowTypeExprParamsList() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 82 + 58, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c98; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c99); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s3 = peg$c100; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c101); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c135(); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c98; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c99); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseArrowTypeExprParams(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s5 = peg$c100; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c101); } + } + if (s5 !== peg$FAILED) { + s1 = peg$c136(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseArrowTypeExprParams() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10; + + var key = peg$currPos * 82 + 59, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = []; + s2 = peg$currPos; + s3 = peg$parseJsIdentifier(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s5 = peg$c43; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseFunctionTypeExprParamOperand(); + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s9 = peg$c114; + peg$currPos++; + } else { + s9 = peg$FAILED; + { peg$fail(peg$c115); } + } + if (s9 !== peg$FAILED) { + s10 = peg$parse_(); + if (s10 !== peg$FAILED) { + s3 = [s3, s4, s5, s6, s7, s8, s9, s10]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + while (s2 !== peg$FAILED) { + s1.push(s2); + s2 = peg$currPos; + s3 = peg$parseJsIdentifier(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s5 = peg$c43; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseFunctionTypeExprParamOperand(); + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s9 = peg$c114; + peg$currPos++; + } else { + s9 = peg$FAILED; + { peg$fail(peg$c115); } + } + if (s9 !== peg$FAILED) { + s10 = peg$parse_(); + if (s10 !== peg$FAILED) { + s3 = [s3, s4, s5, s6, s7, s8, s9, s10]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseVariadicNameExpr(); + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + s1 = peg$c137(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseVariadicNameExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 82 + 60, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 3) === peg$c138) { + s1 = peg$c138; + peg$currPos += 3; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c139); } + } + if (s1 === peg$FAILED) { + s1 = null; + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseJsIdentifier(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s5 = peg$c43; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseFunctionTypeExprParamOperand(); + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s1 = peg$c140(s1, s3, s7); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8; + + var key = peg$currPos * 82 + 61, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c141) { + s1 = peg$c141; + peg$currPos += 8; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c142); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseFunctionTypeExprParamsList(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 58) { + s6 = peg$c43; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s6 !== peg$FAILED) { + s7 = peg$parse_(); + if (s7 !== peg$FAILED) { + s8 = peg$parseFunctionTypeExprReturnableOperand(); + if (s8 !== peg$FAILED) { + s6 = [s6, s7, s8]; + s5 = s6; + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + if (s5 === peg$FAILED) { + s5 = null; + } + if (s5 !== peg$FAILED) { + s1 = peg$c143(s3, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExprParamsList() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + var key = peg$currPos * 82 + 62, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c98; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c99); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseFunctionTypeExprModifier(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c114; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c115); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseFunctionTypeExprParams(); + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s9 = peg$c100; + peg$currPos++; + } else { + s9 = peg$FAILED; + { peg$fail(peg$c101); } + } + if (s9 !== peg$FAILED) { + s1 = peg$c144(s3, s7); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c98; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c99); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseFunctionTypeExprModifier(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s5 = peg$c100; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c101); } + } + if (s5 !== peg$FAILED) { + s1 = peg$c145(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c98; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c99); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s3 = peg$c100; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c101); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c146(); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c98; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c99); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseFunctionTypeExprParams(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s5 = peg$c100; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c101); } + } + if (s5 !== peg$FAILED) { + s1 = peg$c147(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExprModifier() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 82 + 63, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.substr(peg$currPos, 4) === peg$c148) { + s2 = peg$c148; + peg$currPos += 4; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c149); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parse_(); + if (s3 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s4 = peg$c43; + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseFunctionTypeExprParamOperand(); + if (s6 !== peg$FAILED) { + s2 = [s2, s3, s4, s5, s6]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s1 = peg$c150(s1); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$currPos; + if (input.substr(peg$currPos, 3) === peg$c130) { + s2 = peg$c130; + peg$currPos += 3; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c131); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parse_(); + if (s3 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s4 = peg$c43; + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseFunctionTypeExprParamOperand(); + if (s6 !== peg$FAILED) { + s2 = [s2, s3, s4, s5, s6]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s1 = peg$c151(s1); + } + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExprParams() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 82 + 64, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = []; + s2 = peg$currPos; + s3 = peg$parseFunctionTypeExprParamOperand(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c114; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c115); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s3 = [s3, s4, s5, s6]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + while (s2 !== peg$FAILED) { + s1.push(s2); + s2 = peg$currPos; + s3 = peg$parseFunctionTypeExprParamOperand(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c114; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c115); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s3 = [s3, s4, s5, s6]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseVariadicTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseVariadicTypeExprOperand(); + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + s1 = peg$c152(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExprParamOperand() { + var s0; + + var key = peg$currPos * 82 + 65, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseIntersectionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseKeyQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExprReturnableOperand() { + var s0; + + var key = peg$currPos * 82 + 66, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parsePrefixUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseKeyQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseRecordTypeExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 82 + 67, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 123) { + s1 = peg$c153; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c154); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseRecordTypeExprEntries(); + if (s3 === peg$FAILED) { + s3 = null; + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 125) { + s5 = peg$c155; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c156); } + } + if (s5 !== peg$FAILED) { + s1 = peg$c157(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseRecordTypeExprEntries() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 82 + 68, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseRecordTypeExprEntry(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s6 = peg$c114; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c115); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 59) { + s6 = peg$c158; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c159); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + s5 = []; + if (peg$c1.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c2); } + } + while (s6 !== peg$FAILED) { + s5.push(s6); + if (peg$c1.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c2); } + } + } + if (s5 !== peg$FAILED) { + if (peg$c3.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c4); } + } + if (s6 === peg$FAILED) { + s6 = null; + } + if (s6 !== peg$FAILED) { + if (peg$c5.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c6); } + } + if (s7 !== peg$FAILED) { + s5 = [s5, s6, s7]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseRecordTypeExprEntry(); + if (s6 !== peg$FAILED) { + s4 = [s4, s5, s6]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s6 = peg$c114; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c115); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 59) { + s6 = peg$c158; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c159); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + s5 = []; + if (peg$c1.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c2); } + } + while (s6 !== peg$FAILED) { + s5.push(s6); + if (peg$c1.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c2); } + } + } + if (s5 !== peg$FAILED) { + if (peg$c3.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c4); } + } + if (s6 === peg$FAILED) { + s6 = null; + } + if (s6 !== peg$FAILED) { + if (peg$c5.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c6); } + } + if (s7 !== peg$FAILED) { + s5 = [s5, s6, s7]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseRecordTypeExprEntry(); + if (s6 !== peg$FAILED) { + s4 = [s4, s5, s6]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c114; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c115); } + } + if (s5 !== peg$FAILED) { + s4 = [s4, s5]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 59) { + s5 = peg$c158; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c159); } + } + if (s5 !== peg$FAILED) { + s4 = [s4, s5]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = peg$currPos; + s4 = []; + if (peg$c1.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c2); } + } + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c1.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c2); } + } + } + if (s4 !== peg$FAILED) { + if (peg$c3.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c4); } + } + if (s5 === peg$FAILED) { + s5 = null; + } + if (s5 !== peg$FAILED) { + if (peg$c5.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c6); } + } + if (s6 !== peg$FAILED) { + s4 = [s4, s5, s6]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + } + if (s3 === peg$FAILED) { + s3 = null; + } + if (s3 !== peg$FAILED) { + s1 = peg$c160(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseRecordTypeExprEntry() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8; + + var key = peg$currPos * 82 + 69, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c161) { + s2 = peg$c161; + peg$currPos += 8; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c162); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parse__(); + if (s3 !== peg$FAILED) { + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 === peg$FAILED) { + s1 = null; + } + if (s1 !== peg$FAILED) { + s2 = peg$parseRecordTypeExprEntryKey(); + if (s2 !== peg$FAILED) { + s3 = peg$parse_(); + if (s3 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 63) { + s4 = peg$c58; + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c59); } + } + if (s4 === peg$FAILED) { + s4 = null; + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s6 = peg$c43; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s6 !== peg$FAILED) { + s7 = peg$parse_(); + if (s7 !== peg$FAILED) { + s8 = peg$parseRecordTypeExprEntryOperand(); + if (s8 !== peg$FAILED) { + s1 = peg$c163(s1, s2, s4, s8); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c161) { + s2 = peg$c161; + peg$currPos += 8; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c162); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parse__(); + if (s3 !== peg$FAILED) { + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 === peg$FAILED) { + s1 = null; + } + if (s1 !== peg$FAILED) { + s2 = peg$parseRecordTypeExprEntryKey(); + if (s2 !== peg$FAILED) { + s1 = peg$c164(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseRecordTypeExprEntryKey() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 82 + 70, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 34) { + s1 = peg$c25; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 34) { + s3 = peg$c25; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c165(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 39) { + s1 = peg$c17; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 39) { + s3 = peg$c17; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c166(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$currPos; + s2 = peg$parseJsIdentifier(); + if (s2 === peg$FAILED) { + s2 = peg$parseUnsignedDecimalNumberLiteralExpr(); + } + if (s2 !== peg$FAILED) { + s1 = input.substring(s1, peg$currPos); + } else { + s1 = s2; + } + if (s1 !== peg$FAILED) { + s1 = peg$c167(s1); + } + s0 = s1; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseRecordTypeExprEntryOperand() { + var s0; + + var key = peg$currPos * 82 + 71, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseIntersectionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseTupleTypeExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 82 + 72, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 91) { + s1 = peg$c125; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c126); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseTupleTypeExprEntries(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s5 = peg$c127; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c128); } + } + if (s5 !== peg$FAILED) { + s1 = peg$c168(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseTupleTypeExprEntries() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 82 + 73, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = []; + s2 = peg$currPos; + s3 = peg$parseTupleTypeExprOperand(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c114; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c115); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s3 = [s3, s4, s5, s6]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + while (s2 !== peg$FAILED) { + s1.push(s2); + s2 = peg$currPos; + s3 = peg$parseTupleTypeExprOperand(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c114; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c115); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s3 = [s3, s4, s5, s6]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseVariadicTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseVariadicTypeExprOperand(); + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + s1 = peg$c169(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseTupleTypeExprOperand() { + var s0; + + var key = peg$currPos * 82 + 74, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseIntersectionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseKeyQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseParenthesizedExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 82 + 75, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c98; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c99); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseParenthesizedExprOperand(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s5 = peg$c100; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c101); } + } + if (s5 !== peg$FAILED) { + s1 = peg$c170(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseParenthesizedExprOperand() { + var s0; + + var key = peg$currPos * 82 + 76, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseIntersectionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseKeyQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseVariadicTypeExpr() { + var s0; + + var key = peg$currPos * 82 + 77, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parsePrefixVariadicTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseSuffixVariadicTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyVariadicTypeExpr(); + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixVariadicTypeExpr() { + var s0, s1, s2; + + var key = peg$currPos * 82 + 78, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 3) === peg$c138) { + s1 = peg$c138; + peg$currPos += 3; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c139); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseVariadicTypeExprOperand(); + if (s2 !== peg$FAILED) { + s1 = peg$c171(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixVariadicTypeExpr() { + var s0, s1, s2; + + var key = peg$currPos * 82 + 79, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseVariadicTypeExprOperand(); + if (s1 !== peg$FAILED) { + if (input.substr(peg$currPos, 3) === peg$c138) { + s2 = peg$c138; + peg$currPos += 3; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c139); } + } + if (s2 !== peg$FAILED) { + s1 = peg$c172(s1); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseAnyVariadicTypeExpr() { + var s0, s1; + + var key = peg$currPos * 82 + 80, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 3) === peg$c138) { + s1 = peg$c138; + peg$currPos += 3; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c139); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c173(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseVariadicTypeExprOperand() { + var s0; + + var key = peg$currPos * 82 + 81, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseIntersectionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseKeyQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + + const meta = SyntaxType; + const { + GenericTypeSyntax, + VariadicTypeSyntax, OptionalTypeSyntax, + NullableTypeSyntax, NotNullableTypeSyntax, + } = meta; + const NodeType = NodeType_1; + + const NamepathOperatorType = { + MEMBER: 'MEMBER', + INNER_MEMBER: 'INNER_MEMBER', + INSTANCE_MEMBER: 'INSTANCE_MEMBER', + }; + + + peg$result = peg$startRuleFunction(); + + if (peg$result !== peg$FAILED && peg$currPos === input.length) { + return peg$result; + } else { + if (peg$result !== peg$FAILED && peg$currPos < input.length) { + peg$fail(peg$endExpectation()); + } + + throw peg$buildStructuredError( + peg$maxFailExpected, + peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, + peg$maxFailPos < input.length + ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) + : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) + ); + } +} + +var jsdoctypePermissive = { + SyntaxError: peg$SyntaxError$3, + parse: peg$parse$3 +}; + +/* + * Generated by PEG.js 0.10.0. + * + * http://pegjs.org/ + */ + +function peg$subclass$2(child, parent) { + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); +} + +function peg$SyntaxError$2(message, expected, found, location) { + this.message = message; + this.expected = expected; + this.found = found; + this.location = location; + this.name = "SyntaxError"; + + if (typeof Error.captureStackTrace === "function") { + Error.captureStackTrace(this, peg$SyntaxError$2); + } +} + +peg$subclass$2(peg$SyntaxError$2, Error); + +peg$SyntaxError$2.buildMessage = function(expected, found) { + var DESCRIBE_EXPECTATION_FNS = { + literal: function(expectation) { + return "\"" + literalEscape(expectation.text) + "\""; + }, + + "class": function(expectation) { + var escapedParts = "", + i; + + for (i = 0; i < expectation.parts.length; i++) { + escapedParts += expectation.parts[i] instanceof Array + ? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1]) + : classEscape(expectation.parts[i]); + } + + return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]"; + }, + + any: function(expectation) { + return "any character"; + }, + + end: function(expectation) { + return "end of input"; + }, + + other: function(expectation) { + return expectation.description; + } + }; + + function hex(ch) { + return ch.charCodeAt(0).toString(16).toUpperCase(); + } + + function literalEscape(s) { + return s + .replace(/\\/g, '\\\\') + .replace(/"/g, '\\"') + .replace(/\0/g, '\\0') + .replace(/\t/g, '\\t') + .replace(/\n/g, '\\n') + .replace(/\r/g, '\\r') + .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); }); + } + + function classEscape(s) { + return s + .replace(/\\/g, '\\\\') + .replace(/\]/g, '\\]') + .replace(/\^/g, '\\^') + .replace(/-/g, '\\-') + .replace(/\0/g, '\\0') + .replace(/\t/g, '\\t') + .replace(/\n/g, '\\n') + .replace(/\r/g, '\\r') + .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); }); + } + + function describeExpectation(expectation) { + return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); + } + + function describeExpected(expected) { + var descriptions = new Array(expected.length), + i, j; + + for (i = 0; i < expected.length; i++) { + descriptions[i] = describeExpectation(expected[i]); + } + + descriptions.sort(); + + if (descriptions.length > 0) { + for (i = 1, j = 1; i < descriptions.length; i++) { + if (descriptions[i - 1] !== descriptions[i]) { + descriptions[j] = descriptions[i]; + j++; + } + } + descriptions.length = j; + } + + switch (descriptions.length) { + case 1: + return descriptions[0]; + + case 2: + return descriptions[0] + " or " + descriptions[1]; + + default: + return descriptions.slice(0, -1).join(", ") + + ", or " + + descriptions[descriptions.length - 1]; + } + } + + function describeFound(found) { + return found ? "\"" + literalEscape(found) + "\"" : "end of input"; + } + + return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; +}; + +function peg$parse$2(input, options) { + options = options !== void 0 ? options : {}; + + var peg$FAILED = {}, + + peg$startRuleFunctions = { TopTypeExpr: peg$parseTopTypeExpr, NamepathExpr: peg$parseNamepathExpr, BroadNamepathExpr: peg$parseBroadNamepathExpr, ExternalNameExpr: peg$parseExternalNameExpr, ModuleNameExpr: peg$parseModuleNameExpr }, + peg$startRuleFunction = peg$parseTopTypeExpr, + + peg$c0 = function(expr) { + return expr; + }, + peg$c1 = /^[ \t]/, + peg$c2 = peg$classExpectation([" ", "\t"], false, false), + peg$c3 = /^[\r]/, + peg$c4 = peg$classExpectation(["\r"], false, false), + peg$c5 = /^[\n]/, + peg$c6 = peg$classExpectation(["\n"], false, false), + peg$c7 = /^[a-zA-Z_$]/, + peg$c8 = peg$classExpectation([["a", "z"], ["A", "Z"], "_", "$"], false, false), + peg$c9 = /^[a-zA-Z0-9_$]/, + peg$c10 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$"], false, false), + peg$c11 = "event:", + peg$c12 = peg$literalExpectation("event:", false), + peg$c13 = function(rootOwner, memberPartWithOperators) { + return memberPartWithOperators.reduce(function(owner, tokens) { + const operatorType = tokens[1]; + const eventNamespace = tokens[3]; + const MemberName = tokens[5]; + const {quoteStyle, name: memberName} = MemberName; + + switch (operatorType) { + case NamepathOperatorType.MEMBER: + return { + type: NodeType.MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + case NamepathOperatorType.INSTANCE_MEMBER: + return { + type: NodeType.INSTANCE_MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + case NamepathOperatorType.INNER_MEMBER: + return { + type: NodeType.INNER_MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + /* istanbul ignore next */ + default: + throw new Error('Unexpected operator type: "' + operatorType + '"'); + } + }, rootOwner); + }, + peg$c14 = /^[a-zA-Z0-9_$\-]/, + peg$c15 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$", "-"], false, false), + peg$c16 = function(name) { + return { + type: NodeType.NAME, + name + }; + }, + peg$c17 = "'", + peg$c18 = peg$literalExpectation("'", false), + peg$c19 = /^[^\\']/, + peg$c20 = peg$classExpectation(["\\", "'"], true, false), + peg$c21 = "\\", + peg$c22 = peg$literalExpectation("\\", false), + peg$c23 = peg$anyExpectation(), + peg$c24 = function(name) { + return { + quoteStyle: 'single', + name: name.replace(/\\'/g, "'") + .replace(/\\\\/gu, '\\') + }; + }, + peg$c25 = "\"", + peg$c26 = peg$literalExpectation("\"", false), + peg$c27 = /^[^\\"]/, + peg$c28 = peg$classExpectation(["\\", "\""], true, false), + peg$c29 = function(name) { + return { + quoteStyle: 'double', + name: name.replace(/\\"/gu, '"') + .replace(/\\\\/gu, '\\') + }; + }, + peg$c30 = function(name) { + return { + quoteStyle: 'none', + name + }; + }, + peg$c31 = ".", + peg$c32 = peg$literalExpectation(".", false), + peg$c34 = function() { + return NamepathOperatorType.MEMBER; + }, + peg$c35 = "~", + peg$c36 = peg$literalExpectation("~", false), + peg$c37 = function() { + return NamepathOperatorType.INNER_MEMBER; + }, + peg$c38 = "#", + peg$c39 = peg$literalExpectation("#", false), + peg$c40 = function() { + return NamepathOperatorType.INSTANCE_MEMBER; + }, + peg$c41 = "external", + peg$c42 = peg$literalExpectation("external", false), + peg$c43 = ":", + peg$c44 = peg$literalExpectation(":", false), + peg$c45 = function(external, memberPartWithOperators) { + return memberPartWithOperators.reduce(function(owner, tokens) { + const operatorType = tokens[1]; + const eventNamespace = tokens[3]; + const MemberName = tokens[5]; + const {quoteStyle, name: memberName} = MemberName; + + switch (operatorType) { + case NamepathOperatorType.MEMBER: + return { + type: NodeType.MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + case NamepathOperatorType.INSTANCE_MEMBER: + return { + type: NodeType.INSTANCE_MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + case NamepathOperatorType.INNER_MEMBER: + return { + type: NodeType.INNER_MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + /* istanbul ignore next */ + default: + throw new Error('Unexpected operator type: "' + operatorType + '"'); + } + }, Object.assign({ + type: NodeType.EXTERNAL + }, external)); + }, + peg$c46 = "module", + peg$c47 = peg$literalExpectation("module", false), + peg$c48 = function(value) { + return { + type: NodeType.MODULE, + value, + }; + }, + peg$c49 = function(rootOwner, memberPartWithOperators) { + return memberPartWithOperators.reduce(function(owner, tokens) { + const operatorType = tokens[1]; + const eventNamespace = tokens[3]; + const MemberName = tokens[5]; + const {quoteStyle, name: memberName} = MemberName; + + switch (operatorType) { + case NamepathOperatorType.MEMBER: + return { + type: NodeType.MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + case NamepathOperatorType.INSTANCE_MEMBER: + return { + type: NodeType.INSTANCE_MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + case NamepathOperatorType.INNER_MEMBER: + return { + type: NodeType.INNER_MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + /* istanbul ignore next */ + default: + throw new Error('Unexpected operator type: "' + operatorType + '"'); + } + }, rootOwner); + }, + peg$c50 = function(path) { + return { + quoteStyle: 'single', + type: NodeType.FILE_PATH, + path: path.replace(/\\'/g, "'") + .replace(/\\\\/gu, '\\') + }; + }, + peg$c51 = function(path) { + return { + quoteStyle: 'double', + type: NodeType.FILE_PATH, + path: path.replace(/\\"/gu, '"') + .replace(/\\\\/gu, '\\') + }; + }, + peg$c52 = /^[a-zA-Z0-9_$\/\-]/, + peg$c53 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$", "/", "-"], false, false), + peg$c54 = function(path) { + return { + quoteStyle: 'none', + type: NodeType.FILE_PATH, + path, + }; + }, + peg$c55 = "*", + peg$c56 = peg$literalExpectation("*", false), + peg$c57 = function() { + return { type: NodeType.ANY }; + }, + peg$c58 = "?", + peg$c59 = peg$literalExpectation("?", false), + peg$c60 = function() { + return { type: NodeType.UNKNOWN }; + }, + peg$c61 = function(value) { + return { + type: NodeType.STRING_VALUE, + quoteStyle: 'double', + string: value.replace(/\\"/gu, '"') + .replace(/\\\\/gu, '\\') + }; + }, + peg$c62 = function(value) { + return { + type: NodeType.STRING_VALUE, + quoteStyle: 'single', + string: value.replace(/\\'/g, "'") + .replace(/\\\\/gu, '\\') + }; + }, + peg$c63 = function(value) { + return { + type: NodeType.NUMBER_VALUE, + number: value + }; + }, + peg$c64 = "+", + peg$c65 = peg$literalExpectation("+", false), + peg$c66 = "-", + peg$c67 = peg$literalExpectation("-", false), + peg$c68 = /^[0-9]/, + peg$c69 = peg$classExpectation([["0", "9"]], false, false), + peg$c70 = "e", + peg$c71 = peg$literalExpectation("e", false), + peg$c72 = "0b", + peg$c73 = peg$literalExpectation("0b", false), + peg$c74 = /^[01]/, + peg$c75 = peg$classExpectation(["0", "1"], false, false), + peg$c76 = "0o", + peg$c77 = peg$literalExpectation("0o", false), + peg$c78 = /^[0-7]/, + peg$c79 = peg$classExpectation([["0", "7"]], false, false), + peg$c80 = "0x", + peg$c81 = peg$literalExpectation("0x", false), + peg$c82 = /^[0-9a-fA-F]/, + peg$c83 = peg$classExpectation([["0", "9"], ["a", "f"], ["A", "F"]], false, false), + peg$c84 = "|", + peg$c85 = peg$literalExpectation("|", false), + peg$c86 = function(left, right) { + return { + type: NodeType.UNION, + left, + right, + }; + }, + peg$c87 = function(operator, operand) { + return { + type: NodeType.NULLABLE, + value: operand, + meta: { syntax: NullableTypeSyntax.PREFIX_QUESTION_MARK }, + }; + }, + peg$c88 = "!", + peg$c89 = peg$literalExpectation("!", false), + peg$c90 = function(operator, operand) { + return { + type: NodeType.NOT_NULLABLE, + value: operand, + meta: { syntax: NotNullableTypeSyntax.PREFIX_BANG }, + }; + }, + peg$c91 = "=", + peg$c92 = peg$literalExpectation("=", false), + peg$c93 = function(operator, operand) { + return { + type: NodeType.OPTIONAL, + value: operand, + meta: { syntax: OptionalTypeSyntax.PREFIX_EQUALS_SIGN }, + }; + }, + peg$c94 = function(operand, operator) { + return { + type: NodeType.NULLABLE, + value: operand, + meta: { syntax: NullableTypeSyntax.SUFFIX_QUESTION_MARK }, + }; + }, + peg$c95 = function(operand, operator) { + return { + type: NodeType.NOT_NULLABLE, + value: operand, + meta: { syntax: NotNullableTypeSyntax.SUFFIX_BANG }, + }; + }, + peg$c96 = function(operand, operator) { + return { + type: NodeType.OPTIONAL, + value: operand, + meta: { syntax: OptionalTypeSyntax.SUFFIX_EQUALS_SIGN }, + }; + }, + peg$c97 = function(operand, syntax, params) { + return { + type: NodeType.GENERIC, + subject: operand, + objects: params, + meta: { syntax }, + }; + }, + peg$c98 = ",", + peg$c99 = peg$literalExpectation(",", false), + peg$c100 = function(first, restsWithComma) { + return restsWithComma.reduce(function(params, tokens) { + return params.concat([tokens[3]]); + }, [first]); + }, + peg$c101 = ".<", + peg$c102 = peg$literalExpectation(".<", false), + peg$c103 = function() { + return GenericTypeSyntax.ANGLE_BRACKET_WITH_DOT; + }, + peg$c104 = "<", + peg$c105 = peg$literalExpectation("<", false), + peg$c106 = function() { + return GenericTypeSyntax.ANGLE_BRACKET; + }, + peg$c107 = ">", + peg$c108 = peg$literalExpectation(">", false), + peg$c109 = "[", + peg$c110 = peg$literalExpectation("[", false), + peg$c111 = "]", + peg$c112 = peg$literalExpectation("]", false), + peg$c113 = function(operand, brackets) { + return brackets.reduce(function(operand) { + return { + type: NodeType.GENERIC, + subject: { + type: NodeType.NAME, + name: 'Array' + }, + objects: [ operand ], + meta: { syntax: GenericTypeSyntax.SQUARE_BRACKET }, + }; + }, operand); + }, + peg$c114 = "function", + peg$c115 = peg$literalExpectation("function", false), + peg$c116 = function(paramsPart, returnedTypePart) { + const returnedTypeNode = returnedTypePart ? returnedTypePart[2] : null; + + return { + type: NodeType.FUNCTION, + params: paramsPart.params, + returns: returnedTypeNode, + this: paramsPart.modifier.nodeThis, + new: paramsPart.modifier.nodeNew, + }; + }, + peg$c117 = "(", + peg$c118 = peg$literalExpectation("(", false), + peg$c119 = ")", + peg$c120 = peg$literalExpectation(")", false), + peg$c121 = function(modifier, params) { + return { params, modifier }; + }, + peg$c122 = function(modifier) { + return { params: [], modifier }; + }, + peg$c123 = function() { + return { params: [], modifier: { nodeThis: null, nodeNew: null } }; + }, + peg$c124 = function(params) { + return { params, modifier: { nodeThis: null, nodeNew: null } }; + }, + peg$c125 = "this", + peg$c126 = peg$literalExpectation("this", false), + peg$c127 = function(modifierThis) { + return { nodeThis: modifierThis[4], nodeNew: null }; + }, + peg$c128 = "new", + peg$c129 = peg$literalExpectation("new", false), + peg$c130 = function(modifierNew) { + return { nodeThis: null, nodeNew: modifierNew[4] }; + }, + peg$c131 = function(paramsWithComma, lastParam) { + return paramsWithComma.reduceRight(function(params, tokens) { + const [param] = tokens; + return [param].concat(params); + }, lastParam ? [lastParam] : []); + }, + peg$c132 = "{", + peg$c133 = peg$literalExpectation("{", false), + peg$c134 = "}", + peg$c135 = peg$literalExpectation("}", false), + peg$c136 = function(entries) { + return { + type: NodeType.RECORD, + entries: entries || [], + }; + }, + peg$c137 = ";", + peg$c138 = peg$literalExpectation(";", false), + peg$c139 = function(first, restWithComma) { + return restWithComma.reduce(function(entries, tokens) { + const entry = tokens[2]; + return entries.concat([entry]); + }, [first]); + }, + peg$c140 = "readonly", + peg$c141 = peg$literalExpectation("readonly", false), + peg$c142 = function(readonly, keyInfo, optional, value) { + const {quoteStyle, key} = keyInfo; + return { + type: NodeType.RECORD_ENTRY, + key, + quoteStyle, + value: + optional === '?' ? { + type: NodeType.OPTIONAL, + value, + meta: { syntax: OptionalTypeSyntax.SUFFIX_KEY_QUESTION_MARK }, + } : + value, + readonly: Boolean(readonly) + }; + }, + peg$c143 = function(readonly, keyInfo) { + const {quoteStyle, key} = keyInfo; + return { + type: NodeType.RECORD_ENTRY, + key, + quoteStyle, + value: null, + readonly: Boolean(readonly) + }; + }, + peg$c144 = function(key) { + return { + quoteStyle: 'double', + key: key.replace(/\\"/gu, '"') + .replace(/\\\\/gu, '\\') + }; + }, + peg$c145 = function(key) { + return { + quoteStyle: 'single', + key: key.replace(/\\'/g, "'") + .replace(/\\\\/gu, '\\') + }; + }, + peg$c146 = function(key) { + return { + quoteStyle: 'none', + key + }; + }, + peg$c147 = function(wrapped) { + return { + type: NodeType.PARENTHESIS, + value: wrapped, + }; + }, + peg$c148 = "...", + peg$c149 = peg$literalExpectation("...", false), + peg$c150 = function(operand) { + return { + type: NodeType.VARIADIC, + value: operand, + meta: { syntax: VariadicTypeSyntax.PREFIX_DOTS }, + }; + }, + peg$c151 = function(operand) { + return { + type: NodeType.VARIADIC, + value: operand, + meta: { syntax: VariadicTypeSyntax.SUFFIX_DOTS }, + }; + }, + peg$c152 = function() { + return { + type: NodeType.VARIADIC, + value: { type: NodeType.ANY }, + meta: { syntax: VariadicTypeSyntax.ONLY_DOTS }, + }; + }, + + peg$currPos = 0, + peg$posDetailsCache = [{ line: 1, column: 1 }], + peg$maxFailPos = 0, + peg$maxFailExpected = [], + peg$resultsCache = {}, + + peg$result; + + if ("startRule" in options) { + if (!(options.startRule in peg$startRuleFunctions)) { + throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); + } + + peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; + } + + function peg$literalExpectation(text, ignoreCase) { + return { type: "literal", text: text, ignoreCase: ignoreCase }; + } + + function peg$classExpectation(parts, inverted, ignoreCase) { + return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase }; + } + + function peg$anyExpectation() { + return { type: "any" }; + } + + function peg$endExpectation() { + return { type: "end" }; + } + + function peg$computePosDetails(pos) { + var details = peg$posDetailsCache[pos], p; + + if (details) { + return details; + } else { + p = pos - 1; + while (!peg$posDetailsCache[p]) { + p--; + } + + details = peg$posDetailsCache[p]; + details = { + line: details.line, + column: details.column + }; + + while (p < pos) { + if (input.charCodeAt(p) === 10) { + details.line++; + details.column = 1; + } else { + details.column++; + } + + p++; + } + + peg$posDetailsCache[pos] = details; + return details; + } + } + + function peg$computeLocation(startPos, endPos) { + var startPosDetails = peg$computePosDetails(startPos), + endPosDetails = peg$computePosDetails(endPos); + + return { + start: { + offset: startPos, + line: startPosDetails.line, + column: startPosDetails.column + }, + end: { + offset: endPos, + line: endPosDetails.line, + column: endPosDetails.column + } + }; + } + + function peg$fail(expected) { + if (peg$currPos < peg$maxFailPos) { return; } + + if (peg$currPos > peg$maxFailPos) { + peg$maxFailPos = peg$currPos; + peg$maxFailExpected = []; + } + + peg$maxFailExpected.push(expected); + } + + function peg$buildStructuredError(expected, found, location) { + return new peg$SyntaxError$2( + peg$SyntaxError$2.buildMessage(expected, found), + expected, + found, + location + ); + } + + function peg$parseTopTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 69 + 0, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parse_(); + if (s1 !== peg$FAILED) { + s2 = peg$parseVariadicTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseUnionTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseUnaryUnionTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseArrayTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseGenericTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseRecordTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseFunctionTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseBroadNamepathExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseParenthesizedExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseValueExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseAnyTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + if (s2 !== peg$FAILED) { + s3 = peg$parse_(); + if (s3 !== peg$FAILED) { + s1 = peg$c0(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseWS() { + var s0, s1, s2; + + var key = peg$currPos * 69 + 1, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + if (peg$c1.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + { peg$fail(peg$c2); } + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (peg$c3.test(input.charAt(peg$currPos))) { + s1 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c4); } + } + if (s1 === peg$FAILED) { + s1 = null; + } + if (s1 !== peg$FAILED) { + if (peg$c5.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c6); } + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parse_() { + var s0, s1; + + var key = peg$currPos * 69 + 2, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = []; + s1 = peg$parseWS(); + while (s1 !== peg$FAILED) { + s0.push(s1); + s1 = peg$parseWS(); + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parse__() { + var s0, s1; + + var key = peg$currPos * 69 + 3, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = []; + s1 = peg$parseWS(); + if (s1 !== peg$FAILED) { + while (s1 !== peg$FAILED) { + s0.push(s1); + s1 = peg$parseWS(); + } + } else { + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseJsIdentifier() { + var s0, s1, s2, s3, s4; + + var key = peg$currPos * 69 + 4, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (peg$c7.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c8); } + } + if (s2 !== peg$FAILED) { + s3 = []; + if (peg$c9.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c10); } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c9.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c10); } + } + } + if (s3 !== peg$FAILED) { + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseNamepathExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + var key = peg$currPos * 69 + 5, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseParenthesizedExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseTypeNameExprJsDocFlavored(); + } + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseInfixNamepathOperator(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c11) { + s7 = peg$c11; + peg$currPos += 6; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c12); } + } + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseMemberName(); + if (s9 !== peg$FAILED) { + s4 = [s4, s5, s6, s7, s8, s9]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseInfixNamepathOperator(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c11) { + s7 = peg$c11; + peg$currPos += 6; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c12); } + } + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseMemberName(); + if (s9 !== peg$FAILED) { + s4 = [s4, s5, s6, s7, s8, s9]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s1 = peg$c13(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseTypeNameExprJsDocFlavored() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 69 + 6, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + s2 = peg$currPos; + if (peg$c7.test(input.charAt(peg$currPos))) { + s3 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c8); } + } + if (s3 !== peg$FAILED) { + s4 = []; + if (peg$c14.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c15); } + } + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c14.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c15); } + } + } + if (s4 !== peg$FAILED) { + s3 = [s3, s4]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = input.substring(s1, peg$currPos); + } else { + s1 = s2; + } + if (s1 !== peg$FAILED) { + s1 = peg$c16(s1); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseMemberName() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 69 + 7, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 39) { + s1 = peg$c17; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 39) { + s3 = peg$c17; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c24(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 34) { + s1 = peg$c25; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 34) { + s3 = peg$c25; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c29(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parseJsIdentifier(); + if (s1 !== peg$FAILED) { + s1 = peg$c30(s1); + } + s0 = s1; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseInfixNamepathOperator() { + var s0; + + var key = peg$currPos * 69 + 8, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseMemberTypeOperator(); + if (s0 === peg$FAILED) { + s0 = peg$parseInstanceMemberTypeOperator(); + if (s0 === peg$FAILED) { + s0 = peg$parseInnerMemberTypeOperator(); + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseMemberTypeOperator() { + var s0, s1; + + var key = peg$currPos * 69 + 10, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 46) { + s1 = peg$c31; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c32); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c34(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseInnerMemberTypeOperator() { + var s0, s1; + + var key = peg$currPos * 69 + 11, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 126) { + s1 = peg$c35; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c36); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c37(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseInstanceMemberTypeOperator() { + var s0, s1; + + var key = peg$currPos * 69 + 12, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 35) { + s1 = peg$c38; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c39); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c40(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseBroadNamepathExpr() { + var s0; + + var key = peg$currPos * 69 + 13, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseExternalNameExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseModuleNameExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNamepathExpr(); + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseExternalNameExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13; + + var key = peg$currPos * 69 + 14, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c41) { + s1 = peg$c41; + peg$currPos += 8; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c42); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c43; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseMemberName(); + if (s5 !== peg$FAILED) { + s6 = []; + s7 = peg$currPos; + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseInfixNamepathOperator(); + if (s9 !== peg$FAILED) { + s10 = peg$parse_(); + if (s10 !== peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c11) { + s11 = peg$c11; + peg$currPos += 6; + } else { + s11 = peg$FAILED; + { peg$fail(peg$c12); } + } + if (s11 === peg$FAILED) { + s11 = null; + } + if (s11 !== peg$FAILED) { + s12 = peg$parse_(); + if (s12 !== peg$FAILED) { + s13 = peg$parseMemberName(); + if (s13 !== peg$FAILED) { + s8 = [s8, s9, s10, s11, s12, s13]; + s7 = s8; + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + while (s7 !== peg$FAILED) { + s6.push(s7); + s7 = peg$currPos; + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseInfixNamepathOperator(); + if (s9 !== peg$FAILED) { + s10 = peg$parse_(); + if (s10 !== peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c11) { + s11 = peg$c11; + peg$currPos += 6; + } else { + s11 = peg$FAILED; + { peg$fail(peg$c12); } + } + if (s11 === peg$FAILED) { + s11 = null; + } + if (s11 !== peg$FAILED) { + s12 = peg$parse_(); + if (s12 !== peg$FAILED) { + s13 = peg$parseMemberName(); + if (s13 !== peg$FAILED) { + s8 = [s8, s9, s10, s11, s12, s13]; + s7 = s8; + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } + if (s6 !== peg$FAILED) { + s1 = peg$c45(s5, s6); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseModuleNameExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 69 + 15, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 6) === peg$c46) { + s1 = peg$c46; + peg$currPos += 6; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c47); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c43; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseModulePathExpr(); + if (s5 !== peg$FAILED) { + s1 = peg$c48(s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseModulePathExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + var key = peg$currPos * 69 + 16, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseFilePathExpr(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseInfixNamepathOperator(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c11) { + s7 = peg$c11; + peg$currPos += 6; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c12); } + } + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseMemberName(); + if (s9 !== peg$FAILED) { + s4 = [s4, s5, s6, s7, s8, s9]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseInfixNamepathOperator(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c11) { + s7 = peg$c11; + peg$currPos += 6; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c12); } + } + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseMemberName(); + if (s9 !== peg$FAILED) { + s4 = [s4, s5, s6, s7, s8, s9]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s1 = peg$c49(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFilePathExpr() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 69 + 17, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 39) { + s1 = peg$c17; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 39) { + s3 = peg$c17; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c50(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 34) { + s1 = peg$c25; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 34) { + s3 = peg$c25; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c51(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$currPos; + s2 = []; + if (peg$c52.test(input.charAt(peg$currPos))) { + s3 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c53); } + } + if (s3 !== peg$FAILED) { + while (s3 !== peg$FAILED) { + s2.push(s3); + if (peg$c52.test(input.charAt(peg$currPos))) { + s3 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c53); } + } + } + } else { + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = input.substring(s1, peg$currPos); + } else { + s1 = s2; + } + if (s1 !== peg$FAILED) { + s1 = peg$c54(s1); + } + s0 = s1; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseAnyTypeExpr() { + var s0, s1; + + var key = peg$currPos * 69 + 18, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 42) { + s1 = peg$c55; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c56); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c57(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseUnknownTypeExpr() { + var s0, s1; + + var key = peg$currPos * 69 + 19, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 63) { + s1 = peg$c58; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c59); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c60(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseValueExpr() { + var s0; + + var key = peg$currPos * 69 + 20, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseStringLiteralExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNumberLiteralExpr(); + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseStringLiteralExpr() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 69 + 21, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 34) { + s1 = peg$c25; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 34) { + s3 = peg$c25; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c61(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 39) { + s1 = peg$c17; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 39) { + s3 = peg$c17; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c62(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseNumberLiteralExpr() { + var s0, s1; + + var key = peg$currPos * 69 + 22, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseBinNumberLiteralExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseOctNumberLiteralExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseHexNumberLiteralExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseDecimalNumberLiteralExpr(); + } + } + } + if (s1 !== peg$FAILED) { + s1 = peg$c63(s1); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseDecimalNumberLiteralExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 69 + 23, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 43) { + s2 = peg$c64; + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c65); } + } + if (s2 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 45) { + s2 = peg$c66; + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c67); } + } + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + s3 = peg$parseUnsignedDecimalNumberLiteralExpr(); + if (s3 !== peg$FAILED) { + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseUnsignedDecimalNumberLiteralExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 69 + 24, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + s2 = peg$currPos; + s3 = []; + if (peg$c68.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c69); } + } + if (s4 !== peg$FAILED) { + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c68.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c69); } + } + } + } else { + s3 = peg$FAILED; + } + if (s3 !== peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 46) { + s5 = peg$c31; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c32); } + } + if (s5 !== peg$FAILED) { + s6 = []; + if (peg$c68.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c69); } + } + if (s7 !== peg$FAILED) { + while (s7 !== peg$FAILED) { + s6.push(s7); + if (peg$c68.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c69); } + } + } + } else { + s6 = peg$FAILED; + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = null; + } + if (s4 !== peg$FAILED) { + s3 = [s3, s4]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 === peg$FAILED) { + s2 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 46) { + s3 = peg$c31; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c32); } + } + if (s3 !== peg$FAILED) { + s4 = []; + if (peg$c68.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c69); } + } + if (s5 !== peg$FAILED) { + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c68.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c69); } + } + } + } else { + s4 = peg$FAILED; + } + if (s4 !== peg$FAILED) { + s3 = [s3, s4]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s3 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 101) { + s4 = peg$c70; + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c71); } + } + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 43) { + s5 = peg$c64; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c65); } + } + if (s5 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 45) { + s5 = peg$c66; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c67); } + } + } + if (s5 === peg$FAILED) { + s5 = null; + } + if (s5 !== peg$FAILED) { + s6 = []; + if (peg$c68.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c69); } + } + if (s7 !== peg$FAILED) { + while (s7 !== peg$FAILED) { + s6.push(s7); + if (peg$c68.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c69); } + } + } + } else { + s6 = peg$FAILED; + } + if (s6 !== peg$FAILED) { + s4 = [s4, s5, s6]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = null; + } + if (s3 !== peg$FAILED) { + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseBinNumberLiteralExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 69 + 25, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 45) { + s2 = peg$c66; + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c67); } + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c72) { + s3 = peg$c72; + peg$currPos += 2; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c73); } + } + if (s3 !== peg$FAILED) { + s4 = []; + if (peg$c74.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c75); } + } + if (s5 !== peg$FAILED) { + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c74.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c75); } + } + } + } else { + s4 = peg$FAILED; + } + if (s4 !== peg$FAILED) { + s2 = [s2, s3, s4]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseOctNumberLiteralExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 69 + 26, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 45) { + s2 = peg$c66; + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c67); } + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c76) { + s3 = peg$c76; + peg$currPos += 2; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c77); } + } + if (s3 !== peg$FAILED) { + s4 = []; + if (peg$c78.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c79); } + } + if (s5 !== peg$FAILED) { + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c78.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c79); } + } + } + } else { + s4 = peg$FAILED; + } + if (s4 !== peg$FAILED) { + s2 = [s2, s3, s4]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseHexNumberLiteralExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 69 + 27, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 45) { + s2 = peg$c66; + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c67); } + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c80) { + s3 = peg$c80; + peg$currPos += 2; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c81); } + } + if (s3 !== peg$FAILED) { + s4 = []; + if (peg$c82.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c83); } + } + if (s5 !== peg$FAILED) { + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c82.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c83); } + } + } + } else { + s4 = peg$FAILED; + } + if (s4 !== peg$FAILED) { + s2 = [s2, s3, s4]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseUnionTypeExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 69 + 28, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseUnionTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 124) { + s3 = peg$c84; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c85); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseUnionTypeExpr(); + if (s5 === peg$FAILED) { + s5 = peg$parseUnionTypeExprOperand(); + } + if (s5 !== peg$FAILED) { + s1 = peg$c86(s1, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseUnionTypeExprOperand() { + var s0; + + var key = peg$currPos * 69 + 29, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseUnaryUnionTypeExpr() { + var s0; + + var key = peg$currPos * 69 + 30, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseSuffixUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parsePrefixUnaryUnionTypeExpr(); + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixUnaryUnionTypeExpr() { + var s0; + + var key = peg$currPos * 69 + 31, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parsePrefixOptionalTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parsePrefixNotNullableTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parsePrefixNullableTypeExpr(); + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixUnaryUnionTypeExprOperand() { + var s0; + + var key = peg$currPos * 69 + 32, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixNullableTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 69 + 33, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 63) { + s1 = peg$c58; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c59); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); + if (s3 !== peg$FAILED) { + s1 = peg$c87(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixNotNullableTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 69 + 34, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 33) { + s1 = peg$c88; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c89); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); + if (s3 !== peg$FAILED) { + s1 = peg$c90(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixOptionalTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 69 + 35, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 61) { + s1 = peg$c91; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c92); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); + if (s3 !== peg$FAILED) { + s1 = peg$c93(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixUnaryUnionTypeExpr() { + var s0; + + var key = peg$currPos * 69 + 36, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseSuffixOptionalTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseSuffixNullableTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseSuffixNotNullableTypeExpr(); + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixUnaryUnionTypeExprOperand() { + var s0; + + var key = peg$currPos * 69 + 37, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parsePrefixUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixNullableTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 69 + 38, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 63) { + s3 = peg$c58; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c59); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c94(s1); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixNotNullableTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 69 + 39, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 33) { + s3 = peg$c88; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c89); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c95(s1); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixOptionalTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 69 + 40, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseSuffixNullableTypeExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseSuffixNotNullableTypeExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 61) { + s3 = peg$c91; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c92); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c96(s1); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 69 + 41, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseGenericTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseGenericTypeStartToken(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseGenericTypeExprTypeParamList(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseGenericTypeEndToken(); + if (s7 !== peg$FAILED) { + s1 = peg$c97(s1, s3, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeExprOperand() { + var s0; + + var key = peg$currPos * 69 + 42, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeExprTypeParamOperand() { + var s0; + + var key = peg$currPos * 69 + 43, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeExprTypeParamList() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 69 + 44, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseGenericTypeExprTypeParamOperand(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c98; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c99); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseGenericTypeExprTypeParamOperand(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c98; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c99); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseGenericTypeExprTypeParamOperand(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s1 = peg$c100(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeStartToken() { + var s0; + + var key = peg$currPos * 69 + 45, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseGenericTypeEcmaScriptFlavoredStartToken(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeTypeScriptFlavoredStartToken(); + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeEcmaScriptFlavoredStartToken() { + var s0, s1; + + var key = peg$currPos * 69 + 46, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 2) === peg$c101) { + s1 = peg$c101; + peg$currPos += 2; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c102); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c103(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeTypeScriptFlavoredStartToken() { + var s0, s1; + + var key = peg$currPos * 69 + 47, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 60) { + s1 = peg$c104; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c105); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c106(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeEndToken() { + var s0; + + var key = peg$currPos * 69 + 48, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + if (input.charCodeAt(peg$currPos) === 62) { + s0 = peg$c107; + peg$currPos++; + } else { + s0 = peg$FAILED; + { peg$fail(peg$c108); } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseArrayTypeExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 69 + 49, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseArrayTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 91) { + s5 = peg$c109; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c110); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s7 = peg$c111; + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c112); } + } + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 !== peg$FAILED) { + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 91) { + s5 = peg$c109; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c110); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s7 = peg$c111; + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c112); } + } + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + } else { + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = peg$c113(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseArrayTypeExprOperand() { + var s0; + + var key = peg$currPos * 69 + 50, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8; + + var key = peg$currPos * 69 + 51, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c114) { + s1 = peg$c114; + peg$currPos += 8; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c115); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseFunctionTypeExprParamsList(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 58) { + s6 = peg$c43; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s6 !== peg$FAILED) { + s7 = peg$parse_(); + if (s7 !== peg$FAILED) { + s8 = peg$parseFunctionTypeExprReturnableOperand(); + if (s8 !== peg$FAILED) { + s6 = [s6, s7, s8]; + s5 = s6; + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + if (s5 === peg$FAILED) { + s5 = null; + } + if (s5 !== peg$FAILED) { + s1 = peg$c116(s3, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExprParamsList() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + var key = peg$currPos * 69 + 52, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c117; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c118); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseFunctionTypeExprModifier(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c98; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c99); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseFunctionTypeExprParams(); + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s9 = peg$c119; + peg$currPos++; + } else { + s9 = peg$FAILED; + { peg$fail(peg$c120); } + } + if (s9 !== peg$FAILED) { + s1 = peg$c121(s3, s7); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c117; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c118); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseFunctionTypeExprModifier(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s5 = peg$c119; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c120); } + } + if (s5 !== peg$FAILED) { + s1 = peg$c122(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c117; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c118); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s3 = peg$c119; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c120); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c123(); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c117; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c118); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseFunctionTypeExprParams(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s5 = peg$c119; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c120); } + } + if (s5 !== peg$FAILED) { + s1 = peg$c124(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExprModifier() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 69 + 53, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.substr(peg$currPos, 4) === peg$c125) { + s2 = peg$c125; + peg$currPos += 4; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c126); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parse_(); + if (s3 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s4 = peg$c43; + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseFunctionTypeExprParamOperand(); + if (s6 !== peg$FAILED) { + s2 = [s2, s3, s4, s5, s6]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s1 = peg$c127(s1); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$currPos; + if (input.substr(peg$currPos, 3) === peg$c128) { + s2 = peg$c128; + peg$currPos += 3; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c129); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parse_(); + if (s3 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s4 = peg$c43; + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseFunctionTypeExprParamOperand(); + if (s6 !== peg$FAILED) { + s2 = [s2, s3, s4, s5, s6]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s1 = peg$c130(s1); + } + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExprParams() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 69 + 54, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = []; + s2 = peg$currPos; + s3 = peg$parseFunctionTypeExprParamOperand(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c98; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c99); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s3 = [s3, s4, s5, s6]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + while (s2 !== peg$FAILED) { + s1.push(s2); + s2 = peg$currPos; + s3 = peg$parseFunctionTypeExprParamOperand(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c98; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c99); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s3 = [s3, s4, s5, s6]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseVariadicTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseVariadicTypeExprOperand(); + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + s1 = peg$c131(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExprParamOperand() { + var s0; + + var key = peg$currPos * 69 + 55, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExprReturnableOperand() { + var s0; + + var key = peg$currPos * 69 + 56, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parsePrefixUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseRecordTypeExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 69 + 57, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 123) { + s1 = peg$c132; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c133); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseRecordTypeExprEntries(); + if (s3 === peg$FAILED) { + s3 = null; + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 125) { + s5 = peg$c134; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c135); } + } + if (s5 !== peg$FAILED) { + s1 = peg$c136(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseRecordTypeExprEntries() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 69 + 58, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseRecordTypeExprEntry(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s6 = peg$c98; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c99); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 59) { + s6 = peg$c137; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c138); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + s5 = []; + if (peg$c1.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c2); } + } + while (s6 !== peg$FAILED) { + s5.push(s6); + if (peg$c1.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c2); } + } + } + if (s5 !== peg$FAILED) { + if (peg$c3.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c4); } + } + if (s6 === peg$FAILED) { + s6 = null; + } + if (s6 !== peg$FAILED) { + if (peg$c5.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c6); } + } + if (s7 !== peg$FAILED) { + s5 = [s5, s6, s7]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseRecordTypeExprEntry(); + if (s6 !== peg$FAILED) { + s4 = [s4, s5, s6]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s6 = peg$c98; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c99); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 59) { + s6 = peg$c137; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c138); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + s5 = []; + if (peg$c1.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c2); } + } + while (s6 !== peg$FAILED) { + s5.push(s6); + if (peg$c1.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c2); } + } + } + if (s5 !== peg$FAILED) { + if (peg$c3.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c4); } + } + if (s6 === peg$FAILED) { + s6 = null; + } + if (s6 !== peg$FAILED) { + if (peg$c5.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c6); } + } + if (s7 !== peg$FAILED) { + s5 = [s5, s6, s7]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseRecordTypeExprEntry(); + if (s6 !== peg$FAILED) { + s4 = [s4, s5, s6]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c98; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c99); } + } + if (s5 !== peg$FAILED) { + s4 = [s4, s5]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 59) { + s5 = peg$c137; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c138); } + } + if (s5 !== peg$FAILED) { + s4 = [s4, s5]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = peg$currPos; + s4 = []; + if (peg$c1.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c2); } + } + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c1.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c2); } + } + } + if (s4 !== peg$FAILED) { + if (peg$c3.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c4); } + } + if (s5 === peg$FAILED) { + s5 = null; + } + if (s5 !== peg$FAILED) { + if (peg$c5.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c6); } + } + if (s6 !== peg$FAILED) { + s4 = [s4, s5, s6]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + } + if (s3 === peg$FAILED) { + s3 = null; + } + if (s3 !== peg$FAILED) { + s1 = peg$c139(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseRecordTypeExprEntry() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8; + + var key = peg$currPos * 69 + 59, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c140) { + s2 = peg$c140; + peg$currPos += 8; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c141); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parse__(); + if (s3 !== peg$FAILED) { + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 === peg$FAILED) { + s1 = null; + } + if (s1 !== peg$FAILED) { + s2 = peg$parseRecordTypeExprEntryKey(); + if (s2 !== peg$FAILED) { + s3 = peg$parse_(); + if (s3 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 63) { + s4 = peg$c58; + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c59); } + } + if (s4 === peg$FAILED) { + s4 = null; + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s6 = peg$c43; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s6 !== peg$FAILED) { + s7 = peg$parse_(); + if (s7 !== peg$FAILED) { + s8 = peg$parseRecordTypeExprEntryOperand(); + if (s8 !== peg$FAILED) { + s1 = peg$c142(s1, s2, s4, s8); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c140) { + s2 = peg$c140; + peg$currPos += 8; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c141); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parse__(); + if (s3 !== peg$FAILED) { + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 === peg$FAILED) { + s1 = null; + } + if (s1 !== peg$FAILED) { + s2 = peg$parseRecordTypeExprEntryKey(); + if (s2 !== peg$FAILED) { + s1 = peg$c143(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseRecordTypeExprEntryKey() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 69 + 60, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 34) { + s1 = peg$c25; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 34) { + s3 = peg$c25; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c144(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 39) { + s1 = peg$c17; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 39) { + s3 = peg$c17; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c145(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$currPos; + s2 = peg$parseJsIdentifier(); + if (s2 === peg$FAILED) { + s2 = peg$parseUnsignedDecimalNumberLiteralExpr(); + } + if (s2 !== peg$FAILED) { + s1 = input.substring(s1, peg$currPos); + } else { + s1 = s2; + } + if (s1 !== peg$FAILED) { + s1 = peg$c146(s1); + } + s0 = s1; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseRecordTypeExprEntryOperand() { + var s0; + + var key = peg$currPos * 69 + 61, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseParenthesizedExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 69 + 62, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c117; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c118); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseParenthesizedExprOperand(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s5 = peg$c119; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c120); } + } + if (s5 !== peg$FAILED) { + s1 = peg$c147(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseParenthesizedExprOperand() { + var s0; + + var key = peg$currPos * 69 + 63, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseVariadicTypeExpr() { + var s0; + + var key = peg$currPos * 69 + 64, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parsePrefixVariadicTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseSuffixVariadicTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyVariadicTypeExpr(); + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixVariadicTypeExpr() { + var s0, s1, s2; + + var key = peg$currPos * 69 + 65, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 3) === peg$c148) { + s1 = peg$c148; + peg$currPos += 3; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c149); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseVariadicTypeExprOperand(); + if (s2 !== peg$FAILED) { + s1 = peg$c150(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixVariadicTypeExpr() { + var s0, s1, s2; + + var key = peg$currPos * 69 + 66, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseVariadicTypeExprOperand(); + if (s1 !== peg$FAILED) { + if (input.substr(peg$currPos, 3) === peg$c148) { + s2 = peg$c148; + peg$currPos += 3; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c149); } + } + if (s2 !== peg$FAILED) { + s1 = peg$c151(s1); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseAnyVariadicTypeExpr() { + var s0, s1; + + var key = peg$currPos * 69 + 67, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 3) === peg$c148) { + s1 = peg$c148; + peg$currPos += 3; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c149); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c152(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseVariadicTypeExprOperand() { + var s0; + + var key = peg$currPos * 69 + 68, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + + const meta = SyntaxType; + const { + GenericTypeSyntax, + VariadicTypeSyntax, OptionalTypeSyntax, + NullableTypeSyntax, NotNullableTypeSyntax, + } = meta; + const NodeType = NodeType_1; + + const NamepathOperatorType = { + MEMBER: 'MEMBER', + INNER_MEMBER: 'INNER_MEMBER', + INSTANCE_MEMBER: 'INSTANCE_MEMBER', + }; + + + peg$result = peg$startRuleFunction(); + + if (peg$result !== peg$FAILED && peg$currPos === input.length) { + return peg$result; + } else { + if (peg$result !== peg$FAILED && peg$currPos < input.length) { + peg$fail(peg$endExpectation()); + } + + throw peg$buildStructuredError( + peg$maxFailExpected, + peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, + peg$maxFailPos < input.length + ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) + : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) + ); + } +} + +var jsdoctypeJsdoc = { + SyntaxError: peg$SyntaxError$2, + parse: peg$parse$2 +}; + +/* + * Generated by PEG.js 0.10.0. + * + * http://pegjs.org/ + */ + +function peg$subclass$1(child, parent) { + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); +} + +function peg$SyntaxError$1(message, expected, found, location) { + this.message = message; + this.expected = expected; + this.found = found; + this.location = location; + this.name = "SyntaxError"; + + if (typeof Error.captureStackTrace === "function") { + Error.captureStackTrace(this, peg$SyntaxError$1); + } +} + +peg$subclass$1(peg$SyntaxError$1, Error); + +peg$SyntaxError$1.buildMessage = function(expected, found) { + var DESCRIBE_EXPECTATION_FNS = { + literal: function(expectation) { + return "\"" + literalEscape(expectation.text) + "\""; + }, + + "class": function(expectation) { + var escapedParts = "", + i; + + for (i = 0; i < expectation.parts.length; i++) { + escapedParts += expectation.parts[i] instanceof Array + ? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1]) + : classEscape(expectation.parts[i]); + } + + return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]"; + }, + + any: function(expectation) { + return "any character"; + }, + + end: function(expectation) { + return "end of input"; + }, + + other: function(expectation) { + return expectation.description; + } + }; + + function hex(ch) { + return ch.charCodeAt(0).toString(16).toUpperCase(); + } + + function literalEscape(s) { + return s + .replace(/\\/g, '\\\\') + .replace(/"/g, '\\"') + .replace(/\0/g, '\\0') + .replace(/\t/g, '\\t') + .replace(/\n/g, '\\n') + .replace(/\r/g, '\\r') + .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); }); + } + + function classEscape(s) { + return s + .replace(/\\/g, '\\\\') + .replace(/\]/g, '\\]') + .replace(/\^/g, '\\^') + .replace(/-/g, '\\-') + .replace(/\0/g, '\\0') + .replace(/\t/g, '\\t') + .replace(/\n/g, '\\n') + .replace(/\r/g, '\\r') + .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); }); + } + + function describeExpectation(expectation) { + return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); + } + + function describeExpected(expected) { + var descriptions = new Array(expected.length), + i, j; + + for (i = 0; i < expected.length; i++) { + descriptions[i] = describeExpectation(expected[i]); + } + + descriptions.sort(); + + if (descriptions.length > 0) { + for (i = 1, j = 1; i < descriptions.length; i++) { + if (descriptions[i - 1] !== descriptions[i]) { + descriptions[j] = descriptions[i]; + j++; + } + } + descriptions.length = j; + } + + switch (descriptions.length) { + case 1: + return descriptions[0]; + + case 2: + return descriptions[0] + " or " + descriptions[1]; + + default: + return descriptions.slice(0, -1).join(", ") + + ", or " + + descriptions[descriptions.length - 1]; + } + } + + function describeFound(found) { + return found ? "\"" + literalEscape(found) + "\"" : "end of input"; + } + + return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; +}; + +function peg$parse$1(input, options) { + options = options !== void 0 ? options : {}; + + var peg$FAILED = {}, + + peg$startRuleFunctions = { TopTypeExpr: peg$parseTopTypeExpr, NamepathExpr: peg$parseNamepathExpr, BroadNamepathExpr: peg$parseBroadNamepathExpr, ExternalNameExpr: peg$parseExternalNameExpr, ModuleNameExpr: peg$parseModuleNameExpr }, + peg$startRuleFunction = peg$parseTopTypeExpr, + + peg$c0 = function(expr) { + return expr; + }, + peg$c1 = /^[ \t]/, + peg$c2 = peg$classExpectation([" ", "\t"], false, false), + peg$c3 = /^[\r]/, + peg$c4 = peg$classExpectation(["\r"], false, false), + peg$c5 = /^[\n]/, + peg$c6 = peg$classExpectation(["\n"], false, false), + peg$c7 = /^[a-zA-Z_$]/, + peg$c8 = peg$classExpectation([["a", "z"], ["A", "Z"], "_", "$"], false, false), + peg$c9 = /^[a-zA-Z0-9_$]/, + peg$c10 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$"], false, false), + peg$c11 = "event:", + peg$c12 = peg$literalExpectation("event:", false), + peg$c13 = function(rootOwner, memberPartWithOperators) { + return memberPartWithOperators.reduce(function(owner, tokens) { + const operatorType = tokens[1]; + const eventNamespace = tokens[3]; + const MemberName = tokens[5]; + const {quoteStyle, name: memberName} = MemberName; + + switch (operatorType) { + case NamepathOperatorType.MEMBER: + return { + type: NodeType.MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + case NamepathOperatorType.INSTANCE_MEMBER: + return { + type: NodeType.INSTANCE_MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + case NamepathOperatorType.INNER_MEMBER: + return { + type: NodeType.INNER_MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + /* istanbul ignore next */ + default: + throw new Error('Unexpected operator type: "' + operatorType + '"'); + } + }, rootOwner); + }, + peg$c14 = /^[a-zA-Z0-9_$\-]/, + peg$c15 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$", "-"], false, false), + peg$c16 = function(name) { + return { + type: NodeType.NAME, + name + }; + }, + peg$c17 = "'", + peg$c18 = peg$literalExpectation("'", false), + peg$c19 = /^[^\\']/, + peg$c20 = peg$classExpectation(["\\", "'"], true, false), + peg$c21 = "\\", + peg$c22 = peg$literalExpectation("\\", false), + peg$c23 = peg$anyExpectation(), + peg$c24 = function(name) { + return { + quoteStyle: 'single', + name: name.replace(/\\'/g, "'") + .replace(/\\\\/gu, '\\') + }; + }, + peg$c25 = "\"", + peg$c26 = peg$literalExpectation("\"", false), + peg$c27 = /^[^\\"]/, + peg$c28 = peg$classExpectation(["\\", "\""], true, false), + peg$c29 = function(name) { + return { + quoteStyle: 'double', + name: name.replace(/\\"/gu, '"') + .replace(/\\\\/gu, '\\') + }; + }, + peg$c30 = function(name) { + return { + quoteStyle: 'none', + name + }; + }, + peg$c31 = ".", + peg$c32 = peg$literalExpectation(".", false), + peg$c33 = function(rootOwner, memberPart) { + return memberPart.reduce(function(owner, tokens) { + return { + type: NodeType.MEMBER, + owner, + name: tokens[3] + } + }, rootOwner); + }, + peg$c34 = function() { + return NamepathOperatorType.MEMBER; + }, + peg$c35 = "~", + peg$c36 = peg$literalExpectation("~", false), + peg$c37 = function() { + return NamepathOperatorType.INNER_MEMBER; + }, + peg$c38 = "#", + peg$c39 = peg$literalExpectation("#", false), + peg$c40 = function() { + return NamepathOperatorType.INSTANCE_MEMBER; + }, + peg$c41 = "external", + peg$c42 = peg$literalExpectation("external", false), + peg$c43 = ":", + peg$c44 = peg$literalExpectation(":", false), + peg$c45 = function(external, memberPartWithOperators) { + return memberPartWithOperators.reduce(function(owner, tokens) { + const operatorType = tokens[1]; + const eventNamespace = tokens[3]; + const MemberName = tokens[5]; + const {quoteStyle, name: memberName} = MemberName; + + switch (operatorType) { + case NamepathOperatorType.MEMBER: + return { + type: NodeType.MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + case NamepathOperatorType.INSTANCE_MEMBER: + return { + type: NodeType.INSTANCE_MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + case NamepathOperatorType.INNER_MEMBER: + return { + type: NodeType.INNER_MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + /* istanbul ignore next */ + default: + throw new Error('Unexpected operator type: "' + operatorType + '"'); + } + }, Object.assign({ + type: NodeType.EXTERNAL + }, external)); + }, + peg$c46 = "module", + peg$c47 = peg$literalExpectation("module", false), + peg$c48 = function(value) { + return { + type: NodeType.MODULE, + value, + }; + }, + peg$c49 = function(rootOwner, memberPartWithOperators) { + return memberPartWithOperators.reduce(function(owner, tokens) { + const operatorType = tokens[1]; + const eventNamespace = tokens[3]; + const MemberName = tokens[5]; + const {quoteStyle, name: memberName} = MemberName; + + switch (operatorType) { + case NamepathOperatorType.MEMBER: + return { + type: NodeType.MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + case NamepathOperatorType.INSTANCE_MEMBER: + return { + type: NodeType.INSTANCE_MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + case NamepathOperatorType.INNER_MEMBER: + return { + type: NodeType.INNER_MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + /* istanbul ignore next */ + default: + throw new Error('Unexpected operator type: "' + operatorType + '"'); + } + }, rootOwner); + }, + peg$c50 = function(path) { + return { + quoteStyle: 'single', + type: NodeType.FILE_PATH, + path: path.replace(/\\'/g, "'") + .replace(/\\\\/gu, '\\') + }; + }, + peg$c51 = function(path) { + return { + quoteStyle: 'double', + type: NodeType.FILE_PATH, + path: path.replace(/\\"/gu, '"') + .replace(/\\\\/gu, '\\') + }; + }, + peg$c52 = /^[a-zA-Z0-9_$\/\-]/, + peg$c53 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$", "/", "-"], false, false), + peg$c54 = function(path) { + return { + quoteStyle: 'none', + type: NodeType.FILE_PATH, + path, + }; + }, + peg$c55 = "*", + peg$c56 = peg$literalExpectation("*", false), + peg$c57 = function() { + return { type: NodeType.ANY }; + }, + peg$c58 = "?", + peg$c59 = peg$literalExpectation("?", false), + peg$c60 = function() { + return { type: NodeType.UNKNOWN }; + }, + peg$c61 = function(value) { + return { + type: NodeType.STRING_VALUE, + quoteStyle: 'double', + string: value.replace(/\\"/gu, '"') + .replace(/\\\\/gu, '\\') + }; + }, + peg$c62 = function(value) { + return { + type: NodeType.STRING_VALUE, + quoteStyle: 'single', + string: value.replace(/\\'/g, "'") + .replace(/\\\\/gu, '\\') + }; + }, + peg$c63 = function(value) { + return { + type: NodeType.NUMBER_VALUE, + number: value + }; + }, + peg$c64 = "+", + peg$c65 = peg$literalExpectation("+", false), + peg$c66 = "-", + peg$c67 = peg$literalExpectation("-", false), + peg$c68 = /^[0-9]/, + peg$c69 = peg$classExpectation([["0", "9"]], false, false), + peg$c70 = "e", + peg$c71 = peg$literalExpectation("e", false), + peg$c72 = "0b", + peg$c73 = peg$literalExpectation("0b", false), + peg$c74 = /^[01]/, + peg$c75 = peg$classExpectation(["0", "1"], false, false), + peg$c76 = "0o", + peg$c77 = peg$literalExpectation("0o", false), + peg$c78 = /^[0-7]/, + peg$c79 = peg$classExpectation([["0", "7"]], false, false), + peg$c80 = "0x", + peg$c81 = peg$literalExpectation("0x", false), + peg$c82 = /^[0-9a-fA-F]/, + peg$c83 = peg$classExpectation([["0", "9"], ["a", "f"], ["A", "F"]], false, false), + peg$c84 = "|", + peg$c85 = peg$literalExpectation("|", false), + peg$c86 = function(left, right) { + return { + type: NodeType.UNION, + left, + right, + }; + }, + peg$c87 = "typeof", + peg$c88 = peg$literalExpectation("typeof", false), + peg$c89 = function(operator, name) { + return { + type: NodeType.TYPE_QUERY, + name, + }; + }, + peg$c90 = function(operator, operand) { + return { + type: NodeType.NULLABLE, + value: operand, + meta: { syntax: NullableTypeSyntax.PREFIX_QUESTION_MARK }, + }; + }, + peg$c91 = "!", + peg$c92 = peg$literalExpectation("!", false), + peg$c93 = function(operator, operand) { + return { + type: NodeType.NOT_NULLABLE, + value: operand, + meta: { syntax: NotNullableTypeSyntax.PREFIX_BANG }, + }; + }, + peg$c94 = "=", + peg$c95 = peg$literalExpectation("=", false), + peg$c96 = function(operator, operand) { + return { + type: NodeType.OPTIONAL, + value: operand, + meta: { syntax: OptionalTypeSyntax.PREFIX_EQUALS_SIGN }, + }; + }, + peg$c97 = function(operand, operator) { + return { + type: NodeType.NULLABLE, + value: operand, + meta: { syntax: NullableTypeSyntax.SUFFIX_QUESTION_MARK }, + }; + }, + peg$c98 = function(operand, operator) { + return { + type: NodeType.NOT_NULLABLE, + value: operand, + meta: { syntax: NotNullableTypeSyntax.SUFFIX_BANG }, + }; + }, + peg$c99 = function(operand, operator) { + return { + type: NodeType.OPTIONAL, + value: operand, + meta: { syntax: OptionalTypeSyntax.SUFFIX_EQUALS_SIGN }, + }; + }, + peg$c100 = function(operand, syntax, params) { + return { + type: NodeType.GENERIC, + subject: operand, + objects: params, + meta: { syntax }, + }; + }, + peg$c101 = ",", + peg$c102 = peg$literalExpectation(",", false), + peg$c103 = function(first, restsWithComma) { + return restsWithComma.reduce(function(params, tokens) { + return params.concat([tokens[3]]); + }, [first]); + }, + peg$c104 = ".<", + peg$c105 = peg$literalExpectation(".<", false), + peg$c106 = function() { + return GenericTypeSyntax.ANGLE_BRACKET_WITH_DOT; + }, + peg$c107 = "<", + peg$c108 = peg$literalExpectation("<", false), + peg$c109 = function() { + return GenericTypeSyntax.ANGLE_BRACKET; + }, + peg$c110 = ">", + peg$c111 = peg$literalExpectation(">", false), + peg$c112 = "function", + peg$c113 = peg$literalExpectation("function", false), + peg$c114 = function(paramsPart, returnedTypePart) { + const returnedTypeNode = returnedTypePart ? returnedTypePart[2] : null; + + return { + type: NodeType.FUNCTION, + params: paramsPart.params, + returns: returnedTypeNode, + this: paramsPart.modifier.nodeThis, + new: paramsPart.modifier.nodeNew, + }; + }, + peg$c115 = "(", + peg$c116 = peg$literalExpectation("(", false), + peg$c117 = ")", + peg$c118 = peg$literalExpectation(")", false), + peg$c119 = function(modifier, params) { + return { params, modifier }; + }, + peg$c120 = function(modifier) { + return { params: [], modifier }; + }, + peg$c121 = function() { + return { params: [], modifier: { nodeThis: null, nodeNew: null } }; + }, + peg$c122 = function(params) { + return { params, modifier: { nodeThis: null, nodeNew: null } }; + }, + peg$c123 = "this", + peg$c124 = peg$literalExpectation("this", false), + peg$c125 = function(modifierThis) { + return { nodeThis: modifierThis[4], nodeNew: null }; + }, + peg$c126 = "new", + peg$c127 = peg$literalExpectation("new", false), + peg$c128 = function(modifierNew) { + return { nodeThis: null, nodeNew: modifierNew[4] }; + }, + peg$c129 = function(paramsWithComma, lastParam) { + return paramsWithComma.reduceRight(function(params, tokens) { + const [param] = tokens; + return [param].concat(params); + }, lastParam ? [lastParam] : []); + }, + peg$c130 = "{", + peg$c131 = peg$literalExpectation("{", false), + peg$c132 = "}", + peg$c133 = peg$literalExpectation("}", false), + peg$c134 = function(entries) { + return { + type: NodeType.RECORD, + entries: entries || [], + }; + }, + peg$c135 = ";", + peg$c136 = peg$literalExpectation(";", false), + peg$c137 = function(first, restWithComma) { + return restWithComma.reduce(function(entries, tokens) { + const entry = tokens[2]; + return entries.concat([entry]); + }, [first]); + }, + peg$c138 = "readonly", + peg$c139 = peg$literalExpectation("readonly", false), + peg$c140 = function(readonly, keyInfo, optional, value) { + const {quoteStyle, key} = keyInfo; + return { + type: NodeType.RECORD_ENTRY, + key, + quoteStyle, + value: + optional === '?' ? { + type: NodeType.OPTIONAL, + value, + meta: { syntax: OptionalTypeSyntax.SUFFIX_KEY_QUESTION_MARK }, + } : + value, + readonly: Boolean(readonly) + }; + }, + peg$c141 = function(readonly, keyInfo) { + const {quoteStyle, key} = keyInfo; + return { + type: NodeType.RECORD_ENTRY, + key, + quoteStyle, + value: null, + readonly: Boolean(readonly) + }; + }, + peg$c142 = function(key) { + return { + quoteStyle: 'double', + key: key.replace(/\\"/gu, '"') + .replace(/\\\\/gu, '\\') + }; + }, + peg$c143 = function(key) { + return { + quoteStyle: 'single', + key: key.replace(/\\'/g, "'") + .replace(/\\\\/gu, '\\') + }; + }, + peg$c144 = function(key) { + return { + quoteStyle: 'none', + key + }; + }, + peg$c145 = function(wrapped) { + return { + type: NodeType.PARENTHESIS, + value: wrapped, + }; + }, + peg$c146 = "...", + peg$c147 = peg$literalExpectation("...", false), + peg$c148 = function(operand) { + return { + type: NodeType.VARIADIC, + value: operand, + meta: { syntax: VariadicTypeSyntax.PREFIX_DOTS }, + }; + }, + peg$c149 = function(operand) { + return { + type: NodeType.VARIADIC, + value: operand, + meta: { syntax: VariadicTypeSyntax.SUFFIX_DOTS }, + }; + }, + peg$c150 = function() { + return { + type: NodeType.VARIADIC, + value: { type: NodeType.ANY }, + meta: { syntax: VariadicTypeSyntax.ONLY_DOTS }, + }; + }, + + peg$currPos = 0, + peg$posDetailsCache = [{ line: 1, column: 1 }], + peg$maxFailPos = 0, + peg$maxFailExpected = [], + peg$resultsCache = {}, + + peg$result; + + if ("startRule" in options) { + if (!(options.startRule in peg$startRuleFunctions)) { + throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); + } + + peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; + } + + function peg$literalExpectation(text, ignoreCase) { + return { type: "literal", text: text, ignoreCase: ignoreCase }; + } + + function peg$classExpectation(parts, inverted, ignoreCase) { + return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase }; + } + + function peg$anyExpectation() { + return { type: "any" }; + } + + function peg$endExpectation() { + return { type: "end" }; + } + + function peg$computePosDetails(pos) { + var details = peg$posDetailsCache[pos], p; + + if (details) { + return details; + } else { + p = pos - 1; + while (!peg$posDetailsCache[p]) { + p--; + } + + details = peg$posDetailsCache[p]; + details = { + line: details.line, + column: details.column + }; + + while (p < pos) { + if (input.charCodeAt(p) === 10) { + details.line++; + details.column = 1; + } else { + details.column++; + } + + p++; + } + + peg$posDetailsCache[pos] = details; + return details; + } + } + + function peg$computeLocation(startPos, endPos) { + var startPosDetails = peg$computePosDetails(startPos), + endPosDetails = peg$computePosDetails(endPos); + + return { + start: { + offset: startPos, + line: startPosDetails.line, + column: startPosDetails.column + }, + end: { + offset: endPos, + line: endPosDetails.line, + column: endPosDetails.column + } + }; + } + + function peg$fail(expected) { + if (peg$currPos < peg$maxFailPos) { return; } + + if (peg$currPos > peg$maxFailPos) { + peg$maxFailPos = peg$currPos; + peg$maxFailExpected = []; + } + + peg$maxFailExpected.push(expected); + } + + function peg$buildStructuredError(expected, found, location) { + return new peg$SyntaxError$1( + peg$SyntaxError$1.buildMessage(expected, found), + expected, + found, + location + ); + } + + function peg$parseTopTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 68 + 0, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parse_(); + if (s1 !== peg$FAILED) { + s2 = peg$parseVariadicTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseUnionTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseUnaryUnionTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseGenericTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseRecordTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseFunctionTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseTypeQueryExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseBroadNamepathExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseParenthesizedExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseValueExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseAnyTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + if (s2 !== peg$FAILED) { + s3 = peg$parse_(); + if (s3 !== peg$FAILED) { + s1 = peg$c0(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseWS() { + var s0, s1, s2; + + var key = peg$currPos * 68 + 1, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + if (peg$c1.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + { peg$fail(peg$c2); } + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (peg$c3.test(input.charAt(peg$currPos))) { + s1 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c4); } + } + if (s1 === peg$FAILED) { + s1 = null; + } + if (s1 !== peg$FAILED) { + if (peg$c5.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c6); } + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parse_() { + var s0, s1; + + var key = peg$currPos * 68 + 2, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = []; + s1 = peg$parseWS(); + while (s1 !== peg$FAILED) { + s0.push(s1); + s1 = peg$parseWS(); + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parse__() { + var s0, s1; + + var key = peg$currPos * 68 + 3, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = []; + s1 = peg$parseWS(); + if (s1 !== peg$FAILED) { + while (s1 !== peg$FAILED) { + s0.push(s1); + s1 = peg$parseWS(); + } + } else { + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseJsIdentifier() { + var s0, s1, s2, s3, s4; + + var key = peg$currPos * 68 + 4, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (peg$c7.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c8); } + } + if (s2 !== peg$FAILED) { + s3 = []; + if (peg$c9.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c10); } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c9.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c10); } + } + } + if (s3 !== peg$FAILED) { + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseNamepathExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + var key = peg$currPos * 68 + 5, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseParenthesizedExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseTypeNameExprJsDocFlavored(); + } + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseInfixNamepathOperator(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c11) { + s7 = peg$c11; + peg$currPos += 6; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c12); } + } + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseMemberName(); + if (s9 !== peg$FAILED) { + s4 = [s4, s5, s6, s7, s8, s9]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseInfixNamepathOperator(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c11) { + s7 = peg$c11; + peg$currPos += 6; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c12); } + } + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseMemberName(); + if (s9 !== peg$FAILED) { + s4 = [s4, s5, s6, s7, s8, s9]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s1 = peg$c13(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseTypeNameExprJsDocFlavored() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 68 + 6, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + s2 = peg$currPos; + if (peg$c7.test(input.charAt(peg$currPos))) { + s3 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c8); } + } + if (s3 !== peg$FAILED) { + s4 = []; + if (peg$c14.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c15); } + } + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c14.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c15); } + } + } + if (s4 !== peg$FAILED) { + s3 = [s3, s4]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = input.substring(s1, peg$currPos); + } else { + s1 = s2; + } + if (s1 !== peg$FAILED) { + s1 = peg$c16(s1); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseMemberName() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 68 + 7, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 39) { + s1 = peg$c17; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 39) { + s3 = peg$c17; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c24(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 34) { + s1 = peg$c25; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 34) { + s3 = peg$c25; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c29(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parseJsIdentifier(); + if (s1 !== peg$FAILED) { + s1 = peg$c30(s1); + } + s0 = s1; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseInfixNamepathOperator() { + var s0; + + var key = peg$currPos * 68 + 8, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseMemberTypeOperator(); + if (s0 === peg$FAILED) { + s0 = peg$parseInstanceMemberTypeOperator(); + if (s0 === peg$FAILED) { + s0 = peg$parseInnerMemberTypeOperator(); + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseQualifiedMemberName() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 68 + 9, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseTypeNameExprJsDocFlavored(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 46) { + s5 = peg$c31; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c32); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseTypeNameExprJsDocFlavored(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 46) { + s5 = peg$c31; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c32); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseTypeNameExprJsDocFlavored(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s1 = peg$c33(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseMemberTypeOperator() { + var s0, s1; + + var key = peg$currPos * 68 + 10, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 46) { + s1 = peg$c31; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c32); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c34(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseInnerMemberTypeOperator() { + var s0, s1; + + var key = peg$currPos * 68 + 11, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 126) { + s1 = peg$c35; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c36); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c37(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseInstanceMemberTypeOperator() { + var s0, s1; + + var key = peg$currPos * 68 + 12, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 35) { + s1 = peg$c38; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c39); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c40(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseBroadNamepathExpr() { + var s0; + + var key = peg$currPos * 68 + 13, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseExternalNameExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseModuleNameExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNamepathExpr(); + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseExternalNameExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13; + + var key = peg$currPos * 68 + 14, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c41) { + s1 = peg$c41; + peg$currPos += 8; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c42); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c43; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseMemberName(); + if (s5 !== peg$FAILED) { + s6 = []; + s7 = peg$currPos; + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseInfixNamepathOperator(); + if (s9 !== peg$FAILED) { + s10 = peg$parse_(); + if (s10 !== peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c11) { + s11 = peg$c11; + peg$currPos += 6; + } else { + s11 = peg$FAILED; + { peg$fail(peg$c12); } + } + if (s11 === peg$FAILED) { + s11 = null; + } + if (s11 !== peg$FAILED) { + s12 = peg$parse_(); + if (s12 !== peg$FAILED) { + s13 = peg$parseMemberName(); + if (s13 !== peg$FAILED) { + s8 = [s8, s9, s10, s11, s12, s13]; + s7 = s8; + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + while (s7 !== peg$FAILED) { + s6.push(s7); + s7 = peg$currPos; + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseInfixNamepathOperator(); + if (s9 !== peg$FAILED) { + s10 = peg$parse_(); + if (s10 !== peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c11) { + s11 = peg$c11; + peg$currPos += 6; + } else { + s11 = peg$FAILED; + { peg$fail(peg$c12); } + } + if (s11 === peg$FAILED) { + s11 = null; + } + if (s11 !== peg$FAILED) { + s12 = peg$parse_(); + if (s12 !== peg$FAILED) { + s13 = peg$parseMemberName(); + if (s13 !== peg$FAILED) { + s8 = [s8, s9, s10, s11, s12, s13]; + s7 = s8; + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } else { + peg$currPos = s7; + s7 = peg$FAILED; + } + } + if (s6 !== peg$FAILED) { + s1 = peg$c45(s5, s6); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseModuleNameExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 68 + 15, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 6) === peg$c46) { + s1 = peg$c46; + peg$currPos += 6; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c47); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c43; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseModulePathExpr(); + if (s5 !== peg$FAILED) { + s1 = peg$c48(s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseModulePathExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + var key = peg$currPos * 68 + 16, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseFilePathExpr(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseInfixNamepathOperator(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c11) { + s7 = peg$c11; + peg$currPos += 6; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c12); } + } + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseMemberName(); + if (s9 !== peg$FAILED) { + s4 = [s4, s5, s6, s7, s8, s9]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseInfixNamepathOperator(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c11) { + s7 = peg$c11; + peg$currPos += 6; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c12); } + } + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseMemberName(); + if (s9 !== peg$FAILED) { + s4 = [s4, s5, s6, s7, s8, s9]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s1 = peg$c49(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFilePathExpr() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 68 + 17, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 39) { + s1 = peg$c17; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 39) { + s3 = peg$c17; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c50(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 34) { + s1 = peg$c25; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 34) { + s3 = peg$c25; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c51(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$currPos; + s2 = []; + if (peg$c52.test(input.charAt(peg$currPos))) { + s3 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c53); } + } + if (s3 !== peg$FAILED) { + while (s3 !== peg$FAILED) { + s2.push(s3); + if (peg$c52.test(input.charAt(peg$currPos))) { + s3 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c53); } + } + } + } else { + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = input.substring(s1, peg$currPos); + } else { + s1 = s2; + } + if (s1 !== peg$FAILED) { + s1 = peg$c54(s1); + } + s0 = s1; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseAnyTypeExpr() { + var s0, s1; + + var key = peg$currPos * 68 + 18, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 42) { + s1 = peg$c55; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c56); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c57(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseUnknownTypeExpr() { + var s0, s1; + + var key = peg$currPos * 68 + 19, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 63) { + s1 = peg$c58; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c59); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c60(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseValueExpr() { + var s0; + + var key = peg$currPos * 68 + 20, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseStringLiteralExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNumberLiteralExpr(); + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseStringLiteralExpr() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 68 + 21, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 34) { + s1 = peg$c25; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 34) { + s3 = peg$c25; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c61(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 39) { + s1 = peg$c17; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 39) { + s3 = peg$c17; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c62(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseNumberLiteralExpr() { + var s0, s1; + + var key = peg$currPos * 68 + 22, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseBinNumberLiteralExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseOctNumberLiteralExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseHexNumberLiteralExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseDecimalNumberLiteralExpr(); + } + } + } + if (s1 !== peg$FAILED) { + s1 = peg$c63(s1); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseDecimalNumberLiteralExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 68 + 23, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 43) { + s2 = peg$c64; + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c65); } + } + if (s2 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 45) { + s2 = peg$c66; + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c67); } + } + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + s3 = peg$parseUnsignedDecimalNumberLiteralExpr(); + if (s3 !== peg$FAILED) { + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseUnsignedDecimalNumberLiteralExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 68 + 24, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + s2 = peg$currPos; + s3 = []; + if (peg$c68.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c69); } + } + if (s4 !== peg$FAILED) { + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c68.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c69); } + } + } + } else { + s3 = peg$FAILED; + } + if (s3 !== peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 46) { + s5 = peg$c31; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c32); } + } + if (s5 !== peg$FAILED) { + s6 = []; + if (peg$c68.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c69); } + } + if (s7 !== peg$FAILED) { + while (s7 !== peg$FAILED) { + s6.push(s7); + if (peg$c68.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c69); } + } + } + } else { + s6 = peg$FAILED; + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = null; + } + if (s4 !== peg$FAILED) { + s3 = [s3, s4]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 === peg$FAILED) { + s2 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 46) { + s3 = peg$c31; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c32); } + } + if (s3 !== peg$FAILED) { + s4 = []; + if (peg$c68.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c69); } + } + if (s5 !== peg$FAILED) { + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c68.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c69); } + } + } + } else { + s4 = peg$FAILED; + } + if (s4 !== peg$FAILED) { + s3 = [s3, s4]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s3 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 101) { + s4 = peg$c70; + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c71); } + } + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 43) { + s5 = peg$c64; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c65); } + } + if (s5 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 45) { + s5 = peg$c66; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c67); } + } + } + if (s5 === peg$FAILED) { + s5 = null; + } + if (s5 !== peg$FAILED) { + s6 = []; + if (peg$c68.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c69); } + } + if (s7 !== peg$FAILED) { + while (s7 !== peg$FAILED) { + s6.push(s7); + if (peg$c68.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c69); } + } + } + } else { + s6 = peg$FAILED; + } + if (s6 !== peg$FAILED) { + s4 = [s4, s5, s6]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = null; + } + if (s3 !== peg$FAILED) { + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseBinNumberLiteralExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 68 + 25, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 45) { + s2 = peg$c66; + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c67); } + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c72) { + s3 = peg$c72; + peg$currPos += 2; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c73); } + } + if (s3 !== peg$FAILED) { + s4 = []; + if (peg$c74.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c75); } + } + if (s5 !== peg$FAILED) { + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c74.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c75); } + } + } + } else { + s4 = peg$FAILED; + } + if (s4 !== peg$FAILED) { + s2 = [s2, s3, s4]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseOctNumberLiteralExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 68 + 26, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 45) { + s2 = peg$c66; + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c67); } + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c76) { + s3 = peg$c76; + peg$currPos += 2; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c77); } + } + if (s3 !== peg$FAILED) { + s4 = []; + if (peg$c78.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c79); } + } + if (s5 !== peg$FAILED) { + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c78.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c79); } + } + } + } else { + s4 = peg$FAILED; + } + if (s4 !== peg$FAILED) { + s2 = [s2, s3, s4]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseHexNumberLiteralExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 68 + 27, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 45) { + s2 = peg$c66; + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c67); } + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c80) { + s3 = peg$c80; + peg$currPos += 2; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c81); } + } + if (s3 !== peg$FAILED) { + s4 = []; + if (peg$c82.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c83); } + } + if (s5 !== peg$FAILED) { + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c82.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c83); } + } + } + } else { + s4 = peg$FAILED; + } + if (s4 !== peg$FAILED) { + s2 = [s2, s3, s4]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseUnionTypeExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 68 + 28, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseUnionTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 124) { + s3 = peg$c84; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c85); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseUnionTypeExpr(); + if (s5 === peg$FAILED) { + s5 = peg$parseUnionTypeExprOperand(); + } + if (s5 !== peg$FAILED) { + s1 = peg$c86(s1, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseUnionTypeExprOperand() { + var s0; + + var key = peg$currPos * 68 + 29, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseUnaryUnionTypeExpr() { + var s0; + + var key = peg$currPos * 68 + 30, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseSuffixUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parsePrefixUnaryUnionTypeExpr(); + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixUnaryUnionTypeExpr() { + var s0; + + var key = peg$currPos * 68 + 31, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parsePrefixOptionalTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parsePrefixNotNullableTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parsePrefixNullableTypeExpr(); + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixUnaryUnionTypeExprOperand() { + var s0; + + var key = peg$currPos * 68 + 32, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseTypeQueryExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 68 + 33, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 6) === peg$c87) { + s1 = peg$c87; + peg$currPos += 6; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c88); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse__(); + if (s2 !== peg$FAILED) { + s3 = peg$parseQualifiedMemberName(); + if (s3 !== peg$FAILED) { + s1 = peg$c89(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixNullableTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 68 + 34, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 63) { + s1 = peg$c58; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c59); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); + if (s3 !== peg$FAILED) { + s1 = peg$c90(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixNotNullableTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 68 + 35, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 33) { + s1 = peg$c91; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c92); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); + if (s3 !== peg$FAILED) { + s1 = peg$c93(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixOptionalTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 68 + 36, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 61) { + s1 = peg$c94; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c95); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); + if (s3 !== peg$FAILED) { + s1 = peg$c96(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixUnaryUnionTypeExpr() { + var s0; + + var key = peg$currPos * 68 + 37, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseSuffixOptionalTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseSuffixNullableTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseSuffixNotNullableTypeExpr(); + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixUnaryUnionTypeExprOperand() { + var s0; + + var key = peg$currPos * 68 + 38, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parsePrefixUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixNullableTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 68 + 39, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 63) { + s3 = peg$c58; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c59); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c97(s1); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixNotNullableTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 68 + 40, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 33) { + s3 = peg$c91; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c92); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c98(s1); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixOptionalTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 68 + 41, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseSuffixNullableTypeExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseSuffixNotNullableTypeExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 61) { + s3 = peg$c94; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c95); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c99(s1); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 68 + 42, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseGenericTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseGenericTypeStartToken(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseGenericTypeExprTypeParamList(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseGenericTypeEndToken(); + if (s7 !== peg$FAILED) { + s1 = peg$c100(s1, s3, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeExprOperand() { + var s0; + + var key = peg$currPos * 68 + 43, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeExprTypeParamOperand() { + var s0; + + var key = peg$currPos * 68 + 44, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeExprTypeParamList() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 68 + 45, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseGenericTypeExprTypeParamOperand(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c101; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c102); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseGenericTypeExprTypeParamOperand(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c101; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c102); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseGenericTypeExprTypeParamOperand(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s1 = peg$c103(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeStartToken() { + var s0; + + var key = peg$currPos * 68 + 46, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseGenericTypeEcmaScriptFlavoredStartToken(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeTypeScriptFlavoredStartToken(); + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeEcmaScriptFlavoredStartToken() { + var s0, s1; + + var key = peg$currPos * 68 + 47, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 2) === peg$c104) { + s1 = peg$c104; + peg$currPos += 2; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c105); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c106(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeTypeScriptFlavoredStartToken() { + var s0, s1; + + var key = peg$currPos * 68 + 48, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 60) { + s1 = peg$c107; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c108); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c109(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeEndToken() { + var s0; + + var key = peg$currPos * 68 + 49, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + if (input.charCodeAt(peg$currPos) === 62) { + s0 = peg$c110; + peg$currPos++; + } else { + s0 = peg$FAILED; + { peg$fail(peg$c111); } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8; + + var key = peg$currPos * 68 + 50, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c112) { + s1 = peg$c112; + peg$currPos += 8; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c113); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseFunctionTypeExprParamsList(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 58) { + s6 = peg$c43; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s6 !== peg$FAILED) { + s7 = peg$parse_(); + if (s7 !== peg$FAILED) { + s8 = peg$parseFunctionTypeExprReturnableOperand(); + if (s8 !== peg$FAILED) { + s6 = [s6, s7, s8]; + s5 = s6; + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + if (s5 === peg$FAILED) { + s5 = null; + } + if (s5 !== peg$FAILED) { + s1 = peg$c114(s3, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExprParamsList() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + var key = peg$currPos * 68 + 51, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c115; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c116); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseFunctionTypeExprModifier(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c101; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c102); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseFunctionTypeExprParams(); + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s9 = peg$c117; + peg$currPos++; + } else { + s9 = peg$FAILED; + { peg$fail(peg$c118); } + } + if (s9 !== peg$FAILED) { + s1 = peg$c119(s3, s7); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c115; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c116); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseFunctionTypeExprModifier(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s5 = peg$c117; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c118); } + } + if (s5 !== peg$FAILED) { + s1 = peg$c120(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c115; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c116); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s3 = peg$c117; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c118); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c121(); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c115; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c116); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseFunctionTypeExprParams(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s5 = peg$c117; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c118); } + } + if (s5 !== peg$FAILED) { + s1 = peg$c122(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExprModifier() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 68 + 52, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.substr(peg$currPos, 4) === peg$c123) { + s2 = peg$c123; + peg$currPos += 4; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c124); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parse_(); + if (s3 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s4 = peg$c43; + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseFunctionTypeExprParamOperand(); + if (s6 !== peg$FAILED) { + s2 = [s2, s3, s4, s5, s6]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s1 = peg$c125(s1); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$currPos; + if (input.substr(peg$currPos, 3) === peg$c126) { + s2 = peg$c126; + peg$currPos += 3; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c127); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parse_(); + if (s3 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s4 = peg$c43; + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseFunctionTypeExprParamOperand(); + if (s6 !== peg$FAILED) { + s2 = [s2, s3, s4, s5, s6]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s1 = peg$c128(s1); + } + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExprParams() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 68 + 53, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = []; + s2 = peg$currPos; + s3 = peg$parseFunctionTypeExprParamOperand(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c101; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c102); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s3 = [s3, s4, s5, s6]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + while (s2 !== peg$FAILED) { + s1.push(s2); + s2 = peg$currPos; + s3 = peg$parseFunctionTypeExprParamOperand(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c101; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c102); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s3 = [s3, s4, s5, s6]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseVariadicTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseVariadicTypeExprOperand(); + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + s1 = peg$c129(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExprParamOperand() { + var s0; + + var key = peg$currPos * 68 + 54, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExprReturnableOperand() { + var s0; + + var key = peg$currPos * 68 + 55, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parsePrefixUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseRecordTypeExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 68 + 56, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 123) { + s1 = peg$c130; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c131); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseRecordTypeExprEntries(); + if (s3 === peg$FAILED) { + s3 = null; + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 125) { + s5 = peg$c132; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c133); } + } + if (s5 !== peg$FAILED) { + s1 = peg$c134(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseRecordTypeExprEntries() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 68 + 57, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseRecordTypeExprEntry(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s6 = peg$c101; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c102); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 59) { + s6 = peg$c135; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c136); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + s5 = []; + if (peg$c1.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c2); } + } + while (s6 !== peg$FAILED) { + s5.push(s6); + if (peg$c1.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c2); } + } + } + if (s5 !== peg$FAILED) { + if (peg$c3.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c4); } + } + if (s6 === peg$FAILED) { + s6 = null; + } + if (s6 !== peg$FAILED) { + if (peg$c5.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c6); } + } + if (s7 !== peg$FAILED) { + s5 = [s5, s6, s7]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseRecordTypeExprEntry(); + if (s6 !== peg$FAILED) { + s4 = [s4, s5, s6]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s6 = peg$c101; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c102); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 59) { + s6 = peg$c135; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c136); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + s5 = []; + if (peg$c1.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c2); } + } + while (s6 !== peg$FAILED) { + s5.push(s6); + if (peg$c1.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c2); } + } + } + if (s5 !== peg$FAILED) { + if (peg$c3.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c4); } + } + if (s6 === peg$FAILED) { + s6 = null; + } + if (s6 !== peg$FAILED) { + if (peg$c5.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c6); } + } + if (s7 !== peg$FAILED) { + s5 = [s5, s6, s7]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseRecordTypeExprEntry(); + if (s6 !== peg$FAILED) { + s4 = [s4, s5, s6]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c101; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c102); } + } + if (s5 !== peg$FAILED) { + s4 = [s4, s5]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 59) { + s5 = peg$c135; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c136); } + } + if (s5 !== peg$FAILED) { + s4 = [s4, s5]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = peg$currPos; + s4 = []; + if (peg$c1.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c2); } + } + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c1.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c2); } + } + } + if (s4 !== peg$FAILED) { + if (peg$c3.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c4); } + } + if (s5 === peg$FAILED) { + s5 = null; + } + if (s5 !== peg$FAILED) { + if (peg$c5.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c6); } + } + if (s6 !== peg$FAILED) { + s4 = [s4, s5, s6]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + } + if (s3 === peg$FAILED) { + s3 = null; + } + if (s3 !== peg$FAILED) { + s1 = peg$c137(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseRecordTypeExprEntry() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8; + + var key = peg$currPos * 68 + 58, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c138) { + s2 = peg$c138; + peg$currPos += 8; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c139); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parse__(); + if (s3 !== peg$FAILED) { + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 === peg$FAILED) { + s1 = null; + } + if (s1 !== peg$FAILED) { + s2 = peg$parseRecordTypeExprEntryKey(); + if (s2 !== peg$FAILED) { + s3 = peg$parse_(); + if (s3 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 63) { + s4 = peg$c58; + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c59); } + } + if (s4 === peg$FAILED) { + s4 = null; + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s6 = peg$c43; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c44); } + } + if (s6 !== peg$FAILED) { + s7 = peg$parse_(); + if (s7 !== peg$FAILED) { + s8 = peg$parseRecordTypeExprEntryOperand(); + if (s8 !== peg$FAILED) { + s1 = peg$c140(s1, s2, s4, s8); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c138) { + s2 = peg$c138; + peg$currPos += 8; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c139); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parse__(); + if (s3 !== peg$FAILED) { + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 === peg$FAILED) { + s1 = null; + } + if (s1 !== peg$FAILED) { + s2 = peg$parseRecordTypeExprEntryKey(); + if (s2 !== peg$FAILED) { + s1 = peg$c141(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseRecordTypeExprEntryKey() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 68 + 59, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 34) { + s1 = peg$c25; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 34) { + s3 = peg$c25; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c142(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 39) { + s1 = peg$c17; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 39) { + s3 = peg$c17; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c143(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$currPos; + s2 = peg$parseJsIdentifier(); + if (s2 === peg$FAILED) { + s2 = peg$parseUnsignedDecimalNumberLiteralExpr(); + } + if (s2 !== peg$FAILED) { + s1 = input.substring(s1, peg$currPos); + } else { + s1 = s2; + } + if (s1 !== peg$FAILED) { + s1 = peg$c144(s1); + } + s0 = s1; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseRecordTypeExprEntryOperand() { + var s0; + + var key = peg$currPos * 68 + 60, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseParenthesizedExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 68 + 61, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c115; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c116); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseParenthesizedExprOperand(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s5 = peg$c117; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c118); } + } + if (s5 !== peg$FAILED) { + s1 = peg$c145(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseParenthesizedExprOperand() { + var s0; + + var key = peg$currPos * 68 + 62, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseVariadicTypeExpr() { + var s0; + + var key = peg$currPos * 68 + 63, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parsePrefixVariadicTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseSuffixVariadicTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyVariadicTypeExpr(); + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixVariadicTypeExpr() { + var s0, s1, s2; + + var key = peg$currPos * 68 + 64, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 3) === peg$c146) { + s1 = peg$c146; + peg$currPos += 3; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c147); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseVariadicTypeExprOperand(); + if (s2 !== peg$FAILED) { + s1 = peg$c148(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixVariadicTypeExpr() { + var s0, s1, s2; + + var key = peg$currPos * 68 + 65, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseVariadicTypeExprOperand(); + if (s1 !== peg$FAILED) { + if (input.substr(peg$currPos, 3) === peg$c146) { + s2 = peg$c146; + peg$currPos += 3; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c147); } + } + if (s2 !== peg$FAILED) { + s1 = peg$c149(s1); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseAnyVariadicTypeExpr() { + var s0, s1; + + var key = peg$currPos * 68 + 66, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 3) === peg$c146) { + s1 = peg$c146; + peg$currPos += 3; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c147); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c150(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseVariadicTypeExprOperand() { + var s0; + + var key = peg$currPos * 68 + 67, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseBroadNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + + const meta = SyntaxType; + const { + GenericTypeSyntax, + VariadicTypeSyntax, OptionalTypeSyntax, + NullableTypeSyntax, NotNullableTypeSyntax, + } = meta; + const NodeType = NodeType_1; + + const NamepathOperatorType = { + MEMBER: 'MEMBER', + INNER_MEMBER: 'INNER_MEMBER', + INSTANCE_MEMBER: 'INSTANCE_MEMBER', + }; + + + peg$result = peg$startRuleFunction(); + + if (peg$result !== peg$FAILED && peg$currPos === input.length) { + return peg$result; + } else { + if (peg$result !== peg$FAILED && peg$currPos < input.length) { + peg$fail(peg$endExpectation()); + } + + throw peg$buildStructuredError( + peg$maxFailExpected, + peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, + peg$maxFailPos < input.length + ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) + : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) + ); + } +} + +var jsdoctypeClosure = { + SyntaxError: peg$SyntaxError$1, + parse: peg$parse$1 +}; + +/* + * Generated by PEG.js 0.10.0. + * + * http://pegjs.org/ + */ + +function peg$subclass(child, parent) { + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); +} + +function peg$SyntaxError(message, expected, found, location) { + this.message = message; + this.expected = expected; + this.found = found; + this.location = location; + this.name = "SyntaxError"; + + if (typeof Error.captureStackTrace === "function") { + Error.captureStackTrace(this, peg$SyntaxError); + } +} + +peg$subclass(peg$SyntaxError, Error); + +peg$SyntaxError.buildMessage = function(expected, found) { + var DESCRIBE_EXPECTATION_FNS = { + literal: function(expectation) { + return "\"" + literalEscape(expectation.text) + "\""; + }, + + "class": function(expectation) { + var escapedParts = "", + i; + + for (i = 0; i < expectation.parts.length; i++) { + escapedParts += expectation.parts[i] instanceof Array + ? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1]) + : classEscape(expectation.parts[i]); + } + + return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]"; + }, + + any: function(expectation) { + return "any character"; + }, + + end: function(expectation) { + return "end of input"; + }, + + other: function(expectation) { + return expectation.description; + } + }; + + function hex(ch) { + return ch.charCodeAt(0).toString(16).toUpperCase(); + } + + function literalEscape(s) { + return s + .replace(/\\/g, '\\\\') + .replace(/"/g, '\\"') + .replace(/\0/g, '\\0') + .replace(/\t/g, '\\t') + .replace(/\n/g, '\\n') + .replace(/\r/g, '\\r') + .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); }); + } + + function classEscape(s) { + return s + .replace(/\\/g, '\\\\') + .replace(/\]/g, '\\]') + .replace(/\^/g, '\\^') + .replace(/-/g, '\\-') + .replace(/\0/g, '\\0') + .replace(/\t/g, '\\t') + .replace(/\n/g, '\\n') + .replace(/\r/g, '\\r') + .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); }); + } + + function describeExpectation(expectation) { + return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); + } + + function describeExpected(expected) { + var descriptions = new Array(expected.length), + i, j; + + for (i = 0; i < expected.length; i++) { + descriptions[i] = describeExpectation(expected[i]); + } + + descriptions.sort(); + + if (descriptions.length > 0) { + for (i = 1, j = 1; i < descriptions.length; i++) { + if (descriptions[i - 1] !== descriptions[i]) { + descriptions[j] = descriptions[i]; + j++; + } + } + descriptions.length = j; + } + + switch (descriptions.length) { + case 1: + return descriptions[0]; + + case 2: + return descriptions[0] + " or " + descriptions[1]; + + default: + return descriptions.slice(0, -1).join(", ") + + ", or " + + descriptions[descriptions.length - 1]; + } + } + + function describeFound(found) { + return found ? "\"" + literalEscape(found) + "\"" : "end of input"; + } + + return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; +}; + +function peg$parse(input, options) { + options = options !== void 0 ? options : {}; + + var peg$FAILED = {}, + + peg$startRuleFunctions = { TopTypeExpr: peg$parseTopTypeExpr, NamepathExpr: peg$parseNamepathExpr, BroadNamepathExpr: peg$parseBroadNamepathExpr }, + peg$startRuleFunction = peg$parseTopTypeExpr, + + peg$c0 = function(expr) { + return expr; + }, + peg$c1 = /^[ \t]/, + peg$c2 = peg$classExpectation([" ", "\t"], false, false), + peg$c3 = /^[\r]/, + peg$c4 = peg$classExpectation(["\r"], false, false), + peg$c5 = /^[\n]/, + peg$c6 = peg$classExpectation(["\n"], false, false), + peg$c7 = /^[a-zA-Z_$]/, + peg$c8 = peg$classExpectation([["a", "z"], ["A", "Z"], "_", "$"], false, false), + peg$c9 = /^[a-zA-Z0-9_$]/, + peg$c10 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$"], false, false), + peg$c11 = "event:", + peg$c12 = peg$literalExpectation("event:", false), + peg$c13 = function(rootOwner, memberPartWithOperators) { + return memberPartWithOperators.reduce(function(owner, tokens) { + const operatorType = tokens[1]; + const eventNamespace = tokens[3]; + const MemberName = tokens[5]; + const {quoteStyle, name: memberName} = MemberName; + + switch (operatorType) { + case NamepathOperatorType.MEMBER: + return { + type: NodeType.MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + case NamepathOperatorType.INSTANCE_MEMBER: + return { + type: NodeType.INSTANCE_MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + case NamepathOperatorType.INNER_MEMBER: + return { + type: NodeType.INNER_MEMBER, + owner, + name: memberName, + quoteStyle, + hasEventPrefix: Boolean(eventNamespace), + }; + /* istanbul ignore next */ + default: + throw new Error('Unexpected operator type: "' + operatorType + '"'); + } + }, rootOwner); + }, + peg$c14 = /^[a-zA-Z0-9_$\-]/, + peg$c15 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$", "-"], false, false), + peg$c16 = function(name) { + return { + type: NodeType.NAME, + name + }; + }, + peg$c17 = "'", + peg$c18 = peg$literalExpectation("'", false), + peg$c19 = /^[^\\']/, + peg$c20 = peg$classExpectation(["\\", "'"], true, false), + peg$c21 = "\\", + peg$c22 = peg$literalExpectation("\\", false), + peg$c23 = peg$anyExpectation(), + peg$c24 = function(name) { + return { + quoteStyle: 'single', + name: name.replace(/\\'/g, "'") + .replace(/\\\\/gu, '\\') + }; + }, + peg$c25 = "\"", + peg$c26 = peg$literalExpectation("\"", false), + peg$c27 = /^[^\\"]/, + peg$c28 = peg$classExpectation(["\\", "\""], true, false), + peg$c29 = function(name) { + return { + quoteStyle: 'double', + name: name.replace(/\\"/gu, '"') + .replace(/\\\\/gu, '\\') + }; + }, + peg$c30 = function(name) { + return { + quoteStyle: 'none', + name + }; + }, + peg$c31 = ".", + peg$c32 = peg$literalExpectation(".", false), + peg$c33 = function(rootOwner, memberPart) { + return memberPart.reduce(function(owner, tokens) { + return { + type: NodeType.MEMBER, + owner, + name: tokens[3] + } + }, rootOwner); + }, + peg$c34 = function() { + return NamepathOperatorType.MEMBER; + }, + peg$c35 = "~", + peg$c36 = peg$literalExpectation("~", false), + peg$c37 = function() { + return NamepathOperatorType.INNER_MEMBER; + }, + peg$c38 = "#", + peg$c39 = peg$literalExpectation("#", false), + peg$c40 = function() { + return NamepathOperatorType.INSTANCE_MEMBER; + }, + peg$c41 = "*", + peg$c42 = peg$literalExpectation("*", false), + peg$c43 = function() { + return { type: NodeType.ANY }; + }, + peg$c44 = "?", + peg$c45 = peg$literalExpectation("?", false), + peg$c46 = function() { + return { type: NodeType.UNKNOWN }; + }, + peg$c47 = function(value) { + return { + type: NodeType.STRING_VALUE, + quoteStyle: 'double', + string: value.replace(/\\"/gu, '"') + .replace(/\\\\/gu, '\\') + }; + }, + peg$c48 = function(value) { + return { + type: NodeType.STRING_VALUE, + quoteStyle: 'single', + string: value.replace(/\\'/g, "'") + .replace(/\\\\/gu, '\\') + }; + }, + peg$c49 = function(value) { + return { + type: NodeType.NUMBER_VALUE, + number: value + }; + }, + peg$c50 = "+", + peg$c51 = peg$literalExpectation("+", false), + peg$c52 = "-", + peg$c53 = peg$literalExpectation("-", false), + peg$c54 = /^[0-9]/, + peg$c55 = peg$classExpectation([["0", "9"]], false, false), + peg$c56 = "e", + peg$c57 = peg$literalExpectation("e", false), + peg$c58 = "0b", + peg$c59 = peg$literalExpectation("0b", false), + peg$c60 = /^[01]/, + peg$c61 = peg$classExpectation(["0", "1"], false, false), + peg$c62 = "0o", + peg$c63 = peg$literalExpectation("0o", false), + peg$c64 = /^[0-7]/, + peg$c65 = peg$classExpectation([["0", "7"]], false, false), + peg$c66 = "0x", + peg$c67 = peg$literalExpectation("0x", false), + peg$c68 = /^[0-9a-fA-F]/, + peg$c69 = peg$classExpectation([["0", "9"], ["a", "f"], ["A", "F"]], false, false), + peg$c70 = "&", + peg$c71 = peg$literalExpectation("&", false), + peg$c72 = function(left, right) { + return { + type: NodeType.INTERSECTION, + left, + right, + }; + }, + peg$c73 = "|", + peg$c74 = peg$literalExpectation("|", false), + peg$c75 = function(left, right) { + return { + type: NodeType.UNION, + left, + right, + }; + }, + peg$c76 = "typeof", + peg$c77 = peg$literalExpectation("typeof", false), + peg$c78 = function(operator, name) { + return { + type: NodeType.TYPE_QUERY, + name, + }; + }, + peg$c79 = "keyof", + peg$c80 = peg$literalExpectation("keyof", false), + peg$c81 = function(operator, operand) { + return { + type: NodeType.KEY_QUERY, + value: operand, + } + }, + peg$c82 = "import", + peg$c83 = peg$literalExpectation("import", false), + peg$c84 = "(", + peg$c85 = peg$literalExpectation("(", false), + peg$c86 = ")", + peg$c87 = peg$literalExpectation(")", false), + peg$c88 = function(operator, path) { + return { type: NodeType.IMPORT, path }; + }, + peg$c89 = function(operator, operand) { + return { + type: NodeType.NULLABLE, + value: operand, + meta: { syntax: NullableTypeSyntax.PREFIX_QUESTION_MARK }, + }; + }, + peg$c90 = "!", + peg$c91 = peg$literalExpectation("!", false), + peg$c92 = function(operator, operand) { + return { + type: NodeType.NOT_NULLABLE, + value: operand, + meta: { syntax: NotNullableTypeSyntax.PREFIX_BANG }, + }; + }, + peg$c93 = "=", + peg$c94 = peg$literalExpectation("=", false), + peg$c95 = function(operator, operand) { + return { + type: NodeType.OPTIONAL, + value: operand, + meta: { syntax: OptionalTypeSyntax.PREFIX_EQUALS_SIGN }, + }; + }, + peg$c96 = function(operand, operator) { + return { + type: NodeType.NULLABLE, + value: operand, + meta: { syntax: NullableTypeSyntax.SUFFIX_QUESTION_MARK }, + }; + }, + peg$c97 = function(operand, operator) { + return { + type: NodeType.NOT_NULLABLE, + value: operand, + meta: { syntax: NotNullableTypeSyntax.SUFFIX_BANG }, + }; + }, + peg$c98 = function(operand, operator) { + return { + type: NodeType.OPTIONAL, + value: operand, + meta: { syntax: OptionalTypeSyntax.SUFFIX_EQUALS_SIGN }, + }; + }, + peg$c99 = function(operand, syntax, params) { + return { + type: NodeType.GENERIC, + subject: operand, + objects: params, + meta: { syntax }, + }; + }, + peg$c100 = ",", + peg$c101 = peg$literalExpectation(",", false), + peg$c102 = function(first, restsWithComma) { + return restsWithComma.reduce(function(params, tokens) { + return params.concat([tokens[3]]); + }, [first]); + }, + peg$c103 = ".<", + peg$c104 = peg$literalExpectation(".<", false), + peg$c105 = function() { + return GenericTypeSyntax.ANGLE_BRACKET_WITH_DOT; + }, + peg$c106 = "<", + peg$c107 = peg$literalExpectation("<", false), + peg$c108 = function() { + return GenericTypeSyntax.ANGLE_BRACKET; + }, + peg$c109 = ">", + peg$c110 = peg$literalExpectation(">", false), + peg$c111 = "[", + peg$c112 = peg$literalExpectation("[", false), + peg$c113 = "]", + peg$c114 = peg$literalExpectation("]", false), + peg$c115 = function(operand, brackets) { + return brackets.reduce(function(operand) { + return { + type: NodeType.GENERIC, + subject: { + type: NodeType.NAME, + name: 'Array' + }, + objects: [ operand ], + meta: { syntax: GenericTypeSyntax.SQUARE_BRACKET }, + }; + }, operand); + }, + peg$c116 = "new", + peg$c117 = peg$literalExpectation("new", false), + peg$c118 = "=>", + peg$c119 = peg$literalExpectation("=>", false), + peg$c120 = function(newModifier, paramsPart, returnedTypeNode) { + return { + type: NodeType.ARROW, + params: paramsPart, + returns: returnedTypeNode, + new: newModifier + }; + }, + peg$c121 = function() { + return []; + }, + peg$c122 = function(params) { + return params; + }, + peg$c123 = ":", + peg$c124 = peg$literalExpectation(":", false), + peg$c125 = function(paramsWithComma, lastParam) { + return paramsWithComma.reduceRight(function(params, tokens) { + const param = { type: NodeType.NAMED_PARAMETER, name: tokens[0], typeName: tokens[4] }; + return [param].concat(params); + }, lastParam ? [lastParam] : []); + }, + peg$c126 = "...", + peg$c127 = peg$literalExpectation("...", false), + peg$c128 = function(spread, id, type) { + const operand = { type: NodeType.NAMED_PARAMETER, name: id, typeName: type }; + if (spread) { + return { + type: NodeType.VARIADIC, + value: operand, + meta: { syntax: VariadicTypeSyntax.PREFIX_DOTS }, + }; + } + else { + return operand; + } + }, + peg$c129 = "function", + peg$c130 = peg$literalExpectation("function", false), + peg$c131 = function(paramsPart, returnedTypePart) { + const returnedTypeNode = returnedTypePart ? returnedTypePart[2] : null; + + return { + type: NodeType.FUNCTION, + params: paramsPart.params, + returns: returnedTypeNode, + this: paramsPart.modifier.nodeThis, + new: paramsPart.modifier.nodeNew, + }; + }, + peg$c132 = function(modifier, params) { + return { params, modifier }; + }, + peg$c133 = function(modifier) { + return { params: [], modifier }; + }, + peg$c134 = function() { + return { params: [], modifier: { nodeThis: null, nodeNew: null } }; + }, + peg$c135 = function(params) { + return { params, modifier: { nodeThis: null, nodeNew: null } }; + }, + peg$c136 = "this", + peg$c137 = peg$literalExpectation("this", false), + peg$c138 = function(modifierThis) { + return { nodeThis: modifierThis[4], nodeNew: null }; + }, + peg$c139 = function(modifierNew) { + return { nodeThis: null, nodeNew: modifierNew[4] }; + }, + peg$c140 = function(paramsWithComma, lastParam) { + return paramsWithComma.reduceRight(function(params, tokens) { + const [param] = tokens; + return [param].concat(params); + }, lastParam ? [lastParam] : []); + }, + peg$c141 = "{", + peg$c142 = peg$literalExpectation("{", false), + peg$c143 = "}", + peg$c144 = peg$literalExpectation("}", false), + peg$c145 = function(entries) { + return { + type: NodeType.RECORD, + entries: entries || [], + }; + }, + peg$c146 = ";", + peg$c147 = peg$literalExpectation(";", false), + peg$c148 = function(first, restWithComma) { + return restWithComma.reduce(function(entries, tokens) { + const entry = tokens[2]; + return entries.concat([entry]); + }, [first]); + }, + peg$c149 = "readonly", + peg$c150 = peg$literalExpectation("readonly", false), + peg$c151 = function(readonly, keyInfo, optional, value) { + const {quoteStyle, key} = keyInfo; + return { + type: NodeType.RECORD_ENTRY, + key, + quoteStyle, + value: + optional === '?' ? { + type: NodeType.OPTIONAL, + value, + meta: { syntax: OptionalTypeSyntax.SUFFIX_KEY_QUESTION_MARK }, + } : + value, + readonly: Boolean(readonly) + }; + }, + peg$c152 = function(readonly, keyInfo) { + const {quoteStyle, key} = keyInfo; + return { + type: NodeType.RECORD_ENTRY, + key, + quoteStyle, + value: null, + readonly: Boolean(readonly) + }; + }, + peg$c153 = function(key) { + return { + quoteStyle: 'double', + key: key.replace(/\\"/gu, '"') + .replace(/\\\\/gu, '\\') + }; + }, + peg$c154 = function(key) { + return { + quoteStyle: 'single', + key: key.replace(/\\'/g, "'") + .replace(/\\\\/gu, '\\') + }; + }, + peg$c155 = function(key) { + return { + quoteStyle: 'none', + key + }; + }, + peg$c156 = function(entries) { + return { + type: NodeType.TUPLE, + entries, + } + }, + peg$c157 = function(restWithComma, last) { + return restWithComma.reduceRight((entries, tokens) => { + let [entry] = tokens; + return [entry].concat(entries); + }, last ? [last] : []); + }, + peg$c158 = function(wrapped) { + return { + type: NodeType.PARENTHESIS, + value: wrapped, + }; + }, + peg$c159 = function(operand) { + return { + type: NodeType.VARIADIC, + value: operand, + meta: { syntax: VariadicTypeSyntax.PREFIX_DOTS }, + }; + }, + peg$c160 = function(operand) { + return { + type: NodeType.VARIADIC, + value: operand, + meta: { syntax: VariadicTypeSyntax.SUFFIX_DOTS }, + }; + }, + peg$c161 = function() { + return { + type: NodeType.VARIADIC, + value: { type: NodeType.ANY }, + meta: { syntax: VariadicTypeSyntax.ONLY_DOTS }, + }; + }, + + peg$currPos = 0, + peg$posDetailsCache = [{ line: 1, column: 1 }], + peg$maxFailPos = 0, + peg$maxFailExpected = [], + peg$resultsCache = {}, + + peg$result; + + if ("startRule" in options) { + if (!(options.startRule in peg$startRuleFunctions)) { + throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); + } + + peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; + } + + function peg$literalExpectation(text, ignoreCase) { + return { type: "literal", text: text, ignoreCase: ignoreCase }; + } + + function peg$classExpectation(parts, inverted, ignoreCase) { + return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase }; + } + + function peg$anyExpectation() { + return { type: "any" }; + } + + function peg$endExpectation() { + return { type: "end" }; + } + + function peg$computePosDetails(pos) { + var details = peg$posDetailsCache[pos], p; + + if (details) { + return details; + } else { + p = pos - 1; + while (!peg$posDetailsCache[p]) { + p--; + } + + details = peg$posDetailsCache[p]; + details = { + line: details.line, + column: details.column + }; + + while (p < pos) { + if (input.charCodeAt(p) === 10) { + details.line++; + details.column = 1; + } else { + details.column++; + } + + p++; + } + + peg$posDetailsCache[pos] = details; + return details; + } + } + + function peg$computeLocation(startPos, endPos) { + var startPosDetails = peg$computePosDetails(startPos), + endPosDetails = peg$computePosDetails(endPos); + + return { + start: { + offset: startPos, + line: startPosDetails.line, + column: startPosDetails.column + }, + end: { + offset: endPos, + line: endPosDetails.line, + column: endPosDetails.column + } + }; + } + + function peg$fail(expected) { + if (peg$currPos < peg$maxFailPos) { return; } + + if (peg$currPos > peg$maxFailPos) { + peg$maxFailPos = peg$currPos; + peg$maxFailExpected = []; + } + + peg$maxFailExpected.push(expected); + } + + function peg$buildStructuredError(expected, found, location) { + return new peg$SyntaxError( + peg$SyntaxError.buildMessage(expected, found), + expected, + found, + location + ); + } + + function peg$parseTopTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 78 + 0, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parse_(); + if (s1 !== peg$FAILED) { + s2 = peg$parseVariadicTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseUnionTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseIntersectionTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseUnaryUnionTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseArrayTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseGenericTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseRecordTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseTupleTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseArrowTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseFunctionTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseTypeQueryExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseKeyQueryExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseNamepathExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseParenthesizedExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseValueExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseAnyTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + if (s2 !== peg$FAILED) { + s3 = peg$parse_(); + if (s3 !== peg$FAILED) { + s1 = peg$c0(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseWS() { + var s0, s1, s2; + + var key = peg$currPos * 78 + 1, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + if (peg$c1.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + { peg$fail(peg$c2); } + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (peg$c3.test(input.charAt(peg$currPos))) { + s1 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c4); } + } + if (s1 === peg$FAILED) { + s1 = null; + } + if (s1 !== peg$FAILED) { + if (peg$c5.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c6); } + } + if (s2 !== peg$FAILED) { + s1 = [s1, s2]; + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parse_() { + var s0, s1; + + var key = peg$currPos * 78 + 2, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = []; + s1 = peg$parseWS(); + while (s1 !== peg$FAILED) { + s0.push(s1); + s1 = peg$parseWS(); + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parse__() { + var s0, s1; + + var key = peg$currPos * 78 + 3, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = []; + s1 = peg$parseWS(); + if (s1 !== peg$FAILED) { + while (s1 !== peg$FAILED) { + s0.push(s1); + s1 = peg$parseWS(); + } + } else { + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseJsIdentifier() { + var s0, s1, s2, s3, s4; + + var key = peg$currPos * 78 + 4, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (peg$c7.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c8); } + } + if (s2 !== peg$FAILED) { + s3 = []; + if (peg$c9.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c10); } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c9.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c10); } + } + } + if (s3 !== peg$FAILED) { + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseNamepathExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + var key = peg$currPos * 78 + 5, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseParenthesizedExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseImportTypeExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseTypeNameExprJsDocFlavored(); + } + } + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseInfixNamepathOperator(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c11) { + s7 = peg$c11; + peg$currPos += 6; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c12); } + } + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseMemberName(); + if (s9 !== peg$FAILED) { + s4 = [s4, s5, s6, s7, s8, s9]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseInfixNamepathOperator(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c11) { + s7 = peg$c11; + peg$currPos += 6; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c12); } + } + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + s9 = peg$parseMemberName(); + if (s9 !== peg$FAILED) { + s4 = [s4, s5, s6, s7, s8, s9]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s1 = peg$c13(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseTypeNameExprJsDocFlavored() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 78 + 6, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + s2 = peg$currPos; + if (peg$c7.test(input.charAt(peg$currPos))) { + s3 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c8); } + } + if (s3 !== peg$FAILED) { + s4 = []; + if (peg$c14.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c15); } + } + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c14.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c15); } + } + } + if (s4 !== peg$FAILED) { + s3 = [s3, s4]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = input.substring(s1, peg$currPos); + } else { + s1 = s2; + } + if (s1 !== peg$FAILED) { + s1 = peg$c16(s1); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseMemberName() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 78 + 7, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 39) { + s1 = peg$c17; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 39) { + s3 = peg$c17; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c24(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 34) { + s1 = peg$c25; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 34) { + s3 = peg$c25; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c29(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parseJsIdentifier(); + if (s1 !== peg$FAILED) { + s1 = peg$c30(s1); + } + s0 = s1; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseInfixNamepathOperator() { + var s0; + + var key = peg$currPos * 78 + 8, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseMemberTypeOperator(); + if (s0 === peg$FAILED) { + s0 = peg$parseInstanceMemberTypeOperator(); + if (s0 === peg$FAILED) { + s0 = peg$parseInnerMemberTypeOperator(); + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseQualifiedMemberName() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 78 + 9, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseTypeNameExprJsDocFlavored(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 46) { + s5 = peg$c31; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c32); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseTypeNameExprJsDocFlavored(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 46) { + s5 = peg$c31; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c32); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseTypeNameExprJsDocFlavored(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s1 = peg$c33(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseMemberTypeOperator() { + var s0, s1; + + var key = peg$currPos * 78 + 10, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 46) { + s1 = peg$c31; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c32); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c34(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseInnerMemberTypeOperator() { + var s0, s1; + + var key = peg$currPos * 78 + 11, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 126) { + s1 = peg$c35; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c36); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c37(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseInstanceMemberTypeOperator() { + var s0, s1; + + var key = peg$currPos * 78 + 12, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 35) { + s1 = peg$c38; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c39); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c40(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseBroadNamepathExpr() { + var s0; + + var key = peg$currPos * 78 + 13, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseNamepathExpr(); + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseAnyTypeExpr() { + var s0, s1; + + var key = peg$currPos * 78 + 14, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 42) { + s1 = peg$c41; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c42); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c43(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseUnknownTypeExpr() { + var s0, s1; + + var key = peg$currPos * 78 + 15, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 63) { + s1 = peg$c44; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c45); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c46(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseValueExpr() { + var s0; + + var key = peg$currPos * 78 + 16, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseStringLiteralExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNumberLiteralExpr(); + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseStringLiteralExpr() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 78 + 17, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 34) { + s1 = peg$c25; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 34) { + s3 = peg$c25; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c47(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 39) { + s1 = peg$c17; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 39) { + s3 = peg$c17; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c48(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseNumberLiteralExpr() { + var s0, s1; + + var key = peg$currPos * 78 + 18, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseBinNumberLiteralExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseOctNumberLiteralExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseHexNumberLiteralExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseDecimalNumberLiteralExpr(); + } + } + } + if (s1 !== peg$FAILED) { + s1 = peg$c49(s1); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseDecimalNumberLiteralExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 78 + 19, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 43) { + s2 = peg$c50; + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c51); } + } + if (s2 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 45) { + s2 = peg$c52; + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c53); } + } + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + s3 = peg$parseUnsignedDecimalNumberLiteralExpr(); + if (s3 !== peg$FAILED) { + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseUnsignedDecimalNumberLiteralExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 78 + 20, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + s2 = peg$currPos; + s3 = []; + if (peg$c54.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c55); } + } + if (s4 !== peg$FAILED) { + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c54.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c55); } + } + } + } else { + s3 = peg$FAILED; + } + if (s3 !== peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 46) { + s5 = peg$c31; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c32); } + } + if (s5 !== peg$FAILED) { + s6 = []; + if (peg$c54.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c55); } + } + if (s7 !== peg$FAILED) { + while (s7 !== peg$FAILED) { + s6.push(s7); + if (peg$c54.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c55); } + } + } + } else { + s6 = peg$FAILED; + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = null; + } + if (s4 !== peg$FAILED) { + s3 = [s3, s4]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + if (s2 === peg$FAILED) { + s2 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 46) { + s3 = peg$c31; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c32); } + } + if (s3 !== peg$FAILED) { + s4 = []; + if (peg$c54.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c55); } + } + if (s5 !== peg$FAILED) { + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c54.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c55); } + } + } + } else { + s4 = peg$FAILED; + } + if (s4 !== peg$FAILED) { + s3 = [s3, s4]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s3 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 101) { + s4 = peg$c56; + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c57); } + } + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 43) { + s5 = peg$c50; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c51); } + } + if (s5 === peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 45) { + s5 = peg$c52; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c53); } + } + } + if (s5 === peg$FAILED) { + s5 = null; + } + if (s5 !== peg$FAILED) { + s6 = []; + if (peg$c54.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c55); } + } + if (s7 !== peg$FAILED) { + while (s7 !== peg$FAILED) { + s6.push(s7); + if (peg$c54.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c55); } + } + } + } else { + s6 = peg$FAILED; + } + if (s6 !== peg$FAILED) { + s4 = [s4, s5, s6]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = null; + } + if (s3 !== peg$FAILED) { + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseBinNumberLiteralExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 78 + 21, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 45) { + s2 = peg$c52; + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c53); } + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c58) { + s3 = peg$c58; + peg$currPos += 2; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c59); } + } + if (s3 !== peg$FAILED) { + s4 = []; + if (peg$c60.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c61); } + } + if (s5 !== peg$FAILED) { + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c60.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c61); } + } + } + } else { + s4 = peg$FAILED; + } + if (s4 !== peg$FAILED) { + s2 = [s2, s3, s4]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseOctNumberLiteralExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 78 + 22, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 45) { + s2 = peg$c52; + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c53); } + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c62) { + s3 = peg$c62; + peg$currPos += 2; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c63); } + } + if (s3 !== peg$FAILED) { + s4 = []; + if (peg$c64.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c65); } + } + if (s5 !== peg$FAILED) { + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c64.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c65); } + } + } + } else { + s4 = peg$FAILED; + } + if (s4 !== peg$FAILED) { + s2 = [s2, s3, s4]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseHexNumberLiteralExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 78 + 23, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 45) { + s2 = peg$c52; + peg$currPos++; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c53); } + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c66) { + s3 = peg$c66; + peg$currPos += 2; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c67); } + } + if (s3 !== peg$FAILED) { + s4 = []; + if (peg$c68.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c69); } + } + if (s5 !== peg$FAILED) { + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c68.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c69); } + } + } + } else { + s4 = peg$FAILED; + } + if (s4 !== peg$FAILED) { + s2 = [s2, s3, s4]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s0 = input.substring(s0, peg$currPos); + } else { + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseIntersectionTypeExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 78 + 24, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseIntersectionTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 38) { + s3 = peg$c70; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c71); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseIntersectionTypeExpr(); + if (s5 === peg$FAILED) { + s5 = peg$parseIntersectionTypeExprOperand(); + } + if (s5 !== peg$FAILED) { + s1 = peg$c72(s1, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseIntersectionTypeExprOperand() { + var s0; + + var key = peg$currPos * 78 + 25, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseKeyQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseUnionTypeExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 78 + 26, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseUnionTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 124) { + s3 = peg$c73; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c74); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseUnionTypeExpr(); + if (s5 === peg$FAILED) { + s5 = peg$parseUnionTypeExprOperand(); + } + if (s5 !== peg$FAILED) { + s1 = peg$c75(s1, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseUnionTypeExprOperand() { + var s0; + + var key = peg$currPos * 78 + 27, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseKeyQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseUnaryUnionTypeExpr() { + var s0; + + var key = peg$currPos * 78 + 28, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseSuffixUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parsePrefixUnaryUnionTypeExpr(); + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixUnaryUnionTypeExpr() { + var s0; + + var key = peg$currPos * 78 + 29, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parsePrefixOptionalTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parsePrefixNotNullableTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parsePrefixNullableTypeExpr(); + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixUnaryUnionTypeExprOperand() { + var s0; + + var key = peg$currPos * 78 + 30, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseTypeQueryExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 78 + 31, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 6) === peg$c76) { + s1 = peg$c76; + peg$currPos += 6; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c77); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse__(); + if (s2 !== peg$FAILED) { + s3 = peg$parseQualifiedMemberName(); + if (s3 !== peg$FAILED) { + s1 = peg$c78(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseKeyQueryExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 78 + 32, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 5) === peg$c79) { + s1 = peg$c79; + peg$currPos += 5; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c80); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse__(); + if (s2 !== peg$FAILED) { + s3 = peg$parseKeyQueryExprOperand(); + if (s3 !== peg$FAILED) { + s1 = peg$c81(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.substr(peg$currPos, 5) === peg$c79) { + s1 = peg$c79; + peg$currPos += 5; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c80); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseParenthesizedExpr(); + if (s2 !== peg$FAILED) { + s1 = peg$c81(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseKeyQueryExprOperand() { + var s0; + + var key = peg$currPos * 78 + 33, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseIntersectionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseKeyQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseImportTypeExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 78 + 34, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 6) === peg$c82) { + s1 = peg$c82; + peg$currPos += 6; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c83); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 40) { + s3 = peg$c84; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c85); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseStringLiteralExpr(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s7 = peg$c86; + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c87); } + } + if (s7 !== peg$FAILED) { + s1 = peg$c88(s1, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixNullableTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 78 + 35, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 63) { + s1 = peg$c44; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c45); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); + if (s3 !== peg$FAILED) { + s1 = peg$c89(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixNotNullableTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 78 + 36, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 33) { + s1 = peg$c90; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c91); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); + if (s3 !== peg$FAILED) { + s1 = peg$c92(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixOptionalTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 78 + 37, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 61) { + s1 = peg$c93; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c94); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); + if (s3 !== peg$FAILED) { + s1 = peg$c95(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixUnaryUnionTypeExpr() { + var s0; + + var key = peg$currPos * 78 + 38, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseSuffixOptionalTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseSuffixNullableTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseSuffixNotNullableTypeExpr(); + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixUnaryUnionTypeExprOperand() { + var s0; + + var key = peg$currPos * 78 + 39, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parsePrefixUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixNullableTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 78 + 40, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 63) { + s3 = peg$c44; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c45); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c96(s1); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixNotNullableTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 78 + 41, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 33) { + s3 = peg$c90; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c91); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c97(s1); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixOptionalTypeExpr() { + var s0, s1, s2, s3; + + var key = peg$currPos * 78 + 42, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseSuffixNullableTypeExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseSuffixNotNullableTypeExpr(); + if (s1 === peg$FAILED) { + s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 61) { + s3 = peg$c93; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c94); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c98(s1); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 78 + 43, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseGenericTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseGenericTypeStartToken(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$parseGenericTypeExprTypeParamList(); + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseGenericTypeEndToken(); + if (s7 !== peg$FAILED) { + s1 = peg$c99(s1, s3, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeExprOperand() { + var s0; + + var key = peg$currPos * 78 + 44, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeExprTypeParamOperand() { + var s0; + + var key = peg$currPos * 78 + 45, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseIntersectionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseKeyQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeExprTypeParamList() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 78 + 46, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseGenericTypeExprTypeParamOperand(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c100; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c101); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseGenericTypeExprTypeParamOperand(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c100; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c101); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseGenericTypeExprTypeParamOperand(); + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s1 = peg$c102(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeStartToken() { + var s0; + + var key = peg$currPos * 78 + 47, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseGenericTypeEcmaScriptFlavoredStartToken(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeTypeScriptFlavoredStartToken(); + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeEcmaScriptFlavoredStartToken() { + var s0, s1; + + var key = peg$currPos * 78 + 48, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 2) === peg$c103) { + s1 = peg$c103; + peg$currPos += 2; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c104); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c105(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeTypeScriptFlavoredStartToken() { + var s0, s1; + + var key = peg$currPos * 78 + 49, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 60) { + s1 = peg$c106; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c107); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c108(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseGenericTypeEndToken() { + var s0; + + var key = peg$currPos * 78 + 50, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + if (input.charCodeAt(peg$currPos) === 62) { + s0 = peg$c109; + peg$currPos++; + } else { + s0 = peg$FAILED; + { peg$fail(peg$c110); } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseArrayTypeExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 78 + 51, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseArrayTypeExprOperand(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 91) { + s5 = peg$c111; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c112); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s7 = peg$c113; + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c114); } + } + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 !== peg$FAILED) { + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 91) { + s5 = peg$c111; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c112); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s7 = peg$c113; + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c114); } + } + if (s7 !== peg$FAILED) { + s4 = [s4, s5, s6, s7]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + } else { + s2 = peg$FAILED; + } + if (s2 !== peg$FAILED) { + s1 = peg$c115(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseArrayTypeExprOperand() { + var s0; + + var key = peg$currPos * 78 + 52, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseKeyQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseArrowTypeExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 78 + 53, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 3) === peg$c116) { + s1 = peg$c116; + peg$currPos += 3; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c117); } + } + if (s1 === peg$FAILED) { + s1 = null; + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseArrowTypeExprParamsList(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.substr(peg$currPos, 2) === peg$c118) { + s5 = peg$c118; + peg$currPos += 2; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c119); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseFunctionTypeExprReturnableOperand(); + if (s7 !== peg$FAILED) { + s1 = peg$c120(s1, s3, s7); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseArrowTypeExprParamsList() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 78 + 54, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c84; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c85); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s3 = peg$c86; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c87); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c121(); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c84; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c85); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseArrowTypeExprParams(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s5 = peg$c86; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c87); } + } + if (s5 !== peg$FAILED) { + s1 = peg$c122(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseArrowTypeExprParams() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10; + + var key = peg$currPos * 78 + 55, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = []; + s2 = peg$currPos; + s3 = peg$parseJsIdentifier(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s5 = peg$c123; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c124); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseFunctionTypeExprParamOperand(); + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s9 = peg$c100; + peg$currPos++; + } else { + s9 = peg$FAILED; + { peg$fail(peg$c101); } + } + if (s9 !== peg$FAILED) { + s10 = peg$parse_(); + if (s10 !== peg$FAILED) { + s3 = [s3, s4, s5, s6, s7, s8, s9, s10]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + while (s2 !== peg$FAILED) { + s1.push(s2); + s2 = peg$currPos; + s3 = peg$parseJsIdentifier(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s5 = peg$c123; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c124); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseFunctionTypeExprParamOperand(); + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s9 = peg$c100; + peg$currPos++; + } else { + s9 = peg$FAILED; + { peg$fail(peg$c101); } + } + if (s9 !== peg$FAILED) { + s10 = peg$parse_(); + if (s10 !== peg$FAILED) { + s3 = [s3, s4, s5, s6, s7, s8, s9, s10]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseVariadicNameExpr(); + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + s1 = peg$c125(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseVariadicNameExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 78 + 56, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 3) === peg$c126) { + s1 = peg$c126; + peg$currPos += 3; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c127); } + } + if (s1 === peg$FAILED) { + s1 = null; + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseJsIdentifier(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s5 = peg$c123; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c124); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseFunctionTypeExprParamOperand(); + if (s7 === peg$FAILED) { + s7 = null; + } + if (s7 !== peg$FAILED) { + s1 = peg$c128(s1, s3, s7); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExpr() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8; + + var key = peg$currPos * 78 + 57, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c129) { + s1 = peg$c129; + peg$currPos += 8; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c130); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseFunctionTypeExprParamsList(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + s5 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 58) { + s6 = peg$c123; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c124); } + } + if (s6 !== peg$FAILED) { + s7 = peg$parse_(); + if (s7 !== peg$FAILED) { + s8 = peg$parseFunctionTypeExprReturnableOperand(); + if (s8 !== peg$FAILED) { + s6 = [s6, s7, s8]; + s5 = s6; + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + } else { + peg$currPos = s5; + s5 = peg$FAILED; + } + if (s5 === peg$FAILED) { + s5 = null; + } + if (s5 !== peg$FAILED) { + s1 = peg$c131(s3, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExprParamsList() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; + + var key = peg$currPos * 78 + 58, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c84; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c85); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseFunctionTypeExprModifier(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c100; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c101); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s7 = peg$parseFunctionTypeExprParams(); + if (s7 !== peg$FAILED) { + s8 = peg$parse_(); + if (s8 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s9 = peg$c86; + peg$currPos++; + } else { + s9 = peg$FAILED; + { peg$fail(peg$c87); } + } + if (s9 !== peg$FAILED) { + s1 = peg$c132(s3, s7); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c84; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c85); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseFunctionTypeExprModifier(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s5 = peg$c86; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c87); } + } + if (s5 !== peg$FAILED) { + s1 = peg$c133(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c84; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c85); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s3 = peg$c86; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c87); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c134(); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c84; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c85); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseFunctionTypeExprParams(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s5 = peg$c86; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c87); } + } + if (s5 !== peg$FAILED) { + s1 = peg$c135(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExprModifier() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 78 + 59, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.substr(peg$currPos, 4) === peg$c136) { + s2 = peg$c136; + peg$currPos += 4; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c137); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parse_(); + if (s3 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s4 = peg$c123; + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c124); } + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseFunctionTypeExprParamOperand(); + if (s6 !== peg$FAILED) { + s2 = [s2, s3, s4, s5, s6]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s1 = peg$c138(s1); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$currPos; + if (input.substr(peg$currPos, 3) === peg$c116) { + s2 = peg$c116; + peg$currPos += 3; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c117); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parse_(); + if (s3 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s4 = peg$c123; + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c124); } + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseFunctionTypeExprParamOperand(); + if (s6 !== peg$FAILED) { + s2 = [s2, s3, s4, s5, s6]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + s1 = peg$c139(s1); + } + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExprParams() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 78 + 60, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = []; + s2 = peg$currPos; + s3 = peg$parseFunctionTypeExprParamOperand(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c100; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c101); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s3 = [s3, s4, s5, s6]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + while (s2 !== peg$FAILED) { + s1.push(s2); + s2 = peg$currPos; + s3 = peg$parseFunctionTypeExprParamOperand(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c100; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c101); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s3 = [s3, s4, s5, s6]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseVariadicTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseVariadicTypeExprOperand(); + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + s1 = peg$c140(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExprParamOperand() { + var s0; + + var key = peg$currPos * 78 + 61, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseIntersectionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseKeyQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseFunctionTypeExprReturnableOperand() { + var s0; + + var key = peg$currPos * 78 + 62, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parsePrefixUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseKeyQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseRecordTypeExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 78 + 63, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 123) { + s1 = peg$c141; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c142); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseRecordTypeExprEntries(); + if (s3 === peg$FAILED) { + s3 = null; + } + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 125) { + s5 = peg$c143; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c144); } + } + if (s5 !== peg$FAILED) { + s1 = peg$c145(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseRecordTypeExprEntries() { + var s0, s1, s2, s3, s4, s5, s6, s7; + + var key = peg$currPos * 78 + 64, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseRecordTypeExprEntry(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s6 = peg$c100; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c101); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 59) { + s6 = peg$c146; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c147); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + s5 = []; + if (peg$c1.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c2); } + } + while (s6 !== peg$FAILED) { + s5.push(s6); + if (peg$c1.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c2); } + } + } + if (s5 !== peg$FAILED) { + if (peg$c3.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c4); } + } + if (s6 === peg$FAILED) { + s6 = null; + } + if (s6 !== peg$FAILED) { + if (peg$c5.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c6); } + } + if (s7 !== peg$FAILED) { + s5 = [s5, s6, s7]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseRecordTypeExprEntry(); + if (s6 !== peg$FAILED) { + s4 = [s4, s5, s6]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s6 = peg$c100; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c101); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 59) { + s6 = peg$c146; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c147); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + s5 = []; + if (peg$c1.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c2); } + } + while (s6 !== peg$FAILED) { + s5.push(s6); + if (peg$c1.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c2); } + } + } + if (s5 !== peg$FAILED) { + if (peg$c3.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c4); } + } + if (s6 === peg$FAILED) { + s6 = null; + } + if (s6 !== peg$FAILED) { + if (peg$c5.test(input.charAt(peg$currPos))) { + s7 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s7 = peg$FAILED; + { peg$fail(peg$c6); } + } + if (s7 !== peg$FAILED) { + s5 = [s5, s6, s7]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + s6 = peg$parseRecordTypeExprEntry(); + if (s6 !== peg$FAILED) { + s4 = [s4, s5, s6]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + if (s2 !== peg$FAILED) { + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c100; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c101); } + } + if (s5 !== peg$FAILED) { + s4 = [s4, s5]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = peg$currPos; + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 59) { + s5 = peg$c146; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c147); } + } + if (s5 !== peg$FAILED) { + s4 = [s4, s5]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + if (s3 === peg$FAILED) { + s3 = peg$currPos; + s4 = []; + if (peg$c1.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c2); } + } + while (s5 !== peg$FAILED) { + s4.push(s5); + if (peg$c1.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c2); } + } + } + if (s4 !== peg$FAILED) { + if (peg$c3.test(input.charAt(peg$currPos))) { + s5 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c4); } + } + if (s5 === peg$FAILED) { + s5 = null; + } + if (s5 !== peg$FAILED) { + if (peg$c5.test(input.charAt(peg$currPos))) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c6); } + } + if (s6 !== peg$FAILED) { + s4 = [s4, s5, s6]; + s3 = s4; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + } + if (s3 === peg$FAILED) { + s3 = null; + } + if (s3 !== peg$FAILED) { + s1 = peg$c148(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseRecordTypeExprEntry() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8; + + var key = peg$currPos * 78 + 65, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c149) { + s2 = peg$c149; + peg$currPos += 8; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c150); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parse__(); + if (s3 !== peg$FAILED) { + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 === peg$FAILED) { + s1 = null; + } + if (s1 !== peg$FAILED) { + s2 = peg$parseRecordTypeExprEntryKey(); + if (s2 !== peg$FAILED) { + s3 = peg$parse_(); + if (s3 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 63) { + s4 = peg$c44; + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c45); } + } + if (s4 === peg$FAILED) { + s4 = null; + } + if (s4 !== peg$FAILED) { + s5 = peg$parse_(); + if (s5 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s6 = peg$c123; + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c124); } + } + if (s6 !== peg$FAILED) { + s7 = peg$parse_(); + if (s7 !== peg$FAILED) { + s8 = peg$parseRecordTypeExprEntryOperand(); + if (s8 !== peg$FAILED) { + s1 = peg$c151(s1, s2, s4, s8); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c149) { + s2 = peg$c149; + peg$currPos += 8; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c150); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parse__(); + if (s3 !== peg$FAILED) { + s2 = [s2, s3]; + s1 = s2; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 === peg$FAILED) { + s1 = null; + } + if (s1 !== peg$FAILED) { + s2 = peg$parseRecordTypeExprEntryKey(); + if (s2 !== peg$FAILED) { + s1 = peg$c152(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseRecordTypeExprEntryKey() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 78 + 66, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 34) { + s1 = peg$c25; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c27.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c28); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 34) { + s3 = peg$c25; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c26); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c153(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 39) { + s1 = peg$c17; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s1 !== peg$FAILED) { + s2 = peg$currPos; + s3 = []; + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$c19.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + { peg$fail(peg$c20); } + } + if (s4 === peg$FAILED) { + s4 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 92) { + s5 = peg$c21; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c22); } + } + if (s5 !== peg$FAILED) { + if (input.length > peg$currPos) { + s6 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s6 = peg$FAILED; + { peg$fail(peg$c23); } + } + if (s6 !== peg$FAILED) { + s5 = [s5, s6]; + s4 = s5; + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } else { + peg$currPos = s4; + s4 = peg$FAILED; + } + } + } + if (s3 !== peg$FAILED) { + s2 = input.substring(s2, peg$currPos); + } else { + s2 = s3; + } + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 39) { + s3 = peg$c17; + peg$currPos++; + } else { + s3 = peg$FAILED; + { peg$fail(peg$c18); } + } + if (s3 !== peg$FAILED) { + s1 = peg$c154(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$currPos; + s2 = peg$parseJsIdentifier(); + if (s2 === peg$FAILED) { + s2 = peg$parseUnsignedDecimalNumberLiteralExpr(); + } + if (s2 !== peg$FAILED) { + s1 = input.substring(s1, peg$currPos); + } else { + s1 = s2; + } + if (s1 !== peg$FAILED) { + s1 = peg$c155(s1); + } + s0 = s1; + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseRecordTypeExprEntryOperand() { + var s0; + + var key = peg$currPos * 78 + 67, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseIntersectionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseTupleTypeExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 78 + 68, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 91) { + s1 = peg$c111; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c112); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseTupleTypeExprEntries(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s5 = peg$c113; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c114); } + } + if (s5 !== peg$FAILED) { + s1 = peg$c156(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseTupleTypeExprEntries() { + var s0, s1, s2, s3, s4, s5, s6; + + var key = peg$currPos * 78 + 69, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = []; + s2 = peg$currPos; + s3 = peg$parseTupleTypeExprOperand(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c100; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c101); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s3 = [s3, s4, s5, s6]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + while (s2 !== peg$FAILED) { + s1.push(s2); + s2 = peg$currPos; + s3 = peg$parseTupleTypeExprOperand(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c100; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c101); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parse_(); + if (s6 !== peg$FAILED) { + s3 = [s3, s4, s5, s6]; + s2 = s3; + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } else { + peg$currPos = s2; + s2 = peg$FAILED; + } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseVariadicTypeExpr(); + if (s2 === peg$FAILED) { + s2 = peg$parseVariadicTypeExprOperand(); + } + if (s2 === peg$FAILED) { + s2 = null; + } + if (s2 !== peg$FAILED) { + s1 = peg$c157(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseTupleTypeExprOperand() { + var s0; + + var key = peg$currPos * 78 + 70, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseIntersectionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseKeyQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseParenthesizedExpr() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 78 + 71, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c84; + peg$currPos++; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c85); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = peg$parseParenthesizedExprOperand(); + if (s3 !== peg$FAILED) { + s4 = peg$parse_(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s5 = peg$c86; + peg$currPos++; + } else { + s5 = peg$FAILED; + { peg$fail(peg$c87); } + } + if (s5 !== peg$FAILED) { + s1 = peg$c158(s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseParenthesizedExprOperand() { + var s0; + + var key = peg$currPos * 78 + 72, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseIntersectionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseKeyQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseVariadicTypeExpr() { + var s0; + + var key = peg$currPos * 78 + 73, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parsePrefixVariadicTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseSuffixVariadicTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyVariadicTypeExpr(); + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsePrefixVariadicTypeExpr() { + var s0, s1, s2; + + var key = peg$currPos * 78 + 74, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 3) === peg$c126) { + s1 = peg$c126; + peg$currPos += 3; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c127); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseVariadicTypeExprOperand(); + if (s2 !== peg$FAILED) { + s1 = peg$c159(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseSuffixVariadicTypeExpr() { + var s0, s1, s2; + + var key = peg$currPos * 78 + 75, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseVariadicTypeExprOperand(); + if (s1 !== peg$FAILED) { + if (input.substr(peg$currPos, 3) === peg$c126) { + s2 = peg$c126; + peg$currPos += 3; + } else { + s2 = peg$FAILED; + { peg$fail(peg$c127); } + } + if (s2 !== peg$FAILED) { + s1 = peg$c160(s1); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseAnyVariadicTypeExpr() { + var s0, s1; + + var key = peg$currPos * 78 + 76, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 3) === peg$c126) { + s1 = peg$c126; + peg$currPos += 3; + } else { + s1 = peg$FAILED; + { peg$fail(peg$c127); } + } + if (s1 !== peg$FAILED) { + s1 = peg$c161(); + } + s0 = s1; + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseVariadicTypeExprOperand() { + var s0; + + var key = peg$currPos * 78 + 77, + cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$parseUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseIntersectionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnaryUnionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseRecordTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTupleTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrowTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseFunctionTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseParenthesizedExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseTypeQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseKeyQueryExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseArrayTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseGenericTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseNamepathExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseValueExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseAnyTypeExpr(); + if (s0 === peg$FAILED) { + s0 = peg$parseUnknownTypeExpr(); + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + + const meta = SyntaxType; + const { + GenericTypeSyntax, + VariadicTypeSyntax, OptionalTypeSyntax, + NullableTypeSyntax, NotNullableTypeSyntax, + } = meta; + const NodeType = NodeType_1; + + const NamepathOperatorType = { + MEMBER: 'MEMBER', + INNER_MEMBER: 'INNER_MEMBER', + INSTANCE_MEMBER: 'INSTANCE_MEMBER', + }; + + + peg$result = peg$startRuleFunction(); + + if (peg$result !== peg$FAILED && peg$currPos === input.length) { + return peg$result; + } else { + if (peg$result !== peg$FAILED && peg$currPos < input.length) { + peg$fail(peg$endExpectation()); + } + + throw peg$buildStructuredError( + peg$maxFailExpected, + peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, + peg$maxFailPos < input.length + ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) + : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) + ); + } +} + +var jsdoctypeTypescript = { + SyntaxError: peg$SyntaxError, + parse: peg$parse +}; + +/** + * @typedef AstNode + * @property {string} type + * @property {'none'|'single'|'double'} [quoteStyle] + * @property {boolean} [readonly] + * @property {string} [key] + * @property {string} [name] + * @property {string} [number] + * @property {string} [path] + * @property {string} [string] + * @property {boolean} [hasEventPrefix] + * @property {boolean} [typeName] + * @property {Object} [meta] + * @property {AstNode} [returns] + * @property {AstNode} [new] + * @property {AstNode} [value] + * @property {AstNode} [left] + * @property {AstNode} [right] + * @property {AstNode} [owner] + * @property {AstNode} [subject] + * @property {AstNode} [this] + * @property {AstNode[]} [entries] + * @property {AstNode[]} [objects] + * @property {AstNode[]} [params] + */ + +const { + parse: parse$2, SyntaxError: JSDocTypeSyntaxError$1, +} = jsdoctypePermissive; + +const { + parse: parseJsdoc, SyntaxError: JSDocSyntaxError$1, +} = jsdoctypeJsdoc; +const { + parse: parseClosure, SyntaxError: ClosureSyntaxError$1, +} = jsdoctypeClosure; +const { + parse: parseTypeScript, SyntaxError: TypeScriptSyntaxError$1, +} = jsdoctypeTypescript; + +const {inspect} = util__default['default']; + +var parsing = { + + /** + * A class for JSDoc-like type expression syntax errors. + * @constructor + * @extends {Error} + */ + JSDocTypeSyntaxError: JSDocTypeSyntaxError$1, + + /** + * A class for JSDoc-specific type expression syntax errors. + * @constructor + * @extends {Error} + */ + JSDocSyntaxError: JSDocSyntaxError$1, + + /** + * A class for Closure type expression syntax errors. + * @constructor + * @extends {Error} + */ + ClosureSyntaxError: ClosureSyntaxError$1, + + /** + * A class for TypeScript type expression syntax errors. + * @constructor + * @extends {Error} + */ + TypeScriptSyntaxError: TypeScriptSyntaxError$1, + + /** + * @typedef {object} ParseOptions + * @property {"permissive"|"jsdoc"|"closure"|"typescript"} [mode='permissive'] + * @property {"TopTypeExpr"|"BroadNamepathExpr"|"NamepathExpr"|"ExternalNameExpr"|"ModuleNameExpr"} [startRule="TopTypeExpr"] + */ + + /** + * Parse the specified type expression string. + * @param {string} typeExprStr Type expression string. + * @param {ParseOptions} opts + * @return {AstNode} AST. + */ + parse (typeExprStr, {mode = 'permissive', startRule = 'TopTypeExpr'} = {}) { + switch (mode) { + case 'jsdoc': + return parseJsdoc(typeExprStr, {startRule}); + case 'closure': + return parseClosure(typeExprStr, {startRule}); + case 'typescript': + return parseTypeScript(typeExprStr, {startRule}); + case 'permissive': + return parse$2(typeExprStr, {startRule}); + default: + throw new TypeError('Unrecognized mode: ' + inspect(mode)); + } + }, +}; + +const {OPTIONAL, PARENTHESIS} = NodeType_1; +const {OptionalTypeSyntax, VariadicTypeSyntax} = SyntaxType; +const {format} = util__default['default']; + +/** @typedef {import('./parsing').AstNode} AstNode */ +/** @typedef {(node) => string} ConcretePublish */ +/** @typedef {{ [T in import('./NodeType').Type]: (node: AstNode, publish: ConcretePublish) => string }} Publisher */ + +/** + * @param {AstNode} node + * @param {Publisher} [opt_publisher] + * @return {string} + */ +function publish$1(node, opt_publisher) { + const publisher = opt_publisher || createDefaultPublisher$1(); + return publisher[node.type](node, function(childNode) { + return publish$1(childNode, publisher); + }); +} + +/** + * @private + * @param {string} str + * @param {'none'|'single'|'double'|undefined} quoteStyle + * @returns {string} Formatted string + */ +function addQuotesForName (str, quoteStyle) { + // For `MemberName`, not strings + if (!quoteStyle || quoteStyle === 'none') { + return str; + } + const singleQuoteStyle = quoteStyle === 'single'; + + return format( + singleQuoteStyle + ? "'%s'" + : '"%s"', + str + .replace(/\\/g, '\\\\') + .replace( + singleQuoteStyle ? /'/gu : /"/gu, + '\\' + (singleQuoteStyle ? "'" : '"') + ) + ); +} + +/** @return {Publisher} */ +function createDefaultPublisher$1() { + return { + NAME (nameNode) { + return nameNode.name; + }, + MEMBER (memberNode, concretePublish) { + return format('%s.%s%s', concretePublish(memberNode.owner), + memberNode.hasEventPrefix ? 'event:' : '', + addQuotesForName(memberNode.name, memberNode.quoteStyle)); + }, + UNION (unionNode, concretePublish) { + return format('%s | %s', concretePublish(unionNode.left), + concretePublish(unionNode.right)); + }, + INTERSECTION (unionNode, concretePublish) { + return format('%s & %s', concretePublish(unionNode.left), + concretePublish(unionNode.right)); + }, + VARIADIC (variadicNode, concretePublish) { + if (variadicNode.meta.syntax === VariadicTypeSyntax.ONLY_DOTS) { + return '...'; + } + return format('...%s', concretePublish(variadicNode.value)); + }, + RECORD (recordNode, concretePublish) { + const concretePublishedEntries = recordNode.entries.map(concretePublish); + return format('{%s}', concretePublishedEntries.join(', ')); + }, + RECORD_ENTRY (entryNode, concretePublish) { + const {readonly, value, key, quoteStyle} = entryNode; + const readonlyString = readonly ? 'readonly ' : ''; + if (!value) return readonlyString + addQuotesForName(key, quoteStyle); + const keySuffix = ( + value.type === OPTIONAL && + value.meta.syntax === OptionalTypeSyntax.SUFFIX_KEY_QUESTION_MARK + ) + ? '?' + : ''; + return format('%s%s%s: %s', readonlyString, addQuotesForName(key, quoteStyle), keySuffix, concretePublish(value)); + }, + TUPLE (tupleNode, concretePublish) { + const concretePublishedEntries = tupleNode.entries.map(concretePublish); + return format('[%s]', concretePublishedEntries.join(', ')); + }, + GENERIC (genericNode, concretePublish) { + const concretePublishedObjects = genericNode.objects.map(concretePublish); + switch (genericNode.meta.syntax) { + case 'SQUARE_BRACKET': + return format('%s[]', concretePublishedObjects.join(', ')); + case 'ANGLE_BRACKET_WITH_DOT': + return format('%s.<%s>', concretePublish(genericNode.subject), + concretePublishedObjects.join(', ')); + } + return format('%s<%s>', concretePublish(genericNode.subject), + concretePublishedObjects.join(', ')); + }, + MODULE (moduleNode, concretePublish) { + return format('module:%s', concretePublish(moduleNode.value)); + }, + FILE_PATH (filePathNode) { + return addQuotesForName(filePathNode.path, filePathNode.quoteStyle); + }, + OPTIONAL (optionalNode, concretePublish) { + if (optionalNode.meta.syntax === OptionalTypeSyntax.SUFFIX_KEY_QUESTION_MARK) { + return concretePublish(optionalNode.value); + } + return format('%s=', concretePublish(optionalNode.value)); + }, + NULLABLE (nullableNode, concretePublish) { + return format('?%s', concretePublish(nullableNode.value)); + }, + NOT_NULLABLE (notNullableNode, concretePublish) { + return format('!%s', concretePublish(notNullableNode.value)); + }, + FUNCTION (functionNode, concretePublish) { + const publidshedParams = functionNode.params.map(concretePublish); + + if (functionNode.new) { + publidshedParams.unshift(format('new: %s', + concretePublish(functionNode.new))); + } + + if (functionNode.this) { + publidshedParams.unshift(format('this: %s', + concretePublish(functionNode.this))); + } + + if (functionNode.returns) { + return format('function(%s): %s', publidshedParams.join(', '), + concretePublish(functionNode.returns)); + } + + return format('function(%s)', publidshedParams.join(', ')); + }, + ARROW (functionNode, concretePublish) { + const publishedParams = functionNode.params.map(concretePublish); + return (functionNode.new ? 'new ' : '') + format('(%s) => %s', publishedParams.join(', '), concretePublish(functionNode.returns)); + }, + NAMED_PARAMETER (parameterNode, concretePublish) { + return parameterNode.name + ': ' + concretePublish(parameterNode.typeName); + }, + ANY () { + return '*'; + }, + UNKNOWN () { + return '?'; + }, + INNER_MEMBER (memberNode, concretePublish) { + return concretePublish(memberNode.owner) + '~' + + (memberNode.hasEventPrefix ? 'event:' : '') + + addQuotesForName(memberNode.name, memberNode.quoteStyle); + }, + INSTANCE_MEMBER (memberNode, concretePublish) { + return concretePublish(memberNode.owner) + '#' + + (memberNode.hasEventPrefix ? 'event:' : '') + + addQuotesForName(memberNode.name, memberNode.quoteStyle); + }, + STRING_VALUE (stringValueNode) { + return addQuotesForName(stringValueNode.string, stringValueNode.quoteStyle) + }, + NUMBER_VALUE (numberValueNode) { + return numberValueNode.number; + }, + EXTERNAL (externalNode /* , concretePublish */) { + const {name, quoteStyle} = externalNode; + return format('external:%s', addQuotesForName(name, quoteStyle)); + }, + PARENTHESIS (parenthesizedNode, concretePublish) { + return format('(%s)', concretePublish(parenthesizedNode.value)); + }, + TYPE_QUERY (typeQueryNode, concretePublish) { + return format('typeof %s', concretePublish(typeQueryNode.name)); + }, + KEY_QUERY (keyQueryNode, concretePublish) { + if (keyQueryNode.value.type === PARENTHESIS) { + return format('keyof%s', concretePublish(keyQueryNode.value)); + } + return format('keyof %s', concretePublish(keyQueryNode.value)); + }, + IMPORT (importNode, concretePublish) { + return format('import(%s)', concretePublish(importNode.path)); + }, + }; +} + + +var publishing = { + publish: publish$1, + createDefaultPublisher: createDefaultPublisher$1, +}; + +/** @typedef {import('./NodeType').Type} NodeType */ +/** @typedef {{ type: NodeType }} Node */ +/** @typedef {(node: Node, parentPropName: string | null, parentNode: Node | null) => void} TraversalCallback */ + +/** + * Traverse the specified AST. + * @param {Node} node AST to traverse. + * @param {TraversalCallback} [opt_onEnter] Callback for onEnter. + * @param {TraversalCallback} [opt_onLeave] Callback for onLeave. + */ +function traverse$1(node, opt_onEnter, opt_onLeave) { + if (opt_onEnter) opt_onEnter(node, null, null); + + const childNodeInfo = _collectChildNodeInfo(node); + childNodeInfo.forEach(function([childNode, parentPropName, parentNode]) { + traverse$1(childNode, opt_onEnter ? (node, pn, pNode) => { + opt_onEnter(node, pn || parentPropName, pNode || parentNode); + } : null, opt_onLeave ? (node, pn, pNode) => { + opt_onLeave(node, pn || parentPropName, pNode || parentNode); + } : null); + }); + + if (opt_onLeave) opt_onLeave(node, null, null); +} + + +/** + * @private + */ +const _PropertyAccessor = { + NODE (fn, node, parentPropName, parentNode) { + fn(node, parentPropName, parentNode); + }, + NODE_LIST (fn, nodes, parentPropName, parentNode) { + nodes.forEach(function(node) { + fn(node, parentPropName, parentNode); + }); + }, + NULLABLE_NODE (fn, opt_node, parentPropName, parentNode) { + if (opt_node) fn(opt_node, parentPropName, parentNode); + }, +}; + + +/** + * @private + * @type {{ [T in NodeType]: object }} + */ +const _childNodesMap = { + NAME: {}, + NAMED_PARAMETER: { + typeName: _PropertyAccessor.NULLABLE_NODE, + }, + MEMBER: { + owner: _PropertyAccessor.NODE, + }, + UNION: { + left: _PropertyAccessor.NODE, + right: _PropertyAccessor.NODE, + }, + INTERSECTION: { + left: _PropertyAccessor.NODE, + right: _PropertyAccessor.NODE, + }, + VARIADIC: { + value: _PropertyAccessor.NODE, + }, + RECORD: { + entries: _PropertyAccessor.NODE_LIST, + }, + RECORD_ENTRY: { + value: _PropertyAccessor.NULLABLE_NODE, + }, + TUPLE: { + entries: _PropertyAccessor.NODE_LIST, + }, + GENERIC: { + subject: _PropertyAccessor.NODE, + objects: _PropertyAccessor.NODE_LIST, + }, + MODULE: { + value: _PropertyAccessor.NODE, + }, + OPTIONAL: { + value: _PropertyAccessor.NODE, + }, + NULLABLE: { + value: _PropertyAccessor.NODE, + }, + NOT_NULLABLE: { + value: _PropertyAccessor.NODE, + }, + FUNCTION: { + params: _PropertyAccessor.NODE_LIST, + returns: _PropertyAccessor.NULLABLE_NODE, + this: _PropertyAccessor.NULLABLE_NODE, + new: _PropertyAccessor.NULLABLE_NODE, + }, + ARROW: { + params: _PropertyAccessor.NODE_LIST, + returns: _PropertyAccessor.NULLABLE_NODE, + }, + ANY: {}, + UNKNOWN: {}, + INNER_MEMBER: { + owner: _PropertyAccessor.NODE, + }, + INSTANCE_MEMBER: { + owner: _PropertyAccessor.NODE, + }, + STRING_VALUE: {}, + NUMBER_VALUE: {}, + EXTERNAL: {}, + FILE_PATH: {}, + PARENTHESIS: { + value: _PropertyAccessor.NODE, + }, + TYPE_QUERY: { + name: _PropertyAccessor.NODE, + }, + KEY_QUERY: { + value: _PropertyAccessor.NODE, + }, + IMPORT: { + path: _PropertyAccessor.NODE, + }, +}; + + +/** + * @private + * @param {Node} node + */ +function _collectChildNodeInfo(node) { + const childNodeInfo = []; + const propAccessorMap = _childNodesMap[node.type]; + + Object.keys(propAccessorMap).forEach(function(propName) { + const propAccessor = propAccessorMap[propName]; + propAccessor((node, propName, parentNode) => { + childNodeInfo.push([node, propName, parentNode]); + }, node[propName], propName, node); + }); + + return childNodeInfo; +} + +var traversing = { + traverse: traverse$1, +}; + +/** @typedef {import('./lib/parsing').AstNode} AstNode */ + +const { + parse: parse$1, + JSDocTypeSyntaxError, + JSDocSyntaxError, + ClosureSyntaxError, + TypeScriptSyntaxError, +} = parsing; +const {publish, createDefaultPublisher} = publishing; +const {traverse} = traversing; + + + +/** + * Namespace for jsdoctypeparser. + * @namespace + * @exports jsdoctypeparser + */ +var jsdoctypeparser = { + parse: parse$1, + JSDocTypeSyntaxError, + JSDocSyntaxError, + ClosureSyntaxError, + TypeScriptSyntaxError, + publish, + createDefaultPublisher, + traverse, + NodeType: NodeType_1, + SyntaxType, +}; + +var checkTypes = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + + + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const strictNativeTypes = ['undefined', 'null', 'boolean', 'number', 'bigint', 'string', 'symbol', 'object', 'Array', 'Function', 'Date', 'RegExp']; + +const adjustNames = (type, preferred, isGenericMatch, nodeName, node, parentNode) => { + let ret = preferred; + + if (isGenericMatch) { + if (preferred === '[]') { + if (parentNode.objects[0].type === 'UNION') { + parentNode.objects[0] = { + type: 'PARENTHESIS', + value: parentNode.objects[0] + }; + } + + parentNode.meta.syntax = 'SQUARE_BRACKET'; + ret = 'Array'; + } else { + const dotBracketEnd = preferred.match(/\.(?:<>)?$/u); + + if (dotBracketEnd) { + parentNode.meta.syntax = 'ANGLE_BRACKET_WITH_DOT'; + ret = preferred.slice(0, -dotBracketEnd[0].length); + } else { + const bracketEnd = preferred.endsWith('<>'); + + if (bracketEnd) { + parentNode.meta.syntax = 'ANGLE_BRACKET'; + ret = preferred.slice(0, -2); + } else if (parentNode.meta.syntax === 'SQUARE_BRACKET' && (nodeName === '[]' || nodeName === 'Array')) { + parentNode.meta.syntax = 'ANGLE_BRACKET'; + } + } + } + } else if (type === 'ANY') { + node.type = 'NAME'; + } + + node.name = ret.replace(/(?:\.|<>|\.<>|\[\])$/u, ''); // For bare pseudo-types like `<>` + + if (!ret) { + node.name = nodeName; + } +}; + +var _default = (0, _iterateJsdoc.default)(({ + jsdocNode, + sourceCode, + report, + utils, + settings, + context +}) => { + const jsdocTagsWithPossibleType = utils.filterTags(tag => { + return utils.tagMightHaveTypePosition(tag.tag); + }); + const { + preferredTypes, + structuredTags, + mode + } = settings; + const { + noDefaults, + unifyParentAndChildTypeChecks, + exemptTagContexts = [] + } = context.options[0] || {}; + + const getPreferredTypeInfo = (_type, nodeName, parentName, parentNode) => { + let hasMatchingPreferredType; + let isGenericMatch; + let typeName = nodeName; + + if (Object.keys(preferredTypes).length) { + const parentType = parentName === 'subject'; + + if (unifyParentAndChildTypeChecks || parentType) { + var _parentNode$meta; + + const syntax = parentNode === null || parentNode === void 0 ? void 0 : (_parentNode$meta = parentNode.meta) === null || _parentNode$meta === void 0 ? void 0 : _parentNode$meta.syntax; + [['.', 'ANGLE_BRACKET_WITH_DOT'], ['.<>', 'ANGLE_BRACKET_WITH_DOT'], ['<>', 'ANGLE_BRACKET']].some(([checkPostFix, syn]) => { + isGenericMatch = (preferredTypes === null || preferredTypes === void 0 ? void 0 : preferredTypes[nodeName + checkPostFix]) !== undefined && syntax === syn; + + if (isGenericMatch) { + typeName += checkPostFix; + } + + return isGenericMatch; + }); + + if (!isGenericMatch && parentType) { + [['[]', 'SQUARE_BRACKET'], ['.', 'ANGLE_BRACKET_WITH_DOT'], ['.<>', 'ANGLE_BRACKET_WITH_DOT'], ['<>', 'ANGLE_BRACKET']].some(([checkPostFix, syn]) => { + isGenericMatch = (preferredTypes === null || preferredTypes === void 0 ? void 0 : preferredTypes[checkPostFix]) !== undefined && syntax === syn; + + if (isGenericMatch) { + typeName = checkPostFix; + } + + return isGenericMatch; + }); + } + } + + const directNameMatch = (preferredTypes === null || preferredTypes === void 0 ? void 0 : preferredTypes[nodeName]) !== undefined && !Object.values(preferredTypes).includes(nodeName); + const unifiedSyntaxParentMatch = parentType && directNameMatch && unifyParentAndChildTypeChecks; + isGenericMatch = isGenericMatch || unifiedSyntaxParentMatch; + hasMatchingPreferredType = isGenericMatch || directNameMatch && !parentType; + } + + return [hasMatchingPreferredType, typeName, isGenericMatch]; + }; + + jsdocTagsWithPossibleType.forEach(jsdocTag => { + const invalidTypes = []; + let typeAst; + + try { + typeAst = (0, jsdoctypeparser.parse)(jsdocTag.type, { + mode + }); + } catch { + return; + } + + const tagName = jsdocTag.tag; + (0, jsdoctypeparser.traverse)(typeAst, (node, parentName, parentNode) => { + const { + type, + name + } = node; + + if (!['NAME', 'ANY'].includes(type)) { + return; + } + + let nodeName = type === 'ANY' ? '*' : name; + const [hasMatchingPreferredType, typeName, isGenericMatch] = getPreferredTypeInfo(type, nodeName, parentName, parentNode); + let preferred; + let types; + + if (hasMatchingPreferredType) { + const preferredSetting = preferredTypes[typeName]; + nodeName = typeName === '[]' ? typeName : nodeName; + + if (!preferredSetting) { + invalidTypes.push([nodeName]); + } else if (typeof preferredSetting === 'string') { + preferred = preferredSetting; + invalidTypes.push([nodeName, preferred]); + } else if (typeof preferredSetting === 'object') { + preferred = preferredSetting === null || preferredSetting === void 0 ? void 0 : preferredSetting.replacement; + invalidTypes.push([nodeName, preferred, preferredSetting === null || preferredSetting === void 0 ? void 0 : preferredSetting.message]); + } else { + utils.reportSettings('Invalid `settings.jsdoc.preferredTypes`. Values must be falsy, a string, or an object.'); + return; + } + } else if (Object.entries(structuredTags).some(([tag, { + type: typs + }]) => { + types = typs; + return tag === tagName && Array.isArray(types) && !types.includes(nodeName); + })) { + invalidTypes.push([nodeName, types]); + } else if (!noDefaults && type === 'NAME') { + for (const strictNativeType of strictNativeTypes) { + if (strictNativeType === 'object' && mode === 'typescript') { + continue; + } + + if (strictNativeType.toLowerCase() === nodeName.toLowerCase() && strictNativeType !== nodeName && ( // Don't report if user has own map for a strict native type + !preferredTypes || (preferredTypes === null || preferredTypes === void 0 ? void 0 : preferredTypes[strictNativeType]) === undefined)) { + preferred = strictNativeType; + invalidTypes.push([nodeName, preferred]); + break; + } + } + } // For fixer + + + if (preferred) { + adjustNames(type, preferred, isGenericMatch, nodeName, node, parentNode); + } + }); + + if (invalidTypes.length) { + const fixedType = (0, jsdoctypeparser.publish)(typeAst); + invalidTypes.forEach(([badType, preferredType = '', message]) => { + const fix = fixer => { + return fixer.replaceText(jsdocNode, sourceCode.getText(jsdocNode).replace(`{${jsdocTag.type}}`, `{${fixedType}}`)); + }; + + const tagValue = jsdocTag.name ? ` "${jsdocTag.name}"` : ''; + + if (exemptTagContexts.some(({ + tag, + types + }) => { + return tag === tagName && (types === true || types.includes(jsdocTag.type)); + })) { + return; + } + + report(message || `Invalid JSDoc @${tagName}${tagValue} type "${badType}"` + (preferredType ? '; ' : '.') + (preferredType ? `prefer: ${JSON.stringify(preferredType)}.` : ''), preferredType ? fix : null, jsdocTag, message ? { + tagName, + tagValue + } : null); + }); + } + }); +}, { + iterateAllJsdocs: true, + meta: { + docs: { + description: 'Reports invalid types.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-types' + }, + fixable: 'code', + schema: [{ + additionalProperties: false, + properties: { + exemptTagContexts: { + items: { + additionalProperties: false, + properties: { + tag: { + type: 'string' + }, + types: { + oneOf: [{ + type: 'boolean' + }, { + items: { + type: 'string' + }, + type: 'array' + }] + } + }, + type: 'object' + }, + type: 'array' + }, + noDefaults: { + type: 'boolean' + }, + unifyParentAndChildTypeChecks: { + type: 'boolean' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=checkTypes.js.map +}); + +var require$$0 = [ + "0BSD", + "AAL", + "ADSL", + "AFL-1.1", + "AFL-1.2", + "AFL-2.0", + "AFL-2.1", + "AFL-3.0", + "AGPL-1.0-only", + "AGPL-1.0-or-later", + "AGPL-3.0-only", + "AGPL-3.0-or-later", + "AMDPLPA", + "AML", + "AMPAS", + "ANTLR-PD", + "ANTLR-PD-fallback", + "APAFML", + "APL-1.0", + "APSL-1.0", + "APSL-1.1", + "APSL-1.2", + "APSL-2.0", + "Abstyles", + "Adobe-2006", + "Adobe-Glyph", + "Afmparse", + "Aladdin", + "Apache-1.0", + "Apache-1.1", + "Apache-2.0", + "Artistic-1.0", + "Artistic-1.0-Perl", + "Artistic-1.0-cl8", + "Artistic-2.0", + "BSD-1-Clause", + "BSD-2-Clause", + "BSD-2-Clause-Patent", + "BSD-2-Clause-Views", + "BSD-3-Clause", + "BSD-3-Clause-Attribution", + "BSD-3-Clause-Clear", + "BSD-3-Clause-LBNL", + "BSD-3-Clause-No-Nuclear-License", + "BSD-3-Clause-No-Nuclear-License-2014", + "BSD-3-Clause-No-Nuclear-Warranty", + "BSD-3-Clause-Open-MPI", + "BSD-4-Clause", + "BSD-4-Clause-UC", + "BSD-Protection", + "BSD-Source-Code", + "BSL-1.0", + "BUSL-1.1", + "Bahyph", + "Barr", + "Beerware", + "BitTorrent-1.0", + "BitTorrent-1.1", + "BlueOak-1.0.0", + "Borceux", + "CAL-1.0", + "CAL-1.0-Combined-Work-Exception", + "CATOSL-1.1", + "CC-BY-1.0", + "CC-BY-2.0", + "CC-BY-2.5", + "CC-BY-3.0", + "CC-BY-3.0-AT", + "CC-BY-3.0-US", + "CC-BY-4.0", + "CC-BY-NC-1.0", + "CC-BY-NC-2.0", + "CC-BY-NC-2.5", + "CC-BY-NC-3.0", + "CC-BY-NC-4.0", + "CC-BY-NC-ND-1.0", + "CC-BY-NC-ND-2.0", + "CC-BY-NC-ND-2.5", + "CC-BY-NC-ND-3.0", + "CC-BY-NC-ND-3.0-IGO", + "CC-BY-NC-ND-4.0", + "CC-BY-NC-SA-1.0", + "CC-BY-NC-SA-2.0", + "CC-BY-NC-SA-2.5", + "CC-BY-NC-SA-3.0", + "CC-BY-NC-SA-4.0", + "CC-BY-ND-1.0", + "CC-BY-ND-2.0", + "CC-BY-ND-2.5", + "CC-BY-ND-3.0", + "CC-BY-ND-4.0", + "CC-BY-SA-1.0", + "CC-BY-SA-2.0", + "CC-BY-SA-2.0-UK", + "CC-BY-SA-2.5", + "CC-BY-SA-3.0", + "CC-BY-SA-3.0-AT", + "CC-BY-SA-4.0", + "CC-PDDC", + "CC0-1.0", + "CDDL-1.0", + "CDDL-1.1", + "CDLA-Permissive-1.0", + "CDLA-Sharing-1.0", + "CECILL-1.0", + "CECILL-1.1", + "CECILL-2.0", + "CECILL-2.1", + "CECILL-B", + "CECILL-C", + "CERN-OHL-1.1", + "CERN-OHL-1.2", + "CERN-OHL-P-2.0", + "CERN-OHL-S-2.0", + "CERN-OHL-W-2.0", + "CNRI-Jython", + "CNRI-Python", + "CNRI-Python-GPL-Compatible", + "CPAL-1.0", + "CPL-1.0", + "CPOL-1.02", + "CUA-OPL-1.0", + "Caldera", + "ClArtistic", + "Condor-1.1", + "Crossword", + "CrystalStacker", + "Cube", + "D-FSL-1.0", + "DOC", + "DSDP", + "Dotseqn", + "ECL-1.0", + "ECL-2.0", + "EFL-1.0", + "EFL-2.0", + "EPICS", + "EPL-1.0", + "EPL-2.0", + "EUDatagrid", + "EUPL-1.0", + "EUPL-1.1", + "EUPL-1.2", + "Entessa", + "ErlPL-1.1", + "Eurosym", + "FSFAP", + "FSFUL", + "FSFULLR", + "FTL", + "Fair", + "Frameworx-1.0", + "FreeImage", + "GFDL-1.1-invariants-only", + "GFDL-1.1-invariants-or-later", + "GFDL-1.1-no-invariants-only", + "GFDL-1.1-no-invariants-or-later", + "GFDL-1.1-only", + "GFDL-1.1-or-later", + "GFDL-1.2-invariants-only", + "GFDL-1.2-invariants-or-later", + "GFDL-1.2-no-invariants-only", + "GFDL-1.2-no-invariants-or-later", + "GFDL-1.2-only", + "GFDL-1.2-or-later", + "GFDL-1.3-invariants-only", + "GFDL-1.3-invariants-or-later", + "GFDL-1.3-no-invariants-only", + "GFDL-1.3-no-invariants-or-later", + "GFDL-1.3-only", + "GFDL-1.3-or-later", + "GL2PS", + "GLWTPL", + "GPL-1.0-only", + "GPL-1.0-or-later", + "GPL-2.0-only", + "GPL-2.0-or-later", + "GPL-3.0-only", + "GPL-3.0-or-later", + "Giftware", + "Glide", + "Glulxe", + "HPND", + "HPND-sell-variant", + "HTMLTIDY", + "HaskellReport", + "Hippocratic-2.1", + "IBM-pibs", + "ICU", + "IJG", + "IPA", + "IPL-1.0", + "ISC", + "ImageMagick", + "Imlib2", + "Info-ZIP", + "Intel", + "Intel-ACPI", + "Interbase-1.0", + "JPNIC", + "JSON", + "JasPer-2.0", + "LAL-1.2", + "LAL-1.3", + "LGPL-2.0-only", + "LGPL-2.0-or-later", + "LGPL-2.1-only", + "LGPL-2.1-or-later", + "LGPL-3.0-only", + "LGPL-3.0-or-later", + "LGPLLR", + "LPL-1.0", + "LPL-1.02", + "LPPL-1.0", + "LPPL-1.1", + "LPPL-1.2", + "LPPL-1.3a", + "LPPL-1.3c", + "Latex2e", + "Leptonica", + "LiLiQ-P-1.1", + "LiLiQ-R-1.1", + "LiLiQ-Rplus-1.1", + "Libpng", + "Linux-OpenIB", + "MIT", + "MIT-0", + "MIT-CMU", + "MIT-advertising", + "MIT-enna", + "MIT-feh", + "MIT-open-group", + "MITNFA", + "MPL-1.0", + "MPL-1.1", + "MPL-2.0", + "MPL-2.0-no-copyleft-exception", + "MS-PL", + "MS-RL", + "MTLL", + "MakeIndex", + "MirOS", + "Motosoto", + "MulanPSL-1.0", + "MulanPSL-2.0", + "Multics", + "Mup", + "NASA-1.3", + "NBPL-1.0", + "NCGL-UK-2.0", + "NCSA", + "NGPL", + "NIST-PD", + "NIST-PD-fallback", + "NLOD-1.0", + "NLPL", + "NOSL", + "NPL-1.0", + "NPL-1.1", + "NPOSL-3.0", + "NRL", + "NTP", + "NTP-0", + "Naumen", + "Net-SNMP", + "NetCDF", + "Newsletr", + "Nokia", + "Noweb", + "O-UDA-1.0", + "OCCT-PL", + "OCLC-2.0", + "ODC-By-1.0", + "ODbL-1.0", + "OFL-1.0", + "OFL-1.0-RFN", + "OFL-1.0-no-RFN", + "OFL-1.1", + "OFL-1.1-RFN", + "OFL-1.1-no-RFN", + "OGC-1.0", + "OGL-Canada-2.0", + "OGL-UK-1.0", + "OGL-UK-2.0", + "OGL-UK-3.0", + "OGTSL", + "OLDAP-1.1", + "OLDAP-1.2", + "OLDAP-1.3", + "OLDAP-1.4", + "OLDAP-2.0", + "OLDAP-2.0.1", + "OLDAP-2.1", + "OLDAP-2.2", + "OLDAP-2.2.1", + "OLDAP-2.2.2", + "OLDAP-2.3", + "OLDAP-2.4", + "OLDAP-2.5", + "OLDAP-2.6", + "OLDAP-2.7", + "OLDAP-2.8", + "OML", + "OPL-1.0", + "OSET-PL-2.1", + "OSL-1.0", + "OSL-1.1", + "OSL-2.0", + "OSL-2.1", + "OSL-3.0", + "OpenSSL", + "PDDL-1.0", + "PHP-3.0", + "PHP-3.01", + "PSF-2.0", + "Parity-6.0.0", + "Parity-7.0.0", + "Plexus", + "PolyForm-Noncommercial-1.0.0", + "PolyForm-Small-Business-1.0.0", + "PostgreSQL", + "Python-2.0", + "QPL-1.0", + "Qhull", + "RHeCos-1.1", + "RPL-1.1", + "RPL-1.5", + "RPSL-1.0", + "RSA-MD", + "RSCPL", + "Rdisc", + "Ruby", + "SAX-PD", + "SCEA", + "SGI-B-1.0", + "SGI-B-1.1", + "SGI-B-2.0", + "SHL-0.5", + "SHL-0.51", + "SISSL", + "SISSL-1.2", + "SMLNJ", + "SMPPL", + "SNIA", + "SPL-1.0", + "SSH-OpenSSH", + "SSH-short", + "SSPL-1.0", + "SWL", + "Saxpath", + "Sendmail", + "Sendmail-8.23", + "SimPL-2.0", + "Sleepycat", + "Spencer-86", + "Spencer-94", + "Spencer-99", + "SugarCRM-1.1.3", + "TAPR-OHL-1.0", + "TCL", + "TCP-wrappers", + "TMate", + "TORQUE-1.1", + "TOSL", + "TU-Berlin-1.0", + "TU-Berlin-2.0", + "UCL-1.0", + "UPL-1.0", + "Unicode-DFS-2015", + "Unicode-DFS-2016", + "Unicode-TOU", + "Unlicense", + "VOSTROM", + "VSL-1.0", + "Vim", + "W3C", + "W3C-19980720", + "W3C-20150513", + "WTFPL", + "Watcom-1.0", + "Wsuipa", + "X11", + "XFree86-1.1", + "XSkat", + "Xerox", + "Xnet", + "YPL-1.0", + "YPL-1.1", + "ZPL-1.1", + "ZPL-2.0", + "ZPL-2.1", + "Zed", + "Zend-2.0", + "Zimbra-1.3", + "Zimbra-1.4", + "Zlib", + "blessing", + "bzip2-1.0.5", + "bzip2-1.0.6", + "copyleft-next-0.3.0", + "copyleft-next-0.3.1", + "curl", + "diffmark", + "dvipdfm", + "eGenix", + "etalab-2.0", + "gSOAP-1.3b", + "gnuplot", + "iMatix", + "libpng-2.0", + "libselinux-1.0", + "libtiff", + "mpich2", + "psfrag", + "psutils", + "xinetd", + "xpp", + "zlib-acknowledgement" +]; + +var require$$1 = [ + "AGPL-1.0", + "AGPL-3.0", + "BSD-2-Clause-FreeBSD", + "BSD-2-Clause-NetBSD", + "GFDL-1.1", + "GFDL-1.2", + "GFDL-1.3", + "GPL-1.0", + "GPL-2.0", + "GPL-2.0-with-GCC-exception", + "GPL-2.0-with-autoconf-exception", + "GPL-2.0-with-bison-exception", + "GPL-2.0-with-classpath-exception", + "GPL-2.0-with-font-exception", + "GPL-3.0", + "GPL-3.0-with-GCC-exception", + "GPL-3.0-with-autoconf-exception", + "LGPL-2.0", + "LGPL-2.1", + "LGPL-3.0", + "Nunit", + "StandardML-NJ", + "eCos-2.0", + "wxWindows" +]; + +var exceptions = [ + "389-exception", + "Autoconf-exception-2.0", + "Autoconf-exception-3.0", + "Bison-exception-2.2", + "Bootloader-exception", + "Classpath-exception-2.0", + "CLISP-exception-2.0", + "DigiRule-FOSS-exception", + "eCos-exception-2.0", + "Fawkes-Runtime-exception", + "FLTK-exception", + "Font-exception-2.0", + "freertos-exception-2.0", + "GCC-exception-2.0", + "GCC-exception-3.1", + "gnu-javamail-exception", + "GPL-3.0-linking-exception", + "GPL-3.0-linking-source-exception", + "GPL-CC-1.0", + "i2p-gpl-java-exception", + "Libtool-exception", + "Linux-syscall-note", + "LLVM-exception", + "LZMA-exception", + "mif-exception", + "Nokia-Qt-exception-1.1", + "OCaml-LGPL-linking-exception", + "OCCT-exception-1.0", + "OpenJDK-assembly-exception-1.0", + "openvpn-openssl-exception", + "PS-or-PDF-font-exception-20170817", + "Qt-GPL-exception-1.0", + "Qt-LGPL-exception-1.1", + "Qwt-exception-1.0", + "Swift-exception", + "u-boot-exception-2.0", + "Universal-FOSS-exception-1.0", + "WxWindows-exception-3.1" +]; + +var licenses = [] + .concat(require$$0) + .concat(require$$1); + + +var scan = function (source) { + var index = 0; + + function hasMore () { + return index < source.length + } + + // `value` can be a regexp or a string. + // If it is recognized, the matching source string is returned and + // the index is incremented. Otherwise `undefined` is returned. + function read (value) { + if (value instanceof RegExp) { + var chars = source.slice(index); + var match = chars.match(value); + if (match) { + index += match[0].length; + return match[0] + } + } else { + if (source.indexOf(value, index) === index) { + index += value.length; + return value + } + } + } + + function skipWhitespace () { + read(/[ ]*/); + } + + function operator () { + var string; + var possibilities = ['WITH', 'AND', 'OR', '(', ')', ':', '+']; + for (var i = 0; i < possibilities.length; i++) { + string = read(possibilities[i]); + if (string) { + break + } + } + + if (string === '+' && index > 1 && source[index - 2] === ' ') { + throw new Error('Space before `+`') + } + + return string && { + type: 'OPERATOR', + string: string + } + } + + function idstring () { + return read(/[A-Za-z0-9-.]+/) + } + + function expectIdstring () { + var string = idstring(); + if (!string) { + throw new Error('Expected idstring at offset ' + index) + } + return string + } + + function documentRef () { + if (read('DocumentRef-')) { + var string = expectIdstring(); + return { type: 'DOCUMENTREF', string: string } + } + } + + function licenseRef () { + if (read('LicenseRef-')) { + var string = expectIdstring(); + return { type: 'LICENSEREF', string: string } + } + } + + function identifier () { + var begin = index; + var string = idstring(); + + if (licenses.indexOf(string) !== -1) { + return { + type: 'LICENSE', + string: string + } + } else if (exceptions.indexOf(string) !== -1) { + return { + type: 'EXCEPTION', + string: string + } + } + + index = begin; + } + + // Tries to read the next token. Returns `undefined` if no token is + // recognized. + function parseToken () { + // Ordering matters + return ( + operator() || + documentRef() || + licenseRef() || + identifier() + ) + } + + var tokens = []; + while (hasMore()) { + skipWhitespace(); + if (!hasMore()) { + break + } + + var token = parseToken(); + if (!token) { + throw new Error('Unexpected `' + source[index] + + '` at offset ' + index) + } + + tokens.push(token); + } + return tokens +}; + +// The ABNF grammar in the spec is totally ambiguous. +// +// This parser follows the operator precedence defined in the +// `Order of Precedence and Parentheses` section. + +var parse = function (tokens) { + var index = 0; + + function hasMore () { + return index < tokens.length + } + + function token () { + return hasMore() ? tokens[index] : null + } + + function next () { + if (!hasMore()) { + throw new Error() + } + index++; + } + + function parseOperator (operator) { + var t = token(); + if (t && t.type === 'OPERATOR' && operator === t.string) { + next(); + return t.string + } + } + + function parseWith () { + if (parseOperator('WITH')) { + var t = token(); + if (t && t.type === 'EXCEPTION') { + next(); + return t.string + } + throw new Error('Expected exception after `WITH`') + } + } + + function parseLicenseRef () { + // TODO: Actually, everything is concatenated into one string + // for backward-compatibility but it could be better to return + // a nice structure. + var begin = index; + var string = ''; + var t = token(); + if (t.type === 'DOCUMENTREF') { + next(); + string += 'DocumentRef-' + t.string + ':'; + if (!parseOperator(':')) { + throw new Error('Expected `:` after `DocumentRef-...`') + } + } + t = token(); + if (t.type === 'LICENSEREF') { + next(); + string += 'LicenseRef-' + t.string; + return { license: string } + } + index = begin; + } + + function parseLicense () { + var t = token(); + if (t && t.type === 'LICENSE') { + next(); + var node = { license: t.string }; + if (parseOperator('+')) { + node.plus = true; + } + var exception = parseWith(); + if (exception) { + node.exception = exception; + } + return node + } + } + + function parseParenthesizedExpression () { + var left = parseOperator('('); + if (!left) { + return + } + + var expr = parseExpression(); + + if (!parseOperator(')')) { + throw new Error('Expected `)`') + } + + return expr + } + + function parseAtom () { + return ( + parseParenthesizedExpression() || + parseLicenseRef() || + parseLicense() + ) + } + + function makeBinaryOpParser (operator, nextParser) { + return function parseBinaryOp () { + var left = nextParser(); + if (!left) { + return + } + + if (!parseOperator(operator)) { + return left + } + + var right = parseBinaryOp(); + if (!right) { + throw new Error('Expected expression') + } + return { + left: left, + conjunction: operator.toLowerCase(), + right: right + } + } + } + + var parseAnd = makeBinaryOpParser('AND', parseAtom); + var parseExpression = makeBinaryOpParser('OR', parseAnd); + + var node = parseExpression(); + if (!node || hasMore()) { + throw new Error('Syntax error') + } + return node +}; + +var spdxExpressionParse = function (source) { + return parse(scan(source)) +}; + +var checkValues = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _semver = _interopRequireDefault(require$$0__default$2['default']); + +var _spdxExpressionParse = _interopRequireDefault(spdxExpressionParse); + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _default = (0, _iterateJsdoc.default)(({ + utils, + report, + context +}) => { + const options = context.options[0] || {}; + const { + allowedLicenses = null, + allowedAuthors = null, + licensePattern = '/([^\n]*)/gu' + } = options; + utils.forEachPreferredTag('version', (jsdocParameter, targetTagName) => { + const version = jsdocParameter.description.trim(); + + if (!version) { + report(`Missing JSDoc @${targetTagName}.`, null, jsdocParameter); + } else if (!_semver.default.valid(version)) { + report(`Invalid JSDoc @${targetTagName}: "${jsdocParameter.description}".`, null, jsdocParameter); + } + }); + utils.forEachPreferredTag('since', (jsdocParameter, targetTagName) => { + const version = jsdocParameter.description.trim(); + + if (!version) { + report(`Missing JSDoc @${targetTagName}.`, null, jsdocParameter); + } else if (!_semver.default.valid(version)) { + report(`Invalid JSDoc @${targetTagName}: "${jsdocParameter.description}".`, null, jsdocParameter); + } + }); + utils.forEachPreferredTag('license', (jsdocParameter, targetTagName) => { + const licenseRegex = utils.getRegexFromString(licensePattern, 'g'); + const match = jsdocParameter.description.match(licenseRegex); + const license = match && match[1] || match[0]; + + if (!license.trim()) { + report(`Missing JSDoc @${targetTagName}.`, null, jsdocParameter); + } else if (allowedLicenses) { + if (allowedLicenses !== true && !allowedLicenses.includes(license)) { + report(`Invalid JSDoc @${targetTagName}: "${license}"; expected one of ${allowedLicenses.join(', ')}.`, null, jsdocParameter); + } + } else { + try { + (0, _spdxExpressionParse.default)(license); + } catch { + report(`Invalid JSDoc @${targetTagName}: "${license}"; expected SPDX expression: https://spdx.org/licenses/.`, null, jsdocParameter); + } + } + }); + utils.forEachPreferredTag('author', (jsdocParameter, targetTagName) => { + const author = jsdocParameter.description.trim(); + + if (!author) { + report(`Missing JSDoc @${targetTagName}.`, null, jsdocParameter); + } else if (allowedAuthors && !allowedAuthors.includes(author)) { + report(`Invalid JSDoc @${targetTagName}: "${jsdocParameter.description}"; expected one of ${allowedAuthors.join(', ')}.`, null, jsdocParameter); + } + }); +}, { + iterateAllJsdocs: true, + meta: { + docs: { + description: 'This rule checks the values for a handful of tags: `@version`, `@since`, `@license` and `@author`.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-values' + }, + schema: [{ + additionalProperties: false, + properties: { + allowedAuthors: { + items: { + type: 'string' + }, + type: 'array' + }, + allowedLicenses: { + anyOf: [{ + items: { + type: 'string' + }, + type: 'array' + }, { + type: 'boolean' + }] + }, + licensePattern: { + type: 'string' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=checkValues.js.map +}); + +var emptyTags = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const defaultEmptyTags = new Set(['abstract', 'async', 'generator', 'global', 'hideconstructor', 'ignore', 'inner', 'instance', 'override', 'readonly', // jsdoc doesn't use this form in its docs, but allow for compatibility with +// TypeScript which allows and Closure which requires +'inheritDoc', // jsdoc doesn't use but allow for TypeScript +'internal']); +const emptyIfNotClosure = new Set(['package', 'private', 'protected', 'public', 'static', // Closure doesn't allow with this casing +'inheritdoc']); + +var _default = (0, _iterateJsdoc.default)(({ + settings, + jsdoc, + utils +}) => { + const emptyTags = utils.filterTags(({ + tag: tagName + }) => { + return defaultEmptyTags.has(tagName) || utils.hasOptionTag(tagName) && jsdoc.tags.some(({ + tag + }) => { + return tag === tagName; + }) || settings.mode !== 'closure' && emptyIfNotClosure.has(tagName); + }); + emptyTags.forEach(tag => { + const content = tag.name || tag.description || tag.type; + + if (content.trim()) { + const fix = () => { + utils.setTag(tag); + }; + + utils.reportJSDoc(`@${tag.tag} should be empty.`, tag, fix, true); + } + }); +}, { + checkInternal: true, + checkPrivate: true, + iterateAllJsdocs: true, + meta: { + docs: { + description: 'Expects specific tags to be empty of any content.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-empty-tags' + }, + fixable: 'code', + schema: [{ + additionalProperties: false, + properties: { + tags: { + items: { + type: 'string' + }, + type: 'array' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=emptyTags.js.map +}); + +var implementsOnClasses = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _default = (0, _iterateJsdoc.default)(({ + report, + utils +}) => { + const iteratingFunction = utils.isIteratingFunction(); + + if (iteratingFunction) { + if (utils.hasATag(['class', 'constructor']) || utils.isConstructor()) { + return; + } + } else if (!utils.isVirtualFunction()) { + return; + } + + utils.forEachPreferredTag('implements', tag => { + report('@implements used on a non-constructor function', null, tag); + }); +}, { + contextDefaults: true, + meta: { + docs: { + description: 'Reports an issue with any non-constructor function using `@implements`.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-implements-on-classes' + }, + schema: [{ + additionalProperties: false, + properties: { + contexts: { + items: { + type: 'string' + }, + type: 'array' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=implementsOnClasses.js.map +}); + +var matchDescription = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _lodash = _interopRequireDefault(lodash__default['default']); + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// If supporting Node >= 10, we could loosen the default to this for the +// initial letter: \\p{Upper} +const matchDescriptionDefault = '^[A-Z`\\d_][\\s\\S]*[.?!`]$'; + +const stringOrDefault = (value, userDefault) => { + return typeof value === 'string' ? value : userDefault || matchDescriptionDefault; +}; + +var _default = (0, _iterateJsdoc.default)(({ + jsdoc, + report, + context, + utils +}) => { + const options = context.options[0] || {}; + + const validateDescription = (description, tag) => { + if (!tag && options.mainDescription === false) { + return; + } + + let tagValue = options.mainDescription; + + if (tag) { + const tagName = tag.tag; + tagValue = options.tags[tagName]; + } + + const regex = utils.getRegexFromString(stringOrDefault(tagValue, options.matchDescription)); + + if (!regex.test(description)) { + report('JSDoc description does not satisfy the regex pattern.', null, tag || { + // Add one as description would typically be into block + line: jsdoc.source[0].number + 1 + }); + } + }; + + if (jsdoc.description) { + const { + description + } = utils.getDescription(); + validateDescription(description.replace(/\s+$/, '')); + } + + if (!options.tags || !Object.keys(options.tags).length) { + return; + } + + const hasOptionTag = tagName => { + return Boolean(options.tags[tagName]); + }; + + utils.forEachPreferredTag('description', (matchingJsdocTag, targetTagName) => { + const description = (matchingJsdocTag.name + ' ' + matchingJsdocTag.description).trim(); + + if (hasOptionTag(targetTagName)) { + validateDescription(description, matchingJsdocTag); + } + }, true); + const whitelistedTags = utils.filterTags(({ + tag: tagName + }) => { + return hasOptionTag(tagName); + }); + const { + tagsWithNames, + tagsWithoutNames + } = utils.getTagsByType(whitelistedTags); + tagsWithNames.some(tag => { + const description = _lodash.default.trimStart(tag.description, '- '); + + return validateDescription(description, tag); + }); + tagsWithoutNames.some(tag => { + const description = (tag.name + ' ' + tag.description).trim(); + return validateDescription(description, tag); + }); +}, { + contextDefaults: true, + meta: { + docs: { + description: 'Enforces a regular expression pattern on descriptions.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-match-description' + }, + schema: [{ + additionalProperties: false, + properties: { + contexts: { + items: { + type: 'string' + }, + type: 'array' + }, + mainDescription: { + oneOf: [{ + format: 'regex', + type: 'string' + }, { + type: 'boolean' + }] + }, + matchDescription: { + format: 'regex', + type: 'string' + }, + tags: { + patternProperties: { + '.*': { + oneOf: [{ + format: 'regex', + type: 'string' + }, { + enum: [true], + type: 'boolean' + }] + } + }, + type: 'object' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=matchDescription.js.map +}); + +var newlineAfterDescription = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _lodash = _interopRequireDefault(lodash__default['default']); + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _default = (0, _iterateJsdoc.default)(({ + jsdoc, + report, + context, + jsdocNode, + sourceCode, + indent, + utils +}) => { + let always; + + if (!jsdoc.description.trim() || !jsdoc.tags.length) { + return; + } + + if (_lodash.default.has(context.options, 0)) { + always = context.options[0] === 'always'; + } else { + always = true; + } + + const { + description, + lastDescriptionLine + } = utils.getDescription(); + const descriptionEndsWithANewline = /\n\r?$/.test(description); + + if (always) { + if (!descriptionEndsWithANewline) { + const sourceLines = sourceCode.getText(jsdocNode).split('\n'); + report('There must be a newline after the description of the JSDoc block.', fixer => { + // Add the new line + const injectedLine = `${indent} *` + (sourceLines[lastDescriptionLine].endsWith('\r') ? '\r' : ''); + sourceLines.splice(lastDescriptionLine + 1, 0, injectedLine); + return fixer.replaceText(jsdocNode, sourceLines.join('\n')); + }, { + line: lastDescriptionLine + }); + } + } else if (descriptionEndsWithANewline) { + const sourceLines = sourceCode.getText(jsdocNode).split('\n'); + report('There must be no newline after the description of the JSDoc block.', fixer => { + // Remove the extra line + sourceLines.splice(lastDescriptionLine, 1); + return fixer.replaceText(jsdocNode, sourceLines.join('\n')); + }, { + line: lastDescriptionLine + }); + } +}, { + iterateAllJsdocs: true, + meta: { + docs: { + description: 'Enforces a consistent padding of the block description.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-newline-after-description' + }, + fixable: 'whitespace', + schema: [{ + enum: ['always', 'never'], + type: 'string' + }], + type: 'layout' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=newlineAfterDescription.js.map +}); + +var noBadBlocks = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + + + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const commentRegexp = /^\/\*(?!\*)/; + +var _default = (0, _iterateJsdoc.default)(({ + context, + sourceCode, + allComments, + makeReport +}) => { + const [{ + ignore = ['ts-check', 'ts-expect-error', 'ts-ignore', 'ts-nocheck'] + } = {}] = context.options; + const nonJsdocNodes = allComments.filter(comment => { + const commentText = sourceCode.getText(comment); + + if (!commentRegexp.test(commentText)) { + return false; + } + + const [{ + tags = {} + } = {}] = (0, lib.parse)(`${commentText.slice(0, 2)}*${commentText.slice(2)}`); + return tags.length && !tags.some(({ + tag + }) => { + return ignore.includes(tag); + }); + }); + + if (!nonJsdocNodes.length) { + return; + } + + nonJsdocNodes.forEach(node => { + const report = makeReport(context, node); + + const fix = fixer => { + const text = sourceCode.getText(node); + return fixer.replaceText(node, text.replace('/*', '/**')); + }; + + report('Expected JSDoc-like comment to begin with two asterisks.', fix); + }); +}, { + checkFile: true, + meta: { + docs: { + description: 'This rule checks for multi-line-style comments which fail to meet the criteria of a jsdoc block.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-no-bad-blocks' + }, + fixable: 'code', + schema: [{ + additionalProperties: false, + properties: { + ignore: { + items: { + type: 'string' + }, + type: 'array' + } + }, + type: 'object' + }], + type: 'layout' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=noBadBlocks.js.map +}); + +var noDefaults = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _default = (0, _iterateJsdoc.default)(({ + context, + utils +}) => { + const { + noOptionalParamNames + } = context.options[0] || {}; + const paramTags = utils.getPresentTags(['param', 'arg', 'argument']); + paramTags.forEach(tag => { + if (noOptionalParamNames && tag.optional) { + utils.reportJSDoc(`Optional param names are not permitted on @${tag.tag}.`, tag, () => { + utils.changeTag(tag, { + name: tag.name.replace(/([^=]*)(=.+)?/, '$1') + }); + }); + } else if (tag.default) { + utils.reportJSDoc(`Defaults are not permitted on @${tag.tag}.`, tag, () => { + utils.changeTag(tag, { + name: tag.name.replace(/([^=]*)(=.+)?/, '[$1]') + }); + }); + } + }); + const defaultTags = utils.getPresentTags(['default', 'defaultvalue']); + defaultTags.forEach(tag => { + if (tag.description.trim()) { + utils.reportJSDoc(`Default values are not permitted on @${tag.tag}.`, tag, () => { + utils.changeTag(tag, { + description: '', + postTag: '' + }); + }); + } + }); +}, { + contextDefaults: true, + meta: { + docs: { + description: 'This rule reports defaults being used on the relevant portion of `@param` or `@default`.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-no-defaults' + }, + fixable: 'code', + schema: [{ + additionalProperties: false, + properties: { + contexts: { + items: { + type: 'string' + }, + type: 'array' + }, + noOptionalParamNames: { + type: 'boolean' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=noDefaults.js.map +}); + +var noTypes = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const removeType = ({ + tokens +}) => { + tokens.postTag = ''; + tokens.type = ''; +}; + +var _default = (0, _iterateJsdoc.default)(({ + utils +}) => { + if (!utils.isIteratingFunction() && !utils.isVirtualFunction()) { + return; + } + + const tags = utils.getPresentTags(['param', 'arg', 'argument', 'returns', 'return']); + tags.forEach(tag => { + if (tag.type) { + utils.reportJSDoc(`Types are not permitted on @${tag.tag}.`, tag, () => { + tag.source.forEach(removeType); + }); + } + }); +}, { + contextDefaults: true, + meta: { + docs: { + description: 'This rule reports types being used on `@param` or `@returns`.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-no-types' + }, + fixable: 'code', + schema: [{ + additionalProperties: false, + properties: { + contexts: { + items: { + type: 'string' + }, + type: 'array' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=noTypes.js.map +}); + +var noUndefinedTypes = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + + + +var _lodash = _interopRequireDefault(lodash__default['default']); + + + +var _iterateJsdoc = _interopRequireWildcard(iterateJsdoc_1); + +var _jsdocUtils = _interopRequireDefault(jsdocUtils); + +function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } + +function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const extraTypes = ['null', 'undefined', 'void', 'string', 'boolean', 'object', 'function', 'symbol', 'number', 'bigint', 'NaN', 'Infinity', 'any', '*', 'this', 'true', 'false', 'Array', 'Object', 'RegExp', 'Date', 'Function']; + +const stripPseudoTypes = str => { + return str && str.replace(/(?:\.|<>|\.<>|\[\])$/u, ''); +}; + +var _default = (0, _iterateJsdoc.default)(({ + context, + node, + report, + settings, + sourceCode, + utils +}) => { + var _globalScope$childSco; + + const { + scopeManager + } = sourceCode; + const { + globalScope + } = scopeManager; + const { + definedTypes = [] + } = context.options[0] || {}; + let definedPreferredTypes = []; + const { + preferredTypes, + structuredTags, + mode + } = settings; + + if (Object.keys(preferredTypes).length) { + definedPreferredTypes = Object.values(preferredTypes).map(preferredType => { + if (typeof preferredType === 'string') { + // May become an empty string but will be filtered out below + return stripPseudoTypes(preferredType); + } + + if (!preferredType) { + return undefined; + } + + if (typeof preferredType !== 'object') { + utils.reportSettings('Invalid `settings.jsdoc.preferredTypes`. Values must be falsy, a string, or an object.'); + } + + return stripPseudoTypes(preferredType.replacement); + }).filter(preferredType => { + return preferredType; + }); + } + + const typedefDeclarations = (0, _lodash.default)(context.getAllComments()).filter(comment => { + return comment.value.startsWith('*'); + }).map(commentNode => { + return (0, _iterateJsdoc.parseComment)(commentNode, ''); + }).flatMap(doc => { + return doc.tags.filter(({ + tag + }) => { + return utils.isNamepathDefiningTag(tag); + }); + }).map(tag => { + return tag.name; + }).value(); + const ancestorNodes = []; + let currentScope = scopeManager.acquire(node); + + while (currentScope && currentScope.block.type !== 'Program') { + ancestorNodes.push(currentScope.block); + currentScope = currentScope.upper; + } // `currentScope` may be `null` or `Program`, so in such a case, + // we look to present tags instead + + + let templateTags = ancestorNodes.length ? (0, _lodash.default)(ancestorNodes).flatMap(ancestorNode => { + const commentNode = (0, getJSDocComment_1.getJSDocComment)(sourceCode, ancestorNode, settings); + + if (!commentNode) { + return []; + } + + const jsdoc = (0, _iterateJsdoc.parseComment)(commentNode, ''); + return _jsdocUtils.default.filterTags(jsdoc.tags, tag => { + return 'template' === tag.tag; + }); + }).value() : utils.getPresentTags('template'); + const classJsdoc = utils.getClassJsdoc(); + + if (classJsdoc !== null && classJsdoc !== void 0 && classJsdoc.tags) { + templateTags = templateTags.concat(classJsdoc.tags.filter(({ + tag + }) => { + return tag === 'template'; + })); + } + + const closureGenericTypes = _lodash.default.flatMap(templateTags, tag => { + return utils.parseClosureTemplateTag(tag); + }); // In modules, including Node, there is a global scope at top with the + // Program scope inside + + + const cjsOrESMScope = ((_globalScope$childSco = globalScope.childScopes[0]) === null || _globalScope$childSco === void 0 ? void 0 : _globalScope$childSco.block.type) === 'Program'; + const allDefinedTypes = new Set(globalScope.variables.map(({ + name + }) => { + return name; + }) // If the file is a module, concat the variables from the module scope. + .concat(cjsOrESMScope ? _lodash.default.flatMap(globalScope.childScopes, ({ + variables + }) => { + return variables; + }, []).map(({ + name + }) => { + return name; + }) : []).concat(extraTypes).concat(typedefDeclarations).concat(definedTypes).concat(definedPreferredTypes).concat(settings.mode === 'jsdoc' ? [] : closureGenericTypes)); + const jsdocTagsWithPossibleType = utils.filterTags(({ + tag + }) => { + return utils.tagMightHaveTypePosition(tag); + }); + jsdocTagsWithPossibleType.forEach(tag => { + let parsedType; + + try { + parsedType = (0, jsdoctypeparser.parse)(tag.type, { + mode + }); + } catch { + // On syntax error, will be handled by valid-types. + return; + } + + (0, jsdoctypeparser.traverse)(parsedType, ({ + type, + name + }) => { + if (type === 'NAME') { + var _structuredTags$tag$t; + + const structuredTypes = (_structuredTags$tag$t = structuredTags[tag.tag]) === null || _structuredTags$tag$t === void 0 ? void 0 : _structuredTags$tag$t.type; + + if (!allDefinedTypes.has(name) && (!Array.isArray(structuredTypes) || !structuredTypes.includes(name))) { + report(`The type '${name}' is undefined.`, null, tag); + } else if (!extraTypes.includes(name)) { + context.markVariableAsUsed(name); + } + } + }); + }); +}, { + iterateAllJsdocs: true, + meta: { + docs: { + description: 'Checks that types in jsdoc comments are defined.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-no-undefined-types' + }, + schema: [{ + additionalProperties: false, + properties: { + definedTypes: { + items: { + type: 'string' + }, + type: 'array' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=noUndefinedTypes.js.map +}); + +var requireDescription = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _lodash = _interopRequireDefault(lodash__default['default']); + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _default = (0, _iterateJsdoc.default)(({ + jsdoc, + report, + utils, + context +}) => { + if (utils.avoidDocs()) { + return; + } + + const { + descriptionStyle = 'body' + } = context.options[0] || {}; + let targetTagName = utils.getPreferredTagName({ + // We skip reporting except when `@description` is essential to the rule, + // so user can block the tag and still meaningfully use this rule + // even if the tag is present (and `check-tag-names` is the one to + // normally report the fact that it is blocked but present) + skipReportingBlockedTag: descriptionStyle !== 'tag', + tagName: 'description' + }); + + if (!targetTagName) { + return; + } + + const isBlocked = typeof targetTagName === 'object' && targetTagName.blocked; + + if (isBlocked) { + targetTagName = targetTagName.tagName; + } + + const checkDescription = description => { + const exampleContent = _lodash.default.compact(description.trim().split('\n')); + + return exampleContent.length; + }; + + if (descriptionStyle !== 'tag') { + const { + description + } = utils.getDescription(); + + if (checkDescription(description || '')) { + return; + } + + if (descriptionStyle === 'body') { + const descTags = utils.getPresentTags(['desc', 'description']); + + if (descTags.length) { + const [{ + tag: tagName + }] = descTags; + report(`Remove the @${tagName} tag to leave a plain block description or add additional description text above the @${tagName} line.`); + } else { + report('Missing JSDoc block description.'); + } + + return; + } + } + + const functionExamples = isBlocked ? [] : _lodash.default.filter(jsdoc.tags, { + tag: targetTagName + }); + + if (!functionExamples.length) { + report(descriptionStyle === 'any' ? `Missing JSDoc block description or @${targetTagName} declaration.` : `Missing JSDoc @${targetTagName} declaration.`); + return; + } + + functionExamples.forEach(example => { + if (!checkDescription(`${example.name} ${example.description}`)) { + report(`Missing JSDoc @${targetTagName} description.`); + } + }); +}, { + contextDefaults: true, + meta: { + docs: { + description: 'Requires that all functions have a description.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-description' + }, + schema: [{ + additionalProperties: false, + properties: { + checkConstructors: { + default: true, + type: 'boolean' + }, + checkGetters: { + default: true, + type: 'boolean' + }, + checkSetters: { + default: true, + type: 'boolean' + }, + contexts: { + items: { + type: 'string' + }, + type: 'array' + }, + descriptionStyle: { + enum: ['body', 'tag', 'any'], + type: 'string' + }, + exemptedBy: { + items: { + type: 'string' + }, + type: 'array' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requireDescription.js.map +}); + +var mainUmd = createCommonjsModule(function (module, exports) { +(function (global, factory) { + factory(exports) ; +}(commonjsGlobal, (function (exports) { + function _classCallCheck(instance, Constructor) { + if (!(instance instanceof Constructor)) { + throw new TypeError("Cannot call a class as a function"); + } + } + + function _defineProperties(target, props) { + for (var i = 0; i < props.length; i++) { + var descriptor = props[i]; + descriptor.enumerable = descriptor.enumerable || false; + descriptor.configurable = true; + if ("value" in descriptor) descriptor.writable = true; + Object.defineProperty(target, descriptor.key, descriptor); + } + } + + function _createClass(Constructor, protoProps, staticProps) { + if (protoProps) _defineProperties(Constructor.prototype, protoProps); + if (staticProps) _defineProperties(Constructor, staticProps); + return Constructor; + } + + function _setPrototypeOf(o, p) { + _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { + o.__proto__ = p; + return o; + }; + + return _setPrototypeOf(o, p); + } + + function _isNativeReflectConstruct() { + if (typeof Reflect === "undefined" || !Reflect.construct) return false; + if (Reflect.construct.sham) return false; + if (typeof Proxy === "function") return true; + + try { + Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); + return true; + } catch (e) { + return false; + } + } + + function _construct(Parent, args, Class) { + if (_isNativeReflectConstruct()) { + _construct = Reflect.construct; + } else { + _construct = function _construct(Parent, args, Class) { + var a = [null]; + a.push.apply(a, args); + var Constructor = Function.bind.apply(Parent, a); + var instance = new Constructor(); + if (Class) _setPrototypeOf(instance, Class.prototype); + return instance; + }; + } + + return _construct.apply(null, arguments); + } + + /* eslint-disable node/no-unsupported-features/es-syntax */ + + /** + * @param {RegExp} regex + * @param {string} newFlags + * @param {Integer} [newLastIndex=regex.lastIndex] + * @returns {RegExp} + */ + function mixinRegex(regex, newFlags) { + var newLastIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : regex.lastIndex; + newFlags = newFlags || ''; + regex = new RegExp(regex.source, (newFlags.includes('g') ? 'g' : regex.global ? 'g' : '') + (newFlags.includes('i') ? 'i' : regex.ignoreCase ? 'i' : '') + (newFlags.includes('m') ? 'm' : regex.multiline ? 'm' : '') + (newFlags.includes('u') ? 'u' : regex.unicode ? 'u' : '') + (newFlags.includes('y') ? 'y' : regex.sticky ? 'y' : '') + (newFlags.includes('s') ? 's' : regex.dotAll ? 's' : '')); + regex.lastIndex = newLastIndex; + return regex; + } + + exports.RegExtras = /*#__PURE__*/function () { + function RegExtras(regex, flags, newLastIndex) { + _classCallCheck(this, RegExtras); + + this.regex = mixinRegex(typeof regex === 'string' ? new RegExp(regex) : mixinRegex(regex), flags || '', newLastIndex); + } + + _createClass(RegExtras, [{ + key: "forEach", + value: function forEach(str, cb) { + var thisObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + var regex = mixinRegex(this.regex, 'g'); + var matches, + n0, + i = 0; + + while ((matches = regex.exec(str)) !== null) { + n0 = matches.splice(0, 1); + cb.apply(thisObj, matches.concat(i++, n0)); + } + + return this; + } + }, { + key: "some", + value: function some(str, cb) { + var thisObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + var regex = mixinRegex(this.regex, 'g'); + var matches, + ret, + n0, + i = 0; + + while ((matches = regex.exec(str)) !== null) { + n0 = matches.splice(0, 1); + ret = cb.apply(thisObj, matches.concat(i++, n0)); + + if (ret) { + return true; + } + } + + return false; + } + }, { + key: "every", + value: function every(str, cb) { + var thisObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + var regex = mixinRegex(this.regex, 'g'); + var matches, + ret, + n0, + i = 0; + + while ((matches = regex.exec(str)) !== null) { + n0 = matches.splice(0, 1); + ret = cb.apply(thisObj, matches.concat(i++, n0)); + + if (!ret) { + return false; + } + } + + return true; + } + }, { + key: "map", + value: function map(str, cb) { + var thisObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + var ret = []; + var regex = mixinRegex(this.regex, 'g'); + var matches, + n0, + i = 0; + + while ((matches = regex.exec(str)) !== null) { + n0 = matches.splice(0, 1); + ret.push(cb.apply(thisObj, matches.concat(i++, n0))); + } + + return ret; + } + }, { + key: "filter", + value: function filter(str, cb) { + var thisObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + var matches, + n0, + i = 0; + var ret = [], + regex = mixinRegex(this.regex, 'g'); + + while ((matches = regex.exec(str)) !== null) { + n0 = matches.splice(0, 1); + matches = matches.concat(i++, n0); + + if (cb.apply(thisObj, matches)) { + ret.push(n0[0]); + } + } + + return ret; + } + }, { + key: "reduce", + value: function reduce(str, cb, prev) { + var thisObj = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; + var matches, + n0, + i = 0; + var regex = mixinRegex(this.regex, 'g'); + + if (!prev) { + if ((matches = regex.exec(str)) !== null) { + n0 = matches.splice(0, 1); + prev = cb.apply(thisObj, [''].concat(matches.concat(i++, n0))); + } + } + + while ((matches = regex.exec(str)) !== null) { + n0 = matches.splice(0, 1); + prev = cb.apply(thisObj, [prev].concat(matches.concat(i++, n0))); + } + + return prev; + } + }, { + key: "reduceRight", + value: function reduceRight(str, cb, prevOrig, thisObjOrig) { + var matches, + n0, + i, + thisObj = thisObjOrig, + prev = prevOrig; + var matchesContainer = [], + regex = mixinRegex(this.regex, 'g'); + thisObj = thisObj || null; + + while ((matches = regex.exec(str)) !== null) { + matchesContainer.push(matches); + } + + i = matchesContainer.length; + + if (!i) { + if (arguments.length < 3) { + throw new TypeError('reduce of empty matches array with no initial value'); + } + + return prev; + } + + if (!prev) { + matches = matchesContainer.splice(-1)[0]; + n0 = matches.splice(0, 1); + prev = cb.apply(thisObj, [''].concat(matches.concat(i--, n0))); + } + + matchesContainer.reduceRight(function (container, mtches) { + n0 = mtches.splice(0, 1); + prev = cb.apply(thisObj, [prev].concat(mtches.concat(i--, n0))); + return container; + }, matchesContainer); + return prev; + } + }, { + key: "find", + value: function find(str, cb) { + var thisObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + var matches, + ret, + n0, + i = 0; + var regex = mixinRegex(this.regex, 'g'); + + while ((matches = regex.exec(str)) !== null) { + n0 = matches.splice(0, 1); + ret = cb.apply(thisObj, matches.concat(i++, n0)); + + if (ret) { + return n0[0]; + } + } + + return false; + } + }, { + key: "findIndex", + value: function findIndex(str, cb) { + var thisObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + var regex = mixinRegex(this.regex, 'g'); + var matches, + i = 0; + + while ((matches = regex.exec(str)) !== null) { + var n0 = matches.splice(0, 1); + var ret = cb.apply(thisObj, matches.concat(i++, n0)); + + if (ret) { + return i - 1; + } + } + + return -1; + } + }, { + key: "findExec", + value: function findExec(str, cb) { + var thisObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + var regex = mixinRegex(this.regex, 'g'); + var matches, + i = 0; + + while ((matches = regex.exec(str)) !== null) { + var n0 = matches.splice(0, 1); + var ret = cb.apply(thisObj, matches.concat(i++, n0)); + + if (ret) { + return matches; + } + } + + return false; + } + }, { + key: "filterExec", + value: function filterExec(str, cb) { + var thisObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; + var matches, + n0, + i = 0; + var ret = [], + regex = mixinRegex(this.regex, 'g'); + + while ((matches = regex.exec(str)) !== null) { + n0 = matches.splice(0, 1); + matches.push(i++, n0[0]); + + if (cb.apply(thisObj, matches)) { + ret.push(matches); + } + } + + return ret; + } + }]); + + return RegExtras; + }(); + + var _RegExtras = exports.RegExtras; + + exports.RegExtras = function RegExtras() { + for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + // eslint-disable-line no-class-assign + return _construct(_RegExtras, args); + }; + + exports.RegExtras.prototype = _RegExtras.prototype; + exports.RegExtras.mixinRegex = mixinRegex; + + exports.mixinRegex = mixinRegex; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); +}); + +var requireDescriptionCompleteSentence = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _lodash = _interopRequireDefault(lodash__default['default']); + + + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const otherDescriptiveTags = new Set([// 'copyright' and 'see' might be good addition, but as the former may be +// sensitive text, and the latter may have just a link, they are not +// included by default +'summary', 'file', 'fileoverview', 'overview', 'classdesc', 'todo', 'deprecated', 'throws', 'exception', 'yields', 'yield']); + +const extractParagraphs = text => { + return text.split(/(? { + const txt = text // Remove all {} tags. + .replace(/\{[\s\S]*?\}\s*/gu, '') // Remove custom abbreviations + .replace(abbreviationsRegex, ''); + const sentenceEndGrouping = /([.?!])(?:\s+|$)/u; + const puncts = (0, mainUmd.RegExtras)(sentenceEndGrouping).map(txt, punct => { + return punct; + }); + return txt.split(/[.?!](?:\s+|$)/u) // Re-add the dot. + .map((sentence, idx) => { + return /^\s*$/u.test(sentence) ? sentence : `${sentence}${puncts[idx] || ''}`; + }); +}; + +const isNewLinePrecededByAPeriod = text => { + let lastLineEndsSentence; + const lines = text.split('\n'); + return !lines.some(line => { + if (lastLineEndsSentence === false && /^[A-Z][a-z]/u.test(line)) { + return true; + } + + lastLineEndsSentence = /[.:?!|]$/u.test(line); + return false; + }); +}; + +const isCapitalized = str => { + return str[0] === str[0].toUpperCase(); +}; + +const isTable = str => { + return str.charAt() === '|'; +}; + +const capitalize = str => { + return str.charAt(0).toUpperCase() + str.slice(1); +}; + +const validateDescription = (description, reportOrig, jsdocNode, abbreviationsRegex, sourceCode, tag, newlineBeforeCapsAssumesBadSentenceEnd) => { + if (!description) { + return false; + } + + const paragraphs = extractParagraphs(description); + return paragraphs.some((paragraph, parIdx) => { + const sentences = extractSentences(paragraph, abbreviationsRegex); + + const fix = fixer => { + let text = sourceCode.getText(jsdocNode); + + if (!/[.:?!]$/u.test(paragraph)) { + const line = paragraph.split('\n').pop(); + text = text.replace(new RegExp(`${_lodash.default.escapeRegExp(line)}$`, 'mu'), `${line}.`); + } + + for (const sentence of sentences.filter(sentence_ => { + return !/^\s*$/u.test(sentence_) && !isCapitalized(sentence_) && !isTable(sentence_); + })) { + const beginning = sentence.split('\n')[0]; + + if (tag.tag) { + const reg = new RegExp(`(@${_lodash.default.escapeRegExp(tag.tag)}.*)${_lodash.default.escapeRegExp(beginning)}`, 'u'); + text = text.replace(reg, (_$0, $1) => { + return $1 + capitalize(beginning); + }); + } else { + text = text.replace(new RegExp('((?:[.!?]|\\*|\\})\\s*)' + _lodash.default.escapeRegExp(beginning), 'u'), '$1' + capitalize(beginning)); + } + } + + return fixer.replaceText(jsdocNode, text); + }; + + const report = (msg, fixer, tagObj) => { + if ('line' in tagObj) { + tagObj.line += parIdx * 2; + } else { + tagObj.source[0].number += parIdx * 2; + } // Avoid errors if old column doesn't exist here + + + tagObj.column = 0; + reportOrig(msg, fixer, tagObj); + }; + + if (sentences.some(sentence => { + return !/^\s*$/u.test(sentence) && !isCapitalized(sentence) && !isTable(sentence); + })) { + report('Sentence should start with an uppercase character.', fix, tag); + } + + const paragraphNoAbbreviations = paragraph.replace(abbreviationsRegex, ''); + + if (!/[.!?|]\s*$/u.test(paragraphNoAbbreviations)) { + report('Sentence must end with a period.', fix, tag); + return true; + } + + if (newlineBeforeCapsAssumesBadSentenceEnd && !isNewLinePrecededByAPeriod(paragraphNoAbbreviations)) { + report('A line of text is started with an uppercase character, but preceding line does not end the sentence.', null, tag); + return true; + } + + return false; + }); +}; + +var _default = (0, _iterateJsdoc.default)(({ + sourceCode, + context, + jsdoc, + report, + jsdocNode, + utils +}) => { + const options = context.options[0] || {}; + const { + abbreviations = [], + newlineBeforeCapsAssumesBadSentenceEnd = false + } = options; + const abbreviationsRegex = abbreviations.length ? new RegExp('\\b' + abbreviations.map(abbreviation => { + return _lodash.default.escapeRegExp(abbreviation.replace(/\.$/g, '') + '.'); + }).join('|') + '(?:$|\\s)', 'gu') : ''; + const { + description + } = utils.getDescription(); + + if (validateDescription(description, report, jsdocNode, abbreviationsRegex, sourceCode, { + line: jsdoc.source[0].number + 1 + }, newlineBeforeCapsAssumesBadSentenceEnd)) { + return; + } + + utils.forEachPreferredTag('description', matchingJsdocTag => { + const desc = `${matchingJsdocTag.name} ${matchingJsdocTag.description}`.trim(); + validateDescription(desc, report, jsdocNode, abbreviationsRegex, sourceCode, matchingJsdocTag, newlineBeforeCapsAssumesBadSentenceEnd); + }, true); + const { + tagsWithNames + } = utils.getTagsByType(jsdoc.tags); + const tagsWithoutNames = utils.filterTags(({ + tag: tagName + }) => { + return otherDescriptiveTags.has(tagName) || utils.hasOptionTag(tagName) && !tagsWithNames.some(({ + tag + }) => { + // If user accidentally adds tags with names (or like `returns` + // get parsed as having names), do not add to this list + return tag === tagName; + }); + }); + tagsWithNames.some(tag => { + const desc = _lodash.default.trimStart(tag.description, '- ').trimEnd(); + + return validateDescription(desc, report, jsdocNode, abbreviationsRegex, sourceCode, tag, newlineBeforeCapsAssumesBadSentenceEnd); + }); + tagsWithoutNames.some(tag => { + const desc = `${tag.name} ${tag.description}`.trim(); + return validateDescription(desc, report, jsdocNode, abbreviationsRegex, sourceCode, tag, newlineBeforeCapsAssumesBadSentenceEnd); + }); +}, { + iterateAllJsdocs: true, + meta: { + docs: { + description: 'Requires that block description, explicit `@description`, and `@param`/`@returns` tag descriptions are written in complete sentences.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-description-complete-sentence' + }, + fixable: 'code', + schema: [{ + additionalProperties: false, + properties: { + abbreviations: { + items: { + type: 'string' + }, + type: 'array' + }, + newlineBeforeCapsAssumesBadSentenceEnd: { + type: 'boolean' + }, + tags: { + items: { + type: 'string' + }, + type: 'array' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requireDescriptionCompleteSentence.js.map +}); + +var requireExample = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _lodash = _interopRequireDefault(lodash__default['default']); + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _default = (0, _iterateJsdoc.default)(({ + context, + jsdoc, + report, + utils +}) => { + if (utils.avoidDocs()) { + return; + } + + const { + exemptNoArguments = false + } = context.options[0] || {}; + const targetTagName = 'example'; + + const functionExamples = _lodash.default.filter(jsdoc.tags, { + tag: targetTagName + }); + + if (!functionExamples.length) { + if (exemptNoArguments && utils.isIteratingFunction() && !utils.hasParams()) { + return; + } + + utils.reportJSDoc(`Missing JSDoc @${targetTagName} declaration.`, null, () => { + utils.addTag(targetTagName); + }); + return; + } + + functionExamples.forEach(example => { + const exampleContent = _lodash.default.compact(`${example.name} ${example.description}`.trim().split('\n')); + + if (!exampleContent.length) { + report(`Missing JSDoc @${targetTagName} description.`); + } + }); +}, { + contextDefaults: true, + meta: { + docs: { + description: 'Requires that all functions have examples.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-example' + }, + fixable: 'code', + schema: [{ + additionalProperties: false, + properties: { + checkConstructors: { + default: true, + type: 'boolean' + }, + checkGetters: { + default: false, + type: 'boolean' + }, + checkSetters: { + default: false, + type: 'boolean' + }, + contexts: { + items: { + type: 'string' + }, + type: 'array' + }, + exemptedBy: { + items: { + type: 'string' + }, + type: 'array' + }, + exemptNoArguments: { + default: false, + type: 'boolean' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requireExample.js.map +}); + +var requireFileOverview = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const defaultTags = { + file: { + initialCommentsOnly: true, + mustExist: true, + preventDuplicates: true + } +}; + +const setDefaults = state => { + // First iteration + if (!state.globalTags) { + state.globalTags = {}; + state.hasDuplicates = {}; + state.hasTag = {}; + state.hasNonCommentBeforeTag = {}; + } +}; + +var _default = (0, _iterateJsdoc.default)(({ + jsdocNode, + state, + utils, + context +}) => { + const { + tags = defaultTags + } = context.options[0] || {}; + setDefaults(state); + + for (const tagName of Object.keys(tags)) { + const targetTagName = utils.getPreferredTagName({ + tagName + }); + const hasTag = targetTagName && utils.hasTag(targetTagName); + state.hasTag[tagName] = hasTag || state.hasTag[tagName]; + const hasDuplicate = state.hasDuplicates[tagName]; + + if (hasDuplicate === false) { + // Was marked before, so if a tag now, is a dupe + state.hasDuplicates[tagName] = hasTag; + } else if (!hasDuplicate && hasTag) { + // No dupes set before, but has first tag, so change state + // from `undefined` to `false` so can detect next time + state.hasDuplicates[tagName] = false; + state.hasNonCommentBeforeTag[tagName] = state.hasNonComment && state.hasNonComment < jsdocNode.range[0]; + } + } +}, { + exit({ + context, + state, + utils + }) { + setDefaults(state); + const { + tags = defaultTags + } = context.options[0] || {}; + + for (const [tagName, { + mustExist = false, + preventDuplicates = false, + initialCommentsOnly = false + }] of Object.entries(tags)) { + const obj = utils.getPreferredTagNameObject({ + tagName + }); + + if (obj && obj.blocked) { + utils.reportSettings(`\`settings.jsdoc.tagNamePreference\` cannot block @${obj.tagName} ` + 'for the `require-file-overview` rule'); + } else { + const targetTagName = obj && obj.replacement || obj; + + if (mustExist && !state.hasTag[tagName]) { + utils.reportSettings(`Missing @${targetTagName}`); + } + + if (preventDuplicates && state.hasDuplicates[tagName]) { + utils.reportSettings(`Duplicate @${targetTagName}`); + } + + if (initialCommentsOnly && state.hasNonCommentBeforeTag[tagName]) { + utils.reportSettings(`@${targetTagName} should be at the beginning of the file`); + } + } + } + }, + + iterateAllJsdocs: true, + meta: { + docs: { + description: 'Checks that all files have one `@file`, `@fileoverview`, or `@overview` tag at the beginning of the file.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-file-overview' + }, + schema: [{ + additionalProperties: false, + properties: { + tags: { + patternProperties: { + '.*': { + additionalProperties: false, + properties: { + initialCommentsOnly: { + type: 'boolean' + }, + mustExist: { + type: 'boolean' + }, + preventDuplicates: { + type: 'boolean' + } + }, + type: 'object' + } + }, + type: 'object' + } + }, + type: 'object' + }], + type: 'suggestion' + }, + + nonComment({ + state, + node + }) { + if (!state.hasNonComment) { + state.hasNonComment = node.range[0]; + } + } + +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requireFileOverview.js.map +}); + +var requireHyphenBeforeParamDescription = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _default = (0, _iterateJsdoc.default)(({ + sourceCode, + utils, + report, + context, + jsdoc, + jsdocNode +}) => { + const [mainCircumstance, { + tags + } = {}] = context.options; + + const checkHyphens = (jsdocTag, targetTagName, circumstance = mainCircumstance) => { + const always = !circumstance || circumstance === 'always'; + + if (!jsdocTag.description.trim()) { + return; + } + + const startsWithHyphen = /^\s*-/u.test(jsdocTag.description); + + if (always) { + if (!startsWithHyphen) { + report(`There must be a hyphen before @${targetTagName} description.`, fixer => { + const lineIndex = jsdocTag.line; + const sourceLines = sourceCode.getText(jsdocNode).split('\n'); // Get start index of description, accounting for multi-line descriptions + + const description = jsdocTag.description.split('\n')[0]; + const descriptionIndex = sourceLines[lineIndex].lastIndexOf(description); + const replacementLine = sourceLines[lineIndex].slice(0, descriptionIndex) + '- ' + description; + sourceLines.splice(lineIndex, 1, replacementLine); + const replacement = sourceLines.join('\n'); + return fixer.replaceText(jsdocNode, replacement); + }, jsdocTag); + } + } else if (startsWithHyphen) { + report(`There must be no hyphen before @${targetTagName} description.`, fixer => { + const [unwantedPart] = /^\s*-\s*/u.exec(jsdocTag.description); + const replacement = sourceCode.getText(jsdocNode).replace(jsdocTag.description, jsdocTag.description.slice(unwantedPart.length)); + return fixer.replaceText(jsdocNode, replacement); + }, jsdocTag); + } + }; + + utils.forEachPreferredTag('param', checkHyphens); + + if (tags) { + const tagEntries = Object.entries(tags); + tagEntries.forEach(([tagName, circumstance]) => { + if (tagName === '*') { + const preferredParamTag = utils.getPreferredTagName({ + tagName: 'param' + }); + jsdoc.tags.forEach(({ + tag + }) => { + if (tag === preferredParamTag || tagEntries.some(([tagNme]) => { + return tagNme !== '*' && tagNme === tag; + })) { + return; + } + + utils.forEachPreferredTag(tag, (jsdocTag, targetTagName) => { + checkHyphens(jsdocTag, targetTagName, circumstance); + }); + }); + return; + } + + utils.forEachPreferredTag(tagName, (jsdocTag, targetTagName) => { + checkHyphens(jsdocTag, targetTagName, circumstance); + }); + }); + } +}, { + iterateAllJsdocs: true, + meta: { + docs: { + description: 'Requires a hyphen before the `@param` description.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-hyphen-before-param-description' + }, + fixable: 'code', + schema: [{ + enum: ['always', 'never'], + type: 'string' + }, { + additionalProperties: false, + properties: { + tags: { + anyOf: [{ + patternProperties: { + '.*': { + enum: ['always', 'never'], + type: 'string' + } + }, + type: 'object' + }, { + enum: ['any'], + type: 'string' + }] + } + }, + type: 'object' + }], + type: 'layout' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requireHyphenBeforeParamDescription.js.map +}); + +var exportParser = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _debug = _interopRequireDefault(require$$0__default['default']); + + + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const debug = (0, _debug.default)('requireExportJsdoc'); + +const createNode = function () { + return { + props: {} + }; +}; + +const getSymbolValue = function (symbol) { + /* istanbul ignore next */ + if (!symbol) { + /* istanbul ignore next */ + return null; + } + /* istanbul ignore next */ + + + if (symbol.type === 'literal') { + return symbol.value.value; + } + /* istanbul ignore next */ + + + return null; +}; + +const getIdentifier = function (node, globals, scope, opts) { + if (opts.simpleIdentifier) { + // Type is Identier for noncomputed properties + const identifierLiteral = createNode(); + identifierLiteral.type = 'literal'; + identifierLiteral.value = { + value: node.name + }; + return identifierLiteral; + } + /* istanbul ignore next */ + + + const block = scope || globals; // As scopes are not currently supported, they are not traversed upwards recursively + + if (block.props[node.name]) { + return block.props[node.name]; + } // Seems this will only be entered once scopes added and entered + + /* istanbul ignore next */ + + + if (globals.props[node.name]) { + return globals.props[node.name]; + } + + return null; +}; + +let createSymbol = null; + +const getSymbol = function (node, globals, scope, opt) { + const opts = opt || {}; + /* istanbul ignore next */ + + switch (node.type) { + case 'Identifier': + { + return getIdentifier(node, globals, scope, opts); + } + + case 'MemberExpression': + { + const obj = getSymbol(node.object, globals, scope, opts); + const propertySymbol = getSymbol(node.property, globals, scope, { + simpleIdentifier: !node.computed + }); + const propertyValue = getSymbolValue(propertySymbol); + /* istanbul ignore next */ + + if (obj && propertyValue && obj.props[propertyValue]) { + const block = obj.props[propertyValue]; + return block; + } + /* + if (opts.createMissingProps && propertyValue) { + obj.props[propertyValue] = createNode(); + return obj.props[propertyValue]; + } + */ + + /* istanbul ignore next */ + + + debug(`MemberExpression: Missing property ${node.property.name}`); + /* istanbul ignore next */ + + return null; + } + + case 'TSTypeAliasDeclaration': + case 'TSEnumDeclaration': + case 'TSInterfaceDeclaration': + case 'ClassDeclaration': + case 'ClassExpression': + case 'FunctionExpression': + case 'FunctionDeclaration': + case 'ArrowFunctionExpression': + { + const val = createNode(); + val.props.prototype = createNode(); + val.props.prototype.type = 'object'; + val.type = 'object'; + val.value = node; + return val; + } + + case 'AssignmentExpression': + { + return createSymbol(node.left, globals, node.right, scope, opts); + } + + case 'ClassBody': + { + const val = createNode(); + node.body.forEach(method => { + val.props[method.key.name] = createNode(); + val.props[method.key.name].type = 'object'; + val.props[method.key.name].value = method.value; + }); + val.type = 'object'; + val.value = node; + return val; + } + + case 'ObjectExpression': + { + const val = createNode(); + val.type = 'object'; + node.properties.forEach(prop => { + if ([// @typescript-eslint/parser, espree, acorn, etc. + 'SpreadElement', // @babel/eslint-parser + 'ExperimentalSpreadProperty'].includes(prop.type)) { + return; + } + + const propVal = getSymbol(prop.value, globals, scope, opts); + /* istanbul ignore next */ + + if (propVal) { + val.props[prop.key.name] = propVal; + } + }); + return val; + } + + case 'Literal': + { + const val = createNode(); + val.type = 'literal'; + val.value = node; + return val; + } + } + /* istanbul ignore next */ + + + return null; +}; + +const createBlockSymbol = function (block, name, value, globals, isGlobal) { + block.props[name] = value; + + if (isGlobal && globals.props.window && globals.props.window.special) { + globals.props.window.props[name] = value; + } +}; + +createSymbol = function (node, globals, value, scope, isGlobal) { + const block = scope || globals; + let symbol; + + switch (node.type) { + case 'FunctionDeclaration': + /* istanbul ignore next */ + // Fall through + + case 'TSEnumDeclaration': + case 'TSInterfaceDeclaration': + /* istanbul ignore next */ + // Fall through + + case 'TSTypeAliasDeclaration': + case 'ClassDeclaration': + { + /* istanbul ignore next */ + if (node.id && node.id.type === 'Identifier') { + return createSymbol(node.id, globals, node, globals); + } + /* istanbul ignore next */ + + + break; + } + + case 'Identifier': + { + if (value) { + const valueSymbol = getSymbol(value, globals, block); + /* istanbul ignore next */ + + if (valueSymbol) { + createBlockSymbol(block, node.name, valueSymbol, globals, isGlobal); + return block.props[node.name]; + } + /* istanbul ignore next */ + + + debug('Identifier: Missing value symbol for %s', node.name); + } else { + createBlockSymbol(block, node.name, createNode(), globals, isGlobal); + return block.props[node.name]; + } + /* istanbul ignore next */ + + + break; + } + + case 'MemberExpression': + { + symbol = getSymbol(node.object, globals, block); + const propertySymbol = getSymbol(node.property, globals, block, { + simpleIdentifier: !node.computed + }); + const propertyValue = getSymbolValue(propertySymbol); + + if (symbol && propertyValue) { + createBlockSymbol(symbol, propertyValue, getSymbol(value, globals, block), globals, isGlobal); + return symbol.props[propertyValue]; + } + /* istanbul ignore next */ + + + debug('MemberExpression: Missing symbol: %s', node.property.name); + break; + } + } + + return null; +}; // Creates variables from variable definitions + + +const initVariables = function (node, globals, opts) { + switch (node.type) { + case 'Program': + { + node.body.forEach(childNode => { + initVariables(childNode, globals, opts); + }); + break; + } + + case 'ExpressionStatement': + { + initVariables(node.expression, globals, opts); + break; + } + + case 'VariableDeclaration': + { + node.declarations.forEach(declaration => { + // let and const + const symbol = createSymbol(declaration.id, globals, null, globals); + + if (opts.initWindow && node.kind === 'var' && globals.props.window) { + // If var, also add to window + globals.props.window.props[declaration.id.name] = symbol; + } + }); + break; + } + + case 'ExportNamedDeclaration': + { + if (node.declaration) { + initVariables(node.declaration, globals, opts); + } + + break; + } + } +}; // Populates variable maps using AST + + +const mapVariables = function (node, globals, opt, isExport) { + /* istanbul ignore next */ + const opts = opt || {}; + /* istanbul ignore next */ + + switch (node.type) { + case 'Program': + { + if (opts.ancestorsOnly) { + return false; + } + + node.body.forEach(childNode => { + mapVariables(childNode, globals, opts); + }); + break; + } + + case 'ExpressionStatement': + { + mapVariables(node.expression, globals, opts); + break; + } + + case 'AssignmentExpression': + { + createSymbol(node.left, globals, node.right); + break; + } + + case 'VariableDeclaration': + { + node.declarations.forEach(declaration => { + const isGlobal = opts.initWindow && node.kind === 'var' && globals.props.window; + const symbol = createSymbol(declaration.id, globals, declaration.init, globals, isGlobal); + + if (symbol && isExport) { + symbol.exported = true; + } + }); + break; + } + + case 'FunctionDeclaration': + { + /* istanbul ignore next */ + if (node.id.type === 'Identifier') { + createSymbol(node.id, globals, node, globals, true); + } + + break; + } + + case 'ExportDefaultDeclaration': + { + const symbol = createSymbol(node.declaration, globals, node.declaration); + + if (symbol) { + symbol.exported = true; + } else if (!node.id) { + globals.ANONYMOUS_DEFAULT = node.declaration; + } + + break; + } + + case 'ExportNamedDeclaration': + { + if (node.declaration) { + if (node.declaration.type === 'VariableDeclaration') { + mapVariables(node.declaration, globals, opts, true); + } else { + const symbol = createSymbol(node.declaration, globals, node.declaration); + /* istanbul ignore next */ + + if (symbol) { + symbol.exported = true; + } + } + } + + node.specifiers.forEach(specifier => { + mapVariables(specifier, globals, opts); + }); + break; + } + + case 'ExportSpecifier': + { + const symbol = getSymbol(node.local, globals, globals); + /* istanbul ignore next */ + + if (symbol) { + symbol.exported = true; + } + + break; + } + + case 'ClassDeclaration': + { + createSymbol(node.id, globals, node.body, globals); + break; + } + + default: + { + /* istanbul ignore next */ + return false; + } + } + + return true; +}; + +const findNode = function (node, block, cache) { + let blockCache = cache || []; + /* istanbul ignore next */ + + if (!block || blockCache.includes(block)) { + return false; + } + + blockCache = blockCache.slice(); + blockCache.push(block); + + if ((block.type === 'object' || block.type === 'MethodDefinition') && block.value === node) { + return true; + } + + const { + props = block.body + } = block; + + for (const propval of Object.values(props || {})) { + if (Array.isArray(propval)) { + /* istanbul ignore if */ + if (propval.some(val => { + return findNode(node, val, blockCache); + })) { + return true; + } + } else if (findNode(node, propval, blockCache)) { + return true; + } + } + + return false; +}; + +const exportTypes = new Set(['ExportNamedDeclaration', 'ExportDefaultDeclaration']); + +const getExportAncestor = function (nde) { + let node = nde; + + while (node) { + if (exportTypes.has(node.type)) { + return node; + } + + node = node.parent; + } + + return false; +}; + +const canExportedByAncestorType = new Set(['TSPropertySignature', 'TSMethodSignature', 'ClassProperty', 'Method']); +const canExportChildrenType = new Set(['TSInterfaceBody', 'TSInterfaceDeclaration', 'ClassDefinition', 'ClassExpression', 'Program']); + +const isExportByAncestor = function (nde) { + if (!canExportedByAncestorType.has(nde.type)) { + return false; + } + + let node = nde.parent; + + while (node) { + if (exportTypes.has(node.type)) { + return node; + } + + if (!canExportChildrenType.has(node.type)) { + return false; + } + + node = node.parent; + } + + return false; +}; + +const findExportedNode = function (block, node, cache) { + /* istanbul ignore next */ + if (block === null) { + return false; + } + + const blockCache = cache || []; + const { + props + } = block; + + for (const propval of Object.values(props)) { + blockCache.push(propval); + + if (propval.exported && (node === propval.value || findNode(node, propval.value))) { + return true; + } // No need to check `propval` for exported nodes as ESM + // exports are only global + + } + + return false; +}; + +const isNodeExported = function (node, globals, opt) { + if (opt.initModuleExports && globals.props.module && globals.props.module.props.exports && findNode(node, globals.props.module.props.exports)) { + return true; + } + + if (opt.initWindow && globals.props.window && findNode(node, globals.props.window)) { + return true; + } + + if (opt.esm && findExportedNode(globals, node)) { + return true; + } + + return false; +}; + +const parseRecursive = function (node, globalVars, opts) { + // Iterate from top using recursion - stop at first processed node from top + if (node.parent && parseRecursive(node.parent, globalVars, opts)) { + return true; + } + + return mapVariables(node, globalVars, opts); +}; + +const parse = function (ast, node, opt) { + /* istanbul ignore next */ + const opts = opt || { + ancestorsOnly: false, + esm: true, + initModuleExports: true, + initWindow: true + }; + const globalVars = createNode(); + + if (opts.initModuleExports) { + globalVars.props.module = createNode(); + globalVars.props.module.props.exports = createNode(); + globalVars.props.exports = globalVars.props.module.props.exports; + } + + if (opts.initWindow) { + globalVars.props.window = createNode(); + globalVars.props.window.special = true; + } + + if (opts.ancestorsOnly) { + parseRecursive(node, globalVars, opts); + } else { + initVariables(ast, globalVars, opts); + mapVariables(ast, globalVars, opts); + } + + return { + globalVars + }; +}; + +const isUncommentedExport = function (node, sourceCode, opt, settings) { + // console.log({node}); + // Optimize with ancestor check for esm + if (opt.esm) { + const exportNode = getExportAncestor(node); // Is export node comment + + if (exportNode && !(0, getJSDocComment_1.findJSDocComment)(exportNode, sourceCode, settings)) { + return true; + } + /** Some typescript types are not in variable map, but inherit exported (interface property and method)*/ + + + if (isExportByAncestor(node) && !(0, getJSDocComment_1.findJSDocComment)(node, sourceCode, settings)) { + return true; + } + } + + const parseResult = parse(sourceCode.ast, node, opt); + return isNodeExported(node, parseResult.globalVars, opt); +}; + +var _default = { + isUncommentedExport, + parse +}; +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=exportParser.js.map +}); + +var requireJsdoc = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _lodash = _interopRequireDefault(lodash__default['default']); + + + +var _exportParser = _interopRequireDefault(exportParser); + + + +var _jsdocUtils = _interopRequireDefault(jsdocUtils); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const OPTIONS_SCHEMA = { + additionalProperties: false, + properties: { + checkConstructors: { + default: true, + type: 'boolean' + }, + checkGetters: { + anyOf: [{ + type: 'boolean' + }, { + enum: ['no-setter'], + type: 'string' + }], + default: true + }, + checkSetters: { + anyOf: [{ + type: 'boolean' + }, { + enum: ['no-getter'], + type: 'string' + }], + default: true + }, + contexts: { + items: { + anyOf: [{ + type: 'string' + }, { + additionalProperties: false, + properties: { + context: { + type: 'string' + }, + inlineCommentBlock: { + type: 'boolean' + } + }, + type: 'object' + }] + }, + type: 'array' + }, + enableFixer: { + default: true, + type: 'boolean' + }, + exemptEmptyConstructors: { + default: false, + type: 'boolean' + }, + exemptEmptyFunctions: { + default: false, + type: 'boolean' + }, + publicOnly: { + oneOf: [{ + default: false, + type: 'boolean' + }, { + additionalProperties: false, + default: {}, + properties: { + ancestorsOnly: { + type: 'boolean' + }, + cjs: { + type: 'boolean' + }, + esm: { + type: 'boolean' + }, + window: { + type: 'boolean' + } + }, + type: 'object' + }] + }, + require: { + additionalProperties: false, + default: {}, + properties: { + ArrowFunctionExpression: { + default: false, + type: 'boolean' + }, + ClassDeclaration: { + default: false, + type: 'boolean' + }, + ClassExpression: { + default: false, + type: 'boolean' + }, + FunctionDeclaration: { + default: true, + type: 'boolean' + }, + FunctionExpression: { + default: false, + type: 'boolean' + }, + MethodDefinition: { + default: false, + type: 'boolean' + } + }, + type: 'object' + } + }, + type: 'object' +}; + +const getOption = (context, baseObject, option, key) => { + if (!_lodash.default.has(context, `options[0][${option}][${key}]`)) { + return baseObject.properties[key].default; + } + + return context.options[0][option][key]; +}; + +const getOptions = context => { + const { + publicOnly, + contexts = [], + exemptEmptyConstructors = true, + exemptEmptyFunctions = false, + enableFixer = true + } = context.options[0] || {}; + return { + contexts, + enableFixer, + exemptEmptyConstructors, + exemptEmptyFunctions, + publicOnly: (baseObj => { + if (!publicOnly) { + return false; + } + + const properties = {}; + Object.keys(baseObj.properties).forEach(prop => { + const opt = getOption(context, baseObj, 'publicOnly', prop); + properties[prop] = opt; + }); + return properties; + })(OPTIONS_SCHEMA.properties.publicOnly.oneOf[1]), + require: (baseObj => { + const properties = {}; + Object.keys(baseObj.properties).forEach(prop => { + const opt = getOption(context, baseObj, 'require', prop); + properties[prop] = opt; + }); + return properties; + })(OPTIONS_SCHEMA.properties.require) + }; +}; + +var _default = { + create(context) { + const sourceCode = context.getSourceCode(); + const settings = (0, iterateJsdoc_1.getSettings)(context); + + if (!settings) { + return {}; + } + + const { + require: requireOption, + contexts, + publicOnly, + exemptEmptyFunctions, + exemptEmptyConstructors, + enableFixer + } = getOptions(context); + + const checkJsDoc = (node, isFunctionContext) => { + const jsDocNode = (0, getJSDocComment_1.getJSDocComment)(sourceCode, node, settings); + + if (jsDocNode) { + return; + } // For those who have options configured against ANY constructors (or setters or getters) being reported + + + if (_jsdocUtils.default.exemptSpeciaMethods({ + tags: [] + }, node, context, [OPTIONS_SCHEMA])) { + return; + } + + if ( // Avoid reporting param-less, return-less functions (when `exemptEmptyFunctions` option is set) + exemptEmptyFunctions && isFunctionContext || // Avoid reporting param-less, return-less constructor methods (when `exemptEmptyConstructors` option is set) + exemptEmptyConstructors && _jsdocUtils.default.isConstructor(node)) { + const functionParameterNames = _jsdocUtils.default.getFunctionParameterNames(node); + + if (!functionParameterNames.length && !_jsdocUtils.default.hasReturnValue(node, context)) { + return; + } + } + + const fix = fixer => { + // Default to one line break if the `minLines`/`maxLines` settings allow + const lines = settings.minLines === 0 && settings.maxLines >= 1 ? 1 : settings.minLines; + let baseNode = (0, getJSDocComment_1.getReducedASTNode)(node, sourceCode); + const decorator = (0, getJSDocComment_1.getDecorator)(baseNode); + + if (decorator) { + baseNode = decorator; + } + + const indent = _jsdocUtils.default.getIndent({ + text: sourceCode.getText(baseNode, baseNode.loc.start.column) + }); + + const { + inlineCommentBlock + } = contexts.find(({ + context: ctxt + }) => { + return ctxt === node.type; + }) || {}; + const insertion = (inlineCommentBlock ? '/** ' : `/**\n${indent}*\n${indent}`) + `*/${'\n'.repeat(lines)}${indent.slice(0, -1)}`; + return fixer.insertTextBefore(baseNode, insertion); + }; + + const report = () => { + const loc = { + end: node.loc.start + 1, + start: node.loc.start + }; + context.report({ + fix: enableFixer ? fix : null, + loc, + messageId: 'missingJsDoc', + node + }); + }; + + if (publicOnly) { + var _publicOnly$ancestors, _publicOnly$esm, _publicOnly$cjs, _publicOnly$window; + + const opt = { + ancestorsOnly: Boolean((_publicOnly$ancestors = publicOnly === null || publicOnly === void 0 ? void 0 : publicOnly.ancestorsOnly) !== null && _publicOnly$ancestors !== void 0 ? _publicOnly$ancestors : false), + esm: Boolean((_publicOnly$esm = publicOnly === null || publicOnly === void 0 ? void 0 : publicOnly.esm) !== null && _publicOnly$esm !== void 0 ? _publicOnly$esm : true), + initModuleExports: Boolean((_publicOnly$cjs = publicOnly === null || publicOnly === void 0 ? void 0 : publicOnly.cjs) !== null && _publicOnly$cjs !== void 0 ? _publicOnly$cjs : true), + initWindow: Boolean((_publicOnly$window = publicOnly === null || publicOnly === void 0 ? void 0 : publicOnly.window) !== null && _publicOnly$window !== void 0 ? _publicOnly$window : false) + }; + + const exported = _exportParser.default.isUncommentedExport(node, sourceCode, opt, settings); + + if (exported) { + report(); + } + } else { + report(); + } + }; + + const hasOption = prop => { + return requireOption[prop] || contexts.some(ctxt => { + return typeof ctxt === 'object' ? ctxt.context === prop : ctxt === prop; + }); + }; + + return { ..._jsdocUtils.default.getContextObject(_jsdocUtils.default.enforcedContexts(context, []), checkJsDoc), + + ArrowFunctionExpression(node) { + if (!hasOption('ArrowFunctionExpression')) { + return; + } + + if (['VariableDeclarator', 'AssignmentExpression', 'ExportDefaultDeclaration'].includes(node.parent.type) || ['Property', 'ObjectProperty', 'ClassProperty'].includes(node.parent.type) && node === node.parent.value) { + checkJsDoc(node, true); + } + }, + + ClassDeclaration(node) { + if (!hasOption('ClassDeclaration')) { + return; + } + + checkJsDoc(node); + }, + + ClassExpression(node) { + if (!hasOption('ClassExpression')) { + return; + } + + checkJsDoc(node); + }, + + FunctionDeclaration(node) { + if (!hasOption('FunctionDeclaration')) { + return; + } + + checkJsDoc(node, true); + }, + + FunctionExpression(node) { + if (hasOption('MethodDefinition') && node.parent.type === 'MethodDefinition') { + checkJsDoc(node, true); + return; + } + + if (!hasOption('FunctionExpression')) { + return; + } + + if (['VariableDeclarator', 'AssignmentExpression', 'ExportDefaultDeclaration'].includes(node.parent.type) || ['Property', 'ObjectProperty', 'ClassProperty'].includes(node.parent.type) && node === node.parent.value) { + checkJsDoc(node, true); + } + } + + }; + }, + + meta: { + docs: { + category: 'Stylistic Issues', + description: 'Require JSDoc comments', + recommended: 'true', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-jsdoc' + }, + fixable: 'code', + messages: { + missingJsDoc: 'Missing JSDoc comment.' + }, + schema: [OPTIONS_SCHEMA], + type: 'suggestion' + } +}; +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requireJsdoc.js.map +}); + +var requireParam = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _lodash = _interopRequireDefault(lodash__default['default']); + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const rootNamer = (desiredRoots, currentIndex) => { + let name; + let idx = currentIndex; + const incremented = desiredRoots.length <= 1; + + if (incremented) { + const base = desiredRoots[0]; + const suffix = idx++; + name = `${base}${suffix}`; + } else { + name = desiredRoots.shift(); + } + + return [name, incremented, () => { + return rootNamer(desiredRoots, idx); + }]; +}; + +var _default = (0, _iterateJsdoc.default)(({ + jsdoc, + utils, + context +}) => { + const preferredTagName = utils.getPreferredTagName({ + tagName: 'param' + }); + + if (!preferredTagName) { + return; + } + + const jsdocParameterNames = utils.getJsdocTagsDeep(preferredTagName); + const shallowJsdocParameterNames = jsdocParameterNames.filter(tag => { + return !tag.name.includes('.'); + }).map((tag, idx) => { + return { ...tag, + idx + }; + }); + + if (utils.avoidDocs()) { + return; + } // Param type is specified by type in @type + + + if (utils.hasTag('type')) { + return; + } + + const { + autoIncrementBase = 0, + checkRestProperty = false, + checkDestructured = true, + checkDestructuredRoots = true, + checkTypesPattern = '/^(?:[oO]bject|[aA]rray|PlainObject|Generic(?:Object|Array))$/', + enableFixer = true, + enableRootFixer = true, + enableRestElementFixer = true, + unnamedRootBase = ['root'], + useDefaultObjectProperties = false + } = context.options[0] || {}; + const checkTypesRegex = utils.getRegexFromString(checkTypesPattern); + const missingTags = []; + const functionParameterNames = utils.getFunctionParameterNames(useDefaultObjectProperties); + const flattenedRoots = utils.flattenRoots(functionParameterNames).names; + const paramIndex = {}; + + const hasParamIndex = cur => { + return _lodash.default.has(paramIndex, utils.dropPathSegmentQuotes(String(cur))); + }; + + const getParamIndex = cur => { + return paramIndex[utils.dropPathSegmentQuotes(String(cur))]; + }; + + const setParamIndex = (cur, idx) => { + paramIndex[utils.dropPathSegmentQuotes(String(cur))] = idx; + }; + + flattenedRoots.forEach((cur, idx) => { + setParamIndex(cur, idx); + }); + + const findExpectedIndex = (jsdocTags, indexAtFunctionParams) => { + const remainingRoots = functionParameterNames.slice(indexAtFunctionParams || 0); + const foundIndex = jsdocTags.findIndex(({ + name, + newAdd + }) => { + return !newAdd && remainingRoots.some(remainingRoot => { + if (Array.isArray(remainingRoot)) { + return remainingRoot[1].names.includes(name); + } + + if (typeof remainingRoot === 'object') { + return name === remainingRoot.name; + } + + return name === remainingRoot; + }); + }); + const tags = foundIndex > -1 ? jsdocTags.slice(0, foundIndex) : jsdocTags.filter(({ + tag + }) => { + return tag === preferredTagName; + }); + let tagLineCount = 0; + tags.forEach(({ + source + }) => { + source.forEach(({ + tokens: { + end + } + }) => { + if (!end) { + tagLineCount++; + } + }); + }); + return tagLineCount; + }; + + let [nextRootName, incremented, namer] = rootNamer([...unnamedRootBase], autoIncrementBase); + functionParameterNames.forEach((functionParameterName, functionParameterIdx) => { + let inc; + + if (Array.isArray(functionParameterName)) { + const matchedJsdoc = shallowJsdocParameterNames[functionParameterIdx] || jsdocParameterNames[functionParameterIdx]; + let rootName; + + if (functionParameterName[0]) { + rootName = functionParameterName[0]; + } else if (matchedJsdoc && matchedJsdoc.name) { + rootName = matchedJsdoc.name; + + if (matchedJsdoc.type && matchedJsdoc.type.search(checkTypesRegex) === -1) { + return; + } + } else { + rootName = nextRootName; + inc = incremented; + [nextRootName, incremented, namer] = namer(); + } + + const { + hasRestElement, + hasPropertyRest, + rests, + names + } = functionParameterName[1]; + const notCheckingNames = []; + + if (!enableRestElementFixer && hasRestElement) { + return; + } + + if (!checkDestructuredRoots) { + return; + } + + names.forEach((paramName, idx) => { + // Add root if the root name is not in the docs (and is not already + // in the tags to be fixed) + if (!jsdocParameterNames.find(({ + name + }) => { + return name === rootName; + }) && !missingTags.find(({ + functionParameterName: fpn + }) => { + return fpn === rootName; + })) { + const emptyParamIdx = jsdocParameterNames.findIndex(({ + name + }) => { + return !name; + }); + + if (emptyParamIdx > -1) { + missingTags.push({ + functionParameterIdx: emptyParamIdx, + functionParameterName: rootName, + inc, + remove: true + }); + } else { + missingTags.push({ + functionParameterIdx: hasParamIndex(rootName) ? getParamIndex(rootName) : getParamIndex(paramName), + functionParameterName: rootName, + inc + }); + } + } + + if (!checkDestructured) { + return; + } + + if (!checkRestProperty && rests[idx]) { + return; + } + + const fullParamName = `${rootName}.${paramName}`; + const notCheckingName = jsdocParameterNames.find(({ + name, + type: paramType + }) => { + return utils.comparePaths(name)(fullParamName) && paramType.search(checkTypesRegex) === -1 && paramType !== ''; + }); + + if (notCheckingName !== undefined) { + notCheckingNames.push(notCheckingName.name); + } + + if (notCheckingNames.find(name => { + return fullParamName.startsWith(name); + })) { + return; + } + + if (jsdocParameterNames && !jsdocParameterNames.find(({ + name + }) => { + return utils.comparePaths(name)(fullParamName); + })) { + missingTags.push({ + functionParameterIdx: getParamIndex(functionParameterName[0] ? fullParamName : paramName), + functionParameterName: fullParamName, + inc, + type: hasRestElement && !hasPropertyRest ? '{...any}' : undefined + }); + } + }); + return; + } + + let funcParamName; + let type; + + if (typeof functionParameterName === 'object') { + if (!enableRestElementFixer && functionParameterName.restElement) { + return; + } + + funcParamName = functionParameterName.name; + type = '{...any}'; + } else { + funcParamName = functionParameterName; + } + + if (jsdocParameterNames && !jsdocParameterNames.find(({ + name + }) => { + return name === funcParamName; + })) { + missingTags.push({ + functionParameterIdx: getParamIndex(funcParamName), + functionParameterName: funcParamName, + inc, + type + }); + } + }); + + const fix = ({ + functionParameterIdx, + functionParameterName, + remove, + inc, + type + }) => { + if (inc && !enableRootFixer) { + return; + } + + const createTokens = (tagIndex, sourceIndex, spliceCount) => { + // console.log(sourceIndex, tagIndex, jsdoc.tags, jsdoc.source); + const tokens = { + number: sourceIndex + 1, + tokens: { + delimiter: '*', + description: '', + end: '', + name: functionParameterName, + newAdd: true, + postDelimiter: ' ', + postName: '', + postTag: ' ', + postType: type ? ' ' : '', + start: jsdoc.source[sourceIndex].tokens.start, + tag: `@${preferredTagName}`, + type: type !== null && type !== void 0 ? type : '' + } + }; + jsdoc.tags.splice(tagIndex, spliceCount, { + name: functionParameterName, + newAdd: true, + source: [tokens], + tag: preferredTagName, + type: type !== null && type !== void 0 ? type : '' + }); + const firstNumber = jsdoc.source[0].number; + jsdoc.source.splice(sourceIndex, spliceCount, tokens); + jsdoc.source.slice(sourceIndex).forEach((src, idx) => { + src.number = firstNumber + sourceIndex + idx; + }); + }; + + const offset = jsdoc.source.findIndex(({ + tokens: { + tag, + end + } + }) => { + return tag || end; + }); + + if (remove) { + createTokens(functionParameterIdx, offset + functionParameterIdx, 1); + } else { + const expectedIdx = findExpectedIndex(jsdoc.tags, functionParameterIdx); + createTokens(expectedIdx, offset + expectedIdx, 0); + } + }; + + const fixer = () => { + missingTags.forEach(missingTag => { + fix(missingTag); + }); + }; + + missingTags.forEach(({ + functionParameterName + }) => { + utils.reportJSDoc(`Missing JSDoc @${preferredTagName} "${functionParameterName}" declaration.`, null, enableFixer ? fixer : null); + }); +}, { + contextDefaults: true, + meta: { + docs: { + description: 'Requires that all function parameters are documented.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-param' + }, + fixable: 'code', + schema: [{ + additionalProperties: false, + properties: { + autoIncrementBase: { + default: 0, + type: 'integer' + }, + checkConstructors: { + default: true, + type: 'boolean' + }, + checkDestructured: { + default: true, + type: 'boolean' + }, + checkDestructuredRoots: { + default: true, + type: 'boolean' + }, + checkGetters: { + default: false, + type: 'boolean' + }, + checkRestProperty: { + default: false, + type: 'boolean' + }, + checkSetters: { + default: false, + type: 'boolean' + }, + checkTypesPattern: { + type: 'string' + }, + contexts: { + items: { + type: 'string' + }, + type: 'array' + }, + enableFixer: { + type: 'boolean' + }, + enableRestElementFixer: { + type: 'boolean' + }, + enableRootFixer: { + type: 'boolean' + }, + exemptedBy: { + items: { + type: 'string' + }, + type: 'array' + }, + unnamedRootBase: { + items: { + type: 'string' + }, + type: 'array' + }, + useDefaultObjectProperties: { + type: 'boolean' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requireParam.js.map +}); + +var requireParamDescription = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _default = (0, _iterateJsdoc.default)(({ + report, + utils +}) => { + utils.forEachPreferredTag('param', (jsdocParameter, targetTagName) => { + if (!jsdocParameter.description.trim()) { + report(`Missing JSDoc @${targetTagName} "${jsdocParameter.name}" description.`, null, jsdocParameter); + } + }); +}, { + contextDefaults: true, + meta: { + docs: { + description: 'Requires that each `@param` tag has a `description` value.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-param-description' + }, + schema: [{ + additionalProperties: false, + properties: { + contexts: { + items: { + type: 'string' + }, + type: 'array' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requireParamDescription.js.map +}); + +var requireParamName = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _default = (0, _iterateJsdoc.default)(({ + report, + utils +}) => { + utils.forEachPreferredTag('param', (jsdocParameter, targetTagName) => { + if (jsdocParameter.tag && jsdocParameter.name === '') { + report(`There must be an identifier after @${targetTagName} ${jsdocParameter.type === '' ? 'type' : 'tag'}.`, null, jsdocParameter); + } + }); +}, { + contextDefaults: true, + meta: { + docs: { + description: 'Requires that all function parameters have names.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-param-name' + }, + schema: [{ + additionalProperties: false, + properties: { + contexts: { + items: { + type: 'string' + }, + type: 'array' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requireParamName.js.map +}); + +var requireParamType = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _default = (0, _iterateJsdoc.default)(({ + report, + utils +}) => { + utils.forEachPreferredTag('param', (jsdocParameter, targetTagName) => { + if (!jsdocParameter.type) { + report(`Missing JSDoc @${targetTagName} "${jsdocParameter.name}" type.`, null, jsdocParameter); + } + }); +}, { + contextDefaults: true, + meta: { + docs: { + description: 'Requires that each `@param` tag has a `type` value.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-param-type' + }, + schema: [{ + additionalProperties: false, + properties: { + contexts: { + items: { + type: 'string' + }, + type: 'array' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requireParamType.js.map +}); + +var requireProperty = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _default = (0, _iterateJsdoc.default)(({ + utils +}) => { + const propertyAssociatedTags = utils.filterTags(({ + tag + }) => { + return ['typedef', 'namespace'].includes(tag); + }); + + if (!propertyAssociatedTags.length) { + return; + } + + const targetTagName = utils.getPreferredTagName({ + tagName: 'property' + }); + + if (utils.hasATag([targetTagName])) { + return; + } + + propertyAssociatedTags.forEach(propertyAssociatedTag => { + if (!['object', 'Object', 'PlainObject'].includes(propertyAssociatedTag.type)) { + return; + } + + utils.reportJSDoc(`Missing JSDoc @${targetTagName}.`, null, () => { + utils.addTag(targetTagName); + }); + }); +}, { + iterateAllJsdocs: true, + meta: { + docs: { + description: 'Requires that all `@typedef` and `@namespace` tags have `@property` when their type is a plain `object`, `Object`, or `PlainObject`.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-property' + }, + fixable: 'code', + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requireProperty.js.map +}); + +var requirePropertyDescription = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _default = (0, _iterateJsdoc.default)(({ + report, + utils +}) => { + utils.forEachPreferredTag('property', (jsdoc, targetTagName) => { + if (!jsdoc.description.trim()) { + report(`Missing JSDoc @${targetTagName} "${jsdoc.name}" description.`, null, jsdoc); + } + }); +}, { + iterateAllJsdocs: true, + meta: { + docs: { + description: 'Requires that each `@property` tag has a `description` value.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-property-description' + }, + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requirePropertyDescription.js.map +}); + +var requirePropertyName = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _default = (0, _iterateJsdoc.default)(({ + report, + utils +}) => { + utils.forEachPreferredTag('property', (jsdoc, targetTagName) => { + if (jsdoc.tag && jsdoc.name === '') { + report(`There must be an identifier after @${targetTagName} ${jsdoc.type === '' ? 'type' : 'tag'}.`, null, jsdoc); + } + }); +}, { + iterateAllJsdocs: true, + meta: { + docs: { + description: 'Requires that all function `@property` tags have names.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-property-name' + }, + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requirePropertyName.js.map +}); + +var requirePropertyType = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _default = (0, _iterateJsdoc.default)(({ + report, + utils +}) => { + utils.forEachPreferredTag('property', (jsdoc, targetTagName) => { + if (!jsdoc.type) { + report(`Missing JSDoc @${targetTagName} "${jsdoc.name}" type.`, null, jsdoc); + } + }); +}, { + iterateAllJsdocs: true, + meta: { + docs: { + description: 'Requires that each `@property` tag has a `type` value.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-property-type' + }, + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requirePropertyType.js.map +}); + +var requireReturns = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * We can skip checking for a return value, in case the documentation is inherited + * or the method is either a constructor or an abstract method. + * + * In either of these cases the return value is optional or not defined. + * + * @param {*} utils + * a reference to the utils which are used to probe if a tag is present or not. + * @returns {boolean} + * true in case deep checking can be skipped; otherwise false. + */ +const canSkip = utils => { + return utils.hasATag([// inheritdoc implies that all documentation is inherited + // see https://jsdoc.app/tags-inheritdoc.html + // + // Abstract methods are by definition incomplete, + // so it is not an error if it declares a return value but does not implement it. + 'abstract', 'virtual', // Constructors do not have a return value by definition (https://jsdoc.app/tags-class.html) + // So we can bail out here, too. + 'class', 'constructor', // Return type is specified by type in @type + 'type', // This seems to imply a class as well + 'interface']) || utils.avoidDocs(); +}; + +var _default = (0, _iterateJsdoc.default)(({ + report, + utils, + context +}) => { + const { + forceRequireReturn = false, + forceReturnsWithAsync = false + } = context.options[0] || {}; // A preflight check. We do not need to run a deep check + // in case the @returns comment is optional or undefined. + + if (canSkip(utils)) { + return; + } + + const tagName = utils.getPreferredTagName({ + tagName: 'returns' + }); + + if (!tagName) { + return; + } + + const tags = utils.getTags(tagName); + + if (tags.length > 1) { + report(`Found more than one @${tagName} declaration.`); + } + + const iteratingFunction = utils.isIteratingFunction(); // In case the code returns something, we expect a return value in JSDoc. + + const [tag] = tags; + const missingReturnTag = typeof tag === 'undefined' || tag === null; + + const shouldReport = () => { + if (!missingReturnTag) { + return false; + } + + if (forceRequireReturn && (iteratingFunction || utils.isVirtualFunction())) { + return true; + } + + const isAsync = !iteratingFunction && utils.hasTag('async') || iteratingFunction && utils.isAsync(); + + if (forceReturnsWithAsync && isAsync) { + return true; + } + + return iteratingFunction && utils.hasValueOrExecutorHasNonEmptyResolveValue(forceReturnsWithAsync); + }; + + if (shouldReport()) { + report(`Missing JSDoc @${tagName} declaration.`); + } +}, { + contextDefaults: true, + meta: { + docs: { + description: 'Requires returns are documented.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-returns' + }, + schema: [{ + additionalProperties: false, + properties: { + checkConstructors: { + default: false, + type: 'boolean' + }, + checkGetters: { + default: true, + type: 'boolean' + }, + contexts: { + items: { + type: 'string' + }, + type: 'array' + }, + exemptedBy: { + items: { + type: 'string' + }, + type: 'array' + }, + forceRequireReturn: { + default: false, + type: 'boolean' + }, + forceReturnsWithAsync: { + default: false, + type: 'boolean' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requireReturns.js.map +}); + +var requireReturnsCheck = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const canSkip = (utils, settings) => { + const voidingTags = [// An abstract function is by definition incomplete + // so it is perfectly fine if a return is documented but + // not present within the function. + // A subclass may inherit the doc and implement the + // missing return. + 'abstract', 'virtual', // A constructor function returns `this` by default, so may be `@returns` + // tag indicating this but no explicit return + 'class', 'constructor', 'interface']; + + if (settings.mode === 'closure') { + // Structural Interface in GCC terms, equivalent to @interface tag as far as this rule is concerned + voidingTags.push('record'); + } + + return utils.hasATag(voidingTags) || utils.isConstructor() || utils.classHasTag('interface') || settings.mode === 'closure' && utils.classHasTag('record'); +}; + +var _default = (0, _iterateJsdoc.default)(({ + context, + report, + settings, + utils +}) => { + const { + exemptAsync = true, + reportMissingReturnForUndefinedTypes = false + } = context.options[0] || {}; + + if (canSkip(utils, settings)) { + return; + } + + if (exemptAsync && utils.isAsync()) { + return; + } + + const tagName = utils.getPreferredTagName({ + tagName: 'returns' + }); + + if (!tagName) { + return; + } + + const tags = utils.getTags(tagName); + + if (tags.length === 0) { + return; + } + + if (tags.length > 1) { + report(`Found more than one @${tagName} declaration.`); + return; + } // In case a return value is declared in JSDoc, we also expect one in the code. + + + if ((reportMissingReturnForUndefinedTypes || utils.hasDefinedTypeTag(tags[0])) && !utils.hasValueOrExecutorHasNonEmptyResolveValue(exemptAsync)) { + report(`JSDoc @${tagName} declaration present but return expression not available in function.`); + } +}, { + meta: { + docs: { + description: 'Requires a return statement in function body if a `@returns` tag is specified in jsdoc comment.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-returns-check' + }, + schema: [{ + additionalProperties: false, + properties: { + exemptAsync: { + default: true, + type: 'boolean' + }, + reportMissingReturnForUndefinedTypes: { + default: false, + type: 'boolean' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requireReturnsCheck.js.map +}); + +var requireReturnsDescription = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _default = (0, _iterateJsdoc.default)(({ + report, + utils +}) => { + utils.forEachPreferredTag('returns', (jsdocTag, targetTagName) => { + const type = jsdocTag.type && jsdocTag.type.trim(); + + if (['void', 'undefined', 'Promise', 'Promise'].includes(type)) { + return; + } + + if (!jsdocTag.description.trim()) { + report(`Missing JSDoc @${targetTagName} description.`, null, jsdocTag); + } + }); +}, { + contextDefaults: true, + meta: { + docs: { + description: 'Requires that the `@returns` tag has a `description` value.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-returns-description' + }, + schema: [{ + additionalProperties: false, + properties: { + contexts: { + items: { + type: 'string' + }, + type: 'array' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requireReturnsDescription.js.map +}); + +var requireReturnsType = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _default = (0, _iterateJsdoc.default)(({ + report, + utils +}) => { + utils.forEachPreferredTag('returns', (jsdocTag, targetTagName) => { + if (!jsdocTag.type) { + report(`Missing JSDoc @${targetTagName} type.`, null, jsdocTag); + } + }); +}, { + contextDefaults: true, + meta: { + docs: { + description: 'Requires that `@returns` tag has `type` value.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-returns-type' + }, + schema: [{ + additionalProperties: false, + properties: { + contexts: { + items: { + type: 'string' + }, + type: 'array' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requireReturnsType.js.map +}); + +var requireThrows = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * We can skip checking for a throws value, in case the documentation is inherited + * or the method is either a constructor or an abstract method. + * + * @param {*} utils + * a reference to the utils which are used to probe if a tag is present or not. + * @returns {boolean} + * true in case deep checking can be skipped; otherwise false. + */ +const canSkip = utils => { + return utils.hasATag([// inheritdoc implies that all documentation is inherited + // see https://jsdoc.app/tags-inheritdoc.html + // + // Abstract methods are by definition incomplete, + // so it is not necessary to document that they throw an error. + 'abstract', 'virtual', // The designated type can itself document `@throws` + 'type']) || utils.avoidDocs(); +}; + +var _default = (0, _iterateJsdoc.default)(({ + report, + utils +}) => { + // A preflight check. We do not need to run a deep check for abstract + // functions. + if (canSkip(utils)) { + return; + } + + const tagName = utils.getPreferredTagName({ + tagName: 'throws' + }); + + if (!tagName) { + return; + } + + const tags = utils.getTags(tagName); + const iteratingFunction = utils.isIteratingFunction(); // In case the code returns something, we expect a return value in JSDoc. + + const [tag] = tags; + const missingThrowsTag = typeof tag === 'undefined' || tag === null; + + const shouldReport = () => { + if (!missingThrowsTag) { + return false; + } + + return iteratingFunction && utils.hasThrowValue(); + }; + + if (shouldReport()) { + report(`Missing JSDoc @${tagName} declaration.`); + } +}, { + contextDefaults: true, + meta: { + docs: { + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-returns' + }, + schema: [{ + additionalProperties: false, + properties: { + contexts: { + items: { + type: 'string' + }, + type: 'array' + }, + exemptedBy: { + items: { + type: 'string' + }, + type: 'array' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requireThrows.js.map +}); + +var requireYields = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * We can skip checking for a yield value, in case the documentation is inherited + * or the method has a constructor or abstract tag. + * + * In either of these cases the yield value is optional or not defined. + * + * @param {*} utils + * a reference to the utils which are used to probe if a tag is present or not. + * @returns {boolean} + * true in case deep checking can be skipped; otherwise false. + */ +const canSkip = utils => { + return utils.hasATag([// inheritdoc implies that all documentation is inherited + // see https://jsdoc.app/tags-inheritdoc.html + // + // Abstract methods are by definition incomplete, + // so it is not an error if it declares a yield value but does not implement it. + 'abstract', 'virtual', // Constructors do not have a yield value + // so we can bail out here, too. + 'class', 'constructor', // Yield (and any `next`) type is specified accompanying the targeted + // @type + 'type', // This seems to imply a class as well + 'interface']) || utils.avoidDocs(); +}; + +const checkTagName = (utils, report, tagName) => { + const preferredTagName = utils.getPreferredTagName({ + tagName + }); + + if (!preferredTagName) { + return []; + } + + const tags = utils.getTags(preferredTagName); + + if (tags.length > 1) { + report(`Found more than one @${preferredTagName} declaration.`); + } // In case the code yields something, we expect a yields value in JSDoc. + + + const [tag] = tags; + const missingTag = typeof tag === 'undefined' || tag === null; + return [preferredTagName, missingTag]; +}; + +var _default = (0, _iterateJsdoc.default)(({ + report, + utils, + context +}) => { + const { + next = false, + nextWithGeneratorTag = false, + forceRequireNext = false, + forceRequireYields = false, + withGeneratorTag = true + } = context.options[0] || {}; // A preflight check. We do not need to run a deep check + // in case the @yield comment is optional or undefined. + + if (canSkip(utils)) { + return; + } + + const iteratingFunction = utils.isIteratingFunction(); + const [preferredYieldTagName, missingYieldTag] = checkTagName(utils, report, 'yields'); + + if (preferredYieldTagName) { + const shouldReportYields = () => { + if (!missingYieldTag) { + return false; + } + + if (withGeneratorTag && utils.hasTag('generator') || forceRequireYields && iteratingFunction && utils.isGenerator()) { + return true; + } + + return iteratingFunction && utils.isGenerator() && utils.hasYieldValue(); + }; + + if (shouldReportYields()) { + report(`Missing JSDoc @${preferredYieldTagName} declaration.`); + } + } + + if (next || nextWithGeneratorTag || forceRequireNext) { + const [preferredNextTagName, missingNextTag] = checkTagName(utils, report, 'next'); + + if (!preferredNextTagName) { + return; + } + + const shouldReportNext = () => { + if (!missingNextTag) { + return false; + } + + if (nextWithGeneratorTag && utils.hasTag('generator')) { + return true; + } + + if (!next && !forceRequireNext || !iteratingFunction || !utils.isGenerator()) { + return false; + } + + return forceRequireNext || utils.hasYieldReturnValue(); + }; + + if (shouldReportNext()) { + report(`Missing JSDoc @${preferredNextTagName} declaration.`); + } + } +}, { + contextDefaults: true, + meta: { + docs: { + description: 'Requires yields are documented.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-yields' + }, + schema: [{ + additionalProperties: false, + properties: { + contexts: { + items: { + type: 'string' + }, + type: 'array' + }, + exemptedBy: { + items: { + type: 'string' + }, + type: 'array' + }, + forceRequireNext: { + default: false, + type: 'boolean' + }, + forceRequireYields: { + default: false, + type: 'boolean' + }, + next: { + default: false, + type: 'boolean' + }, + nextWithGeneratorTag: { + default: false, + type: 'boolean' + }, + withGeneratorTag: { + default: true, + type: 'boolean' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requireYields.js.map +}); + +var requireYieldsCheck = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const canSkip = (utils, settings) => { + const voidingTags = [// An abstract function is by definition incomplete + // so it is perfectly fine if a yield is documented but + // not present within the function. + // A subclass may inherit the doc and implement the + // missing yield. + 'abstract', 'virtual', // Constructor functions do not have a yield value + // so we can bail here, too. + 'class', 'constructor', // This seems to imply a class as well + 'interface']; + + if (settings.mode === 'closure') { + // Structural Interface in GCC terms, equivalent to @interface tag as far as this rule is concerned + voidingTags.push('record'); + } + + return utils.hasATag(voidingTags) || utils.isConstructor() || utils.classHasTag('interface') || settings.mode === 'closure' && utils.classHasTag('record'); +}; + +const checkTagName = (utils, report, tagName) => { + const preferredTagName = utils.getPreferredTagName({ + tagName + }); + + if (!preferredTagName) { + return []; + } + + const tags = utils.getTags(preferredTagName); + + if (tags.length === 0) { + return []; + } + + if (tags.length > 1) { + report(`Found more than one @${preferredTagName} declaration.`); + return []; + } + + return [preferredTagName, tags[0]]; +}; + +var _default = (0, _iterateJsdoc.default)(({ + context, + report, + settings, + utils +}) => { + if (canSkip(utils, settings)) { + return; + } + + const { + next = false, + checkGeneratorsOnly = false + } = context.options[0] || {}; + const [preferredYieldTagName, yieldTag] = checkTagName(utils, report, 'yields'); + + if (preferredYieldTagName) { + const shouldReportYields = () => { + if (checkGeneratorsOnly && !utils.isGenerator()) { + return true; + } + + return utils.hasDefinedTypeTag(yieldTag) && !utils.hasYieldValue(); + }; // In case a yield value is declared in JSDoc, we also expect one in the code. + + + if (shouldReportYields()) { + report(`JSDoc @${preferredYieldTagName} declaration present but yield expression not available in function.`); + } + } + + if (next) { + const [preferredNextTagName, nextTag] = checkTagName(utils, report, 'next'); + + if (preferredNextTagName) { + const shouldReportNext = () => { + if (checkGeneratorsOnly && !utils.isGenerator()) { + return true; + } + + return utils.hasDefinedTypeTag(nextTag) && !utils.hasYieldReturnValue(); + }; + + if (shouldReportNext()) { + report(`JSDoc @${preferredNextTagName} declaration present but yield expression with return value not available in function.`); + } + } + } +}, { + meta: { + docs: { + description: 'Requires a yield statement in function body if a `@yields` tag is specified in jsdoc comment.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-yields-check' + }, + schema: [{ + additionalProperties: false, + properties: { + checkGeneratorsOnly: { + default: false, + type: 'boolean' + }, + contexts: { + items: { + type: 'string' + }, + type: 'array' + }, + exemptedBy: { + items: { + type: 'string' + }, + type: 'array' + }, + next: { + default: false, + type: 'boolean' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=requireYieldsCheck.js.map +}); + +var validTypes = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + + + +var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const asExpression = /as\s+/u; + +var _default = (0, _iterateJsdoc.default)(({ + jsdoc, + report, + utils, + context, + settings +}) => { + const { + allowEmptyNamepaths = false + } = context.options[0] || {}; + const { + mode + } = settings; + + const tryParseIgnoreError = path => { + try { + (0, jsdoctypeparser.parse)(path, { + mode + }); + return true; + } catch {// Keep the original error for including the whole type + } + + return false; + }; // eslint-disable-next-line complexity + + + jsdoc.tags.forEach(tag => { + const validNamepathParsing = function (namepath, tagName) { + if (tryParseIgnoreError(namepath)) { + return true; + } + + let handled = false; + + if (tagName) { + switch (tagName) { + case 'module': + { + if (!namepath.startsWith('module:')) { + handled = tryParseIgnoreError(`module:${namepath}`); + } + + break; + } + + case 'memberof': + case 'memberof!': + { + const endChar = namepath.slice(-1); + + if (['#', '.', '~'].includes(endChar)) { + handled = tryParseIgnoreError(namepath.slice(0, -1)); + } + + break; + } + + case 'borrows': + { + const startChar = namepath.charAt(); + + if (['#', '.', '~'].includes(startChar)) { + handled = tryParseIgnoreError(namepath.slice(1)); + } + } + } + } + + if (!handled) { + report(`Syntax error in namepath: ${namepath}`, null, tag); + return false; + } + + return true; + }; + + const validTypeParsing = function (type) { + try { + (0, jsdoctypeparser.parse)(type, { + mode + }); + } catch { + report(`Syntax error in type: ${type}`, null, tag); + return false; + } + + return true; + }; + + if (tag.tag === 'borrows') { + const thisNamepath = tag.description.replace(asExpression, '').trim(); + + if (!asExpression.test(tag.description) || !thisNamepath) { + report(`@borrows must have an "as" expression. Found "${tag.description}"`, null, tag); + return; + } + + if (validNamepathParsing(thisNamepath, 'borrows')) { + const thatNamepath = tag.name; + validNamepathParsing(thatNamepath); + } + + return; + } + + const otherModeMaps = ['jsdoc', 'typescript', 'closure', 'permissive'].filter(mde => { + return mde !== mode; + }).map(mde => { + return utils.getTagStructureForMode(mde); + }); + const tagMightHaveNamePosition = utils.tagMightHaveNamePosition(tag.tag, otherModeMaps); + + if (tagMightHaveNamePosition !== true && tag.name) { + const modeInfo = tagMightHaveNamePosition === false ? '' : ` in "${mode}" mode`; + report(`@${tag.tag} should not have a name${modeInfo}.`, null, tag); + return; + } + + const mightHaveTypePosition = utils.tagMightHaveTypePosition(tag.tag, otherModeMaps); + + if (mightHaveTypePosition !== true && tag.type) { + const modeInfo = mightHaveTypePosition === false ? '' : ` in "${mode}" mode`; + report(`@${tag.tag} should not have a bracketed type${modeInfo}.`, null, tag); + return; + } // REQUIRED NAME + + + const tagMustHaveNamePosition = utils.tagMustHaveNamePosition(tag.tag, otherModeMaps); // Don't handle `@param` here though it does require name as handled by + // `require-param-name` (`@property` would similarly seem to require one, + // but is handled by `require-property-name`) + + if (tagMustHaveNamePosition !== false && !tag.name && !allowEmptyNamepaths && !['param', 'arg', 'argument', 'property', 'prop'].includes(tag.tag) && (tag.tag !== 'see' || !tag.description.includes('{@link'))) { + const modeInfo = tagMustHaveNamePosition === true ? '' : ` in "${mode}" mode`; + report(`Tag @${tag.tag} must have a name/namepath${modeInfo}.`, null, tag); + return; + } // REQUIRED TYPE + + + const mustHaveTypePosition = utils.tagMustHaveTypePosition(tag.tag, otherModeMaps); + + if (mustHaveTypePosition !== false && !tag.type) { + const modeInfo = mustHaveTypePosition === true ? '' : ` in "${mode}" mode`; + report(`Tag @${tag.tag} must have a type${modeInfo}.`, null, tag); + return; + } // REQUIRED TYPE OR NAME/NAMEPATH + + + const tagMissingRequiredTypeOrNamepath = utils.tagMissingRequiredTypeOrNamepath(tag, otherModeMaps); + + if (tagMissingRequiredTypeOrNamepath !== false && !allowEmptyNamepaths) { + const modeInfo = tagMissingRequiredTypeOrNamepath === true ? '' : ` in "${mode}" mode`; + report(`Tag @${tag.tag} must have either a type or namepath${modeInfo}.`, null, tag); + return; + } // VALID TYPE + + + const hasTypePosition = mightHaveTypePosition === true && Boolean(tag.type); + + if (hasTypePosition) { + validTypeParsing(tag.type); + } // VALID NAME/NAMEPATH + + + const hasNameOrNamepathPosition = (tagMustHaveNamePosition !== false || utils.tagMightHaveNamepath(tag.tag)) && Boolean(tag.name); + + if (hasNameOrNamepathPosition) { + if (mode !== 'jsdoc' && tag.tag === 'template') { + utils.parseClosureTemplateTag(tag).forEach(namepath => { + validNamepathParsing(namepath); + }); + } else { + validNamepathParsing(tag.name, tag.tag); + } + } + }); +}, { + iterateAllJsdocs: true, + meta: { + docs: { + description: 'Requires all types to be valid JSDoc or Closure compiler types without syntax errors.', + url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-valid-types' + }, + schema: [{ + additionalProperies: false, + properties: { + allowEmptyNamepaths: { + default: false, + type: 'boolean' + } + }, + type: 'object' + }], + type: 'suggestion' + } +}); + +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=validTypes.js.map +}); + +var dist = createCommonjsModule(function (module, exports) { + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +var _checkAccess = _interopRequireDefault(checkAccess); + +var _checkAlignment = _interopRequireDefault(checkAlignment); + +var _checkExamples = _interopRequireDefault(checkExamples); + +var _checkIndentation = _interopRequireDefault(checkIndentation); + +var _checkLineAlignment = _interopRequireDefault(checkLineAlignment); + +var _checkParamNames = _interopRequireDefault(checkParamNames); + +var _checkPropertyNames = _interopRequireDefault(checkPropertyNames); + +var _checkSyntax = _interopRequireDefault(checkSyntax); + +var _checkTagNames = _interopRequireDefault(checkTagNames); + +var _checkTypes = _interopRequireDefault(checkTypes); + +var _checkValues = _interopRequireDefault(checkValues); + +var _emptyTags = _interopRequireDefault(emptyTags); + +var _implementsOnClasses = _interopRequireDefault(implementsOnClasses); + +var _matchDescription = _interopRequireDefault(matchDescription); + +var _newlineAfterDescription = _interopRequireDefault(newlineAfterDescription); + +var _noBadBlocks = _interopRequireDefault(noBadBlocks); + +var _noDefaults = _interopRequireDefault(noDefaults); + +var _noTypes = _interopRequireDefault(noTypes); + +var _noUndefinedTypes = _interopRequireDefault(noUndefinedTypes); + +var _requireDescription = _interopRequireDefault(requireDescription); + +var _requireDescriptionCompleteSentence = _interopRequireDefault(requireDescriptionCompleteSentence); + +var _requireExample = _interopRequireDefault(requireExample); + +var _requireFileOverview = _interopRequireDefault(requireFileOverview); + +var _requireHyphenBeforeParamDescription = _interopRequireDefault(requireHyphenBeforeParamDescription); + +var _requireJsdoc = _interopRequireDefault(requireJsdoc); + +var _requireParam = _interopRequireDefault(requireParam); + +var _requireParamDescription = _interopRequireDefault(requireParamDescription); + +var _requireParamName = _interopRequireDefault(requireParamName); + +var _requireParamType = _interopRequireDefault(requireParamType); + +var _requireProperty = _interopRequireDefault(requireProperty); + +var _requirePropertyDescription = _interopRequireDefault(requirePropertyDescription); + +var _requirePropertyName = _interopRequireDefault(requirePropertyName); + +var _requirePropertyType = _interopRequireDefault(requirePropertyType); + +var _requireReturns = _interopRequireDefault(requireReturns); + +var _requireReturnsCheck = _interopRequireDefault(requireReturnsCheck); + +var _requireReturnsDescription = _interopRequireDefault(requireReturnsDescription); + +var _requireReturnsType = _interopRequireDefault(requireReturnsType); + +var _requireThrows = _interopRequireDefault(requireThrows); + +var _requireYields = _interopRequireDefault(requireYields); + +var _requireYieldsCheck = _interopRequireDefault(requireYieldsCheck); + +var _validTypes = _interopRequireDefault(validTypes); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +var _default = { + configs: { + recommended: { + plugins: ['jsdoc'], + rules: { + 'jsdoc/check-access': 'warn', + 'jsdoc/check-alignment': 'warn', + 'jsdoc/check-examples': 'off', + 'jsdoc/check-indentation': 'off', + 'jsdoc/check-line-alignment': 'off', + 'jsdoc/check-param-names': 'warn', + 'jsdoc/check-property-names': 'warn', + 'jsdoc/check-syntax': 'off', + 'jsdoc/check-tag-names': 'warn', + 'jsdoc/check-types': 'warn', + 'jsdoc/check-values': 'warn', + 'jsdoc/empty-tags': 'warn', + 'jsdoc/implements-on-classes': 'warn', + 'jsdoc/match-description': 'off', + 'jsdoc/newline-after-description': 'warn', + 'jsdoc/no-bad-blocks': 'off', + 'jsdoc/no-defaults': 'off', + 'jsdoc/no-types': 'off', + 'jsdoc/no-undefined-types': 'warn', + 'jsdoc/require-description': 'off', + 'jsdoc/require-description-complete-sentence': 'off', + 'jsdoc/require-example': 'off', + 'jsdoc/require-file-overview': 'off', + 'jsdoc/require-hyphen-before-param-description': 'off', + 'jsdoc/require-jsdoc': 'warn', + 'jsdoc/require-param': 'warn', + 'jsdoc/require-param-description': 'warn', + 'jsdoc/require-param-name': 'warn', + 'jsdoc/require-param-type': 'warn', + 'jsdoc/require-property': 'warn', + 'jsdoc/require-property-description': 'warn', + 'jsdoc/require-property-name': 'warn', + 'jsdoc/require-property-type': 'warn', + 'jsdoc/require-returns': 'warn', + 'jsdoc/require-returns-check': 'warn', + 'jsdoc/require-returns-description': 'warn', + 'jsdoc/require-returns-type': 'warn', + 'jsdoc/require-throws': 'off', + 'jsdoc/require-yields': 'warn', + 'jsdoc/require-yields-check': 'warn', + 'jsdoc/valid-types': 'warn' + } + } + }, + rules: { + 'check-access': _checkAccess.default, + 'check-alignment': _checkAlignment.default, + 'check-examples': _checkExamples.default, + 'check-indentation': _checkIndentation.default, + 'check-line-alignment': _checkLineAlignment.default, + 'check-param-names': _checkParamNames.default, + 'check-property-names': _checkPropertyNames.default, + 'check-syntax': _checkSyntax.default, + 'check-tag-names': _checkTagNames.default, + 'check-types': _checkTypes.default, + 'check-values': _checkValues.default, + 'empty-tags': _emptyTags.default, + 'implements-on-classes': _implementsOnClasses.default, + 'match-description': _matchDescription.default, + 'newline-after-description': _newlineAfterDescription.default, + 'no-bad-blocks': _noBadBlocks.default, + 'no-defaults': _noDefaults.default, + 'no-types': _noTypes.default, + 'no-undefined-types': _noUndefinedTypes.default, + 'require-description': _requireDescription.default, + 'require-description-complete-sentence': _requireDescriptionCompleteSentence.default, + 'require-example': _requireExample.default, + 'require-file-overview': _requireFileOverview.default, + 'require-hyphen-before-param-description': _requireHyphenBeforeParamDescription.default, + 'require-jsdoc': _requireJsdoc.default, + 'require-param': _requireParam.default, + 'require-param-description': _requireParamDescription.default, + 'require-param-name': _requireParamName.default, + 'require-param-type': _requireParamType.default, + 'require-property': _requireProperty.default, + 'require-property-description': _requirePropertyDescription.default, + 'require-property-name': _requirePropertyName.default, + 'require-property-type': _requirePropertyType.default, + 'require-returns': _requireReturns.default, + 'require-returns-check': _requireReturnsCheck.default, + 'require-returns-description': _requireReturnsDescription.default, + 'require-returns-type': _requireReturnsType.default, + 'require-throws': _requireThrows.default, + 'require-yields': _requireYields.default, + 'require-yields-check': _requireYieldsCheck.default, + 'valid-types': _validTypes.default + } +}; +exports.default = _default; +module.exports = exports.default; +//# sourceMappingURL=index.js.map +}); + +var index = /*@__PURE__*/getDefaultExportFromCjs(dist); + +module.exports = index; diff --git a/tools/node_modules/eslint/node_modules/eslint-plugin-markdown/index.js b/tools/node_modules/eslint/node_modules/eslint-plugin-markdown/index.js new file mode 100644 index 00000000000000..d6d8d38daa961e --- /dev/null +++ b/tools/node_modules/eslint/node_modules/eslint-plugin-markdown/index.js @@ -0,0 +1,11965 @@ +'use strict'; + +var path = require('path'); +var require$$0$1 = require('util'); + +function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } + +var path__default = /*#__PURE__*/_interopDefaultLegacy(path); +var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0$1); + +var hasOwn = Object.prototype.hasOwnProperty; +var toStr = Object.prototype.toString; +var defineProperty = Object.defineProperty; +var gOPD = Object.getOwnPropertyDescriptor; + +var isArray = function isArray(arr) { + if (typeof Array.isArray === 'function') { + return Array.isArray(arr); + } + + return toStr.call(arr) === '[object Array]'; +}; + +var isPlainObject = function isPlainObject(obj) { + if (!obj || toStr.call(obj) !== '[object Object]') { + return false; + } + + var hasOwnConstructor = hasOwn.call(obj, 'constructor'); + var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); + // Not own constructor property must be Object + if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + var key; + for (key in obj) { /**/ } + + return typeof key === 'undefined' || hasOwn.call(obj, key); +}; + +// If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target +var setProperty = function setProperty(target, options) { + if (defineProperty && options.name === '__proto__') { + defineProperty(target, options.name, { + enumerable: true, + configurable: true, + value: options.newValue, + writable: true + }); + } else { + target[options.name] = options.newValue; + } +}; + +// Return undefined instead of __proto__ if '__proto__' is not an own property +var getProperty = function getProperty(obj, name) { + if (name === '__proto__') { + if (!hasOwn.call(obj, name)) { + return void 0; + } else if (gOPD) { + // In early versions of node, obj['__proto__'] is buggy when obj has + // __proto__ as an own property. Object.getOwnPropertyDescriptor() works. + return gOPD(obj, name).value; + } + } + + return obj[name]; +}; + +var extend$1 = function extend() { + var options, name, src, copy, copyIsArray, clone; + var target = arguments[0]; + var i = 1; + var length = arguments.length; + var deep = false; + + // Handle a deep copy situation + if (typeof target === 'boolean') { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + if (target == null || (typeof target !== 'object' && typeof target !== 'function')) { + target = {}; + } + + for (; i < length; ++i) { + options = arguments[i]; + // Only deal with non-null/undefined values + if (options != null) { + // Extend the base object + for (name in options) { + src = getProperty(target, name); + copy = getProperty(options, name); + + // Prevent never-ending loop + if (target !== copy) { + // Recurse if we're merging plain objects or arrays + if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) { + if (copyIsArray) { + copyIsArray = false; + clone = src && isArray(src) ? src : []; + } else { + clone = src && isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + setProperty(target, { name: name, newValue: extend(deep, clone, copy) }); + + // Don't bring in undefined values + } else if (typeof copy !== 'undefined') { + setProperty(target, { name: name, newValue: copy }); + } + } + } + } + } + + // Return the modified object + return target; +}; + +var bail_1 = bail; + +function bail(err) { + if (err) { + throw err + } +} + +var own$5 = {}.hasOwnProperty; + +var unistUtilStringifyPosition = stringify; + +function stringify(value) { + /* Nothing. */ + if (!value || typeof value !== 'object') { + return null + } + + /* Node. */ + if (own$5.call(value, 'position') || own$5.call(value, 'type')) { + return position(value.position) + } + + /* Position. */ + if (own$5.call(value, 'start') || own$5.call(value, 'end')) { + return position(value) + } + + /* Point. */ + if (own$5.call(value, 'line') || own$5.call(value, 'column')) { + return point(value) + } + + /* ? */ + return null +} + +function point(point) { + if (!point || typeof point !== 'object') { + point = {}; + } + + return index(point.line) + ':' + index(point.column) +} + +function position(pos) { + if (!pos || typeof pos !== 'object') { + pos = {}; + } + + return point(pos.start) + '-' + point(pos.end) +} + +function index(value) { + return value && typeof value === 'number' ? value : 1 +} + +var vfileMessage = VMessage; + +// Inherit from `Error#`. +function VMessagePrototype() {} +VMessagePrototype.prototype = Error.prototype; +VMessage.prototype = new VMessagePrototype(); + +// Message properties. +var proto$3 = VMessage.prototype; + +proto$3.file = ''; +proto$3.name = ''; +proto$3.reason = ''; +proto$3.message = ''; +proto$3.stack = ''; +proto$3.fatal = null; +proto$3.column = null; +proto$3.line = null; + +// Construct a new VMessage. +// +// Note: We cannot invoke `Error` on the created context, as that adds readonly +// `line` and `column` attributes on Safari 9, thus throwing and failing the +// data. +function VMessage(reason, position, origin) { + var parts; + var range; + var location; + + if (typeof position === 'string') { + origin = position; + position = null; + } + + parts = parseOrigin(origin); + range = unistUtilStringifyPosition(position) || '1:1'; + + location = { + start: {line: null, column: null}, + end: {line: null, column: null} + }; + + // Node. + if (position && position.position) { + position = position.position; + } + + if (position) { + // Position. + if (position.start) { + location = position; + position = position.start; + } else { + // Point. + location.start = position; + } + } + + if (reason.stack) { + this.stack = reason.stack; + reason = reason.message; + } + + this.message = reason; + this.name = range; + this.reason = reason; + this.line = position ? position.line : null; + this.column = position ? position.column : null; + this.location = location; + this.source = parts[0]; + this.ruleId = parts[1]; +} + +function parseOrigin(origin) { + var result = [null, null]; + var index; + + if (typeof origin === 'string') { + index = origin.indexOf(':'); + + if (index === -1) { + result[1] = origin; + } else { + result[0] = origin.slice(0, index); + result[1] = origin.slice(index + 1); + } + } + + return result +} + +function replaceExt(npath, ext) { + if (typeof npath !== 'string') { + return npath; + } + + if (npath.length === 0) { + return npath; + } + + var nFileName = path__default['default'].basename(npath, path__default['default'].extname(npath)) + ext; + return path__default['default'].join(path__default['default'].dirname(npath), nFileName); +} + +var replaceExt_1 = replaceExt; + +/*! + * Determine if an object is a Buffer + * + * @author Feross Aboukhadijeh + * @license MIT + */ +// The _isBuffer check is for Safari 5-7 support, because it's missing +// Object.prototype.constructor. Remove this eventually +var isBuffer_1 = function (obj) { + return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer) +}; + +function isBuffer (obj) { + return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) +} + +// For Node v0.10 support. Remove this eventually. +function isSlowBuffer (obj) { + return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0)) +} + +var core = VFile; + +var own$4 = {}.hasOwnProperty; +var proto$2 = VFile.prototype; + +proto$2.toString = toString$2; + +/* Order of setting (least specific to most), we need this because + * otherwise `{stem: 'a', path: '~/b.js'}` would throw, as a path + * is needed before a stem can be set. */ +var order$1 = [ + 'history', + 'path', + 'basename', + 'stem', + 'extname', + 'dirname' +]; + +/* Construct a new file. */ +function VFile(options) { + var prop; + var index; + var length; + + if (!options) { + options = {}; + } else if (typeof options === 'string' || isBuffer_1(options)) { + options = {contents: options}; + } else if ('message' in options && 'messages' in options) { + return options; + } + + if (!(this instanceof VFile)) { + return new VFile(options); + } + + this.data = {}; + this.messages = []; + this.history = []; + this.cwd = process.cwd(); + + /* Set path related properties in the correct order. */ + index = -1; + length = order$1.length; + + while (++index < length) { + prop = order$1[index]; + + if (own$4.call(options, prop)) { + this[prop] = options[prop]; + } + } + + /* Set non-path related properties. */ + for (prop in options) { + if (order$1.indexOf(prop) === -1) { + this[prop] = options[prop]; + } + } +} + +/* Access full path (`~/index.min.js`). */ +Object.defineProperty(proto$2, 'path', { + get: function () { + return this.history[this.history.length - 1]; + }, + set: function (path) { + assertNonEmpty(path, 'path'); + + if (path !== this.path) { + this.history.push(path); + } + } +}); + +/* Access parent path (`~`). */ +Object.defineProperty(proto$2, 'dirname', { + get: function () { + return typeof this.path === 'string' ? path__default['default'].dirname(this.path) : undefined; + }, + set: function (dirname) { + assertPath(this.path, 'dirname'); + this.path = path__default['default'].join(dirname || '', this.basename); + } +}); + +/* Access basename (`index.min.js`). */ +Object.defineProperty(proto$2, 'basename', { + get: function () { + return typeof this.path === 'string' ? path__default['default'].basename(this.path) : undefined; + }, + set: function (basename) { + assertNonEmpty(basename, 'basename'); + assertPart(basename, 'basename'); + this.path = path__default['default'].join(this.dirname || '', basename); + } +}); + +/* Access extname (`.js`). */ +Object.defineProperty(proto$2, 'extname', { + get: function () { + return typeof this.path === 'string' ? path__default['default'].extname(this.path) : undefined; + }, + set: function (extname) { + var ext = extname || ''; + + assertPart(ext, 'extname'); + assertPath(this.path, 'extname'); + + if (ext) { + if (ext.charAt(0) !== '.') { + throw new Error('`extname` must start with `.`'); + } + + if (ext.indexOf('.', 1) !== -1) { + throw new Error('`extname` cannot contain multiple dots'); + } + } + + this.path = replaceExt_1(this.path, ext); + } +}); + +/* Access stem (`index.min`). */ +Object.defineProperty(proto$2, 'stem', { + get: function () { + return typeof this.path === 'string' ? path__default['default'].basename(this.path, this.extname) : undefined; + }, + set: function (stem) { + assertNonEmpty(stem, 'stem'); + assertPart(stem, 'stem'); + this.path = path__default['default'].join(this.dirname || '', stem + (this.extname || '')); + } +}); + +/* Get the value of the file. */ +function toString$2(encoding) { + var value = this.contents || ''; + return isBuffer_1(value) ? value.toString(encoding) : String(value); +} + +/* Assert that `part` is not a path (i.e., does + * not contain `path.sep`). */ +function assertPart(part, name) { + if (part.indexOf(path__default['default'].sep) !== -1) { + throw new Error('`' + name + '` cannot be a path: did not expect `' + path__default['default'].sep + '`'); + } +} + +/* Assert that `part` is not empty. */ +function assertNonEmpty(part, name) { + if (!part) { + throw new Error('`' + name + '` cannot be empty'); + } +} + +/* Assert `path` exists. */ +function assertPath(path, name) { + if (!path) { + throw new Error('Setting `' + name + '` requires `path` to be set too'); + } +} + +var vfile = core; + +var proto$1 = core.prototype; + +proto$1.message = message; +proto$1.info = info; +proto$1.fail = fail; + +/* Slight backwards compatibility. Remove in the future. */ +proto$1.warn = message; + +/* Create a message with `reason` at `position`. + * When an error is passed in as `reason`, copies the stack. */ +function message(reason, position, origin) { + var filePath = this.path; + var message = new vfileMessage(reason, position, origin); + + if (filePath) { + message.name = filePath + ':' + message.name; + message.file = filePath; + } + + message.fatal = false; + + this.messages.push(message); + + return message; +} + +/* Fail. Creates a vmessage, associates it with the file, + * and throws it. */ +function fail() { + var message = this.message.apply(this, arguments); + + message.fatal = true; + + throw message; +} + +/* Info. Creates a vmessage, associates it with the file, + * and marks the fatality as null. */ +function info() { + var message = this.message.apply(this, arguments); + + message.fatal = null; + + return message; +} + +var slice$2 = [].slice; + +var wrap_1 = wrap; + +// Wrap `fn`. +// Can be sync or async; return a promise, receive a completion handler, return +// new values and errors. +function wrap(fn, callback) { + var invoked; + + return wrapped + + function wrapped() { + var params = slice$2.call(arguments, 0); + var callback = fn.length > params.length; + var result; + + if (callback) { + params.push(done); + } + + try { + result = fn.apply(null, params); + } catch (error) { + // Well, this is quite the pickle. + // `fn` received a callback and invoked it (thus continuing the pipeline), + // but later also threw an error. + // We’re not about to restart the pipeline again, so the only thing left + // to do is to throw the thing instead. + if (callback && invoked) { + throw error + } + + return done(error) + } + + if (!callback) { + if (result && typeof result.then === 'function') { + result.then(then, done); + } else if (result instanceof Error) { + done(result); + } else { + then(result); + } + } + } + + // Invoke `next`, only once. + function done() { + if (!invoked) { + invoked = true; + + callback.apply(null, arguments); + } + } + + // Invoke `done` with one value. + // Tracks if an error is passed, too. + function then(value) { + done(null, value); + } +} + +var trough_1 = trough; + +trough.wrap = wrap_1; + +var slice$1 = [].slice; + +// Create new middleware. +function trough() { + var fns = []; + var middleware = {}; + + middleware.run = run; + middleware.use = use; + + return middleware + + // Run `fns`. Last argument must be a completion handler. + function run() { + var index = -1; + var input = slice$1.call(arguments, 0, -1); + var done = arguments[arguments.length - 1]; + + if (typeof done !== 'function') { + throw new Error('Expected function as last argument, not ' + done) + } + + next.apply(null, [null].concat(input)); + + // Run the next `fn`, if any. + function next(err) { + var fn = fns[++index]; + var params = slice$1.call(arguments, 0); + var values = params.slice(1); + var length = input.length; + var pos = -1; + + if (err) { + done(err); + return + } + + // Copy non-nully input into values. + while (++pos < length) { + if (values[pos] === null || values[pos] === undefined) { + values[pos] = input[pos]; + } + } + + input = values; + + // Next or done. + if (fn) { + wrap_1(fn, next).apply(null, input); + } else { + done.apply(null, [null].concat(input)); + } + } + } + + // Add `fn` to the list. + function use(fn) { + if (typeof fn !== 'function') { + throw new Error('Expected `fn` to be a function, not ' + fn) + } + + fns.push(fn); + + return middleware + } +} + +var toString$1 = Object.prototype.toString; + +var xIsString = isString; + +function isString(obj) { + return toString$1.call(obj) === "[object String]" +} + +var toString = Object.prototype.toString; + +var isPlainObj = function (x) { + var prototype; + return toString.call(x) === '[object Object]' && (prototype = Object.getPrototypeOf(x), prototype === null || prototype === Object.getPrototypeOf({})); +}; + +/* Dependencies. */ + + + + + + + +/* Expose a frozen processor. */ +var unified_1 = unified().freeze(); + +var slice = [].slice; +var own$3 = {}.hasOwnProperty; + +/* Process pipeline. */ +var pipeline = trough_1() + .use(pipelineParse) + .use(pipelineRun) + .use(pipelineStringify); + +function pipelineParse(p, ctx) { + ctx.tree = p.parse(ctx.file); +} + +function pipelineRun(p, ctx, next) { + p.run(ctx.tree, ctx.file, done); + + function done(err, tree, file) { + if (err) { + next(err); + } else { + ctx.tree = tree; + ctx.file = file; + next(); + } + } +} + +function pipelineStringify(p, ctx) { + ctx.file.contents = p.stringify(ctx.tree, ctx.file); +} + +/* Function to create the first processor. */ +function unified() { + var attachers = []; + var transformers = trough_1(); + var namespace = {}; + var frozen = false; + var freezeIndex = -1; + + /* Data management. */ + processor.data = data; + + /* Lock. */ + processor.freeze = freeze; + + /* Plug-ins. */ + processor.attachers = attachers; + processor.use = use; + + /* API. */ + processor.parse = parse; + processor.stringify = stringify; + processor.run = run; + processor.runSync = runSync; + processor.process = process; + processor.processSync = processSync; + + /* Expose. */ + return processor + + /* Create a new processor based on the processor + * in the current scope. */ + function processor() { + var destination = unified(); + var length = attachers.length; + var index = -1; + + while (++index < length) { + destination.use.apply(null, attachers[index]); + } + + destination.data(extend$1(true, {}, namespace)); + + return destination + } + + /* Freeze: used to signal a processor that has finished + * configuration. + * + * For example, take unified itself. It’s frozen. + * Plug-ins should not be added to it. Rather, it should + * be extended, by invoking it, before modifying it. + * + * In essence, always invoke this when exporting a + * processor. */ + function freeze() { + var values; + var plugin; + var options; + var transformer; + + if (frozen) { + return processor + } + + while (++freezeIndex < attachers.length) { + values = attachers[freezeIndex]; + plugin = values[0]; + options = values[1]; + transformer = null; + + if (options === false) { + continue + } + + if (options === true) { + values[1] = undefined; + } + + transformer = plugin.apply(processor, values.slice(1)); + + if (typeof transformer === 'function') { + transformers.use(transformer); + } + } + + frozen = true; + freezeIndex = Infinity; + + return processor + } + + /* Data management. + * Getter / setter for processor-specific informtion. */ + function data(key, value) { + if (xIsString(key)) { + /* Set `key`. */ + if (arguments.length === 2) { + assertUnfrozen('data', frozen); + + namespace[key] = value; + + return processor + } + + /* Get `key`. */ + return (own$3.call(namespace, key) && namespace[key]) || null + } + + /* Set space. */ + if (key) { + assertUnfrozen('data', frozen); + namespace = key; + return processor + } + + /* Get space. */ + return namespace + } + + /* Plug-in management. + * + * Pass it: + * * an attacher and options, + * * a preset, + * * a list of presets, attachers, and arguments (list + * of attachers and options). */ + function use(value) { + var settings; + + assertUnfrozen('use', frozen); + + if (value === null || value === undefined) ; else if (typeof value === 'function') { + addPlugin.apply(null, arguments); + } else if (typeof value === 'object') { + if ('length' in value) { + addList(value); + } else { + addPreset(value); + } + } else { + throw new Error('Expected usable value, not `' + value + '`') + } + + if (settings) { + namespace.settings = extend$1(namespace.settings || {}, settings); + } + + return processor + + function addPreset(result) { + addList(result.plugins); + + if (result.settings) { + settings = extend$1(settings || {}, result.settings); + } + } + + function add(value) { + if (typeof value === 'function') { + addPlugin(value); + } else if (typeof value === 'object') { + if ('length' in value) { + addPlugin.apply(null, value); + } else { + addPreset(value); + } + } else { + throw new Error('Expected usable value, not `' + value + '`') + } + } + + function addList(plugins) { + var length; + var index; + + if (plugins === null || plugins === undefined) ; else if (typeof plugins === 'object' && 'length' in plugins) { + length = plugins.length; + index = -1; + + while (++index < length) { + add(plugins[index]); + } + } else { + throw new Error('Expected a list of plugins, not `' + plugins + '`') + } + } + + function addPlugin(plugin, value) { + var entry = find(plugin); + + if (entry) { + if (isPlainObj(entry[1]) && isPlainObj(value)) { + value = extend$1(entry[1], value); + } + + entry[1] = value; + } else { + attachers.push(slice.call(arguments)); + } + } + } + + function find(plugin) { + var length = attachers.length; + var index = -1; + var entry; + + while (++index < length) { + entry = attachers[index]; + + if (entry[0] === plugin) { + return entry + } + } + } + + /* Parse a file (in string or VFile representation) + * into a Unist node using the `Parser` on the + * processor. */ + function parse(doc) { + var file = vfile(doc); + var Parser; + + freeze(); + Parser = processor.Parser; + assertParser('parse', Parser); + + if (newable(Parser)) { + return new Parser(String(file), file).parse() + } + + return Parser(String(file), file) // eslint-disable-line new-cap + } + + /* Run transforms on a Unist node representation of a file + * (in string or VFile representation), async. */ + function run(node, file, cb) { + assertNode(node); + freeze(); + + if (!cb && typeof file === 'function') { + cb = file; + file = null; + } + + if (!cb) { + return new Promise(executor) + } + + executor(null, cb); + + function executor(resolve, reject) { + transformers.run(node, vfile(file), done); + + function done(err, tree, file) { + tree = tree || node; + if (err) { + reject(err); + } else if (resolve) { + resolve(tree); + } else { + cb(null, tree, file); + } + } + } + } + + /* Run transforms on a Unist node representation of a file + * (in string or VFile representation), sync. */ + function runSync(node, file) { + var complete = false; + var result; + + run(node, file, done); + + assertDone('runSync', 'run', complete); + + return result + + function done(err, tree) { + complete = true; + bail_1(err); + result = tree; + } + } + + /* Stringify a Unist node representation of a file + * (in string or VFile representation) into a string + * using the `Compiler` on the processor. */ + function stringify(node, doc) { + var file = vfile(doc); + var Compiler; + + freeze(); + Compiler = processor.Compiler; + assertCompiler('stringify', Compiler); + assertNode(node); + + if (newable(Compiler)) { + return new Compiler(node, file).compile() + } + + return Compiler(node, file) // eslint-disable-line new-cap + } + + /* Parse a file (in string or VFile representation) + * into a Unist node using the `Parser` on the processor, + * then run transforms on that node, and compile the + * resulting node using the `Compiler` on the processor, + * and store that result on the VFile. */ + function process(doc, cb) { + freeze(); + assertParser('process', processor.Parser); + assertCompiler('process', processor.Compiler); + + if (!cb) { + return new Promise(executor) + } + + executor(null, cb); + + function executor(resolve, reject) { + var file = vfile(doc); + + pipeline.run(processor, {file: file}, done); + + function done(err) { + if (err) { + reject(err); + } else if (resolve) { + resolve(file); + } else { + cb(null, file); + } + } + } + } + + /* Process the given document (in string or VFile + * representation), sync. */ + function processSync(doc) { + var complete = false; + var file; + + freeze(); + assertParser('processSync', processor.Parser); + assertCompiler('processSync', processor.Compiler); + file = vfile(doc); + + process(file, done); + + assertDone('processSync', 'process', complete); + + return file + + function done(err) { + complete = true; + bail_1(err); + } + } +} + +/* Check if `func` is a constructor. */ +function newable(value) { + return typeof value === 'function' && keys$1(value.prototype) +} + +/* Check if `value` is an object with keys. */ +function keys$1(value) { + var key; + for (key in value) { + return true + } + return false +} + +/* Assert a parser is available. */ +function assertParser(name, Parser) { + if (typeof Parser !== 'function') { + throw new Error('Cannot `' + name + '` without `Parser`') + } +} + +/* Assert a compiler is available. */ +function assertCompiler(name, Compiler) { + if (typeof Compiler !== 'function') { + throw new Error('Cannot `' + name + '` without `Compiler`') + } +} + +/* Assert the processor is not frozen. */ +function assertUnfrozen(name, frozen) { + if (frozen) { + throw new Error( + [ + 'Cannot invoke `' + name + '` on a frozen processor.\nCreate a new ', + 'processor first, by invoking it: use `processor()` instead of ', + '`processor`.' + ].join('') + ) + } +} + +/* Assert `node` is a Unist node. */ +function assertNode(node) { + if (!node || !xIsString(node.type)) { + throw new Error('Expected node, got `' + node + '`') + } +} + +/* Assert that `complete` is `true`. */ +function assertDone(name, asyncName, complete) { + if (!complete) { + throw new Error( + '`' + name + '` finished async. Use `' + asyncName + '` instead' + ) + } +} + +var immutable = extend; + +var hasOwnProperty = Object.prototype.hasOwnProperty; + +function extend() { + var target = {}; + + for (var i = 0; i < arguments.length; i++) { + var source = arguments[i]; + + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + target[key] = source[key]; + } + } + } + + return target +} + +function createCommonjsModule(fn) { + var module = { exports: {} }; + return fn(module, module.exports), module.exports; +} + +var inherits_browser = createCommonjsModule(function (module) { +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + if (superCtor) { + ctor.super_ = superCtor; + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + } + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + if (superCtor) { + ctor.super_ = superCtor; + var TempCtor = function () {}; + TempCtor.prototype = superCtor.prototype; + ctor.prototype = new TempCtor(); + ctor.prototype.constructor = ctor; + } + }; +} +}); + +var inherits = createCommonjsModule(function (module) { +try { + var util = require$$0__default['default']; + /* istanbul ignore next */ + if (typeof util.inherits !== 'function') throw ''; + module.exports = util.inherits; +} catch (e) { + /* istanbul ignore next */ + module.exports = inherits_browser; +} +}); + +var unherit_1 = unherit; + +// Create a custom constructor which can be modified without affecting the +// original class. +function unherit(Super) { + var result; + var key; + var value; + + inherits(Of, Super); + inherits(From, Of); + + // Clone values. + result = Of.prototype; + + for (key in result) { + value = result[key]; + + if (value && typeof value === 'object') { + result[key] = 'concat' in value ? value.concat() : immutable(value); + } + } + + return Of + + // Constructor accepting a single argument, which itself is an `arguments` + // object. + function From(parameters) { + return Super.apply(this, parameters) + } + + // Constructor accepting variadic arguments. + function Of() { + if (!(this instanceof Of)) { + return new From(arguments) + } + + return Super.apply(this, arguments) + } +} + +var stateToggle = factory$4; + +// Construct a state `toggler`: a function which inverses `property` in context +// based on its current value. +// The by `toggler` returned function restores that value. +function factory$4(key, state, ctx) { + return enter + + function enter() { + var context = ctx || this; + var current = context[key]; + + context[key] = !state; + + return exit + + function exit() { + context[key] = current; + } + } +} + +var vfileLocation = factory$3; + +function factory$3(file) { + var contents = indices(String(file)); + + return { + toPosition: offsetToPositionFactory(contents), + toOffset: positionToOffsetFactory(contents) + } +} + +// Factory to get the line and column-based `position` for `offset` in the bound +// indices. +function offsetToPositionFactory(indices) { + return offsetToPosition + + // Get the line and column-based `position` for `offset` in the bound indices. + function offsetToPosition(offset) { + var index = -1; + var length = indices.length; + + if (offset < 0) { + return {} + } + + while (++index < length) { + if (indices[index] > offset) { + return { + line: index + 1, + column: offset - (indices[index - 1] || 0) + 1, + offset: offset + } + } + } + + return {} + } +} + +// Factory to get the `offset` for a line and column-based `position` in the +// bound indices. +function positionToOffsetFactory(indices) { + return positionToOffset + + // Get the `offset` for a line and column-based `position` in the bound + // indices. + function positionToOffset(position) { + var line = position && position.line; + var column = position && position.column; + + if (!isNaN(line) && !isNaN(column) && line - 1 in indices) { + return (indices[line - 2] || 0) + column - 1 || 0 + } + + return -1 + } +} + +// Get indices of line-breaks in `value`. +function indices(value) { + var result = []; + var index = value.indexOf('\n'); + + while (index !== -1) { + result.push(index + 1); + index = value.indexOf('\n', index + 1); + } + + result.push(value.length + 1); + + return result +} + +var _unescape = factory$2; + +/* Factory to de-escape a value, based on a list at `key` + * in `ctx`. */ +function factory$2(ctx, key) { + return unescape; + + /* De-escape a string using the expression at `key` + * in `ctx`. */ + function unescape(value) { + var prev = 0; + var index = value.indexOf('\\'); + var escape = ctx[key]; + var queue = []; + var character; + + while (index !== -1) { + queue.push(value.slice(prev, index)); + prev = index + 1; + character = value.charAt(prev); + + /* If the following character is not a valid escape, + * add the slash. */ + if (!character || escape.indexOf(character) === -1) { + queue.push('\\'); + } + + index = value.indexOf('\\', prev); + } + + queue.push(value.slice(prev)); + + return queue.join(''); + } +} + +var AElig$1 = "Æ"; +var AMP$1 = "&"; +var Aacute$1 = "Á"; +var Acirc$1 = "Â"; +var Agrave$1 = "À"; +var Aring$1 = "Å"; +var Atilde$1 = "Ã"; +var Auml$1 = "Ä"; +var COPY$1 = "©"; +var Ccedil$1 = "Ç"; +var ETH$1 = "Ð"; +var Eacute$1 = "É"; +var Ecirc$1 = "Ê"; +var Egrave$1 = "È"; +var Euml$1 = "Ë"; +var GT$1 = ">"; +var Iacute$1 = "Í"; +var Icirc$1 = "Î"; +var Igrave$1 = "Ì"; +var Iuml$1 = "Ï"; +var LT$1 = "<"; +var Ntilde$1 = "Ñ"; +var Oacute$1 = "Ó"; +var Ocirc$1 = "Ô"; +var Ograve$1 = "Ò"; +var Oslash$1 = "Ø"; +var Otilde$1 = "Õ"; +var Ouml$1 = "Ö"; +var QUOT$1 = "\""; +var REG$1 = "®"; +var THORN$1 = "Þ"; +var Uacute$1 = "Ú"; +var Ucirc$1 = "Û"; +var Ugrave$1 = "Ù"; +var Uuml$1 = "Ü"; +var Yacute$1 = "Ý"; +var aacute$1 = "á"; +var acirc$1 = "â"; +var acute$1 = "´"; +var aelig$1 = "æ"; +var agrave$1 = "à"; +var amp$1 = "&"; +var aring$1 = "å"; +var atilde$1 = "ã"; +var auml$1 = "ä"; +var brvbar$1 = "¦"; +var ccedil$1 = "ç"; +var cedil$1 = "¸"; +var cent$1 = "¢"; +var copy$1 = "©"; +var curren$1 = "¤"; +var deg$1 = "°"; +var divide$1 = "÷"; +var eacute$1 = "é"; +var ecirc$1 = "ê"; +var egrave$1 = "è"; +var eth$1 = "ð"; +var euml$1 = "ë"; +var frac12$1 = "½"; +var frac14$1 = "¼"; +var frac34$1 = "¾"; +var gt$1 = ">"; +var iacute$1 = "í"; +var icirc$1 = "î"; +var iexcl$1 = "¡"; +var igrave$1 = "ì"; +var iquest$1 = "¿"; +var iuml$1 = "ï"; +var laquo$1 = "«"; +var lt$1 = "<"; +var macr$1 = "¯"; +var micro$1 = "µ"; +var middot$1 = "·"; +var nbsp$1 = " "; +var not$1 = "¬"; +var ntilde$1 = "ñ"; +var oacute$1 = "ó"; +var ocirc$1 = "ô"; +var ograve$1 = "ò"; +var ordf$1 = "ª"; +var ordm$1 = "º"; +var oslash$1 = "ø"; +var otilde$1 = "õ"; +var ouml$1 = "ö"; +var para$1 = "¶"; +var plusmn$1 = "±"; +var pound$1 = "£"; +var quot$1 = "\""; +var raquo$1 = "»"; +var reg$1 = "®"; +var sect$1 = "§"; +var shy$1 = "­"; +var sup1$1 = "¹"; +var sup2$1 = "²"; +var sup3$1 = "³"; +var szlig$1 = "ß"; +var thorn$1 = "þ"; +var times$1 = "×"; +var uacute$1 = "ú"; +var ucirc$1 = "û"; +var ugrave$1 = "ù"; +var uml$1 = "¨"; +var uuml$1 = "ü"; +var yacute$1 = "ý"; +var yen$1 = "¥"; +var yuml$1 = "ÿ"; +var legacy = { + AElig: AElig$1, + AMP: AMP$1, + Aacute: Aacute$1, + Acirc: Acirc$1, + Agrave: Agrave$1, + Aring: Aring$1, + Atilde: Atilde$1, + Auml: Auml$1, + COPY: COPY$1, + Ccedil: Ccedil$1, + ETH: ETH$1, + Eacute: Eacute$1, + Ecirc: Ecirc$1, + Egrave: Egrave$1, + Euml: Euml$1, + GT: GT$1, + Iacute: Iacute$1, + Icirc: Icirc$1, + Igrave: Igrave$1, + Iuml: Iuml$1, + LT: LT$1, + Ntilde: Ntilde$1, + Oacute: Oacute$1, + Ocirc: Ocirc$1, + Ograve: Ograve$1, + Oslash: Oslash$1, + Otilde: Otilde$1, + Ouml: Ouml$1, + QUOT: QUOT$1, + REG: REG$1, + THORN: THORN$1, + Uacute: Uacute$1, + Ucirc: Ucirc$1, + Ugrave: Ugrave$1, + Uuml: Uuml$1, + Yacute: Yacute$1, + aacute: aacute$1, + acirc: acirc$1, + acute: acute$1, + aelig: aelig$1, + agrave: agrave$1, + amp: amp$1, + aring: aring$1, + atilde: atilde$1, + auml: auml$1, + brvbar: brvbar$1, + ccedil: ccedil$1, + cedil: cedil$1, + cent: cent$1, + copy: copy$1, + curren: curren$1, + deg: deg$1, + divide: divide$1, + eacute: eacute$1, + ecirc: ecirc$1, + egrave: egrave$1, + eth: eth$1, + euml: euml$1, + frac12: frac12$1, + frac14: frac14$1, + frac34: frac34$1, + gt: gt$1, + iacute: iacute$1, + icirc: icirc$1, + iexcl: iexcl$1, + igrave: igrave$1, + iquest: iquest$1, + iuml: iuml$1, + laquo: laquo$1, + lt: lt$1, + macr: macr$1, + micro: micro$1, + middot: middot$1, + nbsp: nbsp$1, + not: not$1, + ntilde: ntilde$1, + oacute: oacute$1, + ocirc: ocirc$1, + ograve: ograve$1, + ordf: ordf$1, + ordm: ordm$1, + oslash: oslash$1, + otilde: otilde$1, + ouml: ouml$1, + para: para$1, + plusmn: plusmn$1, + pound: pound$1, + quot: quot$1, + raquo: raquo$1, + reg: reg$1, + sect: sect$1, + shy: shy$1, + sup1: sup1$1, + sup2: sup2$1, + sup3: sup3$1, + szlig: szlig$1, + thorn: thorn$1, + times: times$1, + uacute: uacute$1, + ucirc: ucirc$1, + ugrave: ugrave$1, + uml: uml$1, + uuml: uuml$1, + yacute: yacute$1, + yen: yen$1, + yuml: yuml$1 +}; + +var invalid = { + "0": "�", + "128": "€", + "130": "‚", + "131": "ƒ", + "132": "„", + "133": "…", + "134": "†", + "135": "‡", + "136": "ˆ", + "137": "‰", + "138": "Š", + "139": "‹", + "140": "Œ", + "142": "Ž", + "145": "‘", + "146": "’", + "147": "“", + "148": "”", + "149": "•", + "150": "–", + "151": "—", + "152": "˜", + "153": "™", + "154": "š", + "155": "›", + "156": "œ", + "158": "ž", + "159": "Ÿ" +}; + +var isDecimal = decimal; + +// Check if the given character code, or the character code at the first +// character, is decimal. +function decimal(character) { + var code = typeof character === 'string' ? character.charCodeAt(0) : character; + + return code >= 48 && code <= 57 /* 0-9 */ +} + +var isHexadecimal = hexadecimal; + +// Check if the given character code, or the character code at the first +// character, is hexadecimal. +function hexadecimal(character) { + var code = typeof character === 'string' ? character.charCodeAt(0) : character; + + return ( + (code >= 97 /* a */ && code <= 102) /* z */ || + (code >= 65 /* A */ && code <= 70) /* Z */ || + (code >= 48 /* A */ && code <= 57) /* Z */ + ) +} + +var isAlphabetical = alphabetical; + +// Check if the given character code, or the character code at the first +// character, is alphabetical. +function alphabetical(character) { + var code = typeof character === 'string' ? character.charCodeAt(0) : character; + + return ( + (code >= 97 && code <= 122) /* a-z */ || + (code >= 65 && code <= 90) /* A-Z */ + ) +} + +var isAlphanumerical = alphanumerical; + +// Check if the given character code, or the character code at the first +// character, is alphanumerical. +function alphanumerical(character) { + return isAlphabetical(character) || isDecimal(character) +} + +var AEli = "Æ"; +var AElig = "Æ"; +var AM = "&"; +var AMP = "&"; +var Aacut = "Á"; +var Aacute = "Á"; +var Abreve = "Ă"; +var Acir = "Â"; +var Acirc = "Â"; +var Acy = "А"; +var Afr = "𝔄"; +var Agrav = "À"; +var Agrave = "À"; +var Alpha = "Α"; +var Amacr = "Ā"; +var And = "⩓"; +var Aogon = "Ą"; +var Aopf = "𝔸"; +var ApplyFunction = "⁡"; +var Arin = "Å"; +var Aring = "Å"; +var Ascr = "𝒜"; +var Assign = "≔"; +var Atild = "Ã"; +var Atilde = "Ã"; +var Aum = "Ä"; +var Auml = "Ä"; +var Backslash = "∖"; +var Barv = "⫧"; +var Barwed = "⌆"; +var Bcy = "Б"; +var Because = "∵"; +var Bernoullis = "ℬ"; +var Beta = "Β"; +var Bfr = "𝔅"; +var Bopf = "𝔹"; +var Breve = "˘"; +var Bscr = "ℬ"; +var Bumpeq = "≎"; +var CHcy = "Ч"; +var COP = "©"; +var COPY = "©"; +var Cacute = "Ć"; +var Cap = "⋒"; +var CapitalDifferentialD = "ⅅ"; +var Cayleys = "ℭ"; +var Ccaron = "Č"; +var Ccedi = "Ç"; +var Ccedil = "Ç"; +var Ccirc = "Ĉ"; +var Cconint = "∰"; +var Cdot = "Ċ"; +var Cedilla = "¸"; +var CenterDot = "·"; +var Cfr = "ℭ"; +var Chi = "Χ"; +var CircleDot = "⊙"; +var CircleMinus = "⊖"; +var CirclePlus = "⊕"; +var CircleTimes = "⊗"; +var ClockwiseContourIntegral = "∲"; +var CloseCurlyDoubleQuote = "”"; +var CloseCurlyQuote = "’"; +var Colon = "∷"; +var Colone = "⩴"; +var Congruent = "≡"; +var Conint = "∯"; +var ContourIntegral = "∮"; +var Copf = "ℂ"; +var Coproduct = "∐"; +var CounterClockwiseContourIntegral = "∳"; +var Cross = "⨯"; +var Cscr = "𝒞"; +var Cup = "⋓"; +var CupCap = "≍"; +var DD = "ⅅ"; +var DDotrahd = "⤑"; +var DJcy = "Ђ"; +var DScy = "Ѕ"; +var DZcy = "Џ"; +var Dagger = "‡"; +var Darr = "↡"; +var Dashv = "⫤"; +var Dcaron = "Ď"; +var Dcy = "Д"; +var Del = "∇"; +var Delta = "Δ"; +var Dfr = "𝔇"; +var DiacriticalAcute = "´"; +var DiacriticalDot = "˙"; +var DiacriticalDoubleAcute = "˝"; +var DiacriticalGrave = "`"; +var DiacriticalTilde = "˜"; +var Diamond = "⋄"; +var DifferentialD = "ⅆ"; +var Dopf = "𝔻"; +var Dot = "¨"; +var DotDot = "⃜"; +var DotEqual = "≐"; +var DoubleContourIntegral = "∯"; +var DoubleDot = "¨"; +var DoubleDownArrow = "⇓"; +var DoubleLeftArrow = "⇐"; +var DoubleLeftRightArrow = "⇔"; +var DoubleLeftTee = "⫤"; +var DoubleLongLeftArrow = "⟸"; +var DoubleLongLeftRightArrow = "⟺"; +var DoubleLongRightArrow = "⟹"; +var DoubleRightArrow = "⇒"; +var DoubleRightTee = "⊨"; +var DoubleUpArrow = "⇑"; +var DoubleUpDownArrow = "⇕"; +var DoubleVerticalBar = "∥"; +var DownArrow = "↓"; +var DownArrowBar = "⤓"; +var DownArrowUpArrow = "⇵"; +var DownBreve = "̑"; +var DownLeftRightVector = "⥐"; +var DownLeftTeeVector = "⥞"; +var DownLeftVector = "↽"; +var DownLeftVectorBar = "⥖"; +var DownRightTeeVector = "⥟"; +var DownRightVector = "⇁"; +var DownRightVectorBar = "⥗"; +var DownTee = "⊤"; +var DownTeeArrow = "↧"; +var Downarrow = "⇓"; +var Dscr = "𝒟"; +var Dstrok = "Đ"; +var ENG = "Ŋ"; +var ET = "Ð"; +var ETH = "Ð"; +var Eacut = "É"; +var Eacute = "É"; +var Ecaron = "Ě"; +var Ecir = "Ê"; +var Ecirc = "Ê"; +var Ecy = "Э"; +var Edot = "Ė"; +var Efr = "𝔈"; +var Egrav = "È"; +var Egrave = "È"; +var Element = "∈"; +var Emacr = "Ē"; +var EmptySmallSquare = "◻"; +var EmptyVerySmallSquare = "▫"; +var Eogon = "Ę"; +var Eopf = "𝔼"; +var Epsilon = "Ε"; +var Equal = "⩵"; +var EqualTilde = "≂"; +var Equilibrium = "⇌"; +var Escr = "ℰ"; +var Esim = "⩳"; +var Eta = "Η"; +var Eum = "Ë"; +var Euml = "Ë"; +var Exists = "∃"; +var ExponentialE = "ⅇ"; +var Fcy = "Ф"; +var Ffr = "𝔉"; +var FilledSmallSquare = "◼"; +var FilledVerySmallSquare = "▪"; +var Fopf = "𝔽"; +var ForAll = "∀"; +var Fouriertrf = "ℱ"; +var Fscr = "ℱ"; +var GJcy = "Ѓ"; +var G = ">"; +var GT = ">"; +var Gamma = "Γ"; +var Gammad = "Ϝ"; +var Gbreve = "Ğ"; +var Gcedil = "Ģ"; +var Gcirc = "Ĝ"; +var Gcy = "Г"; +var Gdot = "Ġ"; +var Gfr = "𝔊"; +var Gg = "⋙"; +var Gopf = "𝔾"; +var GreaterEqual = "≥"; +var GreaterEqualLess = "⋛"; +var GreaterFullEqual = "≧"; +var GreaterGreater = "⪢"; +var GreaterLess = "≷"; +var GreaterSlantEqual = "⩾"; +var GreaterTilde = "≳"; +var Gscr = "𝒢"; +var Gt = "≫"; +var HARDcy = "Ъ"; +var Hacek = "ˇ"; +var Hat = "^"; +var Hcirc = "Ĥ"; +var Hfr = "ℌ"; +var HilbertSpace = "ℋ"; +var Hopf = "ℍ"; +var HorizontalLine = "─"; +var Hscr = "ℋ"; +var Hstrok = "Ħ"; +var HumpDownHump = "≎"; +var HumpEqual = "≏"; +var IEcy = "Е"; +var IJlig = "IJ"; +var IOcy = "Ё"; +var Iacut = "Í"; +var Iacute = "Í"; +var Icir = "Î"; +var Icirc = "Î"; +var Icy = "И"; +var Idot = "İ"; +var Ifr = "ℑ"; +var Igrav = "Ì"; +var Igrave = "Ì"; +var Im = "ℑ"; +var Imacr = "Ī"; +var ImaginaryI = "ⅈ"; +var Implies = "⇒"; +var Int = "∬"; +var Integral = "∫"; +var Intersection = "⋂"; +var InvisibleComma = "⁣"; +var InvisibleTimes = "⁢"; +var Iogon = "Į"; +var Iopf = "𝕀"; +var Iota = "Ι"; +var Iscr = "ℐ"; +var Itilde = "Ĩ"; +var Iukcy = "І"; +var Ium = "Ï"; +var Iuml = "Ï"; +var Jcirc = "Ĵ"; +var Jcy = "Й"; +var Jfr = "𝔍"; +var Jopf = "𝕁"; +var Jscr = "𝒥"; +var Jsercy = "Ј"; +var Jukcy = "Є"; +var KHcy = "Х"; +var KJcy = "Ќ"; +var Kappa = "Κ"; +var Kcedil = "Ķ"; +var Kcy = "К"; +var Kfr = "𝔎"; +var Kopf = "𝕂"; +var Kscr = "𝒦"; +var LJcy = "Љ"; +var L = "<"; +var LT = "<"; +var Lacute = "Ĺ"; +var Lambda = "Λ"; +var Lang = "⟪"; +var Laplacetrf = "ℒ"; +var Larr = "↞"; +var Lcaron = "Ľ"; +var Lcedil = "Ļ"; +var Lcy = "Л"; +var LeftAngleBracket = "⟨"; +var LeftArrow = "←"; +var LeftArrowBar = "⇤"; +var LeftArrowRightArrow = "⇆"; +var LeftCeiling = "⌈"; +var LeftDoubleBracket = "⟦"; +var LeftDownTeeVector = "⥡"; +var LeftDownVector = "⇃"; +var LeftDownVectorBar = "⥙"; +var LeftFloor = "⌊"; +var LeftRightArrow = "↔"; +var LeftRightVector = "⥎"; +var LeftTee = "⊣"; +var LeftTeeArrow = "↤"; +var LeftTeeVector = "⥚"; +var LeftTriangle = "⊲"; +var LeftTriangleBar = "⧏"; +var LeftTriangleEqual = "⊴"; +var LeftUpDownVector = "⥑"; +var LeftUpTeeVector = "⥠"; +var LeftUpVector = "↿"; +var LeftUpVectorBar = "⥘"; +var LeftVector = "↼"; +var LeftVectorBar = "⥒"; +var Leftarrow = "⇐"; +var Leftrightarrow = "⇔"; +var LessEqualGreater = "⋚"; +var LessFullEqual = "≦"; +var LessGreater = "≶"; +var LessLess = "⪡"; +var LessSlantEqual = "⩽"; +var LessTilde = "≲"; +var Lfr = "𝔏"; +var Ll = "⋘"; +var Lleftarrow = "⇚"; +var Lmidot = "Ŀ"; +var LongLeftArrow = "⟵"; +var LongLeftRightArrow = "⟷"; +var LongRightArrow = "⟶"; +var Longleftarrow = "⟸"; +var Longleftrightarrow = "⟺"; +var Longrightarrow = "⟹"; +var Lopf = "𝕃"; +var LowerLeftArrow = "↙"; +var LowerRightArrow = "↘"; +var Lscr = "ℒ"; +var Lsh = "↰"; +var Lstrok = "Ł"; +var Lt = "≪"; +var Mcy = "М"; +var MediumSpace = " "; +var Mellintrf = "ℳ"; +var Mfr = "𝔐"; +var MinusPlus = "∓"; +var Mopf = "𝕄"; +var Mscr = "ℳ"; +var Mu = "Μ"; +var NJcy = "Њ"; +var Nacute = "Ń"; +var Ncaron = "Ň"; +var Ncedil = "Ņ"; +var Ncy = "Н"; +var NegativeMediumSpace = "​"; +var NegativeThickSpace = "​"; +var NegativeThinSpace = "​"; +var NegativeVeryThinSpace = "​"; +var NestedGreaterGreater = "≫"; +var NestedLessLess = "≪"; +var NewLine = "\n"; +var Nfr = "𝔑"; +var NoBreak = "⁠"; +var NonBreakingSpace = " "; +var Nopf = "ℕ"; +var Not = "⫬"; +var NotCongruent = "≢"; +var NotCupCap = "≭"; +var NotDoubleVerticalBar = "∦"; +var NotElement = "∉"; +var NotEqual = "≠"; +var NotEqualTilde = "≂̸"; +var NotExists = "∄"; +var NotGreater = "≯"; +var NotGreaterEqual = "≱"; +var NotGreaterFullEqual = "≧̸"; +var NotGreaterGreater = "≫̸"; +var NotGreaterLess = "≹"; +var NotGreaterSlantEqual = "⩾̸"; +var NotGreaterTilde = "≵"; +var NotHumpDownHump = "≎̸"; +var NotHumpEqual = "≏̸"; +var NotLeftTriangle = "⋪"; +var NotLeftTriangleBar = "⧏̸"; +var NotLeftTriangleEqual = "⋬"; +var NotLess = "≮"; +var NotLessEqual = "≰"; +var NotLessGreater = "≸"; +var NotLessLess = "≪̸"; +var NotLessSlantEqual = "⩽̸"; +var NotLessTilde = "≴"; +var NotNestedGreaterGreater = "⪢̸"; +var NotNestedLessLess = "⪡̸"; +var NotPrecedes = "⊀"; +var NotPrecedesEqual = "⪯̸"; +var NotPrecedesSlantEqual = "⋠"; +var NotReverseElement = "∌"; +var NotRightTriangle = "⋫"; +var NotRightTriangleBar = "⧐̸"; +var NotRightTriangleEqual = "⋭"; +var NotSquareSubset = "⊏̸"; +var NotSquareSubsetEqual = "⋢"; +var NotSquareSuperset = "⊐̸"; +var NotSquareSupersetEqual = "⋣"; +var NotSubset = "⊂⃒"; +var NotSubsetEqual = "⊈"; +var NotSucceeds = "⊁"; +var NotSucceedsEqual = "⪰̸"; +var NotSucceedsSlantEqual = "⋡"; +var NotSucceedsTilde = "≿̸"; +var NotSuperset = "⊃⃒"; +var NotSupersetEqual = "⊉"; +var NotTilde = "≁"; +var NotTildeEqual = "≄"; +var NotTildeFullEqual = "≇"; +var NotTildeTilde = "≉"; +var NotVerticalBar = "∤"; +var Nscr = "𝒩"; +var Ntild = "Ñ"; +var Ntilde = "Ñ"; +var Nu = "Ν"; +var OElig = "Œ"; +var Oacut = "Ó"; +var Oacute = "Ó"; +var Ocir = "Ô"; +var Ocirc = "Ô"; +var Ocy = "О"; +var Odblac = "Ő"; +var Ofr = "𝔒"; +var Ograv = "Ò"; +var Ograve = "Ò"; +var Omacr = "Ō"; +var Omega = "Ω"; +var Omicron = "Ο"; +var Oopf = "𝕆"; +var OpenCurlyDoubleQuote = "“"; +var OpenCurlyQuote = "‘"; +var Or = "⩔"; +var Oscr = "𝒪"; +var Oslas = "Ø"; +var Oslash = "Ø"; +var Otild = "Õ"; +var Otilde = "Õ"; +var Otimes = "⨷"; +var Oum = "Ö"; +var Ouml = "Ö"; +var OverBar = "‾"; +var OverBrace = "⏞"; +var OverBracket = "⎴"; +var OverParenthesis = "⏜"; +var PartialD = "∂"; +var Pcy = "П"; +var Pfr = "𝔓"; +var Phi = "Φ"; +var Pi = "Π"; +var PlusMinus = "±"; +var Poincareplane = "ℌ"; +var Popf = "ℙ"; +var Pr = "⪻"; +var Precedes = "≺"; +var PrecedesEqual = "⪯"; +var PrecedesSlantEqual = "≼"; +var PrecedesTilde = "≾"; +var Prime = "″"; +var Product = "∏"; +var Proportion = "∷"; +var Proportional = "∝"; +var Pscr = "𝒫"; +var Psi = "Ψ"; +var QUO = "\""; +var QUOT = "\""; +var Qfr = "𝔔"; +var Qopf = "ℚ"; +var Qscr = "𝒬"; +var RBarr = "⤐"; +var RE = "®"; +var REG = "®"; +var Racute = "Ŕ"; +var Rang = "⟫"; +var Rarr = "↠"; +var Rarrtl = "⤖"; +var Rcaron = "Ř"; +var Rcedil = "Ŗ"; +var Rcy = "Р"; +var Re = "ℜ"; +var ReverseElement = "∋"; +var ReverseEquilibrium = "⇋"; +var ReverseUpEquilibrium = "⥯"; +var Rfr = "ℜ"; +var Rho = "Ρ"; +var RightAngleBracket = "⟩"; +var RightArrow = "→"; +var RightArrowBar = "⇥"; +var RightArrowLeftArrow = "⇄"; +var RightCeiling = "⌉"; +var RightDoubleBracket = "⟧"; +var RightDownTeeVector = "⥝"; +var RightDownVector = "⇂"; +var RightDownVectorBar = "⥕"; +var RightFloor = "⌋"; +var RightTee = "⊢"; +var RightTeeArrow = "↦"; +var RightTeeVector = "⥛"; +var RightTriangle = "⊳"; +var RightTriangleBar = "⧐"; +var RightTriangleEqual = "⊵"; +var RightUpDownVector = "⥏"; +var RightUpTeeVector = "⥜"; +var RightUpVector = "↾"; +var RightUpVectorBar = "⥔"; +var RightVector = "⇀"; +var RightVectorBar = "⥓"; +var Rightarrow = "⇒"; +var Ropf = "ℝ"; +var RoundImplies = "⥰"; +var Rrightarrow = "⇛"; +var Rscr = "ℛ"; +var Rsh = "↱"; +var RuleDelayed = "⧴"; +var SHCHcy = "Щ"; +var SHcy = "Ш"; +var SOFTcy = "Ь"; +var Sacute = "Ś"; +var Sc = "⪼"; +var Scaron = "Š"; +var Scedil = "Ş"; +var Scirc = "Ŝ"; +var Scy = "С"; +var Sfr = "𝔖"; +var ShortDownArrow = "↓"; +var ShortLeftArrow = "←"; +var ShortRightArrow = "→"; +var ShortUpArrow = "↑"; +var Sigma = "Σ"; +var SmallCircle = "∘"; +var Sopf = "𝕊"; +var Sqrt = "√"; +var Square = "□"; +var SquareIntersection = "⊓"; +var SquareSubset = "⊏"; +var SquareSubsetEqual = "⊑"; +var SquareSuperset = "⊐"; +var SquareSupersetEqual = "⊒"; +var SquareUnion = "⊔"; +var Sscr = "𝒮"; +var Star = "⋆"; +var Sub = "⋐"; +var Subset = "⋐"; +var SubsetEqual = "⊆"; +var Succeeds = "≻"; +var SucceedsEqual = "⪰"; +var SucceedsSlantEqual = "≽"; +var SucceedsTilde = "≿"; +var SuchThat = "∋"; +var Sum = "∑"; +var Sup = "⋑"; +var Superset = "⊃"; +var SupersetEqual = "⊇"; +var Supset = "⋑"; +var THOR = "Þ"; +var THORN = "Þ"; +var TRADE = "™"; +var TSHcy = "Ћ"; +var TScy = "Ц"; +var Tab = "\t"; +var Tau = "Τ"; +var Tcaron = "Ť"; +var Tcedil = "Ţ"; +var Tcy = "Т"; +var Tfr = "𝔗"; +var Therefore = "∴"; +var Theta = "Θ"; +var ThickSpace = "  "; +var ThinSpace = " "; +var Tilde = "∼"; +var TildeEqual = "≃"; +var TildeFullEqual = "≅"; +var TildeTilde = "≈"; +var Topf = "𝕋"; +var TripleDot = "⃛"; +var Tscr = "𝒯"; +var Tstrok = "Ŧ"; +var Uacut = "Ú"; +var Uacute = "Ú"; +var Uarr = "↟"; +var Uarrocir = "⥉"; +var Ubrcy = "Ў"; +var Ubreve = "Ŭ"; +var Ucir = "Û"; +var Ucirc = "Û"; +var Ucy = "У"; +var Udblac = "Ű"; +var Ufr = "𝔘"; +var Ugrav = "Ù"; +var Ugrave = "Ù"; +var Umacr = "Ū"; +var UnderBar = "_"; +var UnderBrace = "⏟"; +var UnderBracket = "⎵"; +var UnderParenthesis = "⏝"; +var Union = "⋃"; +var UnionPlus = "⊎"; +var Uogon = "Ų"; +var Uopf = "𝕌"; +var UpArrow = "↑"; +var UpArrowBar = "⤒"; +var UpArrowDownArrow = "⇅"; +var UpDownArrow = "↕"; +var UpEquilibrium = "⥮"; +var UpTee = "⊥"; +var UpTeeArrow = "↥"; +var Uparrow = "⇑"; +var Updownarrow = "⇕"; +var UpperLeftArrow = "↖"; +var UpperRightArrow = "↗"; +var Upsi = "ϒ"; +var Upsilon = "Υ"; +var Uring = "Ů"; +var Uscr = "𝒰"; +var Utilde = "Ũ"; +var Uum = "Ü"; +var Uuml = "Ü"; +var VDash = "⊫"; +var Vbar = "⫫"; +var Vcy = "В"; +var Vdash = "⊩"; +var Vdashl = "⫦"; +var Vee = "⋁"; +var Verbar = "‖"; +var Vert = "‖"; +var VerticalBar = "∣"; +var VerticalLine = "|"; +var VerticalSeparator = "❘"; +var VerticalTilde = "≀"; +var VeryThinSpace = " "; +var Vfr = "𝔙"; +var Vopf = "𝕍"; +var Vscr = "𝒱"; +var Vvdash = "⊪"; +var Wcirc = "Ŵ"; +var Wedge = "⋀"; +var Wfr = "𝔚"; +var Wopf = "𝕎"; +var Wscr = "𝒲"; +var Xfr = "𝔛"; +var Xi = "Ξ"; +var Xopf = "𝕏"; +var Xscr = "𝒳"; +var YAcy = "Я"; +var YIcy = "Ї"; +var YUcy = "Ю"; +var Yacut = "Ý"; +var Yacute = "Ý"; +var Ycirc = "Ŷ"; +var Ycy = "Ы"; +var Yfr = "𝔜"; +var Yopf = "𝕐"; +var Yscr = "𝒴"; +var Yuml = "Ÿ"; +var ZHcy = "Ж"; +var Zacute = "Ź"; +var Zcaron = "Ž"; +var Zcy = "З"; +var Zdot = "Ż"; +var ZeroWidthSpace = "​"; +var Zeta = "Ζ"; +var Zfr = "ℨ"; +var Zopf = "ℤ"; +var Zscr = "𝒵"; +var aacut = "á"; +var aacute = "á"; +var abreve = "ă"; +var ac = "∾"; +var acE = "∾̳"; +var acd = "∿"; +var acir = "â"; +var acirc = "â"; +var acut = "´"; +var acute = "´"; +var acy = "а"; +var aeli = "æ"; +var aelig = "æ"; +var af = "⁡"; +var afr = "𝔞"; +var agrav = "à"; +var agrave = "à"; +var alefsym = "ℵ"; +var aleph = "ℵ"; +var alpha = "α"; +var amacr = "ā"; +var amalg = "⨿"; +var am = "&"; +var amp = "&"; +var and = "∧"; +var andand = "⩕"; +var andd = "⩜"; +var andslope = "⩘"; +var andv = "⩚"; +var ang = "∠"; +var ange = "⦤"; +var angle = "∠"; +var angmsd = "∡"; +var angmsdaa = "⦨"; +var angmsdab = "⦩"; +var angmsdac = "⦪"; +var angmsdad = "⦫"; +var angmsdae = "⦬"; +var angmsdaf = "⦭"; +var angmsdag = "⦮"; +var angmsdah = "⦯"; +var angrt = "∟"; +var angrtvb = "⊾"; +var angrtvbd = "⦝"; +var angsph = "∢"; +var angst = "Å"; +var angzarr = "⍼"; +var aogon = "ą"; +var aopf = "𝕒"; +var ap = "≈"; +var apE = "⩰"; +var apacir = "⩯"; +var ape = "≊"; +var apid = "≋"; +var apos = "'"; +var approx = "≈"; +var approxeq = "≊"; +var arin = "å"; +var aring = "å"; +var ascr = "𝒶"; +var ast = "*"; +var asymp = "≈"; +var asympeq = "≍"; +var atild = "ã"; +var atilde = "ã"; +var aum = "ä"; +var auml = "ä"; +var awconint = "∳"; +var awint = "⨑"; +var bNot = "⫭"; +var backcong = "≌"; +var backepsilon = "϶"; +var backprime = "‵"; +var backsim = "∽"; +var backsimeq = "⋍"; +var barvee = "⊽"; +var barwed = "⌅"; +var barwedge = "⌅"; +var bbrk = "⎵"; +var bbrktbrk = "⎶"; +var bcong = "≌"; +var bcy = "б"; +var bdquo = "„"; +var becaus = "∵"; +var because = "∵"; +var bemptyv = "⦰"; +var bepsi = "϶"; +var bernou = "ℬ"; +var beta = "β"; +var beth = "ℶ"; +var between = "≬"; +var bfr = "𝔟"; +var bigcap = "⋂"; +var bigcirc = "◯"; +var bigcup = "⋃"; +var bigodot = "⨀"; +var bigoplus = "⨁"; +var bigotimes = "⨂"; +var bigsqcup = "⨆"; +var bigstar = "★"; +var bigtriangledown = "▽"; +var bigtriangleup = "△"; +var biguplus = "⨄"; +var bigvee = "⋁"; +var bigwedge = "⋀"; +var bkarow = "⤍"; +var blacklozenge = "⧫"; +var blacksquare = "▪"; +var blacktriangle = "▴"; +var blacktriangledown = "▾"; +var blacktriangleleft = "◂"; +var blacktriangleright = "▸"; +var blank = "␣"; +var blk12 = "▒"; +var blk14 = "░"; +var blk34 = "▓"; +var block = "█"; +var bne = "=⃥"; +var bnequiv = "≡⃥"; +var bnot = "⌐"; +var bopf = "𝕓"; +var bot = "⊥"; +var bottom = "⊥"; +var bowtie = "⋈"; +var boxDL = "╗"; +var boxDR = "╔"; +var boxDl = "╖"; +var boxDr = "╓"; +var boxH = "═"; +var boxHD = "╦"; +var boxHU = "╩"; +var boxHd = "╤"; +var boxHu = "╧"; +var boxUL = "╝"; +var boxUR = "╚"; +var boxUl = "╜"; +var boxUr = "╙"; +var boxV = "║"; +var boxVH = "╬"; +var boxVL = "╣"; +var boxVR = "╠"; +var boxVh = "╫"; +var boxVl = "╢"; +var boxVr = "╟"; +var boxbox = "⧉"; +var boxdL = "╕"; +var boxdR = "╒"; +var boxdl = "┐"; +var boxdr = "┌"; +var boxh = "─"; +var boxhD = "╥"; +var boxhU = "╨"; +var boxhd = "┬"; +var boxhu = "┴"; +var boxminus = "⊟"; +var boxplus = "⊞"; +var boxtimes = "⊠"; +var boxuL = "╛"; +var boxuR = "╘"; +var boxul = "┘"; +var boxur = "└"; +var boxv = "│"; +var boxvH = "╪"; +var boxvL = "╡"; +var boxvR = "╞"; +var boxvh = "┼"; +var boxvl = "┤"; +var boxvr = "├"; +var bprime = "‵"; +var breve = "˘"; +var brvba = "¦"; +var brvbar = "¦"; +var bscr = "𝒷"; +var bsemi = "⁏"; +var bsim = "∽"; +var bsime = "⋍"; +var bsol = "\\"; +var bsolb = "⧅"; +var bsolhsub = "⟈"; +var bull = "•"; +var bullet = "•"; +var bump = "≎"; +var bumpE = "⪮"; +var bumpe = "≏"; +var bumpeq = "≏"; +var cacute = "ć"; +var cap = "∩"; +var capand = "⩄"; +var capbrcup = "⩉"; +var capcap = "⩋"; +var capcup = "⩇"; +var capdot = "⩀"; +var caps = "∩︀"; +var caret = "⁁"; +var caron = "ˇ"; +var ccaps = "⩍"; +var ccaron = "č"; +var ccedi = "ç"; +var ccedil = "ç"; +var ccirc = "ĉ"; +var ccups = "⩌"; +var ccupssm = "⩐"; +var cdot = "ċ"; +var cedi = "¸"; +var cedil = "¸"; +var cemptyv = "⦲"; +var cen = "¢"; +var cent = "¢"; +var centerdot = "·"; +var cfr = "𝔠"; +var chcy = "ч"; +var check = "✓"; +var checkmark = "✓"; +var chi = "χ"; +var cir = "○"; +var cirE = "⧃"; +var circ = "ˆ"; +var circeq = "≗"; +var circlearrowleft = "↺"; +var circlearrowright = "↻"; +var circledR = "®"; +var circledS = "Ⓢ"; +var circledast = "⊛"; +var circledcirc = "⊚"; +var circleddash = "⊝"; +var cire = "≗"; +var cirfnint = "⨐"; +var cirmid = "⫯"; +var cirscir = "⧂"; +var clubs = "♣"; +var clubsuit = "♣"; +var colon = ":"; +var colone = "≔"; +var coloneq = "≔"; +var comma = ","; +var commat = "@"; +var comp = "∁"; +var compfn = "∘"; +var complement = "∁"; +var complexes = "ℂ"; +var cong = "≅"; +var congdot = "⩭"; +var conint = "∮"; +var copf = "𝕔"; +var coprod = "∐"; +var cop = "©"; +var copy = "©"; +var copysr = "℗"; +var crarr = "↵"; +var cross = "✗"; +var cscr = "𝒸"; +var csub = "⫏"; +var csube = "⫑"; +var csup = "⫐"; +var csupe = "⫒"; +var ctdot = "⋯"; +var cudarrl = "⤸"; +var cudarrr = "⤵"; +var cuepr = "⋞"; +var cuesc = "⋟"; +var cularr = "↶"; +var cularrp = "⤽"; +var cup = "∪"; +var cupbrcap = "⩈"; +var cupcap = "⩆"; +var cupcup = "⩊"; +var cupdot = "⊍"; +var cupor = "⩅"; +var cups = "∪︀"; +var curarr = "↷"; +var curarrm = "⤼"; +var curlyeqprec = "⋞"; +var curlyeqsucc = "⋟"; +var curlyvee = "⋎"; +var curlywedge = "⋏"; +var curre = "¤"; +var curren = "¤"; +var curvearrowleft = "↶"; +var curvearrowright = "↷"; +var cuvee = "⋎"; +var cuwed = "⋏"; +var cwconint = "∲"; +var cwint = "∱"; +var cylcty = "⌭"; +var dArr = "⇓"; +var dHar = "⥥"; +var dagger = "†"; +var daleth = "ℸ"; +var darr = "↓"; +var dash = "‐"; +var dashv = "⊣"; +var dbkarow = "⤏"; +var dblac = "˝"; +var dcaron = "ď"; +var dcy = "д"; +var dd = "ⅆ"; +var ddagger = "‡"; +var ddarr = "⇊"; +var ddotseq = "⩷"; +var de = "°"; +var deg = "°"; +var delta = "δ"; +var demptyv = "⦱"; +var dfisht = "⥿"; +var dfr = "𝔡"; +var dharl = "⇃"; +var dharr = "⇂"; +var diam = "⋄"; +var diamond = "⋄"; +var diamondsuit = "♦"; +var diams = "♦"; +var die = "¨"; +var digamma = "ϝ"; +var disin = "⋲"; +var div = "÷"; +var divid = "÷"; +var divide = "÷"; +var divideontimes = "⋇"; +var divonx = "⋇"; +var djcy = "ђ"; +var dlcorn = "⌞"; +var dlcrop = "⌍"; +var dollar = "$"; +var dopf = "𝕕"; +var dot = "˙"; +var doteq = "≐"; +var doteqdot = "≑"; +var dotminus = "∸"; +var dotplus = "∔"; +var dotsquare = "⊡"; +var doublebarwedge = "⌆"; +var downarrow = "↓"; +var downdownarrows = "⇊"; +var downharpoonleft = "⇃"; +var downharpoonright = "⇂"; +var drbkarow = "⤐"; +var drcorn = "⌟"; +var drcrop = "⌌"; +var dscr = "𝒹"; +var dscy = "ѕ"; +var dsol = "⧶"; +var dstrok = "đ"; +var dtdot = "⋱"; +var dtri = "▿"; +var dtrif = "▾"; +var duarr = "⇵"; +var duhar = "⥯"; +var dwangle = "⦦"; +var dzcy = "џ"; +var dzigrarr = "⟿"; +var eDDot = "⩷"; +var eDot = "≑"; +var eacut = "é"; +var eacute = "é"; +var easter = "⩮"; +var ecaron = "ě"; +var ecir = "ê"; +var ecirc = "ê"; +var ecolon = "≕"; +var ecy = "э"; +var edot = "ė"; +var ee = "ⅇ"; +var efDot = "≒"; +var efr = "𝔢"; +var eg = "⪚"; +var egrav = "è"; +var egrave = "è"; +var egs = "⪖"; +var egsdot = "⪘"; +var el = "⪙"; +var elinters = "⏧"; +var ell = "ℓ"; +var els = "⪕"; +var elsdot = "⪗"; +var emacr = "ē"; +var empty = "∅"; +var emptyset = "∅"; +var emptyv = "∅"; +var emsp13 = " "; +var emsp14 = " "; +var emsp = " "; +var eng = "ŋ"; +var ensp = " "; +var eogon = "ę"; +var eopf = "𝕖"; +var epar = "⋕"; +var eparsl = "⧣"; +var eplus = "⩱"; +var epsi = "ε"; +var epsilon = "ε"; +var epsiv = "ϵ"; +var eqcirc = "≖"; +var eqcolon = "≕"; +var eqsim = "≂"; +var eqslantgtr = "⪖"; +var eqslantless = "⪕"; +var equals = "="; +var equest = "≟"; +var equiv = "≡"; +var equivDD = "⩸"; +var eqvparsl = "⧥"; +var erDot = "≓"; +var erarr = "⥱"; +var escr = "ℯ"; +var esdot = "≐"; +var esim = "≂"; +var eta = "η"; +var et = "ð"; +var eth = "ð"; +var eum = "ë"; +var euml = "ë"; +var euro = "€"; +var excl = "!"; +var exist = "∃"; +var expectation = "ℰ"; +var exponentiale = "ⅇ"; +var fallingdotseq = "≒"; +var fcy = "ф"; +var female = "♀"; +var ffilig = "ffi"; +var fflig = "ff"; +var ffllig = "ffl"; +var ffr = "𝔣"; +var filig = "fi"; +var fjlig = "fj"; +var flat = "♭"; +var fllig = "fl"; +var fltns = "▱"; +var fnof = "ƒ"; +var fopf = "𝕗"; +var forall = "∀"; +var fork = "⋔"; +var forkv = "⫙"; +var fpartint = "⨍"; +var frac1 = "¼"; +var frac12 = "½"; +var frac13 = "⅓"; +var frac14 = "¼"; +var frac15 = "⅕"; +var frac16 = "⅙"; +var frac18 = "⅛"; +var frac23 = "⅔"; +var frac25 = "⅖"; +var frac3 = "¾"; +var frac34 = "¾"; +var frac35 = "⅗"; +var frac38 = "⅜"; +var frac45 = "⅘"; +var frac56 = "⅚"; +var frac58 = "⅝"; +var frac78 = "⅞"; +var frasl = "⁄"; +var frown = "⌢"; +var fscr = "𝒻"; +var gE = "≧"; +var gEl = "⪌"; +var gacute = "ǵ"; +var gamma = "γ"; +var gammad = "ϝ"; +var gap = "⪆"; +var gbreve = "ğ"; +var gcirc = "ĝ"; +var gcy = "г"; +var gdot = "ġ"; +var ge = "≥"; +var gel = "⋛"; +var geq = "≥"; +var geqq = "≧"; +var geqslant = "⩾"; +var ges = "⩾"; +var gescc = "⪩"; +var gesdot = "⪀"; +var gesdoto = "⪂"; +var gesdotol = "⪄"; +var gesl = "⋛︀"; +var gesles = "⪔"; +var gfr = "𝔤"; +var gg = "≫"; +var ggg = "⋙"; +var gimel = "ℷ"; +var gjcy = "ѓ"; +var gl = "≷"; +var glE = "⪒"; +var gla = "⪥"; +var glj = "⪤"; +var gnE = "≩"; +var gnap = "⪊"; +var gnapprox = "⪊"; +var gne = "⪈"; +var gneq = "⪈"; +var gneqq = "≩"; +var gnsim = "⋧"; +var gopf = "𝕘"; +var grave = "`"; +var gscr = "ℊ"; +var gsim = "≳"; +var gsime = "⪎"; +var gsiml = "⪐"; +var g = ">"; +var gt = ">"; +var gtcc = "⪧"; +var gtcir = "⩺"; +var gtdot = "⋗"; +var gtlPar = "⦕"; +var gtquest = "⩼"; +var gtrapprox = "⪆"; +var gtrarr = "⥸"; +var gtrdot = "⋗"; +var gtreqless = "⋛"; +var gtreqqless = "⪌"; +var gtrless = "≷"; +var gtrsim = "≳"; +var gvertneqq = "≩︀"; +var gvnE = "≩︀"; +var hArr = "⇔"; +var hairsp = " "; +var half = "½"; +var hamilt = "ℋ"; +var hardcy = "ъ"; +var harr = "↔"; +var harrcir = "⥈"; +var harrw = "↭"; +var hbar = "ℏ"; +var hcirc = "ĥ"; +var hearts = "♥"; +var heartsuit = "♥"; +var hellip = "…"; +var hercon = "⊹"; +var hfr = "𝔥"; +var hksearow = "⤥"; +var hkswarow = "⤦"; +var hoarr = "⇿"; +var homtht = "∻"; +var hookleftarrow = "↩"; +var hookrightarrow = "↪"; +var hopf = "𝕙"; +var horbar = "―"; +var hscr = "𝒽"; +var hslash = "ℏ"; +var hstrok = "ħ"; +var hybull = "⁃"; +var hyphen = "‐"; +var iacut = "í"; +var iacute = "í"; +var ic = "⁣"; +var icir = "î"; +var icirc = "î"; +var icy = "и"; +var iecy = "е"; +var iexc = "¡"; +var iexcl = "¡"; +var iff = "⇔"; +var ifr = "𝔦"; +var igrav = "ì"; +var igrave = "ì"; +var ii = "ⅈ"; +var iiiint = "⨌"; +var iiint = "∭"; +var iinfin = "⧜"; +var iiota = "℩"; +var ijlig = "ij"; +var imacr = "ī"; +var image = "ℑ"; +var imagline = "ℐ"; +var imagpart = "ℑ"; +var imath = "ı"; +var imof = "⊷"; +var imped = "Ƶ"; +var incare = "℅"; +var infin = "∞"; +var infintie = "⧝"; +var inodot = "ı"; +var int = "∫"; +var intcal = "⊺"; +var integers = "ℤ"; +var intercal = "⊺"; +var intlarhk = "⨗"; +var intprod = "⨼"; +var iocy = "ё"; +var iogon = "į"; +var iopf = "𝕚"; +var iota = "ι"; +var iprod = "⨼"; +var iques = "¿"; +var iquest = "¿"; +var iscr = "𝒾"; +var isin = "∈"; +var isinE = "⋹"; +var isindot = "⋵"; +var isins = "⋴"; +var isinsv = "⋳"; +var isinv = "∈"; +var it = "⁢"; +var itilde = "ĩ"; +var iukcy = "і"; +var ium = "ï"; +var iuml = "ï"; +var jcirc = "ĵ"; +var jcy = "й"; +var jfr = "𝔧"; +var jmath = "ȷ"; +var jopf = "𝕛"; +var jscr = "𝒿"; +var jsercy = "ј"; +var jukcy = "є"; +var kappa = "κ"; +var kappav = "ϰ"; +var kcedil = "ķ"; +var kcy = "к"; +var kfr = "𝔨"; +var kgreen = "ĸ"; +var khcy = "х"; +var kjcy = "ќ"; +var kopf = "𝕜"; +var kscr = "𝓀"; +var lAarr = "⇚"; +var lArr = "⇐"; +var lAtail = "⤛"; +var lBarr = "⤎"; +var lE = "≦"; +var lEg = "⪋"; +var lHar = "⥢"; +var lacute = "ĺ"; +var laemptyv = "⦴"; +var lagran = "ℒ"; +var lambda = "λ"; +var lang = "⟨"; +var langd = "⦑"; +var langle = "⟨"; +var lap = "⪅"; +var laqu = "«"; +var laquo = "«"; +var larr = "←"; +var larrb = "⇤"; +var larrbfs = "⤟"; +var larrfs = "⤝"; +var larrhk = "↩"; +var larrlp = "↫"; +var larrpl = "⤹"; +var larrsim = "⥳"; +var larrtl = "↢"; +var lat = "⪫"; +var latail = "⤙"; +var late = "⪭"; +var lates = "⪭︀"; +var lbarr = "⤌"; +var lbbrk = "❲"; +var lbrace = "{"; +var lbrack = "["; +var lbrke = "⦋"; +var lbrksld = "⦏"; +var lbrkslu = "⦍"; +var lcaron = "ľ"; +var lcedil = "ļ"; +var lceil = "⌈"; +var lcub = "{"; +var lcy = "л"; +var ldca = "⤶"; +var ldquo = "“"; +var ldquor = "„"; +var ldrdhar = "⥧"; +var ldrushar = "⥋"; +var ldsh = "↲"; +var le = "≤"; +var leftarrow = "←"; +var leftarrowtail = "↢"; +var leftharpoondown = "↽"; +var leftharpoonup = "↼"; +var leftleftarrows = "⇇"; +var leftrightarrow = "↔"; +var leftrightarrows = "⇆"; +var leftrightharpoons = "⇋"; +var leftrightsquigarrow = "↭"; +var leftthreetimes = "⋋"; +var leg = "⋚"; +var leq = "≤"; +var leqq = "≦"; +var leqslant = "⩽"; +var les = "⩽"; +var lescc = "⪨"; +var lesdot = "⩿"; +var lesdoto = "⪁"; +var lesdotor = "⪃"; +var lesg = "⋚︀"; +var lesges = "⪓"; +var lessapprox = "⪅"; +var lessdot = "⋖"; +var lesseqgtr = "⋚"; +var lesseqqgtr = "⪋"; +var lessgtr = "≶"; +var lesssim = "≲"; +var lfisht = "⥼"; +var lfloor = "⌊"; +var lfr = "𝔩"; +var lg = "≶"; +var lgE = "⪑"; +var lhard = "↽"; +var lharu = "↼"; +var lharul = "⥪"; +var lhblk = "▄"; +var ljcy = "љ"; +var ll = "≪"; +var llarr = "⇇"; +var llcorner = "⌞"; +var llhard = "⥫"; +var lltri = "◺"; +var lmidot = "ŀ"; +var lmoust = "⎰"; +var lmoustache = "⎰"; +var lnE = "≨"; +var lnap = "⪉"; +var lnapprox = "⪉"; +var lne = "⪇"; +var lneq = "⪇"; +var lneqq = "≨"; +var lnsim = "⋦"; +var loang = "⟬"; +var loarr = "⇽"; +var lobrk = "⟦"; +var longleftarrow = "⟵"; +var longleftrightarrow = "⟷"; +var longmapsto = "⟼"; +var longrightarrow = "⟶"; +var looparrowleft = "↫"; +var looparrowright = "↬"; +var lopar = "⦅"; +var lopf = "𝕝"; +var loplus = "⨭"; +var lotimes = "⨴"; +var lowast = "∗"; +var lowbar = "_"; +var loz = "◊"; +var lozenge = "◊"; +var lozf = "⧫"; +var lpar = "("; +var lparlt = "⦓"; +var lrarr = "⇆"; +var lrcorner = "⌟"; +var lrhar = "⇋"; +var lrhard = "⥭"; +var lrm = "‎"; +var lrtri = "⊿"; +var lsaquo = "‹"; +var lscr = "𝓁"; +var lsh = "↰"; +var lsim = "≲"; +var lsime = "⪍"; +var lsimg = "⪏"; +var lsqb = "["; +var lsquo = "‘"; +var lsquor = "‚"; +var lstrok = "ł"; +var l = "<"; +var lt = "<"; +var ltcc = "⪦"; +var ltcir = "⩹"; +var ltdot = "⋖"; +var lthree = "⋋"; +var ltimes = "⋉"; +var ltlarr = "⥶"; +var ltquest = "⩻"; +var ltrPar = "⦖"; +var ltri = "◃"; +var ltrie = "⊴"; +var ltrif = "◂"; +var lurdshar = "⥊"; +var luruhar = "⥦"; +var lvertneqq = "≨︀"; +var lvnE = "≨︀"; +var mDDot = "∺"; +var mac = "¯"; +var macr = "¯"; +var male = "♂"; +var malt = "✠"; +var maltese = "✠"; +var map = "↦"; +var mapsto = "↦"; +var mapstodown = "↧"; +var mapstoleft = "↤"; +var mapstoup = "↥"; +var marker = "▮"; +var mcomma = "⨩"; +var mcy = "м"; +var mdash = "—"; +var measuredangle = "∡"; +var mfr = "𝔪"; +var mho = "℧"; +var micr = "µ"; +var micro = "µ"; +var mid = "∣"; +var midast = "*"; +var midcir = "⫰"; +var middo = "·"; +var middot = "·"; +var minus = "−"; +var minusb = "⊟"; +var minusd = "∸"; +var minusdu = "⨪"; +var mlcp = "⫛"; +var mldr = "…"; +var mnplus = "∓"; +var models = "⊧"; +var mopf = "𝕞"; +var mp = "∓"; +var mscr = "𝓂"; +var mstpos = "∾"; +var mu = "μ"; +var multimap = "⊸"; +var mumap = "⊸"; +var nGg = "⋙̸"; +var nGt = "≫⃒"; +var nGtv = "≫̸"; +var nLeftarrow = "⇍"; +var nLeftrightarrow = "⇎"; +var nLl = "⋘̸"; +var nLt = "≪⃒"; +var nLtv = "≪̸"; +var nRightarrow = "⇏"; +var nVDash = "⊯"; +var nVdash = "⊮"; +var nabla = "∇"; +var nacute = "ń"; +var nang = "∠⃒"; +var nap = "≉"; +var napE = "⩰̸"; +var napid = "≋̸"; +var napos = "ʼn"; +var napprox = "≉"; +var natur = "♮"; +var natural = "♮"; +var naturals = "ℕ"; +var nbs = " "; +var nbsp = " "; +var nbump = "≎̸"; +var nbumpe = "≏̸"; +var ncap = "⩃"; +var ncaron = "ň"; +var ncedil = "ņ"; +var ncong = "≇"; +var ncongdot = "⩭̸"; +var ncup = "⩂"; +var ncy = "н"; +var ndash = "–"; +var ne = "≠"; +var neArr = "⇗"; +var nearhk = "⤤"; +var nearr = "↗"; +var nearrow = "↗"; +var nedot = "≐̸"; +var nequiv = "≢"; +var nesear = "⤨"; +var nesim = "≂̸"; +var nexist = "∄"; +var nexists = "∄"; +var nfr = "𝔫"; +var ngE = "≧̸"; +var nge = "≱"; +var ngeq = "≱"; +var ngeqq = "≧̸"; +var ngeqslant = "⩾̸"; +var nges = "⩾̸"; +var ngsim = "≵"; +var ngt = "≯"; +var ngtr = "≯"; +var nhArr = "⇎"; +var nharr = "↮"; +var nhpar = "⫲"; +var ni = "∋"; +var nis = "⋼"; +var nisd = "⋺"; +var niv = "∋"; +var njcy = "њ"; +var nlArr = "⇍"; +var nlE = "≦̸"; +var nlarr = "↚"; +var nldr = "‥"; +var nle = "≰"; +var nleftarrow = "↚"; +var nleftrightarrow = "↮"; +var nleq = "≰"; +var nleqq = "≦̸"; +var nleqslant = "⩽̸"; +var nles = "⩽̸"; +var nless = "≮"; +var nlsim = "≴"; +var nlt = "≮"; +var nltri = "⋪"; +var nltrie = "⋬"; +var nmid = "∤"; +var nopf = "𝕟"; +var no = "¬"; +var not = "¬"; +var notin = "∉"; +var notinE = "⋹̸"; +var notindot = "⋵̸"; +var notinva = "∉"; +var notinvb = "⋷"; +var notinvc = "⋶"; +var notni = "∌"; +var notniva = "∌"; +var notnivb = "⋾"; +var notnivc = "⋽"; +var npar = "∦"; +var nparallel = "∦"; +var nparsl = "⫽⃥"; +var npart = "∂̸"; +var npolint = "⨔"; +var npr = "⊀"; +var nprcue = "⋠"; +var npre = "⪯̸"; +var nprec = "⊀"; +var npreceq = "⪯̸"; +var nrArr = "⇏"; +var nrarr = "↛"; +var nrarrc = "⤳̸"; +var nrarrw = "↝̸"; +var nrightarrow = "↛"; +var nrtri = "⋫"; +var nrtrie = "⋭"; +var nsc = "⊁"; +var nsccue = "⋡"; +var nsce = "⪰̸"; +var nscr = "𝓃"; +var nshortmid = "∤"; +var nshortparallel = "∦"; +var nsim = "≁"; +var nsime = "≄"; +var nsimeq = "≄"; +var nsmid = "∤"; +var nspar = "∦"; +var nsqsube = "⋢"; +var nsqsupe = "⋣"; +var nsub = "⊄"; +var nsubE = "⫅̸"; +var nsube = "⊈"; +var nsubset = "⊂⃒"; +var nsubseteq = "⊈"; +var nsubseteqq = "⫅̸"; +var nsucc = "⊁"; +var nsucceq = "⪰̸"; +var nsup = "⊅"; +var nsupE = "⫆̸"; +var nsupe = "⊉"; +var nsupset = "⊃⃒"; +var nsupseteq = "⊉"; +var nsupseteqq = "⫆̸"; +var ntgl = "≹"; +var ntild = "ñ"; +var ntilde = "ñ"; +var ntlg = "≸"; +var ntriangleleft = "⋪"; +var ntrianglelefteq = "⋬"; +var ntriangleright = "⋫"; +var ntrianglerighteq = "⋭"; +var nu = "ν"; +var num = "#"; +var numero = "№"; +var numsp = " "; +var nvDash = "⊭"; +var nvHarr = "⤄"; +var nvap = "≍⃒"; +var nvdash = "⊬"; +var nvge = "≥⃒"; +var nvgt = ">⃒"; +var nvinfin = "⧞"; +var nvlArr = "⤂"; +var nvle = "≤⃒"; +var nvlt = "<⃒"; +var nvltrie = "⊴⃒"; +var nvrArr = "⤃"; +var nvrtrie = "⊵⃒"; +var nvsim = "∼⃒"; +var nwArr = "⇖"; +var nwarhk = "⤣"; +var nwarr = "↖"; +var nwarrow = "↖"; +var nwnear = "⤧"; +var oS = "Ⓢ"; +var oacut = "ó"; +var oacute = "ó"; +var oast = "⊛"; +var ocir = "ô"; +var ocirc = "ô"; +var ocy = "о"; +var odash = "⊝"; +var odblac = "ő"; +var odiv = "⨸"; +var odot = "⊙"; +var odsold = "⦼"; +var oelig = "œ"; +var ofcir = "⦿"; +var ofr = "𝔬"; +var ogon = "˛"; +var ograv = "ò"; +var ograve = "ò"; +var ogt = "⧁"; +var ohbar = "⦵"; +var ohm = "Ω"; +var oint = "∮"; +var olarr = "↺"; +var olcir = "⦾"; +var olcross = "⦻"; +var oline = "‾"; +var olt = "⧀"; +var omacr = "ō"; +var omega = "ω"; +var omicron = "ο"; +var omid = "⦶"; +var ominus = "⊖"; +var oopf = "𝕠"; +var opar = "⦷"; +var operp = "⦹"; +var oplus = "⊕"; +var or = "∨"; +var orarr = "↻"; +var ord = "º"; +var order = "ℴ"; +var orderof = "ℴ"; +var ordf = "ª"; +var ordm = "º"; +var origof = "⊶"; +var oror = "⩖"; +var orslope = "⩗"; +var orv = "⩛"; +var oscr = "ℴ"; +var oslas = "ø"; +var oslash = "ø"; +var osol = "⊘"; +var otild = "õ"; +var otilde = "õ"; +var otimes = "⊗"; +var otimesas = "⨶"; +var oum = "ö"; +var ouml = "ö"; +var ovbar = "⌽"; +var par = "¶"; +var para = "¶"; +var parallel = "∥"; +var parsim = "⫳"; +var parsl = "⫽"; +var part = "∂"; +var pcy = "п"; +var percnt = "%"; +var period = "."; +var permil = "‰"; +var perp = "⊥"; +var pertenk = "‱"; +var pfr = "𝔭"; +var phi = "φ"; +var phiv = "ϕ"; +var phmmat = "ℳ"; +var phone = "☎"; +var pi = "π"; +var pitchfork = "⋔"; +var piv = "ϖ"; +var planck = "ℏ"; +var planckh = "ℎ"; +var plankv = "ℏ"; +var plus = "+"; +var plusacir = "⨣"; +var plusb = "⊞"; +var pluscir = "⨢"; +var plusdo = "∔"; +var plusdu = "⨥"; +var pluse = "⩲"; +var plusm = "±"; +var plusmn = "±"; +var plussim = "⨦"; +var plustwo = "⨧"; +var pm = "±"; +var pointint = "⨕"; +var popf = "𝕡"; +var poun = "£"; +var pound = "£"; +var pr = "≺"; +var prE = "⪳"; +var prap = "⪷"; +var prcue = "≼"; +var pre = "⪯"; +var prec = "≺"; +var precapprox = "⪷"; +var preccurlyeq = "≼"; +var preceq = "⪯"; +var precnapprox = "⪹"; +var precneqq = "⪵"; +var precnsim = "⋨"; +var precsim = "≾"; +var prime = "′"; +var primes = "ℙ"; +var prnE = "⪵"; +var prnap = "⪹"; +var prnsim = "⋨"; +var prod = "∏"; +var profalar = "⌮"; +var profline = "⌒"; +var profsurf = "⌓"; +var prop = "∝"; +var propto = "∝"; +var prsim = "≾"; +var prurel = "⊰"; +var pscr = "𝓅"; +var psi = "ψ"; +var puncsp = " "; +var qfr = "𝔮"; +var qint = "⨌"; +var qopf = "𝕢"; +var qprime = "⁗"; +var qscr = "𝓆"; +var quaternions = "ℍ"; +var quatint = "⨖"; +var quest = "?"; +var questeq = "≟"; +var quo = "\""; +var quot = "\""; +var rAarr = "⇛"; +var rArr = "⇒"; +var rAtail = "⤜"; +var rBarr = "⤏"; +var rHar = "⥤"; +var race = "∽̱"; +var racute = "ŕ"; +var radic = "√"; +var raemptyv = "⦳"; +var rang = "⟩"; +var rangd = "⦒"; +var range = "⦥"; +var rangle = "⟩"; +var raqu = "»"; +var raquo = "»"; +var rarr = "→"; +var rarrap = "⥵"; +var rarrb = "⇥"; +var rarrbfs = "⤠"; +var rarrc = "⤳"; +var rarrfs = "⤞"; +var rarrhk = "↪"; +var rarrlp = "↬"; +var rarrpl = "⥅"; +var rarrsim = "⥴"; +var rarrtl = "↣"; +var rarrw = "↝"; +var ratail = "⤚"; +var ratio = "∶"; +var rationals = "ℚ"; +var rbarr = "⤍"; +var rbbrk = "❳"; +var rbrace = "}"; +var rbrack = "]"; +var rbrke = "⦌"; +var rbrksld = "⦎"; +var rbrkslu = "⦐"; +var rcaron = "ř"; +var rcedil = "ŗ"; +var rceil = "⌉"; +var rcub = "}"; +var rcy = "р"; +var rdca = "⤷"; +var rdldhar = "⥩"; +var rdquo = "”"; +var rdquor = "”"; +var rdsh = "↳"; +var real = "ℜ"; +var realine = "ℛ"; +var realpart = "ℜ"; +var reals = "ℝ"; +var rect = "▭"; +var re$2 = "®"; +var reg = "®"; +var rfisht = "⥽"; +var rfloor = "⌋"; +var rfr = "𝔯"; +var rhard = "⇁"; +var rharu = "⇀"; +var rharul = "⥬"; +var rho = "ρ"; +var rhov = "ϱ"; +var rightarrow = "→"; +var rightarrowtail = "↣"; +var rightharpoondown = "⇁"; +var rightharpoonup = "⇀"; +var rightleftarrows = "⇄"; +var rightleftharpoons = "⇌"; +var rightrightarrows = "⇉"; +var rightsquigarrow = "↝"; +var rightthreetimes = "⋌"; +var ring = "˚"; +var risingdotseq = "≓"; +var rlarr = "⇄"; +var rlhar = "⇌"; +var rlm = "‏"; +var rmoust = "⎱"; +var rmoustache = "⎱"; +var rnmid = "⫮"; +var roang = "⟭"; +var roarr = "⇾"; +var robrk = "⟧"; +var ropar = "⦆"; +var ropf = "𝕣"; +var roplus = "⨮"; +var rotimes = "⨵"; +var rpar = ")"; +var rpargt = "⦔"; +var rppolint = "⨒"; +var rrarr = "⇉"; +var rsaquo = "›"; +var rscr = "𝓇"; +var rsh = "↱"; +var rsqb = "]"; +var rsquo = "’"; +var rsquor = "’"; +var rthree = "⋌"; +var rtimes = "⋊"; +var rtri = "▹"; +var rtrie = "⊵"; +var rtrif = "▸"; +var rtriltri = "⧎"; +var ruluhar = "⥨"; +var rx = "℞"; +var sacute = "ś"; +var sbquo = "‚"; +var sc = "≻"; +var scE = "⪴"; +var scap = "⪸"; +var scaron = "š"; +var sccue = "≽"; +var sce = "⪰"; +var scedil = "ş"; +var scirc = "ŝ"; +var scnE = "⪶"; +var scnap = "⪺"; +var scnsim = "⋩"; +var scpolint = "⨓"; +var scsim = "≿"; +var scy = "с"; +var sdot = "⋅"; +var sdotb = "⊡"; +var sdote = "⩦"; +var seArr = "⇘"; +var searhk = "⤥"; +var searr = "↘"; +var searrow = "↘"; +var sec = "§"; +var sect = "§"; +var semi = ";"; +var seswar = "⤩"; +var setminus = "∖"; +var setmn = "∖"; +var sext = "✶"; +var sfr = "𝔰"; +var sfrown = "⌢"; +var sharp = "♯"; +var shchcy = "щ"; +var shcy = "ш"; +var shortmid = "∣"; +var shortparallel = "∥"; +var sh = "­"; +var shy = "­"; +var sigma = "σ"; +var sigmaf = "ς"; +var sigmav = "ς"; +var sim = "∼"; +var simdot = "⩪"; +var sime = "≃"; +var simeq = "≃"; +var simg = "⪞"; +var simgE = "⪠"; +var siml = "⪝"; +var simlE = "⪟"; +var simne = "≆"; +var simplus = "⨤"; +var simrarr = "⥲"; +var slarr = "←"; +var smallsetminus = "∖"; +var smashp = "⨳"; +var smeparsl = "⧤"; +var smid = "∣"; +var smile = "⌣"; +var smt = "⪪"; +var smte = "⪬"; +var smtes = "⪬︀"; +var softcy = "ь"; +var sol = "/"; +var solb = "⧄"; +var solbar = "⌿"; +var sopf = "𝕤"; +var spades = "♠"; +var spadesuit = "♠"; +var spar = "∥"; +var sqcap = "⊓"; +var sqcaps = "⊓︀"; +var sqcup = "⊔"; +var sqcups = "⊔︀"; +var sqsub = "⊏"; +var sqsube = "⊑"; +var sqsubset = "⊏"; +var sqsubseteq = "⊑"; +var sqsup = "⊐"; +var sqsupe = "⊒"; +var sqsupset = "⊐"; +var sqsupseteq = "⊒"; +var squ = "□"; +var square = "□"; +var squarf = "▪"; +var squf = "▪"; +var srarr = "→"; +var sscr = "𝓈"; +var ssetmn = "∖"; +var ssmile = "⌣"; +var sstarf = "⋆"; +var star = "☆"; +var starf = "★"; +var straightepsilon = "ϵ"; +var straightphi = "ϕ"; +var strns = "¯"; +var sub = "⊂"; +var subE = "⫅"; +var subdot = "⪽"; +var sube = "⊆"; +var subedot = "⫃"; +var submult = "⫁"; +var subnE = "⫋"; +var subne = "⊊"; +var subplus = "⪿"; +var subrarr = "⥹"; +var subset = "⊂"; +var subseteq = "⊆"; +var subseteqq = "⫅"; +var subsetneq = "⊊"; +var subsetneqq = "⫋"; +var subsim = "⫇"; +var subsub = "⫕"; +var subsup = "⫓"; +var succ = "≻"; +var succapprox = "⪸"; +var succcurlyeq = "≽"; +var succeq = "⪰"; +var succnapprox = "⪺"; +var succneqq = "⪶"; +var succnsim = "⋩"; +var succsim = "≿"; +var sum = "∑"; +var sung = "♪"; +var sup = "⊃"; +var sup1 = "¹"; +var sup2 = "²"; +var sup3 = "³"; +var supE = "⫆"; +var supdot = "⪾"; +var supdsub = "⫘"; +var supe = "⊇"; +var supedot = "⫄"; +var suphsol = "⟉"; +var suphsub = "⫗"; +var suplarr = "⥻"; +var supmult = "⫂"; +var supnE = "⫌"; +var supne = "⊋"; +var supplus = "⫀"; +var supset = "⊃"; +var supseteq = "⊇"; +var supseteqq = "⫆"; +var supsetneq = "⊋"; +var supsetneqq = "⫌"; +var supsim = "⫈"; +var supsub = "⫔"; +var supsup = "⫖"; +var swArr = "⇙"; +var swarhk = "⤦"; +var swarr = "↙"; +var swarrow = "↙"; +var swnwar = "⤪"; +var szli = "ß"; +var szlig = "ß"; +var target = "⌖"; +var tau = "τ"; +var tbrk = "⎴"; +var tcaron = "ť"; +var tcedil = "ţ"; +var tcy = "т"; +var tdot = "⃛"; +var telrec = "⌕"; +var tfr = "𝔱"; +var there4 = "∴"; +var therefore = "∴"; +var theta = "θ"; +var thetasym = "ϑ"; +var thetav = "ϑ"; +var thickapprox = "≈"; +var thicksim = "∼"; +var thinsp = " "; +var thkap = "≈"; +var thksim = "∼"; +var thor = "þ"; +var thorn = "þ"; +var tilde = "˜"; +var time = "×"; +var times = "×"; +var timesb = "⊠"; +var timesbar = "⨱"; +var timesd = "⨰"; +var tint = "∭"; +var toea = "⤨"; +var top = "⊤"; +var topbot = "⌶"; +var topcir = "⫱"; +var topf = "𝕥"; +var topfork = "⫚"; +var tosa = "⤩"; +var tprime = "‴"; +var trade = "™"; +var triangle = "▵"; +var triangledown = "▿"; +var triangleleft = "◃"; +var trianglelefteq = "⊴"; +var triangleq = "≜"; +var triangleright = "▹"; +var trianglerighteq = "⊵"; +var tridot = "◬"; +var trie = "≜"; +var triminus = "⨺"; +var triplus = "⨹"; +var trisb = "⧍"; +var tritime = "⨻"; +var trpezium = "⏢"; +var tscr = "𝓉"; +var tscy = "ц"; +var tshcy = "ћ"; +var tstrok = "ŧ"; +var twixt = "≬"; +var twoheadleftarrow = "↞"; +var twoheadrightarrow = "↠"; +var uArr = "⇑"; +var uHar = "⥣"; +var uacut = "ú"; +var uacute = "ú"; +var uarr = "↑"; +var ubrcy = "ў"; +var ubreve = "ŭ"; +var ucir = "û"; +var ucirc = "û"; +var ucy = "у"; +var udarr = "⇅"; +var udblac = "ű"; +var udhar = "⥮"; +var ufisht = "⥾"; +var ufr = "𝔲"; +var ugrav = "ù"; +var ugrave = "ù"; +var uharl = "↿"; +var uharr = "↾"; +var uhblk = "▀"; +var ulcorn = "⌜"; +var ulcorner = "⌜"; +var ulcrop = "⌏"; +var ultri = "◸"; +var umacr = "ū"; +var um = "¨"; +var uml = "¨"; +var uogon = "ų"; +var uopf = "𝕦"; +var uparrow = "↑"; +var updownarrow = "↕"; +var upharpoonleft = "↿"; +var upharpoonright = "↾"; +var uplus = "⊎"; +var upsi = "υ"; +var upsih = "ϒ"; +var upsilon = "υ"; +var upuparrows = "⇈"; +var urcorn = "⌝"; +var urcorner = "⌝"; +var urcrop = "⌎"; +var uring = "ů"; +var urtri = "◹"; +var uscr = "𝓊"; +var utdot = "⋰"; +var utilde = "ũ"; +var utri = "▵"; +var utrif = "▴"; +var uuarr = "⇈"; +var uum = "ü"; +var uuml = "ü"; +var uwangle = "⦧"; +var vArr = "⇕"; +var vBar = "⫨"; +var vBarv = "⫩"; +var vDash = "⊨"; +var vangrt = "⦜"; +var varepsilon = "ϵ"; +var varkappa = "ϰ"; +var varnothing = "∅"; +var varphi = "ϕ"; +var varpi = "ϖ"; +var varpropto = "∝"; +var varr = "↕"; +var varrho = "ϱ"; +var varsigma = "ς"; +var varsubsetneq = "⊊︀"; +var varsubsetneqq = "⫋︀"; +var varsupsetneq = "⊋︀"; +var varsupsetneqq = "⫌︀"; +var vartheta = "ϑ"; +var vartriangleleft = "⊲"; +var vartriangleright = "⊳"; +var vcy = "в"; +var vdash = "⊢"; +var vee = "∨"; +var veebar = "⊻"; +var veeeq = "≚"; +var vellip = "⋮"; +var verbar = "|"; +var vert = "|"; +var vfr = "𝔳"; +var vltri = "⊲"; +var vnsub = "⊂⃒"; +var vnsup = "⊃⃒"; +var vopf = "𝕧"; +var vprop = "∝"; +var vrtri = "⊳"; +var vscr = "𝓋"; +var vsubnE = "⫋︀"; +var vsubne = "⊊︀"; +var vsupnE = "⫌︀"; +var vsupne = "⊋︀"; +var vzigzag = "⦚"; +var wcirc = "ŵ"; +var wedbar = "⩟"; +var wedge = "∧"; +var wedgeq = "≙"; +var weierp = "℘"; +var wfr = "𝔴"; +var wopf = "𝕨"; +var wp = "℘"; +var wr = "≀"; +var wreath = "≀"; +var wscr = "𝓌"; +var xcap = "⋂"; +var xcirc = "◯"; +var xcup = "⋃"; +var xdtri = "▽"; +var xfr = "𝔵"; +var xhArr = "⟺"; +var xharr = "⟷"; +var xi = "ξ"; +var xlArr = "⟸"; +var xlarr = "⟵"; +var xmap = "⟼"; +var xnis = "⋻"; +var xodot = "⨀"; +var xopf = "𝕩"; +var xoplus = "⨁"; +var xotime = "⨂"; +var xrArr = "⟹"; +var xrarr = "⟶"; +var xscr = "𝓍"; +var xsqcup = "⨆"; +var xuplus = "⨄"; +var xutri = "△"; +var xvee = "⋁"; +var xwedge = "⋀"; +var yacut = "ý"; +var yacute = "ý"; +var yacy = "я"; +var ycirc = "ŷ"; +var ycy = "ы"; +var ye = "¥"; +var yen = "¥"; +var yfr = "𝔶"; +var yicy = "ї"; +var yopf = "𝕪"; +var yscr = "𝓎"; +var yucy = "ю"; +var yum = "ÿ"; +var yuml = "ÿ"; +var zacute = "ź"; +var zcaron = "ž"; +var zcy = "з"; +var zdot = "ż"; +var zeetrf = "ℨ"; +var zeta = "ζ"; +var zfr = "𝔷"; +var zhcy = "ж"; +var zigrarr = "⇝"; +var zopf = "𝕫"; +var zscr = "𝓏"; +var zwj = "‍"; +var zwnj = "‌"; +var characterEntities = { + AEli: AEli, + AElig: AElig, + AM: AM, + AMP: AMP, + Aacut: Aacut, + Aacute: Aacute, + Abreve: Abreve, + Acir: Acir, + Acirc: Acirc, + Acy: Acy, + Afr: Afr, + Agrav: Agrav, + Agrave: Agrave, + Alpha: Alpha, + Amacr: Amacr, + And: And, + Aogon: Aogon, + Aopf: Aopf, + ApplyFunction: ApplyFunction, + Arin: Arin, + Aring: Aring, + Ascr: Ascr, + Assign: Assign, + Atild: Atild, + Atilde: Atilde, + Aum: Aum, + Auml: Auml, + Backslash: Backslash, + Barv: Barv, + Barwed: Barwed, + Bcy: Bcy, + Because: Because, + Bernoullis: Bernoullis, + Beta: Beta, + Bfr: Bfr, + Bopf: Bopf, + Breve: Breve, + Bscr: Bscr, + Bumpeq: Bumpeq, + CHcy: CHcy, + COP: COP, + COPY: COPY, + Cacute: Cacute, + Cap: Cap, + CapitalDifferentialD: CapitalDifferentialD, + Cayleys: Cayleys, + Ccaron: Ccaron, + Ccedi: Ccedi, + Ccedil: Ccedil, + Ccirc: Ccirc, + Cconint: Cconint, + Cdot: Cdot, + Cedilla: Cedilla, + CenterDot: CenterDot, + Cfr: Cfr, + Chi: Chi, + CircleDot: CircleDot, + CircleMinus: CircleMinus, + CirclePlus: CirclePlus, + CircleTimes: CircleTimes, + ClockwiseContourIntegral: ClockwiseContourIntegral, + CloseCurlyDoubleQuote: CloseCurlyDoubleQuote, + CloseCurlyQuote: CloseCurlyQuote, + Colon: Colon, + Colone: Colone, + Congruent: Congruent, + Conint: Conint, + ContourIntegral: ContourIntegral, + Copf: Copf, + Coproduct: Coproduct, + CounterClockwiseContourIntegral: CounterClockwiseContourIntegral, + Cross: Cross, + Cscr: Cscr, + Cup: Cup, + CupCap: CupCap, + DD: DD, + DDotrahd: DDotrahd, + DJcy: DJcy, + DScy: DScy, + DZcy: DZcy, + Dagger: Dagger, + Darr: Darr, + Dashv: Dashv, + Dcaron: Dcaron, + Dcy: Dcy, + Del: Del, + Delta: Delta, + Dfr: Dfr, + DiacriticalAcute: DiacriticalAcute, + DiacriticalDot: DiacriticalDot, + DiacriticalDoubleAcute: DiacriticalDoubleAcute, + DiacriticalGrave: DiacriticalGrave, + DiacriticalTilde: DiacriticalTilde, + Diamond: Diamond, + DifferentialD: DifferentialD, + Dopf: Dopf, + Dot: Dot, + DotDot: DotDot, + DotEqual: DotEqual, + DoubleContourIntegral: DoubleContourIntegral, + DoubleDot: DoubleDot, + DoubleDownArrow: DoubleDownArrow, + DoubleLeftArrow: DoubleLeftArrow, + DoubleLeftRightArrow: DoubleLeftRightArrow, + DoubleLeftTee: DoubleLeftTee, + DoubleLongLeftArrow: DoubleLongLeftArrow, + DoubleLongLeftRightArrow: DoubleLongLeftRightArrow, + DoubleLongRightArrow: DoubleLongRightArrow, + DoubleRightArrow: DoubleRightArrow, + DoubleRightTee: DoubleRightTee, + DoubleUpArrow: DoubleUpArrow, + DoubleUpDownArrow: DoubleUpDownArrow, + DoubleVerticalBar: DoubleVerticalBar, + DownArrow: DownArrow, + DownArrowBar: DownArrowBar, + DownArrowUpArrow: DownArrowUpArrow, + DownBreve: DownBreve, + DownLeftRightVector: DownLeftRightVector, + DownLeftTeeVector: DownLeftTeeVector, + DownLeftVector: DownLeftVector, + DownLeftVectorBar: DownLeftVectorBar, + DownRightTeeVector: DownRightTeeVector, + DownRightVector: DownRightVector, + DownRightVectorBar: DownRightVectorBar, + DownTee: DownTee, + DownTeeArrow: DownTeeArrow, + Downarrow: Downarrow, + Dscr: Dscr, + Dstrok: Dstrok, + ENG: ENG, + ET: ET, + ETH: ETH, + Eacut: Eacut, + Eacute: Eacute, + Ecaron: Ecaron, + Ecir: Ecir, + Ecirc: Ecirc, + Ecy: Ecy, + Edot: Edot, + Efr: Efr, + Egrav: Egrav, + Egrave: Egrave, + Element: Element, + Emacr: Emacr, + EmptySmallSquare: EmptySmallSquare, + EmptyVerySmallSquare: EmptyVerySmallSquare, + Eogon: Eogon, + Eopf: Eopf, + Epsilon: Epsilon, + Equal: Equal, + EqualTilde: EqualTilde, + Equilibrium: Equilibrium, + Escr: Escr, + Esim: Esim, + Eta: Eta, + Eum: Eum, + Euml: Euml, + Exists: Exists, + ExponentialE: ExponentialE, + Fcy: Fcy, + Ffr: Ffr, + FilledSmallSquare: FilledSmallSquare, + FilledVerySmallSquare: FilledVerySmallSquare, + Fopf: Fopf, + ForAll: ForAll, + Fouriertrf: Fouriertrf, + Fscr: Fscr, + GJcy: GJcy, + G: G, + GT: GT, + Gamma: Gamma, + Gammad: Gammad, + Gbreve: Gbreve, + Gcedil: Gcedil, + Gcirc: Gcirc, + Gcy: Gcy, + Gdot: Gdot, + Gfr: Gfr, + Gg: Gg, + Gopf: Gopf, + GreaterEqual: GreaterEqual, + GreaterEqualLess: GreaterEqualLess, + GreaterFullEqual: GreaterFullEqual, + GreaterGreater: GreaterGreater, + GreaterLess: GreaterLess, + GreaterSlantEqual: GreaterSlantEqual, + GreaterTilde: GreaterTilde, + Gscr: Gscr, + Gt: Gt, + HARDcy: HARDcy, + Hacek: Hacek, + Hat: Hat, + Hcirc: Hcirc, + Hfr: Hfr, + HilbertSpace: HilbertSpace, + Hopf: Hopf, + HorizontalLine: HorizontalLine, + Hscr: Hscr, + Hstrok: Hstrok, + HumpDownHump: HumpDownHump, + HumpEqual: HumpEqual, + IEcy: IEcy, + IJlig: IJlig, + IOcy: IOcy, + Iacut: Iacut, + Iacute: Iacute, + Icir: Icir, + Icirc: Icirc, + Icy: Icy, + Idot: Idot, + Ifr: Ifr, + Igrav: Igrav, + Igrave: Igrave, + Im: Im, + Imacr: Imacr, + ImaginaryI: ImaginaryI, + Implies: Implies, + Int: Int, + Integral: Integral, + Intersection: Intersection, + InvisibleComma: InvisibleComma, + InvisibleTimes: InvisibleTimes, + Iogon: Iogon, + Iopf: Iopf, + Iota: Iota, + Iscr: Iscr, + Itilde: Itilde, + Iukcy: Iukcy, + Ium: Ium, + Iuml: Iuml, + Jcirc: Jcirc, + Jcy: Jcy, + Jfr: Jfr, + Jopf: Jopf, + Jscr: Jscr, + Jsercy: Jsercy, + Jukcy: Jukcy, + KHcy: KHcy, + KJcy: KJcy, + Kappa: Kappa, + Kcedil: Kcedil, + Kcy: Kcy, + Kfr: Kfr, + Kopf: Kopf, + Kscr: Kscr, + LJcy: LJcy, + L: L, + LT: LT, + Lacute: Lacute, + Lambda: Lambda, + Lang: Lang, + Laplacetrf: Laplacetrf, + Larr: Larr, + Lcaron: Lcaron, + Lcedil: Lcedil, + Lcy: Lcy, + LeftAngleBracket: LeftAngleBracket, + LeftArrow: LeftArrow, + LeftArrowBar: LeftArrowBar, + LeftArrowRightArrow: LeftArrowRightArrow, + LeftCeiling: LeftCeiling, + LeftDoubleBracket: LeftDoubleBracket, + LeftDownTeeVector: LeftDownTeeVector, + LeftDownVector: LeftDownVector, + LeftDownVectorBar: LeftDownVectorBar, + LeftFloor: LeftFloor, + LeftRightArrow: LeftRightArrow, + LeftRightVector: LeftRightVector, + LeftTee: LeftTee, + LeftTeeArrow: LeftTeeArrow, + LeftTeeVector: LeftTeeVector, + LeftTriangle: LeftTriangle, + LeftTriangleBar: LeftTriangleBar, + LeftTriangleEqual: LeftTriangleEqual, + LeftUpDownVector: LeftUpDownVector, + LeftUpTeeVector: LeftUpTeeVector, + LeftUpVector: LeftUpVector, + LeftUpVectorBar: LeftUpVectorBar, + LeftVector: LeftVector, + LeftVectorBar: LeftVectorBar, + Leftarrow: Leftarrow, + Leftrightarrow: Leftrightarrow, + LessEqualGreater: LessEqualGreater, + LessFullEqual: LessFullEqual, + LessGreater: LessGreater, + LessLess: LessLess, + LessSlantEqual: LessSlantEqual, + LessTilde: LessTilde, + Lfr: Lfr, + Ll: Ll, + Lleftarrow: Lleftarrow, + Lmidot: Lmidot, + LongLeftArrow: LongLeftArrow, + LongLeftRightArrow: LongLeftRightArrow, + LongRightArrow: LongRightArrow, + Longleftarrow: Longleftarrow, + Longleftrightarrow: Longleftrightarrow, + Longrightarrow: Longrightarrow, + Lopf: Lopf, + LowerLeftArrow: LowerLeftArrow, + LowerRightArrow: LowerRightArrow, + Lscr: Lscr, + Lsh: Lsh, + Lstrok: Lstrok, + Lt: Lt, + "Map": "⤅", + Mcy: Mcy, + MediumSpace: MediumSpace, + Mellintrf: Mellintrf, + Mfr: Mfr, + MinusPlus: MinusPlus, + Mopf: Mopf, + Mscr: Mscr, + Mu: Mu, + NJcy: NJcy, + Nacute: Nacute, + Ncaron: Ncaron, + Ncedil: Ncedil, + Ncy: Ncy, + NegativeMediumSpace: NegativeMediumSpace, + NegativeThickSpace: NegativeThickSpace, + NegativeThinSpace: NegativeThinSpace, + NegativeVeryThinSpace: NegativeVeryThinSpace, + NestedGreaterGreater: NestedGreaterGreater, + NestedLessLess: NestedLessLess, + NewLine: NewLine, + Nfr: Nfr, + NoBreak: NoBreak, + NonBreakingSpace: NonBreakingSpace, + Nopf: Nopf, + Not: Not, + NotCongruent: NotCongruent, + NotCupCap: NotCupCap, + NotDoubleVerticalBar: NotDoubleVerticalBar, + NotElement: NotElement, + NotEqual: NotEqual, + NotEqualTilde: NotEqualTilde, + NotExists: NotExists, + NotGreater: NotGreater, + NotGreaterEqual: NotGreaterEqual, + NotGreaterFullEqual: NotGreaterFullEqual, + NotGreaterGreater: NotGreaterGreater, + NotGreaterLess: NotGreaterLess, + NotGreaterSlantEqual: NotGreaterSlantEqual, + NotGreaterTilde: NotGreaterTilde, + NotHumpDownHump: NotHumpDownHump, + NotHumpEqual: NotHumpEqual, + NotLeftTriangle: NotLeftTriangle, + NotLeftTriangleBar: NotLeftTriangleBar, + NotLeftTriangleEqual: NotLeftTriangleEqual, + NotLess: NotLess, + NotLessEqual: NotLessEqual, + NotLessGreater: NotLessGreater, + NotLessLess: NotLessLess, + NotLessSlantEqual: NotLessSlantEqual, + NotLessTilde: NotLessTilde, + NotNestedGreaterGreater: NotNestedGreaterGreater, + NotNestedLessLess: NotNestedLessLess, + NotPrecedes: NotPrecedes, + NotPrecedesEqual: NotPrecedesEqual, + NotPrecedesSlantEqual: NotPrecedesSlantEqual, + NotReverseElement: NotReverseElement, + NotRightTriangle: NotRightTriangle, + NotRightTriangleBar: NotRightTriangleBar, + NotRightTriangleEqual: NotRightTriangleEqual, + NotSquareSubset: NotSquareSubset, + NotSquareSubsetEqual: NotSquareSubsetEqual, + NotSquareSuperset: NotSquareSuperset, + NotSquareSupersetEqual: NotSquareSupersetEqual, + NotSubset: NotSubset, + NotSubsetEqual: NotSubsetEqual, + NotSucceeds: NotSucceeds, + NotSucceedsEqual: NotSucceedsEqual, + NotSucceedsSlantEqual: NotSucceedsSlantEqual, + NotSucceedsTilde: NotSucceedsTilde, + NotSuperset: NotSuperset, + NotSupersetEqual: NotSupersetEqual, + NotTilde: NotTilde, + NotTildeEqual: NotTildeEqual, + NotTildeFullEqual: NotTildeFullEqual, + NotTildeTilde: NotTildeTilde, + NotVerticalBar: NotVerticalBar, + Nscr: Nscr, + Ntild: Ntild, + Ntilde: Ntilde, + Nu: Nu, + OElig: OElig, + Oacut: Oacut, + Oacute: Oacute, + Ocir: Ocir, + Ocirc: Ocirc, + Ocy: Ocy, + Odblac: Odblac, + Ofr: Ofr, + Ograv: Ograv, + Ograve: Ograve, + Omacr: Omacr, + Omega: Omega, + Omicron: Omicron, + Oopf: Oopf, + OpenCurlyDoubleQuote: OpenCurlyDoubleQuote, + OpenCurlyQuote: OpenCurlyQuote, + Or: Or, + Oscr: Oscr, + Oslas: Oslas, + Oslash: Oslash, + Otild: Otild, + Otilde: Otilde, + Otimes: Otimes, + Oum: Oum, + Ouml: Ouml, + OverBar: OverBar, + OverBrace: OverBrace, + OverBracket: OverBracket, + OverParenthesis: OverParenthesis, + PartialD: PartialD, + Pcy: Pcy, + Pfr: Pfr, + Phi: Phi, + Pi: Pi, + PlusMinus: PlusMinus, + Poincareplane: Poincareplane, + Popf: Popf, + Pr: Pr, + Precedes: Precedes, + PrecedesEqual: PrecedesEqual, + PrecedesSlantEqual: PrecedesSlantEqual, + PrecedesTilde: PrecedesTilde, + Prime: Prime, + Product: Product, + Proportion: Proportion, + Proportional: Proportional, + Pscr: Pscr, + Psi: Psi, + QUO: QUO, + QUOT: QUOT, + Qfr: Qfr, + Qopf: Qopf, + Qscr: Qscr, + RBarr: RBarr, + RE: RE, + REG: REG, + Racute: Racute, + Rang: Rang, + Rarr: Rarr, + Rarrtl: Rarrtl, + Rcaron: Rcaron, + Rcedil: Rcedil, + Rcy: Rcy, + Re: Re, + ReverseElement: ReverseElement, + ReverseEquilibrium: ReverseEquilibrium, + ReverseUpEquilibrium: ReverseUpEquilibrium, + Rfr: Rfr, + Rho: Rho, + RightAngleBracket: RightAngleBracket, + RightArrow: RightArrow, + RightArrowBar: RightArrowBar, + RightArrowLeftArrow: RightArrowLeftArrow, + RightCeiling: RightCeiling, + RightDoubleBracket: RightDoubleBracket, + RightDownTeeVector: RightDownTeeVector, + RightDownVector: RightDownVector, + RightDownVectorBar: RightDownVectorBar, + RightFloor: RightFloor, + RightTee: RightTee, + RightTeeArrow: RightTeeArrow, + RightTeeVector: RightTeeVector, + RightTriangle: RightTriangle, + RightTriangleBar: RightTriangleBar, + RightTriangleEqual: RightTriangleEqual, + RightUpDownVector: RightUpDownVector, + RightUpTeeVector: RightUpTeeVector, + RightUpVector: RightUpVector, + RightUpVectorBar: RightUpVectorBar, + RightVector: RightVector, + RightVectorBar: RightVectorBar, + Rightarrow: Rightarrow, + Ropf: Ropf, + RoundImplies: RoundImplies, + Rrightarrow: Rrightarrow, + Rscr: Rscr, + Rsh: Rsh, + RuleDelayed: RuleDelayed, + SHCHcy: SHCHcy, + SHcy: SHcy, + SOFTcy: SOFTcy, + Sacute: Sacute, + Sc: Sc, + Scaron: Scaron, + Scedil: Scedil, + Scirc: Scirc, + Scy: Scy, + Sfr: Sfr, + ShortDownArrow: ShortDownArrow, + ShortLeftArrow: ShortLeftArrow, + ShortRightArrow: ShortRightArrow, + ShortUpArrow: ShortUpArrow, + Sigma: Sigma, + SmallCircle: SmallCircle, + Sopf: Sopf, + Sqrt: Sqrt, + Square: Square, + SquareIntersection: SquareIntersection, + SquareSubset: SquareSubset, + SquareSubsetEqual: SquareSubsetEqual, + SquareSuperset: SquareSuperset, + SquareSupersetEqual: SquareSupersetEqual, + SquareUnion: SquareUnion, + Sscr: Sscr, + Star: Star, + Sub: Sub, + Subset: Subset, + SubsetEqual: SubsetEqual, + Succeeds: Succeeds, + SucceedsEqual: SucceedsEqual, + SucceedsSlantEqual: SucceedsSlantEqual, + SucceedsTilde: SucceedsTilde, + SuchThat: SuchThat, + Sum: Sum, + Sup: Sup, + Superset: Superset, + SupersetEqual: SupersetEqual, + Supset: Supset, + THOR: THOR, + THORN: THORN, + TRADE: TRADE, + TSHcy: TSHcy, + TScy: TScy, + Tab: Tab, + Tau: Tau, + Tcaron: Tcaron, + Tcedil: Tcedil, + Tcy: Tcy, + Tfr: Tfr, + Therefore: Therefore, + Theta: Theta, + ThickSpace: ThickSpace, + ThinSpace: ThinSpace, + Tilde: Tilde, + TildeEqual: TildeEqual, + TildeFullEqual: TildeFullEqual, + TildeTilde: TildeTilde, + Topf: Topf, + TripleDot: TripleDot, + Tscr: Tscr, + Tstrok: Tstrok, + Uacut: Uacut, + Uacute: Uacute, + Uarr: Uarr, + Uarrocir: Uarrocir, + Ubrcy: Ubrcy, + Ubreve: Ubreve, + Ucir: Ucir, + Ucirc: Ucirc, + Ucy: Ucy, + Udblac: Udblac, + Ufr: Ufr, + Ugrav: Ugrav, + Ugrave: Ugrave, + Umacr: Umacr, + UnderBar: UnderBar, + UnderBrace: UnderBrace, + UnderBracket: UnderBracket, + UnderParenthesis: UnderParenthesis, + Union: Union, + UnionPlus: UnionPlus, + Uogon: Uogon, + Uopf: Uopf, + UpArrow: UpArrow, + UpArrowBar: UpArrowBar, + UpArrowDownArrow: UpArrowDownArrow, + UpDownArrow: UpDownArrow, + UpEquilibrium: UpEquilibrium, + UpTee: UpTee, + UpTeeArrow: UpTeeArrow, + Uparrow: Uparrow, + Updownarrow: Updownarrow, + UpperLeftArrow: UpperLeftArrow, + UpperRightArrow: UpperRightArrow, + Upsi: Upsi, + Upsilon: Upsilon, + Uring: Uring, + Uscr: Uscr, + Utilde: Utilde, + Uum: Uum, + Uuml: Uuml, + VDash: VDash, + Vbar: Vbar, + Vcy: Vcy, + Vdash: Vdash, + Vdashl: Vdashl, + Vee: Vee, + Verbar: Verbar, + Vert: Vert, + VerticalBar: VerticalBar, + VerticalLine: VerticalLine, + VerticalSeparator: VerticalSeparator, + VerticalTilde: VerticalTilde, + VeryThinSpace: VeryThinSpace, + Vfr: Vfr, + Vopf: Vopf, + Vscr: Vscr, + Vvdash: Vvdash, + Wcirc: Wcirc, + Wedge: Wedge, + Wfr: Wfr, + Wopf: Wopf, + Wscr: Wscr, + Xfr: Xfr, + Xi: Xi, + Xopf: Xopf, + Xscr: Xscr, + YAcy: YAcy, + YIcy: YIcy, + YUcy: YUcy, + Yacut: Yacut, + Yacute: Yacute, + Ycirc: Ycirc, + Ycy: Ycy, + Yfr: Yfr, + Yopf: Yopf, + Yscr: Yscr, + Yuml: Yuml, + ZHcy: ZHcy, + Zacute: Zacute, + Zcaron: Zcaron, + Zcy: Zcy, + Zdot: Zdot, + ZeroWidthSpace: ZeroWidthSpace, + Zeta: Zeta, + Zfr: Zfr, + Zopf: Zopf, + Zscr: Zscr, + aacut: aacut, + aacute: aacute, + abreve: abreve, + ac: ac, + acE: acE, + acd: acd, + acir: acir, + acirc: acirc, + acut: acut, + acute: acute, + acy: acy, + aeli: aeli, + aelig: aelig, + af: af, + afr: afr, + agrav: agrav, + agrave: agrave, + alefsym: alefsym, + aleph: aleph, + alpha: alpha, + amacr: amacr, + amalg: amalg, + am: am, + amp: amp, + and: and, + andand: andand, + andd: andd, + andslope: andslope, + andv: andv, + ang: ang, + ange: ange, + angle: angle, + angmsd: angmsd, + angmsdaa: angmsdaa, + angmsdab: angmsdab, + angmsdac: angmsdac, + angmsdad: angmsdad, + angmsdae: angmsdae, + angmsdaf: angmsdaf, + angmsdag: angmsdag, + angmsdah: angmsdah, + angrt: angrt, + angrtvb: angrtvb, + angrtvbd: angrtvbd, + angsph: angsph, + angst: angst, + angzarr: angzarr, + aogon: aogon, + aopf: aopf, + ap: ap, + apE: apE, + apacir: apacir, + ape: ape, + apid: apid, + apos: apos, + approx: approx, + approxeq: approxeq, + arin: arin, + aring: aring, + ascr: ascr, + ast: ast, + asymp: asymp, + asympeq: asympeq, + atild: atild, + atilde: atilde, + aum: aum, + auml: auml, + awconint: awconint, + awint: awint, + bNot: bNot, + backcong: backcong, + backepsilon: backepsilon, + backprime: backprime, + backsim: backsim, + backsimeq: backsimeq, + barvee: barvee, + barwed: barwed, + barwedge: barwedge, + bbrk: bbrk, + bbrktbrk: bbrktbrk, + bcong: bcong, + bcy: bcy, + bdquo: bdquo, + becaus: becaus, + because: because, + bemptyv: bemptyv, + bepsi: bepsi, + bernou: bernou, + beta: beta, + beth: beth, + between: between, + bfr: bfr, + bigcap: bigcap, + bigcirc: bigcirc, + bigcup: bigcup, + bigodot: bigodot, + bigoplus: bigoplus, + bigotimes: bigotimes, + bigsqcup: bigsqcup, + bigstar: bigstar, + bigtriangledown: bigtriangledown, + bigtriangleup: bigtriangleup, + biguplus: biguplus, + bigvee: bigvee, + bigwedge: bigwedge, + bkarow: bkarow, + blacklozenge: blacklozenge, + blacksquare: blacksquare, + blacktriangle: blacktriangle, + blacktriangledown: blacktriangledown, + blacktriangleleft: blacktriangleleft, + blacktriangleright: blacktriangleright, + blank: blank, + blk12: blk12, + blk14: blk14, + blk34: blk34, + block: block, + bne: bne, + bnequiv: bnequiv, + bnot: bnot, + bopf: bopf, + bot: bot, + bottom: bottom, + bowtie: bowtie, + boxDL: boxDL, + boxDR: boxDR, + boxDl: boxDl, + boxDr: boxDr, + boxH: boxH, + boxHD: boxHD, + boxHU: boxHU, + boxHd: boxHd, + boxHu: boxHu, + boxUL: boxUL, + boxUR: boxUR, + boxUl: boxUl, + boxUr: boxUr, + boxV: boxV, + boxVH: boxVH, + boxVL: boxVL, + boxVR: boxVR, + boxVh: boxVh, + boxVl: boxVl, + boxVr: boxVr, + boxbox: boxbox, + boxdL: boxdL, + boxdR: boxdR, + boxdl: boxdl, + boxdr: boxdr, + boxh: boxh, + boxhD: boxhD, + boxhU: boxhU, + boxhd: boxhd, + boxhu: boxhu, + boxminus: boxminus, + boxplus: boxplus, + boxtimes: boxtimes, + boxuL: boxuL, + boxuR: boxuR, + boxul: boxul, + boxur: boxur, + boxv: boxv, + boxvH: boxvH, + boxvL: boxvL, + boxvR: boxvR, + boxvh: boxvh, + boxvl: boxvl, + boxvr: boxvr, + bprime: bprime, + breve: breve, + brvba: brvba, + brvbar: brvbar, + bscr: bscr, + bsemi: bsemi, + bsim: bsim, + bsime: bsime, + bsol: bsol, + bsolb: bsolb, + bsolhsub: bsolhsub, + bull: bull, + bullet: bullet, + bump: bump, + bumpE: bumpE, + bumpe: bumpe, + bumpeq: bumpeq, + cacute: cacute, + cap: cap, + capand: capand, + capbrcup: capbrcup, + capcap: capcap, + capcup: capcup, + capdot: capdot, + caps: caps, + caret: caret, + caron: caron, + ccaps: ccaps, + ccaron: ccaron, + ccedi: ccedi, + ccedil: ccedil, + ccirc: ccirc, + ccups: ccups, + ccupssm: ccupssm, + cdot: cdot, + cedi: cedi, + cedil: cedil, + cemptyv: cemptyv, + cen: cen, + cent: cent, + centerdot: centerdot, + cfr: cfr, + chcy: chcy, + check: check, + checkmark: checkmark, + chi: chi, + cir: cir, + cirE: cirE, + circ: circ, + circeq: circeq, + circlearrowleft: circlearrowleft, + circlearrowright: circlearrowright, + circledR: circledR, + circledS: circledS, + circledast: circledast, + circledcirc: circledcirc, + circleddash: circleddash, + cire: cire, + cirfnint: cirfnint, + cirmid: cirmid, + cirscir: cirscir, + clubs: clubs, + clubsuit: clubsuit, + colon: colon, + colone: colone, + coloneq: coloneq, + comma: comma, + commat: commat, + comp: comp, + compfn: compfn, + complement: complement, + complexes: complexes, + cong: cong, + congdot: congdot, + conint: conint, + copf: copf, + coprod: coprod, + cop: cop, + copy: copy, + copysr: copysr, + crarr: crarr, + cross: cross, + cscr: cscr, + csub: csub, + csube: csube, + csup: csup, + csupe: csupe, + ctdot: ctdot, + cudarrl: cudarrl, + cudarrr: cudarrr, + cuepr: cuepr, + cuesc: cuesc, + cularr: cularr, + cularrp: cularrp, + cup: cup, + cupbrcap: cupbrcap, + cupcap: cupcap, + cupcup: cupcup, + cupdot: cupdot, + cupor: cupor, + cups: cups, + curarr: curarr, + curarrm: curarrm, + curlyeqprec: curlyeqprec, + curlyeqsucc: curlyeqsucc, + curlyvee: curlyvee, + curlywedge: curlywedge, + curre: curre, + curren: curren, + curvearrowleft: curvearrowleft, + curvearrowright: curvearrowright, + cuvee: cuvee, + cuwed: cuwed, + cwconint: cwconint, + cwint: cwint, + cylcty: cylcty, + dArr: dArr, + dHar: dHar, + dagger: dagger, + daleth: daleth, + darr: darr, + dash: dash, + dashv: dashv, + dbkarow: dbkarow, + dblac: dblac, + dcaron: dcaron, + dcy: dcy, + dd: dd, + ddagger: ddagger, + ddarr: ddarr, + ddotseq: ddotseq, + de: de, + deg: deg, + delta: delta, + demptyv: demptyv, + dfisht: dfisht, + dfr: dfr, + dharl: dharl, + dharr: dharr, + diam: diam, + diamond: diamond, + diamondsuit: diamondsuit, + diams: diams, + die: die, + digamma: digamma, + disin: disin, + div: div, + divid: divid, + divide: divide, + divideontimes: divideontimes, + divonx: divonx, + djcy: djcy, + dlcorn: dlcorn, + dlcrop: dlcrop, + dollar: dollar, + dopf: dopf, + dot: dot, + doteq: doteq, + doteqdot: doteqdot, + dotminus: dotminus, + dotplus: dotplus, + dotsquare: dotsquare, + doublebarwedge: doublebarwedge, + downarrow: downarrow, + downdownarrows: downdownarrows, + downharpoonleft: downharpoonleft, + downharpoonright: downharpoonright, + drbkarow: drbkarow, + drcorn: drcorn, + drcrop: drcrop, + dscr: dscr, + dscy: dscy, + dsol: dsol, + dstrok: dstrok, + dtdot: dtdot, + dtri: dtri, + dtrif: dtrif, + duarr: duarr, + duhar: duhar, + dwangle: dwangle, + dzcy: dzcy, + dzigrarr: dzigrarr, + eDDot: eDDot, + eDot: eDot, + eacut: eacut, + eacute: eacute, + easter: easter, + ecaron: ecaron, + ecir: ecir, + ecirc: ecirc, + ecolon: ecolon, + ecy: ecy, + edot: edot, + ee: ee, + efDot: efDot, + efr: efr, + eg: eg, + egrav: egrav, + egrave: egrave, + egs: egs, + egsdot: egsdot, + el: el, + elinters: elinters, + ell: ell, + els: els, + elsdot: elsdot, + emacr: emacr, + empty: empty, + emptyset: emptyset, + emptyv: emptyv, + emsp13: emsp13, + emsp14: emsp14, + emsp: emsp, + eng: eng, + ensp: ensp, + eogon: eogon, + eopf: eopf, + epar: epar, + eparsl: eparsl, + eplus: eplus, + epsi: epsi, + epsilon: epsilon, + epsiv: epsiv, + eqcirc: eqcirc, + eqcolon: eqcolon, + eqsim: eqsim, + eqslantgtr: eqslantgtr, + eqslantless: eqslantless, + equals: equals, + equest: equest, + equiv: equiv, + equivDD: equivDD, + eqvparsl: eqvparsl, + erDot: erDot, + erarr: erarr, + escr: escr, + esdot: esdot, + esim: esim, + eta: eta, + et: et, + eth: eth, + eum: eum, + euml: euml, + euro: euro, + excl: excl, + exist: exist, + expectation: expectation, + exponentiale: exponentiale, + fallingdotseq: fallingdotseq, + fcy: fcy, + female: female, + ffilig: ffilig, + fflig: fflig, + ffllig: ffllig, + ffr: ffr, + filig: filig, + fjlig: fjlig, + flat: flat, + fllig: fllig, + fltns: fltns, + fnof: fnof, + fopf: fopf, + forall: forall, + fork: fork, + forkv: forkv, + fpartint: fpartint, + frac1: frac1, + frac12: frac12, + frac13: frac13, + frac14: frac14, + frac15: frac15, + frac16: frac16, + frac18: frac18, + frac23: frac23, + frac25: frac25, + frac3: frac3, + frac34: frac34, + frac35: frac35, + frac38: frac38, + frac45: frac45, + frac56: frac56, + frac58: frac58, + frac78: frac78, + frasl: frasl, + frown: frown, + fscr: fscr, + gE: gE, + gEl: gEl, + gacute: gacute, + gamma: gamma, + gammad: gammad, + gap: gap, + gbreve: gbreve, + gcirc: gcirc, + gcy: gcy, + gdot: gdot, + ge: ge, + gel: gel, + geq: geq, + geqq: geqq, + geqslant: geqslant, + ges: ges, + gescc: gescc, + gesdot: gesdot, + gesdoto: gesdoto, + gesdotol: gesdotol, + gesl: gesl, + gesles: gesles, + gfr: gfr, + gg: gg, + ggg: ggg, + gimel: gimel, + gjcy: gjcy, + gl: gl, + glE: glE, + gla: gla, + glj: glj, + gnE: gnE, + gnap: gnap, + gnapprox: gnapprox, + gne: gne, + gneq: gneq, + gneqq: gneqq, + gnsim: gnsim, + gopf: gopf, + grave: grave, + gscr: gscr, + gsim: gsim, + gsime: gsime, + gsiml: gsiml, + g: g, + gt: gt, + gtcc: gtcc, + gtcir: gtcir, + gtdot: gtdot, + gtlPar: gtlPar, + gtquest: gtquest, + gtrapprox: gtrapprox, + gtrarr: gtrarr, + gtrdot: gtrdot, + gtreqless: gtreqless, + gtreqqless: gtreqqless, + gtrless: gtrless, + gtrsim: gtrsim, + gvertneqq: gvertneqq, + gvnE: gvnE, + hArr: hArr, + hairsp: hairsp, + half: half, + hamilt: hamilt, + hardcy: hardcy, + harr: harr, + harrcir: harrcir, + harrw: harrw, + hbar: hbar, + hcirc: hcirc, + hearts: hearts, + heartsuit: heartsuit, + hellip: hellip, + hercon: hercon, + hfr: hfr, + hksearow: hksearow, + hkswarow: hkswarow, + hoarr: hoarr, + homtht: homtht, + hookleftarrow: hookleftarrow, + hookrightarrow: hookrightarrow, + hopf: hopf, + horbar: horbar, + hscr: hscr, + hslash: hslash, + hstrok: hstrok, + hybull: hybull, + hyphen: hyphen, + iacut: iacut, + iacute: iacute, + ic: ic, + icir: icir, + icirc: icirc, + icy: icy, + iecy: iecy, + iexc: iexc, + iexcl: iexcl, + iff: iff, + ifr: ifr, + igrav: igrav, + igrave: igrave, + ii: ii, + iiiint: iiiint, + iiint: iiint, + iinfin: iinfin, + iiota: iiota, + ijlig: ijlig, + imacr: imacr, + image: image, + imagline: imagline, + imagpart: imagpart, + imath: imath, + imof: imof, + imped: imped, + "in": "∈", + incare: incare, + infin: infin, + infintie: infintie, + inodot: inodot, + int: int, + intcal: intcal, + integers: integers, + intercal: intercal, + intlarhk: intlarhk, + intprod: intprod, + iocy: iocy, + iogon: iogon, + iopf: iopf, + iota: iota, + iprod: iprod, + iques: iques, + iquest: iquest, + iscr: iscr, + isin: isin, + isinE: isinE, + isindot: isindot, + isins: isins, + isinsv: isinsv, + isinv: isinv, + it: it, + itilde: itilde, + iukcy: iukcy, + ium: ium, + iuml: iuml, + jcirc: jcirc, + jcy: jcy, + jfr: jfr, + jmath: jmath, + jopf: jopf, + jscr: jscr, + jsercy: jsercy, + jukcy: jukcy, + kappa: kappa, + kappav: kappav, + kcedil: kcedil, + kcy: kcy, + kfr: kfr, + kgreen: kgreen, + khcy: khcy, + kjcy: kjcy, + kopf: kopf, + kscr: kscr, + lAarr: lAarr, + lArr: lArr, + lAtail: lAtail, + lBarr: lBarr, + lE: lE, + lEg: lEg, + lHar: lHar, + lacute: lacute, + laemptyv: laemptyv, + lagran: lagran, + lambda: lambda, + lang: lang, + langd: langd, + langle: langle, + lap: lap, + laqu: laqu, + laquo: laquo, + larr: larr, + larrb: larrb, + larrbfs: larrbfs, + larrfs: larrfs, + larrhk: larrhk, + larrlp: larrlp, + larrpl: larrpl, + larrsim: larrsim, + larrtl: larrtl, + lat: lat, + latail: latail, + late: late, + lates: lates, + lbarr: lbarr, + lbbrk: lbbrk, + lbrace: lbrace, + lbrack: lbrack, + lbrke: lbrke, + lbrksld: lbrksld, + lbrkslu: lbrkslu, + lcaron: lcaron, + lcedil: lcedil, + lceil: lceil, + lcub: lcub, + lcy: lcy, + ldca: ldca, + ldquo: ldquo, + ldquor: ldquor, + ldrdhar: ldrdhar, + ldrushar: ldrushar, + ldsh: ldsh, + le: le, + leftarrow: leftarrow, + leftarrowtail: leftarrowtail, + leftharpoondown: leftharpoondown, + leftharpoonup: leftharpoonup, + leftleftarrows: leftleftarrows, + leftrightarrow: leftrightarrow, + leftrightarrows: leftrightarrows, + leftrightharpoons: leftrightharpoons, + leftrightsquigarrow: leftrightsquigarrow, + leftthreetimes: leftthreetimes, + leg: leg, + leq: leq, + leqq: leqq, + leqslant: leqslant, + les: les, + lescc: lescc, + lesdot: lesdot, + lesdoto: lesdoto, + lesdotor: lesdotor, + lesg: lesg, + lesges: lesges, + lessapprox: lessapprox, + lessdot: lessdot, + lesseqgtr: lesseqgtr, + lesseqqgtr: lesseqqgtr, + lessgtr: lessgtr, + lesssim: lesssim, + lfisht: lfisht, + lfloor: lfloor, + lfr: lfr, + lg: lg, + lgE: lgE, + lhard: lhard, + lharu: lharu, + lharul: lharul, + lhblk: lhblk, + ljcy: ljcy, + ll: ll, + llarr: llarr, + llcorner: llcorner, + llhard: llhard, + lltri: lltri, + lmidot: lmidot, + lmoust: lmoust, + lmoustache: lmoustache, + lnE: lnE, + lnap: lnap, + lnapprox: lnapprox, + lne: lne, + lneq: lneq, + lneqq: lneqq, + lnsim: lnsim, + loang: loang, + loarr: loarr, + lobrk: lobrk, + longleftarrow: longleftarrow, + longleftrightarrow: longleftrightarrow, + longmapsto: longmapsto, + longrightarrow: longrightarrow, + looparrowleft: looparrowleft, + looparrowright: looparrowright, + lopar: lopar, + lopf: lopf, + loplus: loplus, + lotimes: lotimes, + lowast: lowast, + lowbar: lowbar, + loz: loz, + lozenge: lozenge, + lozf: lozf, + lpar: lpar, + lparlt: lparlt, + lrarr: lrarr, + lrcorner: lrcorner, + lrhar: lrhar, + lrhard: lrhard, + lrm: lrm, + lrtri: lrtri, + lsaquo: lsaquo, + lscr: lscr, + lsh: lsh, + lsim: lsim, + lsime: lsime, + lsimg: lsimg, + lsqb: lsqb, + lsquo: lsquo, + lsquor: lsquor, + lstrok: lstrok, + l: l, + lt: lt, + ltcc: ltcc, + ltcir: ltcir, + ltdot: ltdot, + lthree: lthree, + ltimes: ltimes, + ltlarr: ltlarr, + ltquest: ltquest, + ltrPar: ltrPar, + ltri: ltri, + ltrie: ltrie, + ltrif: ltrif, + lurdshar: lurdshar, + luruhar: luruhar, + lvertneqq: lvertneqq, + lvnE: lvnE, + mDDot: mDDot, + mac: mac, + macr: macr, + male: male, + malt: malt, + maltese: maltese, + map: map, + mapsto: mapsto, + mapstodown: mapstodown, + mapstoleft: mapstoleft, + mapstoup: mapstoup, + marker: marker, + mcomma: mcomma, + mcy: mcy, + mdash: mdash, + measuredangle: measuredangle, + mfr: mfr, + mho: mho, + micr: micr, + micro: micro, + mid: mid, + midast: midast, + midcir: midcir, + middo: middo, + middot: middot, + minus: minus, + minusb: minusb, + minusd: minusd, + minusdu: minusdu, + mlcp: mlcp, + mldr: mldr, + mnplus: mnplus, + models: models, + mopf: mopf, + mp: mp, + mscr: mscr, + mstpos: mstpos, + mu: mu, + multimap: multimap, + mumap: mumap, + nGg: nGg, + nGt: nGt, + nGtv: nGtv, + nLeftarrow: nLeftarrow, + nLeftrightarrow: nLeftrightarrow, + nLl: nLl, + nLt: nLt, + nLtv: nLtv, + nRightarrow: nRightarrow, + nVDash: nVDash, + nVdash: nVdash, + nabla: nabla, + nacute: nacute, + nang: nang, + nap: nap, + napE: napE, + napid: napid, + napos: napos, + napprox: napprox, + natur: natur, + natural: natural, + naturals: naturals, + nbs: nbs, + nbsp: nbsp, + nbump: nbump, + nbumpe: nbumpe, + ncap: ncap, + ncaron: ncaron, + ncedil: ncedil, + ncong: ncong, + ncongdot: ncongdot, + ncup: ncup, + ncy: ncy, + ndash: ndash, + ne: ne, + neArr: neArr, + nearhk: nearhk, + nearr: nearr, + nearrow: nearrow, + nedot: nedot, + nequiv: nequiv, + nesear: nesear, + nesim: nesim, + nexist: nexist, + nexists: nexists, + nfr: nfr, + ngE: ngE, + nge: nge, + ngeq: ngeq, + ngeqq: ngeqq, + ngeqslant: ngeqslant, + nges: nges, + ngsim: ngsim, + ngt: ngt, + ngtr: ngtr, + nhArr: nhArr, + nharr: nharr, + nhpar: nhpar, + ni: ni, + nis: nis, + nisd: nisd, + niv: niv, + njcy: njcy, + nlArr: nlArr, + nlE: nlE, + nlarr: nlarr, + nldr: nldr, + nle: nle, + nleftarrow: nleftarrow, + nleftrightarrow: nleftrightarrow, + nleq: nleq, + nleqq: nleqq, + nleqslant: nleqslant, + nles: nles, + nless: nless, + nlsim: nlsim, + nlt: nlt, + nltri: nltri, + nltrie: nltrie, + nmid: nmid, + nopf: nopf, + no: no, + not: not, + notin: notin, + notinE: notinE, + notindot: notindot, + notinva: notinva, + notinvb: notinvb, + notinvc: notinvc, + notni: notni, + notniva: notniva, + notnivb: notnivb, + notnivc: notnivc, + npar: npar, + nparallel: nparallel, + nparsl: nparsl, + npart: npart, + npolint: npolint, + npr: npr, + nprcue: nprcue, + npre: npre, + nprec: nprec, + npreceq: npreceq, + nrArr: nrArr, + nrarr: nrarr, + nrarrc: nrarrc, + nrarrw: nrarrw, + nrightarrow: nrightarrow, + nrtri: nrtri, + nrtrie: nrtrie, + nsc: nsc, + nsccue: nsccue, + nsce: nsce, + nscr: nscr, + nshortmid: nshortmid, + nshortparallel: nshortparallel, + nsim: nsim, + nsime: nsime, + nsimeq: nsimeq, + nsmid: nsmid, + nspar: nspar, + nsqsube: nsqsube, + nsqsupe: nsqsupe, + nsub: nsub, + nsubE: nsubE, + nsube: nsube, + nsubset: nsubset, + nsubseteq: nsubseteq, + nsubseteqq: nsubseteqq, + nsucc: nsucc, + nsucceq: nsucceq, + nsup: nsup, + nsupE: nsupE, + nsupe: nsupe, + nsupset: nsupset, + nsupseteq: nsupseteq, + nsupseteqq: nsupseteqq, + ntgl: ntgl, + ntild: ntild, + ntilde: ntilde, + ntlg: ntlg, + ntriangleleft: ntriangleleft, + ntrianglelefteq: ntrianglelefteq, + ntriangleright: ntriangleright, + ntrianglerighteq: ntrianglerighteq, + nu: nu, + num: num, + numero: numero, + numsp: numsp, + nvDash: nvDash, + nvHarr: nvHarr, + nvap: nvap, + nvdash: nvdash, + nvge: nvge, + nvgt: nvgt, + nvinfin: nvinfin, + nvlArr: nvlArr, + nvle: nvle, + nvlt: nvlt, + nvltrie: nvltrie, + nvrArr: nvrArr, + nvrtrie: nvrtrie, + nvsim: nvsim, + nwArr: nwArr, + nwarhk: nwarhk, + nwarr: nwarr, + nwarrow: nwarrow, + nwnear: nwnear, + oS: oS, + oacut: oacut, + oacute: oacute, + oast: oast, + ocir: ocir, + ocirc: ocirc, + ocy: ocy, + odash: odash, + odblac: odblac, + odiv: odiv, + odot: odot, + odsold: odsold, + oelig: oelig, + ofcir: ofcir, + ofr: ofr, + ogon: ogon, + ograv: ograv, + ograve: ograve, + ogt: ogt, + ohbar: ohbar, + ohm: ohm, + oint: oint, + olarr: olarr, + olcir: olcir, + olcross: olcross, + oline: oline, + olt: olt, + omacr: omacr, + omega: omega, + omicron: omicron, + omid: omid, + ominus: ominus, + oopf: oopf, + opar: opar, + operp: operp, + oplus: oplus, + or: or, + orarr: orarr, + ord: ord, + order: order, + orderof: orderof, + ordf: ordf, + ordm: ordm, + origof: origof, + oror: oror, + orslope: orslope, + orv: orv, + oscr: oscr, + oslas: oslas, + oslash: oslash, + osol: osol, + otild: otild, + otilde: otilde, + otimes: otimes, + otimesas: otimesas, + oum: oum, + ouml: ouml, + ovbar: ovbar, + par: par, + para: para, + parallel: parallel, + parsim: parsim, + parsl: parsl, + part: part, + pcy: pcy, + percnt: percnt, + period: period, + permil: permil, + perp: perp, + pertenk: pertenk, + pfr: pfr, + phi: phi, + phiv: phiv, + phmmat: phmmat, + phone: phone, + pi: pi, + pitchfork: pitchfork, + piv: piv, + planck: planck, + planckh: planckh, + plankv: plankv, + plus: plus, + plusacir: plusacir, + plusb: plusb, + pluscir: pluscir, + plusdo: plusdo, + plusdu: plusdu, + pluse: pluse, + plusm: plusm, + plusmn: plusmn, + plussim: plussim, + plustwo: plustwo, + pm: pm, + pointint: pointint, + popf: popf, + poun: poun, + pound: pound, + pr: pr, + prE: prE, + prap: prap, + prcue: prcue, + pre: pre, + prec: prec, + precapprox: precapprox, + preccurlyeq: preccurlyeq, + preceq: preceq, + precnapprox: precnapprox, + precneqq: precneqq, + precnsim: precnsim, + precsim: precsim, + prime: prime, + primes: primes, + prnE: prnE, + prnap: prnap, + prnsim: prnsim, + prod: prod, + profalar: profalar, + profline: profline, + profsurf: profsurf, + prop: prop, + propto: propto, + prsim: prsim, + prurel: prurel, + pscr: pscr, + psi: psi, + puncsp: puncsp, + qfr: qfr, + qint: qint, + qopf: qopf, + qprime: qprime, + qscr: qscr, + quaternions: quaternions, + quatint: quatint, + quest: quest, + questeq: questeq, + quo: quo, + quot: quot, + rAarr: rAarr, + rArr: rArr, + rAtail: rAtail, + rBarr: rBarr, + rHar: rHar, + race: race, + racute: racute, + radic: radic, + raemptyv: raemptyv, + rang: rang, + rangd: rangd, + range: range, + rangle: rangle, + raqu: raqu, + raquo: raquo, + rarr: rarr, + rarrap: rarrap, + rarrb: rarrb, + rarrbfs: rarrbfs, + rarrc: rarrc, + rarrfs: rarrfs, + rarrhk: rarrhk, + rarrlp: rarrlp, + rarrpl: rarrpl, + rarrsim: rarrsim, + rarrtl: rarrtl, + rarrw: rarrw, + ratail: ratail, + ratio: ratio, + rationals: rationals, + rbarr: rbarr, + rbbrk: rbbrk, + rbrace: rbrace, + rbrack: rbrack, + rbrke: rbrke, + rbrksld: rbrksld, + rbrkslu: rbrkslu, + rcaron: rcaron, + rcedil: rcedil, + rceil: rceil, + rcub: rcub, + rcy: rcy, + rdca: rdca, + rdldhar: rdldhar, + rdquo: rdquo, + rdquor: rdquor, + rdsh: rdsh, + real: real, + realine: realine, + realpart: realpart, + reals: reals, + rect: rect, + re: re$2, + reg: reg, + rfisht: rfisht, + rfloor: rfloor, + rfr: rfr, + rhard: rhard, + rharu: rharu, + rharul: rharul, + rho: rho, + rhov: rhov, + rightarrow: rightarrow, + rightarrowtail: rightarrowtail, + rightharpoondown: rightharpoondown, + rightharpoonup: rightharpoonup, + rightleftarrows: rightleftarrows, + rightleftharpoons: rightleftharpoons, + rightrightarrows: rightrightarrows, + rightsquigarrow: rightsquigarrow, + rightthreetimes: rightthreetimes, + ring: ring, + risingdotseq: risingdotseq, + rlarr: rlarr, + rlhar: rlhar, + rlm: rlm, + rmoust: rmoust, + rmoustache: rmoustache, + rnmid: rnmid, + roang: roang, + roarr: roarr, + robrk: robrk, + ropar: ropar, + ropf: ropf, + roplus: roplus, + rotimes: rotimes, + rpar: rpar, + rpargt: rpargt, + rppolint: rppolint, + rrarr: rrarr, + rsaquo: rsaquo, + rscr: rscr, + rsh: rsh, + rsqb: rsqb, + rsquo: rsquo, + rsquor: rsquor, + rthree: rthree, + rtimes: rtimes, + rtri: rtri, + rtrie: rtrie, + rtrif: rtrif, + rtriltri: rtriltri, + ruluhar: ruluhar, + rx: rx, + sacute: sacute, + sbquo: sbquo, + sc: sc, + scE: scE, + scap: scap, + scaron: scaron, + sccue: sccue, + sce: sce, + scedil: scedil, + scirc: scirc, + scnE: scnE, + scnap: scnap, + scnsim: scnsim, + scpolint: scpolint, + scsim: scsim, + scy: scy, + sdot: sdot, + sdotb: sdotb, + sdote: sdote, + seArr: seArr, + searhk: searhk, + searr: searr, + searrow: searrow, + sec: sec, + sect: sect, + semi: semi, + seswar: seswar, + setminus: setminus, + setmn: setmn, + sext: sext, + sfr: sfr, + sfrown: sfrown, + sharp: sharp, + shchcy: shchcy, + shcy: shcy, + shortmid: shortmid, + shortparallel: shortparallel, + sh: sh, + shy: shy, + sigma: sigma, + sigmaf: sigmaf, + sigmav: sigmav, + sim: sim, + simdot: simdot, + sime: sime, + simeq: simeq, + simg: simg, + simgE: simgE, + siml: siml, + simlE: simlE, + simne: simne, + simplus: simplus, + simrarr: simrarr, + slarr: slarr, + smallsetminus: smallsetminus, + smashp: smashp, + smeparsl: smeparsl, + smid: smid, + smile: smile, + smt: smt, + smte: smte, + smtes: smtes, + softcy: softcy, + sol: sol, + solb: solb, + solbar: solbar, + sopf: sopf, + spades: spades, + spadesuit: spadesuit, + spar: spar, + sqcap: sqcap, + sqcaps: sqcaps, + sqcup: sqcup, + sqcups: sqcups, + sqsub: sqsub, + sqsube: sqsube, + sqsubset: sqsubset, + sqsubseteq: sqsubseteq, + sqsup: sqsup, + sqsupe: sqsupe, + sqsupset: sqsupset, + sqsupseteq: sqsupseteq, + squ: squ, + square: square, + squarf: squarf, + squf: squf, + srarr: srarr, + sscr: sscr, + ssetmn: ssetmn, + ssmile: ssmile, + sstarf: sstarf, + star: star, + starf: starf, + straightepsilon: straightepsilon, + straightphi: straightphi, + strns: strns, + sub: sub, + subE: subE, + subdot: subdot, + sube: sube, + subedot: subedot, + submult: submult, + subnE: subnE, + subne: subne, + subplus: subplus, + subrarr: subrarr, + subset: subset, + subseteq: subseteq, + subseteqq: subseteqq, + subsetneq: subsetneq, + subsetneqq: subsetneqq, + subsim: subsim, + subsub: subsub, + subsup: subsup, + succ: succ, + succapprox: succapprox, + succcurlyeq: succcurlyeq, + succeq: succeq, + succnapprox: succnapprox, + succneqq: succneqq, + succnsim: succnsim, + succsim: succsim, + sum: sum, + sung: sung, + sup: sup, + sup1: sup1, + sup2: sup2, + sup3: sup3, + supE: supE, + supdot: supdot, + supdsub: supdsub, + supe: supe, + supedot: supedot, + suphsol: suphsol, + suphsub: suphsub, + suplarr: suplarr, + supmult: supmult, + supnE: supnE, + supne: supne, + supplus: supplus, + supset: supset, + supseteq: supseteq, + supseteqq: supseteqq, + supsetneq: supsetneq, + supsetneqq: supsetneqq, + supsim: supsim, + supsub: supsub, + supsup: supsup, + swArr: swArr, + swarhk: swarhk, + swarr: swarr, + swarrow: swarrow, + swnwar: swnwar, + szli: szli, + szlig: szlig, + target: target, + tau: tau, + tbrk: tbrk, + tcaron: tcaron, + tcedil: tcedil, + tcy: tcy, + tdot: tdot, + telrec: telrec, + tfr: tfr, + there4: there4, + therefore: therefore, + theta: theta, + thetasym: thetasym, + thetav: thetav, + thickapprox: thickapprox, + thicksim: thicksim, + thinsp: thinsp, + thkap: thkap, + thksim: thksim, + thor: thor, + thorn: thorn, + tilde: tilde, + time: time, + times: times, + timesb: timesb, + timesbar: timesbar, + timesd: timesd, + tint: tint, + toea: toea, + top: top, + topbot: topbot, + topcir: topcir, + topf: topf, + topfork: topfork, + tosa: tosa, + tprime: tprime, + trade: trade, + triangle: triangle, + triangledown: triangledown, + triangleleft: triangleleft, + trianglelefteq: trianglelefteq, + triangleq: triangleq, + triangleright: triangleright, + trianglerighteq: trianglerighteq, + tridot: tridot, + trie: trie, + triminus: triminus, + triplus: triplus, + trisb: trisb, + tritime: tritime, + trpezium: trpezium, + tscr: tscr, + tscy: tscy, + tshcy: tshcy, + tstrok: tstrok, + twixt: twixt, + twoheadleftarrow: twoheadleftarrow, + twoheadrightarrow: twoheadrightarrow, + uArr: uArr, + uHar: uHar, + uacut: uacut, + uacute: uacute, + uarr: uarr, + ubrcy: ubrcy, + ubreve: ubreve, + ucir: ucir, + ucirc: ucirc, + ucy: ucy, + udarr: udarr, + udblac: udblac, + udhar: udhar, + ufisht: ufisht, + ufr: ufr, + ugrav: ugrav, + ugrave: ugrave, + uharl: uharl, + uharr: uharr, + uhblk: uhblk, + ulcorn: ulcorn, + ulcorner: ulcorner, + ulcrop: ulcrop, + ultri: ultri, + umacr: umacr, + um: um, + uml: uml, + uogon: uogon, + uopf: uopf, + uparrow: uparrow, + updownarrow: updownarrow, + upharpoonleft: upharpoonleft, + upharpoonright: upharpoonright, + uplus: uplus, + upsi: upsi, + upsih: upsih, + upsilon: upsilon, + upuparrows: upuparrows, + urcorn: urcorn, + urcorner: urcorner, + urcrop: urcrop, + uring: uring, + urtri: urtri, + uscr: uscr, + utdot: utdot, + utilde: utilde, + utri: utri, + utrif: utrif, + uuarr: uuarr, + uum: uum, + uuml: uuml, + uwangle: uwangle, + vArr: vArr, + vBar: vBar, + vBarv: vBarv, + vDash: vDash, + vangrt: vangrt, + varepsilon: varepsilon, + varkappa: varkappa, + varnothing: varnothing, + varphi: varphi, + varpi: varpi, + varpropto: varpropto, + varr: varr, + varrho: varrho, + varsigma: varsigma, + varsubsetneq: varsubsetneq, + varsubsetneqq: varsubsetneqq, + varsupsetneq: varsupsetneq, + varsupsetneqq: varsupsetneqq, + vartheta: vartheta, + vartriangleleft: vartriangleleft, + vartriangleright: vartriangleright, + vcy: vcy, + vdash: vdash, + vee: vee, + veebar: veebar, + veeeq: veeeq, + vellip: vellip, + verbar: verbar, + vert: vert, + vfr: vfr, + vltri: vltri, + vnsub: vnsub, + vnsup: vnsup, + vopf: vopf, + vprop: vprop, + vrtri: vrtri, + vscr: vscr, + vsubnE: vsubnE, + vsubne: vsubne, + vsupnE: vsupnE, + vsupne: vsupne, + vzigzag: vzigzag, + wcirc: wcirc, + wedbar: wedbar, + wedge: wedge, + wedgeq: wedgeq, + weierp: weierp, + wfr: wfr, + wopf: wopf, + wp: wp, + wr: wr, + wreath: wreath, + wscr: wscr, + xcap: xcap, + xcirc: xcirc, + xcup: xcup, + xdtri: xdtri, + xfr: xfr, + xhArr: xhArr, + xharr: xharr, + xi: xi, + xlArr: xlArr, + xlarr: xlarr, + xmap: xmap, + xnis: xnis, + xodot: xodot, + xopf: xopf, + xoplus: xoplus, + xotime: xotime, + xrArr: xrArr, + xrarr: xrarr, + xscr: xscr, + xsqcup: xsqcup, + xuplus: xuplus, + xutri: xutri, + xvee: xvee, + xwedge: xwedge, + yacut: yacut, + yacute: yacute, + yacy: yacy, + ycirc: ycirc, + ycy: ycy, + ye: ye, + yen: yen, + yfr: yfr, + yicy: yicy, + yopf: yopf, + yscr: yscr, + yucy: yucy, + yum: yum, + yuml: yuml, + zacute: zacute, + zcaron: zcaron, + zcy: zcy, + zdot: zdot, + zeetrf: zeetrf, + zeta: zeta, + zfr: zfr, + zhcy: zhcy, + zigrarr: zigrarr, + zopf: zopf, + zscr: zscr, + zwj: zwj, + zwnj: zwnj +}; + +var decodeEntity_1 = decodeEntity; + +var own$2 = {}.hasOwnProperty; + +function decodeEntity(characters) { + return own$2.call(characterEntities, characters) + ? characterEntities[characters] + : false +} + +var parseEntities_1 = parseEntities; + +var own$1 = {}.hasOwnProperty; +var fromCharCode = String.fromCharCode; +var noop = Function.prototype; + +// Default settings. +var defaults$2 = { + warning: null, + reference: null, + text: null, + warningContext: null, + referenceContext: null, + textContext: null, + position: {}, + additional: null, + attribute: false, + nonTerminated: true +}; + +// Characters. +var tab = 9; // '\t' +var lineFeed = 10; // '\n' +var formFeed = 12; // '\f' +var space = 32; // ' ' +var ampersand = 38; // '&' +var semicolon = 59; // ';' +var lessThan = 60; // '<' +var equalsTo = 61; // '=' +var numberSign = 35; // '#' +var uppercaseX = 88; // 'X' +var lowercaseX = 120; // 'x' +var replacementCharacter = 65533; // '�' + +// Reference types. +var name = 'named'; +var hexa = 'hexadecimal'; +var deci = 'decimal'; + +// Map of bases. +var bases = {}; + +bases[hexa] = 16; +bases[deci] = 10; + +// Map of types to tests. +// Each type of character reference accepts different characters. +// This test is used to detect whether a reference has ended (as the semicolon +// is not strictly needed). +var tests = {}; + +tests[name] = isAlphanumerical; +tests[deci] = isDecimal; +tests[hexa] = isHexadecimal; + +// Warning types. +var namedNotTerminated = 1; +var numericNotTerminated = 2; +var namedEmpty = 3; +var numericEmpty = 4; +var namedUnknown = 5; +var numericDisallowed = 6; +var numericProhibited = 7; + +// Warning messages. +var messages = {}; + +messages[namedNotTerminated] = + 'Named character references must be terminated by a semicolon'; +messages[numericNotTerminated] = + 'Numeric character references must be terminated by a semicolon'; +messages[namedEmpty] = 'Named character references cannot be empty'; +messages[numericEmpty] = 'Numeric character references cannot be empty'; +messages[namedUnknown] = 'Named character references must be known'; +messages[numericDisallowed] = + 'Numeric character references cannot be disallowed'; +messages[numericProhibited] = + 'Numeric character references cannot be outside the permissible Unicode range'; + +// Wrap to ensure clean parameters are given to `parse`. +function parseEntities(value, options) { + var settings = {}; + var option; + var key; + + if (!options) { + options = {}; + } + + for (key in defaults$2) { + option = options[key]; + settings[key] = + option === null || option === undefined ? defaults$2[key] : option; + } + + if (settings.position.indent || settings.position.start) { + settings.indent = settings.position.indent || []; + settings.position = settings.position.start; + } + + return parse$2(value, settings) +} + +// Parse entities. +// eslint-disable-next-line complexity +function parse$2(value, settings) { + var additional = settings.additional; + var nonTerminated = settings.nonTerminated; + var handleText = settings.text; + var handleReference = settings.reference; + var handleWarning = settings.warning; + var textContext = settings.textContext; + var referenceContext = settings.referenceContext; + var warningContext = settings.warningContext; + var pos = settings.position; + var indent = settings.indent || []; + var length = value.length; + var index = 0; + var lines = -1; + var column = pos.column || 1; + var line = pos.line || 1; + var queue = ''; + var result = []; + var entityCharacters; + var namedEntity; + var terminated; + var characters; + var character; + var reference; + var following; + var warning; + var reason; + var output; + var entity; + var begin; + var start; + var type; + var test; + var prev; + var next; + var diff; + var end; + + if (typeof additional === 'string') { + additional = additional.charCodeAt(0); + } + + // Cache the current point. + prev = now(); + + // Wrap `handleWarning`. + warning = handleWarning ? parseError : noop; + + // Ensure the algorithm walks over the first character and the end (inclusive). + index--; + length++; + + while (++index < length) { + // If the previous character was a newline. + if (character === lineFeed) { + column = indent[lines] || 1; + } + + character = value.charCodeAt(index); + + if (character === ampersand) { + following = value.charCodeAt(index + 1); + + // The behaviour depends on the identity of the next character. + if ( + following === tab || + following === lineFeed || + following === formFeed || + following === space || + following === ampersand || + following === lessThan || + following !== following || + (additional && following === additional) + ) { + // Not a character reference. + // No characters are consumed, and nothing is returned. + // This is not an error, either. + queue += fromCharCode(character); + column++; + + continue + } + + start = index + 1; + begin = start; + end = start; + + if (following === numberSign) { + // Numerical entity. + end = ++begin; + + // The behaviour further depends on the next character. + following = value.charCodeAt(end); + + if (following === uppercaseX || following === lowercaseX) { + // ASCII hex digits. + type = hexa; + end = ++begin; + } else { + // ASCII digits. + type = deci; + } + } else { + // Named entity. + type = name; + } + + entityCharacters = ''; + entity = ''; + characters = ''; + test = tests[type]; + end--; + + while (++end < length) { + following = value.charCodeAt(end); + + if (!test(following)) { + break + } + + characters += fromCharCode(following); + + // Check if we can match a legacy named reference. + // If so, we cache that as the last viable named reference. + // This ensures we do not need to walk backwards later. + if (type === name && own$1.call(legacy, characters)) { + entityCharacters = characters; + entity = legacy[characters]; + } + } + + terminated = value.charCodeAt(end) === semicolon; + + if (terminated) { + end++; + + namedEntity = type === name ? decodeEntity_1(characters) : false; + + if (namedEntity) { + entityCharacters = characters; + entity = namedEntity; + } + } + + diff = 1 + end - start; + + if (!terminated && !nonTerminated) ; else if (!characters) { + // An empty (possible) entity is valid, unless it’s numeric (thus an + // ampersand followed by an octothorp). + if (type !== name) { + warning(numericEmpty, diff); + } + } else if (type === name) { + // An ampersand followed by anything unknown, and not terminated, is + // invalid. + if (terminated && !entity) { + warning(namedUnknown, 1); + } else { + // If theres something after an entity name which is not known, cap + // the reference. + if (entityCharacters !== characters) { + end = begin + entityCharacters.length; + diff = 1 + end - begin; + terminated = false; + } + + // If the reference is not terminated, warn. + if (!terminated) { + reason = entityCharacters ? namedNotTerminated : namedEmpty; + + if (settings.attribute) { + following = value.charCodeAt(end); + + if (following === equalsTo) { + warning(reason, diff); + entity = null; + } else if (isAlphanumerical(following)) { + entity = null; + } else { + warning(reason, diff); + } + } else { + warning(reason, diff); + } + } + } + + reference = entity; + } else { + if (!terminated) { + // All non-terminated numeric entities are not rendered, and trigger a + // warning. + warning(numericNotTerminated, diff); + } + + // When terminated and number, parse as either hexadecimal or decimal. + reference = parseInt(characters, bases[type]); + + // Trigger a warning when the parsed number is prohibited, and replace + // with replacement character. + if (prohibited(reference)) { + warning(numericProhibited, diff); + reference = fromCharCode(replacementCharacter); + } else if (reference in invalid) { + // Trigger a warning when the parsed number is disallowed, and replace + // by an alternative. + warning(numericDisallowed, diff); + reference = invalid[reference]; + } else { + // Parse the number. + output = ''; + + // Trigger a warning when the parsed number should not be used. + if (disallowed(reference)) { + warning(numericDisallowed, diff); + } + + // Stringify the number. + if (reference > 0xffff) { + reference -= 0x10000; + output += fromCharCode((reference >>> (10 & 0x3ff)) | 0xd800); + reference = 0xdc00 | (reference & 0x3ff); + } + + reference = output + fromCharCode(reference); + } + } + + // Found it! + // First eat the queued characters as normal text, then eat an entity. + if (reference) { + flush(); + + prev = now(); + index = end - 1; + column += end - start + 1; + result.push(reference); + next = now(); + next.offset++; + + if (handleReference) { + handleReference.call( + referenceContext, + reference, + {start: prev, end: next}, + value.slice(start - 1, end) + ); + } + + prev = next; + } else { + // If we could not find a reference, queue the checked characters (as + // normal characters), and move the pointer to their end. + // This is possible because we can be certain neither newlines nor + // ampersands are included. + characters = value.slice(start - 1, end); + queue += characters; + column += characters.length; + index = end - 1; + } + } else { + // Handle anything other than an ampersand, including newlines and EOF. + if ( + character === 10 // Line feed + ) { + line++; + lines++; + column = 0; + } + + if (character === character) { + queue += fromCharCode(character); + column++; + } else { + flush(); + } + } + } + + // Return the reduced nodes, and any possible warnings. + return result.join('') + + // Get current position. + function now() { + return { + line: line, + column: column, + offset: index + (pos.offset || 0) + } + } + + // “Throw” a parse-error: a warning. + function parseError(code, offset) { + var position = now(); + + position.column += offset; + position.offset += offset; + + handleWarning.call(warningContext, messages[code], position, code); + } + + // Flush `queue` (normal text). + // Macro invoked before each entity and at the end of `value`. + // Does nothing when `queue` is empty. + function flush() { + if (queue) { + result.push(queue); + + if (handleText) { + handleText.call(textContext, queue, {start: prev, end: now()}); + } + + queue = ''; + } + } +} + +// Check if `character` is outside the permissible unicode range. +function prohibited(code) { + return (code >= 0xd800 && code <= 0xdfff) || code > 0x10ffff +} + +// Check if `character` is disallowed. +function disallowed(code) { + return ( + (code >= 0x0001 && code <= 0x0008) || + code === 0x000b || + (code >= 0x000d && code <= 0x001f) || + (code >= 0x007f && code <= 0x009f) || + (code >= 0xfdd0 && code <= 0xfdef) || + (code & 0xffff) === 0xffff || + (code & 0xffff) === 0xfffe + ) +} + +var decode = factory$1; + +/* Factory to create an entity decoder. */ +function factory$1(ctx) { + decoder.raw = decodeRaw; + + return decoder; + + /* Normalize `position` to add an `indent`. */ + function normalize(position) { + var offsets = ctx.offset; + var line = position.line; + var result = []; + + while (++line) { + if (!(line in offsets)) { + break; + } + + result.push((offsets[line] || 0) + 1); + } + + return { + start: position, + indent: result + }; + } + + /* Handle a warning. + * See https://github.com/wooorm/parse-entities + * for the warnings. */ + function handleWarning(reason, position, code) { + if (code === 3) { + return; + } + + ctx.file.message(reason, position); + } + + /* Decode `value` (at `position`) into text-nodes. */ + function decoder(value, position, handler) { + parseEntities_1(value, { + position: normalize(position), + warning: handleWarning, + text: handler, + reference: handler, + textContext: ctx, + referenceContext: ctx + }); + } + + /* Decode `value` (at `position`) into a string. */ + function decodeRaw(value, position, options) { + return parseEntities_1(value, immutable(options, { + position: normalize(position), + warning: handleWarning + })); + } +} + +var tokenizer = factory; + +var MERGEABLE_NODES = { + text: mergeText, + blockquote: mergeBlockquote +}; + +/* Check whether a node is mergeable with adjacent nodes. */ +function mergeable(node) { + var start; + var end; + + if (node.type !== 'text' || !node.position) { + return true; + } + + start = node.position.start; + end = node.position.end; + + /* Only merge nodes which occupy the same size as their + * `value`. */ + return start.line !== end.line || + end.column - start.column === node.value.length; +} + +/* Merge two text nodes: `node` into `prev`. */ +function mergeText(prev, node) { + prev.value += node.value; + + return prev; +} + +/* Merge two blockquotes: `node` into `prev`, unless in + * CommonMark mode. */ +function mergeBlockquote(prev, node) { + if (this.options.commonmark) { + return node; + } + + prev.children = prev.children.concat(node.children); + + return prev; +} + +/* Construct a tokenizer. This creates both + * `tokenizeInline` and `tokenizeBlock`. */ +function factory(type) { + return tokenize; + + /* Tokenizer for a bound `type`. */ + function tokenize(value, location) { + var self = this; + var offset = self.offset; + var tokens = []; + var methods = self[type + 'Methods']; + var tokenizers = self[type + 'Tokenizers']; + var line = location.line; + var column = location.column; + var index; + var length; + var method; + var name; + var matched; + var valueLength; + + /* Trim white space only lines. */ + if (!value) { + return tokens; + } + + /* Expose on `eat`. */ + eat.now = now; + eat.file = self.file; + + /* Sync initial offset. */ + updatePosition(''); + + /* Iterate over `value`, and iterate over all + * tokenizers. When one eats something, re-iterate + * with the remaining value. If no tokenizer eats, + * something failed (should not happen) and an + * exception is thrown. */ + while (value) { + index = -1; + length = methods.length; + matched = false; + + while (++index < length) { + name = methods[index]; + method = tokenizers[name]; + + if ( + method && + /* istanbul ignore next */ (!method.onlyAtStart || self.atStart) && + (!method.notInList || !self.inList) && + (!method.notInBlock || !self.inBlock) && + (!method.notInLink || !self.inLink) + ) { + valueLength = value.length; + + method.apply(self, [eat, value]); + + matched = valueLength !== value.length; + + if (matched) { + break; + } + } + } + + /* istanbul ignore if */ + if (!matched) { + self.file.fail(new Error('Infinite loop'), eat.now()); + } + } + + self.eof = now(); + + return tokens; + + /* Update line, column, and offset based on + * `value`. */ + function updatePosition(subvalue) { + var lastIndex = -1; + var index = subvalue.indexOf('\n'); + + while (index !== -1) { + line++; + lastIndex = index; + index = subvalue.indexOf('\n', index + 1); + } + + if (lastIndex === -1) { + column += subvalue.length; + } else { + column = subvalue.length - lastIndex; + } + + if (line in offset) { + if (lastIndex !== -1) { + column += offset[line]; + } else if (column <= offset[line]) { + column = offset[line] + 1; + } + } + } + + /* Get offset. Called before the first character is + * eaten to retrieve the range's offsets. */ + function getOffset() { + var indentation = []; + var pos = line + 1; + + /* Done. Called when the last character is + * eaten to retrieve the range’s offsets. */ + return function () { + var last = line + 1; + + while (pos < last) { + indentation.push((offset[pos] || 0) + 1); + + pos++; + } + + return indentation; + }; + } + + /* Get the current position. */ + function now() { + var pos = {line: line, column: column}; + + pos.offset = self.toOffset(pos); + + return pos; + } + + /* Store position information for a node. */ + function Position(start) { + this.start = start; + this.end = now(); + } + + /* Throw when a value is incorrectly eaten. + * This shouldn’t happen but will throw on new, + * incorrect rules. */ + function validateEat(subvalue) { + /* istanbul ignore if */ + if (value.substring(0, subvalue.length) !== subvalue) { + /* Capture stack-trace. */ + self.file.fail( + new Error( + 'Incorrectly eaten value: please report this ' + + 'warning on http://git.io/vg5Ft' + ), + now() + ); + } + } + + /* Mark position and patch `node.position`. */ + function position() { + var before = now(); + + return update; + + /* Add the position to a node. */ + function update(node, indent) { + var prev = node.position; + var start = prev ? prev.start : before; + var combined = []; + var n = prev && prev.end.line; + var l = before.line; + + node.position = new Position(start); + + /* If there was already a `position`, this + * node was merged. Fixing `start` wasn’t + * hard, but the indent is different. + * Especially because some information, the + * indent between `n` and `l` wasn’t + * tracked. Luckily, that space is + * (should be?) empty, so we can safely + * check for it now. */ + if (prev && indent && prev.indent) { + combined = prev.indent; + + if (n < l) { + while (++n < l) { + combined.push((offset[n] || 0) + 1); + } + + combined.push(before.column); + } + + indent = combined.concat(indent); + } + + node.position.indent = indent || []; + + return node; + } + } + + /* Add `node` to `parent`s children or to `tokens`. + * Performs merges where possible. */ + function add(node, parent) { + var children = parent ? parent.children : tokens; + var prev = children[children.length - 1]; + + if ( + prev && + node.type === prev.type && + node.type in MERGEABLE_NODES && + mergeable(prev) && + mergeable(node) + ) { + node = MERGEABLE_NODES[node.type].call(self, prev, node); + } + + if (node !== prev) { + children.push(node); + } + + if (self.atStart && tokens.length !== 0) { + self.exitStart(); + } + + return node; + } + + /* Remove `subvalue` from `value`. + * `subvalue` must be at the start of `value`. */ + function eat(subvalue) { + var indent = getOffset(); + var pos = position(); + var current = now(); + + validateEat(subvalue); + + apply.reset = reset; + reset.test = test; + apply.test = test; + + value = value.substring(subvalue.length); + + updatePosition(subvalue); + + indent = indent(); + + return apply; + + /* Add the given arguments, add `position` to + * the returned node, and return the node. */ + function apply(node, parent) { + return pos(add(pos(node), parent), indent); + } + + /* Functions just like apply, but resets the + * content: the line and column are reversed, + * and the eaten value is re-added. + * This is useful for nodes with a single + * type of content, such as lists and tables. + * See `apply` above for what parameters are + * expected. */ + function reset() { + var node = apply.apply(null, arguments); + + line = current.line; + column = current.column; + value = subvalue + value; + + return node; + } + + /* Test the position, after eating, and reverse + * to a not-eaten state. */ + function test() { + var result = pos({}); + + line = current.line; + column = current.column; + value = subvalue + value; + + return result.position; + } + } + } +} + +var markdownEscapes = escapes; + +var defaults$1 = [ + '\\', + '`', + '*', + '{', + '}', + '[', + ']', + '(', + ')', + '#', + '+', + '-', + '.', + '!', + '_', + '>' +]; + +var gfm = defaults$1.concat(['~', '|']); + +var commonmark = gfm.concat([ + '\n', + '"', + '$', + '%', + '&', + "'", + ',', + '/', + ':', + ';', + '<', + '=', + '?', + '@', + '^' +]); + +escapes.default = defaults$1; +escapes.gfm = gfm; +escapes.commonmark = commonmark; + +// Get markdown escapes. +function escapes(options) { + var settings = options || {}; + + if (settings.commonmark) { + return commonmark + } + + return settings.gfm ? gfm : defaults$1 +} + +var require$$0 = [ + "address", + "article", + "aside", + "base", + "basefont", + "blockquote", + "body", + "caption", + "center", + "col", + "colgroup", + "dd", + "details", + "dialog", + "dir", + "div", + "dl", + "dt", + "fieldset", + "figcaption", + "figure", + "footer", + "form", + "frame", + "frameset", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "head", + "header", + "hgroup", + "hr", + "html", + "iframe", + "legend", + "li", + "link", + "main", + "menu", + "menuitem", + "meta", + "nav", + "noframes", + "ol", + "optgroup", + "option", + "p", + "param", + "pre", + "section", + "source", + "title", + "summary", + "table", + "tbody", + "td", + "tfoot", + "th", + "thead", + "title", + "tr", + "track", + "ul" +]; + +var defaults = { + position: true, + gfm: true, + commonmark: false, + footnotes: false, + pedantic: false, + blocks: require$$0 +}; + +var setOptions_1 = setOptions; + +function setOptions(options) { + var self = this; + var current = self.options; + var key; + var value; + + if (options == null) { + options = {}; + } else if (typeof options === 'object') { + options = immutable(options); + } else { + throw new Error( + 'Invalid value `' + options + '` ' + + 'for setting `options`' + ); + } + + for (key in defaults) { + value = options[key]; + + if (value == null) { + value = current[key]; + } + + if ( + (key !== 'blocks' && typeof value !== 'boolean') || + (key === 'blocks' && typeof value !== 'object') + ) { + throw new Error('Invalid value `' + value + '` for setting `options.' + key + '`'); + } + + options[key] = value; + } + + self.options = options; + self.escape = markdownEscapes(options); + + return self; +} + +var convert_1 = convert; + +function convert(test) { + if (typeof test === 'string') { + return typeFactory(test) + } + + if (test === null || test === undefined) { + return ok + } + + if (typeof test === 'object') { + return ('length' in test ? anyFactory : matchesFactory)(test) + } + + if (typeof test === 'function') { + return test + } + + throw new Error('Expected function, string, or object as test') +} + +function convertAll(tests) { + var results = []; + var length = tests.length; + var index = -1; + + while (++index < length) { + results[index] = convert(tests[index]); + } + + return results +} + +// Utility assert each property in `test` is represented in `node`, and each +// values are strictly equal. +function matchesFactory(test) { + return matches + + function matches(node) { + var key; + + for (key in test) { + if (node[key] !== test[key]) { + return false + } + } + + return true + } +} + +function anyFactory(tests) { + var checks = convertAll(tests); + var length = checks.length; + + return matches + + function matches() { + var index = -1; + + while (++index < length) { + if (checks[index].apply(this, arguments)) { + return true + } + } + + return false + } +} + +// Utility to convert a string into a function which checks a given node’s type +// for said string. +function typeFactory(test) { + return type + + function type(node) { + return Boolean(node && node.type === test) + } +} + +// Utility to return true. +function ok() { + return true +} + +var unistUtilVisitParents = visitParents; + + + +var CONTINUE$1 = true; +var SKIP$1 = 'skip'; +var EXIT$1 = false; + +visitParents.CONTINUE = CONTINUE$1; +visitParents.SKIP = SKIP$1; +visitParents.EXIT = EXIT$1; + +function visitParents(tree, test, visitor, reverse) { + var is; + + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + is = convert_1(test); + + one(tree, null, []); + + // Visit a single node. + function one(node, index, parents) { + var result = []; + var subresult; + + if (!test || is(node, index, parents[parents.length - 1] || null)) { + result = toResult(visitor(node, parents)); + + if (result[0] === EXIT$1) { + return result + } + } + + if (node.children && result[0] !== SKIP$1) { + subresult = toResult(all(node.children, parents.concat(node))); + return subresult[0] === EXIT$1 ? subresult : result + } + + return result + } + + // Visit children in `parent`. + function all(children, parents) { + var min = -1; + var step = reverse ? -1 : 1; + var index = (reverse ? children.length : min) + step; + var result; + + while (index > min && index < children.length) { + result = one(children[index], index, parents); + + if (result[0] === EXIT$1) { + return result + } + + index = typeof result[1] === 'number' ? result[1] : index + step; + } + } +} + +function toResult(value) { + if (value !== null && typeof value === 'object' && 'length' in value) { + return value + } + + if (typeof value === 'number') { + return [CONTINUE$1, value] + } + + return [value] +} + +var unistUtilVisit = visit; + + + +var CONTINUE = unistUtilVisitParents.CONTINUE; +var SKIP = unistUtilVisitParents.SKIP; +var EXIT = unistUtilVisitParents.EXIT; + +visit.CONTINUE = CONTINUE; +visit.SKIP = SKIP; +visit.EXIT = EXIT; + +function visit(tree, test, visitor, reverse) { + if (typeof test === 'function' && typeof visitor !== 'function') { + reverse = visitor; + visitor = test; + test = null; + } + + unistUtilVisitParents(tree, test, overload, reverse); + + function overload(node, parents) { + var parent = parents[parents.length - 1]; + var index = parent ? parent.children.indexOf(node) : null; + return visitor(node, index, parent) + } +} + +var unistUtilRemovePosition = removePosition; + +function removePosition(node, force) { + unistUtilVisit(node, force ? hard : soft); + return node +} + +function hard(node) { + delete node.position; +} + +function soft(node) { + node.position = undefined; +} + +var parse_1 = parse$1; + +var C_NEWLINE$d = '\n'; +var EXPRESSION_LINE_BREAKS = /\r\n|\r/g; + +/* Parse the bound file. */ +function parse$1() { + var self = this; + var value = String(self.file); + var start = {line: 1, column: 1, offset: 0}; + var content = immutable(start); + var node; + + /* Clean non-unix newlines: `\r\n` and `\r` are all + * changed to `\n`. This should not affect positional + * information. */ + value = value.replace(EXPRESSION_LINE_BREAKS, C_NEWLINE$d); + + if (value.charCodeAt(0) === 0xFEFF) { + value = value.slice(1); + + content.column++; + content.offset++; + } + + node = { + type: 'root', + children: self.tokenizeBlock(value, content), + position: { + start: start, + end: self.eof || immutable(start) + } + }; + + if (!self.options.position) { + unistUtilRemovePosition(node, true); + } + + return node; +} + +var isWhitespaceCharacter = whitespace; + +var fromCode$1 = String.fromCharCode; +var re$1 = /\s/; + +// Check if the given character code, or the character code at the first +// character, is a whitespace character. +function whitespace(character) { + return re$1.test( + typeof character === 'number' ? fromCode$1(character) : character.charAt(0) + ) +} + +var newline_1 = newline; + +/* Tokenise newline. */ +function newline(eat, value, silent) { + var character = value.charAt(0); + var length; + var subvalue; + var queue; + var index; + + if (character !== '\n') { + return; + } + + /* istanbul ignore if - never used (yet) */ + if (silent) { + return true; + } + + index = 1; + length = value.length; + subvalue = character; + queue = ''; + + while (index < length) { + character = value.charAt(index); + + if (!isWhitespaceCharacter(character)) { + break; + } + + queue += character; + + if (character === '\n') { + subvalue += queue; + queue = ''; + } + + index++; + } + + eat(subvalue); +} + +/*! + * repeat-string + * + * Copyright (c) 2014-2015, Jon Schlinkert. + * Licensed under the MIT License. + */ + +/** + * Results cache + */ + +var res = ''; +var cache; + +/** + * Expose `repeat` + */ + +var repeatString = repeat; + +/** + * Repeat the given `string` the specified `number` + * of times. + * + * **Example:** + * + * ```js + * var repeat = require('repeat-string'); + * repeat('A', 5); + * //=> AAAAA + * ``` + * + * @param {String} `string` The string to repeat + * @param {Number} `number` The number of times to repeat the string + * @return {String} Repeated string + * @api public + */ + +function repeat(str, num) { + if (typeof str !== 'string') { + throw new TypeError('expected a string'); + } + + // cover common, quick use cases + if (num === 1) return str; + if (num === 2) return str + str; + + var max = str.length * num; + if (cache !== str || typeof cache === 'undefined') { + cache = str; + res = ''; + } else if (res.length >= max) { + return res.substr(0, max); + } + + while (max > res.length && num > 1) { + if (num & 1) { + res += str; + } + + num >>= 1; + str += str; + } + + res += str; + res = res.substr(0, max); + return res; +} + +var trimTrailingLines_1 = trimTrailingLines; + +// Remove final newline characters from `value`. +function trimTrailingLines(value) { + return String(value).replace(/\n+$/, '') +} + +var codeIndented = indentedCode; + +var C_NEWLINE$c = '\n'; +var C_TAB$c = '\t'; +var C_SPACE$c = ' '; + +var CODE_INDENT_COUNT$1 = 4; +var CODE_INDENT = repeatString(C_SPACE$c, CODE_INDENT_COUNT$1); + +/* Tokenise indented code. */ +function indentedCode(eat, value, silent) { + var index = -1; + var length = value.length; + var subvalue = ''; + var content = ''; + var subvalueQueue = ''; + var contentQueue = ''; + var character; + var blankQueue; + var indent; + + while (++index < length) { + character = value.charAt(index); + + if (indent) { + indent = false; + + subvalue += subvalueQueue; + content += contentQueue; + subvalueQueue = ''; + contentQueue = ''; + + if (character === C_NEWLINE$c) { + subvalueQueue = character; + contentQueue = character; + } else { + subvalue += character; + content += character; + + while (++index < length) { + character = value.charAt(index); + + if (!character || character === C_NEWLINE$c) { + contentQueue = character; + subvalueQueue = character; + break; + } + + subvalue += character; + content += character; + } + } + } else if ( + character === C_SPACE$c && + value.charAt(index + 1) === character && + value.charAt(index + 2) === character && + value.charAt(index + 3) === character + ) { + subvalueQueue += CODE_INDENT; + index += 3; + indent = true; + } else if (character === C_TAB$c) { + subvalueQueue += character; + indent = true; + } else { + blankQueue = ''; + + while (character === C_TAB$c || character === C_SPACE$c) { + blankQueue += character; + character = value.charAt(++index); + } + + if (character !== C_NEWLINE$c) { + break; + } + + subvalueQueue += blankQueue + character; + contentQueue += character; + } + } + + if (content) { + if (silent) { + return true; + } + + return eat(subvalue)({ + type: 'code', + lang: null, + value: trimTrailingLines_1(content) + }); + } +} + +var codeFenced = fencedCode; + +var C_NEWLINE$b = '\n'; +var C_TAB$b = '\t'; +var C_SPACE$b = ' '; +var C_TILDE$1 = '~'; +var C_TICK$3 = '`'; + +var MIN_FENCE_COUNT = 3; +var CODE_INDENT_COUNT = 4; + +function fencedCode(eat, value, silent) { + var self = this; + var settings = self.options; + var length = value.length + 1; + var index = 0; + var subvalue = ''; + var fenceCount; + var marker; + var character; + var flag; + var queue; + var content; + var exdentedContent; + var closing; + var exdentedClosing; + var indent; + var now; + + if (!settings.gfm) { + return; + } + + /* Eat initial spacing. */ + while (index < length) { + character = value.charAt(index); + + if (character !== C_SPACE$b && character !== C_TAB$b) { + break; + } + + subvalue += character; + index++; + } + + indent = index; + + /* Eat the fence. */ + character = value.charAt(index); + + if (character !== C_TILDE$1 && character !== C_TICK$3) { + return; + } + + index++; + marker = character; + fenceCount = 1; + subvalue += character; + + while (index < length) { + character = value.charAt(index); + + if (character !== marker) { + break; + } + + subvalue += character; + fenceCount++; + index++; + } + + if (fenceCount < MIN_FENCE_COUNT) { + return; + } + + /* Eat spacing before flag. */ + while (index < length) { + character = value.charAt(index); + + if (character !== C_SPACE$b && character !== C_TAB$b) { + break; + } + + subvalue += character; + index++; + } + + /* Eat flag. */ + flag = ''; + queue = ''; + + while (index < length) { + character = value.charAt(index); + + if ( + character === C_NEWLINE$b || + character === C_TILDE$1 || + character === C_TICK$3 + ) { + break; + } + + if (character === C_SPACE$b || character === C_TAB$b) { + queue += character; + } else { + flag += queue + character; + queue = ''; + } + + index++; + } + + character = value.charAt(index); + + if (character && character !== C_NEWLINE$b) { + return; + } + + if (silent) { + return true; + } + + now = eat.now(); + now.column += subvalue.length; + now.offset += subvalue.length; + + subvalue += flag; + flag = self.decode.raw(self.unescape(flag), now); + + if (queue) { + subvalue += queue; + } + + queue = ''; + closing = ''; + exdentedClosing = ''; + content = ''; + exdentedContent = ''; + + /* Eat content. */ + while (index < length) { + character = value.charAt(index); + content += closing; + exdentedContent += exdentedClosing; + closing = ''; + exdentedClosing = ''; + + if (character !== C_NEWLINE$b) { + content += character; + exdentedClosing += character; + index++; + continue; + } + + /* Add the newline to `subvalue` if its the first + * character. Otherwise, add it to the `closing` + * queue. */ + if (content) { + closing += character; + exdentedClosing += character; + } else { + subvalue += character; + } + + queue = ''; + index++; + + while (index < length) { + character = value.charAt(index); + + if (character !== C_SPACE$b) { + break; + } + + queue += character; + index++; + } + + closing += queue; + exdentedClosing += queue.slice(indent); + + if (queue.length >= CODE_INDENT_COUNT) { + continue; + } + + queue = ''; + + while (index < length) { + character = value.charAt(index); + + if (character !== marker) { + break; + } + + queue += character; + index++; + } + + closing += queue; + exdentedClosing += queue; + + if (queue.length < fenceCount) { + continue; + } + + queue = ''; + + while (index < length) { + character = value.charAt(index); + + if (character !== C_SPACE$b && character !== C_TAB$b) { + break; + } + + closing += character; + exdentedClosing += character; + index++; + } + + if (!character || character === C_NEWLINE$b) { + break; + } + } + + subvalue += content + closing; + + return eat(subvalue)({ + type: 'code', + lang: flag || null, + value: trimTrailingLines_1(exdentedContent) + }); +} + +var trim_1 = createCommonjsModule(function (module, exports) { +exports = module.exports = trim; + +function trim(str){ + return str.replace(/^\s*|\s*$/g, ''); +} + +exports.left = function(str){ + return str.replace(/^\s*/, ''); +}; + +exports.right = function(str){ + return str.replace(/\s*$/, ''); +}; +}); + +var interrupt_1 = interrupt; + +function interrupt(interruptors, tokenizers, ctx, params) { + var bools = ['pedantic', 'commonmark']; + var count = bools.length; + var length = interruptors.length; + var index = -1; + var interruptor; + var config; + var fn; + var offset; + var bool; + var ignore; + + while (++index < length) { + interruptor = interruptors[index]; + config = interruptor[1] || {}; + fn = interruptor[0]; + offset = -1; + ignore = false; + + while (++offset < count) { + bool = bools[offset]; + + if (config[bool] !== undefined && config[bool] !== ctx.options[bool]) { + ignore = true; + break; + } + } + + if (ignore) { + continue; + } + + if (tokenizers[fn].apply(ctx, params)) { + return true; + } + } + + return false; +} + +var blockquote_1 = blockquote; + +var C_NEWLINE$a = '\n'; +var C_TAB$a = '\t'; +var C_SPACE$a = ' '; +var C_GT$3 = '>'; + +/* Tokenise a blockquote. */ +function blockquote(eat, value, silent) { + var self = this; + var offsets = self.offset; + var tokenizers = self.blockTokenizers; + var interruptors = self.interruptBlockquote; + var now = eat.now(); + var currentLine = now.line; + var length = value.length; + var values = []; + var contents = []; + var indents = []; + var add; + var index = 0; + var character; + var rest; + var nextIndex; + var content; + var line; + var startIndex; + var prefixed; + var exit; + + while (index < length) { + character = value.charAt(index); + + if (character !== C_SPACE$a && character !== C_TAB$a) { + break; + } + + index++; + } + + if (value.charAt(index) !== C_GT$3) { + return; + } + + if (silent) { + return true; + } + + index = 0; + + while (index < length) { + nextIndex = value.indexOf(C_NEWLINE$a, index); + startIndex = index; + prefixed = false; + + if (nextIndex === -1) { + nextIndex = length; + } + + while (index < length) { + character = value.charAt(index); + + if (character !== C_SPACE$a && character !== C_TAB$a) { + break; + } + + index++; + } + + if (value.charAt(index) === C_GT$3) { + index++; + prefixed = true; + + if (value.charAt(index) === C_SPACE$a) { + index++; + } + } else { + index = startIndex; + } + + content = value.slice(index, nextIndex); + + if (!prefixed && !trim_1(content)) { + index = startIndex; + break; + } + + if (!prefixed) { + rest = value.slice(index); + + /* Check if the following code contains a possible + * block. */ + if (interrupt_1(interruptors, tokenizers, self, [eat, rest, true])) { + break; + } + } + + line = startIndex === index ? content : value.slice(startIndex, nextIndex); + + indents.push(index - startIndex); + values.push(line); + contents.push(content); + + index = nextIndex + 1; + } + + index = -1; + length = indents.length; + add = eat(values.join(C_NEWLINE$a)); + + while (++index < length) { + offsets[currentLine] = (offsets[currentLine] || 0) + indents[index]; + currentLine++; + } + + exit = self.enterBlock(); + contents = self.tokenizeBlock(contents.join(C_NEWLINE$a), now); + exit(); + + return add({ + type: 'blockquote', + children: contents + }); +} + +var headingAtx = atxHeading; + +var C_NEWLINE$9 = '\n'; +var C_TAB$9 = '\t'; +var C_SPACE$9 = ' '; +var C_HASH = '#'; + +var MAX_ATX_COUNT = 6; + +function atxHeading(eat, value, silent) { + var self = this; + var settings = self.options; + var length = value.length + 1; + var index = -1; + var now = eat.now(); + var subvalue = ''; + var content = ''; + var character; + var queue; + var depth; + + /* Eat initial spacing. */ + while (++index < length) { + character = value.charAt(index); + + if (character !== C_SPACE$9 && character !== C_TAB$9) { + index--; + break; + } + + subvalue += character; + } + + /* Eat hashes. */ + depth = 0; + + while (++index <= length) { + character = value.charAt(index); + + if (character !== C_HASH) { + index--; + break; + } + + subvalue += character; + depth++; + } + + if (depth > MAX_ATX_COUNT) { + return; + } + + if ( + !depth || + (!settings.pedantic && value.charAt(index + 1) === C_HASH) + ) { + return; + } + + length = value.length + 1; + + /* Eat intermediate white-space. */ + queue = ''; + + while (++index < length) { + character = value.charAt(index); + + if (character !== C_SPACE$9 && character !== C_TAB$9) { + index--; + break; + } + + queue += character; + } + + /* Exit when not in pedantic mode without spacing. */ + if ( + !settings.pedantic && + queue.length === 0 && + character && + character !== C_NEWLINE$9 + ) { + return; + } + + if (silent) { + return true; + } + + /* Eat content. */ + subvalue += queue; + queue = ''; + content = ''; + + while (++index < length) { + character = value.charAt(index); + + if (!character || character === C_NEWLINE$9) { + break; + } + + if ( + character !== C_SPACE$9 && + character !== C_TAB$9 && + character !== C_HASH + ) { + content += queue + character; + queue = ''; + continue; + } + + while (character === C_SPACE$9 || character === C_TAB$9) { + queue += character; + character = value.charAt(++index); + } + + while (character === C_HASH) { + queue += character; + character = value.charAt(++index); + } + + while (character === C_SPACE$9 || character === C_TAB$9) { + queue += character; + character = value.charAt(++index); + } + + index--; + } + + now.column += subvalue.length; + now.offset += subvalue.length; + subvalue += content + queue; + + return eat(subvalue)({ + type: 'heading', + depth: depth, + children: self.tokenizeInline(content, now) + }); +} + +var thematicBreak_1 = thematicBreak; + +var C_NEWLINE$8 = '\n'; +var C_TAB$8 = '\t'; +var C_SPACE$8 = ' '; +var C_ASTERISK$3 = '*'; +var C_UNDERSCORE$3 = '_'; +var C_DASH$3 = '-'; + +var THEMATIC_BREAK_MARKER_COUNT = 3; + +function thematicBreak(eat, value, silent) { + var index = -1; + var length = value.length + 1; + var subvalue = ''; + var character; + var marker; + var markerCount; + var queue; + + while (++index < length) { + character = value.charAt(index); + + if (character !== C_TAB$8 && character !== C_SPACE$8) { + break; + } + + subvalue += character; + } + + if ( + character !== C_ASTERISK$3 && + character !== C_DASH$3 && + character !== C_UNDERSCORE$3 + ) { + return; + } + + marker = character; + subvalue += character; + markerCount = 1; + queue = ''; + + while (++index < length) { + character = value.charAt(index); + + if (character === marker) { + markerCount++; + subvalue += queue + marker; + queue = ''; + } else if (character === C_SPACE$8) { + queue += character; + } else if ( + markerCount >= THEMATIC_BREAK_MARKER_COUNT && + (!character || character === C_NEWLINE$8) + ) { + subvalue += queue; + + if (silent) { + return true; + } + + return eat(subvalue)({type: 'thematicBreak'}); + } else { + return; + } + } +} + +var getIndentation = indentation$1; + +/* Map of characters, and their column length, + * which can be used as indentation. */ +var characters = {' ': 1, '\t': 4}; + +/* Gets indentation information for a line. */ +function indentation$1(value) { + var index = 0; + var indent = 0; + var character = value.charAt(index); + var stops = {}; + var size; + + while (character in characters) { + size = characters[character]; + + indent += size; + + if (size > 1) { + indent = Math.floor(indent / size) * size; + } + + stops[indent] = index; + + character = value.charAt(++index); + } + + return {indent: indent, stops: stops}; +} + +var removeIndentation = indentation; + +var C_SPACE$7 = ' '; +var C_NEWLINE$7 = '\n'; +var C_TAB$7 = '\t'; + +/* Remove the minimum indent from every line in `value`. + * Supports both tab, spaced, and mixed indentation (as + * well as possible). */ +function indentation(value, maximum) { + var values = value.split(C_NEWLINE$7); + var position = values.length + 1; + var minIndent = Infinity; + var matrix = []; + var index; + var indentation; + var stops; + var padding; + + values.unshift(repeatString(C_SPACE$7, maximum) + '!'); + + while (position--) { + indentation = getIndentation(values[position]); + + matrix[position] = indentation.stops; + + if (trim_1(values[position]).length === 0) { + continue; + } + + if (indentation.indent) { + if (indentation.indent > 0 && indentation.indent < minIndent) { + minIndent = indentation.indent; + } + } else { + minIndent = Infinity; + + break; + } + } + + if (minIndent !== Infinity) { + position = values.length; + + while (position--) { + stops = matrix[position]; + index = minIndent; + + while (index && !(index in stops)) { + index--; + } + + if ( + trim_1(values[position]).length !== 0 && + minIndent && + index !== minIndent + ) { + padding = C_TAB$7; + } else { + padding = ''; + } + + values[position] = padding + values[position].slice( + index in stops ? stops[index] + 1 : 0 + ); + } + } + + values.shift(); + + return values.join(C_NEWLINE$7); +} + +/* eslint-disable max-params */ + + + + + + + + +var list_1 = list; + +var C_ASTERISK$2 = '*'; +var C_UNDERSCORE$2 = '_'; +var C_PLUS = '+'; +var C_DASH$2 = '-'; +var C_DOT = '.'; +var C_SPACE$6 = ' '; +var C_NEWLINE$6 = '\n'; +var C_TAB$6 = '\t'; +var C_PAREN_CLOSE$3 = ')'; +var C_X_LOWER = 'x'; + +var TAB_SIZE$1 = 4; +var EXPRESSION_LOOSE_LIST_ITEM = /\n\n(?!\s*$)/; +var EXPRESSION_TASK_ITEM = /^\[([ \t]|x|X)][ \t]/; +var EXPRESSION_BULLET = /^([ \t]*)([*+-]|\d+[.)])( {1,4}(?! )| |\t|$|(?=\n))([^\n]*)/; +var EXPRESSION_PEDANTIC_BULLET = /^([ \t]*)([*+-]|\d+[.)])([ \t]+)/; +var EXPRESSION_INITIAL_INDENT = /^( {1,4}|\t)?/gm; + +/* Map of characters which can be used to mark + * list-items. */ +var LIST_UNORDERED_MARKERS = {}; + +LIST_UNORDERED_MARKERS[C_ASTERISK$2] = true; +LIST_UNORDERED_MARKERS[C_PLUS] = true; +LIST_UNORDERED_MARKERS[C_DASH$2] = true; + +/* Map of characters which can be used to mark + * list-items after a digit. */ +var LIST_ORDERED_MARKERS = {}; + +LIST_ORDERED_MARKERS[C_DOT] = true; + +/* Map of characters which can be used to mark + * list-items after a digit. */ +var LIST_ORDERED_COMMONMARK_MARKERS = {}; + +LIST_ORDERED_COMMONMARK_MARKERS[C_DOT] = true; +LIST_ORDERED_COMMONMARK_MARKERS[C_PAREN_CLOSE$3] = true; + +function list(eat, value, silent) { + var self = this; + var commonmark = self.options.commonmark; + var pedantic = self.options.pedantic; + var tokenizers = self.blockTokenizers; + var interuptors = self.interruptList; + var markers; + var index = 0; + var length = value.length; + var start = null; + var size = 0; + var queue; + var ordered; + var character; + var marker; + var nextIndex; + var startIndex; + var prefixed; + var currentMarker; + var content; + var line; + var prevEmpty; + var empty; + var items; + var allLines; + var emptyLines; + var item; + var enterTop; + var exitBlockquote; + var isLoose; + var node; + var now; + var end; + var indented; + + while (index < length) { + character = value.charAt(index); + + if (character === C_TAB$6) { + size += TAB_SIZE$1 - (size % TAB_SIZE$1); + } else if (character === C_SPACE$6) { + size++; + } else { + break; + } + + index++; + } + + if (size >= TAB_SIZE$1) { + return; + } + + character = value.charAt(index); + + markers = commonmark ? + LIST_ORDERED_COMMONMARK_MARKERS : + LIST_ORDERED_MARKERS; + + if (LIST_UNORDERED_MARKERS[character] === true) { + marker = character; + ordered = false; + } else { + ordered = true; + queue = ''; + + while (index < length) { + character = value.charAt(index); + + if (!isDecimal(character)) { + break; + } + + queue += character; + index++; + } + + character = value.charAt(index); + + if (!queue || markers[character] !== true) { + return; + } + + start = parseInt(queue, 10); + marker = character; + } + + character = value.charAt(++index); + + if (character !== C_SPACE$6 && character !== C_TAB$6) { + return; + } + + if (silent) { + return true; + } + + index = 0; + items = []; + allLines = []; + emptyLines = []; + + while (index < length) { + nextIndex = value.indexOf(C_NEWLINE$6, index); + startIndex = index; + prefixed = false; + indented = false; + + if (nextIndex === -1) { + nextIndex = length; + } + + end = index + TAB_SIZE$1; + size = 0; + + while (index < length) { + character = value.charAt(index); + + if (character === C_TAB$6) { + size += TAB_SIZE$1 - (size % TAB_SIZE$1); + } else if (character === C_SPACE$6) { + size++; + } else { + break; + } + + index++; + } + + if (size >= TAB_SIZE$1) { + indented = true; + } + + if (item && size >= item.indent) { + indented = true; + } + + character = value.charAt(index); + currentMarker = null; + + if (!indented) { + if (LIST_UNORDERED_MARKERS[character] === true) { + currentMarker = character; + index++; + size++; + } else { + queue = ''; + + while (index < length) { + character = value.charAt(index); + + if (!isDecimal(character)) { + break; + } + + queue += character; + index++; + } + + character = value.charAt(index); + index++; + + if (queue && markers[character] === true) { + currentMarker = character; + size += queue.length + 1; + } + } + + if (currentMarker) { + character = value.charAt(index); + + if (character === C_TAB$6) { + size += TAB_SIZE$1 - (size % TAB_SIZE$1); + index++; + } else if (character === C_SPACE$6) { + end = index + TAB_SIZE$1; + + while (index < end) { + if (value.charAt(index) !== C_SPACE$6) { + break; + } + + index++; + size++; + } + + if (index === end && value.charAt(index) === C_SPACE$6) { + index -= TAB_SIZE$1 - 1; + size -= TAB_SIZE$1 - 1; + } + } else if (character !== C_NEWLINE$6 && character !== '') { + currentMarker = null; + } + } + } + + if (currentMarker) { + if (!pedantic && marker !== currentMarker) { + break; + } + + prefixed = true; + } else { + if (!commonmark && !indented && value.charAt(startIndex) === C_SPACE$6) { + indented = true; + } else if (commonmark && item) { + indented = size >= item.indent || size > TAB_SIZE$1; + } + + prefixed = false; + index = startIndex; + } + + line = value.slice(startIndex, nextIndex); + content = startIndex === index ? line : value.slice(index, nextIndex); + + if ( + currentMarker === C_ASTERISK$2 || + currentMarker === C_UNDERSCORE$2 || + currentMarker === C_DASH$2 + ) { + if (tokenizers.thematicBreak.call(self, eat, line, true)) { + break; + } + } + + prevEmpty = empty; + empty = !trim_1(content).length; + + if (indented && item) { + item.value = item.value.concat(emptyLines, line); + allLines = allLines.concat(emptyLines, line); + emptyLines = []; + } else if (prefixed) { + if (emptyLines.length !== 0) { + item.value.push(''); + item.trail = emptyLines.concat(); + } + + item = { + value: [line], + indent: size, + trail: [] + }; + + items.push(item); + allLines = allLines.concat(emptyLines, line); + emptyLines = []; + } else if (empty) { + if (prevEmpty) { + break; + } + + emptyLines.push(line); + } else { + if (prevEmpty) { + break; + } + + if (interrupt_1(interuptors, tokenizers, self, [eat, line, true])) { + break; + } + + item.value = item.value.concat(emptyLines, line); + allLines = allLines.concat(emptyLines, line); + emptyLines = []; + } + + index = nextIndex + 1; + } + + node = eat(allLines.join(C_NEWLINE$6)).reset({ + type: 'list', + ordered: ordered, + start: start, + loose: null, + children: [] + }); + + enterTop = self.enterList(); + exitBlockquote = self.enterBlock(); + isLoose = false; + index = -1; + length = items.length; + + while (++index < length) { + item = items[index].value.join(C_NEWLINE$6); + now = eat.now(); + + item = eat(item)(listItem(self, item, now), node); + + if (item.loose) { + isLoose = true; + } + + item = items[index].trail.join(C_NEWLINE$6); + + if (index !== length - 1) { + item += C_NEWLINE$6; + } + + eat(item); + } + + enterTop(); + exitBlockquote(); + + node.loose = isLoose; + + return node; +} + +function listItem(ctx, value, position) { + var offsets = ctx.offset; + var fn = ctx.options.pedantic ? pedanticListItem : normalListItem; + var checked = null; + var task; + var indent; + + value = fn.apply(null, arguments); + + if (ctx.options.gfm) { + task = value.match(EXPRESSION_TASK_ITEM); + + if (task) { + indent = task[0].length; + checked = task[1].toLowerCase() === C_X_LOWER; + offsets[position.line] += indent; + value = value.slice(indent); + } + } + + return { + type: 'listItem', + loose: EXPRESSION_LOOSE_LIST_ITEM.test(value) || + value.charAt(value.length - 1) === C_NEWLINE$6, + checked: checked, + children: ctx.tokenizeBlock(value, position) + }; +} + +/* Create a list-item using overly simple mechanics. */ +function pedanticListItem(ctx, value, position) { + var offsets = ctx.offset; + var line = position.line; + + /* Remove the list-item’s bullet. */ + value = value.replace(EXPRESSION_PEDANTIC_BULLET, replacer); + + /* The initial line was also matched by the below, so + * we reset the `line`. */ + line = position.line; + + return value.replace(EXPRESSION_INITIAL_INDENT, replacer); + + /* A simple replacer which removed all matches, + * and adds their length to `offset`. */ + function replacer($0) { + offsets[line] = (offsets[line] || 0) + $0.length; + line++; + + return ''; + } +} + +/* Create a list-item using sane mechanics. */ +function normalListItem(ctx, value, position) { + var offsets = ctx.offset; + var line = position.line; + var max; + var bullet; + var rest; + var lines; + var trimmedLines; + var index; + var length; + + /* Remove the list-item’s bullet. */ + value = value.replace(EXPRESSION_BULLET, replacer); + + lines = value.split(C_NEWLINE$6); + + trimmedLines = removeIndentation(value, getIndentation(max).indent).split(C_NEWLINE$6); + + /* We replaced the initial bullet with something + * else above, which was used to trick + * `removeIndentation` into removing some more + * characters when possible. However, that could + * result in the initial line to be stripped more + * than it should be. */ + trimmedLines[0] = rest; + + offsets[line] = (offsets[line] || 0) + bullet.length; + line++; + + index = 0; + length = lines.length; + + while (++index < length) { + offsets[line] = (offsets[line] || 0) + + lines[index].length - trimmedLines[index].length; + line++; + } + + return trimmedLines.join(C_NEWLINE$6); + + function replacer($0, $1, $2, $3, $4) { + bullet = $1 + $2 + $3; + rest = $4; + + /* Make sure that the first nine numbered list items + * can indent with an extra space. That is, when + * the bullet did not receive an extra final space. */ + if (Number($2) < 10 && bullet.length % 2 === 1) { + $2 = C_SPACE$6 + $2; + } + + max = $1 + repeatString(C_SPACE$6, $2.length) + $3; + + return max + rest; + } +} + +var headingSetext = setextHeading; + +var C_NEWLINE$5 = '\n'; +var C_TAB$5 = '\t'; +var C_SPACE$5 = ' '; +var C_EQUALS = '='; +var C_DASH$1 = '-'; + +var MAX_HEADING_INDENT = 3; + +/* Map of characters which can be used to mark setext + * headers, mapping to their corresponding depth. */ +var SETEXT_MARKERS = {}; + +SETEXT_MARKERS[C_EQUALS] = 1; +SETEXT_MARKERS[C_DASH$1] = 2; + +function setextHeading(eat, value, silent) { + var self = this; + var now = eat.now(); + var length = value.length; + var index = -1; + var subvalue = ''; + var content; + var queue; + var character; + var marker; + var depth; + + /* Eat initial indentation. */ + while (++index < length) { + character = value.charAt(index); + + if (character !== C_SPACE$5 || index >= MAX_HEADING_INDENT) { + index--; + break; + } + + subvalue += character; + } + + /* Eat content. */ + content = ''; + queue = ''; + + while (++index < length) { + character = value.charAt(index); + + if (character === C_NEWLINE$5) { + index--; + break; + } + + if (character === C_SPACE$5 || character === C_TAB$5) { + queue += character; + } else { + content += queue + character; + queue = ''; + } + } + + now.column += subvalue.length; + now.offset += subvalue.length; + subvalue += content + queue; + + /* Ensure the content is followed by a newline and a + * valid marker. */ + character = value.charAt(++index); + marker = value.charAt(++index); + + if (character !== C_NEWLINE$5 || !SETEXT_MARKERS[marker]) { + return; + } + + subvalue += character; + + /* Eat Setext-line. */ + queue = marker; + depth = SETEXT_MARKERS[marker]; + + while (++index < length) { + character = value.charAt(index); + + if (character !== marker) { + if (character !== C_NEWLINE$5) { + return; + } + + index--; + break; + } + + queue += character; + } + + if (silent) { + return true; + } + + return eat(subvalue + queue)({ + type: 'heading', + depth: depth, + children: self.tokenizeInline(content, now) + }); +} + +var attributeName = '[a-zA-Z_:][a-zA-Z0-9:._-]*'; +var unquoted = '[^"\'=<>`\\u0000-\\u0020]+'; +var singleQuoted = '\'[^\']*\''; +var doubleQuoted = '"[^"]*"'; +var attributeValue = '(?:' + unquoted + '|' + singleQuoted + '|' + doubleQuoted + ')'; +var attribute = '(?:\\s+' + attributeName + '(?:\\s*=\\s*' + attributeValue + ')?)'; +var openTag = '<[A-Za-z][A-Za-z0-9\\-]*' + attribute + '*\\s*\\/?>'; +var closeTag = '<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>'; +var comment = '|'; +var processing = '<[?].*?[?]>'; +var declaration = ']*>'; +var cdata = ''; + +var openCloseTag$1 = new RegExp('^(?:' + openTag + '|' + closeTag + ')'); + +var tag$2 = new RegExp('^(?:' + + openTag + '|' + + closeTag + '|' + + comment + '|' + + processing + '|' + + declaration + '|' + + cdata + +')'); + +var html = { + openCloseTag: openCloseTag$1, + tag: tag$2 +}; + +var openCloseTag = html.openCloseTag; + +var htmlBlock = blockHTML; + +var C_TAB$4 = '\t'; +var C_SPACE$4 = ' '; +var C_NEWLINE$4 = '\n'; +var C_LT$4 = '<'; + +function blockHTML(eat, value, silent) { + var self = this; + var blocks = self.options.blocks; + var length = value.length; + var index = 0; + var next; + var line; + var offset; + var character; + var count; + var sequence; + var subvalue; + + var sequences = [ + [/^<(script|pre|style)(?=(\s|>|$))/i, /<\/(script|pre|style)>/i, true], + [/^/, true], + [/^<\?/, /\?>/, true], + [/^/, true], + [/^/, true], + [new RegExp('^|$))', 'i'), /^$/, true], + [new RegExp(openCloseTag.source + '\\s*$'), /^$/, false] + ]; + + /* Eat initial spacing. */ + while (index < length) { + character = value.charAt(index); + + if (character !== C_TAB$4 && character !== C_SPACE$4) { + break; + } + + index++; + } + + if (value.charAt(index) !== C_LT$4) { + return; + } + + next = value.indexOf(C_NEWLINE$4, index + 1); + next = next === -1 ? length : next; + line = value.slice(index, next); + offset = -1; + count = sequences.length; + + while (++offset < count) { + if (sequences[offset][0].test(line)) { + sequence = sequences[offset]; + break; + } + } + + if (!sequence) { + return; + } + + if (silent) { + return sequence[2]; + } + + index = next; + + if (!sequence[1].test(line)) { + while (index < length) { + next = value.indexOf(C_NEWLINE$4, index + 1); + next = next === -1 ? length : next; + line = value.slice(index + 1, next); + + if (sequence[1].test(line)) { + if (line) { + index = next; + } + + break; + } + + index = next; + } + } + + subvalue = value.slice(0, index); + + return eat(subvalue)({type: 'html', value: subvalue}); +} + +var collapseWhiteSpace = collapse; + +// `collapse(' \t\nbar \nbaz\t') // ' bar baz '` +function collapse(value) { + return String(value).replace(/\s+/g, ' ') +} + +var normalize_1 = normalize; + +/* Normalize an identifier. Collapses multiple white space + * characters into a single space, and removes casing. */ +function normalize(value) { + return collapseWhiteSpace(value).toLowerCase(); +} + +var footnoteDefinition_1 = footnoteDefinition; +footnoteDefinition.notInList = true; +footnoteDefinition.notInBlock = true; + +var C_BACKSLASH$4 = '\\'; +var C_NEWLINE$3 = '\n'; +var C_TAB$3 = '\t'; +var C_SPACE$3 = ' '; +var C_BRACKET_OPEN$4 = '['; +var C_BRACKET_CLOSE$4 = ']'; +var C_CARET$1 = '^'; +var C_COLON$2 = ':'; + +var EXPRESSION_INITIAL_TAB = /^( {4}|\t)?/gm; + +function footnoteDefinition(eat, value, silent) { + var self = this; + var offsets = self.offset; + var index; + var length; + var subvalue; + var now; + var currentLine; + var content; + var queue; + var subqueue; + var character; + var identifier; + var add; + var exit; + + if (!self.options.footnotes) { + return; + } + + index = 0; + length = value.length; + subvalue = ''; + now = eat.now(); + currentLine = now.line; + + while (index < length) { + character = value.charAt(index); + + if (!isWhitespaceCharacter(character)) { + break; + } + + subvalue += character; + index++; + } + + if ( + value.charAt(index) !== C_BRACKET_OPEN$4 || + value.charAt(index + 1) !== C_CARET$1 + ) { + return; + } + + subvalue += C_BRACKET_OPEN$4 + C_CARET$1; + index = subvalue.length; + queue = ''; + + while (index < length) { + character = value.charAt(index); + + if (character === C_BRACKET_CLOSE$4) { + break; + } else if (character === C_BACKSLASH$4) { + queue += character; + index++; + character = value.charAt(index); + } + + queue += character; + index++; + } + + if ( + !queue || + value.charAt(index) !== C_BRACKET_CLOSE$4 || + value.charAt(index + 1) !== C_COLON$2 + ) { + return; + } + + if (silent) { + return true; + } + + identifier = normalize_1(queue); + subvalue += queue + C_BRACKET_CLOSE$4 + C_COLON$2; + index = subvalue.length; + + while (index < length) { + character = value.charAt(index); + + if (character !== C_TAB$3 && character !== C_SPACE$3) { + break; + } + + subvalue += character; + index++; + } + + now.column += subvalue.length; + now.offset += subvalue.length; + queue = ''; + content = ''; + subqueue = ''; + + while (index < length) { + character = value.charAt(index); + + if (character === C_NEWLINE$3) { + subqueue = character; + index++; + + while (index < length) { + character = value.charAt(index); + + if (character !== C_NEWLINE$3) { + break; + } + + subqueue += character; + index++; + } + + queue += subqueue; + subqueue = ''; + + while (index < length) { + character = value.charAt(index); + + if (character !== C_SPACE$3) { + break; + } + + subqueue += character; + index++; + } + + if (subqueue.length === 0) { + break; + } + + queue += subqueue; + } + + if (queue) { + content += queue; + queue = ''; + } + + content += character; + index++; + } + + subvalue += content; + + content = content.replace(EXPRESSION_INITIAL_TAB, function (line) { + offsets[currentLine] = (offsets[currentLine] || 0) + line.length; + currentLine++; + + return ''; + }); + + add = eat(subvalue); + + exit = self.enterBlock(); + content = self.tokenizeBlock(content, now); + exit(); + + return add({ + type: 'footnoteDefinition', + identifier: identifier, + children: content + }); +} + +var definition_1 = definition; +definition.notInList = true; +definition.notInBlock = true; + +var C_DOUBLE_QUOTE$1 = '"'; +var C_SINGLE_QUOTE$1 = '\''; +var C_BACKSLASH$3 = '\\'; +var C_NEWLINE$2 = '\n'; +var C_TAB$2 = '\t'; +var C_SPACE$2 = ' '; +var C_BRACKET_OPEN$3 = '['; +var C_BRACKET_CLOSE$3 = ']'; +var C_PAREN_OPEN$2 = '('; +var C_PAREN_CLOSE$2 = ')'; +var C_COLON$1 = ':'; +var C_LT$3 = '<'; +var C_GT$2 = '>'; + +function definition(eat, value, silent) { + var self = this; + var commonmark = self.options.commonmark; + var index = 0; + var length = value.length; + var subvalue = ''; + var beforeURL; + var beforeTitle; + var queue; + var character; + var test; + var identifier; + var url; + var title; + + while (index < length) { + character = value.charAt(index); + + if (character !== C_SPACE$2 && character !== C_TAB$2) { + break; + } + + subvalue += character; + index++; + } + + character = value.charAt(index); + + if (character !== C_BRACKET_OPEN$3) { + return; + } + + index++; + subvalue += character; + queue = ''; + + while (index < length) { + character = value.charAt(index); + + if (character === C_BRACKET_CLOSE$3) { + break; + } else if (character === C_BACKSLASH$3) { + queue += character; + index++; + character = value.charAt(index); + } + + queue += character; + index++; + } + + if ( + !queue || + value.charAt(index) !== C_BRACKET_CLOSE$3 || + value.charAt(index + 1) !== C_COLON$1 + ) { + return; + } + + identifier = queue; + subvalue += queue + C_BRACKET_CLOSE$3 + C_COLON$1; + index = subvalue.length; + queue = ''; + + while (index < length) { + character = value.charAt(index); + + if ( + character !== C_TAB$2 && + character !== C_SPACE$2 && + character !== C_NEWLINE$2 + ) { + break; + } + + subvalue += character; + index++; + } + + character = value.charAt(index); + queue = ''; + beforeURL = subvalue; + + if (character === C_LT$3) { + index++; + + while (index < length) { + character = value.charAt(index); + + if (!isEnclosedURLCharacter(character)) { + break; + } + + queue += character; + index++; + } + + character = value.charAt(index); + + if (character === isEnclosedURLCharacter.delimiter) { + subvalue += C_LT$3 + queue + character; + index++; + } else { + if (commonmark) { + return; + } + + index -= queue.length + 1; + queue = ''; + } + } + + if (!queue) { + while (index < length) { + character = value.charAt(index); + + if (!isUnclosedURLCharacter(character)) { + break; + } + + queue += character; + index++; + } + + subvalue += queue; + } + + if (!queue) { + return; + } + + url = queue; + queue = ''; + + while (index < length) { + character = value.charAt(index); + + if ( + character !== C_TAB$2 && + character !== C_SPACE$2 && + character !== C_NEWLINE$2 + ) { + break; + } + + queue += character; + index++; + } + + character = value.charAt(index); + test = null; + + if (character === C_DOUBLE_QUOTE$1) { + test = C_DOUBLE_QUOTE$1; + } else if (character === C_SINGLE_QUOTE$1) { + test = C_SINGLE_QUOTE$1; + } else if (character === C_PAREN_OPEN$2) { + test = C_PAREN_CLOSE$2; + } + + if (!test) { + queue = ''; + index = subvalue.length; + } else if (queue) { + subvalue += queue + character; + index = subvalue.length; + queue = ''; + + while (index < length) { + character = value.charAt(index); + + if (character === test) { + break; + } + + if (character === C_NEWLINE$2) { + index++; + character = value.charAt(index); + + if (character === C_NEWLINE$2 || character === test) { + return; + } + + queue += C_NEWLINE$2; + } + + queue += character; + index++; + } + + character = value.charAt(index); + + if (character !== test) { + return; + } + + beforeTitle = subvalue; + subvalue += queue + character; + index++; + title = queue; + queue = ''; + } else { + return; + } + + while (index < length) { + character = value.charAt(index); + + if (character !== C_TAB$2 && character !== C_SPACE$2) { + break; + } + + subvalue += character; + index++; + } + + character = value.charAt(index); + + if (!character || character === C_NEWLINE$2) { + if (silent) { + return true; + } + + beforeURL = eat(beforeURL).test().end; + url = self.decode.raw(self.unescape(url), beforeURL, {nonTerminated: false}); + + if (title) { + beforeTitle = eat(beforeTitle).test().end; + title = self.decode.raw(self.unescape(title), beforeTitle); + } + + return eat(subvalue)({ + type: 'definition', + identifier: normalize_1(identifier), + title: title || null, + url: url + }); + } +} + +/* Check if `character` can be inside an enclosed URI. */ +function isEnclosedURLCharacter(character) { + return character !== C_GT$2 && + character !== C_BRACKET_OPEN$3 && + character !== C_BRACKET_CLOSE$3; +} + +isEnclosedURLCharacter.delimiter = C_GT$2; + +/* Check if `character` can be inside an unclosed URI. */ +function isUnclosedURLCharacter(character) { + return character !== C_BRACKET_OPEN$3 && + character !== C_BRACKET_CLOSE$3 && + !isWhitespaceCharacter(character); +} + +var table_1 = table; + +var C_BACKSLASH$2 = '\\'; +var C_TICK$2 = '`'; +var C_DASH = '-'; +var C_PIPE = '|'; +var C_COLON = ':'; +var C_SPACE$1 = ' '; +var C_NEWLINE$1 = '\n'; +var C_TAB$1 = '\t'; + +var MIN_TABLE_COLUMNS = 1; +var MIN_TABLE_ROWS = 2; + +var TABLE_ALIGN_LEFT = 'left'; +var TABLE_ALIGN_CENTER = 'center'; +var TABLE_ALIGN_RIGHT = 'right'; +var TABLE_ALIGN_NONE = null; + +function table(eat, value, silent) { + var self = this; + var index; + var alignments; + var alignment; + var subvalue; + var row; + var length; + var lines; + var queue; + var character; + var hasDash; + var align; + var cell; + var preamble; + var count; + var opening; + var now; + var position; + var lineCount; + var line; + var rows; + var table; + var lineIndex; + var pipeIndex; + var first; + + /* Exit when not in gfm-mode. */ + if (!self.options.gfm) { + return; + } + + /* Get the rows. + * Detecting tables soon is hard, so there are some + * checks for performance here, such as the minimum + * number of rows, and allowed characters in the + * alignment row. */ + index = 0; + lineCount = 0; + length = value.length + 1; + lines = []; + + while (index < length) { + lineIndex = value.indexOf(C_NEWLINE$1, index); + pipeIndex = value.indexOf(C_PIPE, index + 1); + + if (lineIndex === -1) { + lineIndex = value.length; + } + + if (pipeIndex === -1 || pipeIndex > lineIndex) { + if (lineCount < MIN_TABLE_ROWS) { + return; + } + + break; + } + + lines.push(value.slice(index, lineIndex)); + lineCount++; + index = lineIndex + 1; + } + + /* Parse the alignment row. */ + subvalue = lines.join(C_NEWLINE$1); + alignments = lines.splice(1, 1)[0] || []; + index = 0; + length = alignments.length; + lineCount--; + alignment = false; + align = []; + + while (index < length) { + character = alignments.charAt(index); + + if (character === C_PIPE) { + hasDash = null; + + if (alignment === false) { + if (first === false) { + return; + } + } else { + align.push(alignment); + alignment = false; + } + + first = false; + } else if (character === C_DASH) { + hasDash = true; + alignment = alignment || TABLE_ALIGN_NONE; + } else if (character === C_COLON) { + if (alignment === TABLE_ALIGN_LEFT) { + alignment = TABLE_ALIGN_CENTER; + } else if (hasDash && alignment === TABLE_ALIGN_NONE) { + alignment = TABLE_ALIGN_RIGHT; + } else { + alignment = TABLE_ALIGN_LEFT; + } + } else if (!isWhitespaceCharacter(character)) { + return; + } + + index++; + } + + if (alignment !== false) { + align.push(alignment); + } + + /* Exit when without enough columns. */ + if (align.length < MIN_TABLE_COLUMNS) { + return; + } + + /* istanbul ignore if - never used (yet) */ + if (silent) { + return true; + } + + /* Parse the rows. */ + position = -1; + rows = []; + + table = eat(subvalue).reset({ + type: 'table', + align: align, + children: rows + }); + + while (++position < lineCount) { + line = lines[position]; + row = {type: 'tableRow', children: []}; + + /* Eat a newline character when this is not the + * first row. */ + if (position) { + eat(C_NEWLINE$1); + } + + /* Eat the row. */ + eat(line).reset(row, table); + + length = line.length + 1; + index = 0; + queue = ''; + cell = ''; + preamble = true; + count = null; + opening = null; + + while (index < length) { + character = line.charAt(index); + + if (character === C_TAB$1 || character === C_SPACE$1) { + if (cell) { + queue += character; + } else { + eat(character); + } + + index++; + continue; + } + + if (character === '' || character === C_PIPE) { + if (preamble) { + eat(character); + } else { + if (character && opening) { + queue += character; + index++; + continue; + } + + if ((cell || character) && !preamble) { + subvalue = cell; + + if (queue.length > 1) { + if (character) { + subvalue += queue.slice(0, queue.length - 1); + queue = queue.charAt(queue.length - 1); + } else { + subvalue += queue; + queue = ''; + } + } + + now = eat.now(); + + eat(subvalue)({ + type: 'tableCell', + children: self.tokenizeInline(cell, now) + }, row); + } + + eat(queue + character); + + queue = ''; + cell = ''; + } + } else { + if (queue) { + cell += queue; + queue = ''; + } + + cell += character; + + if (character === C_BACKSLASH$2 && index !== length - 2) { + cell += line.charAt(index + 1); + index++; + } + + if (character === C_TICK$2) { + count = 1; + + while (line.charAt(index + 1) === character) { + cell += character; + index++; + count++; + } + + if (!opening) { + opening = count; + } else if (count >= opening) { + opening = 0; + } + } + } + + preamble = false; + index++; + } + + /* Eat the alignment row. */ + if (!position) { + eat(C_NEWLINE$1 + alignments); + } + } + + return table; +} + +var paragraph_1 = paragraph; + +var C_NEWLINE = '\n'; +var C_TAB = '\t'; +var C_SPACE = ' '; + +var TAB_SIZE = 4; + +/* Tokenise paragraph. */ +function paragraph(eat, value, silent) { + var self = this; + var settings = self.options; + var commonmark = settings.commonmark; + var gfm = settings.gfm; + var tokenizers = self.blockTokenizers; + var interruptors = self.interruptParagraph; + var index = value.indexOf(C_NEWLINE); + var length = value.length; + var position; + var subvalue; + var character; + var size; + var now; + + while (index < length) { + /* Eat everything if there’s no following newline. */ + if (index === -1) { + index = length; + break; + } + + /* Stop if the next character is NEWLINE. */ + if (value.charAt(index + 1) === C_NEWLINE) { + break; + } + + /* In commonmark-mode, following indented lines + * are part of the paragraph. */ + if (commonmark) { + size = 0; + position = index + 1; + + while (position < length) { + character = value.charAt(position); + + if (character === C_TAB) { + size = TAB_SIZE; + break; + } else if (character === C_SPACE) { + size++; + } else { + break; + } + + position++; + } + + if (size >= TAB_SIZE) { + index = value.indexOf(C_NEWLINE, index + 1); + continue; + } + } + + subvalue = value.slice(index + 1); + + /* Check if the following code contains a possible + * block. */ + if (interrupt_1(interruptors, tokenizers, self, [eat, subvalue, true])) { + break; + } + + /* Break if the following line starts a list, when + * already in a list, or when in commonmark, or when + * in gfm mode and the bullet is *not* numeric. */ + if ( + tokenizers.list.call(self, eat, subvalue, true) && + ( + self.inList || + commonmark || + (gfm && !isDecimal(trim_1.left(subvalue).charAt(0))) + ) + ) { + break; + } + + position = index; + index = value.indexOf(C_NEWLINE, index + 1); + + if (index !== -1 && trim_1(value.slice(position, index)) === '') { + index = position; + break; + } + } + + subvalue = value.slice(0, index); + + if (trim_1(subvalue) === '') { + eat(subvalue); + + return null; + } + + /* istanbul ignore if - never used (yet) */ + if (silent) { + return true; + } + + now = eat.now(); + subvalue = trimTrailingLines_1(subvalue); + + return eat(subvalue)({ + type: 'paragraph', + children: self.tokenizeInline(subvalue, now) + }); +} + +var _escape$1 = locate$8; + +function locate$8(value, fromIndex) { + return value.indexOf('\\', fromIndex); +} + +var _escape = escape; +escape.locator = _escape$1; + +function escape(eat, value, silent) { + var self = this; + var character; + var node; + + if (value.charAt(0) === '\\') { + character = value.charAt(1); + + if (self.escape.indexOf(character) !== -1) { + /* istanbul ignore if - never used (yet) */ + if (silent) { + return true; + } + + if (character === '\n') { + node = {type: 'break'}; + } else { + node = { + type: 'text', + value: character + }; + } + + return eat('\\' + character)(node); + } + } +} + +var tag$1 = locate$7; + +function locate$7(value, fromIndex) { + return value.indexOf('<', fromIndex); +} + +var autoLink_1 = autoLink; +autoLink.locator = tag$1; +autoLink.notInLink = true; + +var C_LT$2 = '<'; +var C_GT$1 = '>'; +var C_AT_SIGN$1 = '@'; +var C_SLASH = '/'; +var MAILTO = 'mailto:'; +var MAILTO_LENGTH = MAILTO.length; + +/* Tokenise a link. */ +function autoLink(eat, value, silent) { + var self; + var subvalue; + var length; + var index; + var queue; + var character; + var hasAtCharacter; + var link; + var now; + var content; + var tokenizers; + var exit; + + if (value.charAt(0) !== C_LT$2) { + return; + } + + self = this; + subvalue = ''; + length = value.length; + index = 0; + queue = ''; + hasAtCharacter = false; + link = ''; + + index++; + subvalue = C_LT$2; + + while (index < length) { + character = value.charAt(index); + + if ( + isWhitespaceCharacter(character) || + character === C_GT$1 || + character === C_AT_SIGN$1 || + (character === ':' && value.charAt(index + 1) === C_SLASH) + ) { + break; + } + + queue += character; + index++; + } + + if (!queue) { + return; + } + + link += queue; + queue = ''; + + character = value.charAt(index); + link += character; + index++; + + if (character === C_AT_SIGN$1) { + hasAtCharacter = true; + } else { + if ( + character !== ':' || + value.charAt(index + 1) !== C_SLASH + ) { + return; + } + + link += C_SLASH; + index++; + } + + while (index < length) { + character = value.charAt(index); + + if (isWhitespaceCharacter(character) || character === C_GT$1) { + break; + } + + queue += character; + index++; + } + + character = value.charAt(index); + + if (!queue || character !== C_GT$1) { + return; + } + + /* istanbul ignore if - never used (yet) */ + if (silent) { + return true; + } + + link += queue; + content = link; + subvalue += link + character; + now = eat.now(); + now.column++; + now.offset++; + + if (hasAtCharacter) { + if (link.slice(0, MAILTO_LENGTH).toLowerCase() === MAILTO) { + content = content.substr(MAILTO_LENGTH); + now.column += MAILTO_LENGTH; + now.offset += MAILTO_LENGTH; + } else { + link = MAILTO + link; + } + } + + /* Temporarily remove all tokenizers except text in autolinks. */ + tokenizers = self.inlineTokenizers; + self.inlineTokenizers = {text: tokenizers.text}; + + exit = self.enterLink(); + + content = self.tokenizeInline(content, now); + + self.inlineTokenizers = tokenizers; + exit(); + + return eat(subvalue)({ + type: 'link', + title: null, + url: parseEntities_1(link, {nonTerminated: false}), + children: content + }); +} + +var url$1 = locate$6; + +var PROTOCOLS$1 = ['https://', 'http://', 'mailto:']; + +function locate$6(value, fromIndex) { + var length = PROTOCOLS$1.length; + var index = -1; + var min = -1; + var position; + + if (!this.options.gfm) { + return -1; + } + + while (++index < length) { + position = value.indexOf(PROTOCOLS$1[index], fromIndex); + + if (position !== -1 && (position < min || min === -1)) { + min = position; + } + } + + return min; +} + +var url_1 = url; +url.locator = url$1; +url.notInLink = true; + +var C_BRACKET_OPEN$2 = '['; +var C_BRACKET_CLOSE$2 = ']'; +var C_PAREN_OPEN$1 = '('; +var C_PAREN_CLOSE$1 = ')'; +var C_LT$1 = '<'; +var C_AT_SIGN = '@'; + +var HTTP_PROTOCOL = 'http://'; +var HTTPS_PROTOCOL = 'https://'; +var MAILTO_PROTOCOL = 'mailto:'; + +var PROTOCOLS = [ + HTTP_PROTOCOL, + HTTPS_PROTOCOL, + MAILTO_PROTOCOL +]; + +var PROTOCOLS_LENGTH = PROTOCOLS.length; + +function url(eat, value, silent) { + var self = this; + var subvalue; + var content; + var character; + var index; + var position; + var protocol; + var match; + var length; + var queue; + var parenCount; + var nextCharacter; + var exit; + + if (!self.options.gfm) { + return; + } + + subvalue = ''; + index = -1; + length = PROTOCOLS_LENGTH; + + while (++index < length) { + protocol = PROTOCOLS[index]; + match = value.slice(0, protocol.length); + + if (match.toLowerCase() === protocol) { + subvalue = match; + break; + } + } + + if (!subvalue) { + return; + } + + index = subvalue.length; + length = value.length; + queue = ''; + parenCount = 0; + + while (index < length) { + character = value.charAt(index); + + if (isWhitespaceCharacter(character) || character === C_LT$1) { + break; + } + + if ( + character === '.' || + character === ',' || + character === ':' || + character === ';' || + character === '"' || + character === '\'' || + character === ')' || + character === ']' + ) { + nextCharacter = value.charAt(index + 1); + + if (!nextCharacter || isWhitespaceCharacter(nextCharacter)) { + break; + } + } + + if (character === C_PAREN_OPEN$1 || character === C_BRACKET_OPEN$2) { + parenCount++; + } + + if (character === C_PAREN_CLOSE$1 || character === C_BRACKET_CLOSE$2) { + parenCount--; + + if (parenCount < 0) { + break; + } + } + + queue += character; + index++; + } + + if (!queue) { + return; + } + + subvalue += queue; + content = subvalue; + + if (protocol === MAILTO_PROTOCOL) { + position = queue.indexOf(C_AT_SIGN); + + if (position === -1 || position === length - 1) { + return; + } + + content = content.substr(MAILTO_PROTOCOL.length); + } + + /* istanbul ignore if - never used (yet) */ + if (silent) { + return true; + } + + exit = self.enterLink(); + content = self.tokenizeInline(content, eat.now()); + exit(); + + return eat(subvalue)({ + type: 'link', + title: null, + url: parseEntities_1(subvalue, {nonTerminated: false}), + children: content + }); +} + +var tag = html.tag; + +var htmlInline = inlineHTML; +inlineHTML.locator = tag$1; + +var EXPRESSION_HTML_LINK_OPEN = /^
/i; + +function inlineHTML(eat, value, silent) { + var self = this; + var length = value.length; + var character; + var subvalue; + + if (value.charAt(0) !== '<' || length < 3) { + return; + } + + character = value.charAt(1); + + if ( + !isAlphabetical(character) && + character !== '?' && + character !== '!' && + character !== '/' + ) { + return; + } + + subvalue = value.match(tag); + + if (!subvalue) { + return; + } + + /* istanbul ignore if - not used yet. */ + if (silent) { + return true; + } + + subvalue = subvalue[0]; + + if (!self.inLink && EXPRESSION_HTML_LINK_OPEN.test(subvalue)) { + self.inLink = true; + } else if (self.inLink && EXPRESSION_HTML_LINK_CLOSE.test(subvalue)) { + self.inLink = false; + } + + return eat(subvalue)({type: 'html', value: subvalue}); +} + +var link$1 = locate$5; + +function locate$5(value, fromIndex) { + var link = value.indexOf('[', fromIndex); + var image = value.indexOf('![', fromIndex); + + if (image === -1) { + return link; + } + + /* Link can never be `-1` if an image is found, so we don’t need + * to check for that :) */ + return link < image ? link : image; +} + +var link_1 = link; +link.locator = link$1; + +var own = {}.hasOwnProperty; + +var C_BACKSLASH$1 = '\\'; +var C_BRACKET_OPEN$1 = '['; +var C_BRACKET_CLOSE$1 = ']'; +var C_PAREN_OPEN = '('; +var C_PAREN_CLOSE = ')'; +var C_LT = '<'; +var C_GT = '>'; +var C_TICK$1 = '`'; +var C_DOUBLE_QUOTE = '"'; +var C_SINGLE_QUOTE = '\''; + +/* Map of characters, which can be used to mark link + * and image titles. */ +var LINK_MARKERS = {}; + +LINK_MARKERS[C_DOUBLE_QUOTE] = C_DOUBLE_QUOTE; +LINK_MARKERS[C_SINGLE_QUOTE] = C_SINGLE_QUOTE; + +/* Map of characters, which can be used to mark link + * and image titles in commonmark-mode. */ +var COMMONMARK_LINK_MARKERS = {}; + +COMMONMARK_LINK_MARKERS[C_DOUBLE_QUOTE] = C_DOUBLE_QUOTE; +COMMONMARK_LINK_MARKERS[C_SINGLE_QUOTE] = C_SINGLE_QUOTE; +COMMONMARK_LINK_MARKERS[C_PAREN_OPEN] = C_PAREN_CLOSE; + +function link(eat, value, silent) { + var self = this; + var subvalue = ''; + var index = 0; + var character = value.charAt(0); + var pedantic = self.options.pedantic; + var commonmark = self.options.commonmark; + var gfm = self.options.gfm; + var closed; + var count; + var opening; + var beforeURL; + var beforeTitle; + var subqueue; + var hasMarker; + var markers; + var isImage; + var content; + var marker; + var length; + var title; + var depth; + var queue; + var url; + var now; + var exit; + var node; + + /* Detect whether this is an image. */ + if (character === '!') { + isImage = true; + subvalue = character; + character = value.charAt(++index); + } + + /* Eat the opening. */ + if (character !== C_BRACKET_OPEN$1) { + return; + } + + /* Exit when this is a link and we’re already inside + * a link. */ + if (!isImage && self.inLink) { + return; + } + + subvalue += character; + queue = ''; + index++; + + /* Eat the content. */ + length = value.length; + now = eat.now(); + depth = 0; + + now.column += index; + now.offset += index; + + while (index < length) { + character = value.charAt(index); + subqueue = character; + + if (character === C_TICK$1) { + /* Inline-code in link content. */ + count = 1; + + while (value.charAt(index + 1) === C_TICK$1) { + subqueue += character; + index++; + count++; + } + + if (!opening) { + opening = count; + } else if (count >= opening) { + opening = 0; + } + } else if (character === C_BACKSLASH$1) { + /* Allow brackets to be escaped. */ + index++; + subqueue += value.charAt(index); + /* In GFM mode, brackets in code still count. + * In all other modes, they don’t. This empty + * block prevents the next statements are + * entered. */ + } else if ((!opening || gfm) && character === C_BRACKET_OPEN$1) { + depth++; + } else if ((!opening || gfm) && character === C_BRACKET_CLOSE$1) { + if (depth) { + depth--; + } else { + /* Allow white-space between content and + * url in GFM mode. */ + if (!pedantic) { + while (index < length) { + character = value.charAt(index + 1); + + if (!isWhitespaceCharacter(character)) { + break; + } + + subqueue += character; + index++; + } + } + + if (value.charAt(index + 1) !== C_PAREN_OPEN) { + return; + } + + subqueue += C_PAREN_OPEN; + closed = true; + index++; + + break; + } + } + + queue += subqueue; + subqueue = ''; + index++; + } + + /* Eat the content closing. */ + if (!closed) { + return; + } + + content = queue; + subvalue += queue + subqueue; + index++; + + /* Eat white-space. */ + while (index < length) { + character = value.charAt(index); + + if (!isWhitespaceCharacter(character)) { + break; + } + + subvalue += character; + index++; + } + + /* Eat the URL. */ + character = value.charAt(index); + markers = commonmark ? COMMONMARK_LINK_MARKERS : LINK_MARKERS; + queue = ''; + beforeURL = subvalue; + + if (character === C_LT) { + index++; + beforeURL += C_LT; + + while (index < length) { + character = value.charAt(index); + + if (character === C_GT) { + break; + } + + if (commonmark && character === '\n') { + return; + } + + queue += character; + index++; + } + + if (value.charAt(index) !== C_GT) { + return; + } + + subvalue += C_LT + queue + C_GT; + url = queue; + index++; + } else { + character = null; + subqueue = ''; + + while (index < length) { + character = value.charAt(index); + + if (subqueue && own.call(markers, character)) { + break; + } + + if (isWhitespaceCharacter(character)) { + if (!pedantic) { + break; + } + + subqueue += character; + } else { + if (character === C_PAREN_OPEN) { + depth++; + } else if (character === C_PAREN_CLOSE) { + if (depth === 0) { + break; + } + + depth--; + } + + queue += subqueue; + subqueue = ''; + + if (character === C_BACKSLASH$1) { + queue += C_BACKSLASH$1; + character = value.charAt(++index); + } + + queue += character; + } + + index++; + } + + subvalue += queue; + url = queue; + index = subvalue.length; + } + + /* Eat white-space. */ + queue = ''; + + while (index < length) { + character = value.charAt(index); + + if (!isWhitespaceCharacter(character)) { + break; + } + + queue += character; + index++; + } + + character = value.charAt(index); + subvalue += queue; + + /* Eat the title. */ + if (queue && own.call(markers, character)) { + index++; + subvalue += character; + queue = ''; + marker = markers[character]; + beforeTitle = subvalue; + + /* In commonmark-mode, things are pretty easy: the + * marker cannot occur inside the title. + * + * Non-commonmark does, however, support nested + * delimiters. */ + if (commonmark) { + while (index < length) { + character = value.charAt(index); + + if (character === marker) { + break; + } + + if (character === C_BACKSLASH$1) { + queue += C_BACKSLASH$1; + character = value.charAt(++index); + } + + index++; + queue += character; + } + + character = value.charAt(index); + + if (character !== marker) { + return; + } + + title = queue; + subvalue += queue + character; + index++; + + while (index < length) { + character = value.charAt(index); + + if (!isWhitespaceCharacter(character)) { + break; + } + + subvalue += character; + index++; + } + } else { + subqueue = ''; + + while (index < length) { + character = value.charAt(index); + + if (character === marker) { + if (hasMarker) { + queue += marker + subqueue; + subqueue = ''; + } + + hasMarker = true; + } else if (!hasMarker) { + queue += character; + } else if (character === C_PAREN_CLOSE) { + subvalue += queue + marker + subqueue; + title = queue; + break; + } else if (isWhitespaceCharacter(character)) { + subqueue += character; + } else { + queue += marker + subqueue + character; + subqueue = ''; + hasMarker = false; + } + + index++; + } + } + } + + if (value.charAt(index) !== C_PAREN_CLOSE) { + return; + } + + /* istanbul ignore if - never used (yet) */ + if (silent) { + return true; + } + + subvalue += C_PAREN_CLOSE; + + url = self.decode.raw(self.unescape(url), eat(beforeURL).test().end, {nonTerminated: false}); + + if (title) { + beforeTitle = eat(beforeTitle).test().end; + title = self.decode.raw(self.unescape(title), beforeTitle); + } + + node = { + type: isImage ? 'image' : 'link', + title: title || null, + url: url + }; + + if (isImage) { + node.alt = self.decode.raw(self.unescape(content), now) || null; + } else { + exit = self.enterLink(); + node.children = self.tokenizeInline(content, now); + exit(); + } + + return eat(subvalue)(node); +} + +var reference_1 = reference; +reference.locator = link$1; + +var T_LINK = 'link'; +var T_IMAGE = 'image'; +var T_FOOTNOTE = 'footnote'; +var REFERENCE_TYPE_SHORTCUT = 'shortcut'; +var REFERENCE_TYPE_COLLAPSED = 'collapsed'; +var REFERENCE_TYPE_FULL = 'full'; +var C_CARET = '^'; +var C_BACKSLASH = '\\'; +var C_BRACKET_OPEN = '['; +var C_BRACKET_CLOSE = ']'; + +function reference(eat, value, silent) { + var self = this; + var character = value.charAt(0); + var index = 0; + var length = value.length; + var subvalue = ''; + var intro = ''; + var type = T_LINK; + var referenceType = REFERENCE_TYPE_SHORTCUT; + var content; + var identifier; + var now; + var node; + var exit; + var queue; + var bracketed; + var depth; + + /* Check whether we’re eating an image. */ + if (character === '!') { + type = T_IMAGE; + intro = character; + character = value.charAt(++index); + } + + if (character !== C_BRACKET_OPEN) { + return; + } + + index++; + intro += character; + queue = ''; + + /* Check whether we’re eating a footnote. */ + if (self.options.footnotes && value.charAt(index) === C_CARET) { + /* Exit if `![^` is found, so the `!` will be seen as text after this, + * and we’ll enter this function again when `[^` is found. */ + if (type === T_IMAGE) { + return; + } + + intro += C_CARET; + index++; + type = T_FOOTNOTE; + } + + /* Eat the text. */ + depth = 0; + + while (index < length) { + character = value.charAt(index); + + if (character === C_BRACKET_OPEN) { + bracketed = true; + depth++; + } else if (character === C_BRACKET_CLOSE) { + if (!depth) { + break; + } + + depth--; + } + + if (character === C_BACKSLASH) { + queue += C_BACKSLASH; + character = value.charAt(++index); + } + + queue += character; + index++; + } + + subvalue = queue; + content = queue; + character = value.charAt(index); + + if (character !== C_BRACKET_CLOSE) { + return; + } + + index++; + subvalue += character; + queue = ''; + + while (index < length) { + character = value.charAt(index); + + if (!isWhitespaceCharacter(character)) { + break; + } + + queue += character; + index++; + } + + character = value.charAt(index); + + /* Inline footnotes cannot have an identifier. */ + if (type !== T_FOOTNOTE && character === C_BRACKET_OPEN) { + identifier = ''; + queue += character; + index++; + + while (index < length) { + character = value.charAt(index); + + if (character === C_BRACKET_OPEN || character === C_BRACKET_CLOSE) { + break; + } + + if (character === C_BACKSLASH) { + identifier += C_BACKSLASH; + character = value.charAt(++index); + } + + identifier += character; + index++; + } + + character = value.charAt(index); + + if (character === C_BRACKET_CLOSE) { + referenceType = identifier ? REFERENCE_TYPE_FULL : REFERENCE_TYPE_COLLAPSED; + queue += identifier + character; + index++; + } else { + identifier = ''; + } + + subvalue += queue; + queue = ''; + } else { + if (!content) { + return; + } + + identifier = content; + } + + /* Brackets cannot be inside the identifier. */ + if (referenceType !== REFERENCE_TYPE_FULL && bracketed) { + return; + } + + subvalue = intro + subvalue; + + if (type === T_LINK && self.inLink) { + return null; + } + + /* istanbul ignore if - never used (yet) */ + if (silent) { + return true; + } + + if (type === T_FOOTNOTE && content.indexOf(' ') !== -1) { + return eat(subvalue)({ + type: 'footnote', + children: this.tokenizeInline(content, eat.now()) + }); + } + + now = eat.now(); + now.column += intro.length; + now.offset += intro.length; + identifier = referenceType === REFERENCE_TYPE_FULL ? identifier : content; + + node = { + type: type + 'Reference', + identifier: normalize_1(identifier) + }; + + if (type === T_LINK || type === T_IMAGE) { + node.referenceType = referenceType; + } + + if (type === T_LINK) { + exit = self.enterLink(); + node.children = self.tokenizeInline(content, now); + exit(); + } else if (type === T_IMAGE) { + node.alt = self.decode.raw(self.unescape(content), now) || null; + } + + return eat(subvalue)(node); +} + +var strong$1 = locate$4; + +function locate$4(value, fromIndex) { + var asterisk = value.indexOf('**', fromIndex); + var underscore = value.indexOf('__', fromIndex); + + if (underscore === -1) { + return asterisk; + } + + if (asterisk === -1) { + return underscore; + } + + return underscore < asterisk ? underscore : asterisk; +} + +var strong_1 = strong; +strong.locator = strong$1; + +var C_ASTERISK$1 = '*'; +var C_UNDERSCORE$1 = '_'; + +function strong(eat, value, silent) { + var self = this; + var index = 0; + var character = value.charAt(index); + var now; + var pedantic; + var marker; + var queue; + var subvalue; + var length; + var prev; + + if ( + (character !== C_ASTERISK$1 && character !== C_UNDERSCORE$1) || + value.charAt(++index) !== character + ) { + return; + } + + pedantic = self.options.pedantic; + marker = character; + subvalue = marker + marker; + length = value.length; + index++; + queue = ''; + character = ''; + + if (pedantic && isWhitespaceCharacter(value.charAt(index))) { + return; + } + + while (index < length) { + prev = character; + character = value.charAt(index); + + if ( + character === marker && + value.charAt(index + 1) === marker && + (!pedantic || !isWhitespaceCharacter(prev)) + ) { + character = value.charAt(index + 2); + + if (character !== marker) { + if (!trim_1(queue)) { + return; + } + + /* istanbul ignore if - never used (yet) */ + if (silent) { + return true; + } + + now = eat.now(); + now.column += 2; + now.offset += 2; + + return eat(subvalue + queue + subvalue)({ + type: 'strong', + children: self.tokenizeInline(queue, now) + }); + } + } + + if (!pedantic && character === '\\') { + queue += character; + character = value.charAt(++index); + } + + queue += character; + index++; + } +} + +var isWordCharacter = wordCharacter; + +var fromCode = String.fromCharCode; +var re = /\w/; + +// Check if the given character code, or the character code at the first +// character, is a word character. +function wordCharacter(character) { + return re.test( + typeof character === 'number' ? fromCode(character) : character.charAt(0) + ) +} + +var emphasis$1 = locate$3; + +function locate$3(value, fromIndex) { + var asterisk = value.indexOf('*', fromIndex); + var underscore = value.indexOf('_', fromIndex); + + if (underscore === -1) { + return asterisk; + } + + if (asterisk === -1) { + return underscore; + } + + return underscore < asterisk ? underscore : asterisk; +} + +var emphasis_1 = emphasis; +emphasis.locator = emphasis$1; + +var C_ASTERISK = '*'; +var C_UNDERSCORE = '_'; + +function emphasis(eat, value, silent) { + var self = this; + var index = 0; + var character = value.charAt(index); + var now; + var pedantic; + var marker; + var queue; + var subvalue; + var length; + var prev; + + if (character !== C_ASTERISK && character !== C_UNDERSCORE) { + return; + } + + pedantic = self.options.pedantic; + subvalue = character; + marker = character; + length = value.length; + index++; + queue = ''; + character = ''; + + if (pedantic && isWhitespaceCharacter(value.charAt(index))) { + return; + } + + while (index < length) { + prev = character; + character = value.charAt(index); + + if (character === marker && (!pedantic || !isWhitespaceCharacter(prev))) { + character = value.charAt(++index); + + if (character !== marker) { + if (!trim_1(queue) || prev === marker) { + return; + } + + if (!pedantic && marker === C_UNDERSCORE && isWordCharacter(character)) { + queue += marker; + continue; + } + + /* istanbul ignore if - never used (yet) */ + if (silent) { + return true; + } + + now = eat.now(); + now.column++; + now.offset++; + + return eat(subvalue + queue + marker)({ + type: 'emphasis', + children: self.tokenizeInline(queue, now) + }); + } + + queue += marker; + } + + if (!pedantic && character === '\\') { + queue += character; + character = value.charAt(++index); + } + + queue += character; + index++; + } +} + +var _delete$1 = locate$2; + +function locate$2(value, fromIndex) { + return value.indexOf('~~', fromIndex); +} + +var _delete = strikethrough; +strikethrough.locator = _delete$1; + +var C_TILDE = '~'; +var DOUBLE = '~~'; + +function strikethrough(eat, value, silent) { + var self = this; + var character = ''; + var previous = ''; + var preceding = ''; + var subvalue = ''; + var index; + var length; + var now; + + if ( + !self.options.gfm || + value.charAt(0) !== C_TILDE || + value.charAt(1) !== C_TILDE || + isWhitespaceCharacter(value.charAt(2)) + ) { + return; + } + + index = 1; + length = value.length; + now = eat.now(); + now.column += 2; + now.offset += 2; + + while (++index < length) { + character = value.charAt(index); + + if ( + character === C_TILDE && + previous === C_TILDE && + (!preceding || !isWhitespaceCharacter(preceding)) + ) { + /* istanbul ignore if - never used (yet) */ + if (silent) { + return true; + } + + return eat(DOUBLE + subvalue + DOUBLE)({ + type: 'delete', + children: self.tokenizeInline(subvalue, now) + }); + } + + subvalue += previous; + preceding = previous; + previous = character; + } +} + +var codeInline$1 = locate$1; + +function locate$1(value, fromIndex) { + return value.indexOf('`', fromIndex); +} + +var codeInline = inlineCode; +inlineCode.locator = codeInline$1; + +var C_TICK = '`'; + +/* Tokenise inline code. */ +function inlineCode(eat, value, silent) { + var length = value.length; + var index = 0; + var queue = ''; + var tickQueue = ''; + var contentQueue; + var subqueue; + var count; + var openingCount; + var subvalue; + var character; + var found; + var next; + + while (index < length) { + if (value.charAt(index) !== C_TICK) { + break; + } + + queue += C_TICK; + index++; + } + + if (!queue) { + return; + } + + subvalue = queue; + openingCount = index; + queue = ''; + next = value.charAt(index); + count = 0; + + while (index < length) { + character = next; + next = value.charAt(index + 1); + + if (character === C_TICK) { + count++; + tickQueue += character; + } else { + count = 0; + queue += character; + } + + if (count && next !== C_TICK) { + if (count === openingCount) { + subvalue += queue + tickQueue; + found = true; + break; + } + + queue += tickQueue; + tickQueue = ''; + } + + index++; + } + + if (!found) { + if (openingCount % 2 !== 0) { + return; + } + + queue = ''; + } + + /* istanbul ignore if - never used (yet) */ + if (silent) { + return true; + } + + contentQueue = ''; + subqueue = ''; + length = queue.length; + index = -1; + + while (++index < length) { + character = queue.charAt(index); + + if (isWhitespaceCharacter(character)) { + subqueue += character; + continue; + } + + if (subqueue) { + if (contentQueue) { + contentQueue += subqueue; + } + + subqueue = ''; + } + + contentQueue += character; + } + + return eat(subvalue)({ + type: 'inlineCode', + value: contentQueue + }); +} + +var _break$1 = locate; + +function locate(value, fromIndex) { + var index = value.indexOf('\n', fromIndex); + + while (index > fromIndex) { + if (value.charAt(index - 1) !== ' ') { + break; + } + + index--; + } + + return index; +} + +var _break = hardBreak; +hardBreak.locator = _break$1; + +var MIN_BREAK_LENGTH = 2; + +function hardBreak(eat, value, silent) { + var length = value.length; + var index = -1; + var queue = ''; + var character; + + while (++index < length) { + character = value.charAt(index); + + if (character === '\n') { + if (index < MIN_BREAK_LENGTH) { + return; + } + + /* istanbul ignore if - never used (yet) */ + if (silent) { + return true; + } + + queue += character; + + return eat(queue)({type: 'break'}); + } + + if (character !== ' ') { + return; + } + + queue += character; + } +} + +var text_1 = text; + +function text(eat, value, silent) { + var self = this; + var methods; + var tokenizers; + var index; + var length; + var subvalue; + var position; + var tokenizer; + var name; + var min; + var now; + + /* istanbul ignore if - never used (yet) */ + if (silent) { + return true; + } + + methods = self.inlineMethods; + length = methods.length; + tokenizers = self.inlineTokenizers; + index = -1; + min = value.length; + + while (++index < length) { + name = methods[index]; + + if (name === 'text' || !tokenizers[name]) { + continue; + } + + tokenizer = tokenizers[name].locator; + + if (!tokenizer) { + eat.file.fail('Missing locator: `' + name + '`'); + } + + position = tokenizer.call(self, value, 1); + + if (position !== -1 && position < min) { + min = position; + } + } + + subvalue = value.slice(0, min); + now = eat.now(); + + self.decode(subvalue, now, function (content, position, source) { + eat(source || content)({ + type: 'text', + value: content + }); + }); +} + +var parser = Parser; + +function Parser(doc, file) { + this.file = file; + this.offset = {}; + this.options = immutable(this.options); + this.setOptions({}); + + this.inList = false; + this.inBlock = false; + this.inLink = false; + this.atStart = true; + + this.toOffset = vfileLocation(file).toOffset; + this.unescape = _unescape(this, 'escape'); + this.decode = decode(this); +} + +var proto = Parser.prototype; + +/* Expose core. */ +proto.setOptions = setOptions_1; +proto.parse = parse_1; + +/* Expose `defaults`. */ +proto.options = defaults; + +/* Enter and exit helpers. */ +proto.exitStart = stateToggle('atStart', true); +proto.enterList = stateToggle('inList', false); +proto.enterLink = stateToggle('inLink', false); +proto.enterBlock = stateToggle('inBlock', false); + +/* Nodes that can interupt a paragraph: + * + * ```markdown + * A paragraph, followed by a thematic break. + * ___ + * ``` + * + * In the above example, the thematic break “interupts” + * the paragraph. */ +proto.interruptParagraph = [ + ['thematicBreak'], + ['atxHeading'], + ['fencedCode'], + ['blockquote'], + ['html'], + ['setextHeading', {commonmark: false}], + ['definition', {commonmark: false}], + ['footnote', {commonmark: false}] +]; + +/* Nodes that can interupt a list: + * + * ```markdown + * - One + * ___ + * ``` + * + * In the above example, the thematic break “interupts” + * the list. */ +proto.interruptList = [ + ['atxHeading', {pedantic: false}], + ['fencedCode', {pedantic: false}], + ['thematicBreak', {pedantic: false}], + ['definition', {commonmark: false}], + ['footnote', {commonmark: false}] +]; + +/* Nodes that can interupt a blockquote: + * + * ```markdown + * > A paragraph. + * ___ + * ``` + * + * In the above example, the thematic break “interupts” + * the blockquote. */ +proto.interruptBlockquote = [ + ['indentedCode', {commonmark: true}], + ['fencedCode', {commonmark: true}], + ['atxHeading', {commonmark: true}], + ['setextHeading', {commonmark: true}], + ['thematicBreak', {commonmark: true}], + ['html', {commonmark: true}], + ['list', {commonmark: true}], + ['definition', {commonmark: false}], + ['footnote', {commonmark: false}] +]; + +/* Handlers. */ +proto.blockTokenizers = { + newline: newline_1, + indentedCode: codeIndented, + fencedCode: codeFenced, + blockquote: blockquote_1, + atxHeading: headingAtx, + thematicBreak: thematicBreak_1, + list: list_1, + setextHeading: headingSetext, + html: htmlBlock, + footnote: footnoteDefinition_1, + definition: definition_1, + table: table_1, + paragraph: paragraph_1 +}; + +proto.inlineTokenizers = { + escape: _escape, + autoLink: autoLink_1, + url: url_1, + html: htmlInline, + link: link_1, + reference: reference_1, + strong: strong_1, + emphasis: emphasis_1, + deletion: _delete, + code: codeInline, + break: _break, + text: text_1 +}; + +/* Expose precedence. */ +proto.blockMethods = keys(proto.blockTokenizers); +proto.inlineMethods = keys(proto.inlineTokenizers); + +/* Tokenizers. */ +proto.tokenizeBlock = tokenizer('block'); +proto.tokenizeInline = tokenizer('inline'); +proto.tokenizeFactory = tokenizer; + +/* Get all keys in `value`. */ +function keys(value) { + var result = []; + var key; + + for (key in value) { + result.push(key); + } + + return result; +} + +var remarkParse = parse; +parse.Parser = parser; + +function parse(options) { + var Local = unherit_1(parser); + Local.prototype.options = immutable(Local.prototype.options, this.data('settings'), options); + this.Parser = Local; +} + +/** + * @fileoverview Processes Markdown files for consumption by ESLint. + * @author Brandon Mills + */ + + + + +const UNSATISFIABLE_RULES = [ + "eol-last", // The Markdown parser strips trailing newlines in code fences + "unicode-bom" // Code blocks will begin in the middle of Markdown files +]; +const SUPPORTS_AUTOFIX = true; + +const markdown = unified_1().use(remarkParse); + +/** + * @type {Map} + */ +const blocksCache = new Map(); + +/** + * Performs a depth-first traversal of the Markdown AST. + * @param {ASTNode} node A Markdown AST node. + * @param {{[key: string]: (node: ASTNode) => void}} callbacks A map of node types to callbacks. + * @returns {void} + */ +function traverse(node, callbacks) { + if (callbacks[node.type]) { + callbacks[node.type](node); + } else { + callbacks["*"](); + } + + if (typeof node.children !== "undefined") { + for (let i = 0; i < node.children.length; i++) { + traverse(node.children[i], callbacks); + } + } +} + +/** + * Extracts `eslint-*` or `global` comments from HTML comments if present. + * @param {string} html The text content of an HTML AST node. + * @returns {string} The comment's text without the opening and closing tags or + * an empty string if the text is not an ESLint HTML comment. + */ +function getComment(html) { + const commentStart = ""; + const regex = /^(eslint\b|global\s)/u; + + if ( + html.slice(0, commentStart.length) !== commentStart || + html.slice(-commentEnd.length) !== commentEnd + ) { + return ""; + } + + const comment = html.slice(commentStart.length, -commentEnd.length); + + if (!regex.test(comment.trim())) { + return ""; + } + + return comment; +} + +// Before a code block, blockquote characters (`>`) are also considered +// "whitespace". +const leadingWhitespaceRegex = /^[>\s]*/u; + +/** + * Gets the offset for the first column of the node's first line in the + * original source text. + * @param {ASTNode} node A Markdown code block AST node. + * @returns {number} The offset for the first column of the node's first line. + */ +function getBeginningOfLineOffset(node) { + return node.position.start.offset - node.position.start.column + 1; +} + +/** + * Gets the leading text, typically whitespace with possible blockquote chars, + * used to indent a code block. + * @param {string} text The text of the file. + * @param {ASTNode} node A Markdown code block AST node. + * @returns {string} The text from the start of the first line to the opening + * fence of the code block. + */ +function getIndentText(text, node) { + return leadingWhitespaceRegex.exec( + text.slice(getBeginningOfLineOffset(node)) + )[0]; +} + +/** + * When applying fixes, the postprocess step needs to know how to map fix ranges + * from their location in the linted JS to the original offset in the Markdown. + * Configuration comments and indentation trimming both complicate this process. + * + * Configuration comments appear in the linted JS but not in the Markdown code + * block. Fixes to configuration comments would cause undefined behavior and + * should be ignored during postprocessing. Fixes to actual code after + * configuration comments need to be mapped back to the code block after + * removing any offset due to configuration comments. + * + * Fenced code blocks can be indented by up to three spaces at the opening + * fence. Inside of a list, for example, this indent can be in addition to the + * indent already required for list item children. Leading whitespace inside + * indented code blocks is trimmed up to the level of the opening fence and does + * not appear in the linted code. Further, lines can have less leading + * whitespace than the opening fence, so not all lines are guaranteed to have + * the same column offset as the opening fence. + * + * The source code of a non-configuration-comment line in the linted JS is a + * suffix of the corresponding line in the Markdown code block. There are no + * differences within the line, so the mapping need only provide the offset + * delta at the beginning of each line. + * @param {string} text The text of the file. + * @param {ASTNode} node A Markdown code block AST node. + * @param {string[]} comments List of configuration comment strings that will be + * inserted at the beginning of the code block. + * @returns {RangeMap[]} A list of offset-based adjustments, where lookups are + * done based on the `js` key, which represents the range in the linted JS, + * and the `md` key is the offset delta that, when added to the JS range, + * returns the corresponding location in the original Markdown source. + */ +function getBlockRangeMap(text, node, comments) { + + /* + * The parser sets the fenced code block's start offset to wherever content + * should normally begin (typically the first column of the line, but more + * inside a list item, for example). The code block's opening fance may be + * further indented by up to three characters. If the code block has + * additional indenting, the opening fence's first backtick may be up to + * three whitespace characters after the start offset. + */ + const startOffset = getBeginningOfLineOffset(node); + + /* + * Extract the Markdown source to determine the leading whitespace for each + * line. + */ + const code = text.slice(startOffset, node.position.end.offset); + const lines = code.split("\n"); + + /* + * The parser trims leading whitespace from each line of code within the + * fenced code block up to the opening fence's first backtick. The first + * backtick's column is the AST node's starting column plus any additional + * indentation. + */ + const baseIndent = getIndentText(text, node).length; + + /* + * Track the length of any inserted configuration comments at the beginning + * of the linted JS and start the JS offset lookup keys at this index. + */ + const commentLength = comments.reduce((len, comment) => len + comment.length + 1, 0); + + /* + * In case there are configuration comments, initialize the map so that the + * first lookup index is always 0. If there are no configuration comments, + * the lookup index will also be 0, and the lookup should always go to the + * last range that matches, skipping this initialization entry. + */ + const rangeMap = [{ + js: 0, + md: 0 + }]; + + // Start the JS offset after any configuration comments. + let jsOffset = commentLength; + + /* + * Start the Markdown offset at the beginning of the block's first line of + * actual code. The first line of the block is always the opening fence, so + * the code begins on the second line. + */ + let mdOffset = startOffset + lines[0].length + 1; + + /* + * For each line, determine how much leading whitespace was trimmed due to + * indentation. Increase the JS lookup offset by the length of the line + * post-trimming and the Markdown offset by the total line length. + */ + for (let i = 0; i + 1 < lines.length; i++) { + const line = lines[i + 1]; + const leadingWhitespaceLength = leadingWhitespaceRegex.exec(line)[0].length; + + // The parser trims leading whitespace up to the level of the opening + // fence, so keep any additional indentation beyond that. + const trimLength = Math.min(baseIndent, leadingWhitespaceLength); + + rangeMap.push({ + js: jsOffset, + + // Advance `trimLength` character from the beginning of the Markdown + // line to the beginning of the equivalent JS line, then compute the + // delta. + md: mdOffset + trimLength - jsOffset + }); + + // Accumulate the current line in the offsets, and don't forget the + // newline. + mdOffset += line.length + 1; + jsOffset += line.length - trimLength + 1; + } + + return rangeMap; +} + +/** + * Extracts lintable code blocks from Markdown text. + * @param {string} text The text of the file. + * @param {string} filename The filename of the file + * @returns {Array<{ filename: string, text: string }>} Source code blocks to lint. + */ +function preprocess(text, filename) { + const ast = markdown.parse(text); + const blocks = []; + + blocksCache.set(filename, blocks); + + /** + * During the depth-first traversal, keep track of any sequences of HTML + * comment nodes containing `eslint-*` or `global` comments. If a code + * block immediately follows such a sequence, insert the comments at the + * top of the code block. Any non-ESLint comment or other node type breaks + * and empties the sequence. + * @type {string[]} + */ + let htmlComments = []; + + traverse(ast, { + "*"() { + htmlComments = []; + }, + code(node) { + if (node.lang) { + const comments = []; + + for (const comment of htmlComments) { + if (comment.trim() === "eslint-skip") { + htmlComments = []; + return; + } + + comments.push(`/*${comment}*/`); + } + + htmlComments = []; + + blocks.push({ + ...node, + baseIndentText: getIndentText(text, node), + comments, + rangeMap: getBlockRangeMap(text, node, comments) + }); + } + }, + html(node) { + const comment = getComment(node.value); + + if (comment) { + htmlComments.push(comment); + } else { + htmlComments = []; + } + } + }); + + return blocks.map((block, index) => ({ + filename: `${index}.${block.lang.trim().split(" ")[0]}`, + text: [ + ...block.comments, + block.value, + "" + ].join("\n") + })); +} + +/** + * Creates a map function that adjusts messages in a code block. + * @param {Block} block A code block. + * @returns {(message: Message) => Message} A function that adjusts messages in a code block. + */ +function adjustBlock(block) { + const leadingCommentLines = block.comments.reduce((count, comment) => count + comment.split("\n").length, 0); + + const blockStart = block.position.start.line; + + /** + * Adjusts ESLint messages to point to the correct location in the Markdown. + * @param {Message} message A message from ESLint. + * @returns {Message} The same message, but adjusted to the correct location. + */ + return function adjustMessage(message) { + + const lineInCode = message.line - leadingCommentLines; + + if (lineInCode < 1) { + return null; + } + + const out = { + line: lineInCode + blockStart, + column: message.column + block.position.indent[lineInCode - 1] - 1 + }; + + if (Number.isInteger(message.endLine)) { + out.endLine = message.endLine - leadingCommentLines + blockStart; + } + + const adjustedFix = {}; + + if (message.fix) { + adjustedFix.fix = { + range: message.fix.range.map(range => { + + // Advance through the block's range map to find the last + // matching range by finding the first range too far and + // then going back one. + let i = 1; + + while (i < block.rangeMap.length && block.rangeMap[i].js <= range) { + i++; + } + + // Apply the mapping delta for this range. + return range + block.rangeMap[i - 1].md; + }), + text: message.fix.text.replace(/\n/gu, `\n${block.baseIndentText}`) + }; + } + + return { ...message, ...out, ...adjustedFix }; + }; +} + +/** + * Excludes unsatisfiable rules from the list of messages. + * @param {Message} message A message from the linter. + * @returns {boolean} True if the message should be included in output. + */ +function excludeUnsatisfiableRules(message) { + return message && UNSATISFIABLE_RULES.indexOf(message.ruleId) < 0; +} + +/** + * Transforms generated messages for output. + * @param {Array} messages An array containing one array of messages + * for each code block returned from `preprocess`. + * @param {string} filename The filename of the file + * @returns {Message[]} A flattened array of messages with mapped locations. + */ +function postprocess(messages, filename) { + const blocks = blocksCache.get(filename); + + blocksCache.delete(filename); + + return [].concat(...messages.map((group, i) => { + const adjust = adjustBlock(blocks[i]); + + return group.map(adjust).filter(excludeUnsatisfiableRules); + })); +} + +var processor = { + preprocess, + postprocess, + supportsAutofix: SUPPORTS_AUTOFIX +}; + +/** + * @fileoverview Enables the processor for Markdown file extensions. + * @author Brandon Mills + */ + + + +var lib = { + configs: { + recommended: { + plugins: ["markdown"], + overrides: [ + { + files: ["*.md"], + processor: "markdown/markdown" + }, + { + files: ["**/*.md/**"], + parserOptions: { + ecmaFeatures: { + + // Adding a "use strict" directive at the top of + // every code block is tedious and distracting, so + // opt into strict mode parsing without the + // directive. + impliedStrict: true + } + }, + rules: { + + // The Markdown parser automatically trims trailing + // newlines from code blocks. + "eol-last": "off", + + // In code snippets and examples, these rules are often + // counterproductive to clarity and brevity. + "no-undef": "off", + "no-unused-expressions": "off", + "no-unused-vars": "off", + "padded-blocks": "off", + + // Adding a "use strict" directive at the top of every + // code block is tedious and distracting. The config + // opts into strict mode parsing without the directive. + strict: "off", + + // The processor will not receive a Unicode Byte Order + // Mark from the Markdown parser. + "unicode-bom": "off" + } + } + ] + } + }, + processors: { + markdown: processor + } +}; + +/** + * @fileoverview Exports the processor. + * @author Brandon Mills + */ + +var eslintPluginMarkdown = lib; + +module.exports = eslintPluginMarkdown; diff --git a/tools/node_modules/eslint/node_modules/table/README.md b/tools/node_modules/eslint/node_modules/table/README.md index 22a79962a1a2ee..939084d07e7372 100644 --- a/tools/node_modules/eslint/node_modules/table/README.md +++ b/tools/node_modules/eslint/node_modules/table/README.md @@ -14,6 +14,7 @@ * [Cell Content Alignment](#table-usage-cell-content-alignment) * [Column Width](#table-usage-column-width) * [Custom Border](#table-usage-custom-border) + * [Draw Vertical Line](#table-usage-draw-vertical-line) * [Draw Horizontal Line](#table-usage-draw-horizontal-line) * [Single Line Mode](#table-usage-single-line-mode) * [Padding Cell Content](#table-usage-padding-cell-content) @@ -292,6 +293,57 @@ console.log(output); └────┴────┴────┘ ``` + +### Draw Vertical Line + +`{function} config.drawVerticalLine` property is a function that is called for every non-content column in the table. The result of the function `{boolean}` determines whether a border is drawn. + +```js +let data, + output, + options; + +data = [ + ['0A', '0B', '0C'], + ['1A', '1B', '1C'], + ['2A', '2B', '2C'], + ['3A', '3B', '3C'], + ['4A', '4B', '4C'] +]; + +options = { + /** + * @typedef {function} drawVerticalLine + * @param {number} index + * @param {number} size + * @return {boolean} + */ + drawVerticalLine: (index, size) => { + return index === 0 || index === size; + } +}; + +output = table(data, options); + +console.log(output); + +``` + +``` +╔════════════╗ +║ 0A 0B 0C ║ +╟────────────╢ +║ 1A 1B 1C ║ +╟────────────╢ +║ 2A 2B 2C ║ +╟────────────╢ +║ 3A 3B 3C ║ +╟────────────╢ +║ 4A 4B 4C ║ +╚════════════╝ + +``` + ### Draw Horizontal Line diff --git a/tools/node_modules/eslint/node_modules/table/dist/createStream.js b/tools/node_modules/eslint/node_modules/table/dist/createStream.js index 731f12035d0511..f505cf8869e12e 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/createStream.js +++ b/tools/node_modules/eslint/node_modules/table/dist/createStream.js @@ -27,13 +27,13 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de /** * @param {Array} data - * @param {object} config + * @param {streamConfig} config * @returns {Array} */ const prepareData = (data, config) => { let rows; rows = (0, _stringifyTableData.default)(data); - rows = (0, _truncateTableData.default)(data, config); + rows = (0, _truncateTableData.default)(rows, config); const rowHeightIndex = (0, _calculateRowHeightIndex.default)(rows, config); rows = (0, _mapDataUsingRowHeightIndex.default)(rows, rowHeightIndex, config); rows = (0, _alignTableData.default)(rows, config); @@ -43,7 +43,7 @@ const prepareData = (data, config) => { /** * @param {string[]} row * @param {number[]} columnWidthIndex - * @param {object} config + * @param {streamConfig} config * @returns {undefined} */ @@ -51,20 +51,20 @@ const prepareData = (data, config) => { const create = (row, columnWidthIndex, config) => { const rows = prepareData([row], config); const body = rows.map(literalRow => { - return (0, _drawRow.default)(literalRow, config.border); + return (0, _drawRow.default)(literalRow, config); }).join(''); let output; output = ''; - output += (0, _drawBorder.drawBorderTop)(columnWidthIndex, config.border); + output += (0, _drawBorder.drawBorderTop)(columnWidthIndex, config); output += body; - output += (0, _drawBorder.drawBorderBottom)(columnWidthIndex, config.border); + output += (0, _drawBorder.drawBorderBottom)(columnWidthIndex, config); output = output.trimEnd(); process.stdout.write(output); }; /** * @param {string[]} row * @param {number[]} columnWidthIndex - * @param {object} config + * @param {streamConfig} config * @returns {undefined} */ @@ -72,16 +72,16 @@ const create = (row, columnWidthIndex, config) => { const append = (row, columnWidthIndex, config) => { const rows = prepareData([row], config); const body = rows.map(literalRow => { - return (0, _drawRow.default)(literalRow, config.border); + return (0, _drawRow.default)(literalRow, config); }).join(''); let output = ''; - const bottom = (0, _drawBorder.drawBorderBottom)(columnWidthIndex, config.border); + const bottom = (0, _drawBorder.drawBorderBottom)(columnWidthIndex, config); if (bottom !== '\n') { output = '\r\u001B[K'; } - output += (0, _drawBorder.drawBorderJoin)(columnWidthIndex, config.border); + output += (0, _drawBorder.drawBorderJoin)(columnWidthIndex, config); output += body; output += bottom; output = output.trimEnd(); diff --git a/tools/node_modules/eslint/node_modules/table/dist/createStream.js.flow b/tools/node_modules/eslint/node_modules/table/dist/createStream.js.flow index 747ba6a7595bd4..2c2f164f62adb6 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/createStream.js.flow +++ b/tools/node_modules/eslint/node_modules/table/dist/createStream.js.flow @@ -14,7 +14,7 @@ import truncateTableData from './truncateTableData'; /** * @param {Array} data - * @param {object} config + * @param {streamConfig} config * @returns {Array} */ const prepareData = (data, config) => { @@ -22,7 +22,7 @@ const prepareData = (data, config) => { rows = stringifyTableData(data); - rows = truncateTableData(data, config); + rows = truncateTableData(rows, config); const rowHeightIndex = calculateRowHeightIndex(rows, config); @@ -36,23 +36,23 @@ const prepareData = (data, config) => { /** * @param {string[]} row * @param {number[]} columnWidthIndex - * @param {object} config + * @param {streamConfig} config * @returns {undefined} */ const create = (row, columnWidthIndex, config) => { const rows = prepareData([row], config); const body = rows.map((literalRow) => { - return drawRow(literalRow, config.border); + return drawRow(literalRow, config); }).join(''); let output; output = ''; - output += drawBorderTop(columnWidthIndex, config.border); + output += drawBorderTop(columnWidthIndex, config); output += body; - output += drawBorderBottom(columnWidthIndex, config.border); + output += drawBorderBottom(columnWidthIndex, config); output = output.trimEnd(); @@ -62,24 +62,24 @@ const create = (row, columnWidthIndex, config) => { /** * @param {string[]} row * @param {number[]} columnWidthIndex - * @param {object} config + * @param {streamConfig} config * @returns {undefined} */ const append = (row, columnWidthIndex, config) => { const rows = prepareData([row], config); const body = rows.map((literalRow) => { - return drawRow(literalRow, config.border); + return drawRow(literalRow, config); }).join(''); let output = ''; - const bottom = drawBorderBottom(columnWidthIndex, config.border); + const bottom = drawBorderBottom(columnWidthIndex, config); if (bottom !== '\n') { output = '\r\u001B[K'; } - output += drawBorderJoin(columnWidthIndex, config.border); + output += drawBorderJoin(columnWidthIndex, config); output += body; output += bottom; diff --git a/tools/node_modules/eslint/node_modules/table/dist/drawBorder.js b/tools/node_modules/eslint/node_modules/table/dist/drawBorder.js index 965e8539d42749..d6da1fdc4991b0 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/drawBorder.js +++ b/tools/node_modules/eslint/node_modules/table/dist/drawBorder.js @@ -5,8 +5,12 @@ Object.defineProperty(exports, "__esModule", { }); exports.drawBorderTop = exports.drawBorderJoin = exports.drawBorderBottom = exports.drawBorder = void 0; +var _drawHorizontalContent = _interopRequireDefault(require("./drawHorizontalContent")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** - * @typedef drawBorder~parts + * @typedef drawBorder~border * @property {string} left * @property {string} right * @property {string} body @@ -15,94 +19,96 @@ exports.drawBorderTop = exports.drawBorderJoin = exports.drawBorderBottom = expo /** * @param {number[]} columnSizeIndex - * @param {drawBorder~parts} parts + * @param {object} config + * @param {drawBorder~border} config.border + * @param {Function} config.drawVerticalLine * @returns {string} */ -const drawBorder = (columnSizeIndex, parts) => { +const drawBorder = (columnSizeIndex, { + border, + drawVerticalLine +}) => { const columns = columnSizeIndex.map(size => { - return parts.body.repeat(size); - }).join(parts.join); - return parts.left + columns + parts.right + '\n'; + return border.body.repeat(size); + }); + return (0, _drawHorizontalContent.default)(columns, { + drawVerticalLine, + separator: border + }); }; -/** - * @typedef drawBorderTop~parts - * @property {string} topLeft - * @property {string} topRight - * @property {string} topBody - * @property {string} topJoin - */ - /** * @param {number[]} columnSizeIndex - * @param {drawBorderTop~parts} parts + * @param {table~config} config * @returns {string} */ exports.drawBorder = drawBorder; -const drawBorderTop = (columnSizeIndex, parts) => { - const border = drawBorder(columnSizeIndex, { - body: parts.topBody, - join: parts.topJoin, - left: parts.topLeft, - right: parts.topRight +const drawBorderTop = (columnSizeIndex, { + border, + drawVerticalLine +}) => { + const result = drawBorder(columnSizeIndex, { + border: { + body: border.topBody, + join: border.topJoin, + left: border.topLeft, + right: border.topRight + }, + drawVerticalLine }); - if (border === '\n') { + if (result === '\n') { return ''; } - return border; + return result; }; -/** - * @typedef drawBorderJoin~parts - * @property {string} joinLeft - * @property {string} joinRight - * @property {string} joinBody - * @property {string} joinJoin - */ - /** * @param {number[]} columnSizeIndex - * @param {drawBorderJoin~parts} parts + * @param {table~config} config * @returns {string} */ exports.drawBorderTop = drawBorderTop; -const drawBorderJoin = (columnSizeIndex, parts) => { +const drawBorderJoin = (columnSizeIndex, { + border, + drawVerticalLine +}) => { return drawBorder(columnSizeIndex, { - body: parts.joinBody, - join: parts.joinJoin, - left: parts.joinLeft, - right: parts.joinRight + border: { + body: border.joinBody, + join: border.joinJoin, + left: border.joinLeft, + right: border.joinRight + }, + drawVerticalLine }); }; -/** - * @typedef drawBorderBottom~parts - * @property {string} topLeft - * @property {string} topRight - * @property {string} topBody - * @property {string} topJoin - */ - /** * @param {number[]} columnSizeIndex - * @param {drawBorderBottom~parts} parts + * @param {table~config} config * @returns {string} */ exports.drawBorderJoin = drawBorderJoin; -const drawBorderBottom = (columnSizeIndex, parts) => { +const drawBorderBottom = (columnSizeIndex, { + border, + drawVerticalLine +}) => { return drawBorder(columnSizeIndex, { - body: parts.bottomBody, - join: parts.bottomJoin, - left: parts.bottomLeft, - right: parts.bottomRight + border: { + body: border.bottomBody, + join: border.bottomJoin, + left: border.bottomLeft, + right: border.bottomRight + }, + drawVerticalLine }); }; diff --git a/tools/node_modules/eslint/node_modules/table/dist/drawBorder.js.flow b/tools/node_modules/eslint/node_modules/table/dist/drawBorder.js.flow index 85de2475e8b294..fc94622efb6354 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/drawBorder.js.flow +++ b/tools/node_modules/eslint/node_modules/table/dist/drawBorder.js.flow @@ -1,5 +1,7 @@ +import drawHorizontalContent from './drawHorizontalContent'; + /** - * @typedef drawBorder~parts + * @typedef drawBorder~border * @property {string} left * @property {string} right * @property {string} body @@ -8,88 +10,74 @@ /** * @param {number[]} columnSizeIndex - * @param {drawBorder~parts} parts + * @param {object} config + * @param {drawBorder~border} config.border + * @param {Function} config.drawVerticalLine * @returns {string} */ -const drawBorder = (columnSizeIndex, parts) => { - const columns = columnSizeIndex - .map((size) => { - return parts.body.repeat(size); - }) - .join(parts.join); +const drawBorder = (columnSizeIndex, {border, drawVerticalLine}) => { + const columns = columnSizeIndex.map((size) => { + return border.body.repeat(size); + }); - return parts.left + columns + parts.right + '\n'; + return drawHorizontalContent(columns, { + drawVerticalLine, + separator: border, + }); }; -/** - * @typedef drawBorderTop~parts - * @property {string} topLeft - * @property {string} topRight - * @property {string} topBody - * @property {string} topJoin - */ - /** * @param {number[]} columnSizeIndex - * @param {drawBorderTop~parts} parts + * @param {table~config} config * @returns {string} */ -const drawBorderTop = (columnSizeIndex, parts) => { - const border = drawBorder(columnSizeIndex, { - body: parts.topBody, - join: parts.topJoin, - left: parts.topLeft, - right: parts.topRight, - }); +const drawBorderTop = (columnSizeIndex, {border, drawVerticalLine}) => { + const result = drawBorder(columnSizeIndex, {border: { + body: border.topBody, + join: border.topJoin, + left: border.topLeft, + right: border.topRight, + }, + drawVerticalLine}); - if (border === '\n') { + if (result === '\n') { return ''; } - return border; + return result; }; -/** - * @typedef drawBorderJoin~parts - * @property {string} joinLeft - * @property {string} joinRight - * @property {string} joinBody - * @property {string} joinJoin - */ - /** * @param {number[]} columnSizeIndex - * @param {drawBorderJoin~parts} parts + * @param {table~config} config * @returns {string} */ -const drawBorderJoin = (columnSizeIndex, parts) => { +const drawBorderJoin = (columnSizeIndex, {border, drawVerticalLine}) => { return drawBorder(columnSizeIndex, { - body: parts.joinBody, - join: parts.joinJoin, - left: parts.joinLeft, - right: parts.joinRight, + border: { + body: border.joinBody, + join: border.joinJoin, + left: border.joinLeft, + right: border.joinRight, + }, + drawVerticalLine, }); }; -/** - * @typedef drawBorderBottom~parts - * @property {string} topLeft - * @property {string} topRight - * @property {string} topBody - * @property {string} topJoin - */ - /** * @param {number[]} columnSizeIndex - * @param {drawBorderBottom~parts} parts + * @param {table~config} config * @returns {string} */ -const drawBorderBottom = (columnSizeIndex, parts) => { +const drawBorderBottom = (columnSizeIndex, {border, drawVerticalLine}) => { return drawBorder(columnSizeIndex, { - body: parts.bottomBody, - join: parts.bottomJoin, - left: parts.bottomLeft, - right: parts.bottomRight, + border: { + body: border.bottomBody, + join: border.bottomJoin, + left: border.bottomLeft, + right: border.bottomRight, + }, + drawVerticalLine, }); }; diff --git a/tools/node_modules/eslint/node_modules/table/dist/drawHorizontalContent.js b/tools/node_modules/eslint/node_modules/table/dist/drawHorizontalContent.js new file mode 100644 index 00000000000000..1e1ebd798a7965 --- /dev/null +++ b/tools/node_modules/eslint/node_modules/table/dist/drawHorizontalContent.js @@ -0,0 +1,41 @@ +"use strict"; + +Object.defineProperty(exports, "__esModule", { + value: true +}); +exports.default = void 0; + +/** + * @typedef {object} drawHorizontalContent~separator + * @property {string} left + * @property {string} right + * @property {string} join + */ + +/** + * @param {string[]} columns + * @param {object} config + * @param {drawHorizontalContent~separator} config.separator + * @param {Function} config.drawVerticalLine + * @returns {string} + */ +const drawHorizontalContent = (columns, { + separator, + drawVerticalLine +}) => { + const columnCount = columns.length; + const result = []; + result.push(drawVerticalLine(0, columnCount) ? separator.left : ''); + columns.forEach((column, index) => { + result.push(column); + + if (index + 1 < columnCount) { + result.push(drawVerticalLine(index + 1, columnCount) ? separator.join : ''); + } + }); + result.push(drawVerticalLine(columnCount, columnCount) ? separator.right : ''); + return result.join('') + '\n'; +}; + +var _default = drawHorizontalContent; +exports.default = _default; \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/table/dist/drawHorizontalContent.js.flow b/tools/node_modules/eslint/node_modules/table/dist/drawHorizontalContent.js.flow new file mode 100644 index 00000000000000..5b7ac499a57bb9 --- /dev/null +++ b/tools/node_modules/eslint/node_modules/table/dist/drawHorizontalContent.js.flow @@ -0,0 +1,31 @@ +/** + * @typedef {object} drawHorizontalContent~separator + * @property {string} left + * @property {string} right + * @property {string} join + */ + +/** + * @param {string[]} columns + * @param {object} config + * @param {drawHorizontalContent~separator} config.separator + * @param {Function} config.drawVerticalLine + * @returns {string} + */ +export default (columns, {separator, drawVerticalLine}) => { + const columnCount = columns.length; + const result = []; + + result.push(drawVerticalLine(0, columnCount) ? separator.left : ''); + + columns.forEach((column, index) => { + result.push(column); + + if (index + 1 < columnCount) { + result.push(drawVerticalLine(index + 1, columnCount) ? separator.join : ''); + } + }); + result.push(drawVerticalLine(columnCount, columnCount) ? separator.right : ''); + + return result.join('') + '\n'; +}; diff --git a/tools/node_modules/eslint/node_modules/table/dist/drawRow.js b/tools/node_modules/eslint/node_modules/table/dist/drawRow.js index 432f5bce1f9cdd..69a4a00d64aef5 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/drawRow.js +++ b/tools/node_modules/eslint/node_modules/table/dist/drawRow.js @@ -5,6 +5,10 @@ Object.defineProperty(exports, "__esModule", { }); exports.default = void 0; +var _drawHorizontalContent = _interopRequireDefault(require("./drawHorizontalContent")); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + /** * @typedef {object} drawRow~border * @property {string} bodyLeft @@ -13,12 +17,24 @@ exports.default = void 0; */ /** - * @param {number[]} columns - * @param {drawRow~border} border + * @param {string[]} columns + * @param {object} config + * @param {border} config.border + * @param {Function} config.drawVerticalLine * @returns {string} */ -const drawRow = (columns, border) => { - return border.bodyLeft + columns.join(border.bodyJoin) + border.bodyRight + '\n'; +const drawRow = (columns, { + border, + drawVerticalLine +}) => { + return (0, _drawHorizontalContent.default)(columns, { + drawVerticalLine, + separator: { + join: border.bodyJoin, + left: border.bodyLeft, + right: border.bodyRight + } + }); }; var _default = drawRow; diff --git a/tools/node_modules/eslint/node_modules/table/dist/drawRow.js.flow b/tools/node_modules/eslint/node_modules/table/dist/drawRow.js.flow index 978eab2de19941..d185e499a8008f 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/drawRow.js.flow +++ b/tools/node_modules/eslint/node_modules/table/dist/drawRow.js.flow @@ -1,3 +1,5 @@ +import drawHorizontalContent from './drawHorizontalContent'; + /** * @typedef {object} drawRow~border * @property {string} bodyLeft @@ -6,10 +8,22 @@ */ /** - * @param {number[]} columns - * @param {drawRow~border} border + * @param {string[]} columns + * @param {object} config + * @param {border} config.border + * @param {Function} config.drawVerticalLine * @returns {string} */ -export default (columns, border) => { - return border.bodyLeft + columns.join(border.bodyJoin) + border.bodyRight + '\n'; +export default (columns, { + border, + drawVerticalLine, +}) => { + return drawHorizontalContent(columns, { + drawVerticalLine, + separator: { + join: border.bodyJoin, + left: border.bodyLeft, + right: border.bodyRight, + }, + }); }; diff --git a/tools/node_modules/eslint/node_modules/table/dist/drawTable.js b/tools/node_modules/eslint/node_modules/table/dist/drawTable.js index 4c49d0fff50de8..4ae5717e26a721 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/drawTable.js +++ b/tools/node_modules/eslint/node_modules/table/dist/drawTable.js @@ -12,15 +12,17 @@ var _drawRow = _interopRequireDefault(require("./drawRow")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** - * @param {Array} rows - * @param {object} border + * @param {string[][]} rows * @param {Array} columnSizeIndex * @param {Array} rowSpanIndex - * @param {Function} drawHorizontalLine - * @param {boolean} singleLine + * @param {table~config} config * @returns {string} */ -const drawTable = (rows, border, columnSizeIndex, rowSpanIndex, drawHorizontalLine, singleLine) => { +const drawTable = (rows, columnSizeIndex, rowSpanIndex, config) => { + const { + drawHorizontalLine, + singleLine + } = config; let output; let realRowIndex; let rowHeight; @@ -29,11 +31,11 @@ const drawTable = (rows, border, columnSizeIndex, rowSpanIndex, drawHorizontalLi output = ''; if (drawHorizontalLine(realRowIndex, rowCount)) { - output += (0, _drawBorder.drawBorderTop)(columnSizeIndex, border); + output += (0, _drawBorder.drawBorderTop)(columnSizeIndex, config); } rows.forEach((row, index0) => { - output += (0, _drawRow.default)(row, border); + output += (0, _drawRow.default)(row, config); if (!rowHeight) { rowHeight = rowSpanIndex[realRowIndex]; @@ -43,12 +45,12 @@ const drawTable = (rows, border, columnSizeIndex, rowSpanIndex, drawHorizontalLi rowHeight--; if (!singleLine && rowHeight === 0 && index0 !== rowCount - 1 && drawHorizontalLine(realRowIndex, rowCount)) { - output += (0, _drawBorder.drawBorderJoin)(columnSizeIndex, border); + output += (0, _drawBorder.drawBorderJoin)(columnSizeIndex, config); } }); if (drawHorizontalLine(realRowIndex, rowCount)) { - output += (0, _drawBorder.drawBorderBottom)(columnSizeIndex, border); + output += (0, _drawBorder.drawBorderBottom)(columnSizeIndex, config); } return output; diff --git a/tools/node_modules/eslint/node_modules/table/dist/drawTable.js.flow b/tools/node_modules/eslint/node_modules/table/dist/drawTable.js.flow index 84707caa83d04b..402649721e6977 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/drawTable.js.flow +++ b/tools/node_modules/eslint/node_modules/table/dist/drawTable.js.flow @@ -1,20 +1,26 @@ import { - drawBorderTop, - drawBorderJoin, - drawBorderBottom, + drawBorderTop, drawBorderJoin, drawBorderBottom, } from './drawBorder'; import drawRow from './drawRow'; /** - * @param {Array} rows - * @param {object} border + * @param {string[][]} rows * @param {Array} columnSizeIndex * @param {Array} rowSpanIndex - * @param {Function} drawHorizontalLine - * @param {boolean} singleLine + * @param {table~config} config * @returns {string} */ -export default (rows, border, columnSizeIndex, rowSpanIndex, drawHorizontalLine, singleLine) => { +export default ( + rows, + columnSizeIndex, + rowSpanIndex, + config, +) => { + const { + drawHorizontalLine, + singleLine, + } = config; + let output; let realRowIndex; let rowHeight; @@ -26,11 +32,11 @@ export default (rows, border, columnSizeIndex, rowSpanIndex, drawHorizontalLine, output = ''; if (drawHorizontalLine(realRowIndex, rowCount)) { - output += drawBorderTop(columnSizeIndex, border); + output += drawBorderTop(columnSizeIndex, config); } rows.forEach((row, index0) => { - output += drawRow(row, border); + output += drawRow(row, config); if (!rowHeight) { rowHeight = rowSpanIndex[realRowIndex]; @@ -40,13 +46,18 @@ export default (rows, border, columnSizeIndex, rowSpanIndex, drawHorizontalLine, rowHeight--; - if (!singleLine && rowHeight === 0 && index0 !== rowCount - 1 && drawHorizontalLine(realRowIndex, rowCount)) { - output += drawBorderJoin(columnSizeIndex, border); + if ( + !singleLine && + rowHeight === 0 && + index0 !== rowCount - 1 && + drawHorizontalLine(realRowIndex, rowCount) + ) { + output += drawBorderJoin(columnSizeIndex, config); } }); if (drawHorizontalLine(realRowIndex, rowCount)) { - output += drawBorderBottom(columnSizeIndex, border); + output += drawBorderBottom(columnSizeIndex, config); } return output; diff --git a/tools/node_modules/eslint/node_modules/table/dist/makeConfig.js b/tools/node_modules/eslint/node_modules/table/dist/makeConfig.js index a80d9a06acf1c9..8f210cbc0fc1cc 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/makeConfig.js +++ b/tools/node_modules/eslint/node_modules/table/dist/makeConfig.js @@ -73,13 +73,22 @@ const makeConfig = (rows, userConfig = {}) => { if (!config.drawHorizontalLine) { /** - * @returns {boolean} - */ + * @returns {boolean} + */ config.drawHorizontalLine = () => { return true; }; } + if (!config.drawVerticalLine) { + /** + * @returns {boolean} + */ + config.drawVerticalLine = () => { + return true; + }; + } + if (config.singleLine === undefined) { config.singleLine = false; } diff --git a/tools/node_modules/eslint/node_modules/table/dist/makeConfig.js.flow b/tools/node_modules/eslint/node_modules/table/dist/makeConfig.js.flow index 3fcbc79c555f0b..ae03633985341e 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/makeConfig.js.flow +++ b/tools/node_modules/eslint/node_modules/table/dist/makeConfig.js.flow @@ -61,13 +61,22 @@ export default (rows, userConfig = {}) => { if (!config.drawHorizontalLine) { /** - * @returns {boolean} - */ + * @returns {boolean} + */ config.drawHorizontalLine = () => { return true; }; } + if (!config.drawVerticalLine) { + /** + * @returns {boolean} + */ + config.drawVerticalLine = () => { + return true; + }; + } + if (config.singleLine === undefined) { config.singleLine = false; } diff --git a/tools/node_modules/eslint/node_modules/table/dist/makeStreamConfig.js b/tools/node_modules/eslint/node_modules/table/dist/makeStreamConfig.js index 6ca9733dd358e2..dac43d2549735d 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/makeStreamConfig.js +++ b/tools/node_modules/eslint/node_modules/table/dist/makeStreamConfig.js @@ -90,6 +90,16 @@ const makeStreamConfig = (userConfig = {}) => { config.border = makeBorder(config.border); config.columns = makeColumns(config.columnCount, config.columns, config.columnDefault); + + if (!config.drawVerticalLine) { + /** + * @returns {boolean} + */ + config.drawVerticalLine = () => { + return true; + }; + } + return config; }; diff --git a/tools/node_modules/eslint/node_modules/table/dist/makeStreamConfig.js.flow b/tools/node_modules/eslint/node_modules/table/dist/makeStreamConfig.js.flow index 8536bf5b37a0c1..1731a3eda39998 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/makeStreamConfig.js.flow +++ b/tools/node_modules/eslint/node_modules/table/dist/makeStreamConfig.js.flow @@ -79,5 +79,14 @@ export default (userConfig = {}) => { config.border = makeBorder(config.border); config.columns = makeColumns(config.columnCount, config.columns, config.columnDefault); + if (!config.drawVerticalLine) { + /** + * @returns {boolean} + */ + config.drawVerticalLine = () => { + return true; + }; + } + return config; }; diff --git a/tools/node_modules/eslint/node_modules/table/dist/schemas/config.json b/tools/node_modules/eslint/node_modules/table/dist/schemas/config.json index 10fc74ab93cfc1..d82828e91604cd 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/schemas/config.json +++ b/tools/node_modules/eslint/node_modules/table/dist/schemas/config.json @@ -12,6 +12,9 @@ "columnDefault": { "$ref": "shared.json#/definitions/column" }, + "drawVerticalLine": { + "typeof": "function" + }, "drawHorizontalLine": { "typeof": "function" }, diff --git a/tools/node_modules/eslint/node_modules/table/dist/schemas/streamConfig.json b/tools/node_modules/eslint/node_modules/table/dist/schemas/streamConfig.json index 24dfa56282541a..86701518877485 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/schemas/streamConfig.json +++ b/tools/node_modules/eslint/node_modules/table/dist/schemas/streamConfig.json @@ -14,6 +14,9 @@ }, "columnCount": { "type": "number" + }, + "drawVerticalLine": { + "typeof": "function" } }, "additionalProperties": false diff --git a/tools/node_modules/eslint/node_modules/table/dist/table.js b/tools/node_modules/eslint/node_modules/table/dist/table.js index 8c053d81f773b4..0ae78b595cdda7 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/table.js +++ b/tools/node_modules/eslint/node_modules/table/dist/table.js @@ -64,6 +64,17 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de * @property {string} joinJoin */ +/** + * Used to tell whether to draw a vertical line. + * This callback is called for each non-content line of the table. + * The default behavior is to always return true. + * + * @typedef {Function} drawVerticalLine + * @param {number} index + * @param {number} size + * @returns {boolean} + */ + /** * Used to tell whether to draw a horizontal line. * This callback is called for each non-content line of the table. @@ -80,6 +91,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de * @property {table~border} border * @property {table~columns[]} columns Column specific configuration. * @property {table~columns} columnDefault Default values for all columns. Column specific settings overwrite the default values. + * @property {table~drawVerticalLine} drawVerticalLine * @property {table~drawHorizontalLine} drawHorizontalLine * @property {table~singleLine} singleLine Horizontal lines inside the table are not drawn. */ @@ -102,7 +114,7 @@ const table = (data, userConfig = {}) => { rows = (0, _alignTableData.default)(rows, config); rows = (0, _padTableData.default)(rows, config); const cellWidthIndex = (0, _calculateCellWidthIndex.default)(rows[0]); - return (0, _drawTable.default)(rows, config.border, cellWidthIndex, rowHeightIndex, config.drawHorizontalLine, config.singleLine); + return (0, _drawTable.default)(rows, cellWidthIndex, rowHeightIndex, config); }; var _default = table; diff --git a/tools/node_modules/eslint/node_modules/table/dist/table.js.flow b/tools/node_modules/eslint/node_modules/table/dist/table.js.flow index 6790e8cc550f2c..887025b6b75f33 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/table.js.flow +++ b/tools/node_modules/eslint/node_modules/table/dist/table.js.flow @@ -46,6 +46,17 @@ import validateTableData from './validateTableData'; * @property {string} joinJoin */ +/** + * Used to tell whether to draw a vertical line. + * This callback is called for each non-content line of the table. + * The default behavior is to always return true. + * + * @typedef {Function} drawVerticalLine + * @param {number} index + * @param {number} size + * @returns {boolean} + */ + /** * Used to tell whether to draw a horizontal line. * This callback is called for each non-content line of the table. @@ -62,6 +73,7 @@ import validateTableData from './validateTableData'; * @property {table~border} border * @property {table~columns[]} columns Column specific configuration. * @property {table~columns} columnDefault Default values for all columns. Column specific settings overwrite the default values. + * @property {table~drawVerticalLine} drawVerticalLine * @property {table~drawHorizontalLine} drawHorizontalLine * @property {table~singleLine} singleLine Horizontal lines inside the table are not drawn. */ @@ -92,5 +104,5 @@ export default (data, userConfig = {}) => { const cellWidthIndex = calculateCellWidthIndex(rows[0]); - return drawTable(rows, config.border, cellWidthIndex, rowHeightIndex, config.drawHorizontalLine, config.singleLine); + return drawTable(rows, cellWidthIndex, rowHeightIndex, config); }; diff --git a/tools/node_modules/eslint/node_modules/table/dist/validators.js b/tools/node_modules/eslint/node_modules/table/dist/validators.js index 51783aa08b8595..3b2af3d84f6839 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/validators.js +++ b/tools/node_modules/eslint/node_modules/table/dist/validators.js @@ -14,6 +14,9 @@ const schema13 = { "columnDefault": { "$ref": "shared.json#/definitions/column" }, + "drawVerticalLine": { + "typeof": "function" + }, "drawHorizontalLine": { "typeof": "function" }, @@ -801,7 +804,7 @@ function validate43(data, { let errors = 0; if (data && typeof data == "object" && !Array.isArray(data)) { for (const key0 in data) { - if (!(((((key0 === "border") || (key0 === "columns")) || (key0 === "columnDefault")) || (key0 === "drawHorizontalLine")) || (key0 === "singleLine"))) { + if (!((((((key0 === "border") || (key0 === "columns")) || (key0 === "columnDefault")) || (key0 === "drawVerticalLine")) || (key0 === "drawHorizontalLine")) || (key0 === "singleLine"))) { const err0 = { instancePath, schemaPath: "#/additionalProperties", @@ -852,9 +855,26 @@ function validate43(data, { errors = vErrors.length; } } + if (data.drawVerticalLine !== undefined) { + if (typeof data.drawVerticalLine != "function") { + const err1 = { + instancePath: instancePath + "/drawVerticalLine", + schemaPath: "#/properties/drawVerticalLine/typeof", + keyword: "typeof", + params: {}, + message: "should pass \"typeof\" keyword validation" + }; + if (vErrors === null) { + vErrors = [err1]; + } else { + vErrors.push(err1); + } + errors++; + } + } if (data.drawHorizontalLine !== undefined) { if (typeof data.drawHorizontalLine != "function") { - const err1 = { + const err2 = { instancePath: instancePath + "/drawHorizontalLine", schemaPath: "#/properties/drawHorizontalLine/typeof", keyword: "typeof", @@ -862,16 +882,16 @@ function validate43(data, { message: "should pass \"typeof\" keyword validation" }; if (vErrors === null) { - vErrors = [err1]; + vErrors = [err2]; } else { - vErrors.push(err1); + vErrors.push(err2); } errors++; } } if (data.singleLine !== undefined) { if (typeof data.singleLine != "boolean") { - const err2 = { + const err3 = { instancePath: instancePath + "/singleLine", schemaPath: "#/properties/singleLine/typeof", keyword: "typeof", @@ -879,15 +899,15 @@ function validate43(data, { message: "should pass \"typeof\" keyword validation" }; if (vErrors === null) { - vErrors = [err2]; + vErrors = [err3]; } else { - vErrors.push(err2); + vErrors.push(err3); } errors++; } } } else { - const err3 = { + const err4 = { instancePath, schemaPath: "#/type", keyword: "type", @@ -897,9 +917,9 @@ function validate43(data, { message: "must be object" }; if (vErrors === null) { - vErrors = [err3]; + vErrors = [err4]; } else { - vErrors.push(err3); + vErrors.push(err4); } errors++; } @@ -923,6 +943,9 @@ const schema20 = { }, "columnCount": { "type": "number" + }, + "drawVerticalLine": { + "typeof": "function" } }, "additionalProperties": false @@ -1400,7 +1423,7 @@ function validate69(data, { let errors = 0; if (data && typeof data == "object" && !Array.isArray(data)) { for (const key0 in data) { - if (!((((key0 === "border") || (key0 === "columns")) || (key0 === "columnDefault")) || (key0 === "columnCount"))) { + if (!(((((key0 === "border") || (key0 === "columns")) || (key0 === "columnDefault")) || (key0 === "columnCount")) || (key0 === "drawVerticalLine"))) { const err0 = { instancePath, schemaPath: "#/additionalProperties", @@ -1471,8 +1494,25 @@ function validate69(data, { errors++; } } + if (data.drawVerticalLine !== undefined) { + if (typeof data.drawVerticalLine != "function") { + const err2 = { + instancePath: instancePath + "/drawVerticalLine", + schemaPath: "#/properties/drawVerticalLine/typeof", + keyword: "typeof", + params: {}, + message: "should pass \"typeof\" keyword validation" + }; + if (vErrors === null) { + vErrors = [err2]; + } else { + vErrors.push(err2); + } + errors++; + } + } } else { - const err2 = { + const err3 = { instancePath, schemaPath: "#/type", keyword: "type", @@ -1482,9 +1522,9 @@ function validate69(data, { message: "must be object" }; if (vErrors === null) { - vErrors = [err2]; + vErrors = [err3]; } else { - vErrors.push(err2); + vErrors.push(err3); } errors++; } diff --git a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/compile/validate/keyword.js b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/compile/validate/keyword.js index 42b2e7a33759b6..47f6176b1109cf 100644 --- a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/compile/validate/keyword.js +++ b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/compile/validate/keyword.js @@ -99,7 +99,7 @@ function validSchemaType(schema, schemaType, allowUndefined = false) { : typeof schema == st || (allowUndefined && typeof schema == "undefined"))); } exports.validSchemaType = validSchemaType; -function validateKeywordUsage({ schema, opts, self }, def, keyword) { +function validateKeywordUsage({ schema, opts, self, errSchemaPath }, def, keyword) { /* istanbul ignore if */ if (Array.isArray(def.keyword) ? !def.keyword.includes(keyword) : def.keyword !== keyword) { throw new Error("ajv implementation error"); @@ -111,7 +111,8 @@ function validateKeywordUsage({ schema, opts, self }, def, keyword) { if (def.validateSchema) { const valid = def.validateSchema(schema[keyword]); if (!valid) { - const msg = "keyword value is invalid: " + self.errorsText(def.validateSchema.errors); + const msg = `keyword "${keyword}" value is invalid at path "${errSchemaPath}": ` + + self.errorsText(def.validateSchema.errors); if (opts.validateSchema === "log") self.logger.error(msg); else diff --git a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/core.js b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/core.js index 9eba9f49d9e1e8..a1aae13883da38 100644 --- a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/core.js +++ b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/core.js @@ -61,7 +61,7 @@ const deprecatedOptions = { const MAX_EXPRESSION = 200; // eslint-disable-next-line complexity function requiredOptions(o) { - var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u; + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v; const s = o.strict; const _optz = (_a = o.code) === null || _a === void 0 ? void 0 : _a.optimize; const optimize = _optz === true || _optz === undefined ? 1 : _optz || 0; @@ -80,6 +80,7 @@ function requiredOptions(o) { addUsedSchema: (_s = o.addUsedSchema) !== null && _s !== void 0 ? _s : true, validateSchema: (_t = o.validateSchema) !== null && _t !== void 0 ? _t : true, validateFormats: (_u = o.validateFormats) !== null && _u !== void 0 ? _u : true, + unicodeRegExp: (_v = o.unicodeRegExp) !== null && _v !== void 0 ? _v : true, }; } class Ajv { diff --git a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js index 91672bc0846023..09da8547ec735b 100644 --- a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js +++ b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js @@ -50,7 +50,7 @@ const def = { definedProp = codegen_1.nil; } if (patProps.length) { - definedProp = codegen_1.or(definedProp, ...patProps.map((p) => codegen_1._ `${code_1.usePattern(gen, p)}.test(${key})`)); + definedProp = codegen_1.or(definedProp, ...patProps.map((p) => codegen_1._ `${code_1.usePattern(cxt, p)}.test(${key})`)); } return codegen_1.not(definedProp); } diff --git a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js index 1f2f9fe71434cf..ff68c82e1061ec 100644 --- a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js +++ b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js @@ -45,7 +45,7 @@ const def = { } function validateProperties(pat) { gen.forIn("key", data, (key) => { - gen.if(codegen_1._ `${code_1.usePattern(gen, pat)}.test(${key})`, () => { + gen.if(codegen_1._ `${code_1.usePattern(cxt, pat)}.test(${key})`, () => { cxt.subschema({ keyword: "patternProperties", schemaProp: pat, diff --git a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/code.js b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/code.js index 848a72c88f4c9b..c6f852daf9190f 100644 --- a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/code.js +++ b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/code.js @@ -65,11 +65,12 @@ function callValidateCode({ schemaCode, data, it: { gen, topSchemaRef, schemaPat return context !== codegen_1.nil ? codegen_1._ `${func}.call(${context}, ${args})` : codegen_1._ `${func}(${args})`; } exports.callValidateCode = callValidateCode; -function usePattern(gen, pattern) { +function usePattern({ gen, it: { opts } }, pattern) { + const u = opts.unicodeRegExp ? "u" : ""; return gen.scopeValue("pattern", { key: pattern, - ref: new RegExp(pattern, "u"), - code: codegen_1._ `new RegExp(${pattern}, "u")`, + ref: new RegExp(pattern, u), + code: codegen_1._ `new RegExp(${pattern}, ${u})`, }); } exports.usePattern = usePattern; diff --git a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/validation/pattern.js b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/validation/pattern.js index 7bb1587d98d5b5..b0862db342257f 100644 --- a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/validation/pattern.js +++ b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/validation/pattern.js @@ -13,8 +13,10 @@ const def = { $data: true, error, code(cxt) { - const { gen, data, $data, schema, schemaCode } = cxt; - const regExp = $data ? codegen_1._ `(new RegExp(${schemaCode}, "u"))` : code_1.usePattern(gen, schema); // TODO regexp should be wrapped in try/catch + const { data, $data, schema, schemaCode, it } = cxt; + // TODO regexp should be wrapped in try/catchs + const u = it.opts.unicodeRegExp ? "u" : ""; + const regExp = $data ? codegen_1._ `(new RegExp(${schemaCode}, ${u}))` : code_1.usePattern(cxt, schema); cxt.fail$data(codegen_1._ `!${regExp}.test(${data})`); }, }; diff --git a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/package.json b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/package.json index ec9f333b117190..22f7a782c40b27 100644 --- a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/package.json +++ b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/package.json @@ -1,6 +1,6 @@ { "name": "ajv", - "version": "8.0.5", + "version": "8.1.0", "description": "Another JSON Schema Validator", "main": "dist/ajv.js", "types": "dist/ajv.d.ts", diff --git a/tools/node_modules/eslint/node_modules/table/package.json b/tools/node_modules/eslint/node_modules/table/package.json index c1e2f61bacdcd4..ee6dd0beb58871 100644 --- a/tools/node_modules/eslint/node_modules/table/package.json +++ b/tools/node_modules/eslint/node_modules/table/package.json @@ -87,5 +87,5 @@ "lint": "npm run build && eslint ./src ./test && flow", "test": "mocha --require @babel/register" }, - "version": "6.0.9" + "version": "6.1.0" } diff --git a/tools/update-eslint.sh b/tools/update-eslint.sh index eb1045267f70fc..8eb180be779f77 100755 --- a/tools/update-eslint.sh +++ b/tools/update-eslint.sh @@ -18,8 +18,17 @@ rm -rf node_modules/eslint node_modules/eslint-plugin-markdown "$NODE" "$NPM" init --yes + "$NODE" "$NPM" install --production --no-save --no-package-lock \ + eslint@latest \ + eslint-plugin-markdown@latest \ + eslint-plugin-jsdoc@latest \ + rollup @rollup/plugin-node-resolve @rollup/plugin-commonjs @rollup/plugin-json + node -p '"export default"+JSON.stringify({external:Object.keys(require("eslint/package.json").dependencies),output:{format:"cjs",exports:"default"}})' > rollup.config.mjs + "$NODE" "$NPM" exec -- rollup -c rollup.config.mjs -p '@rollup/plugin-node-resolve' -p '@rollup/plugin-commonjs' -p '@rollup/plugin-json' -f cjs --file=./eslint-plugin-markdown/index.js -- ./node_modules/eslint-plugin-markdown/index.js + "$NODE" "$NPM" exec -- rollup -c rollup.config.mjs -p '@rollup/plugin-node-resolve' -p '@rollup/plugin-commonjs' -p '@rollup/plugin-json' -f cjs --file=./eslint-plugin-jsdoc/index.js -- ./node_modules/eslint-plugin-jsdoc/dist/index.js + rm -r node_modules + "$NODE" "$NPM" install --global-style --no-bin-links --production --no-package-lock eslint@latest - "$NODE" "$NPM" install --global-style --no-bin-links --production --no-package-lock eslint-plugin-markdown@latest # Use dmn to remove some unneeded files. "$NODE" "$NPM" exec -- dmn@2.2.2 -f clean @@ -29,5 +38,6 @@ rm -rf node_modules/eslint node_modules/eslint-plugin-markdown ) mv eslint-tmp/node_modules/eslint node_modules/eslint -mv eslint-tmp/node_modules/eslint-plugin-markdown node_modules/eslint-plugin-markdown +mv eslint-tmp/eslint-plugin-markdown node_modules/eslint/node_modules/eslint-plugin-markdown +mv eslint-tmp/eslint-plugin-jsdoc node_modules/eslint/node_modules/eslint-plugin-jsdoc rm -rf eslint-tmp/ From 434f2178846b44aca9d16eeeaad10010f6ef4071 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Zasso?= Date: Sun, 18 Apr 2021 13:51:12 +0200 Subject: [PATCH 2/3] tools: enable JSDoc ESLint plugin Start with a single rule (check-tag-names) and configure it to limit the number of required fixes. --- .eslintrc.js | 17 ++++++++++++++++- benchmark/common.js | 2 +- lib/internal/source_map/source_map.js | 18 +++++++++--------- tools/eslint-rules/non-ascii-character.js | 2 +- 4 files changed, 27 insertions(+), 12 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 27dd8aa10c37a1..87fa1e7459f1c5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -16,6 +16,7 @@ const ModuleFindPath = Module._findPath; const hacks = [ 'eslint-plugin-node-core', 'eslint-plugin-markdown', + 'eslint-plugin-jsdoc', '@babel/eslint-parser', '@babel/plugin-syntax-class-properties', '@babel/plugin-syntax-top-level-await', @@ -38,7 +39,7 @@ Module._findPath = (request, paths, isMain) => { module.exports = { root: true, - plugins: ['markdown', 'node-core'], + plugins: ['markdown', 'node-core', 'jsdoc'], parser: '@babel/eslint-parser', parserOptions: { babelOptions: { @@ -50,6 +51,16 @@ module.exports = { requireConfigFile: false, sourceType: 'script', }, + settings: { + jsdoc: { + // For the @template tag. + mode: 'typescript', + tagNamePreference: { + class: 'constructor', + file: 'fileoverview', + }, + }, + }, overrides: [ { files: [ @@ -313,6 +324,10 @@ module.exports = { // Custom rules from eslint-plugin-node-core 'node-core/no-unescaped-regexp-dot': 'error', 'node-core/no-duplicate-requires': 'error', + + // JSDoc rules + // https://github.com/gajus/eslint-plugin-jsdoc + 'jsdoc/check-tag-names': 'error', }, globals: { AbortController: 'readable', diff --git a/benchmark/common.js b/benchmark/common.js index bdccd6605f365e..77652aa065b902 100644 --- a/benchmark/common.js +++ b/benchmark/common.js @@ -338,7 +338,7 @@ function getUrlData(withBase) { * @param {number} e The repetition of the data, as exponent of 2 * @param {boolean} withBase Whether to include a base URL * @param {boolean} asUrl Whether to return the results as URL objects - * @return {string[] | string[][] | URL[]} + * @returns {string[] | string[][] | URL[]} */ function bakeUrlData(type, e = 0, withBase = false, asUrl = false) { let result = []; diff --git a/lib/internal/source_map/source_map.js b/lib/internal/source_map/source_map.js index f49de5d8c4deda..7589c4ac086ecc 100644 --- a/lib/internal/source_map/source_map.js +++ b/lib/internal/source_map/source_map.js @@ -96,21 +96,21 @@ class StringCharIterator { } /** - * @return {string} + * @returns {string} */ next() { return StringPrototypeCharAt(this._string, this._position++); } /** - * @return {string} + * @returns {string} */ peek() { return StringPrototypeCharAt(this._string, this._position); } /** - * @return {boolean} + * @returns {boolean} */ hasNext() { return this._position < this._string.length; @@ -148,7 +148,7 @@ class SourceMap { } /** - * @return {Object} raw source map v3 payload. + * @returns {Object} raw source map v3 payload. */ get payload() { return cloneSourceMapV3(this.#payload); @@ -179,7 +179,7 @@ class SourceMap { /** * @param {number} lineNumber in compiled resource * @param {number} columnNumber in compiled resource - * @return {?Array} + * @returns {?Array} */ findEntry(lineNumber, columnNumber) { let first = 0; @@ -280,7 +280,7 @@ class SourceMap { /** * @param {string} char - * @return {boolean} + * @returns {boolean} */ function isSeparator(char) { return char === ',' || char === ';'; @@ -288,7 +288,7 @@ function isSeparator(char) { /** * @param {SourceMap.StringCharIterator} stringCharIterator - * @return {number} + * @returns {number} */ function decodeVLQ(stringCharIterator) { // Read unsigned value. @@ -320,7 +320,7 @@ function decodeVLQ(stringCharIterator) { /** * @param {SourceMapV3} payload - * @return {SourceMapV3} + * @returns {SourceMapV3} */ function cloneSourceMapV3(payload) { if (typeof payload !== 'object') { @@ -340,7 +340,7 @@ function cloneSourceMapV3(payload) { * @param {Array} entry1 source map entry [lineNumber, columnNumber, sourceURL, * sourceLineNumber, sourceColumnNumber] * @param {Array} entry2 source map entry. - * @return {number} + * @returns {number} */ function compareSourceMapEntry(entry1, entry2) { const { 0: lineNumber1, 1: columnNumber1 } = entry1; diff --git a/tools/eslint-rules/non-ascii-character.js b/tools/eslint-rules/non-ascii-character.js index 6588125d33d201..421d05c153e472 100644 --- a/tools/eslint-rules/non-ascii-character.js +++ b/tools/eslint-rules/non-ascii-character.js @@ -1,5 +1,5 @@ /** - * @fileOverview Any non-ASCII characters in lib/ will increase the size + * @fileoverview Any non-ASCII characters in lib/ will increase the size * of the compiled node binary. This linter rule ensures that * any such character is reported. * @author Sarat Addepalli From 92d438831da6138c3866225851d4a4347bc074ac Mon Sep 17 00:00:00 2001 From: Antoine du Hamel Date: Mon, 19 Apr 2021 13:48:37 +0200 Subject: [PATCH 3/3] fixup! tools: install eslint-plugin-jsdoc --- .../node_modules/eslint-plugin-jsdoc/index.js | 105538 +-------------- .../eslint-plugin-markdown/index.js | 11958 +- .../eslint/node_modules/table/README.md | 52 - .../node_modules/table/dist/createStream.js | 20 +- .../table/dist/createStream.js.flow | 20 +- .../node_modules/table/dist/drawBorder.js | 108 +- .../table/dist/drawBorder.js.flow | 98 +- .../eslint/node_modules/table/dist/drawRow.js | 24 +- .../node_modules/table/dist/drawRow.js.flow | 22 +- .../node_modules/table/dist/drawTable.js | 20 +- .../node_modules/table/dist/drawTable.js.flow | 37 +- .../node_modules/table/dist/makeConfig.js | 13 +- .../table/dist/makeConfig.js.flow | 13 +- .../table/dist/makeStreamConfig.js | 10 - .../table/dist/makeStreamConfig.js.flow | 9 - .../table/dist/schemas/config.json | 3 - .../table/dist/schemas/streamConfig.json | 3 - .../eslint/node_modules/table/dist/table.js | 14 +- .../node_modules/table/dist/table.js.flow | 14 +- .../node_modules/table/dist/validators.js | 68 +- .../ajv/dist/compile/validate/keyword.js | 5 +- .../table/node_modules/ajv/dist/core.js | 3 +- .../applicator/additionalProperties.js | 2 +- .../applicator/patternProperties.js | 2 +- .../ajv/dist/vocabularies/code.js | 7 +- .../dist/vocabularies/validation/pattern.js | 6 +- .../table/node_modules/ajv/package.json | 2 +- .../eslint/node_modules/table/package.json | 2 +- tools/update-eslint.sh | 14 +- 29 files changed, 203 insertions(+), 117884 deletions(-) diff --git a/tools/node_modules/eslint/node_modules/eslint-plugin-jsdoc/index.js b/tools/node_modules/eslint/node_modules/eslint-plugin-jsdoc/index.js index 08bb390e5066c5..cb9928eff07384 100644 --- a/tools/node_modules/eslint/node_modules/eslint-plugin-jsdoc/index.js +++ b/tools/node_modules/eslint/node_modules/eslint-plugin-jsdoc/index.js @@ -1,105541 +1,7 @@ -'use strict'; - -var lodash = require('lodash'); -var fs = require('fs'); -var path = require('path'); -var require$$2 = require('@eslint/eslintrc'); -var Module = require('module'); -var getGlobParent = require('glob-parent'); -var isGlob = require('is-glob'); -var require$$1$1 = require('minimatch'); -var require$$0$1 = require('debug'); -var eslintScope = require('eslint-scope'); -var vk = require('eslint-visitor-keys'); -var espree = require('espree'); -var globals = require('globals'); -var util$1 = require('util'); -var Ajv = require('ajv'); -var require$$0$2 = require('eslint-utils'); -var assert = require('assert'); -var levn = require('levn'); -var esquery = require('esquery'); -var esutils = require('esutils'); -var createTree = require('functional-red-black-tree'); -var regexpp = require('regexpp'); -var ignore = require('ignore'); -var naturalCompare = require('natural-compare'); -var doctrine = require('doctrine'); -var murmur = require('imurmurhash'); -var fileEntryCache = require('file-entry-cache'); -var stringify = require('json-stable-stringify-without-jsonify'); -var require$$0$3 = require('semver'); - -function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } - -var lodash__default = /*#__PURE__*/_interopDefaultLegacy(lodash); -var fs__default = /*#__PURE__*/_interopDefaultLegacy(fs); -var path__default = /*#__PURE__*/_interopDefaultLegacy(path); -var require$$2__default = /*#__PURE__*/_interopDefaultLegacy(require$$2); -var Module__default = /*#__PURE__*/_interopDefaultLegacy(Module); -var getGlobParent__default = /*#__PURE__*/_interopDefaultLegacy(getGlobParent); -var isGlob__default = /*#__PURE__*/_interopDefaultLegacy(isGlob); -var require$$1__default = /*#__PURE__*/_interopDefaultLegacy(require$$1$1); -var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0$1); -var eslintScope__default = /*#__PURE__*/_interopDefaultLegacy(eslintScope); -var vk__default = /*#__PURE__*/_interopDefaultLegacy(vk); -var espree__default = /*#__PURE__*/_interopDefaultLegacy(espree); -var globals__default = /*#__PURE__*/_interopDefaultLegacy(globals); -var util__default = /*#__PURE__*/_interopDefaultLegacy(util$1); -var Ajv__default = /*#__PURE__*/_interopDefaultLegacy(Ajv); -var require$$0__default$1 = /*#__PURE__*/_interopDefaultLegacy(require$$0$2); -var assert__default = /*#__PURE__*/_interopDefaultLegacy(assert); -var levn__default = /*#__PURE__*/_interopDefaultLegacy(levn); -var esquery__default = /*#__PURE__*/_interopDefaultLegacy(esquery); -var esutils__default = /*#__PURE__*/_interopDefaultLegacy(esutils); -var createTree__default = /*#__PURE__*/_interopDefaultLegacy(createTree); -var regexpp__default = /*#__PURE__*/_interopDefaultLegacy(regexpp); -var ignore__default = /*#__PURE__*/_interopDefaultLegacy(ignore); -var naturalCompare__default = /*#__PURE__*/_interopDefaultLegacy(naturalCompare); -var doctrine__default = /*#__PURE__*/_interopDefaultLegacy(doctrine); -var murmur__default = /*#__PURE__*/_interopDefaultLegacy(murmur); -var fileEntryCache__default = /*#__PURE__*/_interopDefaultLegacy(fileEntryCache); -var stringify__default = /*#__PURE__*/_interopDefaultLegacy(stringify); -var require$$0__default$2 = /*#__PURE__*/_interopDefaultLegacy(require$$0$3); - -var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {}; - -function getDefaultExportFromCjs (x) { - return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; -} - -function createCommonjsModule(fn) { - var module = { exports: {} }; - return fn(module, module.exports), module.exports; -} - -function commonjsRequire (path) { - throw new Error('Could not dynamically require "' + path + '". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.'); -} - -var util = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); -exports.rewireSpecs = exports.rewireSource = exports.seedTokens = exports.seedSpec = exports.seedBlock = exports.splitLines = exports.splitSpace = exports.isSpace = void 0; -function isSpace(source) { - return /^\s+$/.test(source); -} -exports.isSpace = isSpace; -function splitSpace(source) { - const matches = source.match(/^\s+/); - return matches == null - ? ['', source] - : [source.slice(0, matches[0].length), source.slice(matches[0].length)]; -} -exports.splitSpace = splitSpace; -function splitLines(source) { - return source.split(/\r?\n/); -} -exports.splitLines = splitLines; -function seedBlock(block = {}) { - return Object.assign({ description: '', tags: [], source: [], problems: [] }, block); -} -exports.seedBlock = seedBlock; -function seedSpec(spec = {}) { - return Object.assign({ tag: '', name: '', type: '', optional: false, description: '', problems: [], source: [] }, spec); -} -exports.seedSpec = seedSpec; -function seedTokens(tokens = {}) { - return Object.assign({ start: '', delimiter: '', postDelimiter: '', tag: '', postTag: '', name: '', postName: '', type: '', postType: '', description: '', end: '' }, tokens); -} -exports.seedTokens = seedTokens; -/** - * Assures Block.tags[].source contains references to the Block.source items, - * using Block.source as a source of truth. This is a counterpart of rewireSpecs - * @param block parsed coments block - */ -function rewireSource(block) { - const source = block.source.reduce((acc, line) => acc.set(line.number, line), new Map()); - for (const spec of block.tags) { - spec.source = spec.source.map((line) => source.get(line.number)); - } - return block; -} -exports.rewireSource = rewireSource; -/** - * Assures Block.source contains references to the Block.tags[].source items, - * using Block.tags[].source as a source of truth. This is a counterpart of rewireSource - * @param block parsed coments block - */ -function rewireSpecs(block) { - const source = block.tags.reduce((acc, spec) => spec.source.reduce((acc, line) => acc.set(line.number, line), acc), new Map()); - block.source = block.source.map((line) => source.get(line.number) || line); - return block; -} -exports.rewireSpecs = rewireSpecs; -}); - -const reTag = /^@\S+/; -/** - * Creates configured `Parser` - * @param {Partial} options - */ -function getParser$3({ fence = '```', } = {}) { - const fencer = getFencer(fence); - const toggleFence = (source, isFenced) => fencer(source) ? !isFenced : isFenced; - return function parseBlock(source) { - // start with description section - const sections = [[]]; - let isFenced = false; - for (const line of source) { - if (reTag.test(line.tokens.description) && !isFenced) { - sections.push([line]); - } - else { - sections[sections.length - 1].push(line); - } - isFenced = toggleFence(line.tokens.description, isFenced); - } - return sections; - }; -} -var _default$a = getParser$3; -function getFencer(fence) { - if (typeof fence === 'string') - return (source) => source.split(fence).length % 2 === 0; - return fence; -} - -var blockParser = /*#__PURE__*/Object.defineProperty({ - default: _default$a -}, '__esModule', {value: true}); - -var primitives = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); -exports.Markers = void 0; -(function (Markers) { - Markers["start"] = "/**"; - Markers["nostart"] = "/***"; - Markers["delim"] = "*"; - Markers["end"] = "*/"; -})(exports.Markers || (exports.Markers = {})); -}); - -function getParser$2({ startLine = 0, } = {}) { - let block = null; - let num = startLine; - return function parseSource(source) { - let rest = source; - const tokens = util.seedTokens(); - [tokens.start, rest] = util.splitSpace(rest); - if (block === null && - rest.startsWith(primitives.Markers.start) && - !rest.startsWith(primitives.Markers.nostart)) { - block = []; - tokens.delimiter = rest.slice(0, primitives.Markers.start.length); - rest = rest.slice(primitives.Markers.start.length); - [tokens.postDelimiter, rest] = util.splitSpace(rest); - } - if (block === null) { - num++; - return null; - } - const isClosed = rest.trimRight().endsWith(primitives.Markers.end); - if (tokens.delimiter === '' && - rest.startsWith(primitives.Markers.delim) && - !rest.startsWith(primitives.Markers.end)) { - tokens.delimiter = primitives.Markers.delim; - rest = rest.slice(primitives.Markers.delim.length); - [tokens.postDelimiter, rest] = util.splitSpace(rest); - } - if (isClosed) { - const trimmed = rest.trimRight(); - tokens.end = rest.slice(trimmed.length - primitives.Markers.end.length); - rest = trimmed.slice(0, -primitives.Markers.end.length); - } - tokens.description = rest; - block.push({ number: num, source, tokens }); - num++; - if (isClosed) { - const result = block.slice(); - block = null; - return result; - } - return null; - }; -} -var _default$9 = getParser$2; - -var sourceParser = /*#__PURE__*/Object.defineProperty({ - default: _default$9 -}, '__esModule', {value: true}); - -function getParser$1({ tokenizers }) { - return function parseSpec(source) { - var _a; - let spec = util.seedSpec({ source }); - for (const tokenize of tokenizers) { - spec = tokenize(spec); - if ((_a = spec.problems[spec.problems.length - 1]) === null || _a === void 0 ? void 0 : _a.critical) - break; - } - return spec; - }; -} -var _default$8 = getParser$1; - -var specParser = /*#__PURE__*/Object.defineProperty({ - default: _default$8 -}, '__esModule', {value: true}); - -/** - * Splits the `@prefix` from remaining `Spec.lines[].token.descrioption` into the `tag` token, - * and populates `spec.tag` - */ -function tagTokenizer() { - return (spec) => { - const { tokens } = spec.source[0]; - const match = tokens.description.match(/\s*(@(\S+))(\s*)/); - if (match === null) { - spec.problems.push({ - code: 'spec:tag:prefix', - message: 'tag should start with "@" symbol', - line: spec.source[0].number, - critical: true, - }); - return spec; - } - tokens.tag = match[1]; - tokens.postTag = match[3]; - tokens.description = tokens.description.slice(match[0].length); - spec.tag = match[2]; - return spec; - }; -} -var _default$7 = tagTokenizer; - -var tag = /*#__PURE__*/Object.defineProperty({ - default: _default$7 -}, '__esModule', {value: true}); - -/** - * Sets splits remaining `Spec.lines[].tokes.description` into `type` and `description` - * tokens and populates Spec.type` - * - * @param {Spacing} spacing tells how to deal with a whitespace - * for type values going over multiple lines - */ -function typeTokenizer(spacing = 'compact') { - const join = getJoiner(spacing); - return (spec) => { - let curlies = 0; - let lines = []; - for (const [i, { tokens }] of spec.source.entries()) { - let type = ''; - if (i === 0 && tokens.description[0] !== '{') - return spec; - for (const ch of tokens.description) { - if (ch === '{') - curlies++; - if (ch === '}') - curlies--; - type += ch; - if (curlies === 0) - break; - } - lines.push([tokens, type]); - if (curlies === 0) - break; - } - if (curlies !== 0) { - spec.problems.push({ - code: 'spec:type:unpaired-curlies', - message: 'unpaired curlies', - line: spec.source[0].number, - critical: true, - }); - return spec; - } - const parts = []; - const offset = lines[0][0].postDelimiter.length; - for (const [i, [tokens, type]] of lines.entries()) { - if (type === '') - continue; - tokens.type = type; - if (i > 0) { - tokens.type = tokens.postDelimiter.slice(offset) + type; - tokens.postDelimiter = tokens.postDelimiter.slice(0, offset); - } - [tokens.postType, tokens.description] = util.splitSpace(tokens.description.slice(type.length)); - parts.push(tokens.type); - } - parts[0] = parts[0].slice(1); - parts[parts.length - 1] = parts[parts.length - 1].slice(0, -1); - spec.type = join(parts); - return spec; - }; -} -var _default$6 = typeTokenizer; -const trim = (x) => x.trim(); -function getJoiner(spacing) { - if (spacing === 'compact') - return (t) => t.map(trim).join(''); - else if (spacing === 'preserve') - return (t) => t.join('\n'); - else - return spacing; -} - -var type_1 = /*#__PURE__*/Object.defineProperty({ - default: _default$6 -}, '__esModule', {value: true}); - -const isQuoted = (s) => s && s.startsWith('"') && s.endsWith('"'); -/** - * Splits remaining `spec.lines[].tokens.description` into `name` and `descriptions` tokens, - * and populates the `spec.name` - */ -function nameTokenizer() { - const typeEnd = (num, { tokens }, i) => tokens.type === '' ? num : i; - return (spec) => { - // look for the name in the line where {type} ends - const { tokens } = spec.source[spec.source.reduce(typeEnd, 0)]; - const source = tokens.description.trimLeft(); - const quotedGroups = source.split('"'); - // if it starts with quoted group, assume it is a literal - if (quotedGroups.length > 1 && - quotedGroups[0] === '' && - quotedGroups.length % 2 === 1) { - spec.name = quotedGroups[1]; - tokens.name = `"${quotedGroups[1]}"`; - [tokens.postName, tokens.description] = util.splitSpace(source.slice(tokens.name.length)); - return spec; - } - let brackets = 0; - let name = ''; - let optional = false; - let defaultValue; - // assume name is non-space string or anything wrapped into brackets - for (const ch of source) { - if (brackets === 0 && util.isSpace(ch)) - break; - if (ch === '[') - brackets++; - if (ch === ']') - brackets--; - name += ch; - } - if (brackets !== 0) { - spec.problems.push({ - code: 'spec:name:unpaired-brackets', - message: 'unpaired brackets', - line: spec.source[0].number, - critical: true, - }); - return spec; - } - const nameToken = name; - if (name[0] === '[' && name[name.length - 1] === ']') { - optional = true; - name = name.slice(1, -1); - const parts = name.split('='); - name = parts[0].trim(); - if (parts[1] !== undefined) - defaultValue = parts.slice(1).join('=').trim(); - if (name === '') { - spec.problems.push({ - code: 'spec:name:empty-name', - message: 'empty name', - line: spec.source[0].number, - critical: true, - }); - return spec; - } - if (defaultValue === '') { - spec.problems.push({ - code: 'spec:name:empty-default', - message: 'empty default value', - line: spec.source[0].number, - critical: true, - }); - return spec; - } - // has "=" and is not a string, except for "=>" - if (!isQuoted(defaultValue) && /=(?!>)/.test(defaultValue)) { - spec.problems.push({ - code: 'spec:name:invalid-default', - message: 'invalid default value syntax', - line: spec.source[0].number, - critical: true, - }); - return spec; - } - } - spec.optional = optional; - spec.name = name; - tokens.name = nameToken; - if (defaultValue !== undefined) - spec.default = defaultValue; - [tokens.postName, tokens.description] = util.splitSpace(source.slice(tokens.name.length)); - return spec; - }; -} -var _default$5 = nameTokenizer; - -var name$1 = /*#__PURE__*/Object.defineProperty({ - default: _default$5 -}, '__esModule', {value: true}); - -var description$2 = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); -exports.getJoiner = void 0; - -/** - * Makes no changes to `spec.lines[].tokens` but joins them into `spec.description` - * following given spacing srtategy - * @param {Spacing} spacing tells how to handle the whitespace - */ -function descriptionTokenizer(spacing = 'compact') { - const join = getJoiner(spacing); - return (spec) => { - spec.description = join(spec.source); - return spec; - }; -} -exports.default = descriptionTokenizer; -function getJoiner(spacing) { - if (spacing === 'compact') - return compactJoiner; - if (spacing === 'preserve') - return preserveJoiner; - return spacing; -} -exports.getJoiner = getJoiner; -function compactJoiner(lines) { - return lines - .map(({ tokens: { description } }) => description.trim()) - .filter((description) => description !== '') - .join(' '); -} -const lineNo = (num, { tokens }, i) => tokens.type === '' ? num : i; -const getDescription = ({ tokens }) => (tokens.delimiter === '' ? tokens.start : tokens.postDelimiter.slice(1)) + - tokens.description; -function preserveJoiner(lines) { - if (lines.length === 0) - return ''; - // skip the opening line with no description - if (lines[0].tokens.description === '' && - lines[0].tokens.delimiter === primitives.Markers.start) - lines = lines.slice(1); - // skip the closing line with no description - const lastLine = lines[lines.length - 1]; - if (lastLine !== undefined && - lastLine.tokens.description === '' && - lastLine.tokens.end.endsWith(primitives.Markers.end)) - lines = lines.slice(0, -1); - // description starts at the last line of type definition - lines = lines.slice(lines.reduce(lineNo, 0)); - return lines.map(getDescription).join('\n'); -} -}); - -function getParser({ startLine = 0, fence = '```', spacing = 'compact', tokenizers = [ - tag.default(), - type_1.default(spacing), - name$1.default(), - description$2.default(spacing), -], } = {}) { - if (startLine < 0 || startLine % 1 > 0) - throw new Error('Invalid startLine'); - const parseSource = sourceParser.default({ startLine }); - const parseBlock = blockParser.default({ fence }); - const parseSpec = specParser.default({ tokenizers }); - const joinDescription = description$2.getJoiner(spacing); - const notEmpty = (line) => line.tokens.description.trim() != ''; - return function (source) { - const blocks = []; - for (const line of util.splitLines(source)) { - const lines = parseSource(line); - if (lines === null) - continue; - if (lines.find(notEmpty) === undefined) - continue; - const sections = parseBlock(lines); - const specs = sections.slice(1).map(parseSpec); - blocks.push({ - description: joinDescription(sections[0]), - tags: specs, - source: lines, - problems: specs.reduce((acc, spec) => acc.concat(spec.problems), []), - }); - } - return blocks; - }; -} -var _default$4 = getParser; - -var parser$2 = /*#__PURE__*/Object.defineProperty({ - default: _default$4 -}, '__esModule', {value: true}); - -function join(tokens) { - return (tokens.start + - tokens.delimiter + - tokens.postDelimiter + - tokens.tag + - tokens.postTag + - tokens.type + - tokens.postType + - tokens.name + - tokens.postName + - tokens.description + - tokens.end); -} -function getStringifier() { - return (block) => block.source.map(({ tokens }) => join(tokens)).join('\n'); -} -var _default$3 = getStringifier; - -var stringifier = /*#__PURE__*/Object.defineProperty({ - default: _default$3 -}, '__esModule', {value: true}); - -var __rest$1 = (commonjsGlobal && commonjsGlobal.__rest) || function (s, e) { - var t = {}; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) - t[p] = s[p]; - if (s != null && typeof Object.getOwnPropertySymbols === "function") - for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { - if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) - t[p[i]] = s[p[i]]; - } - return t; -}; - - - -const zeroWidth$1 = { - start: 0, - tag: 0, - type: 0, - name: 0, -}; -const getWidth = (w, { tokens: t }) => ({ - start: t.delimiter === primitives.Markers.start ? t.start.length : w.start, - tag: Math.max(w.tag, t.tag.length), - type: Math.max(w.type, t.type.length), - name: Math.max(w.name, t.name.length), -}); -const space = (len) => ''.padStart(len, ' '); -function align$1() { - let intoTags = false; - let w; - function update(line) { - const tokens = Object.assign({}, line.tokens); - if (tokens.tag !== '') - intoTags = true; - const isEmpty = tokens.tag === '' && - tokens.name === '' && - tokens.type === '' && - tokens.description === ''; - // dangling '*/' - if (tokens.end === primitives.Markers.end && isEmpty) { - tokens.start = space(w.start + 1); - return Object.assign(Object.assign({}, line), { tokens }); - } - switch (tokens.delimiter) { - case primitives.Markers.start: - tokens.start = space(w.start); - break; - case primitives.Markers.delim: - tokens.start = space(w.start + 1); - break; - default: - tokens.delimiter = ''; - tokens.start = space(w.start + 2); // compensate delimiter - } - if (!intoTags) { - tokens.postDelimiter = tokens.description === '' ? '' : ' '; - return Object.assign(Object.assign({}, line), { tokens }); - } - const nothingAfter = { - delim: false, - tag: false, - type: false, - name: false, - }; - if (tokens.description === '') { - nothingAfter.name = true; - tokens.postName = ''; - if (tokens.name === '') { - nothingAfter.type = true; - tokens.postType = ''; - if (tokens.type === '') { - nothingAfter.tag = true; - tokens.postTag = ''; - if (tokens.tag === '') { - nothingAfter.delim = true; - } - } - } - } - tokens.postDelimiter = nothingAfter.delim ? '' : ' '; - if (!nothingAfter.tag) - tokens.postTag = space(w.tag - tokens.tag.length + 1); - if (!nothingAfter.type) - tokens.postType = space(w.type - tokens.type.length + 1); - if (!nothingAfter.name) - tokens.postName = space(w.name - tokens.name.length + 1); - return Object.assign(Object.assign({}, line), { tokens }); - } - return (_a) => { - var { source } = _a, fields = __rest$1(_a, ["source"]); - w = source.reduce(getWidth, Object.assign({}, zeroWidth$1)); - return util.rewireSource(Object.assign(Object.assign({}, fields), { source: source.map(update) })); - }; -} -var _default$2 = align$1; - -var align_1 = /*#__PURE__*/Object.defineProperty({ - default: _default$2 -}, '__esModule', {value: true}); - -var __rest = (commonjsGlobal && commonjsGlobal.__rest) || function (s, e) { - var t = {}; - for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) - t[p] = s[p]; - if (s != null && typeof Object.getOwnPropertySymbols === "function") - for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { - if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) - t[p[i]] = s[p[i]]; - } - return t; -}; - - -const pull = (offset) => (str) => str.slice(offset); -const push = (offset) => { - const space = ''.padStart(offset, ' '); - return (str) => str + space; -}; -function indent$1(pos) { - let shift; - const pad = (start) => { - if (shift === undefined) { - const offset = pos - start.length; - shift = offset > 0 ? push(offset) : pull(-offset); - } - return shift(start); - }; - const update = (line) => (Object.assign(Object.assign({}, line), { tokens: Object.assign(Object.assign({}, line.tokens), { start: pad(line.tokens.start) }) })); - return (_a) => { - var { source } = _a, fields = __rest(_a, ["source"]); - return util.rewireSource(Object.assign(Object.assign({}, fields), { source: source.map(update) })); - }; -} -var _default$1 = indent$1; - -var indent_1 = /*#__PURE__*/Object.defineProperty({ - default: _default$1 -}, '__esModule', {value: true}); - -var transforms = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); -exports.flow = void 0; -function flow(...transforms) { - return (block) => transforms.reduce((block, t) => t(block), block); -} -exports.flow = flow; -}); - -const zeroWidth = { - line: 0, - start: 0, - delimiter: 0, - postDelimiter: 0, - tag: 0, - postTag: 0, - name: 0, - postName: 0, - type: 0, - postType: 0, - description: 0, - end: 0, -}; -const fields = Object.keys(zeroWidth); -const repr = (x) => (util.isSpace(x) ? `{${x.length}}` : x); -const frame = (line) => '|' + line.join('|') + '|'; -const align = (width, tokens) => Object.keys(tokens).map((k) => repr(tokens[k]).padEnd(width[k])); -function inspect$1({ source }) { - if (source.length === 0) - return ''; - const width = Object.assign({}, zeroWidth); - for (const f of fields) - width[f] = f.length; - for (const { number, tokens } of source) { - width.line = Math.max(width.line, number.toString().length); - for (const k in tokens) - width[k] = Math.max(width[k], repr(tokens[k]).length); - } - const lines = [[], []]; - for (const f of fields) - lines[0].push(f.padEnd(width[f])); - for (const f of fields) - lines[1].push('-'.padEnd(width[f], '-')); - for (const { number, tokens } of source) { - const line = number.toString().padStart(width.line); - lines.push([line, ...align(width, tokens)]); - } - return lines.map(frame).join('\n'); -} -var _default = inspect$1; - -var inspect_1 = /*#__PURE__*/Object.defineProperty({ - default: _default -}, '__esModule', {value: true}); - -var lib = createCommonjsModule(function (module, exports) { -Object.defineProperty(exports, "__esModule", { value: true }); -exports.tokenizers = exports.transforms = exports.inspect = exports.stringify = exports.parse = void 0; - - - - - - - - - -function parse(source, options = {}) { - return parser$2.default(options)(source); -} -exports.parse = parse; -exports.stringify = stringifier.default(); - -Object.defineProperty(exports, "inspect", { enumerable: true, get: function () { return inspect_1.default; } }); -exports.transforms = { - flow: transforms.flow, - align: align_1.default, - indent: indent_1.default, -}; -exports.tokenizers = { - tag: tag.default, - type: type_1.default, - name: name$1.default, - description: description$2.default, -}; -}); - -var getJSDocComment_1 = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = exports.findJSDocComment = exports.getDecorator = exports.getJSDocComment = exports.getReducedASTNode = void 0; - +"use strict";var e=require("lodash"),t=require("fs"),n=require("path"),r=require("@eslint/eslintrc"),o=require("module"),s=require("glob-parent"),a=require("is-glob"),i=require("minimatch"),c=require("debug"),l=require("eslint-scope"),u=require("eslint-visitor-keys"),p=require("espree"),d=require("globals"),f=require("util"),m=require("ajv"),g=require("eslint-utils"),h=require("assert"),y=require("levn"),x=require("esquery"),b=require("esutils"),E=require("functional-red-black-tree"),S=require("regexpp"),C=require("ignore"),v=require("natural-compare"),A=require("doctrine"),k=require("imurmurhash"),w=require("file-entry-cache"),P=require("json-stable-stringify-without-jsonify"),T=require("semver");function I(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var F=I(e),D=I(t),O=I(n),B=I(r),N=I(o),j=I(s),L=I(a),R=I(i),M=I(c),_=I(l),$=I(u),q=I(p),U=I(d),V=I(f),W=I(m),G=I(g),z=I(h),J=I(y),K=I(x),Y=I(b),H=I(E),X=I(S),Q=I(C),Z=I(v),ee=I(A),te=I(k),ne=I(w),re=I(P),oe=I(T),se="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{};function ae(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function ie(e){var t={exports:{}};return e(t,t.exports),t.exports}function ce(e){throw new Error('Could not dynamically require "'+e+'". Please configure the dynamicRequireTargets or/and ignoreDynamicRequires option of @rollup/plugin-commonjs appropriately for this require call to work.')}var le=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.rewireSpecs=t.rewireSource=t.seedTokens=t.seedSpec=t.seedBlock=t.splitLines=t.splitSpace=t.isSpace=void 0,t.isSpace=function(e){return/^\s+$/.test(e)},t.splitSpace=function(e){const t=e.match(/^\s+/);return null==t?["",e]:[e.slice(0,t[0].length),e.slice(t[0].length)]},t.splitLines=function(e){return e.split(/\r?\n/)},t.seedBlock=function(e={}){return Object.assign({description:"",tags:[],source:[],problems:[]},e)},t.seedSpec=function(e={}){return Object.assign({tag:"",name:"",type:"",optional:!1,description:"",problems:[],source:[]},e)},t.seedTokens=function(e={}){return Object.assign({start:"",delimiter:"",postDelimiter:"",tag:"",postTag:"",name:"",postName:"",type:"",postType:"",description:"",end:""},e)},t.rewireSource=function(e){const t=e.source.reduce(((e,t)=>e.set(t.number,t)),new Map);for(const n of e.tags)n.source=n.source.map((e=>t.get(e.number)));return e},t.rewireSpecs=function(e){const t=e.tags.reduce(((e,t)=>t.source.reduce(((e,t)=>e.set(t.number,t)),e)),new Map);return e.source=e.source.map((e=>t.get(e.number)||e)),e}}));const ue=/^@\S+/;var pe=function({fence:e="```"}={}){const t=function(e){return"string"==typeof e?t=>t.split(e).length%2==0:e}(e),n=(e,n)=>t(e)?!n:n;return function(e){const t=[[]];let r=!1;for(const o of e)ue.test(o.tokens.description)&&!r?t.push([o]):t[t.length-1].push(o),r=n(o.tokens.description,r);return t}};var de=Object.defineProperty({default:pe},"__esModule",{value:!0}),fe=ie((function(e,t){var n;Object.defineProperty(t,"__esModule",{value:!0}),t.Markers=void 0,(n=t.Markers||(t.Markers={})).start="/**",n.nostart="/***",n.delim="*",n.end="*/"}));var me=function({startLine:e=0}={}){let t=null,n=e;return function(e){let r=e;const o=le.seedTokens();if([o.start,r]=le.splitSpace(r),null===t&&r.startsWith(fe.Markers.start)&&!r.startsWith(fe.Markers.nostart)&&(t=[],o.delimiter=r.slice(0,fe.Markers.start.length),r=r.slice(fe.Markers.start.length),[o.postDelimiter,r]=le.splitSpace(r)),null===t)return n++,null;const s=r.trimRight().endsWith(fe.Markers.end);if(""===o.delimiter&&r.startsWith(fe.Markers.delim)&&!r.startsWith(fe.Markers.end)&&(o.delimiter=fe.Markers.delim,r=r.slice(fe.Markers.delim.length),[o.postDelimiter,r]=le.splitSpace(r)),s){const e=r.trimRight();o.end=r.slice(e.length-fe.Markers.end.length),r=e.slice(0,-fe.Markers.end.length)}if(o.description=r,t.push({number:n,source:e,tokens:o}),n++,s){const e=t.slice();return t=null,e}return null}},ge=Object.defineProperty({default:me},"__esModule",{value:!0});var he=function({tokenizers:e}){return function(t){var n;let r=le.seedSpec({source:t});for(const t of e)if(r=t(r),null===(n=r.problems[r.problems.length-1])||void 0===n?void 0:n.critical)break;return r}},ye=Object.defineProperty({default:he},"__esModule",{value:!0});var xe=function(){return e=>{const{tokens:t}=e.source[0],n=t.description.match(/\s*(@(\S+))(\s*)/);return null===n?(e.problems.push({code:"spec:tag:prefix",message:'tag should start with "@" symbol',line:e.source[0].number,critical:!0}),e):(t.tag=n[1],t.postTag=n[3],t.description=t.description.slice(n[0].length),e.tag=n[2],e)}},be=Object.defineProperty({default:xe},"__esModule",{value:!0});var Ee=function(e="compact"){const t=function(e){return"compact"===e?e=>e.map(Se).join(""):"preserve"===e?e=>e.join("\n"):e}(e);return e=>{let n=0,r=[];for(const[t,{tokens:o}]of e.source.entries()){let s="";if(0===t&&"{"!==o.description[0])return e;for(const e of o.description)if("{"===e&&n++,"}"===e&&n--,s+=e,0===n)break;if(r.push([o,s]),0===n)break}if(0!==n)return e.problems.push({code:"spec:type:unpaired-curlies",message:"unpaired curlies",line:e.source[0].number,critical:!0}),e;const o=[],s=r[0][0].postDelimiter.length;for(const[e,[t,n]]of r.entries())""!==n&&(t.type=n,e>0&&(t.type=t.postDelimiter.slice(s)+n,t.postDelimiter=t.postDelimiter.slice(0,s)),[t.postType,t.description]=le.splitSpace(t.description.slice(n.length)),o.push(t.type));return o[0]=o[0].slice(1),o[o.length-1]=o[o.length-1].slice(0,-1),e.type=t(o),e}};const Se=e=>e.trim();var Ce=Object.defineProperty({default:Ee},"__esModule",{value:!0});var ve=function(){const e=(e,{tokens:t},n)=>""===t.type?e:n;return t=>{const{tokens:n}=t.source[t.source.reduce(e,0)],r=n.description.trimLeft(),o=r.split('"');if(o.length>1&&""===o[0]&&o.length%2==1)return t.name=o[1],n.name=`"${o[1]}"`,[n.postName,n.description]=le.splitSpace(r.slice(n.name.length)),t;let s,a=0,i="",c=!1;for(const e of r){if(0===a&&le.isSpace(e))break;"["===e&&a++,"]"===e&&a--,i+=e}if(0!==a)return t.problems.push({code:"spec:name:unpaired-brackets",message:"unpaired brackets",line:t.source[0].number,critical:!0}),t;const l=i;if("["===i[0]&&"]"===i[i.length-1]){c=!0,i=i.slice(1,-1);const e=i.split("=");if(i=e[0].trim(),void 0!==e[1]&&(s=e.slice(1).join("=").trim()),""===i)return t.problems.push({code:"spec:name:empty-name",message:"empty name",line:t.source[0].number,critical:!0}),t;if(""===s)return t.problems.push({code:"spec:name:empty-default",message:"empty default value",line:t.source[0].number,critical:!0}),t;if(!((u=s)&&u.startsWith('"')&&u.endsWith('"'))&&/=(?!>)/.test(s))return t.problems.push({code:"spec:name:invalid-default",message:"invalid default value syntax",line:t.source[0].number,critical:!0}),t}var u;return t.optional=c,t.name=i,n.name=l,void 0!==s&&(t.default=s),[n.postName,n.description]=le.splitSpace(r.slice(n.name.length)),t}},Ae=Object.defineProperty({default:ve},"__esModule",{value:!0}),ke=ie((function(e,t){function n(e){return"compact"===e?r:"preserve"===e?a:e}function r(e){return e.map((({tokens:{description:e}})=>e.trim())).filter((e=>""!==e)).join(" ")}Object.defineProperty(t,"__esModule",{value:!0}),t.getJoiner=void 0,t.default=function(e="compact"){const t=n(e);return e=>(e.description=t(e.source),e)},t.getJoiner=n;const o=(e,{tokens:t},n)=>""===t.type?e:n,s=({tokens:e})=>(""===e.delimiter?e.start:e.postDelimiter.slice(1))+e.description;function a(e){if(0===e.length)return"";""===e[0].tokens.description&&e[0].tokens.delimiter===fe.Markers.start&&(e=e.slice(1));const t=e[e.length-1];return void 0!==t&&""===t.tokens.description&&t.tokens.end.endsWith(fe.Markers.end)&&(e=e.slice(0,-1)),(e=e.slice(e.reduce(o,0))).map(s).join("\n")}}));var we=function({startLine:e=0,fence:t="```",spacing:n="compact",tokenizers:r=[be.default(),Ce.default(n),Ae.default(),ke.default(n)]}={}){if(e<0||e%1>0)throw new Error("Invalid startLine");const o=ge.default({startLine:e}),s=de.default({fence:t}),a=ye.default({tokenizers:r}),i=ke.getJoiner(n),c=e=>""!=e.tokens.description.trim();return function(e){const t=[];for(const n of le.splitLines(e)){const e=o(n);if(null===e)continue;if(void 0===e.find(c))continue;const r=s(e),l=r.slice(1).map(a);t.push({description:i(r[0]),tags:l,source:e,problems:l.reduce(((e,t)=>e.concat(t.problems)),[])})}return t}},Pe=Object.defineProperty({default:we},"__esModule",{value:!0});var Te=function(){return e=>e.source.map((({tokens:e})=>function(e){return e.start+e.delimiter+e.postDelimiter+e.tag+e.postTag+e.type+e.postType+e.name+e.postName+e.description+e.end}(e))).join("\n")},Ie=Object.defineProperty({default:Te},"__esModule",{value:!0}),Fe=se&&se.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(r=Object.getOwnPropertySymbols(e);o({start:t.delimiter===fe.Markers.start?t.start.length:e.start,tag:Math.max(e.tag,t.tag.length),type:Math.max(e.type,t.type.length),name:Math.max(e.name,t.name.length)}),Be=e=>"".padStart(e," ");var Ne=function(){let e,t=!1;function n(n){const r=Object.assign({},n.tokens);""!==r.tag&&(t=!0);const o=""===r.tag&&""===r.name&&""===r.type&&""===r.description;if(r.end===fe.Markers.end&&o)return r.start=Be(e.start+1),Object.assign(Object.assign({},n),{tokens:r});switch(r.delimiter){case fe.Markers.start:r.start=Be(e.start);break;case fe.Markers.delim:r.start=Be(e.start+1);break;default:r.delimiter="",r.start=Be(e.start+2)}if(!t)return r.postDelimiter=""===r.description?"":" ",Object.assign(Object.assign({},n),{tokens:r});const s={delim:!1,tag:!1,type:!1,name:!1};return""===r.description&&(s.name=!0,r.postName="",""===r.name&&(s.type=!0,r.postType="",""===r.type&&(s.tag=!0,r.postTag="",""===r.tag&&(s.delim=!0)))),r.postDelimiter=s.delim?"":" ",s.tag||(r.postTag=Be(e.tag-r.tag.length+1)),s.type||(r.postType=Be(e.type-r.type.length+1)),s.name||(r.postName=Be(e.name-r.name.length+1)),Object.assign(Object.assign({},n),{tokens:r})}return t=>{var{source:r}=t,o=Fe(t,["source"]);return e=r.reduce(Oe,Object.assign({},De)),le.rewireSource(Object.assign(Object.assign({},o),{source:r.map(n)}))}},je=Object.defineProperty({default:Ne},"__esModule",{value:!0}),Le=se&&se.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(r=Object.getOwnPropertySymbols(e);o{if(void 0===t){const r=e-n.length;t=r>0?(e=>{const t="".padStart(e," ");return e=>e+t})(r):(e=>t=>t.slice(e))(-r)}return t(n)},r=e=>Object.assign(Object.assign({},e),{tokens:Object.assign(Object.assign({},e.tokens),{start:n(e.tokens.start)})});return e=>{var{source:t}=e,n=Le(e,["source"]);return le.rewireSource(Object.assign(Object.assign({},n),{source:t.map(r)}))}},Me=Object.defineProperty({default:Re},"__esModule",{value:!0}),_e=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.flow=void 0,t.flow=function(...e){return t=>e.reduce(((e,t)=>t(e)),t)}}));const $e={line:0,start:0,delimiter:0,postDelimiter:0,tag:0,postTag:0,name:0,postName:0,type:0,postType:0,description:0,end:0},qe=Object.keys($e),Ue=e=>le.isSpace(e)?`{${e.length}}`:e,Ve=e=>"|"+e.join("|")+"|",We=(e,t)=>Object.keys(t).map((n=>Ue(t[n]).padEnd(e[n])));var Ge=function({source:e}){if(0===e.length)return"";const t=Object.assign({},$e);for(const e of qe)t[e]=e.length;for(const{number:n,tokens:r}of e){t.line=Math.max(t.line,n.toString().length);for(const e in r)t[e]=Math.max(t[e],Ue(r[e]).length)}const n=[[],[]];for(const e of qe)n[0].push(e.padEnd(t[e]));for(const e of qe)n[1].push("-".padEnd(t[e],"-"));for(const{number:r,tokens:o}of e){const e=r.toString().padStart(t.line);n.push([e,...We(t,o)])}return n.map(Ve).join("\n")},ze=Object.defineProperty({default:Ge},"__esModule",{value:!0}),Je=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.tokenizers=t.transforms=t.inspect=t.stringify=t.parse=void 0,t.parse=function(e,t={}){return Pe.default(t)(e)},t.stringify=Ie.default(),Object.defineProperty(t,"inspect",{enumerable:!0,get:function(){return ze.default}}),t.transforms={flow:_e.flow,align:je.default,indent:Me.default},t.tokenizers={tag:be.default,type:Ce.default,name:Ae.default,description:ke.default}})),Ke=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=t.findJSDocComment=t.getDecorator=t.getJSDocComment=t.getReducedASTNode=void 0; /** * Obtained originally from {@link https://github.com/eslint/eslint/blob/master/lib/util/source-code.js#L313} * * @license MIT */ - -/** - * Checks if the given token is a comment token or not. - * - * @param {Token} token - The token to check. - * @returns {boolean} `true` if the token is a comment token. - */ -const isCommentToken = token => { - return token.type === 'Line' || token.type === 'Block' || token.type === 'Shebang'; -}; - -const getDecorator = node => { - var _node$declaration, _node$declaration$dec, _node$decorators, _node$parent, _node$parent$decorato; - - return (node === null || node === void 0 ? void 0 : (_node$declaration = node.declaration) === null || _node$declaration === void 0 ? void 0 : (_node$declaration$dec = _node$declaration.decorators) === null || _node$declaration$dec === void 0 ? void 0 : _node$declaration$dec[0]) || (node === null || node === void 0 ? void 0 : (_node$decorators = node.decorators) === null || _node$decorators === void 0 ? void 0 : _node$decorators[0]) || (node === null || node === void 0 ? void 0 : (_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : (_node$parent$decorato = _node$parent.decorators) === null || _node$parent$decorato === void 0 ? void 0 : _node$parent$decorato[0]); -}; -/** - * Check to see if its a ES6 export declaration. - * - * @param {ASTNode} astNode An AST node. - * @returns {boolean} whether the given node represents an export declaration. - * @private - */ - - -exports.getDecorator = getDecorator; - -const looksLikeExport = function (astNode) { - return astNode.type === 'ExportDefaultDeclaration' || astNode.type === 'ExportNamedDeclaration' || astNode.type === 'ExportAllDeclaration' || astNode.type === 'ExportSpecifier'; -}; - -const getTSFunctionComment = function (astNode) { - const { - parent - } = astNode; - const grandparent = parent.parent; - const greatGrandparent = grandparent.parent; - const greatGreatGrandparent = greatGrandparent && greatGrandparent.parent; // istanbul ignore if - - if (parent.type !== 'TSTypeAnnotation') { - return astNode; - } - - switch (grandparent.type) { - case 'ClassProperty': - case 'TSDeclareFunction': - case 'TSMethodSignature': - case 'TSPropertySignature': - return grandparent; - - case 'ArrowFunctionExpression': - // istanbul ignore else - if (greatGrandparent.type === 'VariableDeclarator' // && greatGreatGrandparent.parent.type === 'VariableDeclaration' - ) { - return greatGreatGrandparent.parent; - } // istanbul ignore next - - - return astNode; - - case 'FunctionExpression': - // istanbul ignore else - if (greatGrandparent.type === 'MethodDefinition') { - return greatGrandparent; - } - - // Fallthrough - - default: - // istanbul ignore if - if (grandparent.type !== 'Identifier') { - // istanbul ignore next - return astNode; - } - - } // istanbul ignore next - - - switch (greatGrandparent.type) { - case 'ArrowFunctionExpression': - // istanbul ignore else - if (greatGreatGrandparent.type === 'VariableDeclarator' && greatGreatGrandparent.parent.type === 'VariableDeclaration') { - return greatGreatGrandparent.parent; - } // istanbul ignore next - - - return astNode; - - case 'FunctionDeclaration': - return greatGrandparent; - - case 'VariableDeclarator': - // istanbul ignore else - if (greatGreatGrandparent.type === 'VariableDeclaration') { - return greatGreatGrandparent; - } - - // Fallthrough - - default: - // istanbul ignore next - return astNode; - } -}; - -const invokedExpression = new Set(['CallExpression', 'OptionalCallExpression', 'NewExpression']); -const allowableCommentNode = new Set(['VariableDeclaration', 'ExpressionStatement', 'MethodDefinition', 'Property', 'ObjectProperty', 'ClassProperty']); -/* eslint-disable complexity */ - -/** - * Reduces the provided node to the appropriate node for evaluating JSDoc comment status. - * - * @param {ASTNode} node An AST node. - * @param {SourceCode} sourceCode The ESLint SourceCode. - * @returns {ASTNode} The AST node that can be evaluated for appropriate JSDoc comments. - * @private - */ - -const getReducedASTNode = function (node, sourceCode) { - /* eslint-enable complexity */ - let { - parent - } = node; - - switch (node.type) { - case 'TSFunctionType': - return getTSFunctionComment(node); - - case 'TSInterfaceDeclaration': - case 'TSTypeAliasDeclaration': - case 'TSEnumDeclaration': - case 'ClassDeclaration': - case 'FunctionDeclaration': - return looksLikeExport(parent) ? parent : node; - - case 'TSDeclareFunction': - case 'ClassExpression': - case 'ObjectExpression': - case 'ArrowFunctionExpression': - case 'TSEmptyBodyFunctionExpression': - case 'FunctionExpression': - if (!invokedExpression.has(parent.type)) { - while (!sourceCode.getCommentsBefore(parent).length && !/Function/u.test(parent.type) && !allowableCommentNode.has(parent.type)) { - parent = parent.parent; - - if (!parent) { - break; - } - } - - if (parent && parent.type !== 'FunctionDeclaration' && parent.type !== 'Program') { - if (parent.parent && parent.parent.type === 'ExportNamedDeclaration') { - return parent.parent; - } - - return parent; - } - } - - return node; - - default: - return node; - } -}; -/** - * Checks for the presence of a JSDoc comment for the given node and returns it. - * - * @param {ASTNode} astNode The AST node to get the comment for. - * @returns {Token|null} The Block comment token containing the JSDoc comment - * for the given node or null if not found. - * @private - */ - - -exports.getReducedASTNode = getReducedASTNode; - -const findJSDocComment = (astNode, sourceCode, settings) => { - const { - minLines, - maxLines - } = settings; - let currentNode = astNode; - let tokenBefore = null; - - while (currentNode) { - const decorator = getDecorator(currentNode); - - if (decorator) { - currentNode = decorator; - } - - tokenBefore = sourceCode.getTokenBefore(currentNode, { - includeComments: true - }); - - if (!tokenBefore || !isCommentToken(tokenBefore)) { - return null; - } - - if (tokenBefore.type === 'Line') { - currentNode = tokenBefore; - continue; - } - - break; - } - - if (tokenBefore.type === 'Block' && tokenBefore.value.charAt(0) === '*' && currentNode.loc.start.line - tokenBefore.loc.end.line >= minLines && currentNode.loc.start.line - tokenBefore.loc.end.line <= maxLines) { - return tokenBefore; - } - - return null; -}; -/** - * Retrieves the JSDoc comment for a given node. - * - * @param {SourceCode} sourceCode The ESLint SourceCode - * @param {ASTNode} node The AST node to get the comment for. - * @param {object} settings The settings in context - * @returns {Token|null} The Block comment token containing the JSDoc comment - * for the given node or null if not found. - * @public - */ - - -exports.findJSDocComment = findJSDocComment; - -const getJSDocComment = function (sourceCode, node, settings) { - const reducedNode = getReducedASTNode(node, sourceCode); - return findJSDocComment(reducedNode, sourceCode, settings); -}; - -exports.getJSDocComment = getJSDocComment; -var _default = getJSDocComment; -exports.default = _default; -//# sourceMappingURL=getJSDocComment.js.map -}); - -var WarnSettings_1 = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -const WarnSettings = function () { - /** @type {WeakMap>} */ - const warnedSettings = new WeakMap(); - return { - /** - * Warn only once for each context and setting - * - * @param {object} context - * @param {string} setting - */ - hasBeenWarned(context, setting) { - return warnedSettings.has(context) && warnedSettings.get(context).has(setting); - }, - - markSettingAsWarned(context, setting) { - // istanbul ignore else - if (!warnedSettings.has(context)) { - warnedSettings.set(context, new Set()); - } - - warnedSettings.get(context).add(setting); - } - - }; -}; - -var _default = WarnSettings; -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=WarnSettings.js.map -}); - -var getDefaultTagStructureForMode_1 = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -const getDefaultTagStructureForMode = mode => { - const isJsdoc = mode === 'jsdoc'; - const isClosure = mode === 'closure'; - const isTypescript = mode === 'typescript'; - const isPermissive = mode === 'permissive'; - const isJsdocOrTypescript = isJsdoc || isTypescript; - const isTypescriptOrClosure = isTypescript || isClosure; - const isClosureOrPermissive = isClosure || isPermissive; - const isJsdocTypescriptOrPermissive = isJsdocOrTypescript || isPermissive; // Properties: - // `nameContents` - 'namepath-referencing'|'namepath-defining'|'text'|false - // `typeAllowed` - boolean - // `nameRequired` - boolean - // `typeRequired` - boolean - // `typeOrNameRequired` - boolean - // All of `typeAllowed` have a signature with "type" except for - // `augments`/`extends` ("namepath") - // `param`/`arg`/`argument` (no signature) - // `property`/`prop` (no signature) - // `modifies` (undocumented) - // None of the `nameContents: 'namepath-defining'` show as having curly - // brackets for their name/namepath - // Among `namepath-defining` and `namepath-referencing`, these do not seem - // to allow curly brackets in their doc signature or examples (`modifies` - // references namepaths within its type brackets and `param` is - // name-defining but not namepath-defining, so not part of these groups) - // Todo: Should support special processing for "name" as distinct from - // "namepath" (e.g., param can't define a namepath) - // Once checking inline tags: - // Todo: Re: `typeOrNameRequired`, `@link` (or @linkcode/@linkplain) seems - // to require a namepath OR URL and might be checked as such. - // Todo: Should support a `tutorialID` type (for `@tutorial` block and - // inline) - - return new Map([['alias', new Map([// Signature seems to require a "namepath" (and no counter-examples) - ['nameContents', 'namepath-referencing'], // "namepath" - ['typeOrNameRequired', true]])], ['arg', new Map([['nameContents', 'namepath-defining'], // See `param` - ['nameRequired', true], // Has no formal signature in the docs but shows curly brackets - // in the examples - ['typeAllowed', true]])], ['argument', new Map([['nameContents', 'namepath-defining'], // See `param` - ['nameRequired', true], // Has no formal signature in the docs but shows curly brackets - // in the examples - ['typeAllowed', true]])], ['augments', new Map([// Signature seems to require a "namepath" (and no counter-examples) - ['nameContents', 'namepath-referencing'], // Does not show curly brackets in either the signature or examples - ['typeAllowed', true], // "namepath" - ['typeOrNameRequired', true]])], ['borrows', new Map([// `borrows` has a different format, however, so needs special parsing; - // seems to require both, and as "namepath"'s - ['nameContents', 'namepath-referencing'], // "namepath" - ['typeOrNameRequired', true]])], ['callback', new Map([// Seems to require a "namepath" in the signature (with no - // counter-examples) - ['nameContents', 'namepath-defining'], // "namepath" - ['nameRequired', true]])], ['class', new Map([// Allows for "name"'s in signature, but indicated as optional - ['nameContents', 'namepath-defining'], ['typeAllowed', true]])], ['const', new Map([// Allows for "name"'s in signature, but indicated as optional - ['nameContents', 'namepath-defining'], ['typeAllowed', true]])], ['constant', new Map([// Allows for "name"'s in signature, but indicated as optional - ['nameContents', 'namepath-defining'], ['typeAllowed', true]])], ['constructor', new Map([// Allows for "name"'s in signature, but indicated as optional - ['nameContents', 'namepath-defining'], ['typeAllowed', true]])], ['define', new Map([['typeRequired', isClosure]])], ['emits', new Map([// Signature seems to require a "name" (of an event) and no counter-examples - ['nameContents', 'namepath-referencing']])], ['enum', new Map([// Has example showing curly brackets but not in doc signature - ['typeAllowed', true]])], ['event', new Map([// The doc signature of `event` seems to require a "name" - ['nameRequired', true], // Appears to require a "name" in its signature, albeit somewhat - // different from other "name"'s (including as described - // at https://jsdoc.app/about-namepaths.html ) - ['nameContents', 'namepath-defining']])], ['exception', new Map([// Shows curly brackets in the signature and in the examples - ['typeAllowed', true]])], ['export', new Map([['typeAllowed', isClosureOrPermissive]])], ['extends', new Map([// Signature seems to require a "namepath" (and no counter-examples) - ['nameContents', 'namepath-referencing'], // Does not show curly brackets in either the signature or examples - ['typeAllowed', isClosureOrPermissive], ['nameRequired', isJsdocOrTypescript], // "namepath" - ['typeOrNameRequired', isClosureOrPermissive]])], ['external', new Map([// Appears to require a "name" in its signature, albeit somewhat - // different from other "name"'s (including as described - // at https://jsdoc.app/about-namepaths.html ) - ['nameContents', 'namepath-defining'], // "name" (and a special syntax for the `external` name) - ['nameRequired', true]])], ['fires', new Map([// Signature seems to require a "name" (of an event) and no - // counter-examples - ['nameContents', 'namepath-referencing']])], ['function', new Map([// Allows for "name"'s in signature, but indicated as optional - ['nameContents', 'namepath-defining']])], ['func', new Map([// Allows for "name"'s in signature, but indicated as optional - ['nameContents', 'namepath-defining']])], ['host', new Map([// Appears to require a "name" in its signature, albeit somewhat - // different from other "name"'s (including as described - // at https://jsdoc.app/about-namepaths.html ) - ['nameContents', 'namepath-defining'], // See `external` - ['nameRequired', true], // "namepath" - ['typeOrNameRequired', true]])], ['interface', new Map([// Allows for "name" in signature, but indicates as optional - ['nameContents', isJsdocTypescriptOrPermissive ? 'namepath-defining' : false]])], ['implements', new Map([// Shows curly brackets in the doc signature and examples - // "typeExpression" - ['typeRequired', true]])], ['lends', new Map([// Signature seems to require a "namepath" (and no counter-examples) - ['nameContents', 'namepath-referencing'], // "namepath" - ['typeOrNameRequired', true]])], ['listens', new Map([// Signature seems to require a "name" (of an event) and no - // counter-examples - ['nameContents', 'namepath-referencing']])], ['member', new Map([// Allows for "name"'s in signature, but indicated as optional - ['nameContents', 'namepath-defining'], // Has example showing curly brackets but not in doc signature - ['typeAllowed', true]])], ['memberof', new Map([// Signature seems to require a "namepath" (and no counter-examples), - // though it allows an incomplete namepath ending with connecting symbol - ['nameContents', 'namepath-referencing'], // "namepath" - ['typeOrNameRequired', true]])], ['memberof!', new Map([// Signature seems to require a "namepath" (and no counter-examples), - // though it allows an incomplete namepath ending with connecting symbol - ['nameContents', 'namepath-referencing'], // "namepath" - ['typeOrNameRequired', true]])], ['method', new Map([// Allows for "name"'s in signature, but indicated as optional - ['nameContents', 'namepath-defining']])], ['mixes', new Map([// Signature seems to require a "OtherObjectPath" with no - // counter-examples - ['nameContents', 'namepath-referencing'], // "OtherObjectPath" - ['typeOrNameRequired', true]])], ['mixin', new Map([// Allows for "name"'s in signature, but indicated as optional - ['nameContents', 'namepath-defining']])], ['modifies', new Map([// Has no documentation, but test example has curly brackets, and - // "name" would be suggested rather than "namepath" based on example; - // not sure if name is required - ['typeAllowed', true]])], ['module', new Map([// Optional "name" and no curly brackets - // this block impacts `no-undefined-types` and `valid-types` (search for - // "isNamepathDefiningTag|tagMightHaveNamepath|tagMightHaveEitherTypeOrNamePosition") - ['nameContents', isJsdoc ? 'namepath-defining' : 'text'], // Shows the signature with curly brackets but not in the example - ['typeAllowed', true]])], ['name', new Map([// Seems to require a "namepath" in the signature (with no - // counter-examples) - ['nameContents', 'namepath-defining'], // "namepath" - ['nameRequired', true], // "namepath" - ['typeOrNameRequired', true]])], ['namespace', new Map([// Allows for "name"'s in signature, but indicated as optional - ['nameContents', 'namepath-defining'], // Shows the signature with curly brackets but not in the example - ['typeAllowed', true]])], ['package', new Map([// Shows the signature with curly brackets but not in the example - // "typeExpression" - ['typeAllowed', isClosureOrPermissive]])], ['param', new Map([['nameContents', 'namepath-defining'], // Though no signature provided requiring, per - // https://jsdoc.app/tags-param.html: - // "The @param tag requires you to specify the name of the parameter you - // are documenting." - ['nameRequired', true], // Has no formal signature in the docs but shows curly brackets - // in the examples - ['typeAllowed', true]])], ['private', new Map([// Shows the signature with curly brackets but not in the example - // "typeExpression" - ['typeAllowed', isClosureOrPermissive]])], ['prop', new Map([['nameContents', 'namepath-defining'], // See `property` - ['nameRequired', true], // Has no formal signature in the docs but shows curly brackets - // in the examples - ['typeAllowed', true]])], ['property', new Map([['nameContents', 'namepath-defining'], // No docs indicate required, but since parallel to `param`, we treat as - // such: - ['nameRequired', true], // Has no formal signature in the docs but shows curly brackets - // in the examples - ['typeAllowed', true]])], ['protected', new Map([// Shows the signature with curly brackets but not in the example - // "typeExpression" - ['typeAllowed', isClosureOrPermissive]])], ['public', new Map([// Does not show a signature nor show curly brackets in the example - ['typeAllowed', isClosureOrPermissive]])], ['returns', new Map([// Shows curly brackets in the signature and in the examples - ['typeAllowed', true]])], ['return', new Map([// Shows curly brackets in the signature and in the examples - ['typeAllowed', true]])], ['see', new Map([// Signature allows for "namepath" or text, so user must configure to - // 'namepath-referencing' to enforce checks - ['nameContents', 'text']])], ['static', new Map([// Does not show a signature nor show curly brackets in the example - ['typeAllowed', isClosureOrPermissive]])], ['template', new Map([['nameContents', isJsdoc ? 'text' : 'namepath-referencing'], // Though defines `nameContents: 'namepath-defining'` in a sense, it is - // not parseable in the same way for template (e.g., allowing commas), - // so not adding - ['typeAllowed', isTypescriptOrClosure || isPermissive]])], ['this', new Map([// Signature seems to require a "namepath" (and no counter-examples) - // Not used with namepath in Closure/TypeScript, however - ['nameContents', isJsdoc ? 'namepath-referencing' : false], ['typeRequired', isTypescriptOrClosure], // namepath - ['typeOrNameRequired', isJsdoc]])], ['throws', new Map([// Shows curly brackets in the signature and in the examples - ['typeAllowed', true]])], ['type', new Map([// Shows curly brackets in the doc signature and examples - // "typeName" - ['typeRequired', true]])], ['typedef', new Map([// Seems to require a "namepath" in the signature (with no - // counter-examples) - ['nameContents', 'namepath-defining'], // "namepath" - ['nameRequired', isJsdocTypescriptOrPermissive], // Has example showing curly brackets but not in doc signature - ['typeAllowed', true], // "namepath" - ['typeOrNameRequired', true]])], ['var', new Map([// Allows for "name"'s in signature, but indicated as optional - ['nameContents', 'namepath-defining'], // Has example showing curly brackets but not in doc signature - ['typeAllowed', true]])], ['yields', new Map([// Shows curly brackets in the signature and in the examples - ['typeAllowed', true]])], ['yield', new Map([// Shows curly brackets in the signature and in the examples - ['typeAllowed', true]])]]); -}; - -var _default = getDefaultTagStructureForMode; -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=getDefaultTagStructureForMode.js.map -}); - -var tagNames = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.typeScriptTags = exports.closureTags = exports.jsdocTags = void 0; -const jsdocTagsUndocumented = { - // Undocumented but present; see - // https://github.com/jsdoc/jsdoc/issues/1283#issuecomment-516816802 - // https://github.com/jsdoc/jsdoc/blob/master/packages/jsdoc/lib/jsdoc/tag/dictionary/definitions.js#L594 - modifies: [] -}; -const jsdocTags = { ...jsdocTagsUndocumented, - abstract: ['virtual'], - access: [], - alias: [], - async: [], - augments: ['extends'], - author: [], - borrows: [], - callback: [], - class: ['constructor'], - classdesc: [], - constant: ['const'], - constructs: [], - copyright: [], - default: ['defaultvalue'], - deprecated: [], - description: ['desc'], - enum: [], - event: [], - example: [], - exports: [], - external: ['host'], - file: ['fileoverview', 'overview'], - fires: ['emits'], - function: ['func', 'method'], - generator: [], - global: [], - hideconstructor: [], - ignore: [], - implements: [], - inheritdoc: [], - // Allowing casing distinct from jsdoc `definitions.js` (required in Closure) - inheritDoc: [], - inner: [], - instance: [], - interface: [], - kind: [], - lends: [], - license: [], - listens: [], - member: ['var'], - memberof: [], - 'memberof!': [], - mixes: [], - mixin: [], - module: [], - name: [], - namespace: [], - override: [], - package: [], - param: ['arg', 'argument'], - private: [], - property: ['prop'], - protected: [], - public: [], - readonly: [], - requires: [], - returns: ['return'], - see: [], - since: [], - static: [], - summary: [], - this: [], - throws: ['exception'], - todo: [], - tutorial: [], - type: [], - typedef: [], - variation: [], - version: [], - yields: ['yield'] -}; -exports.jsdocTags = jsdocTags; -const typeScriptTags = { ...jsdocTags, - // `@template` is also in TypeScript per: - // https://www.typescriptlang.org/docs/handbook/type-checking-javascript-files.html#supported-jsdoc - template: [] -}; -exports.typeScriptTags = typeScriptTags; -const undocumentedClosureTags = { - // These are in Closure source but not in jsdoc source nor in the Closure - // docs: https://github.com/google/closure-compiler/blob/master/src/com/google/javascript/jscomp/parsing/Annotation.java - closurePrimitive: [], - customElement: [], - expose: [], - hidden: [], - idGenerator: [], - meaning: [], - mixinClass: [], - mixinFunction: [], - ngInject: [], - owner: [], - typeSummary: [], - wizaction: [] -}; -const { - /* eslint-disable no-unused-vars */ - inheritdoc, - // Will be inverted to prefer `return` - returns, - - /* eslint-enable no-unused-vars */ - ...typeScriptTagsInClosure -} = typeScriptTags; -const closureTags = { ...typeScriptTagsInClosure, - ...undocumentedClosureTags, - // From https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler - // These are all recognized in https://github.com/jsdoc/jsdoc/blob/master/packages/jsdoc/lib/jsdoc/tag/dictionary/definitions.js - // except for the experimental `noinline` and the casing differences noted below - // Defined as a synonym of `const` in jsdoc `definitions.js` - define: [], - dict: [], - export: [], - externs: [], - final: [], - // With casing distinct from jsdoc `definitions.js` - implicitCast: [], - noalias: [], - nocollapse: [], - nocompile: [], - noinline: [], - nosideeffects: [], - polymer: [], - polymerBehavior: [], - preserve: [], - // Defined as a synonym of `interface` in jsdoc `definitions.js` - record: [], - return: ['returns'], - struct: [], - suppress: [], - unrestricted: [] -}; -exports.closureTags = closureTags; -//# sourceMappingURL=tagNames.js.map -}); - -var jsdocUtils = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _lodash = _interopRequireDefault(lodash__default['default']); - -var _WarnSettings = _interopRequireDefault(WarnSettings_1); - -var _getDefaultTagStructureForMode = _interopRequireDefault(getDefaultTagStructureForMode_1); - - - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -let tagStructure; - -const setTagStructure = mode => { - tagStructure = (0, _getDefaultTagStructureForMode.default)(mode); -}; // Given a nested array of property names, reduce them to a single array, -// appending the name of the root element along the way if present. - - -const flattenRoots = (params, root = '') => { - let hasRestElement = false; - let hasPropertyRest = false; - const rests = []; - const names = params.reduce((acc, cur) => { - if (Array.isArray(cur)) { - let nms; - - if (Array.isArray(cur[1])) { - nms = cur[1]; - } else { - if (cur[1].hasRestElement) { - hasRestElement = true; - } - - if (cur[1].hasPropertyRest) { - hasPropertyRest = true; - } - - nms = cur[1].names; - } - - const flattened = flattenRoots(nms, root ? `${root}.${cur[0]}` : cur[0]); - - if (flattened.hasRestElement) { - hasRestElement = true; - } - - if (flattened.hasPropertyRest) { - hasPropertyRest = true; - } - - const inner = [root ? `${root}.${cur[0]}` : cur[0], ...flattened.names].filter(Boolean); - rests.push(false, ...flattened.rests); - return acc.concat(inner); - } - - if (typeof cur === 'object') { - if (cur.isRestProperty) { - hasPropertyRest = true; - rests.push(true); - } else { - rests.push(false); - } - - if (cur.restElement) { - hasRestElement = true; - } - - acc.push(root ? `${root}.${cur.name}` : cur.name); - } else if (typeof cur !== 'undefined') { - rests.push(false); - acc.push(root ? `${root}.${cur}` : cur); - } - - return acc; - }, []); - return { - hasPropertyRest, - hasRestElement, - names, - rests - }; -}; - -const getPropertiesFromPropertySignature = propSignature => { - if (propSignature.type === 'TSIndexSignature' || propSignature.type === 'TSConstructSignatureDeclaration' || propSignature.type === 'TSCallSignatureDeclaration') { - return undefined; - } - - if (propSignature.typeAnnotation && propSignature.typeAnnotation.typeAnnotation.type === 'TSTypeLiteral') { - return [propSignature.key.name, propSignature.typeAnnotation.typeAnnotation.members.map(member => { - return getPropertiesFromPropertySignature(member); - })]; - } - - return propSignature.key.name; -}; - -const getFunctionParameterNames = (functionNode, checkDefaultObjects) => { - // eslint-disable-next-line complexity - const getParamName = (param, isProperty) => { - var _param$left, _param$left3; - - if (_lodash.default.has(param, 'typeAnnotation') || _lodash.default.has(param, 'left.typeAnnotation')) { - const typeAnnotation = _lodash.default.has(param, 'left.typeAnnotation') ? param.left.typeAnnotation : param.typeAnnotation; - - if (typeAnnotation.typeAnnotation.type === 'TSTypeLiteral') { - const propertyNames = typeAnnotation.typeAnnotation.members.map(member => { - return getPropertiesFromPropertySignature(member); - }); - const flattened = { ...flattenRoots(propertyNames), - annotationParamName: param.name - }; - - if (_lodash.default.has(param, 'name') || _lodash.default.has(param, 'left.name')) { - return [_lodash.default.has(param, 'left.name') ? param.left.name : param.name, flattened]; - } - - return [undefined, flattened]; - } - } - - if (_lodash.default.has(param, 'name')) { - return param.name; - } - - if (_lodash.default.has(param, 'left.name')) { - return param.left.name; - } - - if (param.type === 'ObjectPattern' || ((_param$left = param.left) === null || _param$left === void 0 ? void 0 : _param$left.type) === 'ObjectPattern') { - var _param$left2; - - const properties = param.properties || ((_param$left2 = param.left) === null || _param$left2 === void 0 ? void 0 : _param$left2.properties); - const roots = properties.map(prop => { - return getParamName(prop, true); - }); - return [undefined, flattenRoots(roots)]; - } - - if (param.type === 'Property') { - switch (param.value.type) { - case 'ArrayPattern': - return [param.key.name, param.value.elements.map((prop, idx) => { - return { - name: idx, - restElement: prop.type === 'RestElement' - }; - })]; - - case 'ObjectPattern': - return [param.key.name, param.value.properties.map(prop => { - return getParamName(prop, isProperty); - })]; - - case 'AssignmentPattern': - { - switch (param.value.left.type) { - case 'Identifier': - // Default parameter - if (checkDefaultObjects && param.value.right.type === 'ObjectExpression') { - return [param.key.name, param.value.right.properties.map(prop => { - return getParamName(prop, isProperty); - })]; - } - - break; - - case 'ObjectPattern': - return [param.key.name, param.value.left.properties.map(prop => { - return getParamName(prop, isProperty); - })]; - - case 'ArrayPattern': - return [param.key.name, param.value.left.elements.map((prop, idx) => { - return { - name: idx, - restElement: prop.type === 'RestElement' - }; - })]; - } - } - } - - switch (param.key.type) { - case 'Identifier': - return param.key.name; - // The key of an object could also be a string or number - - case 'Literal': - return param.key.raw || // istanbul ignore next -- `raw` may not be present in all parsers - param.key.value; - // case 'MemberExpression': - - default: - // Todo: We should really create a structure (and a corresponding - // option analogous to `checkRestProperty`) which allows for - // (and optionally requires) dynamic properties to have a single - // line of documentation - return undefined; - } - } - - if (param.type === 'ArrayPattern' || ((_param$left3 = param.left) === null || _param$left3 === void 0 ? void 0 : _param$left3.type) === 'ArrayPattern') { - var _param$left4; - - const elements = param.elements || ((_param$left4 = param.left) === null || _param$left4 === void 0 ? void 0 : _param$left4.elements); - const roots = elements.map((prop, idx) => { - return { - name: idx, - restElement: prop.type === 'RestElement' - }; - }); - return [undefined, flattenRoots(roots)]; - } - - if (['RestElement', 'ExperimentalRestProperty'].includes(param.type)) { - return { - isRestProperty: isProperty, - name: param.argument.name, - restElement: true - }; - } - - if (param.type === 'TSParameterProperty') { - return getParamName(param.parameter, true); - } - - throw new Error(`Unsupported function signature format: \`${param.type}\`.`); - }; - - return (functionNode.params || functionNode.value.params).map(param => { - return getParamName(param); - }); -}; - -const hasParams = functionNode => { - // Should also check `functionNode.value.params` if supporting `MethodDefinition` - return functionNode.params.length; -}; -/** - * Gets all names of the target type, including those that refer to a path, e.g. - * "@param foo; @param foo.bar". - */ - - -const getJsdocTagsDeep = (jsdoc, targetTagName) => { - const ret = []; - jsdoc.tags.forEach(({ - name, - tag, - type - }, idx) => { - if (tag !== targetTagName) { - return; - } - - ret.push({ - idx, - name, - type - }); - }); - return ret; -}; - -const modeWarnSettings = (0, _WarnSettings.default)(); - -const getTagNamesForMode = (mode, context) => { - switch (mode) { - case 'jsdoc': - return tagNames.jsdocTags; - - case 'typescript': - return tagNames.typeScriptTags; - - case 'closure': - case 'permissive': - return tagNames.closureTags; - - default: - if (!modeWarnSettings.hasBeenWarned(context, 'mode')) { - context.report({ - loc: { - start: { - column: 1, - line: 1 - } - }, - message: `Unrecognized value \`${mode}\` for \`settings.jsdoc.mode\`.` - }); - modeWarnSettings.markSettingAsWarned(context, 'mode'); - } // We'll avoid breaking too many other rules - - - return tagNames.jsdocTags; - } -}; - -const getPreferredTagName = (context, mode, name, tagPreference = {}) => { - var _Object$entries$find; - - const prefValues = Object.values(tagPreference); - - if (prefValues.includes(name) || prefValues.some(prefVal => { - return prefVal && typeof prefVal === 'object' && prefVal.replacement === name; - })) { - return name; - } // Allow keys to have a 'tag ' prefix to avoid upstream bug in ESLint - // that disallows keys that conflict with Object.prototype, - // e.g. 'tag constructor' for 'constructor': - // https://github.com/eslint/eslint/issues/13289 - // https://github.com/gajus/eslint-plugin-jsdoc/issues/537 - - - const tagPreferenceFixed = _lodash.default.mapKeys(tagPreference, (_value, key) => { - return key.replace('tag ', ''); - }); - - if (_lodash.default.has(tagPreferenceFixed, name)) { - return tagPreferenceFixed[name]; - } - - const tagNames = getTagNamesForMode(mode, context); - const preferredTagName = (_Object$entries$find = Object.entries(tagNames).find(([, aliases]) => { - return aliases.includes(name); - })) === null || _Object$entries$find === void 0 ? void 0 : _Object$entries$find[0]; - - if (preferredTagName) { - return preferredTagName; - } - - return name; -}; - -const isValidTag = (context, mode, name, definedTags) => { - const tagNames = getTagNamesForMode(mode, context); - const validTagNames = Object.keys(tagNames).concat(_lodash.default.flatten(Object.values(tagNames))); - const additionalTags = definedTags; - const allTags = validTagNames.concat(additionalTags); - return allTags.includes(name); -}; - -const hasTag = (jsdoc, targetTagName) => { - const targetTagLower = targetTagName.toLowerCase(); - return _lodash.default.some(jsdoc.tags, doc => { - return doc.tag.toLowerCase() === targetTagLower; - }); -}; - -const hasATag = (jsdoc, targetTagNames) => { - return targetTagNames.some(targetTagName => { - return hasTag(jsdoc, targetTagName); - }); -}; -/** - * Checks if the JSDoc comment declares a defined type. - * - * @param {JsDocTag} tag - * the tag which should be checked. - * @returns {boolean} - * true in case a defined type is declared; otherwise false. - */ - - -const hasDefinedTypeTag = tag => { - // The function should not continue in the event the type is not defined... - if (typeof tag === 'undefined' || tag === null) { - return false; - } // .. same applies if it declares an `{undefined}` or `{void}` type - - - const tagType = tag.type.trim(); - - if (tagType === 'undefined' || tagType === 'void') { - return false; - } // In any other case, a type is present - - - return true; -}; - -const ensureMap = (map, tag) => { - if (!map.has(tag)) { - map.set(tag, new Map()); - } - - return map.get(tag); -}; - -const overrideTagStructure = (structuredTags, tagMap = tagStructure) => { - Object.entries(structuredTags).forEach(([tag, { - name, - type, - required = [] - }]) => { - const tagStruct = ensureMap(tagMap, tag); - tagStruct.set('nameContents', name); - tagStruct.set('typeAllowed', type); - const requiredName = required.includes('name'); - - if (requiredName && name === false) { - throw new Error('Cannot add "name" to `require` with the tag\'s `name` set to `false`'); - } - - tagStruct.set('nameRequired', requiredName); - const requiredType = required.includes('type'); - - if (requiredType && type === false) { - throw new Error('Cannot add "type" to `require` with the tag\'s `type` set to `false`'); - } - - tagStruct.set('typeRequired', requiredType); - const typeOrNameRequired = required.includes('typeOrNameRequired'); - - if (typeOrNameRequired && name === false) { - throw new Error('Cannot add "typeOrNameRequired" to `require` with the tag\'s `name` set to `false`'); - } - - if (typeOrNameRequired && type === false) { - throw new Error('Cannot add "typeOrNameRequired" to `require` with the tag\'s `type` set to `false`'); - } - - tagStruct.set('typeOrNameRequired', typeOrNameRequired); - }); -}; - -const getTagStructureForMode = (mode, structuredTags) => { - const tagStruct = (0, _getDefaultTagStructureForMode.default)(mode); - - try { - overrideTagStructure(structuredTags, tagStruct); - } catch {// - } - - return tagStruct; -}; - -const isNamepathDefiningTag = (tag, tagMap = tagStructure) => { - const tagStruct = ensureMap(tagMap, tag); - return tagStruct.get('nameContents') === 'namepath-defining'; -}; - -const tagMustHaveTypePosition = (tag, tagMap = tagStructure) => { - const tagStruct = ensureMap(tagMap, tag); - return tagStruct.get('typeRequired'); -}; - -const tagMightHaveTypePosition = (tag, tagMap = tagStructure) => { - if (tagMustHaveTypePosition(tag, tagMap)) { - return true; - } - - const tagStruct = ensureMap(tagMap, tag); - const ret = tagStruct.get('typeAllowed'); - return ret === undefined ? true : ret; -}; - -const namepathTypes = new Set(['namepath-defining', 'namepath-referencing']); - -const tagMightHaveNamePosition = (tag, tagMap = tagStructure) => { - const tagStruct = ensureMap(tagMap, tag); - const ret = tagStruct.get('nameContents'); - return ret === undefined ? true : Boolean(ret); -}; - -const tagMightHaveNamepath = (tag, tagMap = tagStructure) => { - const tagStruct = ensureMap(tagMap, tag); - return namepathTypes.has(tagStruct.get('nameContents')); -}; - -const tagMustHaveNamePosition = (tag, tagMap = tagStructure) => { - const tagStruct = ensureMap(tagMap, tag); - return tagStruct.get('nameRequired'); -}; - -const tagMightHaveEitherTypeOrNamePosition = (tag, tagMap) => { - return tagMightHaveTypePosition(tag, tagMap) || tagMightHaveNamepath(tag, tagMap); -}; - -const tagMustHaveEitherTypeOrNamePosition = (tag, tagMap) => { - const tagStruct = ensureMap(tagMap, tag); - return tagStruct.get('typeOrNameRequired'); -}; - -const tagMissingRequiredTypeOrNamepath = (tag, tagMap = tagStructure) => { - const mustHaveTypePosition = tagMustHaveTypePosition(tag.tag, tagMap); - const mightHaveTypePosition = tagMightHaveTypePosition(tag.tag, tagMap); - const hasTypePosition = mightHaveTypePosition && Boolean(tag.type); - const hasNameOrNamepathPosition = (tagMustHaveNamePosition(tag.tag, tagMap) || tagMightHaveNamepath(tag.tag, tagMap)) && Boolean(tag.name); - const mustHaveEither = tagMustHaveEitherTypeOrNamePosition(tag.tag, tagMap); - const hasEither = tagMightHaveEitherTypeOrNamePosition(tag.tag, tagMap) && (hasTypePosition || hasNameOrNamepathPosition); - return mustHaveEither && !hasEither && !mustHaveTypePosition; -}; -/** - * Checks if a node is a promise but has no resolve value or an empty value. - * An `undefined` resolve does not count. - * - * @param {object} node - * @returns {boolean} - */ - - -const isNewPromiseExpression = node => { - return node.type === 'NewExpression' && node.callee.type === 'Identifier' && node.callee.name === 'Promise'; -}; -/** - * Checks if a node has a return statement. Void return does not count. - * - * @param {object} node - * @returns {boolean|Node} - */ -// eslint-disable-next-line complexity - - -const hasReturnValue = (node, promFilter) => { - if (!node) { - return false; - } - - switch (node.type) { - case 'FunctionExpression': - case 'FunctionDeclaration': - case 'ArrowFunctionExpression': - { - return node.expression || hasReturnValue(node.body, promFilter); - } - - case 'BlockStatement': - { - return node.body.some(bodyNode => { - return bodyNode.type !== 'FunctionDeclaration' && hasReturnValue(bodyNode, promFilter); - }); - } - - case 'LabeledStatement': - case 'WhileStatement': - case 'DoWhileStatement': - case 'ForStatement': - case 'ForInStatement': - case 'ForOfStatement': - case 'WithStatement': - { - return hasReturnValue(node.body, promFilter); - } - - case 'IfStatement': - { - return hasReturnValue(node.consequent, promFilter) || hasReturnValue(node.alternate, promFilter); - } - - case 'TryStatement': - { - return hasReturnValue(node.block, promFilter) || hasReturnValue(node.handler && node.handler.body, promFilter) || hasReturnValue(node.finalizer, promFilter); - } - - case 'SwitchStatement': - { - return node.cases.some(someCase => { - return someCase.consequent.some(nde => { - return hasReturnValue(nde, promFilter); - }); - }); - } - - case 'ReturnStatement': - { - // void return does not count. - if (node.argument === null) { - return false; - } - - if (promFilter && isNewPromiseExpression(node.argument)) { - // Let caller decide how to filter, but this is, at the least, - // a return of sorts and truthy - return promFilter(node.argument); - } - - return true; - } - - default: - { - return false; - } - } -}; -/** - * Avoids further checking child nodes if a nested function shadows the - * resolver, but otherwise, if name is used (by call or passed in as an - * argument to another function), will be considered as non-empty. - * - * This could check for redeclaration of the resolver, but as such is - * unlikely, we avoid the performance cost of checking everywhere for - * (re)declarations or assignments. - * - * @param {AST} node - * @param {string} resolverName - * @returns {boolean} - */ -// eslint-disable-next-line complexity - - -const hasNonEmptyResolverCall = (node, resolverName) => { - if (!node) { - return false; - } // Arrow function without block - - - switch (node.type) { - // istanbul ignore next -- In Babel? - case 'OptionalCallExpression': - case 'CallExpression': - return node.callee.name === resolverName && ( // Implicit or expliit undefined - node.arguments.length > 1 || node.arguments[0] !== undefined) || node.arguments.some(nde => { - // Being passed in to another function (which might invoke it) - return nde.type === 'Identifier' && nde.name === resolverName || // Handle nested items - hasNonEmptyResolverCall(nde, resolverName); - }); - - case 'ChainExpression': - case 'Decorator': - case 'ExpressionStatement': - return hasNonEmptyResolverCall(node.expression, resolverName); - - case 'ClassBody': - case 'BlockStatement': - return node.body.some(bodyNode => { - return hasNonEmptyResolverCall(bodyNode, resolverName); - }); - - case 'FunctionExpression': - case 'FunctionDeclaration': - case 'ArrowFunctionExpression': - { - var _node$params$; - - // Shadowing - if (((_node$params$ = node.params[0]) === null || _node$params$ === void 0 ? void 0 : _node$params$.name) === resolverName) { - return false; - } - - return hasNonEmptyResolverCall(node.body, resolverName); - } - - case 'LabeledStatement': - case 'WhileStatement': - case 'DoWhileStatement': - case 'ForStatement': - case 'ForInStatement': - case 'ForOfStatement': - case 'WithStatement': - { - return hasNonEmptyResolverCall(node.body, resolverName); - } - - case 'ConditionalExpression': - case 'IfStatement': - { - return hasNonEmptyResolverCall(node.test, resolverName) || hasNonEmptyResolverCall(node.consequent, resolverName) || hasNonEmptyResolverCall(node.alternate, resolverName); - } - - case 'TryStatement': - { - return hasNonEmptyResolverCall(node.block, resolverName) || hasNonEmptyResolverCall(node.handler && node.handler.body, resolverName) || hasNonEmptyResolverCall(node.finalizer, resolverName); - } - - case 'SwitchStatement': - { - return node.cases.some(someCase => { - return someCase.consequent.some(nde => { - return hasNonEmptyResolverCall(nde, resolverName); - }); - }); - } - - case 'ArrayPattern': - case 'ArrayExpression': - return node.elements.some(element => { - return hasNonEmptyResolverCall(element, resolverName); - }); - - case 'AssignmentPattern': - return hasNonEmptyResolverCall(node.right, resolverName); - - case 'AssignmentExpression': - case 'BinaryExpression': - case 'LogicalExpression': - { - return hasNonEmptyResolverCall(node.left, resolverName) || hasNonEmptyResolverCall(node.right, resolverName); - } - // Comma - - case 'SequenceExpression': - case 'TemplateLiteral': - return node.expressions.some(subExpression => { - return hasNonEmptyResolverCall(subExpression, resolverName); - }); - - case 'ObjectPattern': - case 'ObjectExpression': - return node.properties.some(property => { - return hasNonEmptyResolverCall(property, resolverName); - }); - // istanbul ignore next -- In Babel? - - case 'ClassMethod': - case 'MethodDefinition': - return node.decorators && node.decorators.some(decorator => { - return hasNonEmptyResolverCall(decorator, resolverName); - }) || node.computed && hasNonEmptyResolverCall(node.key, resolverName) || hasNonEmptyResolverCall(node.value, resolverName); - // istanbul ignore next -- In Babel? - - case 'ObjectProperty': - /* eslint-disable no-fallthrough */ - // istanbul ignore next -- In Babel? - - case 'ClassProperty': - /* eslint-enable no-fallthrough */ - - case 'Property': - return node.computed && hasNonEmptyResolverCall(node.key, resolverName) || hasNonEmptyResolverCall(node.value, resolverName); - // istanbul ignore next -- In Babel? - - case 'ObjectMethod': - // istanbul ignore next -- In Babel? - return node.computed && hasNonEmptyResolverCall(node.key, resolverName) || node.arguments.some(nde => { - return hasNonEmptyResolverCall(nde, resolverName); - }); - - case 'ClassExpression': - case 'ClassDeclaration': - return hasNonEmptyResolverCall(node.body, resolverName); - - case 'AwaitExpression': - case 'SpreadElement': - case 'UnaryExpression': - case 'YieldExpression': - return hasNonEmptyResolverCall(node.argument, resolverName); - - case 'VariableDeclaration': - { - return node.declarations.some(nde => { - return hasNonEmptyResolverCall(nde, resolverName); - }); - } - - case 'VariableDeclarator': - { - return hasNonEmptyResolverCall(node.id, resolverName) || hasNonEmptyResolverCall(node.init, resolverName); - } - - case 'TaggedTemplateExpression': - return hasNonEmptyResolverCall(node.quasi, resolverName); - // ?. - // istanbul ignore next -- In Babel? - - case 'OptionalMemberExpression': - case 'MemberExpression': - return hasNonEmptyResolverCall(node.object, resolverName) || hasNonEmptyResolverCall(node.property, resolverName); - // istanbul ignore next -- In Babel? - - case 'Import': - case 'ImportExpression': - return hasNonEmptyResolverCall(node.source, resolverName); - - case 'ReturnStatement': - { - if (node.argument === null) { - return false; - } - - return hasNonEmptyResolverCall(node.argument, resolverName); - } - - /* - // Shouldn't need to parse literals/literal components, etc. - case 'Identifier': - case 'TemplateElement': - case 'Super': - // Exports not relevant in this context - */ - - default: - return false; - } -}; -/** - * Checks if a Promise executor has no resolve value or an empty value. - * An `undefined` resolve does not count. - * - * @param {object} node - * @param {boolean} anyPromiseAsReturn - * @returns {boolean} - */ - - -const hasValueOrExecutorHasNonEmptyResolveValue = (node, anyPromiseAsReturn) => { - return hasReturnValue(node, prom => { - if (anyPromiseAsReturn) { - return true; - } - - const [{ - params, - body - } = {}] = prom.arguments; - - if (!(params !== null && params !== void 0 && params.length)) { - return false; - } - - const [{ - name: resolverName - }] = params; - return hasNonEmptyResolverCall(body, resolverName); - }); -}; // eslint-disable-next-line complexity - - -const hasNonFunctionYield = (node, checkYieldReturnValue) => { - if (!node) { - return false; - } - - switch (node.type) { - case 'BlockStatement': - { - return node.body.some(bodyNode => { - return !['ArrowFunctionExpression', 'FunctionDeclaration', 'FunctionExpression'].includes(bodyNode.type) && hasNonFunctionYield(bodyNode, checkYieldReturnValue); - }); - } - // istanbul ignore next -- In Babel? - - case 'OptionalCallExpression': - case 'CallExpression': - return node.arguments.some(element => { - return hasNonFunctionYield(element, checkYieldReturnValue); - }); - - case 'ChainExpression': - case 'ExpressionStatement': - { - return hasNonFunctionYield(node.expression, checkYieldReturnValue); - } - - case 'LabeledStatement': - case 'WhileStatement': - case 'DoWhileStatement': - case 'ForStatement': - case 'ForInStatement': - case 'ForOfStatement': - case 'WithStatement': - { - return hasNonFunctionYield(node.body, checkYieldReturnValue); - } - - case 'ConditionalExpression': - case 'IfStatement': - { - return hasNonFunctionYield(node.test, checkYieldReturnValue) || hasNonFunctionYield(node.consequent, checkYieldReturnValue) || hasNonFunctionYield(node.alternate, checkYieldReturnValue); - } - - case 'TryStatement': - { - return hasNonFunctionYield(node.block, checkYieldReturnValue) || hasNonFunctionYield(node.handler && node.handler.body, checkYieldReturnValue) || hasNonFunctionYield(node.finalizer, checkYieldReturnValue); - } - - case 'SwitchStatement': - { - return node.cases.some(someCase => { - return someCase.consequent.some(nde => { - return hasNonFunctionYield(nde, checkYieldReturnValue); - }); - }); - } - - case 'ArrayPattern': - case 'ArrayExpression': - return node.elements.some(element => { - return hasNonFunctionYield(element, checkYieldReturnValue); - }); - - case 'AssignmentPattern': - return hasNonFunctionYield(node.right, checkYieldReturnValue); - - case 'VariableDeclaration': - { - return node.declarations.some(nde => { - return hasNonFunctionYield(nde, checkYieldReturnValue); - }); - } - - case 'VariableDeclarator': - { - return hasNonFunctionYield(node.id, checkYieldReturnValue) || hasNonFunctionYield(node.init, checkYieldReturnValue); - } - - case 'AssignmentExpression': - case 'BinaryExpression': - case 'LogicalExpression': - { - return hasNonFunctionYield(node.left, checkYieldReturnValue) || hasNonFunctionYield(node.right, checkYieldReturnValue); - } - // Comma - - case 'SequenceExpression': - case 'TemplateLiteral': - return node.expressions.some(subExpression => { - return hasNonFunctionYield(subExpression, checkYieldReturnValue); - }); - - case 'ObjectPattern': - case 'ObjectExpression': - return node.properties.some(property => { - return hasNonFunctionYield(property, checkYieldReturnValue); - }); - // istanbul ignore next -- In Babel? - - case 'ObjectProperty': - /* eslint-disable no-fallthrough */ - // istanbul ignore next -- In Babel? - - case 'ClassProperty': - /* eslint-enable no-fallthrough */ - - case 'Property': - return node.computed && hasNonFunctionYield(node.key, checkYieldReturnValue) || hasNonFunctionYield(node.value, checkYieldReturnValue); - // istanbul ignore next -- In Babel? - - case 'ObjectMethod': - // istanbul ignore next -- In Babel? - return node.computed && hasNonFunctionYield(node.key, checkYieldReturnValue) || node.arguments.some(nde => { - return hasNonFunctionYield(nde, checkYieldReturnValue); - }); - - case 'SpreadElement': - case 'UnaryExpression': - return hasNonFunctionYield(node.argument, checkYieldReturnValue); - - case 'TaggedTemplateExpression': - return hasNonFunctionYield(node.quasi, checkYieldReturnValue); - // ?. - // istanbul ignore next -- In Babel? - - case 'OptionalMemberExpression': - case 'MemberExpression': - return hasNonFunctionYield(node.object, checkYieldReturnValue) || hasNonFunctionYield(node.property, checkYieldReturnValue); - // istanbul ignore next -- In Babel? - - case 'Import': - case 'ImportExpression': - return hasNonFunctionYield(node.source, checkYieldReturnValue); - - case 'ReturnStatement': - { - if (node.argument === null) { - return false; - } - - return hasNonFunctionYield(node.argument, checkYieldReturnValue); - } - - case 'YieldExpression': - { - if (checkYieldReturnValue) { - if (node.parent.type === 'VariableDeclarator') { - return true; - } - - return false; - } // void return does not count. - - - if (node.argument === null) { - return false; - } - - return true; - } - - default: - { - return false; - } - } -}; -/** - * Checks if a node has a return statement. Void return does not count. - * - * @param {object} node - * @returns {boolean} - */ - - -const hasYieldValue = (node, checkYieldReturnValue) => { - return node.generator && (node.expression || hasNonFunctionYield(node.body, checkYieldReturnValue)); -}; -/** - * Checks if a node has a throws statement. - * - * @param {object} node - * @param {boolean} innerFunction - * @returns {boolean} - */ -// eslint-disable-next-line complexity - - -const hasThrowValue = (node, innerFunction) => { - if (!node) { - return false; - } // There are cases where a function may execute its inner function which - // throws, but we're treating functions atomically rather than trying to - // follow them - - - switch (node.type) { - case 'FunctionExpression': - case 'FunctionDeclaration': - case 'ArrowFunctionExpression': - { - return !innerFunction && hasThrowValue(node.body, true); - } - - case 'BlockStatement': - { - return node.body.some(bodyNode => { - return bodyNode.type !== 'FunctionDeclaration' && hasThrowValue(bodyNode); - }); - } - - case 'LabeledStatement': - case 'WhileStatement': - case 'DoWhileStatement': - case 'ForStatement': - case 'ForInStatement': - case 'ForOfStatement': - case 'WithStatement': - { - return hasThrowValue(node.body); - } - - case 'IfStatement': - { - return hasThrowValue(node.consequent) || hasThrowValue(node.alternate); - } - // We only consider it to throw an error if the catch or finally blocks throw an error. - - case 'TryStatement': - { - return hasThrowValue(node.handler && node.handler.body) || hasThrowValue(node.finalizer); - } - - case 'SwitchStatement': - { - return node.cases.some(someCase => { - return someCase.consequent.some(nde => { - return hasThrowValue(nde); - }); - }); - } - - case 'ThrowStatement': - { - return true; - } - - default: - { - return false; - } - } -}; -/** @param {string} tag */ - -/* -const isInlineTag = (tag) => { - return /^(@link|@linkcode|@linkplain|@tutorial) /u.test(tag); -}; -*/ - -/** - * Parses GCC Generic/Template types - * - * @see {https://github.com/google/closure-compiler/wiki/Generic-Types} - * @see {https://www.typescriptlang.org/docs/handbook/jsdoc-supported-types.html#template} - * @param {JsDocTag} tag - * @returns {Array} - */ - - -const parseClosureTemplateTag = tag => { - return tag.name.split(',').map(type => { - return type.trim(); - }); -}; -/** - * Checks user option for `contexts` array, defaulting to - * contexts designated by the rule. Returns an array of - * ESTree AST types, indicating allowable contexts. - * - * @param {*} context - * @param {true|string[]} defaultContexts - * @returns {string[]} - */ - - -const enforcedContexts = (context, defaultContexts) => { - const { - contexts = defaultContexts === true ? ['ArrowFunctionExpression', 'FunctionDeclaration', 'FunctionExpression'] : defaultContexts - } = context.options[0] || {}; - return contexts; -}; -/** - * @param {string[]} contexts - * @param {Function} checkJsdoc - */ - - -const getContextObject = (contexts, checkJsdoc) => { - const properties = {}; - contexts.forEach(prop => { - if (typeof prop === 'object') { - properties[prop.context] = checkJsdoc; - } else { - properties[prop] = checkJsdoc; - } - }); - return properties; -}; - -const filterTags = (tags, filter) => { - return tags.filter(filter); -}; - -const tagsWithNamesAndDescriptions = new Set(['param', 'arg', 'argument', 'property', 'prop', 'template', // These two are parsed by our custom parser as though having a `name` -'returns', 'return']); - -const getTagsByType = (context, mode, tags, tagPreference) => { - const descName = getPreferredTagName(context, mode, 'description', tagPreference); - const tagsWithoutNames = []; - const tagsWithNames = filterTags(tags, tag => { - const { - tag: tagName - } = tag; - const tagWithName = tagsWithNamesAndDescriptions.has(tagName); - - if (!tagWithName && tagName !== descName) { - tagsWithoutNames.push(tag); - } - - return tagWithName; - }); - return { - tagsWithNames, - tagsWithoutNames - }; -}; - -const getIndent = sourceCode => { - var _sourceCode$text$matc, _sourceCode$text$matc2; - - return ((_sourceCode$text$matc = (_sourceCode$text$matc2 = sourceCode.text.match(/^\n*([ \t]+)/u)) === null || _sourceCode$text$matc2 === void 0 ? void 0 : _sourceCode$text$matc2[1]) !== null && _sourceCode$text$matc !== void 0 ? _sourceCode$text$matc : '') + ' '; -}; - -const isConstructor = node => { - var _node$parent; - - return (node === null || node === void 0 ? void 0 : node.type) === 'MethodDefinition' && node.kind === 'constructor' || (node === null || node === void 0 ? void 0 : (_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : _node$parent.kind) === 'constructor'; -}; - -const isGetter = node => { - return node && node.parent.kind === 'get'; -}; - -const isSetter = node => { - return node && node.parent.kind === 'set'; -}; - -const hasAccessorPair = node => { - const { - type, - kind: sourceKind, - key: { - name: sourceName - } - } = node; - const oppositeKind = sourceKind === 'get' ? 'set' : 'get'; - const children = type === 'MethodDefinition' ? 'body' : 'properties'; - return node.parent[children].some(({ - kind, - key: { - name - } - }) => { - return kind === oppositeKind && name === sourceName; - }); -}; - -const exemptSpeciaMethods = (jsdoc, node, context, schema) => { - const hasSchemaOption = prop => { - var _context$options$0$pr, _context$options$; - - const schemaProperties = schema[0].properties; - return (_context$options$0$pr = (_context$options$ = context.options[0]) === null || _context$options$ === void 0 ? void 0 : _context$options$[prop]) !== null && _context$options$0$pr !== void 0 ? _context$options$0$pr : schemaProperties[prop] && schemaProperties[prop].default; - }; - - const checkGetters = hasSchemaOption('checkGetters'); - const checkSetters = hasSchemaOption('checkSetters'); - return !hasSchemaOption('checkConstructors') && (isConstructor(node) || hasATag(jsdoc, ['class', 'constructor'])) || isGetter(node) && (!checkGetters || checkGetters === 'no-setter' && hasAccessorPair(node.parent)) || isSetter(node) && (!checkSetters || checkSetters === 'no-getter' && hasAccessorPair(node.parent)); -}; -/** - * Since path segments may be unquoted (if matching a reserved word, - * identifier or numeric literal) or single or double quoted, in either - * the `@param` or in source, we need to strip the quotes to give a fair - * comparison. - * - * @param {string} str - * @returns {string} - */ - - -const dropPathSegmentQuotes = str => { - return str.replace(/\.(['"])(.*)\1/gu, '.$2'); -}; - -const comparePaths = name => { - return otherPathName => { - return otherPathName === name || dropPathSegmentQuotes(otherPathName) === dropPathSegmentQuotes(name); - }; -}; - -const getRegexFromString = (regexString, requiredFlags) => { - const match = regexString.match(/^\/(.*)\/([gimyus]*)$/us); - let flags = 'u'; - let regex = regexString; - - if (match) { - [, regex, flags] = match; - - if (!flags) { - flags = 'u'; - } - } - - const uniqueFlags = [...new Set(flags + (requiredFlags || ''))]; - flags = uniqueFlags.join(''); - return new RegExp(regex, flags); -}; - -var _default = { - comparePaths, - dropPathSegmentQuotes, - enforcedContexts, - exemptSpeciaMethods, - filterTags, - flattenRoots, - getContextObject, - getFunctionParameterNames, - getIndent, - getJsdocTagsDeep, - getPreferredTagName, - getRegexFromString, - getTagsByType, - getTagStructureForMode, - hasATag, - hasDefinedTypeTag, - hasParams, - hasReturnValue, - hasTag, - hasThrowValue, - hasValueOrExecutorHasNonEmptyResolveValue, - hasYieldValue, - isConstructor, - isGetter, - isNamepathDefiningTag, - isSetter, - isValidTag, - overrideTagStructure, - parseClosureTemplateTag, - setTagStructure, - tagMightHaveNamepath, - tagMightHaveNamePosition, - tagMightHaveTypePosition, - tagMissingRequiredTypeOrNamepath, - tagMustHaveNamePosition, - tagMustHaveTypePosition -}; -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=jsdocUtils.js.map -}); - -var iterateJsdoc_1 = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = iterateJsdoc; -exports.parseComment = exports.getSettings = void 0; - - - -var _description = _interopRequireWildcard(description$2); - -var _name = _interopRequireDefault(name$1); - -var _tag = _interopRequireDefault(tag); - -var _type = _interopRequireDefault(type_1); - - - -var _lodash = _interopRequireDefault(lodash__default['default']); - - - -var _jsdocUtils = _interopRequireDefault(jsdocUtils); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -/* -const { - align as commentAlign, - flow: commentFlow, - indent: commentIndent, -} = transforms; -*/ -const globalState = new Map(); - -const hasSeeWithLink = spec => { - return spec.tag === 'see' && /\{@link.+?\}/u.test(spec.source[0].source); -}; - -const getTokenizers = () => { - // trim - return [// Tag - (0, _tag.default)(), // Type - spec => { - if (['default', 'defaultvalue', 'see'].includes(spec.tag)) { - return spec; - } - - return (0, _type.default)()(spec); - }, // Name - spec => { - if (spec.tag === 'template') { - // const preWS = spec.postTag; - const remainder = spec.source[0].tokens.description; - const pos = remainder.search(/(? { - return (0, _description.default)((0, _description.getJoiner)('preserve'))(spec); - }]; -}; -/** - * - * @param {object} commentNode - * @param {string} indent Whitespace - * @returns {object} - */ - - -const parseComment = (commentNode, indent) => { - // Preserve JSDoc block start/end indentation. - return (0, lib.parse)(`/*${commentNode.value}*/`, { - // @see https://github.com/yavorskiy/comment-parser/issues/21 - tokenizers: getTokenizers() - })[0] || (0, util.seedBlock)({ - source: [{ - number: 0, - tokens: (0, util.seedTokens)({ - delimiter: '/**', - description: '', - end: '', - postDelimiter: '', - start: '' - }) - }, { - number: 1, - tokens: (0, util.seedTokens)({ - delimiter: '', - description: '', - end: '*/', - postDelimiter: '', - start: indent + ' ' - }) - }] - }); -}; - -exports.parseComment = parseComment; - -const getBasicUtils = (context, { - tagNamePreference, - mode -}) => { - const utils = {}; - - utils.reportSettings = message => { - context.report({ - loc: { - start: { - column: 1, - line: 1 - } - }, - message - }); - }; - - utils.parseClosureTemplateTag = tag => { - return _jsdocUtils.default.parseClosureTemplateTag(tag); - }; - - utils.getPreferredTagNameObject = ({ - tagName - }) => { - const ret = _jsdocUtils.default.getPreferredTagName(context, mode, tagName, tagNamePreference); - - const isObject = ret && typeof ret === 'object'; - - if (ret === false || isObject && !ret.replacement) { - return { - blocked: true, - tagName - }; - } - - return ret; - }; - - return utils; -}; - -const getUtils = (node, jsdoc, jsdocNode, settings, report, context, iteratingAll, ruleConfig, indent) => { - const ancestors = context.getAncestors(); - const sourceCode = context.getSourceCode(); - const utils = getBasicUtils(context, settings); - const { - tagNamePreference, - overrideReplacesDocs, - implementsReplacesDocs, - augmentsExtendsReplacesDocs, - maxLines, - minLines, - mode - } = settings; - - utils.isIteratingFunction = () => { - return !iteratingAll || ['MethodDefinition', 'ArrowFunctionExpression', 'FunctionDeclaration', 'FunctionExpression'].includes(node && node.type); - }; - - utils.isVirtualFunction = () => { - return iteratingAll && utils.hasATag(['callback', 'function', 'func', 'method']); - }; - - utils.stringify = (tagBlock, specRewire) => { - return (0, lib.stringify)(specRewire ? (0, util.rewireSpecs)(tagBlock) : tagBlock); - }; - - utils.reportJSDoc = (msg, tag, handler, specRewire) => { - report(msg, handler ? fixer => { - handler(); - const replacement = utils.stringify(jsdoc, specRewire); - return fixer.replaceText(jsdocNode, replacement); - } : null, tag); - }; - - utils.getRegexFromString = (str, requiredFlags) => { - return _jsdocUtils.default.getRegexFromString(str, requiredFlags); - }; - - utils.getDescription = () => { - const descriptions = []; - let lastDescriptionLine; - - if (jsdoc.source[0].tokens.description) { - descriptions.push(jsdoc.source[0].tokens.description); - } - - jsdoc.source.slice(1).some(({ - tokens: { - description, - tag, - end - } - }, idx) => { - if (tag || end) { - lastDescriptionLine = idx; - return true; - } - - descriptions.push(description); - return false; - }); - return { - description: descriptions.join('\n'), - lastDescriptionLine - }; - }; - - utils.changeTag = (tag, ...tokens) => { - tag.source.forEach((src, idx) => { - src.tokens = { ...src.tokens, - ...tokens[idx] - }; - }); - }; - - utils.setTag = (tag, tokens) => { - tag.source = [{ - // Or tag.source[0].number? - number: tag.line, - tokens: (0, util.seedTokens)({ - delimiter: '*', - postDelimiter: ' ', - start: indent + ' ', - tag: '@' + tag.tag, - ...tokens - }) - }]; - }; - - utils.removeTag = tagIndex => { - const { - source - } = jsdoc.tags[tagIndex]; - let lastIndex; - const firstNumber = jsdoc.source[0].number; - source.forEach(({ - number - }) => { - const sourceIndex = jsdoc.source.findIndex(({ - number: srcNumber, - tokens: { - end - } - }) => { - return number === srcNumber && !end; - }); - - if (sourceIndex > -1) { - jsdoc.source.splice(sourceIndex, 1); - lastIndex = sourceIndex; - } - }); - jsdoc.source.slice(lastIndex).forEach((src, idx) => { - src.number = firstNumber + lastIndex + idx; - }); - }; - - utils.addTag = targetTagName => { - var _jsdoc$tags$source$0$, _jsdoc$tags, _jsdoc$tags$source$; - - const number = ((_jsdoc$tags$source$0$ = (_jsdoc$tags = jsdoc.tags[jsdoc.tags.length - 1]) === null || _jsdoc$tags === void 0 ? void 0 : (_jsdoc$tags$source$ = _jsdoc$tags.source[0]) === null || _jsdoc$tags$source$ === void 0 ? void 0 : _jsdoc$tags$source$.number) !== null && _jsdoc$tags$source$0$ !== void 0 ? _jsdoc$tags$source$0$ : 0) + 1; - jsdoc.source.splice(number, 0, { - number, - source: '', - tokens: (0, util.seedTokens)({ - delimiter: '*', - postDelimiter: ' ', - start: indent + ' ', - tag: `@${targetTagName}` - }) - }); - jsdoc.source.slice(number + 1).forEach(src => { - src.number++; - }); - }; - - utils.flattenRoots = params => { - return _jsdocUtils.default.flattenRoots(params); - }; - - utils.getFunctionParameterNames = useDefaultObjectProperties => { - return _jsdocUtils.default.getFunctionParameterNames(node, useDefaultObjectProperties); - }; - - utils.hasParams = () => { - return _jsdocUtils.default.hasParams(node); - }; - - utils.isGenerator = () => { - return node && (node.generator || node.type === 'MethodDefinition' && node.value.generator || ['ExportNamedDeclaration', 'ExportDefaultDeclaration'].includes(node.type) && node.declaration.generator); - }; - - utils.isConstructor = () => { - return _jsdocUtils.default.isConstructor(node); - }; - - utils.getJsdocTagsDeep = tagName => { - const name = utils.getPreferredTagName({ - tagName - }); - - if (!name) { - return false; - } - - return _jsdocUtils.default.getJsdocTagsDeep(jsdoc, name); - }; - - utils.getPreferredTagName = ({ - tagName, - skipReportingBlockedTag = false, - allowObjectReturn = false, - defaultMessage = `Unexpected tag \`@${tagName}\`` - }) => { - const ret = _jsdocUtils.default.getPreferredTagName(context, mode, tagName, tagNamePreference); - - const isObject = ret && typeof ret === 'object'; - - if (utils.hasTag(tagName) && (ret === false || isObject && !ret.replacement)) { - if (skipReportingBlockedTag) { - return { - blocked: true, - tagName - }; - } - - const message = isObject && ret.message || defaultMessage; - report(message, null, utils.getTags(tagName)[0]); - return false; - } - - return isObject && !allowObjectReturn ? ret.replacement : ret; - }; - - utils.isValidTag = (name, definedTags) => { - return _jsdocUtils.default.isValidTag(context, mode, name, definedTags); - }; - - utils.hasATag = name => { - return _jsdocUtils.default.hasATag(jsdoc, name); - }; - - utils.hasTag = name => { - return _jsdocUtils.default.hasTag(jsdoc, name); - }; - - utils.comparePaths = name => { - return _jsdocUtils.default.comparePaths(name); - }; - - utils.dropPathSegmentQuotes = name => { - return _jsdocUtils.default.dropPathSegmentQuotes(name); - }; - - utils.avoidDocs = () => { - var _context$options$0$ex, _context$options$; - - if (overrideReplacesDocs !== false && (utils.hasTag('override') || utils.classHasTag('override')) || implementsReplacesDocs !== false && (utils.hasTag('implements') || utils.classHasTag('implements')) || augmentsExtendsReplacesDocs && (utils.hasATag(['augments', 'extends']) || utils.classHasTag('augments') || utils.classHasTag('extends'))) { - return true; - } - - if (_jsdocUtils.default.exemptSpeciaMethods(jsdoc, node, context, ruleConfig.meta.schema)) { - return true; - } - - const exemptedBy = (_context$options$0$ex = (_context$options$ = context.options[0]) === null || _context$options$ === void 0 ? void 0 : _context$options$.exemptedBy) !== null && _context$options$0$ex !== void 0 ? _context$options$0$ex : ['inheritDoc', ...(mode === 'closure' ? [] : ['inheritdoc'])]; - - if (exemptedBy.length && utils.getPresentTags(exemptedBy).length) { - return true; - } - - return false; - }; - - ['tagMightHaveNamePosition', 'tagMightHaveTypePosition'].forEach(method => { - utils[method] = (tagName, otherModeMaps) => { - const result = _jsdocUtils.default[method](tagName); - - if (result) { - return true; - } - - if (!otherModeMaps) { - return false; - } - - const otherResult = otherModeMaps.some(otherModeMap => { - return _jsdocUtils.default[method](tagName, otherModeMap); - }); - return otherResult ? { - otherMode: true - } : false; - }; - }); - ['tagMustHaveNamePosition', 'tagMustHaveTypePosition', 'tagMissingRequiredTypeOrNamepath'].forEach(method => { - utils[method] = (tagName, otherModeMaps) => { - const result = _jsdocUtils.default[method](tagName); - - if (!result) { - return false; - } // if (!otherModeMaps) { return true; } - - - const otherResult = otherModeMaps.every(otherModeMap => { - return _jsdocUtils.default[method](tagName, otherModeMap); - }); - return otherResult ? true : { - otherMode: false - }; - }; - }); - ['isNamepathDefiningTag', 'tagMightHaveNamepath'].forEach(method => { - utils[method] = tagName => { - return _jsdocUtils.default[method](tagName); - }; - }); - - utils.getTagStructureForMode = mde => { - return _jsdocUtils.default.getTagStructureForMode(mde, settings.structuredTags); - }; - - utils.hasDefinedTypeTag = tag => { - return _jsdocUtils.default.hasDefinedTypeTag(tag); - }; - - utils.hasValueOrExecutorHasNonEmptyResolveValue = anyPromiseAsReturn => { - return _jsdocUtils.default.hasValueOrExecutorHasNonEmptyResolveValue(node, anyPromiseAsReturn); - }; - - utils.hasYieldValue = () => { - if (['ExportNamedDeclaration', 'ExportDefaultDeclaration'].includes(node.type)) { - return _jsdocUtils.default.hasYieldValue(node.declaration); - } - - return _jsdocUtils.default.hasYieldValue(node); - }; - - utils.hasYieldReturnValue = () => { - return _jsdocUtils.default.hasYieldValue(node, true); - }; - - utils.hasThrowValue = () => { - return _jsdocUtils.default.hasThrowValue(node); - }; - - utils.isAsync = () => { - return node.async; - }; - - utils.getTags = tagName => { - return utils.filterTags(item => { - return item.tag === tagName; - }); - }; - - utils.getPresentTags = tagList => { - return utils.filterTags(tag => { - return tagList.includes(tag.tag); - }); - }; - - utils.filterTags = filter => { - return _jsdocUtils.default.filterTags(jsdoc.tags, filter); - }; - - utils.getTagsByType = tags => { - return _jsdocUtils.default.getTagsByType(context, mode, tags, tagNamePreference); - }; - - utils.hasOptionTag = tagName => { - var _context$options$2; - - const { - tags - } = (_context$options$2 = context.options[0]) !== null && _context$options$2 !== void 0 ? _context$options$2 : {}; - return Boolean(tags && tags.includes(tagName)); - }; - - utils.getClassNode = () => { - return [...ancestors, node].reverse().find(parent => { - return parent && ['ClassDeclaration', 'ClassExpression'].includes(parent.type); - }) || null; - }; - - utils.getClassJsdoc = () => { - const classNode = utils.getClassNode(); - - if (!classNode) { - return null; - } - - const classJsdocNode = (0, getJSDocComment_1.getJSDocComment)(sourceCode, classNode, { - maxLines, - minLines - }); - - if (classJsdocNode) { - const indnt = ' '.repeat(classJsdocNode.loc.start.column); - return parseComment(classJsdocNode, indnt); - } - - return null; - }; - - utils.classHasTag = tagName => { - const classJsdoc = utils.getClassJsdoc(); - return Boolean(classJsdoc) && _jsdocUtils.default.hasTag(classJsdoc, tagName); - }; - - utils.forEachPreferredTag = (tagName, arrayHandler, skipReportingBlockedTag = false) => { - const targetTagName = utils.getPreferredTagName({ - skipReportingBlockedTag, - tagName - }); - - if (!targetTagName || skipReportingBlockedTag && targetTagName && typeof targetTagName === 'object') { - return; - } - - const matchingJsdocTags = _lodash.default.filter(jsdoc.tags, { - tag: targetTagName - }); - - matchingJsdocTags.forEach(matchingJsdocTag => { - arrayHandler(matchingJsdocTag, targetTagName); - }); - }; - - return utils; -}; - -const getSettings = context => { - var _context$settings$jsd, _context$settings$jsd2, _context$settings$jsd3, _context$settings$jsd4, _context$settings$jsd5, _context$settings$jsd6, _context$settings$jsd7, _context$settings$jsd8, _context$settings$jsd9, _context$settings$jsd10, _context$settings$jsd11, _context$settings$jsd12, _context$settings$jsd13, _context$settings$jsd14, _context$settings$jsd15, _context$settings$jsd16, _context$settings$jsd17; - - /* eslint-disable sort-keys-fix/sort-keys-fix */ - const settings = { - // All rules - ignorePrivate: Boolean((_context$settings$jsd = context.settings.jsdoc) === null || _context$settings$jsd === void 0 ? void 0 : _context$settings$jsd.ignorePrivate), - ignoreInternal: Boolean((_context$settings$jsd2 = context.settings.jsdoc) === null || _context$settings$jsd2 === void 0 ? void 0 : _context$settings$jsd2.ignoreInternal), - maxLines: Number((_context$settings$jsd3 = (_context$settings$jsd4 = context.settings.jsdoc) === null || _context$settings$jsd4 === void 0 ? void 0 : _context$settings$jsd4.maxLines) !== null && _context$settings$jsd3 !== void 0 ? _context$settings$jsd3 : 1), - minLines: Number((_context$settings$jsd5 = (_context$settings$jsd6 = context.settings.jsdoc) === null || _context$settings$jsd6 === void 0 ? void 0 : _context$settings$jsd6.minLines) !== null && _context$settings$jsd5 !== void 0 ? _context$settings$jsd5 : 0), - // `check-tag-names` and many returns/param rules - tagNamePreference: (_context$settings$jsd7 = (_context$settings$jsd8 = context.settings.jsdoc) === null || _context$settings$jsd8 === void 0 ? void 0 : _context$settings$jsd8.tagNamePreference) !== null && _context$settings$jsd7 !== void 0 ? _context$settings$jsd7 : {}, - // `check-types` and `no-undefined-types` - preferredTypes: (_context$settings$jsd9 = (_context$settings$jsd10 = context.settings.jsdoc) === null || _context$settings$jsd10 === void 0 ? void 0 : _context$settings$jsd10.preferredTypes) !== null && _context$settings$jsd9 !== void 0 ? _context$settings$jsd9 : {}, - // `check-types`, `no-undefined-types`, `valid-types` - structuredTags: (_context$settings$jsd11 = (_context$settings$jsd12 = context.settings.jsdoc) === null || _context$settings$jsd12 === void 0 ? void 0 : _context$settings$jsd12.structuredTags) !== null && _context$settings$jsd11 !== void 0 ? _context$settings$jsd11 : {}, - // `require-param`, `require-description`, `require-example`, `require-returns` - overrideReplacesDocs: (_context$settings$jsd13 = context.settings.jsdoc) === null || _context$settings$jsd13 === void 0 ? void 0 : _context$settings$jsd13.overrideReplacesDocs, - implementsReplacesDocs: (_context$settings$jsd14 = context.settings.jsdoc) === null || _context$settings$jsd14 === void 0 ? void 0 : _context$settings$jsd14.implementsReplacesDocs, - augmentsExtendsReplacesDocs: (_context$settings$jsd15 = context.settings.jsdoc) === null || _context$settings$jsd15 === void 0 ? void 0 : _context$settings$jsd15.augmentsExtendsReplacesDocs, - // Many rules, e.g., `check-tag-names` - mode: (_context$settings$jsd16 = (_context$settings$jsd17 = context.settings.jsdoc) === null || _context$settings$jsd17 === void 0 ? void 0 : _context$settings$jsd17.mode) !== null && _context$settings$jsd16 !== void 0 ? _context$settings$jsd16 : context.parserPath.includes('@typescript-eslint') ? 'typescript' : 'jsdoc' - }; - /* eslint-enable sort-keys-fix/sort-keys-fix */ - - _jsdocUtils.default.setTagStructure(settings.mode); - - try { - _jsdocUtils.default.overrideTagStructure(settings.structuredTags); - } catch (error) { - context.report({ - loc: { - start: { - column: 1, - line: 1 - } - }, - message: error.message - }); - return false; - } - - return settings; -}; -/** - * Create the report function - * - * @param {object} context - * @param {object} commentNode - */ - - -exports.getSettings = getSettings; - -const makeReport = (context, commentNode) => { - const report = (message, fix = null, jsdocLoc = null, data = null) => { - let loc; - - if (jsdocLoc) { - if (!('line' in jsdocLoc)) { - jsdocLoc.line = jsdocLoc.source[0].number; - } - - const lineNumber = commentNode.loc.start.line + jsdocLoc.line; - loc = { - end: { - line: lineNumber - }, - start: { - line: lineNumber - } - }; - - if (jsdocLoc.column) { - const colNumber = commentNode.loc.start.column + jsdocLoc.column; - loc.end.column = colNumber; - loc.start.column = colNumber; - } - } - - context.report({ - data, - fix, - loc, - message, - node: commentNode - }); - }; - - return report; -}; -/** - * @typedef {ReturnType} Utils - * @typedef {ReturnType} Settings - * @typedef {( - * arg: { - * context: object, - * sourceCode: object, - * indent: string, - * jsdoc: object, - * jsdocNode: object, - * node: object | null, - * report: ReturnType, - * settings: Settings, - * utils: Utils, - * } - * ) => any } JsdocVisitor - */ - - -const iterate = (ruleConfig, context, lines, jsdocNode, node, settings, sourceCode, iterator, state, iteratingAll) => { - const sourceLine = lines[jsdocNode.loc.start.line - 1]; - const indent = sourceLine.charAt(0).repeat(jsdocNode.loc.start.column); - const jsdoc = parseComment(jsdocNode, indent); - const report = makeReport(context, jsdocNode); - const utils = getUtils(node, jsdoc, jsdocNode, settings, report, context, iteratingAll, ruleConfig, indent); - - if (!ruleConfig.checkInternal && settings.ignoreInternal && utils.hasTag('internal')) { - return; - } - - if (!ruleConfig.checkPrivate && settings.ignorePrivate && (utils.hasTag('private') || _lodash.default.filter(jsdoc.tags, { - tag: 'access' - }).some(({ - description - }) => { - return description === 'private'; - }))) { - return; - } - - iterator({ - context, - globalState, - indent, - iteratingAll, - jsdoc, - jsdocNode, - node, - report, - settings, - sourceCode, - state, - utils - }); -}; -/** - * Create an eslint rule that iterates over all JSDocs, regardless of whether - * they are attached to a function-like node. - * - * @param {JsdocVisitor} iterator - * @param {{meta: any}} ruleConfig - */ - - -const iterateAllJsdocs = (iterator, ruleConfig) => { - const trackedJsdocs = []; - let settings; - - const callIterator = (context, node, jsdocNodes, state, lastCall) => { - const sourceCode = context.getSourceCode(); - const { - lines - } = sourceCode; - const utils = getBasicUtils(context, settings); - jsdocNodes.forEach(jsdocNode => { - if (!/^\/\*\*\s/.test(sourceCode.getText(jsdocNode))) { - return; - } - - iterate(ruleConfig, context, lines, jsdocNode, node, settings, sourceCode, iterator, state, true); - }); - - if (lastCall && ruleConfig.exit) { - ruleConfig.exit({ - context, - state, - utils - }); - } - }; - - return { - create(context) { - const sourceCode = context.getSourceCode(); - settings = getSettings(context); - - if (!settings) { - return {}; - } - - const state = {}; - return { - '*:not(Program)'(node) { - const reducedNode = (0, getJSDocComment_1.getReducedASTNode)(node, sourceCode); - - if (node !== reducedNode) { - return; - } - - const comment = (0, getJSDocComment_1.getJSDocComment)(sourceCode, node, settings); - - if (trackedJsdocs.includes(comment)) { - return; - } - - if (!comment) { - if (ruleConfig.nonComment) { - ruleConfig.nonComment({ - node, - state - }); - } - - return; - } - - trackedJsdocs.push(comment); - callIterator(context, node, [comment], state); - }, - - 'Program:exit'() { - const allComments = sourceCode.getAllComments(); - const untrackedJSdoc = allComments.filter(node => { - return !trackedJsdocs.includes(node); - }); - callIterator(context, null, untrackedJSdoc, state, true); - } - - }; - }, - - meta: ruleConfig.meta - }; -}; -/** - * Create an eslint rule that iterates over all JSDocs, regardless of whether - * they are attached to a function-like node. - * - * @param {JsdocVisitor} iterator - * @param {{meta: any}} ruleConfig - */ - - -const checkFile = (iterator, ruleConfig) => { - return { - create(context) { - const sourceCode = context.getSourceCode(); - const settings = getSettings(context); - - if (!settings) { - return {}; - } - - return { - 'Program:exit'() { - const allComments = sourceCode.getAllComments(); - const { - lines - } = sourceCode; - const utils = getBasicUtils(context, settings); - iterator({ - allComments, - context, - lines, - makeReport, - settings, - sourceCode, - utils - }); - } - - }; - }, - - meta: ruleConfig.meta - }; -}; - -/** - * @param {JsdocVisitor} iterator - * @param {{ - * meta: any, - * contextDefaults?: true | string[], - * iterateAllJsdocs?: true, - * }} ruleConfig - */ -function iterateJsdoc(iterator, ruleConfig) { - var _ruleConfig$meta; - - const metaType = ruleConfig === null || ruleConfig === void 0 ? void 0 : (_ruleConfig$meta = ruleConfig.meta) === null || _ruleConfig$meta === void 0 ? void 0 : _ruleConfig$meta.type; - - if (!metaType || !['problem', 'suggestion', 'layout'].includes(metaType)) { - throw new TypeError('Rule must include `meta.type` option (with value "problem", "suggestion", or "layout")'); - } - - if (typeof iterator !== 'function') { - throw new TypeError('The iterator argument must be a function.'); - } - - if (ruleConfig.checkFile) { - return checkFile(iterator, ruleConfig); - } - - if (ruleConfig.iterateAllJsdocs) { - return iterateAllJsdocs(iterator, ruleConfig); - } - - return { - /** - * The entrypoint for the JSDoc rule. - * - * @param {*} context - * a reference to the context which hold all important information - * like settings and the sourcecode to check. - * @returns {object} - * a list with parser callback function. - */ - create(context) { - let contexts; - - if (ruleConfig.contextDefaults) { - contexts = _jsdocUtils.default.enforcedContexts(context, ruleConfig.contextDefaults); - - if (contexts.includes('any')) { - return iterateAllJsdocs(iterator, ruleConfig).create(context); - } - } - - const sourceCode = context.getSourceCode(); - const settings = getSettings(context); - - if (!settings) { - return {}; - } - - const { - lines - } = sourceCode; - - const checkJsdoc = node => { - const jsdocNode = (0, getJSDocComment_1.getJSDocComment)(sourceCode, node, settings); - - if (!jsdocNode) { - return; - } - - iterate(ruleConfig, context, lines, jsdocNode, node, settings, sourceCode, iterator); - }; - - if (ruleConfig.contextDefaults) { - return _jsdocUtils.default.getContextObject(contexts, checkJsdoc); - } - - return { - ArrowFunctionExpression: checkJsdoc, - FunctionDeclaration: checkJsdoc, - FunctionExpression: checkJsdoc - }; - }, - - meta: ruleConfig.meta - }; -} -//# sourceMappingURL=iterateJsdoc.js.map -}); - -var checkAccess = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const accessLevels = ['package', 'private', 'protected', 'public']; - -var _default = (0, _iterateJsdoc.default)(({ - report, - utils -}) => { - utils.forEachPreferredTag('access', (jsdocParameter, targetTagName) => { - const desc = targetTagName === 'access' ? jsdocParameter.description : jsdocParameter.name + ' ' + jsdocParameter.description; - - if (!accessLevels.includes(desc.trim())) { - report(`Missing valid JSDoc @${targetTagName} level.`, null, jsdocParameter); - } - }); - const accessLength = utils.getTags('access').length; - const individualTagLength = utils.getPresentTags(accessLevels).length; - - if (accessLength && individualTagLength) { - report('The @access tag may not be used with specific access-control tags (@package, @private, @protected, or @public).'); - } - - if (accessLength > 1 || individualTagLength > 1) { - report('At most one access-control tag may be present on a jsdoc block.'); - } -}, { - checkPrivate: true, - iterateAllJsdocs: true, - meta: { - docs: { - description: 'Checks that `@access` tags have a valid value.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-access' - }, - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=checkAccess.js.map -}); - -var checkAlignment = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const trimStart = string => { - return string.replace(/^\s+/u, ''); -}; - -var _default = (0, _iterateJsdoc.default)(({ - sourceCode, - jsdocNode, - report, - indent -}) => { - // `indent` is whitespace from line 1 (`/**`), so slice and account for "/". - const indentLevel = indent.length + 1; - const sourceLines = sourceCode.getText(jsdocNode).split('\n').slice(1).map(line => { - return line.split('*')[0]; - }).filter(line => { - return !trimStart(line).length; - }); - - const fix = fixer => { - const replacement = sourceCode.getText(jsdocNode).split('\n').map((line, index) => { - // Ignore the first line and all lines not starting with `*` - const ignored = !index || trimStart(line.split('*')[0]).length; - return ignored ? line : `${indent} ${trimStart(line)}`; - }).join('\n'); - return fixer.replaceText(jsdocNode, replacement); - }; - - sourceLines.some((line, lineNum) => { - if (line.length !== indentLevel) { - report('Expected JSDoc block to be aligned.', fix, { - line: lineNum + 1 - }); - return true; - } - - return false; - }); -}, { - iterateAllJsdocs: true, - meta: { - docs: { - description: 'Reports invalid alignment of JSDoc block asterisks.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-alignment' - }, - fixable: 'code', - type: 'layout' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=checkAlignment.js.map -}); - -/** - * @fileoverview Default CLIEngineOptions. - * @author Ian VanSchooten - */ - -var defaultCliOptions = { - configFile: null, - baseConfig: false, - rulePaths: [], - useEslintrc: true, - envs: [], - globals: [], - extensions: null, - ignore: true, - ignorePath: void 0, - cache: false, - - /* - * in order to honor the cacheFile option if specified - * this option should not have a default value otherwise - * it will always be used - */ - cacheLocation: "", - cacheFile: ".eslintcache", - cacheStrategy: "metadata", - fix: false, - allowInlineConfig: true, - reportUnusedDisableDirectives: void 0, - globInputPaths: true -}; - -var name = "eslint"; -var version$1 = "7.24.0"; -var author = "Nicholas C. Zakas "; -var description$1 = "An AST-based pattern checker for JavaScript."; -var bin = { - eslint: "./bin/eslint.js" -}; -var main = "./lib/api.js"; -var scripts = { - test: "node Makefile.js test", - "test:cli": "mocha", - lint: "node Makefile.js lint", - fix: "node Makefile.js lint -- fix", - fuzz: "node Makefile.js fuzz", - "generate-release": "node Makefile.js generateRelease", - "generate-alpharelease": "node Makefile.js generatePrerelease -- alpha", - "generate-betarelease": "node Makefile.js generatePrerelease -- beta", - "generate-rcrelease": "node Makefile.js generatePrerelease -- rc", - "publish-release": "node Makefile.js publishRelease", - docs: "node Makefile.js docs", - gensite: "node Makefile.js gensite", - webpack: "node Makefile.js webpack", - perf: "node Makefile.js perf" -}; -var gitHooks = { - "pre-commit": "lint-staged" -}; -var files = [ - "LICENSE", - "README.md", - "bin", - "conf", - "lib", - "messages" -]; -var repository = "eslint/eslint"; -var funding = "https://opencollective.com/eslint"; -var homepage = "https://eslint.org"; -var bugs = "https://github.com/eslint/eslint/issues/"; -var dependencies$1 = { - "@babel/code-frame": "7.12.11", - "@eslint/eslintrc": "^0.4.0", - ajv: "^6.10.0", - chalk: "^4.0.0", - "cross-spawn": "^7.0.2", - debug: "^4.0.1", - doctrine: "^3.0.0", - enquirer: "^2.3.5", - "eslint-scope": "^5.1.1", - "eslint-utils": "^2.1.0", - "eslint-visitor-keys": "^2.0.0", - espree: "^7.3.1", - esquery: "^1.4.0", - esutils: "^2.0.2", - "file-entry-cache": "^6.0.1", - "functional-red-black-tree": "^1.0.1", - "glob-parent": "^5.0.0", - globals: "^13.6.0", - ignore: "^4.0.6", - "import-fresh": "^3.0.0", - imurmurhash: "^0.1.4", - "is-glob": "^4.0.0", - "js-yaml": "^3.13.1", - "json-stable-stringify-without-jsonify": "^1.0.1", - levn: "^0.4.1", - lodash: "^4.17.21", - minimatch: "^3.0.4", - "natural-compare": "^1.4.0", - optionator: "^0.9.1", - progress: "^2.0.0", - regexpp: "^3.1.0", - semver: "^7.2.1", - "strip-ansi": "^6.0.0", - "strip-json-comments": "^3.1.0", - table: "^6.0.4", - "text-table": "^0.2.0", - "v8-compile-cache": "^2.0.3" -}; -var devDependencies = { - "@babel/core": "^7.4.3", - "@babel/preset-env": "^7.4.3", - acorn: "^7.2.0", - "babel-loader": "^8.0.5", - chai: "^4.0.1", - cheerio: "^0.22.0", - "common-tags": "^1.8.0", - "core-js": "^3.1.3", - dateformat: "^3.0.3", - ejs: "^3.0.2", - "escape-string-regexp": "^3.0.0", - eslint: "file:.", - "eslint-config-eslint": "file:packages/eslint-config-eslint", - "eslint-plugin-eslint-plugin": "^2.2.1", - "eslint-plugin-internal-rules": "file:tools/internal-rules", - "eslint-plugin-jsdoc": "^25.4.3", - "eslint-plugin-node": "^11.1.0", - "eslint-release": "^2.0.0", - eslump: "^2.0.0", - esprima: "^4.0.1", - "fs-teardown": "^0.1.0", - glob: "^7.1.6", - jsdoc: "^3.5.5", - karma: "^6.1.1", - "karma-chrome-launcher": "^3.1.0", - "karma-mocha": "^2.0.1", - "karma-mocha-reporter": "^2.2.5", - "karma-webpack": "^5.0.0", - "lint-staged": "^10.1.2", - "load-perf": "^0.2.0", - markdownlint: "^0.19.0", - "markdownlint-cli": "^0.22.0", - memfs: "^3.0.1", - mocha: "^8.3.2", - "mocha-junit-reporter": "^2.0.0", - "node-polyfill-webpack-plugin": "^1.0.3", - "npm-license": "^0.3.3", - nyc: "^15.0.1", - proxyquire: "^2.0.1", - puppeteer: "^7.1.0", - recast: "^0.19.0", - "regenerator-runtime": "^0.13.2", - shelljs: "^0.8.2", - sinon: "^9.0.1", - temp: "^0.9.0", - webpack: "^5.23.0", - "webpack-cli": "^4.5.0", - yorkie: "^2.0.0" -}; -var keywords$1 = [ - "ast", - "lint", - "javascript", - "ecmascript", - "espree" -]; -var license = "MIT"; -var engines = { - node: "^10.12.0 || >=12.0.0" -}; -var require$$3 = { - name: name, - version: version$1, - author: author, - description: description$1, - bin: bin, - main: main, - scripts: scripts, - gitHooks: gitHooks, - "lint-staged": { - "*.js": [ - "eslint --fix", - "git add" - ], - "*.md": "markdownlint" -}, - files: files, - repository: repository, - funding: funding, - homepage: homepage, - bugs: bugs, - dependencies: dependencies$1, - devDependencies: devDependencies, - keywords: keywords$1, - license: license, - engines: engines -}; - -/** - * Utility for resolving a module relative to another module - * @author Teddy Katz - */ - - - -/* - * `Module.createRequire` is added in v12.2.0. It supports URL as well. - * We only support the case where the argument is a filepath, not a URL. - */ -// eslint-disable-next-line node/no-unsupported-features/node-builtins, node/no-deprecated-api -const createRequire = Module__default['default'].createRequire || Module__default['default'].createRequireFromPath; - -var relativeModuleResolver = { - - /** - * Resolves a Node module relative to another module - * @param {string} moduleName The name of a Node module, or a path to a Node module. - * @param {string} relativeToPath An absolute path indicating the module that `moduleName` should be resolved relative to. This must be - * a file rather than a directory, but the file need not actually exist. - * @returns {string} The absolute path that would result from calling `require.resolve(moduleName)` in a file located at `relativeToPath` - */ - resolve(moduleName, relativeToPath) { - try { - return createRequire(relativeToPath).resolve(moduleName); - } catch (error) { - - // This `if` block is for older Node.js than 12.0.0. We can remove this block in the future. - if ( - typeof error === "object" && - error !== null && - error.code === "MODULE_NOT_FOUND" && - !error.requireStack && - error.message.includes(moduleName) - ) { - error.message += `\nRequire stack:\n- ${relativeToPath}`; - } - throw error; - } - } -}; - -/** - * @fileoverview `FileEnumerator` class. - * - * `FileEnumerator` class has two responsibilities: - * - * 1. Find target files by processing glob patterns. - * 2. Tie each target file and appropriate configuration. - * - * It provides a method: - * - * - `iterateFiles(patterns)` - * Iterate files which are matched by given patterns together with the - * corresponded configuration. This is for `CLIEngine#executeOnFiles()`. - * While iterating files, it loads the configuration file of each directory - * before iterate files on the directory, so we can use the configuration - * files to determine target files. - * - * @example - * const enumerator = new FileEnumerator(); - * const linter = new Linter(); - * - * for (const { config, filePath } of enumerator.iterateFiles(["*.js"])) { - * const code = fs.readFileSync(filePath, "utf8"); - * const messages = linter.verify(code, config, filePath); - * - * console.log(messages); - * } - * - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - - -const { escapeRegExp: escapeRegExp$1 } = lodash__default['default']; -const { Minimatch } = require$$1__default['default']; - -const { - Legacy: { - IgnorePattern: IgnorePattern$1, - CascadingConfigArrayFactory: CascadingConfigArrayFactory$1 - } -} = require$$2__default['default']; -const debug$8 = require$$0__default['default']("eslint:file-enumerator"); - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const minimatchOpts = { dot: true, matchBase: true }; -const dotfilesPattern = /(?:(?:^\.)|(?:[/\\]\.))[^/\\.].*/u; -const NONE = 0; -const IGNORED_SILENTLY = 1; -const IGNORED = 2; - -// For VSCode intellisense -/** @typedef {ReturnType} ConfigArray */ - -/** - * @typedef {Object} FileEnumeratorOptions - * @property {CascadingConfigArrayFactory} [configArrayFactory] The factory for config arrays. - * @property {string} [cwd] The base directory to start lookup. - * @property {string[]} [extensions] The extensions to match files for directory patterns. - * @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file. - * @property {boolean} [ignore] The flag to check ignored files. - * @property {string[]} [rulePaths] The value of `--rulesdir` option. - */ - -/** - * @typedef {Object} FileAndConfig - * @property {string} filePath The path to a target file. - * @property {ConfigArray} config The config entries of that file. - * @property {boolean} ignored If `true` then this file should be ignored and warned because it was directly specified. - */ - -/** - * @typedef {Object} FileEntry - * @property {string} filePath The path to a target file. - * @property {ConfigArray} config The config entries of that file. - * @property {NONE|IGNORED_SILENTLY|IGNORED} flag The flag. - * - `NONE` means the file is a target file. - * - `IGNORED_SILENTLY` means the file should be ignored silently. - * - `IGNORED` means the file should be ignored and warned because it was directly specified. - */ - -/** - * @typedef {Object} FileEnumeratorInternalSlots - * @property {CascadingConfigArrayFactory} configArrayFactory The factory for config arrays. - * @property {string} cwd The base directory to start lookup. - * @property {RegExp|null} extensionRegExp The RegExp to test if a string ends with specific file extensions. - * @property {boolean} globInputPaths Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file. - * @property {boolean} ignoreFlag The flag to check ignored files. - * @property {(filePath:string, dot:boolean) => boolean} defaultIgnores The default predicate function to ignore files. - */ - -/** @type {WeakMap} */ -const internalSlotsMap$2 = new WeakMap(); - -/** - * Check if a string is a glob pattern or not. - * @param {string} pattern A glob pattern. - * @returns {boolean} `true` if the string is a glob pattern. - */ -function isGlobPattern(pattern) { - return isGlob__default['default'](path__default['default'].sep === "\\" ? pattern.replace(/\\/gu, "/") : pattern); -} - -/** - * Get stats of a given path. - * @param {string} filePath The path to target file. - * @returns {fs.Stats|null} The stats. - * @private - */ -function statSafeSync(filePath) { - try { - return fs__default['default'].statSync(filePath); - } catch (error) { - /* istanbul ignore next */ - if (error.code !== "ENOENT") { - throw error; - } - return null; - } -} - -/** - * Get filenames in a given path to a directory. - * @param {string} directoryPath The path to target directory. - * @returns {import("fs").Dirent[]} The filenames. - * @private - */ -function readdirSafeSync(directoryPath) { - try { - return fs__default['default'].readdirSync(directoryPath, { withFileTypes: true }); - } catch (error) { - /* istanbul ignore next */ - if (error.code !== "ENOENT") { - throw error; - } - return []; - } -} - -/** - * Create a `RegExp` object to detect extensions. - * @param {string[] | null} extensions The extensions to create. - * @returns {RegExp | null} The created `RegExp` object or null. - */ -function createExtensionRegExp(extensions) { - if (extensions) { - const normalizedExts = extensions.map(ext => escapeRegExp$1( - ext.startsWith(".") - ? ext.slice(1) - : ext - )); - - return new RegExp( - `.\\.(?:${normalizedExts.join("|")})$`, - "u" - ); - } - return null; -} - -/** - * The error type when no files match a glob. - */ -class NoFilesFoundError extends Error { - - // eslint-disable-next-line jsdoc/require-description - /** - * @param {string} pattern The glob pattern which was not found. - * @param {boolean} globDisabled If `true` then the pattern was a glob pattern, but glob was disabled. - */ - constructor(pattern, globDisabled) { - super(`No files matching '${pattern}' were found${globDisabled ? " (glob was disabled)" : ""}.`); - this.messageTemplate = "file-not-found"; - this.messageData = { pattern, globDisabled }; - } -} - -/** - * The error type when there are files matched by a glob, but all of them have been ignored. - */ -class AllFilesIgnoredError extends Error { - - // eslint-disable-next-line jsdoc/require-description - /** - * @param {string} pattern The glob pattern which was not found. - */ - constructor(pattern) { - super(`All files matched by '${pattern}' are ignored.`); - this.messageTemplate = "all-files-ignored"; - this.messageData = { pattern }; - } -} - -/** - * This class provides the functionality that enumerates every file which is - * matched by given glob patterns and that configuration. - */ -class FileEnumerator$1 { - - /** - * Initialize this enumerator. - * @param {FileEnumeratorOptions} options The options. - */ - constructor({ - cwd = process.cwd(), - configArrayFactory = new CascadingConfigArrayFactory$1({ - cwd, - eslintRecommendedPath: path__default['default'].resolve(__dirname, "../../conf/eslint-recommended.js"), - eslintAllPath: path__default['default'].resolve(__dirname, "../../conf/eslint-all.js") - }), - extensions = null, - globInputPaths = true, - errorOnUnmatchedPattern = true, - ignore = true - } = {}) { - internalSlotsMap$2.set(this, { - configArrayFactory, - cwd, - defaultIgnores: IgnorePattern$1.createDefaultIgnore(cwd), - extensionRegExp: createExtensionRegExp(extensions), - globInputPaths, - errorOnUnmatchedPattern, - ignoreFlag: ignore - }); - } - - /** - * Check if a given file is target or not. - * @param {string} filePath The path to a candidate file. - * @param {ConfigArray} [providedConfig] Optional. The configuration for the file. - * @returns {boolean} `true` if the file is a target. - */ - isTargetPath(filePath, providedConfig) { - const { - configArrayFactory, - extensionRegExp - } = internalSlotsMap$2.get(this); - - // If `--ext` option is present, use it. - if (extensionRegExp) { - return extensionRegExp.test(filePath); - } - - // `.js` file is target by default. - if (filePath.endsWith(".js")) { - return true; - } - - // use `overrides[].files` to check additional targets. - const config = - providedConfig || - configArrayFactory.getConfigArrayForFile( - filePath, - { ignoreNotFoundError: true } - ); - - return config.isAdditionalTargetPath(filePath); - } - - /** - * Iterate files which are matched by given glob patterns. - * @param {string|string[]} patternOrPatterns The glob patterns to iterate files. - * @returns {IterableIterator} The found files. - */ - *iterateFiles(patternOrPatterns) { - const { globInputPaths, errorOnUnmatchedPattern } = internalSlotsMap$2.get(this); - const patterns = Array.isArray(patternOrPatterns) - ? patternOrPatterns - : [patternOrPatterns]; - - debug$8("Start to iterate files: %o", patterns); - - // The set of paths to remove duplicate. - const set = new Set(); - - for (const pattern of patterns) { - let foundRegardlessOfIgnored = false; - let found = false; - - // Skip empty string. - if (!pattern) { - continue; - } - - // Iterate files of this pattern. - for (const { config, filePath, flag } of this._iterateFiles(pattern)) { - foundRegardlessOfIgnored = true; - if (flag === IGNORED_SILENTLY) { - continue; - } - found = true; - - // Remove duplicate paths while yielding paths. - if (!set.has(filePath)) { - set.add(filePath); - yield { - config, - filePath, - ignored: flag === IGNORED - }; - } - } - - // Raise an error if any files were not found. - if (errorOnUnmatchedPattern) { - if (!foundRegardlessOfIgnored) { - throw new NoFilesFoundError( - pattern, - !globInputPaths && isGlob__default['default'](pattern) - ); - } - if (!found) { - throw new AllFilesIgnoredError(pattern); - } - } - } - - debug$8(`Complete iterating files: ${JSON.stringify(patterns)}`); - } - - /** - * Iterate files which are matched by a given glob pattern. - * @param {string} pattern The glob pattern to iterate files. - * @returns {IterableIterator} The found files. - */ - _iterateFiles(pattern) { - const { cwd, globInputPaths } = internalSlotsMap$2.get(this); - const absolutePath = path__default['default'].resolve(cwd, pattern); - const isDot = dotfilesPattern.test(pattern); - const stat = statSafeSync(absolutePath); - - if (stat && stat.isDirectory()) { - return this._iterateFilesWithDirectory(absolutePath, isDot); - } - if (stat && stat.isFile()) { - return this._iterateFilesWithFile(absolutePath); - } - if (globInputPaths && isGlobPattern(pattern)) { - return this._iterateFilesWithGlob(absolutePath, isDot); - } - - return []; - } - - /** - * Iterate a file which is matched by a given path. - * @param {string} filePath The path to the target file. - * @returns {IterableIterator} The found files. - * @private - */ - _iterateFilesWithFile(filePath) { - debug$8(`File: ${filePath}`); - - const { configArrayFactory } = internalSlotsMap$2.get(this); - const config = configArrayFactory.getConfigArrayForFile(filePath); - const ignored = this._isIgnoredFile(filePath, { config, direct: true }); - const flag = ignored ? IGNORED : NONE; - - return [{ config, filePath, flag }]; - } - - /** - * Iterate files in a given path. - * @param {string} directoryPath The path to the target directory. - * @param {boolean} dotfiles If `true` then it doesn't skip dot files by default. - * @returns {IterableIterator} The found files. - * @private - */ - _iterateFilesWithDirectory(directoryPath, dotfiles) { - debug$8(`Directory: ${directoryPath}`); - - return this._iterateFilesRecursive( - directoryPath, - { dotfiles, recursive: true, selector: null } - ); - } - - /** - * Iterate files which are matched by a given glob pattern. - * @param {string} pattern The glob pattern to iterate files. - * @param {boolean} dotfiles If `true` then it doesn't skip dot files by default. - * @returns {IterableIterator} The found files. - * @private - */ - _iterateFilesWithGlob(pattern, dotfiles) { - debug$8(`Glob: ${pattern}`); - - const directoryPath = path__default['default'].resolve(getGlobParent__default['default'](pattern)); - const globPart = pattern.slice(directoryPath.length + 1); - - /* - * recursive if there are `**` or path separators in the glob part. - * Otherwise, patterns such as `src/*.js`, it doesn't need recursive. - */ - const recursive = /\*\*|\/|\\/u.test(globPart); - const selector = new Minimatch(pattern, minimatchOpts); - - debug$8(`recursive? ${recursive}`); - - return this._iterateFilesRecursive( - directoryPath, - { dotfiles, recursive, selector } - ); - } - - /** - * Iterate files in a given path. - * @param {string} directoryPath The path to the target directory. - * @param {Object} options The options to iterate files. - * @param {boolean} [options.dotfiles] If `true` then it doesn't skip dot files by default. - * @param {boolean} [options.recursive] If `true` then it dives into sub directories. - * @param {InstanceType} [options.selector] The matcher to choose files. - * @returns {IterableIterator} The found files. - * @private - */ - *_iterateFilesRecursive(directoryPath, options) { - debug$8(`Enter the directory: ${directoryPath}`); - const { configArrayFactory } = internalSlotsMap$2.get(this); - - /** @type {ConfigArray|null} */ - let config = null; - - // Enumerate the files of this directory. - for (const entry of readdirSafeSync(directoryPath)) { - const filePath = path__default['default'].join(directoryPath, entry.name); - const fileInfo = entry.isSymbolicLink() ? statSafeSync(filePath) : entry; - - if (!fileInfo) { - continue; - } - - // Check if the file is matched. - if (fileInfo.isFile()) { - if (!config) { - config = configArrayFactory.getConfigArrayForFile( - filePath, - - /* - * We must ignore `ConfigurationNotFoundError` at this - * point because we don't know if target files exist in - * this directory. - */ - { ignoreNotFoundError: true } - ); - } - const matched = options.selector - - // Started with a glob pattern; choose by the pattern. - ? options.selector.match(filePath) - - // Started with a directory path; choose by file extensions. - : this.isTargetPath(filePath, config); - - if (matched) { - const ignored = this._isIgnoredFile(filePath, { ...options, config }); - const flag = ignored ? IGNORED_SILENTLY : NONE; - - debug$8(`Yield: ${entry.name}${ignored ? " but ignored" : ""}`); - yield { - config: configArrayFactory.getConfigArrayForFile(filePath), - filePath, - flag - }; - } else { - debug$8(`Didn't match: ${entry.name}`); - } - - // Dive into the sub directory. - } else if (options.recursive && fileInfo.isDirectory()) { - if (!config) { - config = configArrayFactory.getConfigArrayForFile( - filePath, - { ignoreNotFoundError: true } - ); - } - const ignored = this._isIgnoredFile( - filePath + path__default['default'].sep, - { ...options, config } - ); - - if (!ignored) { - yield* this._iterateFilesRecursive(filePath, options); - } - } - } - - debug$8(`Leave the directory: ${directoryPath}`); - } - - /** - * Check if a given file should be ignored. - * @param {string} filePath The path to a file to check. - * @param {Object} options Options - * @param {ConfigArray} [options.config] The config for this file. - * @param {boolean} [options.dotfiles] If `true` then this is not ignore dot files by default. - * @param {boolean} [options.direct] If `true` then this is a direct specified file. - * @returns {boolean} `true` if the file should be ignored. - * @private - */ - _isIgnoredFile(filePath, { - config: providedConfig, - dotfiles = false, - direct = false - }) { - const { - configArrayFactory, - defaultIgnores, - ignoreFlag - } = internalSlotsMap$2.get(this); - - if (ignoreFlag) { - const config = - providedConfig || - configArrayFactory.getConfigArrayForFile( - filePath, - { ignoreNotFoundError: true } - ); - const ignores = - config.extractConfig(filePath).ignores || defaultIgnores; - - return ignores(filePath, dotfiles); - } - - return !direct && defaultIgnores(filePath, dotfiles); - } -} - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -var fileEnumerator = { FileEnumerator: FileEnumerator$1 }; - -/** - * @fileoverview Defines environment settings and globals. - * @author Elan Shanker - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Get the object that has difference. - * @param {Record} current The newer object. - * @param {Record} prev The older object. - * @returns {Record} The difference object. - */ -function getDiff(current, prev) { - const retv = {}; - - for (const [key, value] of Object.entries(current)) { - if (!Object.hasOwnProperty.call(prev, key)) { - retv[key] = value; - } - } - - return retv; -} - -const newGlobals2015 = getDiff(globals__default['default'].es2015, globals__default['default'].es5); // 19 variables such as Promise, Map, ... -const newGlobals2017 = { - Atomics: false, - SharedArrayBuffer: false -}; -const newGlobals2020 = { - BigInt: false, - BigInt64Array: false, - BigUint64Array: false, - globalThis: false -}; - -const newGlobals2021 = { - AggregateError: false, - FinalizationRegistry: false, - WeakRef: false -}; - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -/** @type {Map} */ -var environments = new Map(Object.entries({ - - // Language - builtin: { - globals: globals__default['default'].es5 - }, - es6: { - globals: newGlobals2015, - parserOptions: { - ecmaVersion: 6 - } - }, - es2015: { - globals: newGlobals2015, - parserOptions: { - ecmaVersion: 6 - } - }, - es2017: { - globals: { ...newGlobals2015, ...newGlobals2017 }, - parserOptions: { - ecmaVersion: 8 - } - }, - es2020: { - globals: { ...newGlobals2015, ...newGlobals2017, ...newGlobals2020 }, - parserOptions: { - ecmaVersion: 11 - } - }, - es2021: { - globals: { ...newGlobals2015, ...newGlobals2017, ...newGlobals2020, ...newGlobals2021 }, - parserOptions: { - ecmaVersion: 12 - } - }, - - // Platforms - browser: { - globals: globals__default['default'].browser - }, - node: { - globals: globals__default['default'].node, - parserOptions: { - ecmaFeatures: { - globalReturn: true - } - } - }, - "shared-node-browser": { - globals: globals__default['default']["shared-node-browser"] - }, - worker: { - globals: globals__default['default'].worker - }, - serviceworker: { - globals: globals__default['default'].serviceworker - }, - - // Frameworks - commonjs: { - globals: globals__default['default'].commonjs, - parserOptions: { - ecmaFeatures: { - globalReturn: true - } - } - }, - amd: { - globals: globals__default['default'].amd - }, - mocha: { - globals: globals__default['default'].mocha - }, - jasmine: { - globals: globals__default['default'].jasmine - }, - jest: { - globals: globals__default['default'].jest - }, - phantomjs: { - globals: globals__default['default'].phantomjs - }, - jquery: { - globals: globals__default['default'].jquery - }, - qunit: { - globals: globals__default['default'].qunit - }, - prototypejs: { - globals: globals__default['default'].prototypejs - }, - shelljs: { - globals: globals__default['default'].shelljs - }, - meteor: { - globals: globals__default['default'].meteor - }, - mongo: { - globals: globals__default['default'].mongo - }, - protractor: { - globals: globals__default['default'].protractor - }, - applescript: { - globals: globals__default['default'].applescript - }, - nashorn: { - globals: globals__default['default'].nashorn - }, - atomtest: { - globals: globals__default['default'].atomtest - }, - embertest: { - globals: globals__default['default'].embertest - }, - webextensions: { - globals: globals__default['default'].webextensions - }, - greasemonkey: { - globals: globals__default['default'].greasemonkey - } -})); - -/** - * @fileoverview Common utils for AST. - * - * This file contains only shared items for core and rules. - * If you make a utility for rules, please see `../rules/utils/ast-utils.js`. - * - * @author Toru Nagashima - */ - -const breakableTypePattern$1 = /^(?:(?:Do)?While|For(?:In|Of)?|Switch)Statement$/u; -const lineBreakPattern = /\r\n|[\r\n\u2028\u2029]/u; -const shebangPattern = /^#!([^\r\n]+)/u; - -/** - * Creates a version of the `lineBreakPattern` regex with the global flag. - * Global regexes are mutable, so this needs to be a function instead of a constant. - * @returns {RegExp} A global regular expression that matches line terminators - */ -function createGlobalLinebreakMatcher() { - return new RegExp(lineBreakPattern.source, "gu"); -} - -var astUtils$1 = { - breakableTypePattern: breakableTypePattern$1, - lineBreakPattern, - createGlobalLinebreakMatcher, - shebangPattern -}; - -/** - * @fileoverview Config file operations. This file must be usable in the browser, - * so no Node-specific code can be here. - * @author Nicholas C. Zakas - */ - -var configOps = createCommonjsModule(function (module) { - -//------------------------------------------------------------------------------ -// Private -//------------------------------------------------------------------------------ - -const RULE_SEVERITY_STRINGS = ["off", "warn", "error"], - RULE_SEVERITY = RULE_SEVERITY_STRINGS.reduce((map, value, index) => { - map[value] = index; - return map; - }, {}), - VALID_SEVERITIES = [0, 1, 2, "off", "warn", "error"]; - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -module.exports = { - - /** - * Normalizes the severity value of a rule's configuration to a number - * @param {(number|string|[number, ...*]|[string, ...*])} ruleConfig A rule's configuration value, generally - * received from the user. A valid config value is either 0, 1, 2, the string "off" (treated the same as 0), - * the string "warn" (treated the same as 1), the string "error" (treated the same as 2), or an array - * whose first element is one of the above values. Strings are matched case-insensitively. - * @returns {(0|1|2)} The numeric severity value if the config value was valid, otherwise 0. - */ - getRuleSeverity(ruleConfig) { - const severityValue = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig; - - if (severityValue === 0 || severityValue === 1 || severityValue === 2) { - return severityValue; - } - - if (typeof severityValue === "string") { - return RULE_SEVERITY[severityValue.toLowerCase()] || 0; - } - - return 0; - }, - - /** - * Converts old-style severity settings (0, 1, 2) into new-style - * severity settings (off, warn, error) for all rules. Assumption is that severity - * values have already been validated as correct. - * @param {Object} config The config object to normalize. - * @returns {void} - */ - normalizeToStrings(config) { - - if (config.rules) { - Object.keys(config.rules).forEach(ruleId => { - const ruleConfig = config.rules[ruleId]; - - if (typeof ruleConfig === "number") { - config.rules[ruleId] = RULE_SEVERITY_STRINGS[ruleConfig] || RULE_SEVERITY_STRINGS[0]; - } else if (Array.isArray(ruleConfig) && typeof ruleConfig[0] === "number") { - ruleConfig[0] = RULE_SEVERITY_STRINGS[ruleConfig[0]] || RULE_SEVERITY_STRINGS[0]; - } - }); - } - }, - - /** - * Determines if the severity for the given rule configuration represents an error. - * @param {int|string|Array} ruleConfig The configuration for an individual rule. - * @returns {boolean} True if the rule represents an error, false if not. - */ - isErrorSeverity(ruleConfig) { - return module.exports.getRuleSeverity(ruleConfig) === 2; - }, - - /** - * Checks whether a given config has valid severity or not. - * @param {number|string|Array} ruleConfig The configuration for an individual rule. - * @returns {boolean} `true` if the configuration has valid severity. - */ - isValidSeverity(ruleConfig) { - let severity = Array.isArray(ruleConfig) ? ruleConfig[0] : ruleConfig; - - if (typeof severity === "string") { - severity = severity.toLowerCase(); - } - return VALID_SEVERITIES.indexOf(severity) !== -1; - }, - - /** - * Checks whether every rule of a given config has valid severity or not. - * @param {Object} config The configuration for rules. - * @returns {boolean} `true` if the configuration has valid severity. - */ - isEverySeverityValid(config) { - return Object.keys(config).every(ruleId => this.isValidSeverity(config[ruleId])); - }, - - /** - * Normalizes a value for a global in a config - * @param {(boolean|string|null)} configuredValue The value given for a global in configuration or in - * a global directive comment - * @returns {("readable"|"writeable"|"off")} The value normalized as a string - * @throws Error if global value is invalid - */ - normalizeConfigGlobal(configuredValue) { - switch (configuredValue) { - case "off": - return "off"; - - case true: - case "true": - case "writeable": - case "writable": - return "writable"; - - case null: - case false: - case "false": - case "readable": - case "readonly": - return "readonly"; - - default: - throw new Error(`'${configuredValue}' is not a valid configuration for a global (use 'readonly', 'writable', or 'off')`); - } - } -}; -}); - -/** - * @fileoverview Defines a schema for configs. - * @author Sylvan Mably - */ - -const baseConfigProperties$1 = { - $schema: { type: "string" }, - env: { type: "object" }, - extends: { $ref: "#/definitions/stringOrStrings" }, - globals: { type: "object" }, - overrides: { - type: "array", - items: { $ref: "#/definitions/overrideConfig" }, - additionalItems: false - }, - parser: { type: ["string", "null"] }, - parserOptions: { type: "object" }, - plugins: { type: "array" }, - processor: { type: "string" }, - rules: { type: "object" }, - settings: { type: "object" }, - noInlineConfig: { type: "boolean" }, - reportUnusedDisableDirectives: { type: "boolean" }, - - ecmaFeatures: { type: "object" } // deprecated; logs a warning when used -}; - -const configSchema$1 = { - definitions: { - stringOrStrings: { - oneOf: [ - { type: "string" }, - { - type: "array", - items: { type: "string" }, - additionalItems: false - } - ] - }, - stringOrStringsRequired: { - oneOf: [ - { type: "string" }, - { - type: "array", - items: { type: "string" }, - additionalItems: false, - minItems: 1 - } - ] - }, - - // Config at top-level. - objectConfig: { - type: "object", - properties: { - root: { type: "boolean" }, - ignorePatterns: { $ref: "#/definitions/stringOrStrings" }, - ...baseConfigProperties$1 - }, - additionalProperties: false - }, - - // Config in `overrides`. - overrideConfig: { - type: "object", - properties: { - excludedFiles: { $ref: "#/definitions/stringOrStrings" }, - files: { $ref: "#/definitions/stringOrStringsRequired" }, - ...baseConfigProperties$1 - }, - required: ["files"], - additionalProperties: false - } - }, - - $ref: "#/definitions/objectConfig" -}; - -var configSchema_1$1 = configSchema$1; - -/** - * @fileoverview Provide the function that emits deprecation warnings. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Private -//------------------------------------------------------------------------------ - -// Defitions for deprecation warnings. -const deprecationWarningMessages$1 = { - ESLINT_LEGACY_ECMAFEATURES: - "The 'ecmaFeatures' config file property is deprecated and has no effect.", - ESLINT_PERSONAL_CONFIG_LOAD: - "'~/.eslintrc.*' config files have been deprecated. " + - "Please use a config file per project or the '--config' option.", - ESLINT_PERSONAL_CONFIG_SUPPRESS: - "'~/.eslintrc.*' config files have been deprecated. " + - "Please remove it or add 'root:true' to the config files in your " + - "projects in order to avoid loading '~/.eslintrc.*' accidentally." -}; - -const sourceFileErrorCache = new Set(); - -/** - * Emits a deprecation warning containing a given filepath. A new deprecation warning is emitted - * for each unique file path, but repeated invocations with the same file path have no effect. - * No warnings are emitted if the `--no-deprecation` or `--no-warnings` Node runtime flags are active. - * @param {string} source The name of the configuration source to report the warning for. - * @param {string} errorCode The warning message to show. - * @returns {void} - */ -function emitDeprecationWarning$3(source, errorCode) { - const cacheKey = JSON.stringify({ source, errorCode }); - - if (sourceFileErrorCache.has(cacheKey)) { - return; - } - sourceFileErrorCache.add(cacheKey); - - const rel = path__default['default'].relative(process.cwd(), source); - const message = deprecationWarningMessages$1[errorCode]; - - process.emitWarning( - `${message} (found in "${rel}")`, - "DeprecationWarning", - errorCode - ); -} - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -var deprecationWarnings$1 = { - emitDeprecationWarning: emitDeprecationWarning$3 -}; - -var id = "http://json-schema.org/draft-04/schema#"; -var $schema = "http://json-schema.org/draft-04/schema#"; -var description = "Core schema meta-schema"; -var definitions = { - schemaArray: { - type: "array", - minItems: 1, - items: { - $ref: "#" - } - }, - positiveInteger: { - type: "integer", - minimum: 0 - }, - positiveIntegerDefault0: { - allOf: [ - { - $ref: "#/definitions/positiveInteger" - }, - { - "default": 0 - } - ] - }, - simpleTypes: { - "enum": [ - "array", - "boolean", - "integer", - "null", - "number", - "object", - "string" - ] - }, - stringArray: { - type: "array", - items: { - type: "string" - }, - minItems: 1, - uniqueItems: true - } -}; -var type = "object"; -var properties = { - id: { - type: "string" - }, - $schema: { - type: "string" - }, - title: { - type: "string" - }, - description: { - type: "string" - }, - "default": { - }, - multipleOf: { - type: "number", - minimum: 0, - exclusiveMinimum: true - }, - maximum: { - type: "number" - }, - exclusiveMaximum: { - type: "boolean", - "default": false - }, - minimum: { - type: "number" - }, - exclusiveMinimum: { - type: "boolean", - "default": false - }, - maxLength: { - $ref: "#/definitions/positiveInteger" - }, - minLength: { - $ref: "#/definitions/positiveIntegerDefault0" - }, - pattern: { - type: "string", - format: "regex" - }, - additionalItems: { - anyOf: [ - { - type: "boolean" - }, - { - $ref: "#" - } - ], - "default": { - } - }, - items: { - anyOf: [ - { - $ref: "#" - }, - { - $ref: "#/definitions/schemaArray" - } - ], - "default": { - } - }, - maxItems: { - $ref: "#/definitions/positiveInteger" - }, - minItems: { - $ref: "#/definitions/positiveIntegerDefault0" - }, - uniqueItems: { - type: "boolean", - "default": false - }, - maxProperties: { - $ref: "#/definitions/positiveInteger" - }, - minProperties: { - $ref: "#/definitions/positiveIntegerDefault0" - }, - required: { - $ref: "#/definitions/stringArray" - }, - additionalProperties: { - anyOf: [ - { - type: "boolean" - }, - { - $ref: "#" - } - ], - "default": { - } - }, - definitions: { - type: "object", - additionalProperties: { - $ref: "#" - }, - "default": { - } - }, - properties: { - type: "object", - additionalProperties: { - $ref: "#" - }, - "default": { - } - }, - patternProperties: { - type: "object", - additionalProperties: { - $ref: "#" - }, - "default": { - } - }, - dependencies: { - type: "object", - additionalProperties: { - anyOf: [ - { - $ref: "#" - }, - { - $ref: "#/definitions/stringArray" - } - ] - } - }, - "enum": { - type: "array", - minItems: 1, - uniqueItems: true - }, - type: { - anyOf: [ - { - $ref: "#/definitions/simpleTypes" - }, - { - type: "array", - items: { - $ref: "#/definitions/simpleTypes" - }, - minItems: 1, - uniqueItems: true - } - ] - }, - format: { - type: "string" - }, - allOf: { - $ref: "#/definitions/schemaArray" - }, - anyOf: { - $ref: "#/definitions/schemaArray" - }, - oneOf: { - $ref: "#/definitions/schemaArray" - }, - not: { - $ref: "#" - } -}; -var dependencies = { - exclusiveMaximum: [ - "maximum" - ], - exclusiveMinimum: [ - "minimum" - ] -}; -var metaSchema = { - id: id, - $schema: $schema, - description: description, - definitions: definitions, - type: type, - properties: properties, - dependencies: dependencies, - "default": { -} -}; - -/** - * @fileoverview The instance of Ajv validator. - * @author Evgeny Poberezkin - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -var ajv$4 = (additionalOptions = {}) => { - const ajv = new Ajv__default['default']({ - meta: false, - useDefaults: true, - validateSchema: false, - missingRefs: "ignore", - verbose: true, - schemaId: "auto", - ...additionalOptions - }); - - ajv.addMetaSchema(metaSchema); - // eslint-disable-next-line no-underscore-dangle - ajv._opts.defaultMeta = metaSchema.id; - - return ajv; -}; - -/** - * @fileoverview Validates configs. - * @author Brandon Mills - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -const - { emitDeprecationWarning: emitDeprecationWarning$2 } = deprecationWarnings$1; - -const ajv$3 = ajv$4(); -const ruleValidators$1 = new WeakMap(); -const noop$2 = Function.prototype; - -//------------------------------------------------------------------------------ -// Private -//------------------------------------------------------------------------------ -let validateSchema$1; -const severityMap$1 = { - error: 2, - warn: 1, - off: 0 -}; - -const validated$1 = new WeakSet(); - -//----------------------------------------------------------------------------- -// Exports -//----------------------------------------------------------------------------- - -var configValidator$1 = class ConfigValidator { - constructor({ builtInRules = new Map() } = {}) { - this.builtInRules = builtInRules; - } - - /** - * Gets a complete options schema for a rule. - * @param {{create: Function, schema: (Array|null)}} rule A new-style rule object - * @returns {Object} JSON Schema for the rule's options. - */ - getRuleOptionsSchema(rule) { - if (!rule) { - return null; - } - - const schema = rule.schema || rule.meta && rule.meta.schema; - - // Given a tuple of schemas, insert warning level at the beginning - if (Array.isArray(schema)) { - if (schema.length) { - return { - type: "array", - items: schema, - minItems: 0, - maxItems: schema.length - }; - } - return { - type: "array", - minItems: 0, - maxItems: 0 - }; - - } - - // Given a full schema, leave it alone - return schema || null; - } - - /** - * Validates a rule's severity and returns the severity value. Throws an error if the severity is invalid. - * @param {options} options The given options for the rule. - * @returns {number|string} The rule's severity value - */ - validateRuleSeverity(options) { - const severity = Array.isArray(options) ? options[0] : options; - const normSeverity = typeof severity === "string" ? severityMap$1[severity.toLowerCase()] : severity; - - if (normSeverity === 0 || normSeverity === 1 || normSeverity === 2) { - return normSeverity; - } - - throw new Error(`\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '${util__default['default'].inspect(severity).replace(/'/gu, "\"").replace(/\n/gu, "")}').\n`); - - } - - /** - * Validates the non-severity options passed to a rule, based on its schema. - * @param {{create: Function}} rule The rule to validate - * @param {Array} localOptions The options for the rule, excluding severity - * @returns {void} - */ - validateRuleSchema(rule, localOptions) { - if (!ruleValidators$1.has(rule)) { - const schema = this.getRuleOptionsSchema(rule); - - if (schema) { - ruleValidators$1.set(rule, ajv$3.compile(schema)); - } - } - - const validateRule = ruleValidators$1.get(rule); - - if (validateRule) { - validateRule(localOptions); - if (validateRule.errors) { - throw new Error(validateRule.errors.map( - error => `\tValue ${JSON.stringify(error.data)} ${error.message}.\n` - ).join("")); - } - } - } - - /** - * Validates a rule's options against its schema. - * @param {{create: Function}|null} rule The rule that the config is being validated for - * @param {string} ruleId The rule's unique name. - * @param {Array|number} options The given options for the rule. - * @param {string|null} source The name of the configuration source to report in any errors. If null or undefined, - * no source is prepended to the message. - * @returns {void} - */ - validateRuleOptions(rule, ruleId, options, source = null) { - try { - const severity = this.validateRuleSeverity(options); - - if (severity !== 0) { - this.validateRuleSchema(rule, Array.isArray(options) ? options.slice(1) : []); - } - } catch (err) { - const enhancedMessage = `Configuration for rule "${ruleId}" is invalid:\n${err.message}`; - - if (typeof source === "string") { - throw new Error(`${source}:\n\t${enhancedMessage}`); - } else { - throw new Error(enhancedMessage); - } - } - } - - /** - * Validates an environment object - * @param {Object} environment The environment config object to validate. - * @param {string} source The name of the configuration source to report in any errors. - * @param {function(envId:string): Object} [getAdditionalEnv] A map from strings to loaded environments. - * @returns {void} - */ - validateEnvironment( - environment, - source, - getAdditionalEnv = noop$2 - ) { - - // not having an environment is ok - if (!environment) { - return; - } - - Object.keys(environment).forEach(id => { - const env = getAdditionalEnv(id) || environments.get(id) || null; - - if (!env) { - const message = `${source}:\n\tEnvironment key "${id}" is unknown\n`; - - throw new Error(message); - } - }); - } - - /** - * Validates a rules config object - * @param {Object} rulesConfig The rules config object to validate. - * @param {string} source The name of the configuration source to report in any errors. - * @param {function(ruleId:string): Object} getAdditionalRule A map from strings to loaded rules - * @returns {void} - */ - validateRules( - rulesConfig, - source, - getAdditionalRule = noop$2 - ) { - if (!rulesConfig) { - return; - } - - Object.keys(rulesConfig).forEach(id => { - const rule = getAdditionalRule(id) || this.builtInRules.get(id) || null; - - this.validateRuleOptions(rule, id, rulesConfig[id], source); - }); - } - - /** - * Validates a `globals` section of a config file - * @param {Object} globalsConfig The `globals` section - * @param {string|null} source The name of the configuration source to report in the event of an error. - * @returns {void} - */ - validateGlobals(globalsConfig, source = null) { - if (!globalsConfig) { - return; - } - - Object.entries(globalsConfig) - .forEach(([configuredGlobal, configuredValue]) => { - try { - configOps.normalizeConfigGlobal(configuredValue); - } catch (err) { - throw new Error(`ESLint configuration of global '${configuredGlobal}' in ${source} is invalid:\n${err.message}`); - } - }); - } - - /** - * Validate `processor` configuration. - * @param {string|undefined} processorName The processor name. - * @param {string} source The name of config file. - * @param {function(id:string): Processor} getProcessor The getter of defined processors. - * @returns {void} - */ - validateProcessor(processorName, source, getProcessor) { - if (processorName && !getProcessor(processorName)) { - throw new Error(`ESLint configuration of processor in '${source}' is invalid: '${processorName}' was not found.`); - } - } - - /** - * Formats an array of schema validation errors. - * @param {Array} errors An array of error messages to format. - * @returns {string} Formatted error message - */ - formatErrors(errors) { - return errors.map(error => { - if (error.keyword === "additionalProperties") { - const formattedPropertyPath = error.dataPath.length ? `${error.dataPath.slice(1)}.${error.params.additionalProperty}` : error.params.additionalProperty; - - return `Unexpected top-level property "${formattedPropertyPath}"`; - } - if (error.keyword === "type") { - const formattedField = error.dataPath.slice(1); - const formattedExpectedType = Array.isArray(error.schema) ? error.schema.join("/") : error.schema; - const formattedValue = JSON.stringify(error.data); - - return `Property "${formattedField}" is the wrong type (expected ${formattedExpectedType} but got \`${formattedValue}\`)`; - } - - const field = error.dataPath[0] === "." ? error.dataPath.slice(1) : error.dataPath; - - return `"${field}" ${error.message}. Value: ${JSON.stringify(error.data)}`; - }).map(message => `\t- ${message}.\n`).join(""); - } - - /** - * Validates the top level properties of the config object. - * @param {Object} config The config object to validate. - * @param {string} source The name of the configuration source to report in any errors. - * @returns {void} - */ - validateConfigSchema(config, source = null) { - validateSchema$1 = validateSchema$1 || ajv$3.compile(configSchema_1$1); - - if (!validateSchema$1(config)) { - throw new Error(`ESLint configuration in ${source} is invalid:\n${this.formatErrors(validateSchema$1.errors)}`); - } - - if (Object.hasOwnProperty.call(config, "ecmaFeatures")) { - emitDeprecationWarning$2(source, "ESLINT_LEGACY_ECMAFEATURES"); - } - } - - /** - * Validates an entire config object. - * @param {Object} config The config object to validate. - * @param {string} source The name of the configuration source to report in any errors. - * @param {function(ruleId:string): Object} [getAdditionalRule] A map from strings to loaded rules. - * @param {function(envId:string): Object} [getAdditionalEnv] A map from strings to loaded envs. - * @returns {void} - */ - validate(config, source, getAdditionalRule, getAdditionalEnv) { - this.validateConfigSchema(config, source); - this.validateRules(config.rules, source, getAdditionalRule); - this.validateEnvironment(config.env, source, getAdditionalEnv); - this.validateGlobals(config.globals, source); - - for (const override of config.overrides || []) { - this.validateRules(override.rules, source, getAdditionalRule); - this.validateEnvironment(override.env, source, getAdditionalEnv); - this.validateGlobals(config.globals, source); - } - } - - /** - * Validate config array object. - * @param {ConfigArray} configArray The config array to validate. - * @returns {void} - */ - validateConfigArray(configArray) { - const getPluginEnv = Map.prototype.get.bind(configArray.pluginEnvironments); - const getPluginProcessor = Map.prototype.get.bind(configArray.pluginProcessors); - const getPluginRule = Map.prototype.get.bind(configArray.pluginRules); - - // Validate. - for (const element of configArray) { - if (validated$1.has(element)) { - continue; - } - validated$1.add(element); - - this.validateEnvironment(element.env, element.name, getPluginEnv); - this.validateGlobals(element.globals, element.name); - this.validateProcessor(element.processor, element.name, getPluginProcessor); - this.validateRules(element.rules, element.name, getPluginRule); - } - } - -}; - -/** - * @fileoverview Traverser to traverse AST trees. - * @author Nicholas C. Zakas - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - -const debug$7 = require$$0__default['default']("eslint:traverser"); - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Do nothing. - * @returns {void} - */ -function noop$1() { - - // do nothing. -} - -/** - * Check whether the given value is an ASTNode or not. - * @param {any} x The value to check. - * @returns {boolean} `true` if the value is an ASTNode. - */ -function isNode(x) { - return x !== null && typeof x === "object" && typeof x.type === "string"; -} - -/** - * Get the visitor keys of a given node. - * @param {Object} visitorKeys The map of visitor keys. - * @param {ASTNode} node The node to get their visitor keys. - * @returns {string[]} The visitor keys of the node. - */ -function getVisitorKeys(visitorKeys, node) { - let keys = visitorKeys[node.type]; - - if (!keys) { - keys = vk__default['default'].getKeys(node); - debug$7("Unknown node type \"%s\": Estimated visitor keys %j", node.type, keys); - } - - return keys; -} - -/** - * The traverser class to traverse AST trees. - */ -class Traverser { - constructor() { - this._current = null; - this._parents = []; - this._skipped = false; - this._broken = false; - this._visitorKeys = null; - this._enter = null; - this._leave = null; - } - - // eslint-disable-next-line jsdoc/require-description - /** - * @returns {ASTNode} The current node. - */ - current() { - return this._current; - } - - // eslint-disable-next-line jsdoc/require-description - /** - * @returns {ASTNode[]} The ancestor nodes. - */ - parents() { - return this._parents.slice(0); - } - - /** - * Break the current traversal. - * @returns {void} - */ - break() { - this._broken = true; - } - - /** - * Skip child nodes for the current traversal. - * @returns {void} - */ - skip() { - this._skipped = true; - } - - /** - * Traverse the given AST tree. - * @param {ASTNode} node The root node to traverse. - * @param {Object} options The option object. - * @param {Object} [options.visitorKeys=DEFAULT_VISITOR_KEYS] The keys of each node types to traverse child nodes. Default is `./default-visitor-keys.json`. - * @param {Function} [options.enter=noop] The callback function which is called on entering each node. - * @param {Function} [options.leave=noop] The callback function which is called on leaving each node. - * @returns {void} - */ - traverse(node, options) { - this._current = null; - this._parents = []; - this._skipped = false; - this._broken = false; - this._visitorKeys = options.visitorKeys || vk__default['default'].KEYS; - this._enter = options.enter || noop$1; - this._leave = options.leave || noop$1; - this._traverse(node, null); - } - - /** - * Traverse the given AST tree recursively. - * @param {ASTNode} node The current node. - * @param {ASTNode|null} parent The parent node. - * @returns {void} - * @private - */ - _traverse(node, parent) { - if (!isNode(node)) { - return; - } - - this._current = node; - this._skipped = false; - this._enter(node, parent); - - if (!this._skipped && !this._broken) { - const keys = getVisitorKeys(this._visitorKeys, node); - - if (keys.length >= 1) { - this._parents.push(node); - for (let i = 0; i < keys.length && !this._broken; ++i) { - const child = node[keys[i]]; - - if (Array.isArray(child)) { - for (let j = 0; j < child.length && !this._broken; ++j) { - this._traverse(child[j], node); - } - } else { - this._traverse(child, node); - } - } - this._parents.pop(); - } - } - - if (!this._broken) { - this._leave(node, parent); - } - - this._current = parent; - } - - /** - * Calculates the keys to use for traversal. - * @param {ASTNode} node The node to read keys from. - * @returns {string[]} An array of keys to visit on the node. - * @private - */ - static getKeys(node) { - return vk__default['default'].getKeys(node); - } - - /** - * Traverse the given AST tree. - * @param {ASTNode} node The root node to traverse. - * @param {Object} options The option object. - * @param {Object} [options.visitorKeys=DEFAULT_VISITOR_KEYS] The keys of each node types to traverse child nodes. Default is `./default-visitor-keys.json`. - * @param {Function} [options.enter=noop] The callback function which is called on entering each node. - * @param {Function} [options.leave=noop] The callback function which is called on leaving each node. - * @returns {void} - */ - static traverse(node, options) { - new Traverser().traverse(node, options); - } - - /** - * The default visitor keys. - * @type {Object} - */ - static get DEFAULT_VISITOR_KEYS() { - return vk__default['default'].KEYS; - } -} - -var traverser = Traverser; - -/** - * @fileoverview Define the abstract class about cursors which iterate tokens. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Exports -//------------------------------------------------------------------------------ - -/** - * The abstract class about cursors which iterate tokens. - * - * This class has 2 abstract methods. - * - * - `current: Token | Comment | null` ... The current token. - * - `moveNext(): boolean` ... Moves this cursor to the next token. If the next token didn't exist, it returns `false`. - * - * This is similar to ES2015 Iterators. - * However, Iterators were slow (at 2017-01), so I created this class as similar to C# IEnumerable. - * - * There are the following known sub classes. - * - * - ForwardTokenCursor .......... The cursor which iterates tokens only. - * - BackwardTokenCursor ......... The cursor which iterates tokens only in reverse. - * - ForwardTokenCommentCursor ... The cursor which iterates tokens and comments. - * - BackwardTokenCommentCursor .. The cursor which iterates tokens and comments in reverse. - * - DecorativeCursor - * - FilterCursor ............ The cursor which ignores the specified tokens. - * - SkipCursor .............. The cursor which ignores the first few tokens. - * - LimitCursor ............. The cursor which limits the count of tokens. - * - */ -var cursor = class Cursor { - - /** - * Initializes this cursor. - */ - constructor() { - this.current = null; - } - - /** - * Gets the first token. - * This consumes this cursor. - * @returns {Token|Comment} The first token or null. - */ - getOneToken() { - return this.moveNext() ? this.current : null; - } - - /** - * Gets the first tokens. - * This consumes this cursor. - * @returns {(Token|Comment)[]} All tokens. - */ - getAllTokens() { - const tokens = []; - - while (this.moveNext()) { - tokens.push(this.current); - } - - return tokens; - } - - /** - * Moves this cursor to the next token. - * @returns {boolean} `true` if the next token exists. - * @abstract - */ - /* istanbul ignore next */ - moveNext() { // eslint-disable-line class-methods-use-this - throw new Error("Not implemented."); - } -}; - -/** - * @fileoverview Define utility functions for token store. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Gets `token.range[0]` from the given token. - * @param {Node|Token|Comment} token The token to get. - * @returns {number} The start location. - * @private - */ -function getStartLocation(token) { - return token.range[0]; -} - -//------------------------------------------------------------------------------ -// Exports -//------------------------------------------------------------------------------ - -/** - * Binary-searches the index of the first token which is after the given location. - * If it was not found, this returns `tokens.length`. - * @param {(Token|Comment)[]} tokens It searches the token in this list. - * @param {number} location The location to search. - * @returns {number} The found index or `tokens.length`. - */ -var search = function search(tokens, location) { - return lodash__default['default'].sortedIndexBy( - tokens, - { range: [location] }, - getStartLocation - ); -}; - -/** - * Gets the index of the `startLoc` in `tokens`. - * `startLoc` can be the value of `node.range[1]`, so this checks about `startLoc - 1` as well. - * @param {(Token|Comment)[]} tokens The tokens to find an index. - * @param {Object} indexMap The map from locations to indices. - * @param {number} startLoc The location to get an index. - * @returns {number} The index. - */ -var getFirstIndex = function getFirstIndex(tokens, indexMap, startLoc) { - if (startLoc in indexMap) { - return indexMap[startLoc]; - } - if ((startLoc - 1) in indexMap) { - const index = indexMap[startLoc - 1]; - const token = (index >= 0 && index < tokens.length) ? tokens[index] : null; - - /* - * For the map of "comment's location -> token's index", it points the next token of a comment. - * In that case, +1 is unnecessary. - */ - if (token && token.range[0] >= startLoc) { - return index; - } - return index + 1; - } - return 0; -}; - -/** - * Gets the index of the `endLoc` in `tokens`. - * The information of end locations are recorded at `endLoc - 1` in `indexMap`, so this checks about `endLoc - 1` as well. - * @param {(Token|Comment)[]} tokens The tokens to find an index. - * @param {Object} indexMap The map from locations to indices. - * @param {number} endLoc The location to get an index. - * @returns {number} The index. - */ -var getLastIndex = function getLastIndex(tokens, indexMap, endLoc) { - if (endLoc in indexMap) { - return indexMap[endLoc] - 1; - } - if ((endLoc - 1) in indexMap) { - const index = indexMap[endLoc - 1]; - const token = (index >= 0 && index < tokens.length) ? tokens[index] : null; - - /* - * For the map of "comment's location -> token's index", it points the next token of a comment. - * In that case, -1 is necessary. - */ - if (token && token.range[1] > endLoc) { - return index - 1; - } - return index; - } - return tokens.length - 1; -}; - -var utils = { - search: search, - getFirstIndex: getFirstIndex, - getLastIndex: getLastIndex -}; - -/** - * @fileoverview Define the cursor which iterates tokens and comments in reverse. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//------------------------------------------------------------------------------ -// Exports -//------------------------------------------------------------------------------ - -/** - * The cursor which iterates tokens and comments in reverse. - */ -var backwardTokenCommentCursor = class BackwardTokenCommentCursor extends cursor { - - /** - * Initializes this cursor. - * @param {Token[]} tokens The array of tokens. - * @param {Comment[]} comments The array of comments. - * @param {Object} indexMap The map from locations to indices in `tokens`. - * @param {number} startLoc The start location of the iteration range. - * @param {number} endLoc The end location of the iteration range. - */ - constructor(tokens, comments, indexMap, startLoc, endLoc) { - super(); - this.tokens = tokens; - this.comments = comments; - this.tokenIndex = utils.getLastIndex(tokens, indexMap, endLoc); - this.commentIndex = utils.search(comments, endLoc) - 1; - this.border = startLoc; - } - - /** @inheritdoc */ - moveNext() { - const token = (this.tokenIndex >= 0) ? this.tokens[this.tokenIndex] : null; - const comment = (this.commentIndex >= 0) ? this.comments[this.commentIndex] : null; - - if (token && (!comment || token.range[1] > comment.range[1])) { - this.current = token; - this.tokenIndex -= 1; - } else if (comment) { - this.current = comment; - this.commentIndex -= 1; - } else { - this.current = null; - } - - return Boolean(this.current) && (this.border === -1 || this.current.range[0] >= this.border); - } -}; - -/** - * @fileoverview Define the cursor which iterates tokens only in reverse. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//------------------------------------------------------------------------------ -// Exports -//------------------------------------------------------------------------------ - -/** - * The cursor which iterates tokens only in reverse. - */ -var backwardTokenCursor = class BackwardTokenCursor extends cursor { - - /** - * Initializes this cursor. - * @param {Token[]} tokens The array of tokens. - * @param {Comment[]} comments The array of comments. - * @param {Object} indexMap The map from locations to indices in `tokens`. - * @param {number} startLoc The start location of the iteration range. - * @param {number} endLoc The end location of the iteration range. - */ - constructor(tokens, comments, indexMap, startLoc, endLoc) { - super(); - this.tokens = tokens; - this.index = utils.getLastIndex(tokens, indexMap, endLoc); - this.indexEnd = utils.getFirstIndex(tokens, indexMap, startLoc); - } - - /** @inheritdoc */ - moveNext() { - if (this.index >= this.indexEnd) { - this.current = this.tokens[this.index]; - this.index -= 1; - return true; - } - return false; - } - - /* - * - * Shorthand for performance. - * - */ - - /** @inheritdoc */ - getOneToken() { - return (this.index >= this.indexEnd) ? this.tokens[this.index] : null; - } -}; - -/** - * @fileoverview Define the abstract class about cursors which manipulate another cursor. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Exports -//------------------------------------------------------------------------------ - -/** - * The abstract class about cursors which manipulate another cursor. - */ -var decorativeCursor = class DecorativeCursor extends cursor { - - /** - * Initializes this cursor. - * @param {Cursor} cursor The cursor to be decorated. - */ - constructor(cursor) { - super(); - this.cursor = cursor; - } - - /** @inheritdoc */ - moveNext() { - const retv = this.cursor.moveNext(); - - this.current = this.cursor.current; - - return retv; - } -}; - -/** - * @fileoverview Define the cursor which ignores specified tokens. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Exports -//------------------------------------------------------------------------------ - -/** - * The decorative cursor which ignores specified tokens. - */ -var filterCursor = class FilterCursor extends decorativeCursor { - - /** - * Initializes this cursor. - * @param {Cursor} cursor The cursor to be decorated. - * @param {Function} predicate The predicate function to decide tokens this cursor iterates. - */ - constructor(cursor, predicate) { - super(cursor); - this.predicate = predicate; - } - - /** @inheritdoc */ - moveNext() { - const predicate = this.predicate; - - while (super.moveNext()) { - if (predicate(this.current)) { - return true; - } - } - return false; - } -}; - -/** - * @fileoverview Define the cursor which iterates tokens and comments. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//------------------------------------------------------------------------------ -// Exports -//------------------------------------------------------------------------------ - -/** - * The cursor which iterates tokens and comments. - */ -var forwardTokenCommentCursor = class ForwardTokenCommentCursor extends cursor { - - /** - * Initializes this cursor. - * @param {Token[]} tokens The array of tokens. - * @param {Comment[]} comments The array of comments. - * @param {Object} indexMap The map from locations to indices in `tokens`. - * @param {number} startLoc The start location of the iteration range. - * @param {number} endLoc The end location of the iteration range. - */ - constructor(tokens, comments, indexMap, startLoc, endLoc) { - super(); - this.tokens = tokens; - this.comments = comments; - this.tokenIndex = utils.getFirstIndex(tokens, indexMap, startLoc); - this.commentIndex = utils.search(comments, startLoc); - this.border = endLoc; - } - - /** @inheritdoc */ - moveNext() { - const token = (this.tokenIndex < this.tokens.length) ? this.tokens[this.tokenIndex] : null; - const comment = (this.commentIndex < this.comments.length) ? this.comments[this.commentIndex] : null; - - if (token && (!comment || token.range[0] < comment.range[0])) { - this.current = token; - this.tokenIndex += 1; - } else if (comment) { - this.current = comment; - this.commentIndex += 1; - } else { - this.current = null; - } - - return Boolean(this.current) && (this.border === -1 || this.current.range[1] <= this.border); - } -}; - -/** - * @fileoverview Define the cursor which iterates tokens only. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//------------------------------------------------------------------------------ -// Exports -//------------------------------------------------------------------------------ - -/** - * The cursor which iterates tokens only. - */ -var forwardTokenCursor = class ForwardTokenCursor extends cursor { - - /** - * Initializes this cursor. - * @param {Token[]} tokens The array of tokens. - * @param {Comment[]} comments The array of comments. - * @param {Object} indexMap The map from locations to indices in `tokens`. - * @param {number} startLoc The start location of the iteration range. - * @param {number} endLoc The end location of the iteration range. - */ - constructor(tokens, comments, indexMap, startLoc, endLoc) { - super(); - this.tokens = tokens; - this.index = utils.getFirstIndex(tokens, indexMap, startLoc); - this.indexEnd = utils.getLastIndex(tokens, indexMap, endLoc); - } - - /** @inheritdoc */ - moveNext() { - if (this.index <= this.indexEnd) { - this.current = this.tokens[this.index]; - this.index += 1; - return true; - } - return false; - } - - /* - * - * Shorthand for performance. - * - */ - - /** @inheritdoc */ - getOneToken() { - return (this.index <= this.indexEnd) ? this.tokens[this.index] : null; - } - - /** @inheritdoc */ - getAllTokens() { - return this.tokens.slice(this.index, this.indexEnd + 1); - } -}; - -/** - * @fileoverview Define the cursor which limits the number of tokens. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Exports -//------------------------------------------------------------------------------ - -/** - * The decorative cursor which limits the number of tokens. - */ -var limitCursor = class LimitCursor extends decorativeCursor { - - /** - * Initializes this cursor. - * @param {Cursor} cursor The cursor to be decorated. - * @param {number} count The count of tokens this cursor iterates. - */ - constructor(cursor, count) { - super(cursor); - this.count = count; - } - - /** @inheritdoc */ - moveNext() { - if (this.count > 0) { - this.count -= 1; - return super.moveNext(); - } - return false; - } -}; - -/** - * @fileoverview Define the cursor which ignores the first few tokens. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Exports -//------------------------------------------------------------------------------ - -/** - * The decorative cursor which ignores the first few tokens. - */ -var skipCursor = class SkipCursor extends decorativeCursor { - - /** - * Initializes this cursor. - * @param {Cursor} cursor The cursor to be decorated. - * @param {number} count The count of tokens this cursor skips. - */ - constructor(cursor, count) { - super(cursor); - this.count = count; - } - - /** @inheritdoc */ - moveNext() { - while (this.count > 0) { - this.count -= 1; - if (!super.moveNext()) { - return false; - } - } - return super.moveNext(); - } -}; - -/** - * @fileoverview Define 2 token factories; forward and backward. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - - - - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * The cursor factory. - * @private - */ -class CursorFactory { - - /** - * Initializes this cursor. - * @param {Function} TokenCursor The class of the cursor which iterates tokens only. - * @param {Function} TokenCommentCursor The class of the cursor which iterates the mix of tokens and comments. - */ - constructor(TokenCursor, TokenCommentCursor) { - this.TokenCursor = TokenCursor; - this.TokenCommentCursor = TokenCommentCursor; - } - - /** - * Creates a base cursor instance that can be decorated by createCursor. - * @param {Token[]} tokens The array of tokens. - * @param {Comment[]} comments The array of comments. - * @param {Object} indexMap The map from locations to indices in `tokens`. - * @param {number} startLoc The start location of the iteration range. - * @param {number} endLoc The end location of the iteration range. - * @param {boolean} includeComments The flag to iterate comments as well. - * @returns {Cursor} The created base cursor. - */ - createBaseCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments) { - const Cursor = includeComments ? this.TokenCommentCursor : this.TokenCursor; - - return new Cursor(tokens, comments, indexMap, startLoc, endLoc); - } - - /** - * Creates a cursor that iterates tokens with normalized options. - * @param {Token[]} tokens The array of tokens. - * @param {Comment[]} comments The array of comments. - * @param {Object} indexMap The map from locations to indices in `tokens`. - * @param {number} startLoc The start location of the iteration range. - * @param {number} endLoc The end location of the iteration range. - * @param {boolean} includeComments The flag to iterate comments as well. - * @param {Function|null} filter The predicate function to choose tokens. - * @param {number} skip The count of tokens the cursor skips. - * @param {number} count The maximum count of tokens the cursor iterates. Zero is no iteration for backward compatibility. - * @returns {Cursor} The created cursor. - */ - createCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments, filter, skip, count) { - let cursor = this.createBaseCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments); - - if (filter) { - cursor = new filterCursor(cursor, filter); - } - if (skip >= 1) { - cursor = new skipCursor(cursor, skip); - } - if (count >= 0) { - cursor = new limitCursor(cursor, count); - } - - return cursor; - } -} - -//------------------------------------------------------------------------------ -// Exports -//------------------------------------------------------------------------------ - -var forward = new CursorFactory(forwardTokenCursor, forwardTokenCommentCursor); -var backward = new CursorFactory(backwardTokenCursor, backwardTokenCommentCursor); - -var cursors = { - forward: forward, - backward: backward -}; - -/** - * @fileoverview Define the cursor which iterates tokens only, with inflated range. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Exports -//------------------------------------------------------------------------------ - -/** - * The cursor which iterates tokens only, with inflated range. - * This is for the backward compatibility of padding options. - */ -var paddedTokenCursor = class PaddedTokenCursor extends forwardTokenCursor { - - /** - * Initializes this cursor. - * @param {Token[]} tokens The array of tokens. - * @param {Comment[]} comments The array of comments. - * @param {Object} indexMap The map from locations to indices in `tokens`. - * @param {number} startLoc The start location of the iteration range. - * @param {number} endLoc The end location of the iteration range. - * @param {number} beforeCount The number of tokens this cursor iterates before start. - * @param {number} afterCount The number of tokens this cursor iterates after end. - */ - constructor(tokens, comments, indexMap, startLoc, endLoc, beforeCount, afterCount) { - super(tokens, comments, indexMap, startLoc, endLoc); - this.index = Math.max(0, this.index - beforeCount); - this.indexEnd = Math.min(tokens.length - 1, this.indexEnd + afterCount); - } -}; - -/** - * @fileoverview Object to handle access and retrieval of tokens. - * @author Brandon Mills - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - -const { isCommentToken: isCommentToken$2 } = require$$0__default$1['default']; - - - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const TOKENS = Symbol("tokens"); -const COMMENTS = Symbol("comments"); -const INDEX_MAP = Symbol("indexMap"); - -/** - * Creates the map from locations to indices in `tokens`. - * - * The first/last location of tokens is mapped to the index of the token. - * The first/last location of comments is mapped to the index of the next token of each comment. - * @param {Token[]} tokens The array of tokens. - * @param {Comment[]} comments The array of comments. - * @returns {Object} The map from locations to indices in `tokens`. - * @private - */ -function createIndexMap(tokens, comments) { - const map = Object.create(null); - let tokenIndex = 0; - let commentIndex = 0; - let nextStart = 0; - let range = null; - - while (tokenIndex < tokens.length || commentIndex < comments.length) { - nextStart = (commentIndex < comments.length) ? comments[commentIndex].range[0] : Number.MAX_SAFE_INTEGER; - while (tokenIndex < tokens.length && (range = tokens[tokenIndex].range)[0] < nextStart) { - map[range[0]] = tokenIndex; - map[range[1] - 1] = tokenIndex; - tokenIndex += 1; - } - - nextStart = (tokenIndex < tokens.length) ? tokens[tokenIndex].range[0] : Number.MAX_SAFE_INTEGER; - while (commentIndex < comments.length && (range = comments[commentIndex].range)[0] < nextStart) { - map[range[0]] = tokenIndex; - map[range[1] - 1] = tokenIndex; - commentIndex += 1; - } - } - - return map; -} - -/** - * Creates the cursor iterates tokens with options. - * @param {CursorFactory} factory The cursor factory to initialize cursor. - * @param {Token[]} tokens The array of tokens. - * @param {Comment[]} comments The array of comments. - * @param {Object} indexMap The map from locations to indices in `tokens`. - * @param {number} startLoc The start location of the iteration range. - * @param {number} endLoc The end location of the iteration range. - * @param {number|Function|Object} [opts=0] The option object. If this is a number then it's `opts.skip`. If this is a function then it's `opts.filter`. - * @param {boolean} [opts.includeComments=false] The flag to iterate comments as well. - * @param {Function|null} [opts.filter=null] The predicate function to choose tokens. - * @param {number} [opts.skip=0] The count of tokens the cursor skips. - * @returns {Cursor} The created cursor. - * @private - */ -function createCursorWithSkip(factory, tokens, comments, indexMap, startLoc, endLoc, opts) { - let includeComments = false; - let skip = 0; - let filter = null; - - if (typeof opts === "number") { - skip = opts | 0; - } else if (typeof opts === "function") { - filter = opts; - } else if (opts) { - includeComments = !!opts.includeComments; - skip = opts.skip | 0; - filter = opts.filter || null; - } - assert__default['default'](skip >= 0, "options.skip should be zero or a positive integer."); - assert__default['default'](!filter || typeof filter === "function", "options.filter should be a function."); - - return factory.createCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments, filter, skip, -1); -} - -/** - * Creates the cursor iterates tokens with options. - * @param {CursorFactory} factory The cursor factory to initialize cursor. - * @param {Token[]} tokens The array of tokens. - * @param {Comment[]} comments The array of comments. - * @param {Object} indexMap The map from locations to indices in `tokens`. - * @param {number} startLoc The start location of the iteration range. - * @param {number} endLoc The end location of the iteration range. - * @param {number|Function|Object} [opts=0] The option object. If this is a number then it's `opts.count`. If this is a function then it's `opts.filter`. - * @param {boolean} [opts.includeComments] The flag to iterate comments as well. - * @param {Function|null} [opts.filter=null] The predicate function to choose tokens. - * @param {number} [opts.count=0] The maximum count of tokens the cursor iterates. Zero is no iteration for backward compatibility. - * @returns {Cursor} The created cursor. - * @private - */ -function createCursorWithCount(factory, tokens, comments, indexMap, startLoc, endLoc, opts) { - let includeComments = false; - let count = 0; - let countExists = false; - let filter = null; - - if (typeof opts === "number") { - count = opts | 0; - countExists = true; - } else if (typeof opts === "function") { - filter = opts; - } else if (opts) { - includeComments = !!opts.includeComments; - count = opts.count | 0; - countExists = typeof opts.count === "number"; - filter = opts.filter || null; - } - assert__default['default'](count >= 0, "options.count should be zero or a positive integer."); - assert__default['default'](!filter || typeof filter === "function", "options.filter should be a function."); - - return factory.createCursor(tokens, comments, indexMap, startLoc, endLoc, includeComments, filter, 0, countExists ? count : -1); -} - -/** - * Creates the cursor iterates tokens with options. - * This is overload function of the below. - * @param {Token[]} tokens The array of tokens. - * @param {Comment[]} comments The array of comments. - * @param {Object} indexMap The map from locations to indices in `tokens`. - * @param {number} startLoc The start location of the iteration range. - * @param {number} endLoc The end location of the iteration range. - * @param {Function|Object} opts The option object. If this is a function then it's `opts.filter`. - * @param {boolean} [opts.includeComments] The flag to iterate comments as well. - * @param {Function|null} [opts.filter=null] The predicate function to choose tokens. - * @param {number} [opts.count=0] The maximum count of tokens the cursor iterates. Zero is no iteration for backward compatibility. - * @returns {Cursor} The created cursor. - * @private - */ -/** - * Creates the cursor iterates tokens with options. - * @param {Token[]} tokens The array of tokens. - * @param {Comment[]} comments The array of comments. - * @param {Object} indexMap The map from locations to indices in `tokens`. - * @param {number} startLoc The start location of the iteration range. - * @param {number} endLoc The end location of the iteration range. - * @param {number} [beforeCount=0] The number of tokens before the node to retrieve. - * @param {boolean} [afterCount=0] The number of tokens after the node to retrieve. - * @returns {Cursor} The created cursor. - * @private - */ -function createCursorWithPadding(tokens, comments, indexMap, startLoc, endLoc, beforeCount, afterCount) { - if (typeof beforeCount === "undefined" && typeof afterCount === "undefined") { - return new forwardTokenCursor(tokens, comments, indexMap, startLoc, endLoc); - } - if (typeof beforeCount === "number" || typeof beforeCount === "undefined") { - return new paddedTokenCursor(tokens, comments, indexMap, startLoc, endLoc, beforeCount | 0, afterCount | 0); - } - return createCursorWithCount(cursors.forward, tokens, comments, indexMap, startLoc, endLoc, beforeCount); -} - -/** - * Gets comment tokens that are adjacent to the current cursor position. - * @param {Cursor} cursor A cursor instance. - * @returns {Array} An array of comment tokens adjacent to the current cursor position. - * @private - */ -function getAdjacentCommentTokensFromCursor(cursor) { - const tokens = []; - let currentToken = cursor.getOneToken(); - - while (currentToken && isCommentToken$2(currentToken)) { - tokens.push(currentToken); - currentToken = cursor.getOneToken(); - } - - return tokens; -} - -//------------------------------------------------------------------------------ -// Exports -//------------------------------------------------------------------------------ - -/** - * The token store. - * - * This class provides methods to get tokens by locations as fast as possible. - * The methods are a part of public API, so we should be careful if it changes this class. - * - * People can get tokens in O(1) by the hash map which is mapping from the location of tokens/comments to tokens. - * Also people can get a mix of tokens and comments in O(log k), the k is the number of comments. - * Assuming that comments to be much fewer than tokens, this does not make hash map from token's locations to comments to reduce memory cost. - * This uses binary-searching instead for comments. - */ -var tokenStore = class TokenStore { - - /** - * Initializes this token store. - * @param {Token[]} tokens The array of tokens. - * @param {Comment[]} comments The array of comments. - */ - constructor(tokens, comments) { - this[TOKENS] = tokens; - this[COMMENTS] = comments; - this[INDEX_MAP] = createIndexMap(tokens, comments); - } - - //-------------------------------------------------------------------------- - // Gets single token. - //-------------------------------------------------------------------------- - - /** - * Gets the token starting at the specified index. - * @param {number} offset Index of the start of the token's range. - * @param {Object} [options=0] The option object. - * @param {boolean} [options.includeComments=false] The flag to iterate comments as well. - * @returns {Token|null} The token starting at index, or null if no such token. - */ - getTokenByRangeStart(offset, options) { - const includeComments = options && options.includeComments; - const token = cursors.forward.createBaseCursor( - this[TOKENS], - this[COMMENTS], - this[INDEX_MAP], - offset, - -1, - includeComments - ).getOneToken(); - - if (token && token.range[0] === offset) { - return token; - } - return null; - } - - /** - * Gets the first token of the given node. - * @param {ASTNode} node The AST node. - * @param {number|Function|Object} [options=0] The option object. If this is a number then it's `options.skip`. If this is a function then it's `options.filter`. - * @param {boolean} [options.includeComments=false] The flag to iterate comments as well. - * @param {Function|null} [options.filter=null] The predicate function to choose tokens. - * @param {number} [options.skip=0] The count of tokens the cursor skips. - * @returns {Token|null} An object representing the token. - */ - getFirstToken(node, options) { - return createCursorWithSkip( - cursors.forward, - this[TOKENS], - this[COMMENTS], - this[INDEX_MAP], - node.range[0], - node.range[1], - options - ).getOneToken(); - } - - /** - * Gets the last token of the given node. - * @param {ASTNode} node The AST node. - * @param {number|Function|Object} [options=0] The option object. Same options as getFirstToken() - * @returns {Token|null} An object representing the token. - */ - getLastToken(node, options) { - return createCursorWithSkip( - cursors.backward, - this[TOKENS], - this[COMMENTS], - this[INDEX_MAP], - node.range[0], - node.range[1], - options - ).getOneToken(); - } - - /** - * Gets the token that precedes a given node or token. - * @param {ASTNode|Token|Comment} node The AST node or token. - * @param {number|Function|Object} [options=0] The option object. Same options as getFirstToken() - * @returns {Token|null} An object representing the token. - */ - getTokenBefore(node, options) { - return createCursorWithSkip( - cursors.backward, - this[TOKENS], - this[COMMENTS], - this[INDEX_MAP], - -1, - node.range[0], - options - ).getOneToken(); - } - - /** - * Gets the token that follows a given node or token. - * @param {ASTNode|Token|Comment} node The AST node or token. - * @param {number|Function|Object} [options=0] The option object. Same options as getFirstToken() - * @returns {Token|null} An object representing the token. - */ - getTokenAfter(node, options) { - return createCursorWithSkip( - cursors.forward, - this[TOKENS], - this[COMMENTS], - this[INDEX_MAP], - node.range[1], - -1, - options - ).getOneToken(); - } - - /** - * Gets the first token between two non-overlapping nodes. - * @param {ASTNode|Token|Comment} left Node before the desired token range. - * @param {ASTNode|Token|Comment} right Node after the desired token range. - * @param {number|Function|Object} [options=0] The option object. Same options as getFirstToken() - * @returns {Token|null} An object representing the token. - */ - getFirstTokenBetween(left, right, options) { - return createCursorWithSkip( - cursors.forward, - this[TOKENS], - this[COMMENTS], - this[INDEX_MAP], - left.range[1], - right.range[0], - options - ).getOneToken(); - } - - /** - * Gets the last token between two non-overlapping nodes. - * @param {ASTNode|Token|Comment} left Node before the desired token range. - * @param {ASTNode|Token|Comment} right Node after the desired token range. - * @param {number|Function|Object} [options=0] The option object. Same options as getFirstToken() - * @returns {Token|null} An object representing the token. - */ - getLastTokenBetween(left, right, options) { - return createCursorWithSkip( - cursors.backward, - this[TOKENS], - this[COMMENTS], - this[INDEX_MAP], - left.range[1], - right.range[0], - options - ).getOneToken(); - } - - /** - * Gets the token that precedes a given node or token in the token stream. - * This is defined for backward compatibility. Use `includeComments` option instead. - * TODO: We have a plan to remove this in a future major version. - * @param {ASTNode|Token|Comment} node The AST node or token. - * @param {number} [skip=0] A number of tokens to skip. - * @returns {Token|null} An object representing the token. - * @deprecated - */ - getTokenOrCommentBefore(node, skip) { - return this.getTokenBefore(node, { includeComments: true, skip }); - } - - /** - * Gets the token that follows a given node or token in the token stream. - * This is defined for backward compatibility. Use `includeComments` option instead. - * TODO: We have a plan to remove this in a future major version. - * @param {ASTNode|Token|Comment} node The AST node or token. - * @param {number} [skip=0] A number of tokens to skip. - * @returns {Token|null} An object representing the token. - * @deprecated - */ - getTokenOrCommentAfter(node, skip) { - return this.getTokenAfter(node, { includeComments: true, skip }); - } - - //-------------------------------------------------------------------------- - // Gets multiple tokens. - //-------------------------------------------------------------------------- - - /** - * Gets the first `count` tokens of the given node. - * @param {ASTNode} node The AST node. - * @param {number|Function|Object} [options=0] The option object. If this is a number then it's `options.count`. If this is a function then it's `options.filter`. - * @param {boolean} [options.includeComments=false] The flag to iterate comments as well. - * @param {Function|null} [options.filter=null] The predicate function to choose tokens. - * @param {number} [options.count=0] The maximum count of tokens the cursor iterates. - * @returns {Token[]} Tokens. - */ - getFirstTokens(node, options) { - return createCursorWithCount( - cursors.forward, - this[TOKENS], - this[COMMENTS], - this[INDEX_MAP], - node.range[0], - node.range[1], - options - ).getAllTokens(); - } - - /** - * Gets the last `count` tokens of the given node. - * @param {ASTNode} node The AST node. - * @param {number|Function|Object} [options=0] The option object. Same options as getFirstTokens() - * @returns {Token[]} Tokens. - */ - getLastTokens(node, options) { - return createCursorWithCount( - cursors.backward, - this[TOKENS], - this[COMMENTS], - this[INDEX_MAP], - node.range[0], - node.range[1], - options - ).getAllTokens().reverse(); - } - - /** - * Gets the `count` tokens that precedes a given node or token. - * @param {ASTNode|Token|Comment} node The AST node or token. - * @param {number|Function|Object} [options=0] The option object. Same options as getFirstTokens() - * @returns {Token[]} Tokens. - */ - getTokensBefore(node, options) { - return createCursorWithCount( - cursors.backward, - this[TOKENS], - this[COMMENTS], - this[INDEX_MAP], - -1, - node.range[0], - options - ).getAllTokens().reverse(); - } - - /** - * Gets the `count` tokens that follows a given node or token. - * @param {ASTNode|Token|Comment} node The AST node or token. - * @param {number|Function|Object} [options=0] The option object. Same options as getFirstTokens() - * @returns {Token[]} Tokens. - */ - getTokensAfter(node, options) { - return createCursorWithCount( - cursors.forward, - this[TOKENS], - this[COMMENTS], - this[INDEX_MAP], - node.range[1], - -1, - options - ).getAllTokens(); - } - - /** - * Gets the first `count` tokens between two non-overlapping nodes. - * @param {ASTNode|Token|Comment} left Node before the desired token range. - * @param {ASTNode|Token|Comment} right Node after the desired token range. - * @param {number|Function|Object} [options=0] The option object. Same options as getFirstTokens() - * @returns {Token[]} Tokens between left and right. - */ - getFirstTokensBetween(left, right, options) { - return createCursorWithCount( - cursors.forward, - this[TOKENS], - this[COMMENTS], - this[INDEX_MAP], - left.range[1], - right.range[0], - options - ).getAllTokens(); - } - - /** - * Gets the last `count` tokens between two non-overlapping nodes. - * @param {ASTNode|Token|Comment} left Node before the desired token range. - * @param {ASTNode|Token|Comment} right Node after the desired token range. - * @param {number|Function|Object} [options=0] The option object. Same options as getFirstTokens() - * @returns {Token[]} Tokens between left and right. - */ - getLastTokensBetween(left, right, options) { - return createCursorWithCount( - cursors.backward, - this[TOKENS], - this[COMMENTS], - this[INDEX_MAP], - left.range[1], - right.range[0], - options - ).getAllTokens().reverse(); - } - - /** - * Gets all tokens that are related to the given node. - * @param {ASTNode} node The AST node. - * @param {Function|Object} options The option object. If this is a function then it's `options.filter`. - * @param {boolean} [options.includeComments=false] The flag to iterate comments as well. - * @param {Function|null} [options.filter=null] The predicate function to choose tokens. - * @param {number} [options.count=0] The maximum count of tokens the cursor iterates. - * @returns {Token[]} Array of objects representing tokens. - */ - /** - * Gets all tokens that are related to the given node. - * @param {ASTNode} node The AST node. - * @param {int} [beforeCount=0] The number of tokens before the node to retrieve. - * @param {int} [afterCount=0] The number of tokens after the node to retrieve. - * @returns {Token[]} Array of objects representing tokens. - */ - getTokens(node, beforeCount, afterCount) { - return createCursorWithPadding( - this[TOKENS], - this[COMMENTS], - this[INDEX_MAP], - node.range[0], - node.range[1], - beforeCount, - afterCount - ).getAllTokens(); - } - - /** - * Gets all of the tokens between two non-overlapping nodes. - * @param {ASTNode|Token|Comment} left Node before the desired token range. - * @param {ASTNode|Token|Comment} right Node after the desired token range. - * @param {Function|Object} options The option object. If this is a function then it's `options.filter`. - * @param {boolean} [options.includeComments=false] The flag to iterate comments as well. - * @param {Function|null} [options.filter=null] The predicate function to choose tokens. - * @param {number} [options.count=0] The maximum count of tokens the cursor iterates. - * @returns {Token[]} Tokens between left and right. - */ - /** - * Gets all of the tokens between two non-overlapping nodes. - * @param {ASTNode|Token|Comment} left Node before the desired token range. - * @param {ASTNode|Token|Comment} right Node after the desired token range. - * @param {int} [padding=0] Number of extra tokens on either side of center. - * @returns {Token[]} Tokens between left and right. - */ - getTokensBetween(left, right, padding) { - return createCursorWithPadding( - this[TOKENS], - this[COMMENTS], - this[INDEX_MAP], - left.range[1], - right.range[0], - padding, - padding - ).getAllTokens(); - } - - //-------------------------------------------------------------------------- - // Others. - //-------------------------------------------------------------------------- - - /** - * Checks whether any comments exist or not between the given 2 nodes. - * @param {ASTNode} left The node to check. - * @param {ASTNode} right The node to check. - * @returns {boolean} `true` if one or more comments exist. - */ - commentsExistBetween(left, right) { - const index = utils.search(this[COMMENTS], left.range[1]); - - return ( - index < this[COMMENTS].length && - this[COMMENTS][index].range[1] <= right.range[0] - ); - } - - /** - * Gets all comment tokens directly before the given node or token. - * @param {ASTNode|token} nodeOrToken The AST node or token to check for adjacent comment tokens. - * @returns {Array} An array of comments in occurrence order. - */ - getCommentsBefore(nodeOrToken) { - const cursor = createCursorWithCount( - cursors.backward, - this[TOKENS], - this[COMMENTS], - this[INDEX_MAP], - -1, - nodeOrToken.range[0], - { includeComments: true } - ); - - return getAdjacentCommentTokensFromCursor(cursor).reverse(); - } - - /** - * Gets all comment tokens directly after the given node or token. - * @param {ASTNode|token} nodeOrToken The AST node or token to check for adjacent comment tokens. - * @returns {Array} An array of comments in occurrence order. - */ - getCommentsAfter(nodeOrToken) { - const cursor = createCursorWithCount( - cursors.forward, - this[TOKENS], - this[COMMENTS], - this[INDEX_MAP], - nodeOrToken.range[1], - -1, - { includeComments: true } - ); - - return getAdjacentCommentTokensFromCursor(cursor); - } - - /** - * Gets all comment tokens inside the given node. - * @param {ASTNode} node The AST node to get the comments for. - * @returns {Array} An array of comments in occurrence order. - */ - getCommentsInside(node) { - return this.getTokens(node, { - includeComments: true, - filter: isCommentToken$2 - }); - } -}; - -/** - * @fileoverview Abstraction of JavaScript source code. - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -const - { isCommentToken: isCommentToken$1 } = require$$0__default$1['default']; - -//------------------------------------------------------------------------------ -// Private -//------------------------------------------------------------------------------ - -/** - * Validates that the given AST has the required information. - * @param {ASTNode} ast The Program node of the AST to check. - * @throws {Error} If the AST doesn't contain the correct information. - * @returns {void} - * @private - */ -function validate$2(ast) { - if (!ast.tokens) { - throw new Error("AST is missing the tokens array."); - } - - if (!ast.comments) { - throw new Error("AST is missing the comments array."); - } - - if (!ast.loc) { - throw new Error("AST is missing location information."); - } - - if (!ast.range) { - throw new Error("AST is missing range information"); - } -} - -/** - * Check to see if its a ES6 export declaration. - * @param {ASTNode} astNode An AST node. - * @returns {boolean} whether the given node represents an export declaration. - * @private - */ -function looksLikeExport(astNode) { - return astNode.type === "ExportDefaultDeclaration" || astNode.type === "ExportNamedDeclaration" || - astNode.type === "ExportAllDeclaration" || astNode.type === "ExportSpecifier"; -} - -/** - * Merges two sorted lists into a larger sorted list in O(n) time. - * @param {Token[]} tokens The list of tokens. - * @param {Token[]} comments The list of comments. - * @returns {Token[]} A sorted list of tokens and comments. - * @private - */ -function sortedMerge(tokens, comments) { - const result = []; - let tokenIndex = 0; - let commentIndex = 0; - - while (tokenIndex < tokens.length || commentIndex < comments.length) { - if (commentIndex >= comments.length || tokenIndex < tokens.length && tokens[tokenIndex].range[0] < comments[commentIndex].range[0]) { - result.push(tokens[tokenIndex++]); - } else { - result.push(comments[commentIndex++]); - } - } - - return result; -} - -/** - * Determines if two nodes or tokens overlap. - * @param {ASTNode|Token} first The first node or token to check. - * @param {ASTNode|Token} second The second node or token to check. - * @returns {boolean} True if the two nodes or tokens overlap. - * @private - */ -function nodesOrTokensOverlap(first, second) { - return (first.range[0] <= second.range[0] && first.range[1] >= second.range[0]) || - (second.range[0] <= first.range[0] && second.range[1] >= first.range[0]); -} - -/** - * Determines if two nodes or tokens have at least one whitespace character - * between them. Order does not matter. Returns false if the given nodes or - * tokens overlap. - * @param {SourceCode} sourceCode The source code object. - * @param {ASTNode|Token} first The first node or token to check between. - * @param {ASTNode|Token} second The second node or token to check between. - * @param {boolean} checkInsideOfJSXText If `true` is present, check inside of JSXText tokens for backward compatibility. - * @returns {boolean} True if there is a whitespace character between - * any of the tokens found between the two given nodes or tokens. - * @public - */ -function isSpaceBetween(sourceCode, first, second, checkInsideOfJSXText) { - if (nodesOrTokensOverlap(first, second)) { - return false; - } - - const [startingNodeOrToken, endingNodeOrToken] = first.range[1] <= second.range[0] - ? [first, second] - : [second, first]; - const firstToken = sourceCode.getLastToken(startingNodeOrToken) || startingNodeOrToken; - const finalToken = sourceCode.getFirstToken(endingNodeOrToken) || endingNodeOrToken; - let currentToken = firstToken; - - while (currentToken !== finalToken) { - const nextToken = sourceCode.getTokenAfter(currentToken, { includeComments: true }); - - if ( - currentToken.range[1] !== nextToken.range[0] || - - /* - * For backward compatibility, check spaces in JSXText. - * https://github.com/eslint/eslint/issues/12614 - */ - ( - checkInsideOfJSXText && - nextToken !== finalToken && - nextToken.type === "JSXText" && - /\s/u.test(nextToken.value) - ) - ) { - return true; - } - - currentToken = nextToken; - } - - return false; -} - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -class SourceCode$1 extends tokenStore { - - /** - * Represents parsed source code. - * @param {string|Object} textOrConfig The source code text or config object. - * @param {string} textOrConfig.text The source code text. - * @param {ASTNode} textOrConfig.ast The Program node of the AST representing the code. This AST should be created from the text that BOM was stripped. - * @param {Object|null} textOrConfig.parserServices The parser services. - * @param {ScopeManager|null} textOrConfig.scopeManager The scope of this source code. - * @param {Object|null} textOrConfig.visitorKeys The visitor keys to traverse AST. - * @param {ASTNode} [astIfNoConfig] The Program node of the AST representing the code. This AST should be created from the text that BOM was stripped. - */ - constructor(textOrConfig, astIfNoConfig) { - let text, ast, parserServices, scopeManager, visitorKeys; - - // Process overloading. - if (typeof textOrConfig === "string") { - text = textOrConfig; - ast = astIfNoConfig; - } else if (typeof textOrConfig === "object" && textOrConfig !== null) { - text = textOrConfig.text; - ast = textOrConfig.ast; - parserServices = textOrConfig.parserServices; - scopeManager = textOrConfig.scopeManager; - visitorKeys = textOrConfig.visitorKeys; - } - - validate$2(ast); - super(ast.tokens, ast.comments); - - /** - * The flag to indicate that the source code has Unicode BOM. - * @type boolean - */ - this.hasBOM = (text.charCodeAt(0) === 0xFEFF); - - /** - * The original text source code. - * BOM was stripped from this text. - * @type string - */ - this.text = (this.hasBOM ? text.slice(1) : text); - - /** - * The parsed AST for the source code. - * @type ASTNode - */ - this.ast = ast; - - /** - * The parser services of this source code. - * @type {Object} - */ - this.parserServices = parserServices || {}; - - /** - * The scope of this source code. - * @type {ScopeManager|null} - */ - this.scopeManager = scopeManager || null; - - /** - * The visitor keys to traverse AST. - * @type {Object} - */ - this.visitorKeys = visitorKeys || traverser.DEFAULT_VISITOR_KEYS; - - // Check the source text for the presence of a shebang since it is parsed as a standard line comment. - const shebangMatched = this.text.match(astUtils$1.shebangPattern); - const hasShebang = shebangMatched && ast.comments.length && ast.comments[0].value === shebangMatched[1]; - - if (hasShebang) { - ast.comments[0].type = "Shebang"; - } - - this.tokensAndComments = sortedMerge(ast.tokens, ast.comments); - - /** - * The source code split into lines according to ECMA-262 specification. - * This is done to avoid each rule needing to do so separately. - * @type string[] - */ - this.lines = []; - this.lineStartIndices = [0]; - - const lineEndingPattern = astUtils$1.createGlobalLinebreakMatcher(); - let match; - - /* - * Previously, this was implemented using a regex that - * matched a sequence of non-linebreak characters followed by a - * linebreak, then adding the lengths of the matches. However, - * this caused a catastrophic backtracking issue when the end - * of a file contained a large number of non-newline characters. - * To avoid this, the current implementation just matches newlines - * and uses match.index to get the correct line start indices. - */ - while ((match = lineEndingPattern.exec(this.text))) { - this.lines.push(this.text.slice(this.lineStartIndices[this.lineStartIndices.length - 1], match.index)); - this.lineStartIndices.push(match.index + match[0].length); - } - this.lines.push(this.text.slice(this.lineStartIndices[this.lineStartIndices.length - 1])); - - // Cache for comments found using getComments(). - this._commentCache = new WeakMap(); - - // don't allow modification of this object - Object.freeze(this); - Object.freeze(this.lines); - } - - /** - * Split the source code into multiple lines based on the line delimiters. - * @param {string} text Source code as a string. - * @returns {string[]} Array of source code lines. - * @public - */ - static splitLines(text) { - return text.split(astUtils$1.createGlobalLinebreakMatcher()); - } - - /** - * Gets the source code for the given node. - * @param {ASTNode} [node] The AST node to get the text for. - * @param {int} [beforeCount] The number of characters before the node to retrieve. - * @param {int} [afterCount] The number of characters after the node to retrieve. - * @returns {string} The text representing the AST node. - * @public - */ - getText(node, beforeCount, afterCount) { - if (node) { - return this.text.slice(Math.max(node.range[0] - (beforeCount || 0), 0), - node.range[1] + (afterCount || 0)); - } - return this.text; - } - - /** - * Gets the entire source text split into an array of lines. - * @returns {Array} The source text as an array of lines. - * @public - */ - getLines() { - return this.lines; - } - - /** - * Retrieves an array containing all comments in the source code. - * @returns {ASTNode[]} An array of comment nodes. - * @public - */ - getAllComments() { - return this.ast.comments; - } - - /** - * Gets all comments for the given node. - * @param {ASTNode} node The AST node to get the comments for. - * @returns {Object} An object containing a leading and trailing array - * of comments indexed by their position. - * @public - * @deprecated replaced by getCommentsBefore(), getCommentsAfter(), and getCommentsInside(). - */ - getComments(node) { - if (this._commentCache.has(node)) { - return this._commentCache.get(node); - } - - const comments = { - leading: [], - trailing: [] - }; - - /* - * Return all comments as leading comments of the Program node when - * there is no executable code. - */ - if (node.type === "Program") { - if (node.body.length === 0) { - comments.leading = node.comments; - } - } else { - - /* - * Return comments as trailing comments of nodes that only contain - * comments (to mimic the comment attachment behavior present in Espree). - */ - if ((node.type === "BlockStatement" || node.type === "ClassBody") && node.body.length === 0 || - node.type === "ObjectExpression" && node.properties.length === 0 || - node.type === "ArrayExpression" && node.elements.length === 0 || - node.type === "SwitchStatement" && node.cases.length === 0 - ) { - comments.trailing = this.getTokens(node, { - includeComments: true, - filter: isCommentToken$1 - }); - } - - /* - * Iterate over tokens before and after node and collect comment tokens. - * Do not include comments that exist outside of the parent node - * to avoid duplication. - */ - let currentToken = this.getTokenBefore(node, { includeComments: true }); - - while (currentToken && isCommentToken$1(currentToken)) { - if (node.parent && (currentToken.start < node.parent.start)) { - break; - } - comments.leading.push(currentToken); - currentToken = this.getTokenBefore(currentToken, { includeComments: true }); - } - - comments.leading.reverse(); - - currentToken = this.getTokenAfter(node, { includeComments: true }); - - while (currentToken && isCommentToken$1(currentToken)) { - if (node.parent && (currentToken.end > node.parent.end)) { - break; - } - comments.trailing.push(currentToken); - currentToken = this.getTokenAfter(currentToken, { includeComments: true }); - } - } - - this._commentCache.set(node, comments); - return comments; - } - - /** - * Retrieves the JSDoc comment for a given node. - * @param {ASTNode} node The AST node to get the comment for. - * @returns {Token|null} The Block comment token containing the JSDoc comment - * for the given node or null if not found. - * @public - * @deprecated - */ - getJSDocComment(node) { - - /** - * Checks for the presence of a JSDoc comment for the given node and returns it. - * @param {ASTNode} astNode The AST node to get the comment for. - * @returns {Token|null} The Block comment token containing the JSDoc comment - * for the given node or null if not found. - * @private - */ - const findJSDocComment = astNode => { - const tokenBefore = this.getTokenBefore(astNode, { includeComments: true }); - - if ( - tokenBefore && - isCommentToken$1(tokenBefore) && - tokenBefore.type === "Block" && - tokenBefore.value.charAt(0) === "*" && - astNode.loc.start.line - tokenBefore.loc.end.line <= 1 - ) { - return tokenBefore; - } - - return null; - }; - let parent = node.parent; - - switch (node.type) { - case "ClassDeclaration": - case "FunctionDeclaration": - return findJSDocComment(looksLikeExport(parent) ? parent : node); - - case "ClassExpression": - return findJSDocComment(parent.parent); - - case "ArrowFunctionExpression": - case "FunctionExpression": - if (parent.type !== "CallExpression" && parent.type !== "NewExpression") { - while ( - !this.getCommentsBefore(parent).length && - !/Function/u.test(parent.type) && - parent.type !== "MethodDefinition" && - parent.type !== "Property" - ) { - parent = parent.parent; - - if (!parent) { - break; - } - } - - if (parent && parent.type !== "FunctionDeclaration" && parent.type !== "Program") { - return findJSDocComment(parent); - } - } - - return findJSDocComment(node); - - // falls through - default: - return null; - } - } - - /** - * Gets the deepest node containing a range index. - * @param {int} index Range index of the desired node. - * @returns {ASTNode} The node if found or null if not found. - * @public - */ - getNodeByRangeIndex(index) { - let result = null; - - traverser.traverse(this.ast, { - visitorKeys: this.visitorKeys, - enter(node) { - if (node.range[0] <= index && index < node.range[1]) { - result = node; - } else { - this.skip(); - } - }, - leave(node) { - if (node === result) { - this.break(); - } - } - }); - - return result; - } - - /** - * Determines if two nodes or tokens have at least one whitespace character - * between them. Order does not matter. Returns false if the given nodes or - * tokens overlap. - * @param {ASTNode|Token} first The first node or token to check between. - * @param {ASTNode|Token} second The second node or token to check between. - * @returns {boolean} True if there is a whitespace character between - * any of the tokens found between the two given nodes or tokens. - * @public - */ - isSpaceBetween(first, second) { - return isSpaceBetween(this, first, second, false); - } - - /** - * Determines if two nodes or tokens have at least one whitespace character - * between them. Order does not matter. Returns false if the given nodes or - * tokens overlap. - * For backward compatibility, this method returns true if there are - * `JSXText` tokens that contain whitespaces between the two. - * @param {ASTNode|Token} first The first node or token to check between. - * @param {ASTNode|Token} second The second node or token to check between. - * @returns {boolean} True if there is a whitespace character between - * any of the tokens found between the two given nodes or tokens. - * @deprecated in favor of isSpaceBetween(). - * @public - */ - isSpaceBetweenTokens(first, second) { - return isSpaceBetween(this, first, second, true); - } - - /** - * Converts a source text index into a (line, column) pair. - * @param {number} index The index of a character in a file - * @returns {Object} A {line, column} location object with a 0-indexed column - * @public - */ - getLocFromIndex(index) { - if (typeof index !== "number") { - throw new TypeError("Expected `index` to be a number."); - } - - if (index < 0 || index > this.text.length) { - throw new RangeError(`Index out of range (requested index ${index}, but source text has length ${this.text.length}).`); - } - - /* - * For an argument of this.text.length, return the location one "spot" past the last character - * of the file. If the last character is a linebreak, the location will be column 0 of the next - * line; otherwise, the location will be in the next column on the same line. - * - * See getIndexFromLoc for the motivation for this special case. - */ - if (index === this.text.length) { - return { line: this.lines.length, column: this.lines[this.lines.length - 1].length }; - } - - /* - * To figure out which line rangeIndex is on, determine the last index at which rangeIndex could - * be inserted into lineIndices to keep the list sorted. - */ - const lineNumber = lodash__default['default'].sortedLastIndex(this.lineStartIndices, index); - - return { line: lineNumber, column: index - this.lineStartIndices[lineNumber - 1] }; - } - - /** - * Converts a (line, column) pair into a range index. - * @param {Object} loc A line/column location - * @param {number} loc.line The line number of the location (1-indexed) - * @param {number} loc.column The column number of the location (0-indexed) - * @returns {number} The range index of the location in the file. - * @public - */ - getIndexFromLoc(loc) { - if (typeof loc !== "object" || typeof loc.line !== "number" || typeof loc.column !== "number") { - throw new TypeError("Expected `loc` to be an object with numeric `line` and `column` properties."); - } - - if (loc.line <= 0) { - throw new RangeError(`Line number out of range (line ${loc.line} requested). Line numbers should be 1-based.`); - } - - if (loc.line > this.lineStartIndices.length) { - throw new RangeError(`Line number out of range (line ${loc.line} requested, but only ${this.lineStartIndices.length} lines present).`); - } - - const lineStartIndex = this.lineStartIndices[loc.line - 1]; - const lineEndIndex = loc.line === this.lineStartIndices.length ? this.text.length : this.lineStartIndices[loc.line]; - const positionIndex = lineStartIndex + loc.column; - - /* - * By design, getIndexFromLoc({ line: lineNum, column: 0 }) should return the start index of - * the given line, provided that the line number is valid element of this.lines. Since the - * last element of this.lines is an empty string for files with trailing newlines, add a - * special case where getting the index for the first location after the end of the file - * will return the length of the file, rather than throwing an error. This allows rules to - * use getIndexFromLoc consistently without worrying about edge cases at the end of a file. - */ - if ( - loc.line === this.lineStartIndices.length && positionIndex > lineEndIndex || - loc.line < this.lineStartIndices.length && positionIndex >= lineEndIndex - ) { - throw new RangeError(`Column number out of range (column ${loc.column} requested, but the length of line ${loc.line} is ${lineEndIndex - lineStartIndex}).`); - } - - return positionIndex; - } -} - -var sourceCode$1 = SourceCode$1; - -var sourceCode = { - SourceCode: sourceCode$1 -}; - -/** - * @fileoverview Helpers to debug for code path analysis. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -const debug$6 = require$$0__default['default']("eslint:code-path"); - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Gets id of a given segment. - * @param {CodePathSegment} segment A segment to get. - * @returns {string} Id of the segment. - */ -/* istanbul ignore next */ -function getId(segment) { // eslint-disable-line jsdoc/require-jsdoc - return segment.id + (segment.reachable ? "" : "!"); -} - -/** - * Get string for the given node and operation. - * @param {ASTNode} node The node to convert. - * @param {"enter" | "exit" | undefined} label The operation label. - * @returns {string} The string representation. - */ -function nodeToString(node, label) { - const suffix = label ? `:${label}` : ""; - - switch (node.type) { - case "Identifier": return `${node.type}${suffix} (${node.name})`; - case "Literal": return `${node.type}${suffix} (${node.value})`; - default: return `${node.type}${suffix}`; - } -} - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -var debugHelpers = { - - /** - * A flag that debug dumping is enabled or not. - * @type {boolean} - */ - enabled: debug$6.enabled, - - /** - * Dumps given objects. - * @param {...any} args objects to dump. - * @returns {void} - */ - dump: debug$6, - - /** - * Dumps the current analyzing state. - * @param {ASTNode} node A node to dump. - * @param {CodePathState} state A state to dump. - * @param {boolean} leaving A flag whether or not it's leaving - * @returns {void} - */ - dumpState: !debug$6.enabled ? debug$6 : /* istanbul ignore next */ function(node, state, leaving) { - for (let i = 0; i < state.currentSegments.length; ++i) { - const segInternal = state.currentSegments[i].internal; - - if (leaving) { - const last = segInternal.nodes.length - 1; - - if (last >= 0 && segInternal.nodes[last] === nodeToString(node, "enter")) { - segInternal.nodes[last] = nodeToString(node, void 0); - } else { - segInternal.nodes.push(nodeToString(node, "exit")); - } - } else { - segInternal.nodes.push(nodeToString(node, "enter")); - } - } - - debug$6([ - `${state.currentSegments.map(getId).join(",")})`, - `${node.type}${leaving ? ":exit" : ""}` - ].join(" ")); - }, - - /** - * Dumps a DOT code of a given code path. - * The DOT code can be visualized with Graphvis. - * @param {CodePath} codePath A code path to dump. - * @returns {void} - * @see http://www.graphviz.org - * @see http://www.webgraphviz.com - */ - dumpDot: !debug$6.enabled ? debug$6 : /* istanbul ignore next */ function(codePath) { - let text = - "\n" + - "digraph {\n" + - "node[shape=box,style=\"rounded,filled\",fillcolor=white];\n" + - "initial[label=\"\",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];\n"; - - if (codePath.returnedSegments.length > 0) { - text += "final[label=\"\",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];\n"; - } - if (codePath.thrownSegments.length > 0) { - text += "thrown[label=\"✘\",shape=circle,width=0.3,height=0.3,fixedsize];\n"; - } - - const traceMap = Object.create(null); - const arrows = this.makeDotArrows(codePath, traceMap); - - for (const id in traceMap) { // eslint-disable-line guard-for-in - const segment = traceMap[id]; - - text += `${id}[`; - - if (segment.reachable) { - text += "label=\""; - } else { - text += "style=\"rounded,dashed,filled\",fillcolor=\"#FF9800\",label=\"<>\\n"; - } - - if (segment.internal.nodes.length > 0) { - text += segment.internal.nodes.join("\\n"); - } else { - text += "????"; - } - - text += "\"];\n"; - } - - text += `${arrows}\n`; - text += "}"; - debug$6("DOT", text); - }, - - /** - * Makes a DOT code of a given code path. - * The DOT code can be visualized with Graphvis. - * @param {CodePath} codePath A code path to make DOT. - * @param {Object} traceMap Optional. A map to check whether or not segments had been done. - * @returns {string} A DOT code of the code path. - */ - makeDotArrows(codePath, traceMap) { - const stack = [[codePath.initialSegment, 0]]; - const done = traceMap || Object.create(null); - let lastId = codePath.initialSegment.id; - let text = `initial->${codePath.initialSegment.id}`; - - while (stack.length > 0) { - const item = stack.pop(); - const segment = item[0]; - const index = item[1]; - - if (done[segment.id] && index === 0) { - continue; - } - done[segment.id] = segment; - - const nextSegment = segment.allNextSegments[index]; - - if (!nextSegment) { - continue; - } - - if (lastId === segment.id) { - text += `->${nextSegment.id}`; - } else { - text += `;\n${segment.id}->${nextSegment.id}`; - } - lastId = nextSegment.id; - - stack.unshift([segment, 1 + index]); - stack.push([nextSegment, 0]); - } - - codePath.returnedSegments.forEach(finalSegment => { - if (lastId === finalSegment.id) { - text += "->final"; - } else { - text += `;\n${finalSegment.id}->final`; - } - lastId = null; - }); - - codePath.thrownSegments.forEach(finalSegment => { - if (lastId === finalSegment.id) { - text += "->thrown"; - } else { - text += `;\n${finalSegment.id}->thrown`; - } - lastId = null; - }); - - return `${text};`; - } -}; - -/** - * @fileoverview A class of the code path segment. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether or not a given segment is reachable. - * @param {CodePathSegment} segment A segment to check. - * @returns {boolean} `true` if the segment is reachable. - */ -function isReachable$5(segment) { - return segment.reachable; -} - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -/** - * A code path segment. - */ -class CodePathSegment { - - // eslint-disable-next-line jsdoc/require-description - /** - * @param {string} id An identifier. - * @param {CodePathSegment[]} allPrevSegments An array of the previous segments. - * This array includes unreachable segments. - * @param {boolean} reachable A flag which shows this is reachable. - */ - constructor(id, allPrevSegments, reachable) { - - /** - * The identifier of this code path. - * Rules use it to store additional information of each rule. - * @type {string} - */ - this.id = id; - - /** - * An array of the next segments. - * @type {CodePathSegment[]} - */ - this.nextSegments = []; - - /** - * An array of the previous segments. - * @type {CodePathSegment[]} - */ - this.prevSegments = allPrevSegments.filter(isReachable$5); - - /** - * An array of the next segments. - * This array includes unreachable segments. - * @type {CodePathSegment[]} - */ - this.allNextSegments = []; - - /** - * An array of the previous segments. - * This array includes unreachable segments. - * @type {CodePathSegment[]} - */ - this.allPrevSegments = allPrevSegments; - - /** - * A flag which shows this is reachable. - * @type {boolean} - */ - this.reachable = reachable; - - // Internal data. - Object.defineProperty(this, "internal", { - value: { - used: false, - loopedPrevSegments: [] - } - }); - - /* istanbul ignore if */ - if (debugHelpers.enabled) { - this.internal.nodes = []; - } - } - - /** - * Checks a given previous segment is coming from the end of a loop. - * @param {CodePathSegment} segment A previous segment to check. - * @returns {boolean} `true` if the segment is coming from the end of a loop. - */ - isLoopedPrevSegment(segment) { - return this.internal.loopedPrevSegments.indexOf(segment) !== -1; - } - - /** - * Creates the root segment. - * @param {string} id An identifier. - * @returns {CodePathSegment} The created segment. - */ - static newRoot(id) { - return new CodePathSegment(id, [], true); - } - - /** - * Creates a segment that follows given segments. - * @param {string} id An identifier. - * @param {CodePathSegment[]} allPrevSegments An array of the previous segments. - * @returns {CodePathSegment} The created segment. - */ - static newNext(id, allPrevSegments) { - return new CodePathSegment( - id, - CodePathSegment.flattenUnusedSegments(allPrevSegments), - allPrevSegments.some(isReachable$5) - ); - } - - /** - * Creates an unreachable segment that follows given segments. - * @param {string} id An identifier. - * @param {CodePathSegment[]} allPrevSegments An array of the previous segments. - * @returns {CodePathSegment} The created segment. - */ - static newUnreachable(id, allPrevSegments) { - const segment = new CodePathSegment(id, CodePathSegment.flattenUnusedSegments(allPrevSegments), false); - - /* - * In `if (a) return a; foo();` case, the unreachable segment preceded by - * the return statement is not used but must not be remove. - */ - CodePathSegment.markUsed(segment); - - return segment; - } - - /** - * Creates a segment that follows given segments. - * This factory method does not connect with `allPrevSegments`. - * But this inherits `reachable` flag. - * @param {string} id An identifier. - * @param {CodePathSegment[]} allPrevSegments An array of the previous segments. - * @returns {CodePathSegment} The created segment. - */ - static newDisconnected(id, allPrevSegments) { - return new CodePathSegment(id, [], allPrevSegments.some(isReachable$5)); - } - - /** - * Makes a given segment being used. - * - * And this function registers the segment into the previous segments as a next. - * @param {CodePathSegment} segment A segment to mark. - * @returns {void} - */ - static markUsed(segment) { - if (segment.internal.used) { - return; - } - segment.internal.used = true; - - let i; - - if (segment.reachable) { - for (i = 0; i < segment.allPrevSegments.length; ++i) { - const prevSegment = segment.allPrevSegments[i]; - - prevSegment.allNextSegments.push(segment); - prevSegment.nextSegments.push(segment); - } - } else { - for (i = 0; i < segment.allPrevSegments.length; ++i) { - segment.allPrevSegments[i].allNextSegments.push(segment); - } - } - } - - /** - * Marks a previous segment as looped. - * @param {CodePathSegment} segment A segment. - * @param {CodePathSegment} prevSegment A previous segment to mark. - * @returns {void} - */ - static markPrevSegmentAsLooped(segment, prevSegment) { - segment.internal.loopedPrevSegments.push(prevSegment); - } - - /** - * Replaces unused segments with the previous segments of each unused segment. - * @param {CodePathSegment[]} segments An array of segments to replace. - * @returns {CodePathSegment[]} The replaced array. - */ - static flattenUnusedSegments(segments) { - const done = Object.create(null); - const retv = []; - - for (let i = 0; i < segments.length; ++i) { - const segment = segments[i]; - - // Ignores duplicated. - if (done[segment.id]) { - continue; - } - - // Use previous segments if unused. - if (!segment.internal.used) { - for (let j = 0; j < segment.allPrevSegments.length; ++j) { - const prevSegment = segment.allPrevSegments[j]; - - if (!done[prevSegment.id]) { - done[prevSegment.id] = true; - retv.push(prevSegment); - } - } - } else { - done[segment.id] = true; - retv.push(segment); - } - } - - return retv; - } -} - -var codePathSegment = CodePathSegment; - -/** - * @fileoverview A class to operate forking. - * - * This is state of forking. - * This has a fork list and manages it. - * - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Gets whether or not a given segment is reachable. - * @param {CodePathSegment} segment A segment to get. - * @returns {boolean} `true` if the segment is reachable. - */ -function isReachable$4(segment) { - return segment.reachable; -} - -/** - * Creates new segments from the specific range of `context.segmentsList`. - * - * When `context.segmentsList` is `[[a, b], [c, d], [e, f]]`, `begin` is `0`, and - * `end` is `-1`, this creates `[g, h]`. This `g` is from `a`, `c`, and `e`. - * This `h` is from `b`, `d`, and `f`. - * @param {ForkContext} context An instance. - * @param {number} begin The first index of the previous segments. - * @param {number} end The last index of the previous segments. - * @param {Function} create A factory function of new segments. - * @returns {CodePathSegment[]} New segments. - */ -function makeSegments(context, begin, end, create) { - const list = context.segmentsList; - - const normalizedBegin = begin >= 0 ? begin : list.length + begin; - const normalizedEnd = end >= 0 ? end : list.length + end; - - const segments = []; - - for (let i = 0; i < context.count; ++i) { - const allPrevSegments = []; - - for (let j = normalizedBegin; j <= normalizedEnd; ++j) { - allPrevSegments.push(list[j][i]); - } - - segments.push(create(context.idGenerator.next(), allPrevSegments)); - } - - return segments; -} - -/** - * `segments` becomes doubly in a `finally` block. Then if a code path exits by a - * control statement (such as `break`, `continue`) from the `finally` block, the - * destination's segments may be half of the source segments. In that case, this - * merges segments. - * @param {ForkContext} context An instance. - * @param {CodePathSegment[]} segments Segments to merge. - * @returns {CodePathSegment[]} The merged segments. - */ -function mergeExtraSegments(context, segments) { - let currentSegments = segments; - - while (currentSegments.length > context.count) { - const merged = []; - - for (let i = 0, length = currentSegments.length / 2 | 0; i < length; ++i) { - merged.push(codePathSegment.newNext( - context.idGenerator.next(), - [currentSegments[i], currentSegments[i + length]] - )); - } - currentSegments = merged; - } - return currentSegments; -} - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -/** - * A class to manage forking. - */ -class ForkContext { - - // eslint-disable-next-line jsdoc/require-description - /** - * @param {IdGenerator} idGenerator An identifier generator for segments. - * @param {ForkContext|null} upper An upper fork context. - * @param {number} count A number of parallel segments. - */ - constructor(idGenerator, upper, count) { - this.idGenerator = idGenerator; - this.upper = upper; - this.count = count; - this.segmentsList = []; - } - - /** - * The head segments. - * @type {CodePathSegment[]} - */ - get head() { - const list = this.segmentsList; - - return list.length === 0 ? [] : list[list.length - 1]; - } - - /** - * A flag which shows empty. - * @type {boolean} - */ - get empty() { - return this.segmentsList.length === 0; - } - - /** - * A flag which shows reachable. - * @type {boolean} - */ - get reachable() { - const segments = this.head; - - return segments.length > 0 && segments.some(isReachable$4); - } - - /** - * Creates new segments from this context. - * @param {number} begin The first index of previous segments. - * @param {number} end The last index of previous segments. - * @returns {CodePathSegment[]} New segments. - */ - makeNext(begin, end) { - return makeSegments(this, begin, end, codePathSegment.newNext); - } - - /** - * Creates new segments from this context. - * The new segments is always unreachable. - * @param {number} begin The first index of previous segments. - * @param {number} end The last index of previous segments. - * @returns {CodePathSegment[]} New segments. - */ - makeUnreachable(begin, end) { - return makeSegments(this, begin, end, codePathSegment.newUnreachable); - } - - /** - * Creates new segments from this context. - * The new segments don't have connections for previous segments. - * But these inherit the reachable flag from this context. - * @param {number} begin The first index of previous segments. - * @param {number} end The last index of previous segments. - * @returns {CodePathSegment[]} New segments. - */ - makeDisconnected(begin, end) { - return makeSegments(this, begin, end, codePathSegment.newDisconnected); - } - - /** - * Adds segments into this context. - * The added segments become the head. - * @param {CodePathSegment[]} segments Segments to add. - * @returns {void} - */ - add(segments) { - assert__default['default'](segments.length >= this.count, `${segments.length} >= ${this.count}`); - - this.segmentsList.push(mergeExtraSegments(this, segments)); - } - - /** - * Replaces the head segments with given segments. - * The current head segments are removed. - * @param {CodePathSegment[]} segments Segments to add. - * @returns {void} - */ - replaceHead(segments) { - assert__default['default'](segments.length >= this.count, `${segments.length} >= ${this.count}`); - - this.segmentsList.splice(-1, 1, mergeExtraSegments(this, segments)); - } - - /** - * Adds all segments of a given fork context into this context. - * @param {ForkContext} context A fork context to add. - * @returns {void} - */ - addAll(context) { - assert__default['default'](context.count === this.count); - - const source = context.segmentsList; - - for (let i = 0; i < source.length; ++i) { - this.segmentsList.push(source[i]); - } - } - - /** - * Clears all segments in this context. - * @returns {void} - */ - clear() { - this.segmentsList = []; - } - - /** - * Creates the root fork context. - * @param {IdGenerator} idGenerator An identifier generator for segments. - * @returns {ForkContext} New fork context. - */ - static newRoot(idGenerator) { - const context = new ForkContext(idGenerator, null, 1); - - context.add([codePathSegment.newRoot(idGenerator.next())]); - - return context; - } - - /** - * Creates an empty fork context preceded by a given context. - * @param {ForkContext} parentContext The parent fork context. - * @param {boolean} forkLeavingPath A flag which shows inside of `finally` block. - * @returns {ForkContext} New fork context. - */ - static newEmpty(parentContext, forkLeavingPath) { - return new ForkContext( - parentContext.idGenerator, - parentContext, - (forkLeavingPath ? 2 : 1) * parentContext.count - ); - } -} - -var forkContext = ForkContext; - -/** - * @fileoverview A class to manage state of generating a code path. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Adds given segments into the `dest` array. - * If the `others` array does not includes the given segments, adds to the `all` - * array as well. - * - * This adds only reachable and used segments. - * @param {CodePathSegment[]} dest A destination array (`returnedSegments` or `thrownSegments`). - * @param {CodePathSegment[]} others Another destination array (`returnedSegments` or `thrownSegments`). - * @param {CodePathSegment[]} all The unified destination array (`finalSegments`). - * @param {CodePathSegment[]} segments Segments to add. - * @returns {void} - */ -function addToReturnedOrThrown(dest, others, all, segments) { - for (let i = 0; i < segments.length; ++i) { - const segment = segments[i]; - - dest.push(segment); - if (others.indexOf(segment) === -1) { - all.push(segment); - } - } -} - -/** - * Gets a loop-context for a `continue` statement. - * @param {CodePathState} state A state to get. - * @param {string} label The label of a `continue` statement. - * @returns {LoopContext} A loop-context for a `continue` statement. - */ -function getContinueContext(state, label) { - if (!label) { - return state.loopContext; - } - - let context = state.loopContext; - - while (context) { - if (context.label === label) { - return context; - } - context = context.upper; - } - - /* istanbul ignore next: foolproof (syntax error) */ - return null; -} - -/** - * Gets a context for a `break` statement. - * @param {CodePathState} state A state to get. - * @param {string} label The label of a `break` statement. - * @returns {LoopContext|SwitchContext} A context for a `break` statement. - */ -function getBreakContext(state, label) { - let context = state.breakContext; - - while (context) { - if (label ? context.label === label : context.breakable) { - return context; - } - context = context.upper; - } - - /* istanbul ignore next: foolproof (syntax error) */ - return null; -} - -/** - * Gets a context for a `return` statement. - * @param {CodePathState} state A state to get. - * @returns {TryContext|CodePathState} A context for a `return` statement. - */ -function getReturnContext(state) { - let context = state.tryContext; - - while (context) { - if (context.hasFinalizer && context.position !== "finally") { - return context; - } - context = context.upper; - } - - return state; -} - -/** - * Gets a context for a `throw` statement. - * @param {CodePathState} state A state to get. - * @returns {TryContext|CodePathState} A context for a `throw` statement. - */ -function getThrowContext(state) { - let context = state.tryContext; - - while (context) { - if (context.position === "try" || - (context.hasFinalizer && context.position === "catch") - ) { - return context; - } - context = context.upper; - } - - return state; -} - -/** - * Removes a given element from a given array. - * @param {any[]} xs An array to remove the specific element. - * @param {any} x An element to be removed. - * @returns {void} - */ -function remove$1(xs, x) { - xs.splice(xs.indexOf(x), 1); -} - -/** - * Disconnect given segments. - * - * This is used in a process for switch statements. - * If there is the "default" chunk before other cases, the order is different - * between node's and running's. - * @param {CodePathSegment[]} prevSegments Forward segments to disconnect. - * @param {CodePathSegment[]} nextSegments Backward segments to disconnect. - * @returns {void} - */ -function removeConnection(prevSegments, nextSegments) { - for (let i = 0; i < prevSegments.length; ++i) { - const prevSegment = prevSegments[i]; - const nextSegment = nextSegments[i]; - - remove$1(prevSegment.nextSegments, nextSegment); - remove$1(prevSegment.allNextSegments, nextSegment); - remove$1(nextSegment.prevSegments, prevSegment); - remove$1(nextSegment.allPrevSegments, prevSegment); - } -} - -/** - * Creates looping path. - * @param {CodePathState} state The instance. - * @param {CodePathSegment[]} unflattenedFromSegments Segments which are source. - * @param {CodePathSegment[]} unflattenedToSegments Segments which are destination. - * @returns {void} - */ -function makeLooped(state, unflattenedFromSegments, unflattenedToSegments) { - const fromSegments = codePathSegment.flattenUnusedSegments(unflattenedFromSegments); - const toSegments = codePathSegment.flattenUnusedSegments(unflattenedToSegments); - - const end = Math.min(fromSegments.length, toSegments.length); - - for (let i = 0; i < end; ++i) { - const fromSegment = fromSegments[i]; - const toSegment = toSegments[i]; - - if (toSegment.reachable) { - fromSegment.nextSegments.push(toSegment); - } - if (fromSegment.reachable) { - toSegment.prevSegments.push(fromSegment); - } - fromSegment.allNextSegments.push(toSegment); - toSegment.allPrevSegments.push(fromSegment); - - if (toSegment.allPrevSegments.length >= 2) { - codePathSegment.markPrevSegmentAsLooped(toSegment, fromSegment); - } - - state.notifyLooped(fromSegment, toSegment); - } -} - -/** - * Finalizes segments of `test` chunk of a ForStatement. - * - * - Adds `false` paths to paths which are leaving from the loop. - * - Sets `true` paths to paths which go to the body. - * @param {LoopContext} context A loop context to modify. - * @param {ChoiceContext} choiceContext A choice context of this loop. - * @param {CodePathSegment[]} head The current head paths. - * @returns {void} - */ -function finalizeTestSegmentsOfFor(context, choiceContext, head) { - if (!choiceContext.processed) { - choiceContext.trueForkContext.add(head); - choiceContext.falseForkContext.add(head); - choiceContext.qqForkContext.add(head); - } - - if (context.test !== true) { - context.brokenForkContext.addAll(choiceContext.falseForkContext); - } - context.endOfTestSegments = choiceContext.trueForkContext.makeNext(0, -1); -} - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -/** - * A class which manages state to analyze code paths. - */ -class CodePathState { - - // eslint-disable-next-line jsdoc/require-description - /** - * @param {IdGenerator} idGenerator An id generator to generate id for code - * path segments. - * @param {Function} onLooped A callback function to notify looping. - */ - constructor(idGenerator, onLooped) { - this.idGenerator = idGenerator; - this.notifyLooped = onLooped; - this.forkContext = forkContext.newRoot(idGenerator); - this.choiceContext = null; - this.switchContext = null; - this.tryContext = null; - this.loopContext = null; - this.breakContext = null; - this.chainContext = null; - - this.currentSegments = []; - this.initialSegment = this.forkContext.head[0]; - - // returnedSegments and thrownSegments push elements into finalSegments also. - const final = this.finalSegments = []; - const returned = this.returnedForkContext = []; - const thrown = this.thrownForkContext = []; - - returned.add = addToReturnedOrThrown.bind(null, returned, thrown, final); - thrown.add = addToReturnedOrThrown.bind(null, thrown, returned, final); - } - - /** - * The head segments. - * @type {CodePathSegment[]} - */ - get headSegments() { - return this.forkContext.head; - } - - /** - * The parent forking context. - * This is used for the root of new forks. - * @type {ForkContext} - */ - get parentForkContext() { - const current = this.forkContext; - - return current && current.upper; - } - - /** - * Creates and stacks new forking context. - * @param {boolean} forkLeavingPath A flag which shows being in a - * "finally" block. - * @returns {ForkContext} The created context. - */ - pushForkContext(forkLeavingPath) { - this.forkContext = forkContext.newEmpty( - this.forkContext, - forkLeavingPath - ); - - return this.forkContext; - } - - /** - * Pops and merges the last forking context. - * @returns {ForkContext} The last context. - */ - popForkContext() { - const lastContext = this.forkContext; - - this.forkContext = lastContext.upper; - this.forkContext.replaceHead(lastContext.makeNext(0, -1)); - - return lastContext; - } - - /** - * Creates a new path. - * @returns {void} - */ - forkPath() { - this.forkContext.add(this.parentForkContext.makeNext(-1, -1)); - } - - /** - * Creates a bypass path. - * This is used for such as IfStatement which does not have "else" chunk. - * @returns {void} - */ - forkBypassPath() { - this.forkContext.add(this.parentForkContext.head); - } - - //-------------------------------------------------------------------------- - // ConditionalExpression, LogicalExpression, IfStatement - //-------------------------------------------------------------------------- - - /** - * Creates a context for ConditionalExpression, LogicalExpression, AssignmentExpression (logical assignments only), - * IfStatement, WhileStatement, DoWhileStatement, or ForStatement. - * - * LogicalExpressions have cases that it goes different paths between the - * `true` case and the `false` case. - * - * For Example: - * - * if (a || b) { - * foo(); - * } else { - * bar(); - * } - * - * In this case, `b` is evaluated always in the code path of the `else` - * block, but it's not so in the code path of the `if` block. - * So there are 3 paths. - * - * a -> foo(); - * a -> b -> foo(); - * a -> b -> bar(); - * @param {string} kind A kind string. - * If the new context is LogicalExpression's or AssignmentExpression's, this is `"&&"` or `"||"` or `"??"`. - * If it's IfStatement's or ConditionalExpression's, this is `"test"`. - * Otherwise, this is `"loop"`. - * @param {boolean} isForkingAsResult A flag that shows that goes different - * paths between `true` and `false`. - * @returns {void} - */ - pushChoiceContext(kind, isForkingAsResult) { - this.choiceContext = { - upper: this.choiceContext, - kind, - isForkingAsResult, - trueForkContext: forkContext.newEmpty(this.forkContext), - falseForkContext: forkContext.newEmpty(this.forkContext), - qqForkContext: forkContext.newEmpty(this.forkContext), - processed: false - }; - } - - /** - * Pops the last choice context and finalizes it. - * @returns {ChoiceContext} The popped context. - */ - popChoiceContext() { - const context = this.choiceContext; - - this.choiceContext = context.upper; - - const forkContext = this.forkContext; - const headSegments = forkContext.head; - - switch (context.kind) { - case "&&": - case "||": - case "??": - - /* - * If any result were not transferred from child contexts, - * this sets the head segments to both cases. - * The head segments are the path of the right-hand operand. - */ - if (!context.processed) { - context.trueForkContext.add(headSegments); - context.falseForkContext.add(headSegments); - context.qqForkContext.add(headSegments); - } - - /* - * Transfers results to upper context if this context is in - * test chunk. - */ - if (context.isForkingAsResult) { - const parentContext = this.choiceContext; - - parentContext.trueForkContext.addAll(context.trueForkContext); - parentContext.falseForkContext.addAll(context.falseForkContext); - parentContext.qqForkContext.addAll(context.qqForkContext); - parentContext.processed = true; - - return context; - } - - break; - - case "test": - if (!context.processed) { - - /* - * The head segments are the path of the `if` block here. - * Updates the `true` path with the end of the `if` block. - */ - context.trueForkContext.clear(); - context.trueForkContext.add(headSegments); - } else { - - /* - * The head segments are the path of the `else` block here. - * Updates the `false` path with the end of the `else` - * block. - */ - context.falseForkContext.clear(); - context.falseForkContext.add(headSegments); - } - - break; - - case "loop": - - /* - * Loops are addressed in popLoopContext(). - * This is called from popLoopContext(). - */ - return context; - - /* istanbul ignore next */ - default: - throw new Error("unreachable"); - } - - // Merges all paths. - const prevForkContext = context.trueForkContext; - - prevForkContext.addAll(context.falseForkContext); - forkContext.replaceHead(prevForkContext.makeNext(0, -1)); - - return context; - } - - /** - * Makes a code path segment of the right-hand operand of a logical - * expression. - * @returns {void} - */ - makeLogicalRight() { - const context = this.choiceContext; - const forkContext = this.forkContext; - - if (context.processed) { - - /* - * This got segments already from the child choice context. - * Creates the next path from own true/false fork context. - */ - let prevForkContext; - - switch (context.kind) { - case "&&": // if true then go to the right-hand side. - prevForkContext = context.trueForkContext; - break; - case "||": // if false then go to the right-hand side. - prevForkContext = context.falseForkContext; - break; - case "??": // Both true/false can short-circuit, so needs the third path to go to the right-hand side. That's qqForkContext. - prevForkContext = context.qqForkContext; - break; - default: - throw new Error("unreachable"); - } - - forkContext.replaceHead(prevForkContext.makeNext(0, -1)); - prevForkContext.clear(); - context.processed = false; - } else { - - /* - * This did not get segments from the child choice context. - * So addresses the head segments. - * The head segments are the path of the left-hand operand. - */ - switch (context.kind) { - case "&&": // the false path can short-circuit. - context.falseForkContext.add(forkContext.head); - break; - case "||": // the true path can short-circuit. - context.trueForkContext.add(forkContext.head); - break; - case "??": // both can short-circuit. - context.trueForkContext.add(forkContext.head); - context.falseForkContext.add(forkContext.head); - break; - default: - throw new Error("unreachable"); - } - - forkContext.replaceHead(forkContext.makeNext(-1, -1)); - } - } - - /** - * Makes a code path segment of the `if` block. - * @returns {void} - */ - makeIfConsequent() { - const context = this.choiceContext; - const forkContext = this.forkContext; - - /* - * If any result were not transferred from child contexts, - * this sets the head segments to both cases. - * The head segments are the path of the test expression. - */ - if (!context.processed) { - context.trueForkContext.add(forkContext.head); - context.falseForkContext.add(forkContext.head); - context.qqForkContext.add(forkContext.head); - } - - context.processed = false; - - // Creates new path from the `true` case. - forkContext.replaceHead( - context.trueForkContext.makeNext(0, -1) - ); - } - - /** - * Makes a code path segment of the `else` block. - * @returns {void} - */ - makeIfAlternate() { - const context = this.choiceContext; - const forkContext = this.forkContext; - - /* - * The head segments are the path of the `if` block. - * Updates the `true` path with the end of the `if` block. - */ - context.trueForkContext.clear(); - context.trueForkContext.add(forkContext.head); - context.processed = true; - - // Creates new path from the `false` case. - forkContext.replaceHead( - context.falseForkContext.makeNext(0, -1) - ); - } - - //-------------------------------------------------------------------------- - // ChainExpression - //-------------------------------------------------------------------------- - - /** - * Push a new `ChainExpression` context to the stack. - * This method is called on entering to each `ChainExpression` node. - * This context is used to count forking in the optional chain then merge them on the exiting from the `ChainExpression` node. - * @returns {void} - */ - pushChainContext() { - this.chainContext = { - upper: this.chainContext, - countChoiceContexts: 0 - }; - } - - /** - * Pop a `ChainExpression` context from the stack. - * This method is called on exiting from each `ChainExpression` node. - * This merges all forks of the last optional chaining. - * @returns {void} - */ - popChainContext() { - const context = this.chainContext; - - this.chainContext = context.upper; - - // pop all choice contexts of this. - for (let i = context.countChoiceContexts; i > 0; --i) { - this.popChoiceContext(); - } - } - - /** - * Create a choice context for optional access. - * This method is called on entering to each `(Call|Member)Expression[optional=true]` node. - * This creates a choice context as similar to `LogicalExpression[operator="??"]` node. - * @returns {void} - */ - makeOptionalNode() { - if (this.chainContext) { - this.chainContext.countChoiceContexts += 1; - this.pushChoiceContext("??", false); - } - } - - /** - * Create a fork. - * This method is called on entering to the `arguments|property` property of each `(Call|Member)Expression` node. - * @returns {void} - */ - makeOptionalRight() { - if (this.chainContext) { - this.makeLogicalRight(); - } - } - - //-------------------------------------------------------------------------- - // SwitchStatement - //-------------------------------------------------------------------------- - - /** - * Creates a context object of SwitchStatement and stacks it. - * @param {boolean} hasCase `true` if the switch statement has one or more - * case parts. - * @param {string|null} label The label text. - * @returns {void} - */ - pushSwitchContext(hasCase, label) { - this.switchContext = { - upper: this.switchContext, - hasCase, - defaultSegments: null, - defaultBodySegments: null, - foundDefault: false, - lastIsDefault: false, - countForks: 0 - }; - - this.pushBreakContext(true, label); - } - - /** - * Pops the last context of SwitchStatement and finalizes it. - * - * - Disposes all forking stack for `case` and `default`. - * - Creates the next code path segment from `context.brokenForkContext`. - * - If the last `SwitchCase` node is not a `default` part, creates a path - * to the `default` body. - * @returns {void} - */ - popSwitchContext() { - const context = this.switchContext; - - this.switchContext = context.upper; - - const forkContext = this.forkContext; - const brokenForkContext = this.popBreakContext().brokenForkContext; - - if (context.countForks === 0) { - - /* - * When there is only one `default` chunk and there is one or more - * `break` statements, even if forks are nothing, it needs to merge - * those. - */ - if (!brokenForkContext.empty) { - brokenForkContext.add(forkContext.makeNext(-1, -1)); - forkContext.replaceHead(brokenForkContext.makeNext(0, -1)); - } - - return; - } - - const lastSegments = forkContext.head; - - this.forkBypassPath(); - const lastCaseSegments = forkContext.head; - - /* - * `brokenForkContext` is used to make the next segment. - * It must add the last segment into `brokenForkContext`. - */ - brokenForkContext.add(lastSegments); - - /* - * A path which is failed in all case test should be connected to path - * of `default` chunk. - */ - if (!context.lastIsDefault) { - if (context.defaultBodySegments) { - - /* - * Remove a link from `default` label to its chunk. - * It's false route. - */ - removeConnection(context.defaultSegments, context.defaultBodySegments); - makeLooped(this, lastCaseSegments, context.defaultBodySegments); - } else { - - /* - * It handles the last case body as broken if `default` chunk - * does not exist. - */ - brokenForkContext.add(lastCaseSegments); - } - } - - // Pops the segment context stack until the entry segment. - for (let i = 0; i < context.countForks; ++i) { - this.forkContext = this.forkContext.upper; - } - - /* - * Creates a path from all brokenForkContext paths. - * This is a path after switch statement. - */ - this.forkContext.replaceHead(brokenForkContext.makeNext(0, -1)); - } - - /** - * Makes a code path segment for a `SwitchCase` node. - * @param {boolean} isEmpty `true` if the body is empty. - * @param {boolean} isDefault `true` if the body is the default case. - * @returns {void} - */ - makeSwitchCaseBody(isEmpty, isDefault) { - const context = this.switchContext; - - if (!context.hasCase) { - return; - } - - /* - * Merge forks. - * The parent fork context has two segments. - * Those are from the current case and the body of the previous case. - */ - const parentForkContext = this.forkContext; - const forkContext = this.pushForkContext(); - - forkContext.add(parentForkContext.makeNext(0, -1)); - - /* - * Save `default` chunk info. - * If the `default` label is not at the last, we must make a path from - * the last `case` to the `default` chunk. - */ - if (isDefault) { - context.defaultSegments = parentForkContext.head; - if (isEmpty) { - context.foundDefault = true; - } else { - context.defaultBodySegments = forkContext.head; - } - } else { - if (!isEmpty && context.foundDefault) { - context.foundDefault = false; - context.defaultBodySegments = forkContext.head; - } - } - - context.lastIsDefault = isDefault; - context.countForks += 1; - } - - //-------------------------------------------------------------------------- - // TryStatement - //-------------------------------------------------------------------------- - - /** - * Creates a context object of TryStatement and stacks it. - * @param {boolean} hasFinalizer `true` if the try statement has a - * `finally` block. - * @returns {void} - */ - pushTryContext(hasFinalizer) { - this.tryContext = { - upper: this.tryContext, - position: "try", - hasFinalizer, - - returnedForkContext: hasFinalizer - ? forkContext.newEmpty(this.forkContext) - : null, - - thrownForkContext: forkContext.newEmpty(this.forkContext), - lastOfTryIsReachable: false, - lastOfCatchIsReachable: false - }; - } - - /** - * Pops the last context of TryStatement and finalizes it. - * @returns {void} - */ - popTryContext() { - const context = this.tryContext; - - this.tryContext = context.upper; - - if (context.position === "catch") { - - // Merges two paths from the `try` block and `catch` block merely. - this.popForkContext(); - return; - } - - /* - * The following process is executed only when there is the `finally` - * block. - */ - - const returned = context.returnedForkContext; - const thrown = context.thrownForkContext; - - if (returned.empty && thrown.empty) { - return; - } - - // Separate head to normal paths and leaving paths. - const headSegments = this.forkContext.head; - - this.forkContext = this.forkContext.upper; - const normalSegments = headSegments.slice(0, headSegments.length / 2 | 0); - const leavingSegments = headSegments.slice(headSegments.length / 2 | 0); - - // Forwards the leaving path to upper contexts. - if (!returned.empty) { - getReturnContext(this).returnedForkContext.add(leavingSegments); - } - if (!thrown.empty) { - getThrowContext(this).thrownForkContext.add(leavingSegments); - } - - // Sets the normal path as the next. - this.forkContext.replaceHead(normalSegments); - - /* - * If both paths of the `try` block and the `catch` block are - * unreachable, the next path becomes unreachable as well. - */ - if (!context.lastOfTryIsReachable && !context.lastOfCatchIsReachable) { - this.forkContext.makeUnreachable(); - } - } - - /** - * Makes a code path segment for a `catch` block. - * @returns {void} - */ - makeCatchBlock() { - const context = this.tryContext; - const forkContext$1 = this.forkContext; - const thrown = context.thrownForkContext; - - // Update state. - context.position = "catch"; - context.thrownForkContext = forkContext.newEmpty(forkContext$1); - context.lastOfTryIsReachable = forkContext$1.reachable; - - // Merge thrown paths. - thrown.add(forkContext$1.head); - const thrownSegments = thrown.makeNext(0, -1); - - // Fork to a bypass and the merged thrown path. - this.pushForkContext(); - this.forkBypassPath(); - this.forkContext.add(thrownSegments); - } - - /** - * Makes a code path segment for a `finally` block. - * - * In the `finally` block, parallel paths are created. The parallel paths - * are used as leaving-paths. The leaving-paths are paths from `return` - * statements and `throw` statements in a `try` block or a `catch` block. - * @returns {void} - */ - makeFinallyBlock() { - const context = this.tryContext; - let forkContext = this.forkContext; - const returned = context.returnedForkContext; - const thrown = context.thrownForkContext; - const headOfLeavingSegments = forkContext.head; - - // Update state. - if (context.position === "catch") { - - // Merges two paths from the `try` block and `catch` block. - this.popForkContext(); - forkContext = this.forkContext; - - context.lastOfCatchIsReachable = forkContext.reachable; - } else { - context.lastOfTryIsReachable = forkContext.reachable; - } - context.position = "finally"; - - if (returned.empty && thrown.empty) { - - // This path does not leave. - return; - } - - /* - * Create a parallel segment from merging returned and thrown. - * This segment will leave at the end of this finally block. - */ - const segments = forkContext.makeNext(-1, -1); - - for (let i = 0; i < forkContext.count; ++i) { - const prevSegsOfLeavingSegment = [headOfLeavingSegments[i]]; - - for (let j = 0; j < returned.segmentsList.length; ++j) { - prevSegsOfLeavingSegment.push(returned.segmentsList[j][i]); - } - for (let j = 0; j < thrown.segmentsList.length; ++j) { - prevSegsOfLeavingSegment.push(thrown.segmentsList[j][i]); - } - - segments.push( - codePathSegment.newNext( - this.idGenerator.next(), - prevSegsOfLeavingSegment - ) - ); - } - - this.pushForkContext(true); - this.forkContext.add(segments); - } - - /** - * Makes a code path segment from the first throwable node to the `catch` - * block or the `finally` block. - * @returns {void} - */ - makeFirstThrowablePathInTryBlock() { - const forkContext = this.forkContext; - - if (!forkContext.reachable) { - return; - } - - const context = getThrowContext(this); - - if (context === this || - context.position !== "try" || - !context.thrownForkContext.empty - ) { - return; - } - - context.thrownForkContext.add(forkContext.head); - forkContext.replaceHead(forkContext.makeNext(-1, -1)); - } - - //-------------------------------------------------------------------------- - // Loop Statements - //-------------------------------------------------------------------------- - - /** - * Creates a context object of a loop statement and stacks it. - * @param {string} type The type of the node which was triggered. One of - * `WhileStatement`, `DoWhileStatement`, `ForStatement`, `ForInStatement`, - * and `ForStatement`. - * @param {string|null} label A label of the node which was triggered. - * @returns {void} - */ - pushLoopContext(type, label) { - const forkContext$1 = this.forkContext; - const breakContext = this.pushBreakContext(true, label); - - switch (type) { - case "WhileStatement": - this.pushChoiceContext("loop", false); - this.loopContext = { - upper: this.loopContext, - type, - label, - test: void 0, - continueDestSegments: null, - brokenForkContext: breakContext.brokenForkContext - }; - break; - - case "DoWhileStatement": - this.pushChoiceContext("loop", false); - this.loopContext = { - upper: this.loopContext, - type, - label, - test: void 0, - entrySegments: null, - continueForkContext: forkContext.newEmpty(forkContext$1), - brokenForkContext: breakContext.brokenForkContext - }; - break; - - case "ForStatement": - this.pushChoiceContext("loop", false); - this.loopContext = { - upper: this.loopContext, - type, - label, - test: void 0, - endOfInitSegments: null, - testSegments: null, - endOfTestSegments: null, - updateSegments: null, - endOfUpdateSegments: null, - continueDestSegments: null, - brokenForkContext: breakContext.brokenForkContext - }; - break; - - case "ForInStatement": - case "ForOfStatement": - this.loopContext = { - upper: this.loopContext, - type, - label, - prevSegments: null, - leftSegments: null, - endOfLeftSegments: null, - continueDestSegments: null, - brokenForkContext: breakContext.brokenForkContext - }; - break; - - /* istanbul ignore next */ - default: - throw new Error(`unknown type: "${type}"`); - } - } - - /** - * Pops the last context of a loop statement and finalizes it. - * @returns {void} - */ - popLoopContext() { - const context = this.loopContext; - - this.loopContext = context.upper; - - const forkContext = this.forkContext; - const brokenForkContext = this.popBreakContext().brokenForkContext; - - // Creates a looped path. - switch (context.type) { - case "WhileStatement": - case "ForStatement": - this.popChoiceContext(); - makeLooped( - this, - forkContext.head, - context.continueDestSegments - ); - break; - - case "DoWhileStatement": { - const choiceContext = this.popChoiceContext(); - - if (!choiceContext.processed) { - choiceContext.trueForkContext.add(forkContext.head); - choiceContext.falseForkContext.add(forkContext.head); - } - if (context.test !== true) { - brokenForkContext.addAll(choiceContext.falseForkContext); - } - - // `true` paths go to looping. - const segmentsList = choiceContext.trueForkContext.segmentsList; - - for (let i = 0; i < segmentsList.length; ++i) { - makeLooped( - this, - segmentsList[i], - context.entrySegments - ); - } - break; - } - - case "ForInStatement": - case "ForOfStatement": - brokenForkContext.add(forkContext.head); - makeLooped( - this, - forkContext.head, - context.leftSegments - ); - break; - - /* istanbul ignore next */ - default: - throw new Error("unreachable"); - } - - // Go next. - if (brokenForkContext.empty) { - forkContext.replaceHead(forkContext.makeUnreachable(-1, -1)); - } else { - forkContext.replaceHead(brokenForkContext.makeNext(0, -1)); - } - } - - /** - * Makes a code path segment for the test part of a WhileStatement. - * @param {boolean|undefined} test The test value (only when constant). - * @returns {void} - */ - makeWhileTest(test) { - const context = this.loopContext; - const forkContext = this.forkContext; - const testSegments = forkContext.makeNext(0, -1); - - // Update state. - context.test = test; - context.continueDestSegments = testSegments; - forkContext.replaceHead(testSegments); - } - - /** - * Makes a code path segment for the body part of a WhileStatement. - * @returns {void} - */ - makeWhileBody() { - const context = this.loopContext; - const choiceContext = this.choiceContext; - const forkContext = this.forkContext; - - if (!choiceContext.processed) { - choiceContext.trueForkContext.add(forkContext.head); - choiceContext.falseForkContext.add(forkContext.head); - } - - // Update state. - if (context.test !== true) { - context.brokenForkContext.addAll(choiceContext.falseForkContext); - } - forkContext.replaceHead(choiceContext.trueForkContext.makeNext(0, -1)); - } - - /** - * Makes a code path segment for the body part of a DoWhileStatement. - * @returns {void} - */ - makeDoWhileBody() { - const context = this.loopContext; - const forkContext = this.forkContext; - const bodySegments = forkContext.makeNext(-1, -1); - - // Update state. - context.entrySegments = bodySegments; - forkContext.replaceHead(bodySegments); - } - - /** - * Makes a code path segment for the test part of a DoWhileStatement. - * @param {boolean|undefined} test The test value (only when constant). - * @returns {void} - */ - makeDoWhileTest(test) { - const context = this.loopContext; - const forkContext = this.forkContext; - - context.test = test; - - // Creates paths of `continue` statements. - if (!context.continueForkContext.empty) { - context.continueForkContext.add(forkContext.head); - const testSegments = context.continueForkContext.makeNext(0, -1); - - forkContext.replaceHead(testSegments); - } - } - - /** - * Makes a code path segment for the test part of a ForStatement. - * @param {boolean|undefined} test The test value (only when constant). - * @returns {void} - */ - makeForTest(test) { - const context = this.loopContext; - const forkContext = this.forkContext; - const endOfInitSegments = forkContext.head; - const testSegments = forkContext.makeNext(-1, -1); - - // Update state. - context.test = test; - context.endOfInitSegments = endOfInitSegments; - context.continueDestSegments = context.testSegments = testSegments; - forkContext.replaceHead(testSegments); - } - - /** - * Makes a code path segment for the update part of a ForStatement. - * @returns {void} - */ - makeForUpdate() { - const context = this.loopContext; - const choiceContext = this.choiceContext; - const forkContext = this.forkContext; - - // Make the next paths of the test. - if (context.testSegments) { - finalizeTestSegmentsOfFor( - context, - choiceContext, - forkContext.head - ); - } else { - context.endOfInitSegments = forkContext.head; - } - - // Update state. - const updateSegments = forkContext.makeDisconnected(-1, -1); - - context.continueDestSegments = context.updateSegments = updateSegments; - forkContext.replaceHead(updateSegments); - } - - /** - * Makes a code path segment for the body part of a ForStatement. - * @returns {void} - */ - makeForBody() { - const context = this.loopContext; - const choiceContext = this.choiceContext; - const forkContext$1 = this.forkContext; - - // Update state. - if (context.updateSegments) { - context.endOfUpdateSegments = forkContext$1.head; - - // `update` -> `test` - if (context.testSegments) { - makeLooped( - this, - context.endOfUpdateSegments, - context.testSegments - ); - } - } else if (context.testSegments) { - finalizeTestSegmentsOfFor( - context, - choiceContext, - forkContext$1.head - ); - } else { - context.endOfInitSegments = forkContext$1.head; - } - - let bodySegments = context.endOfTestSegments; - - if (!bodySegments) { - - /* - * If there is not the `test` part, the `body` path comes from the - * `init` part and the `update` part. - */ - const prevForkContext = forkContext.newEmpty(forkContext$1); - - prevForkContext.add(context.endOfInitSegments); - if (context.endOfUpdateSegments) { - prevForkContext.add(context.endOfUpdateSegments); - } - - bodySegments = prevForkContext.makeNext(0, -1); - } - context.continueDestSegments = context.continueDestSegments || bodySegments; - forkContext$1.replaceHead(bodySegments); - } - - /** - * Makes a code path segment for the left part of a ForInStatement and a - * ForOfStatement. - * @returns {void} - */ - makeForInOfLeft() { - const context = this.loopContext; - const forkContext = this.forkContext; - const leftSegments = forkContext.makeDisconnected(-1, -1); - - // Update state. - context.prevSegments = forkContext.head; - context.leftSegments = context.continueDestSegments = leftSegments; - forkContext.replaceHead(leftSegments); - } - - /** - * Makes a code path segment for the right part of a ForInStatement and a - * ForOfStatement. - * @returns {void} - */ - makeForInOfRight() { - const context = this.loopContext; - const forkContext$1 = this.forkContext; - const temp = forkContext.newEmpty(forkContext$1); - - temp.add(context.prevSegments); - const rightSegments = temp.makeNext(-1, -1); - - // Update state. - context.endOfLeftSegments = forkContext$1.head; - forkContext$1.replaceHead(rightSegments); - } - - /** - * Makes a code path segment for the body part of a ForInStatement and a - * ForOfStatement. - * @returns {void} - */ - makeForInOfBody() { - const context = this.loopContext; - const forkContext$1 = this.forkContext; - const temp = forkContext.newEmpty(forkContext$1); - - temp.add(context.endOfLeftSegments); - const bodySegments = temp.makeNext(-1, -1); - - // Make a path: `right` -> `left`. - makeLooped(this, forkContext$1.head, context.leftSegments); - - // Update state. - context.brokenForkContext.add(forkContext$1.head); - forkContext$1.replaceHead(bodySegments); - } - - //-------------------------------------------------------------------------- - // Control Statements - //-------------------------------------------------------------------------- - - /** - * Creates new context for BreakStatement. - * @param {boolean} breakable The flag to indicate it can break by - * an unlabeled BreakStatement. - * @param {string|null} label The label of this context. - * @returns {Object} The new context. - */ - pushBreakContext(breakable, label) { - this.breakContext = { - upper: this.breakContext, - breakable, - label, - brokenForkContext: forkContext.newEmpty(this.forkContext) - }; - return this.breakContext; - } - - /** - * Removes the top item of the break context stack. - * @returns {Object} The removed context. - */ - popBreakContext() { - const context = this.breakContext; - const forkContext = this.forkContext; - - this.breakContext = context.upper; - - // Process this context here for other than switches and loops. - if (!context.breakable) { - const brokenForkContext = context.brokenForkContext; - - if (!brokenForkContext.empty) { - brokenForkContext.add(forkContext.head); - forkContext.replaceHead(brokenForkContext.makeNext(0, -1)); - } - } - - return context; - } - - /** - * Makes a path for a `break` statement. - * - * It registers the head segment to a context of `break`. - * It makes new unreachable segment, then it set the head with the segment. - * @param {string} label A label of the break statement. - * @returns {void} - */ - makeBreak(label) { - const forkContext = this.forkContext; - - if (!forkContext.reachable) { - return; - } - - const context = getBreakContext(this, label); - - /* istanbul ignore else: foolproof (syntax error) */ - if (context) { - context.brokenForkContext.add(forkContext.head); - } - - forkContext.replaceHead(forkContext.makeUnreachable(-1, -1)); - } - - /** - * Makes a path for a `continue` statement. - * - * It makes a looping path. - * It makes new unreachable segment, then it set the head with the segment. - * @param {string} label A label of the continue statement. - * @returns {void} - */ - makeContinue(label) { - const forkContext = this.forkContext; - - if (!forkContext.reachable) { - return; - } - - const context = getContinueContext(this, label); - - /* istanbul ignore else: foolproof (syntax error) */ - if (context) { - if (context.continueDestSegments) { - makeLooped(this, forkContext.head, context.continueDestSegments); - - // If the context is a for-in/of loop, this effects a break also. - if (context.type === "ForInStatement" || - context.type === "ForOfStatement" - ) { - context.brokenForkContext.add(forkContext.head); - } - } else { - context.continueForkContext.add(forkContext.head); - } - } - forkContext.replaceHead(forkContext.makeUnreachable(-1, -1)); - } - - /** - * Makes a path for a `return` statement. - * - * It registers the head segment to a context of `return`. - * It makes new unreachable segment, then it set the head with the segment. - * @returns {void} - */ - makeReturn() { - const forkContext = this.forkContext; - - if (forkContext.reachable) { - getReturnContext(this).returnedForkContext.add(forkContext.head); - forkContext.replaceHead(forkContext.makeUnreachable(-1, -1)); - } - } - - /** - * Makes a path for a `throw` statement. - * - * It registers the head segment to a context of `throw`. - * It makes new unreachable segment, then it set the head with the segment. - * @returns {void} - */ - makeThrow() { - const forkContext = this.forkContext; - - if (forkContext.reachable) { - getThrowContext(this).thrownForkContext.add(forkContext.head); - forkContext.replaceHead(forkContext.makeUnreachable(-1, -1)); - } - } - - /** - * Makes the final path. - * @returns {void} - */ - makeFinal() { - const segments = this.currentSegments; - - if (segments.length > 0 && segments[0].reachable) { - this.returnedForkContext.add(segments); - } - } -} - -var codePathState = CodePathState; - -/** - * @fileoverview A class of identifiers generator for code path segments. - * - * Each rule uses the identifier of code path segments to store additional - * information of the code path. - * - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -/** - * A generator for unique ids. - */ -class IdGenerator { - - // eslint-disable-next-line jsdoc/require-description - /** - * @param {string} prefix Optional. A prefix of generated ids. - */ - constructor(prefix) { - this.prefix = String(prefix); - this.n = 0; - } - - /** - * Generates id. - * @returns {string} A generated id. - */ - next() { - this.n = 1 + this.n | 0; - - /* istanbul ignore if */ - if (this.n < 0) { - this.n = 1; - } - - return this.prefix + this.n; - } -} - -var idGenerator = IdGenerator; - -/** - * @fileoverview A class of the code path. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -/** - * A code path. - */ -class CodePath { - - // eslint-disable-next-line jsdoc/require-description - /** - * @param {string} id An identifier. - * @param {CodePath|null} upper The code path of the upper function scope. - * @param {Function} onLooped A callback function to notify looping. - */ - constructor(id, upper, onLooped) { - - /** - * The identifier of this code path. - * Rules use it to store additional information of each rule. - * @type {string} - */ - this.id = id; - - /** - * The code path of the upper function scope. - * @type {CodePath|null} - */ - this.upper = upper; - - /** - * The code paths of nested function scopes. - * @type {CodePath[]} - */ - this.childCodePaths = []; - - // Initializes internal state. - Object.defineProperty( - this, - "internal", - { value: new codePathState(new idGenerator(`${id}_`), onLooped) } - ); - - // Adds this into `childCodePaths` of `upper`. - if (upper) { - upper.childCodePaths.push(this); - } - } - - /** - * Gets the state of a given code path. - * @param {CodePath} codePath A code path to get. - * @returns {CodePathState} The state of the code path. - */ - static getState(codePath) { - return codePath.internal; - } - - /** - * The initial code path segment. - * @type {CodePathSegment} - */ - get initialSegment() { - return this.internal.initialSegment; - } - - /** - * Final code path segments. - * This array is a mix of `returnedSegments` and `thrownSegments`. - * @type {CodePathSegment[]} - */ - get finalSegments() { - return this.internal.finalSegments; - } - - /** - * Final code path segments which is with `return` statements. - * This array contains the last path segment if it's reachable. - * Since the reachable last path returns `undefined`. - * @type {CodePathSegment[]} - */ - get returnedSegments() { - return this.internal.returnedForkContext; - } - - /** - * Final code path segments which is with `throw` statements. - * @type {CodePathSegment[]} - */ - get thrownSegments() { - return this.internal.thrownForkContext; - } - - /** - * Current code path segments. - * @type {CodePathSegment[]} - */ - get currentSegments() { - return this.internal.currentSegments; - } - - /** - * Traverses all segments in this code path. - * - * codePath.traverseSegments(function(segment, controller) { - * // do something. - * }); - * - * This method enumerates segments in order from the head. - * - * The `controller` object has two methods. - * - * - `controller.skip()` - Skip the following segments in this branch. - * - `controller.break()` - Skip all following segments. - * @param {Object} [options] Omittable. - * @param {CodePathSegment} [options.first] The first segment to traverse. - * @param {CodePathSegment} [options.last] The last segment to traverse. - * @param {Function} callback A callback function. - * @returns {void} - */ - traverseSegments(options, callback) { - let resolvedOptions; - let resolvedCallback; - - if (typeof options === "function") { - resolvedCallback = options; - resolvedOptions = {}; - } else { - resolvedOptions = options || {}; - resolvedCallback = callback; - } - - const startSegment = resolvedOptions.first || this.internal.initialSegment; - const lastSegment = resolvedOptions.last; - - let item = null; - let index = 0; - let end = 0; - let segment = null; - const visited = Object.create(null); - const stack = [[startSegment, 0]]; - let skippedSegment = null; - let broken = false; - const controller = { - skip() { - if (stack.length <= 1) { - broken = true; - } else { - skippedSegment = stack[stack.length - 2][0]; - } - }, - break() { - broken = true; - } - }; - - /** - * Checks a given previous segment has been visited. - * @param {CodePathSegment} prevSegment A previous segment to check. - * @returns {boolean} `true` if the segment has been visited. - */ - function isVisited(prevSegment) { - return ( - visited[prevSegment.id] || - segment.isLoopedPrevSegment(prevSegment) - ); - } - - while (stack.length > 0) { - item = stack[stack.length - 1]; - segment = item[0]; - index = item[1]; - - if (index === 0) { - - // Skip if this segment has been visited already. - if (visited[segment.id]) { - stack.pop(); - continue; - } - - // Skip if all previous segments have not been visited. - if (segment !== startSegment && - segment.prevSegments.length > 0 && - !segment.prevSegments.every(isVisited) - ) { - stack.pop(); - continue; - } - - // Reset the flag of skipping if all branches have been skipped. - if (skippedSegment && segment.prevSegments.indexOf(skippedSegment) !== -1) { - skippedSegment = null; - } - visited[segment.id] = true; - - // Call the callback when the first time. - if (!skippedSegment) { - resolvedCallback.call(this, segment, controller); - if (segment === lastSegment) { - controller.skip(); - } - if (broken) { - break; - } - } - } - - // Update the stack. - end = segment.nextSegments.length - 1; - if (index < end) { - item[1] += 1; - stack.push([segment.nextSegments[index], 0]); - } else if (index === end) { - item[0] = segment.nextSegments[index]; - item[1] = 0; - } else { - stack.pop(); - } - } - } -} - -var codePath = CodePath; - -/** - * @fileoverview A class of the code path analyzer. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -const { breakableTypePattern } = astUtils$1; - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether or not a given node is a `case` node (not `default` node). - * @param {ASTNode} node A `SwitchCase` node to check. - * @returns {boolean} `true` if the node is a `case` node (not `default` node). - */ -function isCaseNode(node) { - return Boolean(node.test); -} - -/** - * Checks whether the given logical operator is taken into account for the code - * path analysis. - * @param {string} operator The operator found in the LogicalExpression node - * @returns {boolean} `true` if the operator is "&&" or "||" or "??" - */ -function isHandledLogicalOperator(operator) { - return operator === "&&" || operator === "||" || operator === "??"; -} - -/** - * Checks whether the given assignment operator is a logical assignment operator. - * Logical assignments are taken into account for the code path analysis - * because of their short-circuiting semantics. - * @param {string} operator The operator found in the AssignmentExpression node - * @returns {boolean} `true` if the operator is "&&=" or "||=" or "??=" - */ -function isLogicalAssignmentOperator(operator) { - return operator === "&&=" || operator === "||=" || operator === "??="; -} - -/** - * Gets the label if the parent node of a given node is a LabeledStatement. - * @param {ASTNode} node A node to get. - * @returns {string|null} The label or `null`. - */ -function getLabel(node) { - if (node.parent.type === "LabeledStatement") { - return node.parent.label.name; - } - return null; -} - -/** - * Checks whether or not a given logical expression node goes different path - * between the `true` case and the `false` case. - * @param {ASTNode} node A node to check. - * @returns {boolean} `true` if the node is a test of a choice statement. - */ -function isForkingByTrueOrFalse(node) { - const parent = node.parent; - - switch (parent.type) { - case "ConditionalExpression": - case "IfStatement": - case "WhileStatement": - case "DoWhileStatement": - case "ForStatement": - return parent.test === node; - - case "LogicalExpression": - return isHandledLogicalOperator(parent.operator); - - case "AssignmentExpression": - return isLogicalAssignmentOperator(parent.operator); - - default: - return false; - } -} - -/** - * Gets the boolean value of a given literal node. - * - * This is used to detect infinity loops (e.g. `while (true) {}`). - * Statements preceded by an infinity loop are unreachable if the loop didn't - * have any `break` statement. - * @param {ASTNode} node A node to get. - * @returns {boolean|undefined} a boolean value if the node is a Literal node, - * otherwise `undefined`. - */ -function getBooleanValueIfSimpleConstant(node) { - if (node.type === "Literal") { - return Boolean(node.value); - } - return void 0; -} - -/** - * Checks that a given identifier node is a reference or not. - * - * This is used to detect the first throwable node in a `try` block. - * @param {ASTNode} node An Identifier node to check. - * @returns {boolean} `true` if the node is a reference. - */ -function isIdentifierReference(node) { - const parent = node.parent; - - switch (parent.type) { - case "LabeledStatement": - case "BreakStatement": - case "ContinueStatement": - case "ArrayPattern": - case "RestElement": - case "ImportSpecifier": - case "ImportDefaultSpecifier": - case "ImportNamespaceSpecifier": - case "CatchClause": - return false; - - case "FunctionDeclaration": - case "FunctionExpression": - case "ArrowFunctionExpression": - case "ClassDeclaration": - case "ClassExpression": - case "VariableDeclarator": - return parent.id !== node; - - case "Property": - case "MethodDefinition": - return ( - parent.key !== node || - parent.computed || - parent.shorthand - ); - - case "AssignmentPattern": - return parent.key !== node; - - default: - return true; - } -} - -/** - * Updates the current segment with the head segment. - * This is similar to local branches and tracking branches of git. - * - * To separate the current and the head is in order to not make useless segments. - * - * In this process, both "onCodePathSegmentStart" and "onCodePathSegmentEnd" - * events are fired. - * @param {CodePathAnalyzer} analyzer The instance. - * @param {ASTNode} node The current AST node. - * @returns {void} - */ -function forwardCurrentToHead(analyzer, node) { - const codePath$1 = analyzer.codePath; - const state = codePath.getState(codePath$1); - const currentSegments = state.currentSegments; - const headSegments = state.headSegments; - const end = Math.max(currentSegments.length, headSegments.length); - let i, currentSegment, headSegment; - - // Fires leaving events. - for (i = 0; i < end; ++i) { - currentSegment = currentSegments[i]; - headSegment = headSegments[i]; - - if (currentSegment !== headSegment && currentSegment) { - debugHelpers.dump(`onCodePathSegmentEnd ${currentSegment.id}`); - - if (currentSegment.reachable) { - analyzer.emitter.emit( - "onCodePathSegmentEnd", - currentSegment, - node - ); - } - } - } - - // Update state. - state.currentSegments = headSegments; - - // Fires entering events. - for (i = 0; i < end; ++i) { - currentSegment = currentSegments[i]; - headSegment = headSegments[i]; - - if (currentSegment !== headSegment && headSegment) { - debugHelpers.dump(`onCodePathSegmentStart ${headSegment.id}`); - - codePathSegment.markUsed(headSegment); - if (headSegment.reachable) { - analyzer.emitter.emit( - "onCodePathSegmentStart", - headSegment, - node - ); - } - } - } - -} - -/** - * Updates the current segment with empty. - * This is called at the last of functions or the program. - * @param {CodePathAnalyzer} analyzer The instance. - * @param {ASTNode} node The current AST node. - * @returns {void} - */ -function leaveFromCurrentSegment(analyzer, node) { - const state = codePath.getState(analyzer.codePath); - const currentSegments = state.currentSegments; - - for (let i = 0; i < currentSegments.length; ++i) { - const currentSegment = currentSegments[i]; - - debugHelpers.dump(`onCodePathSegmentEnd ${currentSegment.id}`); - if (currentSegment.reachable) { - analyzer.emitter.emit( - "onCodePathSegmentEnd", - currentSegment, - node - ); - } - } - - state.currentSegments = []; -} - -/** - * Updates the code path due to the position of a given node in the parent node - * thereof. - * - * For example, if the node is `parent.consequent`, this creates a fork from the - * current path. - * @param {CodePathAnalyzer} analyzer The instance. - * @param {ASTNode} node The current AST node. - * @returns {void} - */ -function preprocess(analyzer, node) { - const codePath$1 = analyzer.codePath; - const state = codePath.getState(codePath$1); - const parent = node.parent; - - switch (parent.type) { - - // The `arguments.length == 0` case is in `postprocess` function. - case "CallExpression": - if (parent.optional === true && parent.arguments.length >= 1 && parent.arguments[0] === node) { - state.makeOptionalRight(); - } - break; - case "MemberExpression": - if (parent.optional === true && parent.property === node) { - state.makeOptionalRight(); - } - break; - - case "LogicalExpression": - if ( - parent.right === node && - isHandledLogicalOperator(parent.operator) - ) { - state.makeLogicalRight(); - } - break; - - case "AssignmentExpression": - if ( - parent.right === node && - isLogicalAssignmentOperator(parent.operator) - ) { - state.makeLogicalRight(); - } - break; - - case "ConditionalExpression": - case "IfStatement": - - /* - * Fork if this node is at `consequent`/`alternate`. - * `popForkContext()` exists at `IfStatement:exit` and - * `ConditionalExpression:exit`. - */ - if (parent.consequent === node) { - state.makeIfConsequent(); - } else if (parent.alternate === node) { - state.makeIfAlternate(); - } - break; - - case "SwitchCase": - if (parent.consequent[0] === node) { - state.makeSwitchCaseBody(false, !parent.test); - } - break; - - case "TryStatement": - if (parent.handler === node) { - state.makeCatchBlock(); - } else if (parent.finalizer === node) { - state.makeFinallyBlock(); - } - break; - - case "WhileStatement": - if (parent.test === node) { - state.makeWhileTest(getBooleanValueIfSimpleConstant(node)); - } else { - assert__default['default'](parent.body === node); - state.makeWhileBody(); - } - break; - - case "DoWhileStatement": - if (parent.body === node) { - state.makeDoWhileBody(); - } else { - assert__default['default'](parent.test === node); - state.makeDoWhileTest(getBooleanValueIfSimpleConstant(node)); - } - break; - - case "ForStatement": - if (parent.test === node) { - state.makeForTest(getBooleanValueIfSimpleConstant(node)); - } else if (parent.update === node) { - state.makeForUpdate(); - } else if (parent.body === node) { - state.makeForBody(); - } - break; - - case "ForInStatement": - case "ForOfStatement": - if (parent.left === node) { - state.makeForInOfLeft(); - } else if (parent.right === node) { - state.makeForInOfRight(); - } else { - assert__default['default'](parent.body === node); - state.makeForInOfBody(); - } - break; - - case "AssignmentPattern": - - /* - * Fork if this node is at `right`. - * `left` is executed always, so it uses the current path. - * `popForkContext()` exists at `AssignmentPattern:exit`. - */ - if (parent.right === node) { - state.pushForkContext(); - state.forkBypassPath(); - state.forkPath(); - } - break; - } -} - -/** - * Updates the code path due to the type of a given node in entering. - * @param {CodePathAnalyzer} analyzer The instance. - * @param {ASTNode} node The current AST node. - * @returns {void} - */ -function processCodePathToEnter(analyzer, node) { - let codePath$1 = analyzer.codePath; - let state = codePath$1 && codePath.getState(codePath$1); - const parent = node.parent; - - switch (node.type) { - case "Program": - case "FunctionDeclaration": - case "FunctionExpression": - case "ArrowFunctionExpression": - if (codePath$1) { - - // Emits onCodePathSegmentStart events if updated. - forwardCurrentToHead(analyzer, node); - debugHelpers.dumpState(node, state, false); - } - - // Create the code path of this scope. - codePath$1 = analyzer.codePath = new codePath( - analyzer.idGenerator.next(), - codePath$1, - analyzer.onLooped - ); - state = codePath.getState(codePath$1); - - // Emits onCodePathStart events. - debugHelpers.dump(`onCodePathStart ${codePath$1.id}`); - analyzer.emitter.emit("onCodePathStart", codePath$1, node); - break; - - case "ChainExpression": - state.pushChainContext(); - break; - case "CallExpression": - if (node.optional === true) { - state.makeOptionalNode(); - } - break; - case "MemberExpression": - if (node.optional === true) { - state.makeOptionalNode(); - } - break; - - case "LogicalExpression": - if (isHandledLogicalOperator(node.operator)) { - state.pushChoiceContext( - node.operator, - isForkingByTrueOrFalse(node) - ); - } - break; - - case "AssignmentExpression": - if (isLogicalAssignmentOperator(node.operator)) { - state.pushChoiceContext( - node.operator.slice(0, -1), // removes `=` from the end - isForkingByTrueOrFalse(node) - ); - } - break; - - case "ConditionalExpression": - case "IfStatement": - state.pushChoiceContext("test", false); - break; - - case "SwitchStatement": - state.pushSwitchContext( - node.cases.some(isCaseNode), - getLabel(node) - ); - break; - - case "TryStatement": - state.pushTryContext(Boolean(node.finalizer)); - break; - - case "SwitchCase": - - /* - * Fork if this node is after the 2st node in `cases`. - * It's similar to `else` blocks. - * The next `test` node is processed in this path. - */ - if (parent.discriminant !== node && parent.cases[0] !== node) { - state.forkPath(); - } - break; - - case "WhileStatement": - case "DoWhileStatement": - case "ForStatement": - case "ForInStatement": - case "ForOfStatement": - state.pushLoopContext(node.type, getLabel(node)); - break; - - case "LabeledStatement": - if (!breakableTypePattern.test(node.body.type)) { - state.pushBreakContext(false, node.label.name); - } - break; - } - - // Emits onCodePathSegmentStart events if updated. - forwardCurrentToHead(analyzer, node); - debugHelpers.dumpState(node, state, false); -} - -/** - * Updates the code path due to the type of a given node in leaving. - * @param {CodePathAnalyzer} analyzer The instance. - * @param {ASTNode} node The current AST node. - * @returns {void} - */ -function processCodePathToExit(analyzer, node) { - const codePath$1 = analyzer.codePath; - const state = codePath.getState(codePath$1); - let dontForward = false; - - switch (node.type) { - case "ChainExpression": - state.popChainContext(); - break; - - case "IfStatement": - case "ConditionalExpression": - state.popChoiceContext(); - break; - - case "LogicalExpression": - if (isHandledLogicalOperator(node.operator)) { - state.popChoiceContext(); - } - break; - - case "AssignmentExpression": - if (isLogicalAssignmentOperator(node.operator)) { - state.popChoiceContext(); - } - break; - - case "SwitchStatement": - state.popSwitchContext(); - break; - - case "SwitchCase": - - /* - * This is the same as the process at the 1st `consequent` node in - * `preprocess` function. - * Must do if this `consequent` is empty. - */ - if (node.consequent.length === 0) { - state.makeSwitchCaseBody(true, !node.test); - } - if (state.forkContext.reachable) { - dontForward = true; - } - break; - - case "TryStatement": - state.popTryContext(); - break; - - case "BreakStatement": - forwardCurrentToHead(analyzer, node); - state.makeBreak(node.label && node.label.name); - dontForward = true; - break; - - case "ContinueStatement": - forwardCurrentToHead(analyzer, node); - state.makeContinue(node.label && node.label.name); - dontForward = true; - break; - - case "ReturnStatement": - forwardCurrentToHead(analyzer, node); - state.makeReturn(); - dontForward = true; - break; - - case "ThrowStatement": - forwardCurrentToHead(analyzer, node); - state.makeThrow(); - dontForward = true; - break; - - case "Identifier": - if (isIdentifierReference(node)) { - state.makeFirstThrowablePathInTryBlock(); - dontForward = true; - } - break; - - case "CallExpression": - case "ImportExpression": - case "MemberExpression": - case "NewExpression": - case "YieldExpression": - state.makeFirstThrowablePathInTryBlock(); - break; - - case "WhileStatement": - case "DoWhileStatement": - case "ForStatement": - case "ForInStatement": - case "ForOfStatement": - state.popLoopContext(); - break; - - case "AssignmentPattern": - state.popForkContext(); - break; - - case "LabeledStatement": - if (!breakableTypePattern.test(node.body.type)) { - state.popBreakContext(); - } - break; - } - - // Emits onCodePathSegmentStart events if updated. - if (!dontForward) { - forwardCurrentToHead(analyzer, node); - } - debugHelpers.dumpState(node, state, true); -} - -/** - * Updates the code path to finalize the current code path. - * @param {CodePathAnalyzer} analyzer The instance. - * @param {ASTNode} node The current AST node. - * @returns {void} - */ -function postprocess(analyzer, node) { - switch (node.type) { - case "Program": - case "FunctionDeclaration": - case "FunctionExpression": - case "ArrowFunctionExpression": { - let codePath$1 = analyzer.codePath; - - // Mark the current path as the final node. - codePath.getState(codePath$1).makeFinal(); - - // Emits onCodePathSegmentEnd event of the current segments. - leaveFromCurrentSegment(analyzer, node); - - // Emits onCodePathEnd event of this code path. - debugHelpers.dump(`onCodePathEnd ${codePath$1.id}`); - analyzer.emitter.emit("onCodePathEnd", codePath$1, node); - debugHelpers.dumpDot(codePath$1); - - codePath$1 = analyzer.codePath = analyzer.codePath.upper; - if (codePath$1) { - debugHelpers.dumpState(node, codePath.getState(codePath$1), true); - } - break; - } - - // The `arguments.length >= 1` case is in `preprocess` function. - case "CallExpression": - if (node.optional === true && node.arguments.length === 0) { - codePath.getState(analyzer.codePath).makeOptionalRight(); - } - break; - } -} - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -/** - * The class to analyze code paths. - * This class implements the EventGenerator interface. - */ -class CodePathAnalyzer { - - // eslint-disable-next-line jsdoc/require-description - /** - * @param {EventGenerator} eventGenerator An event generator to wrap. - */ - constructor(eventGenerator) { - this.original = eventGenerator; - this.emitter = eventGenerator.emitter; - this.codePath = null; - this.idGenerator = new idGenerator("s"); - this.currentNode = null; - this.onLooped = this.onLooped.bind(this); - } - - /** - * Does the process to enter a given AST node. - * This updates state of analysis and calls `enterNode` of the wrapped. - * @param {ASTNode} node A node which is entering. - * @returns {void} - */ - enterNode(node) { - this.currentNode = node; - - // Updates the code path due to node's position in its parent node. - if (node.parent) { - preprocess(this, node); - } - - /* - * Updates the code path. - * And emits onCodePathStart/onCodePathSegmentStart events. - */ - processCodePathToEnter(this, node); - - // Emits node events. - this.original.enterNode(node); - - this.currentNode = null; - } - - /** - * Does the process to leave a given AST node. - * This updates state of analysis and calls `leaveNode` of the wrapped. - * @param {ASTNode} node A node which is leaving. - * @returns {void} - */ - leaveNode(node) { - this.currentNode = node; - - /* - * Updates the code path. - * And emits onCodePathStart/onCodePathSegmentStart events. - */ - processCodePathToExit(this, node); - - // Emits node events. - this.original.leaveNode(node); - - // Emits the last onCodePathStart/onCodePathSegmentStart events. - postprocess(this, node); - - this.currentNode = null; - } - - /** - * This is called on a code path looped. - * Then this raises a looped event. - * @param {CodePathSegment} fromSegment A segment of prev. - * @param {CodePathSegment} toSegment A segment of next. - * @returns {void} - */ - onLooped(fromSegment, toSegment) { - if (fromSegment.reachable && toSegment.reachable) { - debugHelpers.dump(`onCodePathSegmentLoop ${fromSegment.id} -> ${toSegment.id}`); - this.emitter.emit( - "onCodePathSegmentLoop", - fromSegment, - toSegment, - this.currentNode - ); - } - } -} - -var codePathAnalyzer = CodePathAnalyzer; - -/** - * @fileoverview A module that filters reported problems based on `eslint-disable` and `eslint-enable` comments - * @author Teddy Katz - */ - - - -/** - * Compares the locations of two objects in a source file - * @param {{line: number, column: number}} itemA The first object - * @param {{line: number, column: number}} itemB The second object - * @returns {number} A value less than 1 if itemA appears before itemB in the source file, greater than 1 if - * itemA appears after itemB in the source file, or 0 if itemA and itemB have the same location. - */ -function compareLocations(itemA, itemB) { - return itemA.line - itemB.line || itemA.column - itemB.column; -} - -/** - * This is the same as the exported function, except that it - * doesn't handle disable-line and disable-next-line directives, and it always reports unused - * disable directives. - * @param {Object} options options for applying directives. This is the same as the options - * for the exported function, except that `reportUnusedDisableDirectives` is not supported - * (this function always reports unused disable directives). - * @returns {{problems: Problem[], unusedDisableDirectives: Problem[]}} An object with a list - * of filtered problems and unused eslint-disable directives - */ -function applyDirectives(options) { - const problems = []; - let nextDirectiveIndex = 0; - let currentGlobalDisableDirective = null; - const disabledRuleMap = new Map(); - - // enabledRules is only used when there is a current global disable directive. - const enabledRules = new Set(); - const usedDisableDirectives = new Set(); - - for (const problem of options.problems) { - while ( - nextDirectiveIndex < options.directives.length && - compareLocations(options.directives[nextDirectiveIndex], problem) <= 0 - ) { - const directive = options.directives[nextDirectiveIndex++]; - - switch (directive.type) { - case "disable": - if (directive.ruleId === null) { - currentGlobalDisableDirective = directive; - disabledRuleMap.clear(); - enabledRules.clear(); - } else if (currentGlobalDisableDirective) { - enabledRules.delete(directive.ruleId); - disabledRuleMap.set(directive.ruleId, directive); - } else { - disabledRuleMap.set(directive.ruleId, directive); - } - break; - - case "enable": - if (directive.ruleId === null) { - currentGlobalDisableDirective = null; - disabledRuleMap.clear(); - } else if (currentGlobalDisableDirective) { - enabledRules.add(directive.ruleId); - disabledRuleMap.delete(directive.ruleId); - } else { - disabledRuleMap.delete(directive.ruleId); - } - break; - - // no default - } - } - - if (disabledRuleMap.has(problem.ruleId)) { - usedDisableDirectives.add(disabledRuleMap.get(problem.ruleId)); - } else if (currentGlobalDisableDirective && !enabledRules.has(problem.ruleId)) { - usedDisableDirectives.add(currentGlobalDisableDirective); - } else { - problems.push(problem); - } - } - - const unusedDisableDirectives = options.directives - .filter(directive => directive.type === "disable" && !usedDisableDirectives.has(directive)) - .map(directive => ({ - ruleId: null, - message: directive.ruleId - ? `Unused eslint-disable directive (no problems were reported from '${directive.ruleId}').` - : "Unused eslint-disable directive (no problems were reported).", - line: directive.unprocessedDirective.line, - column: directive.unprocessedDirective.column, - severity: options.reportUnusedDisableDirectives === "warn" ? 1 : 2, - nodeType: null - })); - - return { problems, unusedDisableDirectives }; -} - -/** - * Given a list of directive comments (i.e. metadata about eslint-disable and eslint-enable comments) and a list - * of reported problems, determines which problems should be reported. - * @param {Object} options Information about directives and problems - * @param {{ - * type: ("disable"|"enable"|"disable-line"|"disable-next-line"), - * ruleId: (string|null), - * line: number, - * column: number - * }} options.directives Directive comments found in the file, with one-based columns. - * Two directive comments can only have the same location if they also have the same type (e.g. a single eslint-disable - * comment for two different rules is represented as two directives). - * @param {{ruleId: (string|null), line: number, column: number}[]} options.problems - * A list of problems reported by rules, sorted by increasing location in the file, with one-based columns. - * @param {"off" | "warn" | "error"} options.reportUnusedDisableDirectives If `"warn"` or `"error"`, adds additional problems for unused directives - * @returns {{ruleId: (string|null), line: number, column: number}[]} - * A list of reported problems that were not disabled by the directive comments. - */ -var applyDisableDirectives = ({ directives, problems, reportUnusedDisableDirectives = "off" }) => { - const blockDirectives = directives - .filter(directive => directive.type === "disable" || directive.type === "enable") - .map(directive => Object.assign({}, directive, { unprocessedDirective: directive })) - .sort(compareLocations); - - const lineDirectives = lodash__default['default'].flatMap(directives, directive => { - switch (directive.type) { - case "disable": - case "enable": - return []; - - case "disable-line": - return [ - { type: "disable", line: directive.line, column: 1, ruleId: directive.ruleId, unprocessedDirective: directive }, - { type: "enable", line: directive.line + 1, column: 0, ruleId: directive.ruleId, unprocessedDirective: directive } - ]; - - case "disable-next-line": - return [ - { type: "disable", line: directive.line + 1, column: 1, ruleId: directive.ruleId, unprocessedDirective: directive }, - { type: "enable", line: directive.line + 2, column: 0, ruleId: directive.ruleId, unprocessedDirective: directive } - ]; - - default: - throw new TypeError(`Unrecognized directive type '${directive.type}'`); - } - }).sort(compareLocations); - - const blockDirectivesResult = applyDirectives({ - problems, - directives: blockDirectives, - reportUnusedDisableDirectives - }); - const lineDirectivesResult = applyDirectives({ - problems: blockDirectivesResult.problems, - directives: lineDirectives, - reportUnusedDisableDirectives - }); - - return reportUnusedDisableDirectives !== "off" - ? lineDirectivesResult.problems - .concat(blockDirectivesResult.unusedDisableDirectives) - .concat(lineDirectivesResult.unusedDisableDirectives) - .sort(compareLocations) - : lineDirectivesResult.problems; -}; - -/** - * @fileoverview Config Comment Parser - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -const debug$5 = require$$0__default['default']("eslint:config-comment-parser"); - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -/** - * Object to parse ESLint configuration comments inside JavaScript files. - * @name ConfigCommentParser - */ -var configCommentParser = class ConfigCommentParser { - - /** - * Parses a list of "name:string_value" or/and "name" options divided by comma or - * whitespace. Used for "global" and "exported" comments. - * @param {string} string The string to parse. - * @param {Comment} comment The comment node which has the string. - * @returns {Object} Result map object of names and string values, or null values if no value was provided - */ - parseStringConfig(string, comment) { - debug$5("Parsing String config"); - - const items = {}; - - // Collapse whitespace around `:` and `,` to make parsing easier - const trimmedString = string.replace(/\s*([:,])\s*/gu, "$1"); - - trimmedString.split(/\s|,+/u).forEach(name => { - if (!name) { - return; - } - - // value defaults to null (if not provided), e.g: "foo" => ["foo", null] - const [key, value = null] = name.split(":"); - - items[key] = { value, comment }; - }); - return items; - } - - /** - * Parses a JSON-like config. - * @param {string} string The string to parse. - * @param {Object} location Start line and column of comments for potential error message. - * @returns {({success: true, config: Object}|{success: false, error: Problem})} Result map object - */ - parseJsonConfig(string, location) { - debug$5("Parsing JSON config"); - - let items = {}; - - // Parses a JSON-like comment by the same way as parsing CLI option. - try { - items = levn__default['default'].parse("Object", string) || {}; - - // Some tests say that it should ignore invalid comments such as `/*eslint no-alert:abc*/`. - // Also, commaless notations have invalid severity: - // "no-alert: 2 no-console: 2" --> {"no-alert": "2 no-console: 2"} - // Should ignore that case as well. - if (configOps.isEverySeverityValid(items)) { - return { - success: true, - config: items - }; - } - } catch { - - debug$5("Levn parsing failed; falling back to manual parsing."); - - // ignore to parse the string by a fallback. - } - - /* - * Optionator cannot parse commaless notations. - * But we are supporting that. So this is a fallback for that. - */ - items = {}; - const normalizedString = string.replace(/([-a-zA-Z0-9/]+):/gu, "\"$1\":").replace(/(\]|[0-9])\s+(?=")/u, "$1,"); - - try { - items = JSON.parse(`{${normalizedString}}`); - } catch (ex) { - debug$5("Manual parsing failed."); - - return { - success: false, - error: { - ruleId: null, - fatal: true, - severity: 2, - message: `Failed to parse JSON from '${normalizedString}': ${ex.message}`, - line: location.start.line, - column: location.start.column + 1 - } - }; - - } - - return { - success: true, - config: items - }; - } - - /** - * Parses a config of values separated by comma. - * @param {string} string The string to parse. - * @returns {Object} Result map of values and true values - */ - parseListConfig(string) { - debug$5("Parsing list config"); - - const items = {}; - - // Collapse whitespace around commas - string.replace(/\s*,\s*/gu, ",").split(/,+/u).forEach(name => { - const trimmedName = name.trim(); - - if (trimmedName) { - items[trimmedName] = true; - } - }); - return items; - } - -}; - -/** - * @fileoverview The event generator for AST nodes. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//------------------------------------------------------------------------------ -// Typedefs -//------------------------------------------------------------------------------ - -/** - * An object describing an AST selector - * @typedef {Object} ASTSelector - * @property {string} rawSelector The string that was parsed into this selector - * @property {boolean} isExit `true` if this should be emitted when exiting the node rather than when entering - * @property {Object} parsedSelector An object (from esquery) describing the matching behavior of the selector - * @property {string[]|null} listenerTypes A list of node types that could possibly cause the selector to match, - * or `null` if all node types could cause a match - * @property {number} attributeCount The total number of classes, pseudo-classes, and attribute queries in this selector - * @property {number} identifierCount The total number of identifier queries in this selector - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Gets the possible types of a selector - * @param {Object} parsedSelector An object (from esquery) describing the matching behavior of the selector - * @returns {string[]|null} The node types that could possibly trigger this selector, or `null` if all node types could trigger it - */ -function getPossibleTypes(parsedSelector) { - switch (parsedSelector.type) { - case "identifier": - return [parsedSelector.value]; - - case "matches": { - const typesForComponents = parsedSelector.selectors.map(getPossibleTypes); - - if (typesForComponents.every(Boolean)) { - return lodash__default['default'].union(...typesForComponents); - } - return null; - } - - case "compound": { - const typesForComponents = parsedSelector.selectors.map(getPossibleTypes).filter(typesForComponent => typesForComponent); - - // If all of the components could match any type, then the compound could also match any type. - if (!typesForComponents.length) { - return null; - } - - /* - * If at least one of the components could only match a particular type, the compound could only match - * the intersection of those types. - */ - return lodash__default['default'].intersection(...typesForComponents); - } - - case "child": - case "descendant": - case "sibling": - case "adjacent": - return getPossibleTypes(parsedSelector.right); - - default: - return null; - - } -} - -/** - * Counts the number of class, pseudo-class, and attribute queries in this selector - * @param {Object} parsedSelector An object (from esquery) describing the selector's matching behavior - * @returns {number} The number of class, pseudo-class, and attribute queries in this selector - */ -function countClassAttributes(parsedSelector) { - switch (parsedSelector.type) { - case "child": - case "descendant": - case "sibling": - case "adjacent": - return countClassAttributes(parsedSelector.left) + countClassAttributes(parsedSelector.right); - - case "compound": - case "not": - case "matches": - return parsedSelector.selectors.reduce((sum, childSelector) => sum + countClassAttributes(childSelector), 0); - - case "attribute": - case "field": - case "nth-child": - case "nth-last-child": - return 1; - - default: - return 0; - } -} - -/** - * Counts the number of identifier queries in this selector - * @param {Object} parsedSelector An object (from esquery) describing the selector's matching behavior - * @returns {number} The number of identifier queries - */ -function countIdentifiers(parsedSelector) { - switch (parsedSelector.type) { - case "child": - case "descendant": - case "sibling": - case "adjacent": - return countIdentifiers(parsedSelector.left) + countIdentifiers(parsedSelector.right); - - case "compound": - case "not": - case "matches": - return parsedSelector.selectors.reduce((sum, childSelector) => sum + countIdentifiers(childSelector), 0); - - case "identifier": - return 1; - - default: - return 0; - } -} - -/** - * Compares the specificity of two selector objects, with CSS-like rules. - * @param {ASTSelector} selectorA An AST selector descriptor - * @param {ASTSelector} selectorB Another AST selector descriptor - * @returns {number} - * a value less than 0 if selectorA is less specific than selectorB - * a value greater than 0 if selectorA is more specific than selectorB - * a value less than 0 if selectorA and selectorB have the same specificity, and selectorA <= selectorB alphabetically - * a value greater than 0 if selectorA and selectorB have the same specificity, and selectorA > selectorB alphabetically - */ -function compareSpecificity(selectorA, selectorB) { - return selectorA.attributeCount - selectorB.attributeCount || - selectorA.identifierCount - selectorB.identifierCount || - (selectorA.rawSelector <= selectorB.rawSelector ? -1 : 1); -} - -/** - * Parses a raw selector string, and throws a useful error if parsing fails. - * @param {string} rawSelector A raw AST selector - * @returns {Object} An object (from esquery) describing the matching behavior of this selector - * @throws {Error} An error if the selector is invalid - */ -function tryParseSelector(rawSelector) { - try { - return esquery__default['default'].parse(rawSelector.replace(/:exit$/u, "")); - } catch (err) { - if (err.location && err.location.start && typeof err.location.start.offset === "number") { - throw new SyntaxError(`Syntax error in selector "${rawSelector}" at position ${err.location.start.offset}: ${err.message}`); - } - throw err; - } -} - -/** - * Parses a raw selector string, and returns the parsed selector along with specificity and type information. - * @param {string} rawSelector A raw AST selector - * @returns {ASTSelector} A selector descriptor - */ -const parseSelector = lodash__default['default'].memoize(rawSelector => { - const parsedSelector = tryParseSelector(rawSelector); - - return { - rawSelector, - isExit: rawSelector.endsWith(":exit"), - parsedSelector, - listenerTypes: getPossibleTypes(parsedSelector), - attributeCount: countClassAttributes(parsedSelector), - identifierCount: countIdentifiers(parsedSelector) - }; -}); - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -/** - * The event generator for AST nodes. - * This implements below interface. - * - * ```ts - * interface EventGenerator { - * emitter: SafeEmitter; - * enterNode(node: ASTNode): void; - * leaveNode(node: ASTNode): void; - * } - * ``` - */ -class NodeEventGenerator { - - // eslint-disable-next-line jsdoc/require-description - /** - * @param {SafeEmitter} emitter - * An SafeEmitter which is the destination of events. This emitter must already - * have registered listeners for all of the events that it needs to listen for. - * (See lib/linter/safe-emitter.js for more details on `SafeEmitter`.) - * @param {ESQueryOptions} esqueryOptions `esquery` options for traversing custom nodes. - * @returns {NodeEventGenerator} new instance - */ - constructor(emitter, esqueryOptions) { - this.emitter = emitter; - this.esqueryOptions = esqueryOptions; - this.currentAncestry = []; - this.enterSelectorsByNodeType = new Map(); - this.exitSelectorsByNodeType = new Map(); - this.anyTypeEnterSelectors = []; - this.anyTypeExitSelectors = []; - - emitter.eventNames().forEach(rawSelector => { - const selector = parseSelector(rawSelector); - - if (selector.listenerTypes) { - const typeMap = selector.isExit ? this.exitSelectorsByNodeType : this.enterSelectorsByNodeType; - - selector.listenerTypes.forEach(nodeType => { - if (!typeMap.has(nodeType)) { - typeMap.set(nodeType, []); - } - typeMap.get(nodeType).push(selector); - }); - return; - } - const selectors = selector.isExit ? this.anyTypeExitSelectors : this.anyTypeEnterSelectors; - - selectors.push(selector); - }); - - this.anyTypeEnterSelectors.sort(compareSpecificity); - this.anyTypeExitSelectors.sort(compareSpecificity); - this.enterSelectorsByNodeType.forEach(selectorList => selectorList.sort(compareSpecificity)); - this.exitSelectorsByNodeType.forEach(selectorList => selectorList.sort(compareSpecificity)); - } - - /** - * Checks a selector against a node, and emits it if it matches - * @param {ASTNode} node The node to check - * @param {ASTSelector} selector An AST selector descriptor - * @returns {void} - */ - applySelector(node, selector) { - if (esquery__default['default'].matches(node, selector.parsedSelector, this.currentAncestry, this.esqueryOptions)) { - this.emitter.emit(selector.rawSelector, node); - } - } - - /** - * Applies all appropriate selectors to a node, in specificity order - * @param {ASTNode} node The node to check - * @param {boolean} isExit `false` if the node is currently being entered, `true` if it's currently being exited - * @returns {void} - */ - applySelectors(node, isExit) { - const selectorsByNodeType = (isExit ? this.exitSelectorsByNodeType : this.enterSelectorsByNodeType).get(node.type) || []; - const anyTypeSelectors = isExit ? this.anyTypeExitSelectors : this.anyTypeEnterSelectors; - - /* - * selectorsByNodeType and anyTypeSelectors were already sorted by specificity in the constructor. - * Iterate through each of them, applying selectors in the right order. - */ - let selectorsByTypeIndex = 0; - let anyTypeSelectorsIndex = 0; - - while (selectorsByTypeIndex < selectorsByNodeType.length || anyTypeSelectorsIndex < anyTypeSelectors.length) { - if ( - selectorsByTypeIndex >= selectorsByNodeType.length || - anyTypeSelectorsIndex < anyTypeSelectors.length && - compareSpecificity(anyTypeSelectors[anyTypeSelectorsIndex], selectorsByNodeType[selectorsByTypeIndex]) < 0 - ) { - this.applySelector(node, anyTypeSelectors[anyTypeSelectorsIndex++]); - } else { - this.applySelector(node, selectorsByNodeType[selectorsByTypeIndex++]); - } - } - } - - /** - * Emits an event of entering AST node. - * @param {ASTNode} node A node which was entered. - * @returns {void} - */ - enterNode(node) { - if (node.parent) { - this.currentAncestry.unshift(node.parent); - } - this.applySelectors(node, false); - } - - /** - * Emits an event of leaving AST node. - * @param {ASTNode} node A node which was left. - * @returns {void} - */ - leaveNode(node) { - this.applySelectors(node, true); - this.currentAncestry.shift(); - } -} - -var nodeEventGenerator = NodeEventGenerator; - -/** - * @fileoverview An object that creates fix commands for rules. - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -// none! - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Creates a fix command that inserts text at the specified index in the source text. - * @param {int} index The 0-based index at which to insert the new text. - * @param {string} text The text to insert. - * @returns {Object} The fix command. - * @private - */ -function insertTextAt(index, text) { - return { - range: [index, index], - text - }; -} - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -/** - * Creates code fixing commands for rules. - */ - -const ruleFixer = Object.freeze({ - - /** - * Creates a fix command that inserts text after the given node or token. - * The fix is not applied until applyFixes() is called. - * @param {ASTNode|Token} nodeOrToken The node or token to insert after. - * @param {string} text The text to insert. - * @returns {Object} The fix command. - */ - insertTextAfter(nodeOrToken, text) { - return this.insertTextAfterRange(nodeOrToken.range, text); - }, - - /** - * Creates a fix command that inserts text after the specified range in the source text. - * The fix is not applied until applyFixes() is called. - * @param {int[]} range The range to replace, first item is start of range, second - * is end of range. - * @param {string} text The text to insert. - * @returns {Object} The fix command. - */ - insertTextAfterRange(range, text) { - return insertTextAt(range[1], text); - }, - - /** - * Creates a fix command that inserts text before the given node or token. - * The fix is not applied until applyFixes() is called. - * @param {ASTNode|Token} nodeOrToken The node or token to insert before. - * @param {string} text The text to insert. - * @returns {Object} The fix command. - */ - insertTextBefore(nodeOrToken, text) { - return this.insertTextBeforeRange(nodeOrToken.range, text); - }, - - /** - * Creates a fix command that inserts text before the specified range in the source text. - * The fix is not applied until applyFixes() is called. - * @param {int[]} range The range to replace, first item is start of range, second - * is end of range. - * @param {string} text The text to insert. - * @returns {Object} The fix command. - */ - insertTextBeforeRange(range, text) { - return insertTextAt(range[0], text); - }, - - /** - * Creates a fix command that replaces text at the node or token. - * The fix is not applied until applyFixes() is called. - * @param {ASTNode|Token} nodeOrToken The node or token to remove. - * @param {string} text The text to insert. - * @returns {Object} The fix command. - */ - replaceText(nodeOrToken, text) { - return this.replaceTextRange(nodeOrToken.range, text); - }, - - /** - * Creates a fix command that replaces text at the specified range in the source text. - * The fix is not applied until applyFixes() is called. - * @param {int[]} range The range to replace, first item is start of range, second - * is end of range. - * @param {string} text The text to insert. - * @returns {Object} The fix command. - */ - replaceTextRange(range, text) { - return { - range, - text - }; - }, - - /** - * Creates a fix command that removes the node or token from the source. - * The fix is not applied until applyFixes() is called. - * @param {ASTNode|Token} nodeOrToken The node or token to remove. - * @returns {Object} The fix command. - */ - remove(nodeOrToken) { - return this.removeRange(nodeOrToken.range); - }, - - /** - * Creates a fix command that removes the specified range of text from the source. - * The fix is not applied until applyFixes() is called. - * @param {int[]} range The range to remove, first item is start of range, second - * is end of range. - * @returns {Object} The fix command. - */ - removeRange(range) { - return { - range, - text: "" - }; - } - -}); - - -var ruleFixer_1 = ruleFixer; - -/** - * @fileoverview Interpolate keys from an object into a string with {{ }} markers. - * @author Jed Fox - */ - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -var interpolate$1 = (text, data) => { - if (!data) { - return text; - } - - // Substitution content for any {{ }} markers. - return text.replace(/\{\{([^{}]+?)\}\}/gu, (fullMatch, termWithWhitespace) => { - const term = termWithWhitespace.trim(); - - if (term in data) { - return data[term]; - } - - // Preserve old behavior: If parameter name not provided, don't replace it. - return fullMatch; - }); -}; - -/** - * @fileoverview A helper that translates context.report() calls from the rule API into generic problem objects - * @author Teddy Katz - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - - -//------------------------------------------------------------------------------ -// Typedefs -//------------------------------------------------------------------------------ - -/** - * An error message description - * @typedef {Object} MessageDescriptor - * @property {ASTNode} [node] The reported node - * @property {Location} loc The location of the problem. - * @property {string} message The problem message. - * @property {Object} [data] Optional data to use to fill in placeholders in the - * message. - * @property {Function} [fix] The function to call that creates a fix command. - * @property {Array<{desc?: string, messageId?: string, fix: Function}>} suggest Suggestion descriptions and functions to create a the associated fixes. - */ - -/** - * Information about the report - * @typedef {Object} ReportInfo - * @property {string} ruleId - * @property {(0|1|2)} severity - * @property {(string|undefined)} message - * @property {(string|undefined)} [messageId] - * @property {number} line - * @property {number} column - * @property {(number|undefined)} [endLine] - * @property {(number|undefined)} [endColumn] - * @property {(string|null)} nodeType - * @property {string} source - * @property {({text: string, range: (number[]|null)}|null)} [fix] - * @property {Array<{text: string, range: (number[]|null)}|null>} [suggestions] - */ - -//------------------------------------------------------------------------------ -// Module Definition -//------------------------------------------------------------------------------ - - -/** - * Translates a multi-argument context.report() call into a single object argument call - * @param {...*} args A list of arguments passed to `context.report` - * @returns {MessageDescriptor} A normalized object containing report information - */ -function normalizeMultiArgReportCall(...args) { - - // If there is one argument, it is considered to be a new-style call already. - if (args.length === 1) { - - // Shallow clone the object to avoid surprises if reusing the descriptor - return Object.assign({}, args[0]); - } - - // If the second argument is a string, the arguments are interpreted as [node, message, data, fix]. - if (typeof args[1] === "string") { - return { - node: args[0], - message: args[1], - data: args[2], - fix: args[3] - }; - } - - // Otherwise, the arguments are interpreted as [node, loc, message, data, fix]. - return { - node: args[0], - loc: args[1], - message: args[2], - data: args[3], - fix: args[4] - }; -} - -/** - * Asserts that either a loc or a node was provided, and the node is valid if it was provided. - * @param {MessageDescriptor} descriptor A descriptor to validate - * @returns {void} - * @throws AssertionError if neither a node nor a loc was provided, or if the node is not an object - */ -function assertValidNodeInfo(descriptor) { - if (descriptor.node) { - assert__default['default'](typeof descriptor.node === "object", "Node must be an object"); - } else { - assert__default['default'](descriptor.loc, "Node must be provided when reporting error if location is not provided"); - } -} - -/** - * Normalizes a MessageDescriptor to always have a `loc` with `start` and `end` properties - * @param {MessageDescriptor} descriptor A descriptor for the report from a rule. - * @returns {{start: Location, end: (Location|null)}} An updated location that infers the `start` and `end` properties - * from the `node` of the original descriptor, or infers the `start` from the `loc` of the original descriptor. - */ -function normalizeReportLoc(descriptor) { - if (descriptor.loc) { - if (descriptor.loc.start) { - return descriptor.loc; - } - return { start: descriptor.loc, end: null }; - } - return descriptor.node.loc; -} - -/** - * Check that a fix has a valid range. - * @param {Fix|null} fix The fix to validate. - * @returns {void} - */ -function assertValidFix(fix) { - if (fix) { - assert__default['default'](fix.range && typeof fix.range[0] === "number" && typeof fix.range[1] === "number", `Fix has invalid range: ${JSON.stringify(fix, null, 2)}`); - } -} - -/** - * Compares items in a fixes array by range. - * @param {Fix} a The first message. - * @param {Fix} b The second message. - * @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal. - * @private - */ -function compareFixesByRange(a, b) { - return a.range[0] - b.range[0] || a.range[1] - b.range[1]; -} - -/** - * Merges the given fixes array into one. - * @param {Fix[]} fixes The fixes to merge. - * @param {SourceCode} sourceCode The source code object to get the text between fixes. - * @returns {{text: string, range: number[]}} The merged fixes - */ -function mergeFixes(fixes, sourceCode) { - for (const fix of fixes) { - assertValidFix(fix); - } - - if (fixes.length === 0) { - return null; - } - if (fixes.length === 1) { - return fixes[0]; - } - - fixes.sort(compareFixesByRange); - - const originalText = sourceCode.text; - const start = fixes[0].range[0]; - const end = fixes[fixes.length - 1].range[1]; - let text = ""; - let lastPos = Number.MIN_SAFE_INTEGER; - - for (const fix of fixes) { - assert__default['default'](fix.range[0] >= lastPos, "Fix objects must not be overlapped in a report."); - - if (fix.range[0] >= 0) { - text += originalText.slice(Math.max(0, start, lastPos), fix.range[0]); - } - text += fix.text; - lastPos = fix.range[1]; - } - text += originalText.slice(Math.max(0, start, lastPos), end); - - return { range: [start, end], text }; -} - -/** - * Gets one fix object from the given descriptor. - * If the descriptor retrieves multiple fixes, this merges those to one. - * @param {MessageDescriptor} descriptor The report descriptor. - * @param {SourceCode} sourceCode The source code object to get text between fixes. - * @returns {({text: string, range: number[]}|null)} The fix for the descriptor - */ -function normalizeFixes(descriptor, sourceCode) { - if (typeof descriptor.fix !== "function") { - return null; - } - - // @type {null | Fix | Fix[] | IterableIterator} - const fix = descriptor.fix(ruleFixer_1); - - // Merge to one. - if (fix && Symbol.iterator in fix) { - return mergeFixes(Array.from(fix), sourceCode); - } - - assertValidFix(fix); - return fix; -} - -/** - * Gets an array of suggestion objects from the given descriptor. - * @param {MessageDescriptor} descriptor The report descriptor. - * @param {SourceCode} sourceCode The source code object to get text between fixes. - * @param {Object} messages Object of meta messages for the rule. - * @returns {Array} The suggestions for the descriptor - */ -function mapSuggestions(descriptor, sourceCode, messages) { - if (!descriptor.suggest || !Array.isArray(descriptor.suggest)) { - return []; - } - - return descriptor.suggest - .map(suggestInfo => { - const computedDesc = suggestInfo.desc || messages[suggestInfo.messageId]; - - return { - ...suggestInfo, - desc: interpolate$1(computedDesc, suggestInfo.data), - fix: normalizeFixes(suggestInfo, sourceCode) - }; - }) - - // Remove suggestions that didn't provide a fix - .filter(({ fix }) => fix); -} - -/** - * Creates information about the report from a descriptor - * @param {Object} options Information about the problem - * @param {string} options.ruleId Rule ID - * @param {(0|1|2)} options.severity Rule severity - * @param {(ASTNode|null)} options.node Node - * @param {string} options.message Error message - * @param {string} [options.messageId] The error message ID. - * @param {{start: SourceLocation, end: (SourceLocation|null)}} options.loc Start and end location - * @param {{text: string, range: (number[]|null)}} options.fix The fix object - * @param {Array<{text: string, range: (number[]|null)}>} options.suggestions The array of suggestions objects - * @returns {function(...args): ReportInfo} Function that returns information about the report - */ -function createProblem(options) { - const problem = { - ruleId: options.ruleId, - severity: options.severity, - message: options.message, - line: options.loc.start.line, - column: options.loc.start.column + 1, - nodeType: options.node && options.node.type || null - }; - - /* - * If this isn’t in the conditional, some of the tests fail - * because `messageId` is present in the problem object - */ - if (options.messageId) { - problem.messageId = options.messageId; - } - - if (options.loc.end) { - problem.endLine = options.loc.end.line; - problem.endColumn = options.loc.end.column + 1; - } - - if (options.fix) { - problem.fix = options.fix; - } - - if (options.suggestions && options.suggestions.length > 0) { - problem.suggestions = options.suggestions; - } - - return problem; -} - -/** - * Validates that suggestions are properly defined. Throws if an error is detected. - * @param {Array<{ desc?: string, messageId?: string }>} suggest The incoming suggest data. - * @param {Object} messages Object of meta messages for the rule. - * @returns {void} - */ -function validateSuggestions(suggest, messages) { - if (suggest && Array.isArray(suggest)) { - suggest.forEach(suggestion => { - if (suggestion.messageId) { - const { messageId } = suggestion; - - if (!messages) { - throw new TypeError(`context.report() called with a suggest option with a messageId '${messageId}', but no messages were present in the rule metadata.`); - } - - if (!messages[messageId]) { - throw new TypeError(`context.report() called with a suggest option with a messageId '${messageId}' which is not present in the 'messages' config: ${JSON.stringify(messages, null, 2)}`); - } - - if (suggestion.desc) { - throw new TypeError("context.report() called with a suggest option that defines both a 'messageId' and an 'desc'. Please only pass one."); - } - } else if (!suggestion.desc) { - throw new TypeError("context.report() called with a suggest option that doesn't have either a `desc` or `messageId`"); - } - - if (typeof suggestion.fix !== "function") { - throw new TypeError(`context.report() called with a suggest option without a fix function. See: ${suggestion}`); - } - }); - } -} - -/** - * Returns a function that converts the arguments of a `context.report` call from a rule into a reported - * problem for the Node.js API. - * @param {{ruleId: string, severity: number, sourceCode: SourceCode, messageIds: Object, disableFixes: boolean}} metadata Metadata for the reported problem - * @param {SourceCode} sourceCode The `SourceCode` instance for the text being linted - * @returns {function(...args): ReportInfo} Function that returns information about the report - */ - -var reportTranslator = function createReportTranslator(metadata) { - - /* - * `createReportTranslator` gets called once per enabled rule per file. It needs to be very performant. - * The report translator itself (i.e. the function that `createReportTranslator` returns) gets - * called every time a rule reports a problem, which happens much less frequently (usually, the vast - * majority of rules don't report any problems for a given file). - */ - return (...args) => { - const descriptor = normalizeMultiArgReportCall(...args); - const messages = metadata.messageIds; - - assertValidNodeInfo(descriptor); - - let computedMessage; - - if (descriptor.messageId) { - if (!messages) { - throw new TypeError("context.report() called with a messageId, but no messages were present in the rule metadata."); - } - const id = descriptor.messageId; - - if (descriptor.message) { - throw new TypeError("context.report() called with a message and a messageId. Please only pass one."); - } - if (!messages || !Object.prototype.hasOwnProperty.call(messages, id)) { - throw new TypeError(`context.report() called with a messageId of '${id}' which is not present in the 'messages' config: ${JSON.stringify(messages, null, 2)}`); - } - computedMessage = messages[id]; - } else if (descriptor.message) { - computedMessage = descriptor.message; - } else { - throw new TypeError("Missing `message` property in report() call; add a message that describes the linting problem."); - } - - validateSuggestions(descriptor.suggest, messages); - - return createProblem({ - ruleId: metadata.ruleId, - severity: metadata.severity, - node: descriptor.node, - message: interpolate$1(computedMessage, descriptor.data), - messageId: descriptor.messageId, - loc: normalizeReportLoc(descriptor), - fix: metadata.disableFixes ? null : normalizeFixes(descriptor, metadata.sourceCode), - suggestions: metadata.disableFixes ? [] : mapSuggestions(descriptor, metadata.sourceCode, messages) - }); - }; -}; - -/** - * @fileoverview `Map` to load rules lazily. - * @author Toru Nagashima - */ - -const debug$4 = require$$0__default['default']("eslint:rules"); - -/** @typedef {import("./types").Rule} Rule */ - -/** - * The `Map` object that loads each rule when it's accessed. - * @example - * const rules = new LazyLoadingRuleMap([ - * ["eqeqeq", () => require("eqeqeq")], - * ["semi", () => require("semi")], - * ["no-unused-vars", () => require("no-unused-vars")], - * ]) - * - * rules.get("semi") // call `() => require("semi")` here. - * - * @extends {Map Rule>} - */ -class LazyLoadingRuleMap$1 extends Map { - - /** - * Initialize this map. - * @param {Array<[string, function(): Rule]>} loaders The rule loaders. - */ - constructor(loaders) { - let remaining = loaders.length; - - super( - debug$4.enabled - ? loaders.map(([ruleId, load]) => { - let cache = null; - - return [ - ruleId, - () => { - if (!cache) { - debug$4("Loading rule %o (remaining=%d)", ruleId, --remaining); - cache = load(); - } - return cache; - } - ]; - }) - : loaders - ); - - // `super(...iterable)` uses `this.set()`, so disable it here. - Object.defineProperty(LazyLoadingRuleMap$1.prototype, "set", { - configurable: true, - value: void 0 - }); - } - - /** - * Get a rule. - * Each rule will be loaded on the first access. - * @param {string} ruleId The rule ID to get. - * @returns {Rule|undefined} The rule. - */ - get(ruleId) { - const load = super.get(ruleId); - - return load && load(); - } - - /** - * Iterate rules. - * @returns {IterableIterator} Rules. - */ - *values() { - for (const load of super.values()) { - yield load(); - } - } - - /** - * Iterate rules. - * @returns {IterableIterator<[string, Rule]>} Rules. - */ - *entries() { - for (const [ruleId, load] of super.entries()) { - yield [ruleId, load()]; - } - } - - /** - * Call a function with each rule. - * @param {Function} callbackFn The callback function. - * @param {any} [thisArg] The object to pass to `this` of the callback function. - * @returns {void} - */ - forEach(callbackFn, thisArg) { - for (const [ruleId, load] of super.entries()) { - callbackFn.call(thisArg, load(), ruleId, this); - } - } -} - -// Forbid mutation. -Object.defineProperties(LazyLoadingRuleMap$1.prototype, { - clear: { configurable: true, value: void 0 }, - delete: { configurable: true, value: void 0 }, - [Symbol.iterator]: { - configurable: true, - writable: true, - value: LazyLoadingRuleMap$1.prototype.entries - } -}); - -var lazyLoadingRuleMap = { LazyLoadingRuleMap: LazyLoadingRuleMap$1 }; - -/** - * @fileoverview Common utils for AST. - * @author Gyandeep Singh - */ - -var astUtils = createCommonjsModule(function (module) { - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -const { - breakableTypePattern, - createGlobalLinebreakMatcher, - lineBreakPattern, - shebangPattern -} = astUtils$1; - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const anyFunctionPattern = /^(?:Function(?:Declaration|Expression)|ArrowFunctionExpression)$/u; -const anyLoopPattern = /^(?:DoWhile|For|ForIn|ForOf|While)Statement$/u; -const arrayOrTypedArrayPattern = /Array$/u; -const arrayMethodPattern = /^(?:every|filter|find|findIndex|forEach|map|some)$/u; -const bindOrCallOrApplyPattern = /^(?:bind|call|apply)$/u; -const thisTagPattern = /^[\s*]*@this/mu; - - -const COMMENTS_IGNORE_PATTERN = /^\s*(?:eslint|jshint\s+|jslint\s+|istanbul\s+|globals?\s+|exported\s+|jscs)/u; -const LINEBREAKS = new Set(["\r\n", "\r", "\n", "\u2028", "\u2029"]); - -// A set of node types that can contain a list of statements -const STATEMENT_LIST_PARENTS = new Set(["Program", "BlockStatement", "SwitchCase"]); - -const DECIMAL_INTEGER_PATTERN = /^(?:0|0[0-7]*[89]\d*|[1-9](?:_?\d)*)$/u; - -// Tests the presence of at least one LegacyOctalEscapeSequence or NonOctalDecimalEscapeSequence in a raw string -const OCTAL_OR_NON_OCTAL_DECIMAL_ESCAPE_PATTERN = /^(?:[^\\]|\\.)*\\(?:[1-9]|0[0-9])/su; - -const LOGICAL_ASSIGNMENT_OPERATORS = new Set(["&&=", "||=", "??="]); - -/** - * Checks reference if is non initializer and writable. - * @param {Reference} reference A reference to check. - * @param {int} index The index of the reference in the references. - * @param {Reference[]} references The array that the reference belongs to. - * @returns {boolean} Success/Failure - * @private - */ -function isModifyingReference(reference, index, references) { - const identifier = reference.identifier; - - /* - * Destructuring assignments can have multiple default value, so - * possibly there are multiple writeable references for the same - * identifier. - */ - const modifyingDifferentIdentifier = index === 0 || - references[index - 1].identifier !== identifier; - - return (identifier && - reference.init === false && - reference.isWrite() && - modifyingDifferentIdentifier - ); -} - -/** - * Checks whether the given string starts with uppercase or not. - * @param {string} s The string to check. - * @returns {boolean} `true` if the string starts with uppercase. - */ -function startsWithUpperCase(s) { - return s[0] !== s[0].toLocaleLowerCase(); -} - -/** - * Checks whether or not a node is a constructor. - * @param {ASTNode} node A function node to check. - * @returns {boolean} Whether or not a node is a constructor. - */ -function isES5Constructor(node) { - return (node.id && startsWithUpperCase(node.id.name)); -} - -/** - * Finds a function node from ancestors of a node. - * @param {ASTNode} node A start node to find. - * @returns {Node|null} A found function node. - */ -function getUpperFunction(node) { - for (let currentNode = node; currentNode; currentNode = currentNode.parent) { - if (anyFunctionPattern.test(currentNode.type)) { - return currentNode; - } - } - return null; -} - -/** - * Checks whether a given node is a function node or not. - * The following types are function nodes: - * - * - ArrowFunctionExpression - * - FunctionDeclaration - * - FunctionExpression - * @param {ASTNode|null} node A node to check. - * @returns {boolean} `true` if the node is a function node. - */ -function isFunction(node) { - return Boolean(node && anyFunctionPattern.test(node.type)); -} - -/** - * Checks whether a given node is a loop node or not. - * The following types are loop nodes: - * - * - DoWhileStatement - * - ForInStatement - * - ForOfStatement - * - ForStatement - * - WhileStatement - * @param {ASTNode|null} node A node to check. - * @returns {boolean} `true` if the node is a loop node. - */ -function isLoop(node) { - return Boolean(node && anyLoopPattern.test(node.type)); -} - -/** - * Checks whether the given node is in a loop or not. - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if the node is in a loop. - */ -function isInLoop(node) { - for (let currentNode = node; currentNode && !isFunction(currentNode); currentNode = currentNode.parent) { - if (isLoop(currentNode)) { - return true; - } - } - - return false; -} - -/** - * Determines whether the given node is a `null` literal. - * @param {ASTNode} node The node to check - * @returns {boolean} `true` if the node is a `null` literal - */ -function isNullLiteral(node) { - - /* - * Checking `node.value === null` does not guarantee that a literal is a null literal. - * When parsing values that cannot be represented in the current environment (e.g. unicode - * regexes in Node 4), `node.value` is set to `null` because it wouldn't be possible to - * set `node.value` to a unicode regex. To make sure a literal is actually `null`, check - * `node.regex` instead. Also see: https://github.com/eslint/eslint/issues/8020 - */ - return node.type === "Literal" && node.value === null && !node.regex && !node.bigint; -} - -/** - * Checks whether or not a node is `null` or `undefined`. - * @param {ASTNode} node A node to check. - * @returns {boolean} Whether or not the node is a `null` or `undefined`. - * @public - */ -function isNullOrUndefined(node) { - return ( - isNullLiteral(node) || - (node.type === "Identifier" && node.name === "undefined") || - (node.type === "UnaryExpression" && node.operator === "void") - ); -} - -/** - * Checks whether or not a node is callee. - * @param {ASTNode} node A node to check. - * @returns {boolean} Whether or not the node is callee. - */ -function isCallee(node) { - return node.parent.type === "CallExpression" && node.parent.callee === node; -} - -/** - * Returns the result of the string conversion applied to the evaluated value of the given expression node, - * if it can be determined statically. - * - * This function returns a `string` value for all `Literal` nodes and simple `TemplateLiteral` nodes only. - * In all other cases, this function returns `null`. - * @param {ASTNode} node Expression node. - * @returns {string|null} String value if it can be determined. Otherwise, `null`. - */ -function getStaticStringValue(node) { - switch (node.type) { - case "Literal": - if (node.value === null) { - if (isNullLiteral(node)) { - return String(node.value); // "null" - } - if (node.regex) { - return `/${node.regex.pattern}/${node.regex.flags}`; - } - if (node.bigint) { - return node.bigint; - } - - // Otherwise, this is an unknown literal. The function will return null. - - } else { - return String(node.value); - } - break; - case "TemplateLiteral": - if (node.expressions.length === 0 && node.quasis.length === 1) { - return node.quasis[0].value.cooked; - } - break; - - // no default - } - - return null; -} - -/** - * Gets the property name of a given node. - * The node can be a MemberExpression, a Property, or a MethodDefinition. - * - * If the name is dynamic, this returns `null`. - * - * For examples: - * - * a.b // => "b" - * a["b"] // => "b" - * a['b'] // => "b" - * a[`b`] // => "b" - * a[100] // => "100" - * a[b] // => null - * a["a" + "b"] // => null - * a[tag`b`] // => null - * a[`${b}`] // => null - * - * let a = {b: 1} // => "b" - * let a = {["b"]: 1} // => "b" - * let a = {['b']: 1} // => "b" - * let a = {[`b`]: 1} // => "b" - * let a = {[100]: 1} // => "100" - * let a = {[b]: 1} // => null - * let a = {["a" + "b"]: 1} // => null - * let a = {[tag`b`]: 1} // => null - * let a = {[`${b}`]: 1} // => null - * @param {ASTNode} node The node to get. - * @returns {string|null} The property name if static. Otherwise, null. - */ -function getStaticPropertyName(node) { - let prop; - - switch (node && node.type) { - case "ChainExpression": - return getStaticPropertyName(node.expression); - - case "Property": - case "MethodDefinition": - prop = node.key; - break; - - case "MemberExpression": - prop = node.property; - break; - - // no default - } - - if (prop) { - if (prop.type === "Identifier" && !node.computed) { - return prop.name; - } - - return getStaticStringValue(prop); - } - - return null; -} - -/** - * Retrieve `ChainExpression#expression` value if the given node a `ChainExpression` node. Otherwise, pass through it. - * @param {ASTNode} node The node to address. - * @returns {ASTNode} The `ChainExpression#expression` value if the node is a `ChainExpression` node. Otherwise, the node. - */ -function skipChainExpression(node) { - return node && node.type === "ChainExpression" ? node.expression : node; -} - -/** - * Check if the `actual` is an expected value. - * @param {string} actual The string value to check. - * @param {string | RegExp} expected The expected string value or pattern. - * @returns {boolean} `true` if the `actual` is an expected value. - */ -function checkText(actual, expected) { - return typeof expected === "string" - ? actual === expected - : expected.test(actual); -} - -/** - * Check if a given node is an Identifier node with a given name. - * @param {ASTNode} node The node to check. - * @param {string | RegExp} name The expected name or the expected pattern of the object name. - * @returns {boolean} `true` if the node is an Identifier node with the name. - */ -function isSpecificId(node, name) { - return node.type === "Identifier" && checkText(node.name, name); -} - -/** - * Check if a given node is member access with a given object name and property name pair. - * This is regardless of optional or not. - * @param {ASTNode} node The node to check. - * @param {string | RegExp | null} objectName The expected name or the expected pattern of the object name. If this is nullish, this method doesn't check object. - * @param {string | RegExp | null} propertyName The expected name or the expected pattern of the property name. If this is nullish, this method doesn't check property. - * @returns {boolean} `true` if the node is member access with the object name and property name pair. - * The node is a `MemberExpression` or `ChainExpression`. - */ -function isSpecificMemberAccess(node, objectName, propertyName) { - const checkNode = skipChainExpression(node); - - if (checkNode.type !== "MemberExpression") { - return false; - } - - if (objectName && !isSpecificId(checkNode.object, objectName)) { - return false; - } - - if (propertyName) { - const actualPropertyName = getStaticPropertyName(checkNode); - - if (typeof actualPropertyName !== "string" || !checkText(actualPropertyName, propertyName)) { - return false; - } - } - - return true; -} - -/** - * Check if two literal nodes are the same value. - * @param {ASTNode} left The Literal node to compare. - * @param {ASTNode} right The other Literal node to compare. - * @returns {boolean} `true` if the two literal nodes are the same value. - */ -function equalLiteralValue(left, right) { - - // RegExp literal. - if (left.regex || right.regex) { - return Boolean( - left.regex && - right.regex && - left.regex.pattern === right.regex.pattern && - left.regex.flags === right.regex.flags - ); - } - - // BigInt literal. - if (left.bigint || right.bigint) { - return left.bigint === right.bigint; - } - - return left.value === right.value; -} - -/** - * Check if two expressions reference the same value. For example: - * a = a - * a.b = a.b - * a[0] = a[0] - * a['b'] = a['b'] - * @param {ASTNode} left The left side of the comparison. - * @param {ASTNode} right The right side of the comparison. - * @param {boolean} [disableStaticComputedKey] Don't address `a.b` and `a["b"]` are the same if `true`. For backward compatibility. - * @returns {boolean} `true` if both sides match and reference the same value. - */ -function isSameReference(left, right, disableStaticComputedKey = false) { - if (left.type !== right.type) { - - // Handle `a.b` and `a?.b` are samely. - if (left.type === "ChainExpression") { - return isSameReference(left.expression, right, disableStaticComputedKey); - } - if (right.type === "ChainExpression") { - return isSameReference(left, right.expression, disableStaticComputedKey); - } - - return false; - } - - switch (left.type) { - case "Super": - case "ThisExpression": - return true; - - case "Identifier": - return left.name === right.name; - case "Literal": - return equalLiteralValue(left, right); - - case "ChainExpression": - return isSameReference(left.expression, right.expression, disableStaticComputedKey); - - case "MemberExpression": { - if (!disableStaticComputedKey) { - const nameA = getStaticPropertyName(left); - - // x.y = x["y"] - if (nameA !== null) { - return ( - isSameReference(left.object, right.object, disableStaticComputedKey) && - nameA === getStaticPropertyName(right) - ); - } - } - - /* - * x[0] = x[0] - * x[y] = x[y] - * x.y = x.y - */ - return ( - left.computed === right.computed && - isSameReference(left.object, right.object, disableStaticComputedKey) && - isSameReference(left.property, right.property, disableStaticComputedKey) - ); - } - - default: - return false; - } -} - -/** - * Checks whether or not a node is `Reflect.apply`. - * @param {ASTNode} node A node to check. - * @returns {boolean} Whether or not the node is a `Reflect.apply`. - */ -function isReflectApply(node) { - return isSpecificMemberAccess(node, "Reflect", "apply"); -} - -/** - * Checks whether or not a node is `Array.from`. - * @param {ASTNode} node A node to check. - * @returns {boolean} Whether or not the node is a `Array.from`. - */ -function isArrayFromMethod(node) { - return isSpecificMemberAccess(node, arrayOrTypedArrayPattern, "from"); -} - -/** - * Checks whether or not a node is a method which has `thisArg`. - * @param {ASTNode} node A node to check. - * @returns {boolean} Whether or not the node is a method which has `thisArg`. - */ -function isMethodWhichHasThisArg(node) { - return isSpecificMemberAccess(node, null, arrayMethodPattern); -} - -/** - * Creates the negate function of the given function. - * @param {Function} f The function to negate. - * @returns {Function} Negated function. - */ -function negate(f) { - return token => !f(token); -} - -/** - * Checks whether or not a node has a `@this` tag in its comments. - * @param {ASTNode} node A node to check. - * @param {SourceCode} sourceCode A SourceCode instance to get comments. - * @returns {boolean} Whether or not the node has a `@this` tag in its comments. - */ -function hasJSDocThisTag(node, sourceCode) { - const jsdocComment = sourceCode.getJSDocComment(node); - - if (jsdocComment && thisTagPattern.test(jsdocComment.value)) { - return true; - } - - // Checks `@this` in its leading comments for callbacks, - // because callbacks don't have its JSDoc comment. - // e.g. - // sinon.test(/* @this sinon.Sandbox */function() { this.spy(); }); - return sourceCode.getCommentsBefore(node).some(comment => thisTagPattern.test(comment.value)); -} - -/** - * Determines if a node is surrounded by parentheses. - * @param {SourceCode} sourceCode The ESLint source code object - * @param {ASTNode} node The node to be checked. - * @returns {boolean} True if the node is parenthesised. - * @private - */ -function isParenthesised(sourceCode, node) { - const previousToken = sourceCode.getTokenBefore(node), - nextToken = sourceCode.getTokenAfter(node); - - return Boolean(previousToken && nextToken) && - previousToken.value === "(" && previousToken.range[1] <= node.range[0] && - nextToken.value === ")" && nextToken.range[0] >= node.range[1]; -} - -/** - * Checks if the given token is an arrow token or not. - * @param {Token} token The token to check. - * @returns {boolean} `true` if the token is an arrow token. - */ -function isArrowToken(token) { - return token.value === "=>" && token.type === "Punctuator"; -} - -/** - * Checks if the given token is a comma token or not. - * @param {Token} token The token to check. - * @returns {boolean} `true` if the token is a comma token. - */ -function isCommaToken(token) { - return token.value === "," && token.type === "Punctuator"; -} - -/** - * Checks if the given token is a dot token or not. - * @param {Token} token The token to check. - * @returns {boolean} `true` if the token is a dot token. - */ -function isDotToken(token) { - return token.value === "." && token.type === "Punctuator"; -} - -/** - * Checks if the given token is a `?.` token or not. - * @param {Token} token The token to check. - * @returns {boolean} `true` if the token is a `?.` token. - */ -function isQuestionDotToken(token) { - return token.value === "?." && token.type === "Punctuator"; -} - -/** - * Checks if the given token is a semicolon token or not. - * @param {Token} token The token to check. - * @returns {boolean} `true` if the token is a semicolon token. - */ -function isSemicolonToken(token) { - return token.value === ";" && token.type === "Punctuator"; -} - -/** - * Checks if the given token is a colon token or not. - * @param {Token} token The token to check. - * @returns {boolean} `true` if the token is a colon token. - */ -function isColonToken(token) { - return token.value === ":" && token.type === "Punctuator"; -} - -/** - * Checks if the given token is an opening parenthesis token or not. - * @param {Token} token The token to check. - * @returns {boolean} `true` if the token is an opening parenthesis token. - */ -function isOpeningParenToken(token) { - return token.value === "(" && token.type === "Punctuator"; -} - -/** - * Checks if the given token is a closing parenthesis token or not. - * @param {Token} token The token to check. - * @returns {boolean} `true` if the token is a closing parenthesis token. - */ -function isClosingParenToken(token) { - return token.value === ")" && token.type === "Punctuator"; -} - -/** - * Checks if the given token is an opening square bracket token or not. - * @param {Token} token The token to check. - * @returns {boolean} `true` if the token is an opening square bracket token. - */ -function isOpeningBracketToken(token) { - return token.value === "[" && token.type === "Punctuator"; -} - -/** - * Checks if the given token is a closing square bracket token or not. - * @param {Token} token The token to check. - * @returns {boolean} `true` if the token is a closing square bracket token. - */ -function isClosingBracketToken(token) { - return token.value === "]" && token.type === "Punctuator"; -} - -/** - * Checks if the given token is an opening brace token or not. - * @param {Token} token The token to check. - * @returns {boolean} `true` if the token is an opening brace token. - */ -function isOpeningBraceToken(token) { - return token.value === "{" && token.type === "Punctuator"; -} - -/** - * Checks if the given token is a closing brace token or not. - * @param {Token} token The token to check. - * @returns {boolean} `true` if the token is a closing brace token. - */ -function isClosingBraceToken(token) { - return token.value === "}" && token.type === "Punctuator"; -} - -/** - * Checks if the given token is a comment token or not. - * @param {Token} token The token to check. - * @returns {boolean} `true` if the token is a comment token. - */ -function isCommentToken(token) { - return token.type === "Line" || token.type === "Block" || token.type === "Shebang"; -} - -/** - * Checks if the given token is a keyword token or not. - * @param {Token} token The token to check. - * @returns {boolean} `true` if the token is a keyword token. - */ -function isKeywordToken(token) { - return token.type === "Keyword"; -} - -/** - * Gets the `(` token of the given function node. - * @param {ASTNode} node The function node to get. - * @param {SourceCode} sourceCode The source code object to get tokens. - * @returns {Token} `(` token. - */ -function getOpeningParenOfParams(node, sourceCode) { - return node.id - ? sourceCode.getTokenAfter(node.id, isOpeningParenToken) - : sourceCode.getFirstToken(node, isOpeningParenToken); -} - -/** - * Checks whether or not the tokens of two given nodes are same. - * @param {ASTNode} left A node 1 to compare. - * @param {ASTNode} right A node 2 to compare. - * @param {SourceCode} sourceCode The ESLint source code object. - * @returns {boolean} the source code for the given node. - */ -function equalTokens(left, right, sourceCode) { - const tokensL = sourceCode.getTokens(left); - const tokensR = sourceCode.getTokens(right); - - if (tokensL.length !== tokensR.length) { - return false; - } - for (let i = 0; i < tokensL.length; ++i) { - if (tokensL[i].type !== tokensR[i].type || - tokensL[i].value !== tokensR[i].value - ) { - return false; - } - } - - return true; -} - -/** - * Check if the given node is a true logical expression or not. - * - * The three binary expressions logical-or (`||`), logical-and (`&&`), and - * coalesce (`??`) are known as `ShortCircuitExpression`. - * But ESTree represents those by `LogicalExpression` node. - * - * This function rejects coalesce expressions of `LogicalExpression` node. - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if the node is `&&` or `||`. - * @see https://tc39.es/ecma262/#prod-ShortCircuitExpression - */ -function isLogicalExpression(node) { - return ( - node.type === "LogicalExpression" && - (node.operator === "&&" || node.operator === "||") - ); -} - -/** - * Check if the given node is a nullish coalescing expression or not. - * - * The three binary expressions logical-or (`||`), logical-and (`&&`), and - * coalesce (`??`) are known as `ShortCircuitExpression`. - * But ESTree represents those by `LogicalExpression` node. - * - * This function finds only coalesce expressions of `LogicalExpression` node. - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if the node is `??`. - */ -function isCoalesceExpression(node) { - return node.type === "LogicalExpression" && node.operator === "??"; -} - -/** - * Check if given two nodes are the pair of a logical expression and a coalesce expression. - * @param {ASTNode} left A node to check. - * @param {ASTNode} right Another node to check. - * @returns {boolean} `true` if the two nodes are the pair of a logical expression and a coalesce expression. - */ -function isMixedLogicalAndCoalesceExpressions(left, right) { - return ( - (isLogicalExpression(left) && isCoalesceExpression(right)) || - (isCoalesceExpression(left) && isLogicalExpression(right)) - ); -} - -/** - * Checks if the given operator is a logical assignment operator. - * @param {string} operator The operator to check. - * @returns {boolean} `true` if the operator is a logical assignment operator. - */ -function isLogicalAssignmentOperator(operator) { - return LOGICAL_ASSIGNMENT_OPERATORS.has(operator); -} - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -module.exports = { - COMMENTS_IGNORE_PATTERN, - LINEBREAKS, - LINEBREAK_MATCHER: lineBreakPattern, - SHEBANG_MATCHER: shebangPattern, - STATEMENT_LIST_PARENTS, - - /** - * Determines whether two adjacent tokens are on the same line. - * @param {Object} left The left token object. - * @param {Object} right The right token object. - * @returns {boolean} Whether or not the tokens are on the same line. - * @public - */ - isTokenOnSameLine(left, right) { - return left.loc.end.line === right.loc.start.line; - }, - - isNullOrUndefined, - isCallee, - isES5Constructor, - getUpperFunction, - isFunction, - isLoop, - isInLoop, - isArrayFromMethod, - isParenthesised, - createGlobalLinebreakMatcher, - equalTokens, - - isArrowToken, - isClosingBraceToken, - isClosingBracketToken, - isClosingParenToken, - isColonToken, - isCommaToken, - isCommentToken, - isDotToken, - isQuestionDotToken, - isKeywordToken, - isNotClosingBraceToken: negate(isClosingBraceToken), - isNotClosingBracketToken: negate(isClosingBracketToken), - isNotClosingParenToken: negate(isClosingParenToken), - isNotColonToken: negate(isColonToken), - isNotCommaToken: negate(isCommaToken), - isNotDotToken: negate(isDotToken), - isNotQuestionDotToken: negate(isQuestionDotToken), - isNotOpeningBraceToken: negate(isOpeningBraceToken), - isNotOpeningBracketToken: negate(isOpeningBracketToken), - isNotOpeningParenToken: negate(isOpeningParenToken), - isNotSemicolonToken: negate(isSemicolonToken), - isOpeningBraceToken, - isOpeningBracketToken, - isOpeningParenToken, - isSemicolonToken, - - /** - * Checks whether or not a given node is a string literal. - * @param {ASTNode} node A node to check. - * @returns {boolean} `true` if the node is a string literal. - */ - isStringLiteral(node) { - return ( - (node.type === "Literal" && typeof node.value === "string") || - node.type === "TemplateLiteral" - ); - }, - - /** - * Checks whether a given node is a breakable statement or not. - * The node is breakable if the node is one of the following type: - * - * - DoWhileStatement - * - ForInStatement - * - ForOfStatement - * - ForStatement - * - SwitchStatement - * - WhileStatement - * @param {ASTNode} node A node to check. - * @returns {boolean} `true` if the node is breakable. - */ - isBreakableStatement(node) { - return breakableTypePattern.test(node.type); - }, - - /** - * Gets references which are non initializer and writable. - * @param {Reference[]} references An array of references. - * @returns {Reference[]} An array of only references which are non initializer and writable. - * @public - */ - getModifyingReferences(references) { - return references.filter(isModifyingReference); - }, - - /** - * Validate that a string passed in is surrounded by the specified character - * @param {string} val The text to check. - * @param {string} character The character to see if it's surrounded by. - * @returns {boolean} True if the text is surrounded by the character, false if not. - * @private - */ - isSurroundedBy(val, character) { - return val[0] === character && val[val.length - 1] === character; - }, - - /** - * Returns whether the provided node is an ESLint directive comment or not - * @param {Line|Block} node The comment token to be checked - * @returns {boolean} `true` if the node is an ESLint directive comment - */ - isDirectiveComment(node) { - const comment = node.value.trim(); - - return ( - node.type === "Line" && comment.indexOf("eslint-") === 0 || - node.type === "Block" && ( - comment.indexOf("global ") === 0 || - comment.indexOf("eslint ") === 0 || - comment.indexOf("eslint-") === 0 - ) - ); - }, - - /** - * Gets the trailing statement of a given node. - * - * if (code) - * consequent; - * - * When taking this `IfStatement`, returns `consequent;` statement. - * @param {ASTNode} A node to get. - * @returns {ASTNode|null} The trailing statement's node. - */ - getTrailingStatement: esutils__default['default'].ast.trailingStatement, - - /** - * Finds the variable by a given name in a given scope and its upper scopes. - * @param {eslint-scope.Scope} initScope A scope to start find. - * @param {string} name A variable name to find. - * @returns {eslint-scope.Variable|null} A found variable or `null`. - */ - getVariableByName(initScope, name) { - let scope = initScope; - - while (scope) { - const variable = scope.set.get(name); - - if (variable) { - return variable; - } - - scope = scope.upper; - } - - return null; - }, - - /** - * Checks whether or not a given function node is the default `this` binding. - * - * First, this checks the node: - * - * - The function name does not start with uppercase. It's a convention to capitalize the names - * of constructor functions. This check is not performed if `capIsConstructor` is set to `false`. - * - The function does not have a JSDoc comment that has a @this tag. - * - * Next, this checks the location of the node. - * If the location is below, this judges `this` is valid. - * - * - The location is not on an object literal. - * - The location is not assigned to a variable which starts with an uppercase letter. Applies to anonymous - * functions only, as the name of the variable is considered to be the name of the function in this case. - * This check is not performed if `capIsConstructor` is set to `false`. - * - The location is not on an ES2015 class. - * - Its `bind`/`call`/`apply` method is not called directly. - * - The function is not a callback of array methods (such as `.forEach()`) if `thisArg` is given. - * @param {ASTNode} node A function node to check. - * @param {SourceCode} sourceCode A SourceCode instance to get comments. - * @param {boolean} [capIsConstructor = true] `false` disables the assumption that functions which name starts - * with an uppercase or are assigned to a variable which name starts with an uppercase are constructors. - * @returns {boolean} The function node is the default `this` binding. - */ - isDefaultThisBinding(node, sourceCode, { capIsConstructor = true } = {}) { - if ( - (capIsConstructor && isES5Constructor(node)) || - hasJSDocThisTag(node, sourceCode) - ) { - return false; - } - const isAnonymous = node.id === null; - let currentNode = node; - - while (currentNode) { - const parent = currentNode.parent; - - switch (parent.type) { - - /* - * Looks up the destination. - * e.g., obj.foo = nativeFoo || function foo() { ... }; - */ - case "LogicalExpression": - case "ConditionalExpression": - case "ChainExpression": - currentNode = parent; - break; - - /* - * If the upper function is IIFE, checks the destination of the return value. - * e.g. - * obj.foo = (function() { - * // setup... - * return function foo() { ... }; - * })(); - * obj.foo = (() => - * function foo() { ... } - * )(); - */ - case "ReturnStatement": { - const func = getUpperFunction(parent); - - if (func === null || !isCallee(func)) { - return true; - } - currentNode = func.parent; - break; - } - case "ArrowFunctionExpression": - if (currentNode !== parent.body || !isCallee(parent)) { - return true; - } - currentNode = parent.parent; - break; - - /* - * e.g. - * var obj = { foo() { ... } }; - * var obj = { foo: function() { ... } }; - * class A { constructor() { ... } } - * class A { foo() { ... } } - * class A { get foo() { ... } } - * class A { set foo() { ... } } - * class A { static foo() { ... } } - */ - case "Property": - case "MethodDefinition": - return parent.value !== currentNode; - - /* - * e.g. - * obj.foo = function foo() { ... }; - * Foo = function() { ... }; - * [obj.foo = function foo() { ... }] = a; - * [Foo = function() { ... }] = a; - */ - case "AssignmentExpression": - case "AssignmentPattern": - if (parent.left.type === "MemberExpression") { - return false; - } - if ( - capIsConstructor && - isAnonymous && - parent.left.type === "Identifier" && - startsWithUpperCase(parent.left.name) - ) { - return false; - } - return true; - - /* - * e.g. - * var Foo = function() { ... }; - */ - case "VariableDeclarator": - return !( - capIsConstructor && - isAnonymous && - parent.init === currentNode && - parent.id.type === "Identifier" && - startsWithUpperCase(parent.id.name) - ); - - /* - * e.g. - * var foo = function foo() { ... }.bind(obj); - * (function foo() { ... }).call(obj); - * (function foo() { ... }).apply(obj, []); - */ - case "MemberExpression": - if ( - parent.object === currentNode && - isSpecificMemberAccess(parent, null, bindOrCallOrApplyPattern) - ) { - const maybeCalleeNode = parent.parent.type === "ChainExpression" - ? parent.parent - : parent; - - return !( - isCallee(maybeCalleeNode) && - maybeCalleeNode.parent.arguments.length >= 1 && - !isNullOrUndefined(maybeCalleeNode.parent.arguments[0]) - ); - } - return true; - - /* - * e.g. - * Reflect.apply(function() {}, obj, []); - * Array.from([], function() {}, obj); - * list.forEach(function() {}, obj); - */ - case "CallExpression": - if (isReflectApply(parent.callee)) { - return ( - parent.arguments.length !== 3 || - parent.arguments[0] !== currentNode || - isNullOrUndefined(parent.arguments[1]) - ); - } - if (isArrayFromMethod(parent.callee)) { - return ( - parent.arguments.length !== 3 || - parent.arguments[1] !== currentNode || - isNullOrUndefined(parent.arguments[2]) - ); - } - if (isMethodWhichHasThisArg(parent.callee)) { - return ( - parent.arguments.length !== 2 || - parent.arguments[0] !== currentNode || - isNullOrUndefined(parent.arguments[1]) - ); - } - return true; - - // Otherwise `this` is default. - default: - return true; - } - } - - /* istanbul ignore next */ - return true; - }, - - /** - * Get the precedence level based on the node type - * @param {ASTNode} node node to evaluate - * @returns {int} precedence level - * @private - */ - getPrecedence(node) { - switch (node.type) { - case "SequenceExpression": - return 0; - - case "AssignmentExpression": - case "ArrowFunctionExpression": - case "YieldExpression": - return 1; - - case "ConditionalExpression": - return 3; - - case "LogicalExpression": - switch (node.operator) { - case "||": - case "??": - return 4; - case "&&": - return 5; - - // no default - } - - /* falls through */ - - case "BinaryExpression": - - switch (node.operator) { - case "|": - return 6; - case "^": - return 7; - case "&": - return 8; - case "==": - case "!=": - case "===": - case "!==": - return 9; - case "<": - case "<=": - case ">": - case ">=": - case "in": - case "instanceof": - return 10; - case "<<": - case ">>": - case ">>>": - return 11; - case "+": - case "-": - return 12; - case "*": - case "/": - case "%": - return 13; - case "**": - return 15; - - // no default - } - - /* falls through */ - - case "UnaryExpression": - case "AwaitExpression": - return 16; - - case "UpdateExpression": - return 17; - - case "CallExpression": - case "ChainExpression": - case "ImportExpression": - return 18; - - case "NewExpression": - return 19; - - default: - return 20; - } - }, - - /** - * Checks whether the given node is an empty block node or not. - * @param {ASTNode|null} node The node to check. - * @returns {boolean} `true` if the node is an empty block. - */ - isEmptyBlock(node) { - return Boolean(node && node.type === "BlockStatement" && node.body.length === 0); - }, - - /** - * Checks whether the given node is an empty function node or not. - * @param {ASTNode|null} node The node to check. - * @returns {boolean} `true` if the node is an empty function. - */ - isEmptyFunction(node) { - return isFunction(node) && module.exports.isEmptyBlock(node.body); - }, - - /** - * Get directives from directive prologue of a Program or Function node. - * @param {ASTNode} node The node to check. - * @returns {ASTNode[]} The directives found in the directive prologue. - */ - getDirectivePrologue(node) { - const directives = []; - - // Directive prologues only occur at the top of files or functions. - if ( - node.type === "Program" || - node.type === "FunctionDeclaration" || - node.type === "FunctionExpression" || - - /* - * Do not check arrow functions with implicit return. - * `() => "use strict";` returns the string `"use strict"`. - */ - (node.type === "ArrowFunctionExpression" && node.body.type === "BlockStatement") - ) { - const statements = node.type === "Program" ? node.body : node.body.body; - - for (const statement of statements) { - if ( - statement.type === "ExpressionStatement" && - statement.expression.type === "Literal" - ) { - directives.push(statement); - } else { - break; - } - } - } - - return directives; - }, - - - /** - * Determines whether this node is a decimal integer literal. If a node is a decimal integer literal, a dot added - * after the node will be parsed as a decimal point, rather than a property-access dot. - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if this node is a decimal integer. - * @example - * - * 0 // true - * 5 // true - * 50 // true - * 5_000 // true - * 1_234_56 // true - * 08 // true - * 0192 // true - * 5. // false - * .5 // false - * 5.0 // false - * 5.00_00 // false - * 05 // false - * 0x5 // false - * 0b101 // false - * 0b11_01 // false - * 0o5 // false - * 5e0 // false - * 5e1_000 // false - * 5n // false - * 1_000n // false - * '5' // false - */ - isDecimalInteger(node) { - return node.type === "Literal" && typeof node.value === "number" && - DECIMAL_INTEGER_PATTERN.test(node.raw); - }, - - /** - * Determines whether this token is a decimal integer numeric token. - * This is similar to isDecimalInteger(), but for tokens. - * @param {Token} token The token to check. - * @returns {boolean} `true` if this token is a decimal integer. - */ - isDecimalIntegerNumericToken(token) { - return token.type === "Numeric" && DECIMAL_INTEGER_PATTERN.test(token.value); - }, - - /** - * Gets the name and kind of the given function node. - * - * - `function foo() {}` .................... `function 'foo'` - * - `(function foo() {})` .................. `function 'foo'` - * - `(function() {})` ...................... `function` - * - `function* foo() {}` ................... `generator function 'foo'` - * - `(function* foo() {})` ................. `generator function 'foo'` - * - `(function*() {})` ..................... `generator function` - * - `() => {}` ............................. `arrow function` - * - `async () => {}` ....................... `async arrow function` - * - `({ foo: function foo() {} })` ......... `method 'foo'` - * - `({ foo: function() {} })` ............. `method 'foo'` - * - `({ ['foo']: function() {} })` ......... `method 'foo'` - * - `({ [foo]: function() {} })` ........... `method` - * - `({ foo() {} })` ....................... `method 'foo'` - * - `({ foo: function* foo() {} })` ........ `generator method 'foo'` - * - `({ foo: function*() {} })` ............ `generator method 'foo'` - * - `({ ['foo']: function*() {} })` ........ `generator method 'foo'` - * - `({ [foo]: function*() {} })` .......... `generator method` - * - `({ *foo() {} })` ...................... `generator method 'foo'` - * - `({ foo: async function foo() {} })` ... `async method 'foo'` - * - `({ foo: async function() {} })` ....... `async method 'foo'` - * - `({ ['foo']: async function() {} })` ... `async method 'foo'` - * - `({ [foo]: async function() {} })` ..... `async method` - * - `({ async foo() {} })` ................. `async method 'foo'` - * - `({ get foo() {} })` ................... `getter 'foo'` - * - `({ set foo(a) {} })` .................. `setter 'foo'` - * - `class A { constructor() {} }` ......... `constructor` - * - `class A { foo() {} }` ................. `method 'foo'` - * - `class A { *foo() {} }` ................ `generator method 'foo'` - * - `class A { async foo() {} }` ........... `async method 'foo'` - * - `class A { ['foo']() {} }` ............. `method 'foo'` - * - `class A { *['foo']() {} }` ............ `generator method 'foo'` - * - `class A { async ['foo']() {} }` ....... `async method 'foo'` - * - `class A { [foo]() {} }` ............... `method` - * - `class A { *[foo]() {} }` .............. `generator method` - * - `class A { async [foo]() {} }` ......... `async method` - * - `class A { get foo() {} }` ............. `getter 'foo'` - * - `class A { set foo(a) {} }` ............ `setter 'foo'` - * - `class A { static foo() {} }` .......... `static method 'foo'` - * - `class A { static *foo() {} }` ......... `static generator method 'foo'` - * - `class A { static async foo() {} }` .... `static async method 'foo'` - * - `class A { static get foo() {} }` ...... `static getter 'foo'` - * - `class A { static set foo(a) {} }` ..... `static setter 'foo'` - * @param {ASTNode} node The function node to get. - * @returns {string} The name and kind of the function node. - */ - getFunctionNameWithKind(node) { - const parent = node.parent; - const tokens = []; - - if (parent.type === "MethodDefinition" && parent.static) { - tokens.push("static"); - } - if (node.async) { - tokens.push("async"); - } - if (node.generator) { - tokens.push("generator"); - } - - if (node.type === "ArrowFunctionExpression") { - tokens.push("arrow", "function"); - } else if (parent.type === "Property" || parent.type === "MethodDefinition") { - if (parent.kind === "constructor") { - return "constructor"; - } - if (parent.kind === "get") { - tokens.push("getter"); - } else if (parent.kind === "set") { - tokens.push("setter"); - } else { - tokens.push("method"); - } - } else { - tokens.push("function"); - } - - if (node.id) { - tokens.push(`'${node.id.name}'`); - } else { - const name = getStaticPropertyName(parent); - - if (name !== null) { - tokens.push(`'${name}'`); - } - } - - return tokens.join(" "); - }, - - /** - * Gets the location of the given function node for reporting. - * - * - `function foo() {}` - * ^^^^^^^^^^^^ - * - `(function foo() {})` - * ^^^^^^^^^^^^ - * - `(function() {})` - * ^^^^^^^^ - * - `function* foo() {}` - * ^^^^^^^^^^^^^ - * - `(function* foo() {})` - * ^^^^^^^^^^^^^ - * - `(function*() {})` - * ^^^^^^^^^ - * - `() => {}` - * ^^ - * - `async () => {}` - * ^^ - * - `({ foo: function foo() {} })` - * ^^^^^^^^^^^^^^^^^ - * - `({ foo: function() {} })` - * ^^^^^^^^^^^^^ - * - `({ ['foo']: function() {} })` - * ^^^^^^^^^^^^^^^^^ - * - `({ [foo]: function() {} })` - * ^^^^^^^^^^^^^^^ - * - `({ foo() {} })` - * ^^^ - * - `({ foo: function* foo() {} })` - * ^^^^^^^^^^^^^^^^^^ - * - `({ foo: function*() {} })` - * ^^^^^^^^^^^^^^ - * - `({ ['foo']: function*() {} })` - * ^^^^^^^^^^^^^^^^^^ - * - `({ [foo]: function*() {} })` - * ^^^^^^^^^^^^^^^^ - * - `({ *foo() {} })` - * ^^^^ - * - `({ foo: async function foo() {} })` - * ^^^^^^^^^^^^^^^^^^^^^^^ - * - `({ foo: async function() {} })` - * ^^^^^^^^^^^^^^^^^^^ - * - `({ ['foo']: async function() {} })` - * ^^^^^^^^^^^^^^^^^^^^^^^ - * - `({ [foo]: async function() {} })` - * ^^^^^^^^^^^^^^^^^^^^^ - * - `({ async foo() {} })` - * ^^^^^^^^^ - * - `({ get foo() {} })` - * ^^^^^^^ - * - `({ set foo(a) {} })` - * ^^^^^^^ - * - `class A { constructor() {} }` - * ^^^^^^^^^^^ - * - `class A { foo() {} }` - * ^^^ - * - `class A { *foo() {} }` - * ^^^^ - * - `class A { async foo() {} }` - * ^^^^^^^^^ - * - `class A { ['foo']() {} }` - * ^^^^^^^ - * - `class A { *['foo']() {} }` - * ^^^^^^^^ - * - `class A { async ['foo']() {} }` - * ^^^^^^^^^^^^^ - * - `class A { [foo]() {} }` - * ^^^^^ - * - `class A { *[foo]() {} }` - * ^^^^^^ - * - `class A { async [foo]() {} }` - * ^^^^^^^^^^^ - * - `class A { get foo() {} }` - * ^^^^^^^ - * - `class A { set foo(a) {} }` - * ^^^^^^^ - * - `class A { static foo() {} }` - * ^^^^^^^^^^ - * - `class A { static *foo() {} }` - * ^^^^^^^^^^^ - * - `class A { static async foo() {} }` - * ^^^^^^^^^^^^^^^^ - * - `class A { static get foo() {} }` - * ^^^^^^^^^^^^^^ - * - `class A { static set foo(a) {} }` - * ^^^^^^^^^^^^^^ - * @param {ASTNode} node The function node to get. - * @param {SourceCode} sourceCode The source code object to get tokens. - * @returns {string} The location of the function node for reporting. - */ - getFunctionHeadLoc(node, sourceCode) { - const parent = node.parent; - let start = null; - let end = null; - - if (node.type === "ArrowFunctionExpression") { - const arrowToken = sourceCode.getTokenBefore(node.body, isArrowToken); - - start = arrowToken.loc.start; - end = arrowToken.loc.end; - } else if (parent.type === "Property" || parent.type === "MethodDefinition") { - start = parent.loc.start; - end = getOpeningParenOfParams(node, sourceCode).loc.start; - } else { - start = node.loc.start; - end = getOpeningParenOfParams(node, sourceCode).loc.start; - } - - return { - start: Object.assign({}, start), - end: Object.assign({}, end) - }; - }, - - /** - * Gets next location when the result is not out of bound, otherwise returns null. - * - * Assumptions: - * - * - The given location represents a valid location in the given source code. - * - Columns are 0-based. - * - Lines are 1-based. - * - Column immediately after the last character in a line (not incl. linebreaks) is considered to be a valid location. - * - If the source code ends with a linebreak, `sourceCode.lines` array will have an extra element (empty string) at the end. - * The start (column 0) of that extra line is considered to be a valid location. - * - * Examples of successive locations (line, column): - * - * code: foo - * locations: (1, 0) -> (1, 1) -> (1, 2) -> (1, 3) -> null - * - * code: foo - * locations: (1, 0) -> (1, 1) -> (1, 2) -> (1, 3) -> (2, 0) -> null - * - * code: foo - * locations: (1, 0) -> (1, 1) -> (1, 2) -> (1, 3) -> (2, 0) -> null - * - * code: ab - * locations: (1, 0) -> (1, 1) -> (2, 0) -> (2, 1) -> null - * - * code: ab - * locations: (1, 0) -> (1, 1) -> (2, 0) -> (2, 1) -> (3, 0) -> null - * - * code: ab - * locations: (1, 0) -> (1, 1) -> (2, 0) -> (2, 1) -> (3, 0) -> null - * - * code: a - * locations: (1, 0) -> (1, 1) -> (2, 0) -> (3, 0) -> null - * - * code: - * locations: (1, 0) -> (2, 0) -> null - * - * code: - * locations: (1, 0) -> null - * @param {SourceCode} sourceCode The sourceCode - * @param {{line: number, column: number}} location The location - * @returns {{line: number, column: number} | null} Next location - */ - getNextLocation(sourceCode, { line, column }) { - if (column < sourceCode.lines[line - 1].length) { - return { - line, - column: column + 1 - }; - } - - if (line < sourceCode.lines.length) { - return { - line: line + 1, - column: 0 - }; - } - - return null; - }, - - /** - * Gets the parenthesized text of a node. This is similar to sourceCode.getText(node), but it also includes any parentheses - * surrounding the node. - * @param {SourceCode} sourceCode The source code object - * @param {ASTNode} node An expression node - * @returns {string} The text representing the node, with all surrounding parentheses included - */ - getParenthesisedText(sourceCode, node) { - let leftToken = sourceCode.getFirstToken(node); - let rightToken = sourceCode.getLastToken(node); - - while ( - sourceCode.getTokenBefore(leftToken) && - sourceCode.getTokenBefore(leftToken).type === "Punctuator" && - sourceCode.getTokenBefore(leftToken).value === "(" && - sourceCode.getTokenAfter(rightToken) && - sourceCode.getTokenAfter(rightToken).type === "Punctuator" && - sourceCode.getTokenAfter(rightToken).value === ")" - ) { - leftToken = sourceCode.getTokenBefore(leftToken); - rightToken = sourceCode.getTokenAfter(rightToken); - } - - return sourceCode.getText().slice(leftToken.range[0], rightToken.range[1]); - }, - - /* - * Determine if a node has a possibility to be an Error object - * @param {ASTNode} node ASTNode to check - * @returns {boolean} True if there is a chance it contains an Error obj - */ - couldBeError(node) { - switch (node.type) { - case "Identifier": - case "CallExpression": - case "NewExpression": - case "MemberExpression": - case "TaggedTemplateExpression": - case "YieldExpression": - case "AwaitExpression": - case "ChainExpression": - return true; // possibly an error object. - - case "AssignmentExpression": - if (["=", "&&="].includes(node.operator)) { - return module.exports.couldBeError(node.right); - } - - if (["||=", "??="].includes(node.operator)) { - return module.exports.couldBeError(node.left) || module.exports.couldBeError(node.right); - } - - /** - * All other assignment operators are mathematical assignment operators (arithmetic or bitwise). - * An assignment expression with a mathematical operator can either evaluate to a primitive value, - * or throw, depending on the operands. Thus, it cannot evaluate to an `Error` object. - */ - return false; - - case "SequenceExpression": { - const exprs = node.expressions; - - return exprs.length !== 0 && module.exports.couldBeError(exprs[exprs.length - 1]); - } - - case "LogicalExpression": - - /* - * If the && operator short-circuits, the left side was falsy and therefore not an error, and if it - * doesn't short-circuit, it takes the value from the right side, so the right side must always be - * a plausible error. A future improvement could verify that the left side could be truthy by - * excluding falsy literals. - */ - if (node.operator === "&&") { - return module.exports.couldBeError(node.right); - } - - return module.exports.couldBeError(node.left) || module.exports.couldBeError(node.right); - - case "ConditionalExpression": - return module.exports.couldBeError(node.consequent) || module.exports.couldBeError(node.alternate); - - default: - return false; - } - }, - - /** - * Check if a given node is a numeric literal or not. - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if the node is a number or bigint literal. - */ - isNumericLiteral(node) { - return ( - node.type === "Literal" && - (typeof node.value === "number" || Boolean(node.bigint)) - ); - }, - - /** - * Determines whether two tokens can safely be placed next to each other without merging into a single token - * @param {Token|string} leftValue The left token. If this is a string, it will be tokenized and the last token will be used. - * @param {Token|string} rightValue The right token. If this is a string, it will be tokenized and the first token will be used. - * @returns {boolean} If the tokens cannot be safely placed next to each other, returns `false`. If the tokens can be placed - * next to each other, behavior is undefined (although it should return `true` in most cases). - */ - canTokensBeAdjacent(leftValue, rightValue) { - const espreeOptions = { - ecmaVersion: espree__default['default'].latestEcmaVersion, - comment: true, - range: true - }; - - let leftToken; - - if (typeof leftValue === "string") { - let tokens; - - try { - tokens = espree__default['default'].tokenize(leftValue, espreeOptions); - } catch { - return false; - } - - const comments = tokens.comments; - - leftToken = tokens[tokens.length - 1]; - if (comments.length) { - const lastComment = comments[comments.length - 1]; - - if (lastComment.range[0] > leftToken.range[0]) { - leftToken = lastComment; - } - } - } else { - leftToken = leftValue; - } - - if (leftToken.type === "Shebang") { - return false; - } - - let rightToken; - - if (typeof rightValue === "string") { - let tokens; - - try { - tokens = espree__default['default'].tokenize(rightValue, espreeOptions); - } catch { - return false; - } - - const comments = tokens.comments; - - rightToken = tokens[0]; - if (comments.length) { - const firstComment = comments[0]; - - if (firstComment.range[0] < rightToken.range[0]) { - rightToken = firstComment; - } - } - } else { - rightToken = rightValue; - } - - if (leftToken.type === "Punctuator" || rightToken.type === "Punctuator") { - if (leftToken.type === "Punctuator" && rightToken.type === "Punctuator") { - const PLUS_TOKENS = new Set(["+", "++"]); - const MINUS_TOKENS = new Set(["-", "--"]); - - return !( - PLUS_TOKENS.has(leftToken.value) && PLUS_TOKENS.has(rightToken.value) || - MINUS_TOKENS.has(leftToken.value) && MINUS_TOKENS.has(rightToken.value) - ); - } - if (leftToken.type === "Punctuator" && leftToken.value === "/") { - return !["Block", "Line", "RegularExpression"].includes(rightToken.type); - } - return true; - } - - if ( - leftToken.type === "String" || rightToken.type === "String" || - leftToken.type === "Template" || rightToken.type === "Template" - ) { - return true; - } - - if (leftToken.type !== "Numeric" && rightToken.type === "Numeric" && rightToken.value.startsWith(".")) { - return true; - } - - if (leftToken.type === "Block" || rightToken.type === "Block" || rightToken.type === "Line") { - return true; - } - - return false; - }, - - /** - * Get the `loc` object of a given name in a `/*globals` directive comment. - * @param {SourceCode} sourceCode The source code to convert index to loc. - * @param {Comment} comment The `/*globals` directive comment which include the name. - * @param {string} name The name to find. - * @returns {SourceLocation} The `loc` object. - */ - getNameLocationInGlobalDirectiveComment(sourceCode, comment, name) { - const namePattern = new RegExp(`[\\s,]${lodash__default['default'].escapeRegExp(name)}(?:$|[\\s,:])`, "gu"); - - // To ignore the first text "global". - namePattern.lastIndex = comment.value.indexOf("global") + 6; - - // Search a given variable name. - const match = namePattern.exec(comment.value); - - // Convert the index to loc. - const start = sourceCode.getLocFromIndex( - comment.range[0] + - "/*".length + - (match ? match.index + 1 : 0) - ); - const end = { - line: start.line, - column: start.column + (match ? name.length : 1) - }; - - return { start, end }; - }, - - /** - * Determines whether the given raw string contains an octal escape sequence - * or a non-octal decimal escape sequence ("\8", "\9"). - * - * "\1", "\2" ... "\7", "\8", "\9" - * "\00", "\01" ... "\07", "\08", "\09" - * - * "\0", when not followed by a digit, is not an octal escape sequence. - * @param {string} rawString A string in its raw representation. - * @returns {boolean} `true` if the string contains at least one octal escape sequence - * or at least one non-octal decimal escape sequence. - */ - hasOctalOrNonOctalDecimalEscapeSequence(rawString) { - return OCTAL_OR_NON_OCTAL_DECIMAL_ESCAPE_PATTERN.test(rawString); - }, - - isLogicalExpression, - isCoalesceExpression, - isMixedLogicalAndCoalesceExpressions, - isNullLiteral, - getStaticStringValue, - getStaticPropertyName, - skipChainExpression, - isSpecificId, - isSpecificMemberAccess, - equalLiteralValue, - isSameReference, - isLogicalAssignmentOperator -}; -}); - -/** - * @fileoverview Rule to enforce getter and setter pairs in objects and classes. - * @author Gyandeep Singh - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Typedefs -//------------------------------------------------------------------------------ - -/** - * Property name if it can be computed statically, otherwise the list of the tokens of the key node. - * @typedef {string|Token[]} Key - */ - -/** - * Accessor nodes with the same key. - * @typedef {Object} AccessorData - * @property {Key} key Accessor's key - * @property {ASTNode[]} getters List of getter nodes. - * @property {ASTNode[]} setters List of setter nodes. - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether or not the given lists represent the equal tokens in the same order. - * Tokens are compared by their properties, not by instance. - * @param {Token[]} left First list of tokens. - * @param {Token[]} right Second list of tokens. - * @returns {boolean} `true` if the lists have same tokens. - */ -function areEqualTokenLists$1(left, right) { - if (left.length !== right.length) { - return false; - } - - for (let i = 0; i < left.length; i++) { - const leftToken = left[i], - rightToken = right[i]; - - if (leftToken.type !== rightToken.type || leftToken.value !== rightToken.value) { - return false; - } - } - - return true; -} - -/** - * Checks whether or not the given keys are equal. - * @param {Key} left First key. - * @param {Key} right Second key. - * @returns {boolean} `true` if the keys are equal. - */ -function areEqualKeys$1(left, right) { - if (typeof left === "string" && typeof right === "string") { - - // Statically computed names. - return left === right; - } - if (Array.isArray(left) && Array.isArray(right)) { - - // Token lists. - return areEqualTokenLists$1(left, right); - } - - return false; -} - -/** - * Checks whether or not a given node is of an accessor kind ('get' or 'set'). - * @param {ASTNode} node A node to check. - * @returns {boolean} `true` if the node is of an accessor kind. - */ -function isAccessorKind$1(node) { - return node.kind === "get" || node.kind === "set"; -} - -/** - * Checks whether or not a given node is an argument of a specified method call. - * @param {ASTNode} node A node to check. - * @param {number} index An expected index of the node in arguments. - * @param {string} object An expected name of the object of the method. - * @param {string} property An expected name of the method. - * @returns {boolean} `true` if the node is an argument of the specified method call. - */ -function isArgumentOfMethodCall(node, index, object, property) { - const parent = node.parent; - - return ( - parent.type === "CallExpression" && - astUtils.isSpecificMemberAccess(parent.callee, object, property) && - parent.arguments[index] === node - ); -} - -/** - * Checks whether or not a given node is a property descriptor. - * @param {ASTNode} node A node to check. - * @returns {boolean} `true` if the node is a property descriptor. - */ -function isPropertyDescriptor$1(node) { - - // Object.defineProperty(obj, "foo", {set: ...}) - if (isArgumentOfMethodCall(node, 2, "Object", "defineProperty") || - isArgumentOfMethodCall(node, 2, "Reflect", "defineProperty") - ) { - return true; - } - - /* - * Object.defineProperties(obj, {foo: {set: ...}}) - * Object.create(proto, {foo: {set: ...}}) - */ - const grandparent = node.parent.parent; - - return grandparent.type === "ObjectExpression" && ( - isArgumentOfMethodCall(grandparent, 1, "Object", "create") || - isArgumentOfMethodCall(grandparent, 1, "Object", "defineProperties") - ); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var accessorPairs = { - meta: { - type: "suggestion", - - docs: { - description: "enforce getter and setter pairs in objects and classes", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/accessor-pairs" - }, - - schema: [{ - type: "object", - properties: { - getWithoutSet: { - type: "boolean", - default: false - }, - setWithoutGet: { - type: "boolean", - default: true - }, - enforceForClassMembers: { - type: "boolean", - default: true - } - }, - additionalProperties: false - }], - - messages: { - missingGetterInPropertyDescriptor: "Getter is not present in property descriptor.", - missingSetterInPropertyDescriptor: "Setter is not present in property descriptor.", - missingGetterInObjectLiteral: "Getter is not present for {{ name }}.", - missingSetterInObjectLiteral: "Setter is not present for {{ name }}.", - missingGetterInClass: "Getter is not present for class {{ name }}.", - missingSetterInClass: "Setter is not present for class {{ name }}." - } - }, - create(context) { - const config = context.options[0] || {}; - const checkGetWithoutSet = config.getWithoutSet === true; - const checkSetWithoutGet = config.setWithoutGet !== false; - const enforceForClassMembers = config.enforceForClassMembers !== false; - const sourceCode = context.getSourceCode(); - - /** - * Reports the given node. - * @param {ASTNode} node The node to report. - * @param {string} messageKind "missingGetter" or "missingSetter". - * @returns {void} - * @private - */ - function report(node, messageKind) { - if (node.type === "Property") { - context.report({ - node, - messageId: `${messageKind}InObjectLiteral`, - loc: astUtils.getFunctionHeadLoc(node.value, sourceCode), - data: { name: astUtils.getFunctionNameWithKind(node.value) } - }); - } else if (node.type === "MethodDefinition") { - context.report({ - node, - messageId: `${messageKind}InClass`, - loc: astUtils.getFunctionHeadLoc(node.value, sourceCode), - data: { name: astUtils.getFunctionNameWithKind(node.value) } - }); - } else { - context.report({ - node, - messageId: `${messageKind}InPropertyDescriptor` - }); - } - } - - /** - * Reports each of the nodes in the given list using the same messageId. - * @param {ASTNode[]} nodes Nodes to report. - * @param {string} messageKind "missingGetter" or "missingSetter". - * @returns {void} - * @private - */ - function reportList(nodes, messageKind) { - for (const node of nodes) { - report(node, messageKind); - } - } - - /** - * Creates a new `AccessorData` object for the given getter or setter node. - * @param {ASTNode} node A getter or setter node. - * @returns {AccessorData} New `AccessorData` object that contains the given node. - * @private - */ - function createAccessorData(node) { - const name = astUtils.getStaticPropertyName(node); - const key = (name !== null) ? name : sourceCode.getTokens(node.key); - - return { - key, - getters: node.kind === "get" ? [node] : [], - setters: node.kind === "set" ? [node] : [] - }; - } - - /** - * Merges the given `AccessorData` object into the given accessors list. - * @param {AccessorData[]} accessors The list to merge into. - * @param {AccessorData} accessorData The object to merge. - * @returns {AccessorData[]} The same instance with the merged object. - * @private - */ - function mergeAccessorData(accessors, accessorData) { - const equalKeyElement = accessors.find(a => areEqualKeys$1(a.key, accessorData.key)); - - if (equalKeyElement) { - equalKeyElement.getters.push(...accessorData.getters); - equalKeyElement.setters.push(...accessorData.setters); - } else { - accessors.push(accessorData); - } - - return accessors; - } - - /** - * Checks accessor pairs in the given list of nodes. - * @param {ASTNode[]} nodes The list to check. - * @returns {void} - * @private - */ - function checkList(nodes) { - const accessors = nodes - .filter(isAccessorKind$1) - .map(createAccessorData) - .reduce(mergeAccessorData, []); - - for (const { getters, setters } of accessors) { - if (checkSetWithoutGet && setters.length && !getters.length) { - reportList(setters, "missingGetter"); - } - if (checkGetWithoutSet && getters.length && !setters.length) { - reportList(getters, "missingSetter"); - } - } - } - - /** - * Checks accessor pairs in an object literal. - * @param {ASTNode} node `ObjectExpression` node to check. - * @returns {void} - * @private - */ - function checkObjectLiteral(node) { - checkList(node.properties.filter(p => p.type === "Property")); - } - - /** - * Checks accessor pairs in a property descriptor. - * @param {ASTNode} node Property descriptor `ObjectExpression` node to check. - * @returns {void} - * @private - */ - function checkPropertyDescriptor(node) { - const namesToCheck = node.properties - .filter(p => p.type === "Property" && p.kind === "init" && !p.computed) - .map(({ key }) => key.name); - - const hasGetter = namesToCheck.includes("get"); - const hasSetter = namesToCheck.includes("set"); - - if (checkSetWithoutGet && hasSetter && !hasGetter) { - report(node, "missingGetter"); - } - if (checkGetWithoutSet && hasGetter && !hasSetter) { - report(node, "missingSetter"); - } - } - - /** - * Checks the given object expression as an object literal and as a possible property descriptor. - * @param {ASTNode} node `ObjectExpression` node to check. - * @returns {void} - * @private - */ - function checkObjectExpression(node) { - checkObjectLiteral(node); - if (isPropertyDescriptor$1(node)) { - checkPropertyDescriptor(node); - } - } - - /** - * Checks the given class body. - * @param {ASTNode} node `ClassBody` node to check. - * @returns {void} - * @private - */ - function checkClassBody(node) { - const methodDefinitions = node.body.filter(m => m.type === "MethodDefinition"); - - checkList(methodDefinitions.filter(m => m.static)); - checkList(methodDefinitions.filter(m => !m.static)); - } - - const listeners = {}; - - if (checkSetWithoutGet || checkGetWithoutSet) { - listeners.ObjectExpression = checkObjectExpression; - if (enforceForClassMembers) { - listeners.ClassBody = checkClassBody; - } - } - - return listeners; - } -}; - -/** - * @fileoverview Rule to enforce linebreaks after open and before close array brackets - * @author Jan Peer Stöcklmair - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var arrayBracketNewline = { - meta: { - type: "layout", - - docs: { - description: "enforce linebreaks after opening and before closing array brackets", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/array-bracket-newline" - }, - - fixable: "whitespace", - - schema: [ - { - oneOf: [ - { - enum: ["always", "never", "consistent"] - }, - { - type: "object", - properties: { - multiline: { - type: "boolean" - }, - minItems: { - type: ["integer", "null"], - minimum: 0 - } - }, - additionalProperties: false - } - ] - } - ], - - messages: { - unexpectedOpeningLinebreak: "There should be no linebreak after '['.", - unexpectedClosingLinebreak: "There should be no linebreak before ']'.", - missingOpeningLinebreak: "A linebreak is required after '['.", - missingClosingLinebreak: "A linebreak is required before ']'." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - - //---------------------------------------------------------------------- - // Helpers - //---------------------------------------------------------------------- - - /** - * Normalizes a given option value. - * @param {string|Object|undefined} option An option value to parse. - * @returns {{multiline: boolean, minItems: number}} Normalized option object. - */ - function normalizeOptionValue(option) { - let consistent = false; - let multiline = false; - let minItems = 0; - - if (option) { - if (option === "consistent") { - consistent = true; - minItems = Number.POSITIVE_INFINITY; - } else if (option === "always" || option.minItems === 0) { - minItems = 0; - } else if (option === "never") { - minItems = Number.POSITIVE_INFINITY; - } else { - multiline = Boolean(option.multiline); - minItems = option.minItems || Number.POSITIVE_INFINITY; - } - } else { - consistent = false; - multiline = true; - minItems = Number.POSITIVE_INFINITY; - } - - return { consistent, multiline, minItems }; - } - - /** - * Normalizes a given option value. - * @param {string|Object|undefined} options An option value to parse. - * @returns {{ArrayExpression: {multiline: boolean, minItems: number}, ArrayPattern: {multiline: boolean, minItems: number}}} Normalized option object. - */ - function normalizeOptions(options) { - const value = normalizeOptionValue(options); - - return { ArrayExpression: value, ArrayPattern: value }; - } - - /** - * Reports that there shouldn't be a linebreak after the first token - * @param {ASTNode} node The node to report in the event of an error. - * @param {Token} token The token to use for the report. - * @returns {void} - */ - function reportNoBeginningLinebreak(node, token) { - context.report({ - node, - loc: token.loc, - messageId: "unexpectedOpeningLinebreak", - fix(fixer) { - const nextToken = sourceCode.getTokenAfter(token, { includeComments: true }); - - if (astUtils.isCommentToken(nextToken)) { - return null; - } - - return fixer.removeRange([token.range[1], nextToken.range[0]]); - } - }); - } - - /** - * Reports that there shouldn't be a linebreak before the last token - * @param {ASTNode} node The node to report in the event of an error. - * @param {Token} token The token to use for the report. - * @returns {void} - */ - function reportNoEndingLinebreak(node, token) { - context.report({ - node, - loc: token.loc, - messageId: "unexpectedClosingLinebreak", - fix(fixer) { - const previousToken = sourceCode.getTokenBefore(token, { includeComments: true }); - - if (astUtils.isCommentToken(previousToken)) { - return null; - } - - return fixer.removeRange([previousToken.range[1], token.range[0]]); - } - }); - } - - /** - * Reports that there should be a linebreak after the first token - * @param {ASTNode} node The node to report in the event of an error. - * @param {Token} token The token to use for the report. - * @returns {void} - */ - function reportRequiredBeginningLinebreak(node, token) { - context.report({ - node, - loc: token.loc, - messageId: "missingOpeningLinebreak", - fix(fixer) { - return fixer.insertTextAfter(token, "\n"); - } - }); - } - - /** - * Reports that there should be a linebreak before the last token - * @param {ASTNode} node The node to report in the event of an error. - * @param {Token} token The token to use for the report. - * @returns {void} - */ - function reportRequiredEndingLinebreak(node, token) { - context.report({ - node, - loc: token.loc, - messageId: "missingClosingLinebreak", - fix(fixer) { - return fixer.insertTextBefore(token, "\n"); - } - }); - } - - /** - * Reports a given node if it violated this rule. - * @param {ASTNode} node A node to check. This is an ArrayExpression node or an ArrayPattern node. - * @returns {void} - */ - function check(node) { - const elements = node.elements; - const normalizedOptions = normalizeOptions(context.options[0]); - const options = normalizedOptions[node.type]; - const openBracket = sourceCode.getFirstToken(node); - const closeBracket = sourceCode.getLastToken(node); - const firstIncComment = sourceCode.getTokenAfter(openBracket, { includeComments: true }); - const lastIncComment = sourceCode.getTokenBefore(closeBracket, { includeComments: true }); - const first = sourceCode.getTokenAfter(openBracket); - const last = sourceCode.getTokenBefore(closeBracket); - - const needsLinebreaks = ( - elements.length >= options.minItems || - ( - options.multiline && - elements.length > 0 && - firstIncComment.loc.start.line !== lastIncComment.loc.end.line - ) || - ( - elements.length === 0 && - firstIncComment.type === "Block" && - firstIncComment.loc.start.line !== lastIncComment.loc.end.line && - firstIncComment === lastIncComment - ) || - ( - options.consistent && - openBracket.loc.end.line !== first.loc.start.line - ) - ); - - /* - * Use tokens or comments to check multiline or not. - * But use only tokens to check whether linebreaks are needed. - * This allows: - * var arr = [ // eslint-disable-line foo - * 'a' - * ] - */ - - if (needsLinebreaks) { - if (astUtils.isTokenOnSameLine(openBracket, first)) { - reportRequiredBeginningLinebreak(node, openBracket); - } - if (astUtils.isTokenOnSameLine(last, closeBracket)) { - reportRequiredEndingLinebreak(node, closeBracket); - } - } else { - if (!astUtils.isTokenOnSameLine(openBracket, first)) { - reportNoBeginningLinebreak(node, openBracket); - } - if (!astUtils.isTokenOnSameLine(last, closeBracket)) { - reportNoEndingLinebreak(node, closeBracket); - } - } - } - - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - - return { - ArrayPattern: check, - ArrayExpression: check - }; - } -}; - -/** - * @fileoverview Disallows or enforces spaces inside of array brackets. - * @author Jamund Ferguson - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var arrayBracketSpacing = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent spacing inside array brackets", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/array-bracket-spacing" - }, - - fixable: "whitespace", - - schema: [ - { - enum: ["always", "never"] - }, - { - type: "object", - properties: { - singleValue: { - type: "boolean" - }, - objectsInArrays: { - type: "boolean" - }, - arraysInArrays: { - type: "boolean" - } - }, - additionalProperties: false - } - ], - - messages: { - unexpectedSpaceAfter: "There should be no space after '{{tokenValue}}'.", - unexpectedSpaceBefore: "There should be no space before '{{tokenValue}}'.", - missingSpaceAfter: "A space is required after '{{tokenValue}}'.", - missingSpaceBefore: "A space is required before '{{tokenValue}}'." - } - }, - create(context) { - const spaced = context.options[0] === "always", - sourceCode = context.getSourceCode(); - - /** - * Determines whether an option is set, relative to the spacing option. - * If spaced is "always", then check whether option is set to false. - * If spaced is "never", then check whether option is set to true. - * @param {Object} option The option to exclude. - * @returns {boolean} Whether or not the property is excluded. - */ - function isOptionSet(option) { - return context.options[1] ? context.options[1][option] === !spaced : false; - } - - const options = { - spaced, - singleElementException: isOptionSet("singleValue"), - objectsInArraysException: isOptionSet("objectsInArrays"), - arraysInArraysException: isOptionSet("arraysInArrays") - }; - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Reports that there shouldn't be a space after the first token - * @param {ASTNode} node The node to report in the event of an error. - * @param {Token} token The token to use for the report. - * @returns {void} - */ - function reportNoBeginningSpace(node, token) { - const nextToken = sourceCode.getTokenAfter(token); - - context.report({ - node, - loc: { start: token.loc.end, end: nextToken.loc.start }, - messageId: "unexpectedSpaceAfter", - data: { - tokenValue: token.value - }, - fix(fixer) { - return fixer.removeRange([token.range[1], nextToken.range[0]]); - } - }); - } - - /** - * Reports that there shouldn't be a space before the last token - * @param {ASTNode} node The node to report in the event of an error. - * @param {Token} token The token to use for the report. - * @returns {void} - */ - function reportNoEndingSpace(node, token) { - const previousToken = sourceCode.getTokenBefore(token); - - context.report({ - node, - loc: { start: previousToken.loc.end, end: token.loc.start }, - messageId: "unexpectedSpaceBefore", - data: { - tokenValue: token.value - }, - fix(fixer) { - return fixer.removeRange([previousToken.range[1], token.range[0]]); - } - }); - } - - /** - * Reports that there should be a space after the first token - * @param {ASTNode} node The node to report in the event of an error. - * @param {Token} token The token to use for the report. - * @returns {void} - */ - function reportRequiredBeginningSpace(node, token) { - context.report({ - node, - loc: token.loc, - messageId: "missingSpaceAfter", - data: { - tokenValue: token.value - }, - fix(fixer) { - return fixer.insertTextAfter(token, " "); - } - }); - } - - /** - * Reports that there should be a space before the last token - * @param {ASTNode} node The node to report in the event of an error. - * @param {Token} token The token to use for the report. - * @returns {void} - */ - function reportRequiredEndingSpace(node, token) { - context.report({ - node, - loc: token.loc, - messageId: "missingSpaceBefore", - data: { - tokenValue: token.value - }, - fix(fixer) { - return fixer.insertTextBefore(token, " "); - } - }); - } - - /** - * Determines if a node is an object type - * @param {ASTNode} node The node to check. - * @returns {boolean} Whether or not the node is an object type. - */ - function isObjectType(node) { - return node && (node.type === "ObjectExpression" || node.type === "ObjectPattern"); - } - - /** - * Determines if a node is an array type - * @param {ASTNode} node The node to check. - * @returns {boolean} Whether or not the node is an array type. - */ - function isArrayType(node) { - return node && (node.type === "ArrayExpression" || node.type === "ArrayPattern"); - } - - /** - * Validates the spacing around array brackets - * @param {ASTNode} node The node we're checking for spacing - * @returns {void} - */ - function validateArraySpacing(node) { - if (options.spaced && node.elements.length === 0) { - return; - } - - const first = sourceCode.getFirstToken(node), - second = sourceCode.getFirstToken(node, 1), - last = node.typeAnnotation - ? sourceCode.getTokenBefore(node.typeAnnotation) - : sourceCode.getLastToken(node), - penultimate = sourceCode.getTokenBefore(last), - firstElement = node.elements[0], - lastElement = node.elements[node.elements.length - 1]; - - const openingBracketMustBeSpaced = - options.objectsInArraysException && isObjectType(firstElement) || - options.arraysInArraysException && isArrayType(firstElement) || - options.singleElementException && node.elements.length === 1 - ? !options.spaced : options.spaced; - - const closingBracketMustBeSpaced = - options.objectsInArraysException && isObjectType(lastElement) || - options.arraysInArraysException && isArrayType(lastElement) || - options.singleElementException && node.elements.length === 1 - ? !options.spaced : options.spaced; - - if (astUtils.isTokenOnSameLine(first, second)) { - if (openingBracketMustBeSpaced && !sourceCode.isSpaceBetweenTokens(first, second)) { - reportRequiredBeginningSpace(node, first); - } - if (!openingBracketMustBeSpaced && sourceCode.isSpaceBetweenTokens(first, second)) { - reportNoBeginningSpace(node, first); - } - } - - if (first !== penultimate && astUtils.isTokenOnSameLine(penultimate, last)) { - if (closingBracketMustBeSpaced && !sourceCode.isSpaceBetweenTokens(penultimate, last)) { - reportRequiredEndingSpace(node, last); - } - if (!closingBracketMustBeSpaced && sourceCode.isSpaceBetweenTokens(penultimate, last)) { - reportNoEndingSpace(node, last); - } - } - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - ArrayPattern: validateArraySpacing, - ArrayExpression: validateArraySpacing - }; - } -}; - -/** - * @fileoverview Rule to enforce return statements in callbacks of array's methods - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const TARGET_NODE_TYPE$2 = /^(?:Arrow)?FunctionExpression$/u; -const TARGET_METHODS = /^(?:every|filter|find(?:Index)?|flatMap|forEach|map|reduce(?:Right)?|some|sort)$/u; - -/** - * Checks a given code path segment is reachable. - * @param {CodePathSegment} segment A segment to check. - * @returns {boolean} `true` if the segment is reachable. - */ -function isReachable$3(segment) { - return segment.reachable; -} - -/** - * Checks a given node is a member access which has the specified name's - * property. - * @param {ASTNode} node A node to check. - * @returns {boolean} `true` if the node is a member access which has - * the specified name's property. The node may be a `(Chain|Member)Expression` node. - */ -function isTargetMethod(node) { - return astUtils.isSpecificMemberAccess(node, null, TARGET_METHODS); -} - -/** - * Returns a human-legible description of an array method - * @param {string} arrayMethodName A method name to fully qualify - * @returns {string} the method name prefixed with `Array.` if it is a class method, - * or else `Array.prototype.` if it is an instance method. - */ -function fullMethodName(arrayMethodName) { - if (["from", "of", "isArray"].includes(arrayMethodName)) { - return "Array.".concat(arrayMethodName); - } - return "Array.prototype.".concat(arrayMethodName); -} - -/** - * Checks whether or not a given node is a function expression which is the - * callback of an array method, returning the method name. - * @param {ASTNode} node A node to check. This is one of - * FunctionExpression or ArrowFunctionExpression. - * @returns {string} The method name if the node is a callback method, - * null otherwise. - */ -function getArrayMethodName(node) { - let currentNode = node; - - while (currentNode) { - const parent = currentNode.parent; - - switch (parent.type) { - - /* - * Looks up the destination. e.g., - * foo.every(nativeFoo || function foo() { ... }); - */ - case "LogicalExpression": - case "ConditionalExpression": - case "ChainExpression": - currentNode = parent; - break; - - /* - * If the upper function is IIFE, checks the destination of the return value. - * e.g. - * foo.every((function() { - * // setup... - * return function callback() { ... }; - * })()); - */ - case "ReturnStatement": { - const func = astUtils.getUpperFunction(parent); - - if (func === null || !astUtils.isCallee(func)) { - return null; - } - currentNode = func.parent; - break; - } - - /* - * e.g. - * Array.from([], function() {}); - * list.every(function() {}); - */ - case "CallExpression": - if (astUtils.isArrayFromMethod(parent.callee)) { - if ( - parent.arguments.length >= 2 && - parent.arguments[1] === currentNode - ) { - return "from"; - } - } - if (isTargetMethod(parent.callee)) { - if ( - parent.arguments.length >= 1 && - parent.arguments[0] === currentNode - ) { - return astUtils.getStaticPropertyName(parent.callee); - } - } - return null; - - // Otherwise this node is not target. - default: - return null; - } - } - - /* istanbul ignore next: unreachable */ - return null; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var arrayCallbackReturn = { - meta: { - type: "problem", - - docs: { - description: "enforce `return` statements in callbacks of array methods", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/array-callback-return" - }, - - schema: [ - { - type: "object", - properties: { - allowImplicit: { - type: "boolean", - default: false - }, - checkForEach: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - messages: { - expectedAtEnd: "{{arrayMethodName}}() expects a value to be returned at the end of {{name}}.", - expectedInside: "{{arrayMethodName}}() expects a return value from {{name}}.", - expectedReturnValue: "{{arrayMethodName}}() expects a return value from {{name}}.", - expectedNoReturnValue: "{{arrayMethodName}}() expects no useless return value from {{name}}." - } - }, - - create(context) { - - const options = context.options[0] || { allowImplicit: false, checkForEach: false }; - const sourceCode = context.getSourceCode(); - - let funcInfo = { - arrayMethodName: null, - upper: null, - codePath: null, - hasReturn: false, - shouldCheck: false, - node: null - }; - - /** - * Checks whether or not the last code path segment is reachable. - * Then reports this function if the segment is reachable. - * - * If the last code path segment is reachable, there are paths which are not - * returned or thrown. - * @param {ASTNode} node A node to check. - * @returns {void} - */ - function checkLastSegment(node) { - - if (!funcInfo.shouldCheck) { - return; - } - - let messageId = null; - - if (funcInfo.arrayMethodName === "forEach") { - if (options.checkForEach && node.type === "ArrowFunctionExpression" && node.expression) { - messageId = "expectedNoReturnValue"; - } - } else { - if (node.body.type === "BlockStatement" && funcInfo.codePath.currentSegments.some(isReachable$3)) { - messageId = funcInfo.hasReturn ? "expectedAtEnd" : "expectedInside"; - } - } - - if (messageId) { - const name = astUtils.getFunctionNameWithKind(node); - - context.report({ - node, - loc: astUtils.getFunctionHeadLoc(node, sourceCode), - messageId, - data: { name, arrayMethodName: fullMethodName(funcInfo.arrayMethodName) } - }); - } - } - - return { - - // Stacks this function's information. - onCodePathStart(codePath, node) { - - let methodName = null; - - if (TARGET_NODE_TYPE$2.test(node.type)) { - methodName = getArrayMethodName(node); - } - - funcInfo = { - arrayMethodName: methodName, - upper: funcInfo, - codePath, - hasReturn: false, - shouldCheck: - methodName && - !node.async && - !node.generator, - node - }; - }, - - // Pops this function's information. - onCodePathEnd() { - funcInfo = funcInfo.upper; - }, - - // Checks the return statement is valid. - ReturnStatement(node) { - - if (!funcInfo.shouldCheck) { - return; - } - - funcInfo.hasReturn = true; - - let messageId = null; - - if (funcInfo.arrayMethodName === "forEach") { - - // if checkForEach: true, returning a value at any path inside a forEach is not allowed - if (options.checkForEach && node.argument) { - messageId = "expectedNoReturnValue"; - } - } else { - - // if allowImplicit: false, should also check node.argument - if (!options.allowImplicit && !node.argument) { - messageId = "expectedReturnValue"; - } - } - - if (messageId) { - context.report({ - node, - messageId, - data: { - name: astUtils.getFunctionNameWithKind(funcInfo.node), - arrayMethodName: fullMethodName(funcInfo.arrayMethodName) - } - }); - } - }, - - // Reports a given function if the last path is reachable. - "FunctionExpression:exit": checkLastSegment, - "ArrowFunctionExpression:exit": checkLastSegment - }; - } -}; - -/** - * @fileoverview Rule to enforce line breaks after each array element - * @author Jan Peer Stöcklmair - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var arrayElementNewline = { - meta: { - type: "layout", - - docs: { - description: "enforce line breaks after each array element", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/array-element-newline" - }, - - fixable: "whitespace", - - schema: { - definitions: { - basicConfig: { - oneOf: [ - { - enum: ["always", "never", "consistent"] - }, - { - type: "object", - properties: { - multiline: { - type: "boolean" - }, - minItems: { - type: ["integer", "null"], - minimum: 0 - } - }, - additionalProperties: false - } - ] - } - }, - items: [ - { - oneOf: [ - { - $ref: "#/definitions/basicConfig" - }, - { - type: "object", - properties: { - ArrayExpression: { - $ref: "#/definitions/basicConfig" - }, - ArrayPattern: { - $ref: "#/definitions/basicConfig" - } - }, - additionalProperties: false, - minProperties: 1 - } - ] - } - ] - }, - - messages: { - unexpectedLineBreak: "There should be no linebreak here.", - missingLineBreak: "There should be a linebreak after this element." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - //---------------------------------------------------------------------- - // Helpers - //---------------------------------------------------------------------- - - /** - * Normalizes a given option value. - * @param {string|Object|undefined} providedOption An option value to parse. - * @returns {{multiline: boolean, minItems: number}} Normalized option object. - */ - function normalizeOptionValue(providedOption) { - let consistent = false; - let multiline = false; - let minItems; - - const option = providedOption || "always"; - - if (!option || option === "always" || option.minItems === 0) { - minItems = 0; - } else if (option === "never") { - minItems = Number.POSITIVE_INFINITY; - } else if (option === "consistent") { - consistent = true; - minItems = Number.POSITIVE_INFINITY; - } else { - multiline = Boolean(option.multiline); - minItems = option.minItems || Number.POSITIVE_INFINITY; - } - - return { consistent, multiline, minItems }; - } - - /** - * Normalizes a given option value. - * @param {string|Object|undefined} options An option value to parse. - * @returns {{ArrayExpression: {multiline: boolean, minItems: number}, ArrayPattern: {multiline: boolean, minItems: number}}} Normalized option object. - */ - function normalizeOptions(options) { - if (options && (options.ArrayExpression || options.ArrayPattern)) { - let expressionOptions, patternOptions; - - if (options.ArrayExpression) { - expressionOptions = normalizeOptionValue(options.ArrayExpression); - } - - if (options.ArrayPattern) { - patternOptions = normalizeOptionValue(options.ArrayPattern); - } - - return { ArrayExpression: expressionOptions, ArrayPattern: patternOptions }; - } - - const value = normalizeOptionValue(options); - - return { ArrayExpression: value, ArrayPattern: value }; - } - - /** - * Reports that there shouldn't be a line break after the first token - * @param {Token} token The token to use for the report. - * @returns {void} - */ - function reportNoLineBreak(token) { - const tokenBefore = sourceCode.getTokenBefore(token, { includeComments: true }); - - context.report({ - loc: { - start: tokenBefore.loc.end, - end: token.loc.start - }, - messageId: "unexpectedLineBreak", - fix(fixer) { - if (astUtils.isCommentToken(tokenBefore)) { - return null; - } - - if (!astUtils.isTokenOnSameLine(tokenBefore, token)) { - return fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], " "); - } - - /* - * This will check if the comma is on the same line as the next element - * Following array: - * [ - * 1 - * , 2 - * , 3 - * ] - * - * will be fixed to: - * [ - * 1, 2, 3 - * ] - */ - const twoTokensBefore = sourceCode.getTokenBefore(tokenBefore, { includeComments: true }); - - if (astUtils.isCommentToken(twoTokensBefore)) { - return null; - } - - return fixer.replaceTextRange([twoTokensBefore.range[1], tokenBefore.range[0]], ""); - - } - }); - } - - /** - * Reports that there should be a line break after the first token - * @param {Token} token The token to use for the report. - * @returns {void} - */ - function reportRequiredLineBreak(token) { - const tokenBefore = sourceCode.getTokenBefore(token, { includeComments: true }); - - context.report({ - loc: { - start: tokenBefore.loc.end, - end: token.loc.start - }, - messageId: "missingLineBreak", - fix(fixer) { - return fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], "\n"); - } - }); - } - - /** - * Reports a given node if it violated this rule. - * @param {ASTNode} node A node to check. This is an ObjectExpression node or an ObjectPattern node. - * @returns {void} - */ - function check(node) { - const elements = node.elements; - const normalizedOptions = normalizeOptions(context.options[0]); - const options = normalizedOptions[node.type]; - - if (!options) { - return; - } - - let elementBreak = false; - - /* - * MULTILINE: true - * loop through every element and check - * if at least one element has linebreaks inside - * this ensures that following is not valid (due to elements are on the same line): - * - * [ - * 1, - * 2, - * 3 - * ] - */ - if (options.multiline) { - elementBreak = elements - .filter(element => element !== null) - .some(element => element.loc.start.line !== element.loc.end.line); - } - - const linebreaksCount = node.elements.map((element, i) => { - const previousElement = elements[i - 1]; - - if (i === 0 || element === null || previousElement === null) { - return false; - } - - const commaToken = sourceCode.getFirstTokenBetween(previousElement, element, astUtils.isCommaToken); - const lastTokenOfPreviousElement = sourceCode.getTokenBefore(commaToken); - const firstTokenOfCurrentElement = sourceCode.getTokenAfter(commaToken); - - return !astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement); - }).filter(isBreak => isBreak === true).length; - - const needsLinebreaks = ( - elements.length >= options.minItems || - ( - options.multiline && - elementBreak - ) || - ( - options.consistent && - linebreaksCount > 0 && - linebreaksCount < node.elements.length - ) - ); - - elements.forEach((element, i) => { - const previousElement = elements[i - 1]; - - if (i === 0 || element === null || previousElement === null) { - return; - } - - const commaToken = sourceCode.getFirstTokenBetween(previousElement, element, astUtils.isCommaToken); - const lastTokenOfPreviousElement = sourceCode.getTokenBefore(commaToken); - const firstTokenOfCurrentElement = sourceCode.getTokenAfter(commaToken); - - if (needsLinebreaks) { - if (astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement)) { - reportRequiredLineBreak(firstTokenOfCurrentElement); - } - } else { - if (!astUtils.isTokenOnSameLine(lastTokenOfPreviousElement, firstTokenOfCurrentElement)) { - reportNoLineBreak(firstTokenOfCurrentElement); - } - } - }); - } - - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - - return { - ArrayPattern: check, - ArrayExpression: check - }; - } -}; - -/** - * @fileoverview Rule to require braces in arrow function body. - * @author Alberto Rodríguez - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var arrowBodyStyle = { - meta: { - type: "suggestion", - - docs: { - description: "require braces around arrow function bodies", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/arrow-body-style" - }, - - schema: { - anyOf: [ - { - type: "array", - items: [ - { - enum: ["always", "never"] - } - ], - minItems: 0, - maxItems: 1 - }, - { - type: "array", - items: [ - { - enum: ["as-needed"] - }, - { - type: "object", - properties: { - requireReturnForObjectLiteral: { type: "boolean" } - }, - additionalProperties: false - } - ], - minItems: 0, - maxItems: 2 - } - ] - }, - - fixable: "code", - - messages: { - unexpectedOtherBlock: "Unexpected block statement surrounding arrow body.", - unexpectedEmptyBlock: "Unexpected block statement surrounding arrow body; put a value of `undefined` immediately after the `=>`.", - unexpectedObjectBlock: "Unexpected block statement surrounding arrow body; parenthesize the returned value and move it immediately after the `=>`.", - unexpectedSingleBlock: "Unexpected block statement surrounding arrow body; move the returned value immediately after the `=>`.", - expectedBlock: "Expected block statement surrounding arrow body." - } - }, - - create(context) { - const options = context.options; - const always = options[0] === "always"; - const asNeeded = !options[0] || options[0] === "as-needed"; - const never = options[0] === "never"; - const requireReturnForObjectLiteral = options[1] && options[1].requireReturnForObjectLiteral; - const sourceCode = context.getSourceCode(); - let funcInfo = null; - - /** - * Checks whether the given node has ASI problem or not. - * @param {Token} token The token to check. - * @returns {boolean} `true` if it changes semantics if `;` or `}` followed by the token are removed. - */ - function hasASIProblem(token) { - return token && token.type === "Punctuator" && /^[([/`+-]/u.test(token.value); - } - - /** - * Gets the closing parenthesis which is the pair of the given opening parenthesis. - * @param {Token} token The opening parenthesis token to get. - * @returns {Token} The found closing parenthesis token. - */ - function findClosingParen(token) { - let node = sourceCode.getNodeByRangeIndex(token.range[0]); - - while (!astUtils.isParenthesised(sourceCode, node)) { - node = node.parent; - } - return sourceCode.getTokenAfter(node); - } - - /** - * Check whether the node is inside of a for loop's init - * @param {ASTNode} node node is inside for loop - * @returns {boolean} `true` if the node is inside of a for loop, else `false` - */ - function isInsideForLoopInitializer(node) { - if (node && node.parent) { - if (node.parent.type === "ForStatement" && node.parent.init === node) { - return true; - } - return isInsideForLoopInitializer(node.parent); - } - return false; - } - - /** - * Determines whether a arrow function body needs braces - * @param {ASTNode} node The arrow function node. - * @returns {void} - */ - function validate(node) { - const arrowBody = node.body; - - if (arrowBody.type === "BlockStatement") { - const blockBody = arrowBody.body; - - if (blockBody.length !== 1 && !never) { - return; - } - - if (asNeeded && requireReturnForObjectLiteral && blockBody[0].type === "ReturnStatement" && - blockBody[0].argument && blockBody[0].argument.type === "ObjectExpression") { - return; - } - - if (never || asNeeded && blockBody[0].type === "ReturnStatement") { - let messageId; - - if (blockBody.length === 0) { - messageId = "unexpectedEmptyBlock"; - } else if (blockBody.length > 1) { - messageId = "unexpectedOtherBlock"; - } else if (blockBody[0].argument === null) { - messageId = "unexpectedSingleBlock"; - } else if (astUtils.isOpeningBraceToken(sourceCode.getFirstToken(blockBody[0], { skip: 1 }))) { - messageId = "unexpectedObjectBlock"; - } else { - messageId = "unexpectedSingleBlock"; - } - - context.report({ - node, - loc: arrowBody.loc, - messageId, - fix(fixer) { - const fixes = []; - - if (blockBody.length !== 1 || - blockBody[0].type !== "ReturnStatement" || - !blockBody[0].argument || - hasASIProblem(sourceCode.getTokenAfter(arrowBody)) - ) { - return fixes; - } - - const openingBrace = sourceCode.getFirstToken(arrowBody); - const closingBrace = sourceCode.getLastToken(arrowBody); - const firstValueToken = sourceCode.getFirstToken(blockBody[0], 1); - const lastValueToken = sourceCode.getLastToken(blockBody[0]); - const commentsExist = - sourceCode.commentsExistBetween(openingBrace, firstValueToken) || - sourceCode.commentsExistBetween(lastValueToken, closingBrace); - - /* - * Remove tokens around the return value. - * If comments don't exist, remove extra spaces as well. - */ - if (commentsExist) { - fixes.push( - fixer.remove(openingBrace), - fixer.remove(closingBrace), - fixer.remove(sourceCode.getTokenAfter(openingBrace)) // return keyword - ); - } else { - fixes.push( - fixer.removeRange([openingBrace.range[0], firstValueToken.range[0]]), - fixer.removeRange([lastValueToken.range[1], closingBrace.range[1]]) - ); - } - - /* - * If the first token of the return value is `{` or the return value is a sequence expression, - * enclose the return value by parentheses to avoid syntax error. - */ - if (astUtils.isOpeningBraceToken(firstValueToken) || blockBody[0].argument.type === "SequenceExpression" || (funcInfo.hasInOperator && isInsideForLoopInitializer(node))) { - if (!astUtils.isParenthesised(sourceCode, blockBody[0].argument)) { - fixes.push( - fixer.insertTextBefore(firstValueToken, "("), - fixer.insertTextAfter(lastValueToken, ")") - ); - } - } - - /* - * If the last token of the return statement is semicolon, remove it. - * Non-block arrow body is an expression, not a statement. - */ - if (astUtils.isSemicolonToken(lastValueToken)) { - fixes.push(fixer.remove(lastValueToken)); - } - - return fixes; - } - }); - } - } else { - if (always || (asNeeded && requireReturnForObjectLiteral && arrowBody.type === "ObjectExpression")) { - context.report({ - node, - loc: arrowBody.loc, - messageId: "expectedBlock", - fix(fixer) { - const fixes = []; - const arrowToken = sourceCode.getTokenBefore(arrowBody, astUtils.isArrowToken); - const [firstTokenAfterArrow, secondTokenAfterArrow] = sourceCode.getTokensAfter(arrowToken, { count: 2 }); - const lastToken = sourceCode.getLastToken(node); - const isParenthesisedObjectLiteral = - astUtils.isOpeningParenToken(firstTokenAfterArrow) && - astUtils.isOpeningBraceToken(secondTokenAfterArrow); - - // If the value is object literal, remove parentheses which were forced by syntax. - if (isParenthesisedObjectLiteral) { - const openingParenToken = firstTokenAfterArrow; - const openingBraceToken = secondTokenAfterArrow; - - if (astUtils.isTokenOnSameLine(openingParenToken, openingBraceToken)) { - fixes.push(fixer.replaceText(openingParenToken, "{return ")); - } else { - - // Avoid ASI - fixes.push( - fixer.replaceText(openingParenToken, "{"), - fixer.insertTextBefore(openingBraceToken, "return ") - ); - } - - // Closing paren for the object doesn't have to be lastToken, e.g.: () => ({}).foo() - fixes.push(fixer.remove(findClosingParen(openingBraceToken))); - fixes.push(fixer.insertTextAfter(lastToken, "}")); - - } else { - fixes.push(fixer.insertTextBefore(firstTokenAfterArrow, "{return ")); - fixes.push(fixer.insertTextAfter(lastToken, "}")); - } - - return fixes; - } - }); - } - } - } - - return { - "BinaryExpression[operator='in']"() { - let info = funcInfo; - - while (info) { - info.hasInOperator = true; - info = info.upper; - } - }, - ArrowFunctionExpression() { - funcInfo = { - upper: funcInfo, - hasInOperator: false - }; - }, - "ArrowFunctionExpression:exit"(node) { - validate(node); - funcInfo = funcInfo.upper; - } - }; - } -}; - -/** - * @fileoverview Rule to require parens in arrow function arguments. - * @author Jxck - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Determines if the given arrow function has block body. - * @param {ASTNode} node `ArrowFunctionExpression` node. - * @returns {boolean} `true` if the function has block body. - */ -function hasBlockBody(node) { - return node.body.type === "BlockStatement"; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var arrowParens = { - meta: { - type: "layout", - - docs: { - description: "require parentheses around arrow function arguments", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/arrow-parens" - }, - - fixable: "code", - - schema: [ - { - enum: ["always", "as-needed"] - }, - { - type: "object", - properties: { - requireForBlockBody: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - messages: { - unexpectedParens: "Unexpected parentheses around single function argument.", - expectedParens: "Expected parentheses around arrow function argument.", - - unexpectedParensInline: "Unexpected parentheses around single function argument having a body with no curly braces.", - expectedParensBlock: "Expected parentheses around arrow function argument having a body with curly braces." - } - }, - - create(context) { - const asNeeded = context.options[0] === "as-needed"; - const requireForBlockBody = asNeeded && context.options[1] && context.options[1].requireForBlockBody === true; - - const sourceCode = context.getSourceCode(); - - /** - * Finds opening paren of parameters for the given arrow function, if it exists. - * It is assumed that the given arrow function has exactly one parameter. - * @param {ASTNode} node `ArrowFunctionExpression` node. - * @returns {Token|null} the opening paren, or `null` if the given arrow function doesn't have parens of parameters. - */ - function findOpeningParenOfParams(node) { - const tokenBeforeParams = sourceCode.getTokenBefore(node.params[0]); - - if ( - tokenBeforeParams && - astUtils.isOpeningParenToken(tokenBeforeParams) && - node.range[0] <= tokenBeforeParams.range[0] - ) { - return tokenBeforeParams; - } - - return null; - } - - /** - * Finds closing paren of parameters for the given arrow function. - * It is assumed that the given arrow function has parens of parameters and that it has exactly one parameter. - * @param {ASTNode} node `ArrowFunctionExpression` node. - * @returns {Token} the closing paren of parameters. - */ - function getClosingParenOfParams(node) { - return sourceCode.getTokenAfter(node.params[0], astUtils.isClosingParenToken); - } - - /** - * Determines whether the given arrow function has comments inside parens of parameters. - * It is assumed that the given arrow function has parens of parameters. - * @param {ASTNode} node `ArrowFunctionExpression` node. - * @param {Token} openingParen Opening paren of parameters. - * @returns {boolean} `true` if the function has at least one comment inside of parens of parameters. - */ - function hasCommentsInParensOfParams(node, openingParen) { - return sourceCode.commentsExistBetween(openingParen, getClosingParenOfParams(node)); - } - - /** - * Determines whether the given arrow function has unexpected tokens before opening paren of parameters, - * in which case it will be assumed that the existing parens of parameters are necessary. - * Only tokens within the range of the arrow function (tokens that are part of the arrow function) are taken into account. - * Example: (a) => b - * @param {ASTNode} node `ArrowFunctionExpression` node. - * @param {Token} openingParen Opening paren of parameters. - * @returns {boolean} `true` if the function has at least one unexpected token. - */ - function hasUnexpectedTokensBeforeOpeningParen(node, openingParen) { - const expectedCount = node.async ? 1 : 0; - - return sourceCode.getFirstToken(node, { skip: expectedCount }) !== openingParen; - } - - return { - "ArrowFunctionExpression[params.length=1]"(node) { - const shouldHaveParens = !asNeeded || requireForBlockBody && hasBlockBody(node); - const openingParen = findOpeningParenOfParams(node); - const hasParens = openingParen !== null; - const [param] = node.params; - - if (shouldHaveParens && !hasParens) { - context.report({ - node, - messageId: requireForBlockBody ? "expectedParensBlock" : "expectedParens", - loc: param.loc, - *fix(fixer) { - yield fixer.insertTextBefore(param, "("); - yield fixer.insertTextAfter(param, ")"); - } - }); - } - - if ( - !shouldHaveParens && - hasParens && - param.type === "Identifier" && - !param.typeAnnotation && - !node.returnType && - !hasCommentsInParensOfParams(node, openingParen) && - !hasUnexpectedTokensBeforeOpeningParen(node, openingParen) - ) { - context.report({ - node, - messageId: requireForBlockBody ? "unexpectedParensInline" : "unexpectedParens", - loc: param.loc, - *fix(fixer) { - const tokenBeforeOpeningParen = sourceCode.getTokenBefore(openingParen); - const closingParen = getClosingParenOfParams(node); - - if ( - tokenBeforeOpeningParen && - tokenBeforeOpeningParen.range[1] === openingParen.range[0] && - !astUtils.canTokensBeAdjacent(tokenBeforeOpeningParen, sourceCode.getFirstToken(param)) - ) { - yield fixer.insertTextBefore(openingParen, " "); - } - - // remove parens, whitespace inside parens, and possible trailing comma - yield fixer.removeRange([openingParen.range[0], param.range[0]]); - yield fixer.removeRange([param.range[1], closingParen.range[1]]); - } - }); - } - } - }; - } -}; - -/** - * @fileoverview Rule to define spacing before/after arrow function's arrow. - * @author Jxck - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var arrowSpacing = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent spacing before and after the arrow in arrow functions", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/arrow-spacing" - }, - - fixable: "whitespace", - - schema: [ - { - type: "object", - properties: { - before: { - type: "boolean", - default: true - }, - after: { - type: "boolean", - default: true - } - }, - additionalProperties: false - } - ], - - messages: { - expectedBefore: "Missing space before =>.", - unexpectedBefore: "Unexpected space before =>.", - - expectedAfter: "Missing space after =>.", - unexpectedAfter: "Unexpected space after =>." - } - }, - - create(context) { - - // merge rules with default - const rule = Object.assign({}, context.options[0]); - - rule.before = rule.before !== false; - rule.after = rule.after !== false; - - const sourceCode = context.getSourceCode(); - - /** - * Get tokens of arrow(`=>`) and before/after arrow. - * @param {ASTNode} node The arrow function node. - * @returns {Object} Tokens of arrow and before/after arrow. - */ - function getTokens(node) { - const arrow = sourceCode.getTokenBefore(node.body, astUtils.isArrowToken); - - return { - before: sourceCode.getTokenBefore(arrow), - arrow, - after: sourceCode.getTokenAfter(arrow) - }; - } - - /** - * Count spaces before/after arrow(`=>`) token. - * @param {Object} tokens Tokens before/after arrow. - * @returns {Object} count of space before/after arrow. - */ - function countSpaces(tokens) { - const before = tokens.arrow.range[0] - tokens.before.range[1]; - const after = tokens.after.range[0] - tokens.arrow.range[1]; - - return { before, after }; - } - - /** - * Determines whether space(s) before after arrow(`=>`) is satisfy rule. - * if before/after value is `true`, there should be space(s). - * if before/after value is `false`, there should be no space. - * @param {ASTNode} node The arrow function node. - * @returns {void} - */ - function spaces(node) { - const tokens = getTokens(node); - const countSpace = countSpaces(tokens); - - if (rule.before) { - - // should be space(s) before arrow - if (countSpace.before === 0) { - context.report({ - node: tokens.before, - messageId: "expectedBefore", - fix(fixer) { - return fixer.insertTextBefore(tokens.arrow, " "); - } - }); - } - } else { - - // should be no space before arrow - if (countSpace.before > 0) { - context.report({ - node: tokens.before, - messageId: "unexpectedBefore", - fix(fixer) { - return fixer.removeRange([tokens.before.range[1], tokens.arrow.range[0]]); - } - }); - } - } - - if (rule.after) { - - // should be space(s) after arrow - if (countSpace.after === 0) { - context.report({ - node: tokens.after, - messageId: "expectedAfter", - fix(fixer) { - return fixer.insertTextAfter(tokens.arrow, " "); - } - }); - } - } else { - - // should be no space after arrow - if (countSpace.after > 0) { - context.report({ - node: tokens.after, - messageId: "unexpectedAfter", - fix(fixer) { - return fixer.removeRange([tokens.arrow.range[1], tokens.after.range[0]]); - } - }); - } - } - } - - return { - ArrowFunctionExpression: spaces - }; - } -}; - -/** - * @fileoverview Rule to check for "block scoped" variables by binding context - * @author Matt DuVall - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var blockScopedVar = { - meta: { - type: "suggestion", - - docs: { - description: "enforce the use of variables within the scope they are defined", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/block-scoped-var" - }, - - schema: [], - - messages: { - outOfScope: "'{{name}}' used outside of binding context." - } - }, - - create(context) { - let stack = []; - - /** - * Makes a block scope. - * @param {ASTNode} node A node of a scope. - * @returns {void} - */ - function enterScope(node) { - stack.push(node.range); - } - - /** - * Pops the last block scope. - * @returns {void} - */ - function exitScope() { - stack.pop(); - } - - /** - * Reports a given reference. - * @param {eslint-scope.Reference} reference A reference to report. - * @returns {void} - */ - function report(reference) { - const identifier = reference.identifier; - - context.report({ node: identifier, messageId: "outOfScope", data: { name: identifier.name } }); - } - - /** - * Finds and reports references which are outside of valid scopes. - * @param {ASTNode} node A node to get variables. - * @returns {void} - */ - function checkForVariables(node) { - if (node.kind !== "var") { - return; - } - - // Defines a predicate to check whether or not a given reference is outside of valid scope. - const scopeRange = stack[stack.length - 1]; - - /** - * Check if a reference is out of scope - * @param {ASTNode} reference node to examine - * @returns {boolean} True is its outside the scope - * @private - */ - function isOutsideOfScope(reference) { - const idRange = reference.identifier.range; - - return idRange[0] < scopeRange[0] || idRange[1] > scopeRange[1]; - } - - // Gets declared variables, and checks its references. - const variables = context.getDeclaredVariables(node); - - for (let i = 0; i < variables.length; ++i) { - - // Reports. - variables[i] - .references - .filter(isOutsideOfScope) - .forEach(report); - } - } - - return { - Program(node) { - stack = [node.range]; - }, - - // Manages scopes. - BlockStatement: enterScope, - "BlockStatement:exit": exitScope, - ForStatement: enterScope, - "ForStatement:exit": exitScope, - ForInStatement: enterScope, - "ForInStatement:exit": exitScope, - ForOfStatement: enterScope, - "ForOfStatement:exit": exitScope, - SwitchStatement: enterScope, - "SwitchStatement:exit": exitScope, - CatchClause: enterScope, - "CatchClause:exit": exitScope, - - // Finds and reports references which are outside of valid scope. - VariableDeclaration: checkForVariables - }; - - } -}; - -/** - * @fileoverview A rule to disallow or enforce spaces inside of single line blocks. - * @author Toru Nagashima - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var blockSpacing = { - meta: { - type: "layout", - - docs: { - description: "disallow or enforce spaces inside of blocks after opening block and before closing block", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/block-spacing" - }, - - fixable: "whitespace", - - schema: [ - { enum: ["always", "never"] } - ], - - messages: { - missing: "Requires a space {{location}} '{{token}}'.", - extra: "Unexpected space(s) {{location}} '{{token}}'." - } - }, - - create(context) { - const always = (context.options[0] !== "never"), - messageId = always ? "missing" : "extra", - sourceCode = context.getSourceCode(); - - /** - * Gets the open brace token from a given node. - * @param {ASTNode} node A BlockStatement/SwitchStatement node to get. - * @returns {Token} The token of the open brace. - */ - function getOpenBrace(node) { - if (node.type === "SwitchStatement") { - if (node.cases.length > 0) { - return sourceCode.getTokenBefore(node.cases[0]); - } - return sourceCode.getLastToken(node, 1); - } - return sourceCode.getFirstToken(node); - } - - /** - * Checks whether or not: - * - given tokens are on same line. - * - there is/isn't a space between given tokens. - * @param {Token} left A token to check. - * @param {Token} right The token which is next to `left`. - * @returns {boolean} - * When the option is `"always"`, `true` if there are one or more spaces between given tokens. - * When the option is `"never"`, `true` if there are not any spaces between given tokens. - * If given tokens are not on same line, it's always `true`. - */ - function isValid(left, right) { - return ( - !astUtils.isTokenOnSameLine(left, right) || - sourceCode.isSpaceBetweenTokens(left, right) === always - ); - } - - /** - * Reports invalid spacing style inside braces. - * @param {ASTNode} node A BlockStatement/SwitchStatement node to get. - * @returns {void} - */ - function checkSpacingInsideBraces(node) { - - // Gets braces and the first/last token of content. - const openBrace = getOpenBrace(node); - const closeBrace = sourceCode.getLastToken(node); - const firstToken = sourceCode.getTokenAfter(openBrace, { includeComments: true }); - const lastToken = sourceCode.getTokenBefore(closeBrace, { includeComments: true }); - - // Skip if the node is invalid or empty. - if (openBrace.type !== "Punctuator" || - openBrace.value !== "{" || - closeBrace.type !== "Punctuator" || - closeBrace.value !== "}" || - firstToken === closeBrace - ) { - return; - } - - // Skip line comments for option never - if (!always && firstToken.type === "Line") { - return; - } - - // Check. - if (!isValid(openBrace, firstToken)) { - let loc = openBrace.loc; - - if (messageId === "extra") { - loc = { - start: openBrace.loc.end, - end: firstToken.loc.start - }; - } - - context.report({ - node, - loc, - messageId, - data: { - location: "after", - token: openBrace.value - }, - fix(fixer) { - if (always) { - return fixer.insertTextBefore(firstToken, " "); - } - - return fixer.removeRange([openBrace.range[1], firstToken.range[0]]); - } - }); - } - if (!isValid(lastToken, closeBrace)) { - let loc = closeBrace.loc; - - if (messageId === "extra") { - loc = { - start: lastToken.loc.end, - end: closeBrace.loc.start - }; - } - context.report({ - node, - loc, - messageId, - data: { - location: "before", - token: closeBrace.value - }, - fix(fixer) { - if (always) { - return fixer.insertTextAfter(lastToken, " "); - } - - return fixer.removeRange([lastToken.range[1], closeBrace.range[0]]); - } - }); - } - } - - return { - BlockStatement: checkSpacingInsideBraces, - SwitchStatement: checkSpacingInsideBraces - }; - } -}; - -/** - * @fileoverview Rule to flag block statements that do not use the one true brace style - * @author Ian Christian Myers - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var braceStyle = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent brace style for blocks", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/brace-style" - }, - - schema: [ - { - enum: ["1tbs", "stroustrup", "allman"] - }, - { - type: "object", - properties: { - allowSingleLine: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - fixable: "whitespace", - - messages: { - nextLineOpen: "Opening curly brace does not appear on the same line as controlling statement.", - sameLineOpen: "Opening curly brace appears on the same line as controlling statement.", - blockSameLine: "Statement inside of curly braces should be on next line.", - nextLineClose: "Closing curly brace does not appear on the same line as the subsequent block.", - singleLineClose: "Closing curly brace should be on the same line as opening curly brace or on the line after the previous block.", - sameLineClose: "Closing curly brace appears on the same line as the subsequent block." - } - }, - - create(context) { - const style = context.options[0] || "1tbs", - params = context.options[1] || {}, - sourceCode = context.getSourceCode(); - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Fixes a place where a newline unexpectedly appears - * @param {Token} firstToken The token before the unexpected newline - * @param {Token} secondToken The token after the unexpected newline - * @returns {Function} A fixer function to remove the newlines between the tokens - */ - function removeNewlineBetween(firstToken, secondToken) { - const textRange = [firstToken.range[1], secondToken.range[0]]; - const textBetween = sourceCode.text.slice(textRange[0], textRange[1]); - - // Don't do a fix if there is a comment between the tokens - if (textBetween.trim()) { - return null; - } - return fixer => fixer.replaceTextRange(textRange, " "); - } - - /** - * Validates a pair of curly brackets based on the user's config - * @param {Token} openingCurly The opening curly bracket - * @param {Token} closingCurly The closing curly bracket - * @returns {void} - */ - function validateCurlyPair(openingCurly, closingCurly) { - const tokenBeforeOpeningCurly = sourceCode.getTokenBefore(openingCurly); - const tokenAfterOpeningCurly = sourceCode.getTokenAfter(openingCurly); - const tokenBeforeClosingCurly = sourceCode.getTokenBefore(closingCurly); - const singleLineException = params.allowSingleLine && astUtils.isTokenOnSameLine(openingCurly, closingCurly); - - if (style !== "allman" && !astUtils.isTokenOnSameLine(tokenBeforeOpeningCurly, openingCurly)) { - context.report({ - node: openingCurly, - messageId: "nextLineOpen", - fix: removeNewlineBetween(tokenBeforeOpeningCurly, openingCurly) - }); - } - - if (style === "allman" && astUtils.isTokenOnSameLine(tokenBeforeOpeningCurly, openingCurly) && !singleLineException) { - context.report({ - node: openingCurly, - messageId: "sameLineOpen", - fix: fixer => fixer.insertTextBefore(openingCurly, "\n") - }); - } - - if (astUtils.isTokenOnSameLine(openingCurly, tokenAfterOpeningCurly) && tokenAfterOpeningCurly !== closingCurly && !singleLineException) { - context.report({ - node: openingCurly, - messageId: "blockSameLine", - fix: fixer => fixer.insertTextAfter(openingCurly, "\n") - }); - } - - if (tokenBeforeClosingCurly !== openingCurly && !singleLineException && astUtils.isTokenOnSameLine(tokenBeforeClosingCurly, closingCurly)) { - context.report({ - node: closingCurly, - messageId: "singleLineClose", - fix: fixer => fixer.insertTextBefore(closingCurly, "\n") - }); - } - } - - /** - * Validates the location of a token that appears before a keyword (e.g. a newline before `else`) - * @param {Token} curlyToken The closing curly token. This is assumed to precede a keyword token (such as `else` or `finally`). - * @returns {void} - */ - function validateCurlyBeforeKeyword(curlyToken) { - const keywordToken = sourceCode.getTokenAfter(curlyToken); - - if (style === "1tbs" && !astUtils.isTokenOnSameLine(curlyToken, keywordToken)) { - context.report({ - node: curlyToken, - messageId: "nextLineClose", - fix: removeNewlineBetween(curlyToken, keywordToken) - }); - } - - if (style !== "1tbs" && astUtils.isTokenOnSameLine(curlyToken, keywordToken)) { - context.report({ - node: curlyToken, - messageId: "sameLineClose", - fix: fixer => fixer.insertTextAfter(curlyToken, "\n") - }); - } - } - - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- - - return { - BlockStatement(node) { - if (!astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type)) { - validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node)); - } - }, - ClassBody(node) { - validateCurlyPair(sourceCode.getFirstToken(node), sourceCode.getLastToken(node)); - }, - SwitchStatement(node) { - const closingCurly = sourceCode.getLastToken(node); - const openingCurly = sourceCode.getTokenBefore(node.cases.length ? node.cases[0] : closingCurly); - - validateCurlyPair(openingCurly, closingCurly); - }, - IfStatement(node) { - if (node.consequent.type === "BlockStatement" && node.alternate) { - - // Handle the keyword after the `if` block (before `else`) - validateCurlyBeforeKeyword(sourceCode.getLastToken(node.consequent)); - } - }, - TryStatement(node) { - - // Handle the keyword after the `try` block (before `catch` or `finally`) - validateCurlyBeforeKeyword(sourceCode.getLastToken(node.block)); - - if (node.handler && node.finalizer) { - - // Handle the keyword after the `catch` block (before `finally`) - validateCurlyBeforeKeyword(sourceCode.getLastToken(node.handler.body)); - } - } - }; - } -}; - -/** - * @fileoverview Enforce return after a callback. - * @author Jamund Ferguson - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var callbackReturn = { - meta: { - deprecated: true, - - replacedBy: [], - - type: "suggestion", - - docs: { - description: "require `return` statements after callbacks", - category: "Node.js and CommonJS", - recommended: false, - url: "https://eslint.org/docs/rules/callback-return" - }, - - schema: [{ - type: "array", - items: { type: "string" } - }], - - messages: { - missingReturn: "Expected return with your callback function." - } - }, - - create(context) { - - const callbacks = context.options[0] || ["callback", "cb", "next"], - sourceCode = context.getSourceCode(); - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Find the closest parent matching a list of types. - * @param {ASTNode} node The node whose parents we are searching - * @param {Array} types The node types to match - * @returns {ASTNode} The matched node or undefined. - */ - function findClosestParentOfType(node, types) { - if (!node.parent) { - return null; - } - if (types.indexOf(node.parent.type) === -1) { - return findClosestParentOfType(node.parent, types); - } - return node.parent; - } - - /** - * Check to see if a node contains only identifiers - * @param {ASTNode} node The node to check - * @returns {boolean} Whether or not the node contains only identifiers - */ - function containsOnlyIdentifiers(node) { - if (node.type === "Identifier") { - return true; - } - - if (node.type === "MemberExpression") { - if (node.object.type === "Identifier") { - return true; - } - if (node.object.type === "MemberExpression") { - return containsOnlyIdentifiers(node.object); - } - } - - return false; - } - - /** - * Check to see if a CallExpression is in our callback list. - * @param {ASTNode} node The node to check against our callback names list. - * @returns {boolean} Whether or not this function matches our callback name. - */ - function isCallback(node) { - return containsOnlyIdentifiers(node.callee) && callbacks.indexOf(sourceCode.getText(node.callee)) > -1; - } - - /** - * Determines whether or not the callback is part of a callback expression. - * @param {ASTNode} node The callback node - * @param {ASTNode} parentNode The expression node - * @returns {boolean} Whether or not this is part of a callback expression - */ - function isCallbackExpression(node, parentNode) { - - // ensure the parent node exists and is an expression - if (!parentNode || parentNode.type !== "ExpressionStatement") { - return false; - } - - // cb() - if (parentNode.expression === node) { - return true; - } - - // special case for cb && cb() and similar - if (parentNode.expression.type === "BinaryExpression" || parentNode.expression.type === "LogicalExpression") { - if (parentNode.expression.right === node) { - return true; - } - } - - return false; - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - CallExpression(node) { - - // if we're not a callback we can return - if (!isCallback(node)) { - return; - } - - // find the closest block, return or loop - const closestBlock = findClosestParentOfType(node, ["BlockStatement", "ReturnStatement", "ArrowFunctionExpression"]) || {}; - - // if our parent is a return we know we're ok - if (closestBlock.type === "ReturnStatement") { - return; - } - - // arrow functions don't always have blocks and implicitly return - if (closestBlock.type === "ArrowFunctionExpression") { - return; - } - - // block statements are part of functions and most if statements - if (closestBlock.type === "BlockStatement") { - - // find the last item in the block - const lastItem = closestBlock.body[closestBlock.body.length - 1]; - - // if the callback is the last thing in a block that might be ok - if (isCallbackExpression(node, lastItem)) { - - const parentType = closestBlock.parent.type; - - // but only if the block is part of a function - if (parentType === "FunctionExpression" || - parentType === "FunctionDeclaration" || - parentType === "ArrowFunctionExpression" - ) { - return; - } - - } - - // ending a block with a return is also ok - if (lastItem.type === "ReturnStatement") { - - // but only if the callback is immediately before - if (isCallbackExpression(node, closestBlock.body[closestBlock.body.length - 2])) { - return; - } - } - - } - - // as long as you're the child of a function at this point you should be asked to return - if (findClosestParentOfType(node, ["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"])) { - context.report({ node, messageId: "missingReturn" }); - } - - } - - }; - } -}; - -/** - * @fileoverview Rule to flag non-camelcased identifiers - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var camelcase = { - meta: { - type: "suggestion", - - docs: { - description: "enforce camelcase naming convention", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/camelcase" - }, - - schema: [ - { - type: "object", - properties: { - ignoreDestructuring: { - type: "boolean", - default: false - }, - ignoreImports: { - type: "boolean", - default: false - }, - ignoreGlobals: { - type: "boolean", - default: false - }, - properties: { - enum: ["always", "never"] - }, - allow: { - type: "array", - items: [ - { - type: "string" - } - ], - minItems: 0, - uniqueItems: true - } - }, - additionalProperties: false - } - ], - - messages: { - notCamelCase: "Identifier '{{name}}' is not in camel case." - } - }, - - create(context) { - - const options = context.options[0] || {}; - let properties = options.properties || ""; - const ignoreDestructuring = options.ignoreDestructuring; - const ignoreImports = options.ignoreImports; - const ignoreGlobals = options.ignoreGlobals; - const allow = options.allow || []; - - let globalScope; - - if (properties !== "always" && properties !== "never") { - properties = "always"; - } - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - // contains reported nodes to avoid reporting twice on destructuring with shorthand notation - const reported = []; - const ALLOWED_PARENT_TYPES = new Set(["CallExpression", "NewExpression"]); - - /** - * Checks if a string contains an underscore and isn't all upper-case - * @param {string} name The string to check. - * @returns {boolean} if the string is underscored - * @private - */ - function isUnderscored(name) { - - // if there's an underscore, it might be A_CONSTANT, which is okay - return name.includes("_") && name !== name.toUpperCase(); - } - - /** - * Checks if a string match the ignore list - * @param {string} name The string to check. - * @returns {boolean} if the string is ignored - * @private - */ - function isAllowed(name) { - return allow.some( - entry => name === entry || name.match(new RegExp(entry, "u")) - ); - } - - /** - * Checks if a parent of a node is an ObjectPattern. - * @param {ASTNode} node The node to check. - * @returns {boolean} if the node is inside an ObjectPattern - * @private - */ - function isInsideObjectPattern(node) { - let current = node; - - while (current) { - const parent = current.parent; - - if (parent && parent.type === "Property" && parent.computed && parent.key === current) { - return false; - } - - if (current.type === "ObjectPattern") { - return true; - } - - current = parent; - } - - return false; - } - - /** - * Checks whether the given node represents assignment target property in destructuring. - * - * For examples: - * ({a: b.foo} = c); // => true for `foo` - * ([a.foo] = b); // => true for `foo` - * ([a.foo = 1] = b); // => true for `foo` - * ({...a.foo} = b); // => true for `foo` - * @param {ASTNode} node An Identifier node to check - * @returns {boolean} True if the node is an assignment target property in destructuring. - */ - function isAssignmentTargetPropertyInDestructuring(node) { - if ( - node.parent.type === "MemberExpression" && - node.parent.property === node && - !node.parent.computed - ) { - const effectiveParent = node.parent.parent; - - return ( - effectiveParent.type === "Property" && - effectiveParent.value === node.parent && - effectiveParent.parent.type === "ObjectPattern" || - effectiveParent.type === "ArrayPattern" || - effectiveParent.type === "RestElement" || - ( - effectiveParent.type === "AssignmentPattern" && - effectiveParent.left === node.parent - ) - ); - } - return false; - } - - /** - * Checks whether the given node represents a reference to a global variable that is not declared in the source code. - * These identifiers will be allowed, as it is assumed that user has no control over the names of external global variables. - * @param {ASTNode} node `Identifier` node to check. - * @returns {boolean} `true` if the node is a reference to a global variable. - */ - function isReferenceToGlobalVariable(node) { - const variable = globalScope.set.get(node.name); - - return variable && variable.defs.length === 0 && - variable.references.some(ref => ref.identifier === node); - } - - /** - * Checks whether the given node represents a reference to a property of an object in an object literal expression. - * This allows to differentiate between a global variable that is allowed to be used as a reference, and the key - * of the expressed object (which shouldn't be allowed). - * @param {ASTNode} node `Identifier` node to check. - * @returns {boolean} `true` if the node is a property name of an object literal expression - */ - function isPropertyNameInObjectLiteral(node) { - const parent = node.parent; - - return ( - parent.type === "Property" && - parent.parent.type === "ObjectExpression" && - !parent.computed && - parent.key === node - ); - } - - /** - * Reports an AST node as a rule violation. - * @param {ASTNode} node The node to report. - * @returns {void} - * @private - */ - function report(node) { - if (!reported.includes(node)) { - reported.push(node); - context.report({ node, messageId: "notCamelCase", data: { name: node.name } }); - } - } - - return { - - Program() { - globalScope = context.getScope(); - }, - - Identifier(node) { - - /* - * Leading and trailing underscores are commonly used to flag - * private/protected identifiers, strip them before checking if underscored - */ - const name = node.name, - nameIsUnderscored = isUnderscored(name.replace(/^_+|_+$/gu, "")), - effectiveParent = (node.parent.type === "MemberExpression") ? node.parent.parent : node.parent; - - // First, we ignore the node if it match the ignore list - if (isAllowed(name)) { - return; - } - - // Check if it's a global variable - if (ignoreGlobals && isReferenceToGlobalVariable(node) && !isPropertyNameInObjectLiteral(node)) { - return; - } - - // MemberExpressions get special rules - if (node.parent.type === "MemberExpression") { - - // "never" check properties - if (properties === "never") { - return; - } - - // Always report underscored object names - if (node.parent.object.type === "Identifier" && node.parent.object.name === node.name && nameIsUnderscored) { - report(node); - - // Report AssignmentExpressions only if they are the left side of the assignment - } else if (effectiveParent.type === "AssignmentExpression" && nameIsUnderscored && (effectiveParent.right.type !== "MemberExpression" || effectiveParent.left.type === "MemberExpression" && effectiveParent.left.property.name === node.name)) { - report(node); - - } else if (isAssignmentTargetPropertyInDestructuring(node) && nameIsUnderscored) { - report(node); - } - - /* - * Properties have their own rules, and - * AssignmentPattern nodes can be treated like Properties: - * e.g.: const { no_camelcased = false } = bar; - */ - } else if (node.parent.type === "Property" || node.parent.type === "AssignmentPattern") { - - if (node.parent.parent && node.parent.parent.type === "ObjectPattern") { - if (node.parent.shorthand && node.parent.value.left && nameIsUnderscored) { - report(node); - } - - const assignmentKeyEqualsValue = node.parent.key.name === node.parent.value.name; - - if (nameIsUnderscored && node.parent.computed) { - report(node); - } - - // prevent checking righthand side of destructured object - if (node.parent.key === node && node.parent.value !== node) { - return; - } - - const valueIsUnderscored = node.parent.value.name && nameIsUnderscored; - - // ignore destructuring if the option is set, unless a new identifier is created - if (valueIsUnderscored && !(assignmentKeyEqualsValue && ignoreDestructuring)) { - report(node); - } - } - - // "never" check properties or always ignore destructuring - if (properties === "never" || (ignoreDestructuring && isInsideObjectPattern(node))) { - return; - } - - // don't check right hand side of AssignmentExpression to prevent duplicate warnings - if (nameIsUnderscored && !ALLOWED_PARENT_TYPES.has(effectiveParent.type) && !(node.parent.right === node)) { - report(node); - } - - // Check if it's an import specifier - } else if (["ImportSpecifier", "ImportNamespaceSpecifier", "ImportDefaultSpecifier"].includes(node.parent.type)) { - - if (node.parent.type === "ImportSpecifier" && ignoreImports) { - return; - } - - // Report only if the local imported identifier is underscored - if ( - node.parent.local && - node.parent.local.name === node.name && - nameIsUnderscored - ) { - report(node); - } - - // Report anything that is underscored that isn't a CallExpression - } else if (nameIsUnderscored && !ALLOWED_PARENT_TYPES.has(effectiveParent.type)) { - report(node); - } - } - - }; - - } -}; - -/** - * @fileoverview Pattern for detecting any letter (even letters outside of ASCII). - * NOTE: This file was generated using this script in JSCS based on the Unicode 7.0.0 standard: https://github.com/jscs-dev/node-jscs/blob/f5ed14427deb7e7aac84f3056a5aab2d9f3e563e/publish/helpers/generate-patterns.js - * Do not edit this file by hand-- please use https://github.com/mathiasbynens/regenerate to regenerate the regular expression exported from this file. - * @author Kevin Partington - * @license MIT License (from JSCS). See below. - */ - -var letters = /[A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDE00-\uDE11\uDE13-\uDE2B\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDE00-\uDE2F\uDE44\uDE80-\uDEAA]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]/u; - -/** - * @fileoverview enforce or disallow capitalization of the first letter of a comment - * @author Kevin Partington - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const DEFAULT_IGNORE_PATTERN = astUtils.COMMENTS_IGNORE_PATTERN, - WHITESPACE = /\s/gu, - MAYBE_URL = /^\s*[^:/?#\s]+:\/\/[^?#]/u; // TODO: Combine w/ max-len pattern? - -/* - * Base schema body for defining the basic capitalization rule, ignorePattern, - * and ignoreInlineComments values. - * This can be used in a few different ways in the actual schema. - */ -const SCHEMA_BODY = { - type: "object", - properties: { - ignorePattern: { - type: "string" - }, - ignoreInlineComments: { - type: "boolean" - }, - ignoreConsecutiveComments: { - type: "boolean" - } - }, - additionalProperties: false -}; -const DEFAULTS = { - ignorePattern: "", - ignoreInlineComments: false, - ignoreConsecutiveComments: false -}; - -/** - * Get normalized options for either block or line comments from the given - * user-provided options. - * - If the user-provided options is just a string, returns a normalized - * set of options using default values for all other options. - * - If the user-provided options is an object, then a normalized option - * set is returned. Options specified in overrides will take priority - * over options specified in the main options object, which will in - * turn take priority over the rule's defaults. - * @param {Object|string} rawOptions The user-provided options. - * @param {string} which Either "line" or "block". - * @returns {Object} The normalized options. - */ -function getNormalizedOptions(rawOptions, which) { - return Object.assign({}, DEFAULTS, rawOptions[which] || rawOptions); -} - -/** - * Get normalized options for block and line comments. - * @param {Object|string} rawOptions The user-provided options. - * @returns {Object} An object with "Line" and "Block" keys and corresponding - * normalized options objects. - */ -function getAllNormalizedOptions(rawOptions = {}) { - return { - Line: getNormalizedOptions(rawOptions, "line"), - Block: getNormalizedOptions(rawOptions, "block") - }; -} - -/** - * Creates a regular expression for each ignorePattern defined in the rule - * options. - * - * This is done in order to avoid invoking the RegExp constructor repeatedly. - * @param {Object} normalizedOptions The normalized rule options. - * @returns {void} - */ -function createRegExpForIgnorePatterns(normalizedOptions) { - Object.keys(normalizedOptions).forEach(key => { - const ignorePatternStr = normalizedOptions[key].ignorePattern; - - if (ignorePatternStr) { - const regExp = RegExp(`^\\s*(?:${ignorePatternStr})`, "u"); - - normalizedOptions[key].ignorePatternRegExp = regExp; - } - }); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var capitalizedComments = { - meta: { - type: "suggestion", - - docs: { - description: "enforce or disallow capitalization of the first letter of a comment", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/capitalized-comments" - }, - - fixable: "code", - - schema: [ - { enum: ["always", "never"] }, - { - oneOf: [ - SCHEMA_BODY, - { - type: "object", - properties: { - line: SCHEMA_BODY, - block: SCHEMA_BODY - }, - additionalProperties: false - } - ] - } - ], - - messages: { - unexpectedLowercaseComment: "Comments should not begin with a lowercase character.", - unexpectedUppercaseComment: "Comments should not begin with an uppercase character." - } - }, - - create(context) { - - const capitalize = context.options[0] || "always", - normalizedOptions = getAllNormalizedOptions(context.options[1]), - sourceCode = context.getSourceCode(); - - createRegExpForIgnorePatterns(normalizedOptions); - - //---------------------------------------------------------------------- - // Helpers - //---------------------------------------------------------------------- - - /** - * Checks whether a comment is an inline comment. - * - * For the purpose of this rule, a comment is inline if: - * 1. The comment is preceded by a token on the same line; and - * 2. The command is followed by a token on the same line. - * - * Note that the comment itself need not be single-line! - * - * Also, it follows from this definition that only block comments can - * be considered as possibly inline. This is because line comments - * would consume any following tokens on the same line as the comment. - * @param {ASTNode} comment The comment node to check. - * @returns {boolean} True if the comment is an inline comment, false - * otherwise. - */ - function isInlineComment(comment) { - const previousToken = sourceCode.getTokenBefore(comment, { includeComments: true }), - nextToken = sourceCode.getTokenAfter(comment, { includeComments: true }); - - return Boolean( - previousToken && - nextToken && - comment.loc.start.line === previousToken.loc.end.line && - comment.loc.end.line === nextToken.loc.start.line - ); - } - - /** - * Determine if a comment follows another comment. - * @param {ASTNode} comment The comment to check. - * @returns {boolean} True if the comment follows a valid comment. - */ - function isConsecutiveComment(comment) { - const previousTokenOrComment = sourceCode.getTokenBefore(comment, { includeComments: true }); - - return Boolean( - previousTokenOrComment && - ["Block", "Line"].indexOf(previousTokenOrComment.type) !== -1 - ); - } - - /** - * Check a comment to determine if it is valid for this rule. - * @param {ASTNode} comment The comment node to process. - * @param {Object} options The options for checking this comment. - * @returns {boolean} True if the comment is valid, false otherwise. - */ - function isCommentValid(comment, options) { - - // 1. Check for default ignore pattern. - if (DEFAULT_IGNORE_PATTERN.test(comment.value)) { - return true; - } - - // 2. Check for custom ignore pattern. - const commentWithoutAsterisks = comment.value - .replace(/\*/gu, ""); - - if (options.ignorePatternRegExp && options.ignorePatternRegExp.test(commentWithoutAsterisks)) { - return true; - } - - // 3. Check for inline comments. - if (options.ignoreInlineComments && isInlineComment(comment)) { - return true; - } - - // 4. Is this a consecutive comment (and are we tolerating those)? - if (options.ignoreConsecutiveComments && isConsecutiveComment(comment)) { - return true; - } - - // 5. Does the comment start with a possible URL? - if (MAYBE_URL.test(commentWithoutAsterisks)) { - return true; - } - - // 6. Is the initial word character a letter? - const commentWordCharsOnly = commentWithoutAsterisks - .replace(WHITESPACE, ""); - - if (commentWordCharsOnly.length === 0) { - return true; - } - - const firstWordChar = commentWordCharsOnly[0]; - - if (!letters.test(firstWordChar)) { - return true; - } - - // 7. Check the case of the initial word character. - const isUppercase = firstWordChar !== firstWordChar.toLocaleLowerCase(), - isLowercase = firstWordChar !== firstWordChar.toLocaleUpperCase(); - - if (capitalize === "always" && isLowercase) { - return false; - } - if (capitalize === "never" && isUppercase) { - return false; - } - - return true; - } - - /** - * Process a comment to determine if it needs to be reported. - * @param {ASTNode} comment The comment node to process. - * @returns {void} - */ - function processComment(comment) { - const options = normalizedOptions[comment.type], - commentValid = isCommentValid(comment, options); - - if (!commentValid) { - const messageId = capitalize === "always" - ? "unexpectedLowercaseComment" - : "unexpectedUppercaseComment"; - - context.report({ - node: null, // Intentionally using loc instead - loc: comment.loc, - messageId, - fix(fixer) { - const match = comment.value.match(letters); - - return fixer.replaceTextRange( - - // Offset match.index by 2 to account for the first 2 characters that start the comment (// or /*) - [comment.range[0] + match.index + 2, comment.range[0] + match.index + 3], - capitalize === "always" ? match[0].toLocaleUpperCase() : match[0].toLocaleLowerCase() - ); - } - }); - } - } - - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - - return { - Program() { - const comments = sourceCode.getAllComments(); - - comments.filter(token => token.type !== "Shebang").forEach(processComment); - } - }; - } -}; - -/** - * @fileoverview Rule to enforce that all class methods use 'this'. - * @author Patrick Williams - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var classMethodsUseThis = { - meta: { - type: "suggestion", - - docs: { - description: "enforce that class methods utilize `this`", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/class-methods-use-this" - }, - - schema: [{ - type: "object", - properties: { - exceptMethods: { - type: "array", - items: { - type: "string" - } - } - }, - additionalProperties: false - }], - - messages: { - missingThis: "Expected 'this' to be used by class {{name}}." - } - }, - create(context) { - const config = Object.assign({}, context.options[0]); - const exceptMethods = new Set(config.exceptMethods || []); - - const stack = []; - - /** - * Initializes the current context to false and pushes it onto the stack. - * These booleans represent whether 'this' has been used in the context. - * @returns {void} - * @private - */ - function enterFunction() { - stack.push(false); - } - - /** - * Check if the node is an instance method - * @param {ASTNode} node node to check - * @returns {boolean} True if its an instance method - * @private - */ - function isInstanceMethod(node) { - return !node.static && node.kind !== "constructor" && node.type === "MethodDefinition"; - } - - /** - * Check if the node is an instance method not excluded by config - * @param {ASTNode} node node to check - * @returns {boolean} True if it is an instance method, and not excluded by config - * @private - */ - function isIncludedInstanceMethod(node) { - return isInstanceMethod(node) && - (node.computed || !exceptMethods.has(node.key.name)); - } - - /** - * Checks if we are leaving a function that is a method, and reports if 'this' has not been used. - * Static methods and the constructor are exempt. - * Then pops the context off the stack. - * @param {ASTNode} node A function node that was entered. - * @returns {void} - * @private - */ - function exitFunction(node) { - const methodUsesThis = stack.pop(); - - if (isIncludedInstanceMethod(node.parent) && !methodUsesThis) { - context.report({ - node, - messageId: "missingThis", - data: { - name: astUtils.getFunctionNameWithKind(node) - } - }); - } - } - - /** - * Mark the current context as having used 'this'. - * @returns {void} - * @private - */ - function markThisUsed() { - if (stack.length) { - stack[stack.length - 1] = true; - } - } - - return { - FunctionDeclaration: enterFunction, - "FunctionDeclaration:exit": exitFunction, - FunctionExpression: enterFunction, - "FunctionExpression:exit": exitFunction, - ThisExpression: markThisUsed, - Super: markThisUsed - }; - } -}; - -/** - * @fileoverview Rule to forbid or enforce dangling commas. - * @author Ian Christian Myers - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const DEFAULT_OPTIONS$1 = Object.freeze({ - arrays: "never", - objects: "never", - imports: "never", - exports: "never", - functions: "never" -}); - -/** - * Checks whether or not a trailing comma is allowed in a given node. - * If the `lastItem` is `RestElement` or `RestProperty`, it disallows trailing commas. - * @param {ASTNode} lastItem The node of the last element in the given node. - * @returns {boolean} `true` if a trailing comma is allowed. - */ -function isTrailingCommaAllowed(lastItem) { - return !( - lastItem.type === "RestElement" || - lastItem.type === "RestProperty" || - lastItem.type === "ExperimentalRestProperty" - ); -} - -/** - * Normalize option value. - * @param {string|Object|undefined} optionValue The 1st option value to normalize. - * @param {number} ecmaVersion The normalized ECMAScript version. - * @returns {Object} The normalized option value. - */ -function normalizeOptions$2(optionValue, ecmaVersion) { - if (typeof optionValue === "string") { - return { - arrays: optionValue, - objects: optionValue, - imports: optionValue, - exports: optionValue, - functions: (!ecmaVersion || ecmaVersion < 8) ? "ignore" : optionValue - }; - } - if (typeof optionValue === "object" && optionValue !== null) { - return { - arrays: optionValue.arrays || DEFAULT_OPTIONS$1.arrays, - objects: optionValue.objects || DEFAULT_OPTIONS$1.objects, - imports: optionValue.imports || DEFAULT_OPTIONS$1.imports, - exports: optionValue.exports || DEFAULT_OPTIONS$1.exports, - functions: optionValue.functions || DEFAULT_OPTIONS$1.functions - }; - } - - return DEFAULT_OPTIONS$1; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var commaDangle = { - meta: { - type: "layout", - - docs: { - description: "require or disallow trailing commas", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/comma-dangle" - }, - - fixable: "code", - - schema: { - definitions: { - value: { - enum: [ - "always-multiline", - "always", - "never", - "only-multiline" - ] - }, - valueWithIgnore: { - enum: [ - "always-multiline", - "always", - "ignore", - "never", - "only-multiline" - ] - } - }, - type: "array", - items: [ - { - oneOf: [ - { - $ref: "#/definitions/value" - }, - { - type: "object", - properties: { - arrays: { $ref: "#/definitions/valueWithIgnore" }, - objects: { $ref: "#/definitions/valueWithIgnore" }, - imports: { $ref: "#/definitions/valueWithIgnore" }, - exports: { $ref: "#/definitions/valueWithIgnore" }, - functions: { $ref: "#/definitions/valueWithIgnore" } - }, - additionalProperties: false - } - ] - } - ] - }, - - messages: { - unexpected: "Unexpected trailing comma.", - missing: "Missing trailing comma." - } - }, - - create(context) { - const options = normalizeOptions$2(context.options[0], context.parserOptions.ecmaVersion); - - const sourceCode = context.getSourceCode(); - - /** - * Gets the last item of the given node. - * @param {ASTNode} node The node to get. - * @returns {ASTNode|null} The last node or null. - */ - function getLastItem(node) { - switch (node.type) { - case "ObjectExpression": - case "ObjectPattern": - return lodash__default['default'].last(node.properties); - case "ArrayExpression": - case "ArrayPattern": - return lodash__default['default'].last(node.elements); - case "ImportDeclaration": - case "ExportNamedDeclaration": - return lodash__default['default'].last(node.specifiers); - case "FunctionDeclaration": - case "FunctionExpression": - case "ArrowFunctionExpression": - return lodash__default['default'].last(node.params); - case "CallExpression": - case "NewExpression": - return lodash__default['default'].last(node.arguments); - default: - return null; - } - } - - /** - * Gets the trailing comma token of the given node. - * If the trailing comma does not exist, this returns the token which is - * the insertion point of the trailing comma token. - * @param {ASTNode} node The node to get. - * @param {ASTNode} lastItem The last item of the node. - * @returns {Token} The trailing comma token or the insertion point. - */ - function getTrailingToken(node, lastItem) { - switch (node.type) { - case "ObjectExpression": - case "ArrayExpression": - case "CallExpression": - case "NewExpression": - return sourceCode.getLastToken(node, 1); - default: { - const nextToken = sourceCode.getTokenAfter(lastItem); - - if (astUtils.isCommaToken(nextToken)) { - return nextToken; - } - return sourceCode.getLastToken(lastItem); - } - } - } - - /** - * Checks whether or not a given node is multiline. - * This rule handles a given node as multiline when the closing parenthesis - * and the last element are not on the same line. - * @param {ASTNode} node A node to check. - * @returns {boolean} `true` if the node is multiline. - */ - function isMultiline(node) { - const lastItem = getLastItem(node); - - if (!lastItem) { - return false; - } - - const penultimateToken = getTrailingToken(node, lastItem); - const lastToken = sourceCode.getTokenAfter(penultimateToken); - - return lastToken.loc.end.line !== penultimateToken.loc.end.line; - } - - /** - * Reports a trailing comma if it exists. - * @param {ASTNode} node A node to check. Its type is one of - * ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern, - * ImportDeclaration, and ExportNamedDeclaration. - * @returns {void} - */ - function forbidTrailingComma(node) { - const lastItem = getLastItem(node); - - if (!lastItem || (node.type === "ImportDeclaration" && lastItem.type !== "ImportSpecifier")) { - return; - } - - const trailingToken = getTrailingToken(node, lastItem); - - if (astUtils.isCommaToken(trailingToken)) { - context.report({ - node: lastItem, - loc: trailingToken.loc, - messageId: "unexpected", - fix(fixer) { - return fixer.remove(trailingToken); - } - }); - } - } - - /** - * Reports the last element of a given node if it does not have a trailing - * comma. - * - * If a given node is `ArrayPattern` which has `RestElement`, the trailing - * comma is disallowed, so report if it exists. - * @param {ASTNode} node A node to check. Its type is one of - * ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern, - * ImportDeclaration, and ExportNamedDeclaration. - * @returns {void} - */ - function forceTrailingComma(node) { - const lastItem = getLastItem(node); - - if (!lastItem || (node.type === "ImportDeclaration" && lastItem.type !== "ImportSpecifier")) { - return; - } - if (!isTrailingCommaAllowed(lastItem)) { - forbidTrailingComma(node); - return; - } - - const trailingToken = getTrailingToken(node, lastItem); - - if (trailingToken.value !== ",") { - context.report({ - node: lastItem, - loc: { - start: trailingToken.loc.end, - end: astUtils.getNextLocation(sourceCode, trailingToken.loc.end) - }, - messageId: "missing", - fix(fixer) { - return fixer.insertTextAfter(trailingToken, ","); - } - }); - } - } - - /** - * If a given node is multiline, reports the last element of a given node - * when it does not have a trailing comma. - * Otherwise, reports a trailing comma if it exists. - * @param {ASTNode} node A node to check. Its type is one of - * ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern, - * ImportDeclaration, and ExportNamedDeclaration. - * @returns {void} - */ - function forceTrailingCommaIfMultiline(node) { - if (isMultiline(node)) { - forceTrailingComma(node); - } else { - forbidTrailingComma(node); - } - } - - /** - * Only if a given node is not multiline, reports the last element of a given node - * when it does not have a trailing comma. - * Otherwise, reports a trailing comma if it exists. - * @param {ASTNode} node A node to check. Its type is one of - * ObjectExpression, ObjectPattern, ArrayExpression, ArrayPattern, - * ImportDeclaration, and ExportNamedDeclaration. - * @returns {void} - */ - function allowTrailingCommaIfMultiline(node) { - if (!isMultiline(node)) { - forbidTrailingComma(node); - } - } - - const predicate = { - always: forceTrailingComma, - "always-multiline": forceTrailingCommaIfMultiline, - "only-multiline": allowTrailingCommaIfMultiline, - never: forbidTrailingComma, - ignore: lodash__default['default'].noop - }; - - return { - ObjectExpression: predicate[options.objects], - ObjectPattern: predicate[options.objects], - - ArrayExpression: predicate[options.arrays], - ArrayPattern: predicate[options.arrays], - - ImportDeclaration: predicate[options.imports], - - ExportNamedDeclaration: predicate[options.exports], - - FunctionDeclaration: predicate[options.functions], - FunctionExpression: predicate[options.functions], - ArrowFunctionExpression: predicate[options.functions], - CallExpression: predicate[options.functions], - NewExpression: predicate[options.functions] - }; - } -}; - -/** - * @fileoverview Comma spacing - validates spacing before and after comma - * @author Vignesh Anand aka vegetableman. - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var commaSpacing = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent spacing before and after commas", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/comma-spacing" - }, - - fixable: "whitespace", - - schema: [ - { - type: "object", - properties: { - before: { - type: "boolean", - default: false - }, - after: { - type: "boolean", - default: true - } - }, - additionalProperties: false - } - ], - - messages: { - missing: "A space is required {{loc}} ','.", - unexpected: "There should be no space {{loc}} ','." - } - }, - - create(context) { - - const sourceCode = context.getSourceCode(); - const tokensAndComments = sourceCode.tokensAndComments; - - const options = { - before: context.options[0] ? context.options[0].before : false, - after: context.options[0] ? context.options[0].after : true - }; - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - // list of comma tokens to ignore for the check of leading whitespace - const commaTokensToIgnore = []; - - /** - * Reports a spacing error with an appropriate message. - * @param {ASTNode} node The binary expression node to report. - * @param {string} loc Is the error "before" or "after" the comma? - * @param {ASTNode} otherNode The node at the left or right of `node` - * @returns {void} - * @private - */ - function report(node, loc, otherNode) { - context.report({ - node, - fix(fixer) { - if (options[loc]) { - if (loc === "before") { - return fixer.insertTextBefore(node, " "); - } - return fixer.insertTextAfter(node, " "); - - } - let start, end; - const newText = ""; - - if (loc === "before") { - start = otherNode.range[1]; - end = node.range[0]; - } else { - start = node.range[1]; - end = otherNode.range[0]; - } - - return fixer.replaceTextRange([start, end], newText); - - }, - messageId: options[loc] ? "missing" : "unexpected", - data: { - loc - } - }); - } - - /** - * Validates the spacing around a comma token. - * @param {Object} tokens The tokens to be validated. - * @param {Token} tokens.comma The token representing the comma. - * @param {Token} [tokens.left] The last token before the comma. - * @param {Token} [tokens.right] The first token after the comma. - * @param {Token|ASTNode} reportItem The item to use when reporting an error. - * @returns {void} - * @private - */ - function validateCommaItemSpacing(tokens, reportItem) { - if (tokens.left && astUtils.isTokenOnSameLine(tokens.left, tokens.comma) && - (options.before !== sourceCode.isSpaceBetweenTokens(tokens.left, tokens.comma)) - ) { - report(reportItem, "before", tokens.left); - } - - if (tokens.right && astUtils.isClosingParenToken(tokens.right)) { - return; - } - - if (tokens.right && !options.after && tokens.right.type === "Line") { - return; - } - - if (tokens.right && astUtils.isTokenOnSameLine(tokens.comma, tokens.right) && - (options.after !== sourceCode.isSpaceBetweenTokens(tokens.comma, tokens.right)) - ) { - report(reportItem, "after", tokens.right); - } - } - - /** - * Adds null elements of the given ArrayExpression or ArrayPattern node to the ignore list. - * @param {ASTNode} node An ArrayExpression or ArrayPattern node. - * @returns {void} - */ - function addNullElementsToIgnoreList(node) { - let previousToken = sourceCode.getFirstToken(node); - - node.elements.forEach(element => { - let token; - - if (element === null) { - token = sourceCode.getTokenAfter(previousToken); - - if (astUtils.isCommaToken(token)) { - commaTokensToIgnore.push(token); - } - } else { - token = sourceCode.getTokenAfter(element); - } - - previousToken = token; - }); - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - "Program:exit"() { - tokensAndComments.forEach((token, i) => { - - if (!astUtils.isCommaToken(token)) { - return; - } - - if (token && token.type === "JSXText") { - return; - } - - const previousToken = tokensAndComments[i - 1]; - const nextToken = tokensAndComments[i + 1]; - - validateCommaItemSpacing({ - comma: token, - left: astUtils.isCommaToken(previousToken) || commaTokensToIgnore.indexOf(token) > -1 ? null : previousToken, - right: astUtils.isCommaToken(nextToken) ? null : nextToken - }, token); - }); - }, - ArrayExpression: addNullElementsToIgnoreList, - ArrayPattern: addNullElementsToIgnoreList - - }; - - } -}; - -/** - * @fileoverview Comma style - enforces comma styles of two types: last and first - * @author Vignesh Anand aka vegetableman - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var commaStyle = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent comma style", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/comma-style" - }, - - fixable: "code", - - schema: [ - { - enum: ["first", "last"] - }, - { - type: "object", - properties: { - exceptions: { - type: "object", - additionalProperties: { - type: "boolean" - } - } - }, - additionalProperties: false - } - ], - - messages: { - unexpectedLineBeforeAndAfterComma: "Bad line breaking before and after ','.", - expectedCommaFirst: "',' should be placed first.", - expectedCommaLast: "',' should be placed last." - } - }, - - create(context) { - const style = context.options[0] || "last", - sourceCode = context.getSourceCode(); - const exceptions = { - ArrayPattern: true, - ArrowFunctionExpression: true, - CallExpression: true, - FunctionDeclaration: true, - FunctionExpression: true, - ImportDeclaration: true, - ObjectPattern: true, - NewExpression: true - }; - - if (context.options.length === 2 && Object.prototype.hasOwnProperty.call(context.options[1], "exceptions")) { - const keys = Object.keys(context.options[1].exceptions); - - for (let i = 0; i < keys.length; i++) { - exceptions[keys[i]] = context.options[1].exceptions[keys[i]]; - } - } - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Modified text based on the style - * @param {string} styleType Style type - * @param {string} text Source code text - * @returns {string} modified text - * @private - */ - function getReplacedText(styleType, text) { - switch (styleType) { - case "between": - return `,${text.replace(astUtils.LINEBREAK_MATCHER, "")}`; - - case "first": - return `${text},`; - - case "last": - return `,${text}`; - - default: - return ""; - } - } - - /** - * Determines the fixer function for a given style. - * @param {string} styleType comma style - * @param {ASTNode} previousItemToken The token to check. - * @param {ASTNode} commaToken The token to check. - * @param {ASTNode} currentItemToken The token to check. - * @returns {Function} Fixer function - * @private - */ - function getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken) { - const text = - sourceCode.text.slice(previousItemToken.range[1], commaToken.range[0]) + - sourceCode.text.slice(commaToken.range[1], currentItemToken.range[0]); - const range = [previousItemToken.range[1], currentItemToken.range[0]]; - - return function(fixer) { - return fixer.replaceTextRange(range, getReplacedText(styleType, text)); - }; - } - - /** - * Validates the spacing around single items in lists. - * @param {Token} previousItemToken The last token from the previous item. - * @param {Token} commaToken The token representing the comma. - * @param {Token} currentItemToken The first token of the current item. - * @param {Token} reportItem The item to use when reporting an error. - * @returns {void} - * @private - */ - function validateCommaItemSpacing(previousItemToken, commaToken, currentItemToken, reportItem) { - - // if single line - if (astUtils.isTokenOnSameLine(commaToken, currentItemToken) && - astUtils.isTokenOnSameLine(previousItemToken, commaToken)) ; else if (!astUtils.isTokenOnSameLine(commaToken, currentItemToken) && - !astUtils.isTokenOnSameLine(previousItemToken, commaToken)) { - - const comment = sourceCode.getCommentsAfter(commaToken)[0]; - const styleType = comment && comment.type === "Block" && astUtils.isTokenOnSameLine(commaToken, comment) - ? style - : "between"; - - // lone comma - context.report({ - node: reportItem, - loc: commaToken.loc, - messageId: "unexpectedLineBeforeAndAfterComma", - fix: getFixerFunction(styleType, previousItemToken, commaToken, currentItemToken) - }); - - } else if (style === "first" && !astUtils.isTokenOnSameLine(commaToken, currentItemToken)) { - - context.report({ - node: reportItem, - loc: commaToken.loc, - messageId: "expectedCommaFirst", - fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken) - }); - - } else if (style === "last" && astUtils.isTokenOnSameLine(commaToken, currentItemToken)) { - - context.report({ - node: reportItem, - loc: commaToken.loc, - messageId: "expectedCommaLast", - fix: getFixerFunction(style, previousItemToken, commaToken, currentItemToken) - }); - } - } - - /** - * Checks the comma placement with regards to a declaration/property/element - * @param {ASTNode} node The binary expression node to check - * @param {string} property The property of the node containing child nodes. - * @private - * @returns {void} - */ - function validateComma(node, property) { - const items = node[property], - arrayLiteral = (node.type === "ArrayExpression" || node.type === "ArrayPattern"); - - if (items.length > 1 || arrayLiteral) { - - // seed as opening [ - let previousItemToken = sourceCode.getFirstToken(node); - - items.forEach(item => { - const commaToken = item ? sourceCode.getTokenBefore(item) : previousItemToken, - currentItemToken = item ? sourceCode.getFirstToken(item) : sourceCode.getTokenAfter(commaToken), - reportItem = item || currentItemToken; - - /* - * This works by comparing three token locations: - * - previousItemToken is the last token of the previous item - * - commaToken is the location of the comma before the current item - * - currentItemToken is the first token of the current item - * - * These values get switched around if item is undefined. - * previousItemToken will refer to the last token not belonging - * to the current item, which could be a comma or an opening - * square bracket. currentItemToken could be a comma. - * - * All comparisons are done based on these tokens directly, so - * they are always valid regardless of an undefined item. - */ - if (astUtils.isCommaToken(commaToken)) { - validateCommaItemSpacing(previousItemToken, commaToken, - currentItemToken, reportItem); - } - - if (item) { - const tokenAfterItem = sourceCode.getTokenAfter(item, astUtils.isNotClosingParenToken); - - previousItemToken = tokenAfterItem - ? sourceCode.getTokenBefore(tokenAfterItem) - : sourceCode.ast.tokens[sourceCode.ast.tokens.length - 1]; - } - }); - - /* - * Special case for array literals that have empty last items, such - * as [ 1, 2, ]. These arrays only have two items show up in the - * AST, so we need to look at the token to verify that there's no - * dangling comma. - */ - if (arrayLiteral) { - - const lastToken = sourceCode.getLastToken(node), - nextToLastToken = sourceCode.getTokenBefore(lastToken); - - if (astUtils.isCommaToken(nextToLastToken)) { - validateCommaItemSpacing( - sourceCode.getTokenBefore(nextToLastToken), - nextToLastToken, - lastToken, - lastToken - ); - } - } - } - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - const nodes = {}; - - if (!exceptions.VariableDeclaration) { - nodes.VariableDeclaration = function(node) { - validateComma(node, "declarations"); - }; - } - if (!exceptions.ObjectExpression) { - nodes.ObjectExpression = function(node) { - validateComma(node, "properties"); - }; - } - if (!exceptions.ObjectPattern) { - nodes.ObjectPattern = function(node) { - validateComma(node, "properties"); - }; - } - if (!exceptions.ArrayExpression) { - nodes.ArrayExpression = function(node) { - validateComma(node, "elements"); - }; - } - if (!exceptions.ArrayPattern) { - nodes.ArrayPattern = function(node) { - validateComma(node, "elements"); - }; - } - if (!exceptions.FunctionDeclaration) { - nodes.FunctionDeclaration = function(node) { - validateComma(node, "params"); - }; - } - if (!exceptions.FunctionExpression) { - nodes.FunctionExpression = function(node) { - validateComma(node, "params"); - }; - } - if (!exceptions.ArrowFunctionExpression) { - nodes.ArrowFunctionExpression = function(node) { - validateComma(node, "params"); - }; - } - if (!exceptions.CallExpression) { - nodes.CallExpression = function(node) { - validateComma(node, "arguments"); - }; - } - if (!exceptions.ImportDeclaration) { - nodes.ImportDeclaration = function(node) { - validateComma(node, "specifiers"); - }; - } - if (!exceptions.NewExpression) { - nodes.NewExpression = function(node) { - validateComma(node, "arguments"); - }; - } - - return nodes; - } -}; - -/** - * @fileoverview Counts the cyclomatic complexity of each function of the script. See http://en.wikipedia.org/wiki/Cyclomatic_complexity. - * Counts the number of if, conditional, for, while, try, switch/case, - * @author Patrick Brosset - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var complexity = { - meta: { - type: "suggestion", - - docs: { - description: "enforce a maximum cyclomatic complexity allowed in a program", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/complexity" - }, - - schema: [ - { - oneOf: [ - { - type: "integer", - minimum: 0 - }, - { - type: "object", - properties: { - maximum: { - type: "integer", - minimum: 0 - }, - max: { - type: "integer", - minimum: 0 - } - }, - additionalProperties: false - } - ] - } - ], - - messages: { - complex: "{{name}} has a complexity of {{complexity}}. Maximum allowed is {{max}}." - } - }, - - create(context) { - const option = context.options[0]; - let THRESHOLD = 20; - - if ( - typeof option === "object" && - (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max")) - ) { - THRESHOLD = option.maximum || option.max; - } else if (typeof option === "number") { - THRESHOLD = option; - } - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - // Using a stack to store complexity (handling nested functions) - const fns = []; - - /** - * When parsing a new function, store it in our function stack - * @returns {void} - * @private - */ - function startFunction() { - fns.push(1); - } - - /** - * Evaluate the node at the end of function - * @param {ASTNode} node node to evaluate - * @returns {void} - * @private - */ - function endFunction(node) { - const name = lodash__default['default'].upperFirst(astUtils.getFunctionNameWithKind(node)); - const complexity = fns.pop(); - - if (complexity > THRESHOLD) { - context.report({ - node, - messageId: "complex", - data: { name, complexity, max: THRESHOLD } - }); - } - } - - /** - * Increase the complexity of the function in context - * @returns {void} - * @private - */ - function increaseComplexity() { - if (fns.length) { - fns[fns.length - 1]++; - } - } - - /** - * Increase the switch complexity in context - * @param {ASTNode} node node to evaluate - * @returns {void} - * @private - */ - function increaseSwitchComplexity(node) { - - // Avoiding `default` - if (node.test) { - increaseComplexity(); - } - } - - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- - - return { - FunctionDeclaration: startFunction, - FunctionExpression: startFunction, - ArrowFunctionExpression: startFunction, - "FunctionDeclaration:exit": endFunction, - "FunctionExpression:exit": endFunction, - "ArrowFunctionExpression:exit": endFunction, - - CatchClause: increaseComplexity, - ConditionalExpression: increaseComplexity, - LogicalExpression: increaseComplexity, - ForStatement: increaseComplexity, - ForInStatement: increaseComplexity, - ForOfStatement: increaseComplexity, - IfStatement: increaseComplexity, - SwitchCase: increaseSwitchComplexity, - WhileStatement: increaseComplexity, - DoWhileStatement: increaseComplexity, - - AssignmentExpression(node) { - if (astUtils.isLogicalAssignmentOperator(node.operator)) { - increaseComplexity(); - } - } - }; - - } -}; - -/** - * @fileoverview Disallows or enforces spaces inside computed properties. - * @author Jamund Ferguson - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var computedPropertySpacing = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent spacing inside computed property brackets", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/computed-property-spacing" - }, - - fixable: "whitespace", - - schema: [ - { - enum: ["always", "never"] - }, - { - type: "object", - properties: { - enforceForClassMembers: { - type: "boolean", - default: true - } - }, - additionalProperties: false - } - ], - - messages: { - unexpectedSpaceBefore: "There should be no space before '{{tokenValue}}'.", - unexpectedSpaceAfter: "There should be no space after '{{tokenValue}}'.", - - missingSpaceBefore: "A space is required before '{{tokenValue}}'.", - missingSpaceAfter: "A space is required after '{{tokenValue}}'." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const propertyNameMustBeSpaced = context.options[0] === "always"; // default is "never" - const enforceForClassMembers = !context.options[1] || context.options[1].enforceForClassMembers; - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Reports that there shouldn't be a space after the first token - * @param {ASTNode} node The node to report in the event of an error. - * @param {Token} token The token to use for the report. - * @param {Token} tokenAfter The token after `token`. - * @returns {void} - */ - function reportNoBeginningSpace(node, token, tokenAfter) { - context.report({ - node, - loc: { start: token.loc.end, end: tokenAfter.loc.start }, - messageId: "unexpectedSpaceAfter", - data: { - tokenValue: token.value - }, - fix(fixer) { - return fixer.removeRange([token.range[1], tokenAfter.range[0]]); - } - }); - } - - /** - * Reports that there shouldn't be a space before the last token - * @param {ASTNode} node The node to report in the event of an error. - * @param {Token} token The token to use for the report. - * @param {Token} tokenBefore The token before `token`. - * @returns {void} - */ - function reportNoEndingSpace(node, token, tokenBefore) { - context.report({ - node, - loc: { start: tokenBefore.loc.end, end: token.loc.start }, - messageId: "unexpectedSpaceBefore", - data: { - tokenValue: token.value - }, - fix(fixer) { - return fixer.removeRange([tokenBefore.range[1], token.range[0]]); - } - }); - } - - /** - * Reports that there should be a space after the first token - * @param {ASTNode} node The node to report in the event of an error. - * @param {Token} token The token to use for the report. - * @returns {void} - */ - function reportRequiredBeginningSpace(node, token) { - context.report({ - node, - loc: token.loc, - messageId: "missingSpaceAfter", - data: { - tokenValue: token.value - }, - fix(fixer) { - return fixer.insertTextAfter(token, " "); - } - }); - } - - /** - * Reports that there should be a space before the last token - * @param {ASTNode} node The node to report in the event of an error. - * @param {Token} token The token to use for the report. - * @returns {void} - */ - function reportRequiredEndingSpace(node, token) { - context.report({ - node, - loc: token.loc, - messageId: "missingSpaceBefore", - data: { - tokenValue: token.value - }, - fix(fixer) { - return fixer.insertTextBefore(token, " "); - } - }); - } - - /** - * Returns a function that checks the spacing of a node on the property name - * that was passed in. - * @param {string} propertyName The property on the node to check for spacing - * @returns {Function} A function that will check spacing on a node - */ - function checkSpacing(propertyName) { - return function(node) { - if (!node.computed) { - return; - } - - const property = node[propertyName]; - - const before = sourceCode.getTokenBefore(property, astUtils.isOpeningBracketToken), - first = sourceCode.getTokenAfter(before, { includeComments: true }), - after = sourceCode.getTokenAfter(property, astUtils.isClosingBracketToken), - last = sourceCode.getTokenBefore(after, { includeComments: true }); - - if (astUtils.isTokenOnSameLine(before, first)) { - if (propertyNameMustBeSpaced) { - if (!sourceCode.isSpaceBetweenTokens(before, first) && astUtils.isTokenOnSameLine(before, first)) { - reportRequiredBeginningSpace(node, before); - } - } else { - if (sourceCode.isSpaceBetweenTokens(before, first)) { - reportNoBeginningSpace(node, before, first); - } - } - } - - if (astUtils.isTokenOnSameLine(last, after)) { - if (propertyNameMustBeSpaced) { - if (!sourceCode.isSpaceBetweenTokens(last, after) && astUtils.isTokenOnSameLine(last, after)) { - reportRequiredEndingSpace(node, after); - } - } else { - if (sourceCode.isSpaceBetweenTokens(last, after)) { - reportNoEndingSpace(node, after, last); - } - } - } - }; - } - - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - const listeners = { - Property: checkSpacing("key"), - MemberExpression: checkSpacing("property") - }; - - if (enforceForClassMembers) { - listeners.MethodDefinition = checkSpacing("key"); - } - - return listeners; - - } -}; - -/** - * @fileoverview Rule to flag consistent return values - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether or not a given code path segment is unreachable. - * @param {CodePathSegment} segment A CodePathSegment to check. - * @returns {boolean} `true` if the segment is unreachable. - */ -function isUnreachable$1(segment) { - return !segment.reachable; -} - -/** - * Checks whether a given node is a `constructor` method in an ES6 class - * @param {ASTNode} node A node to check - * @returns {boolean} `true` if the node is a `constructor` method - */ -function isClassConstructor(node) { - return node.type === "FunctionExpression" && - node.parent && - node.parent.type === "MethodDefinition" && - node.parent.kind === "constructor"; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var consistentReturn = { - meta: { - type: "suggestion", - - docs: { - description: "require `return` statements to either always or never specify values", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/consistent-return" - }, - - schema: [{ - type: "object", - properties: { - treatUndefinedAsUnspecified: { - type: "boolean", - default: false - } - }, - additionalProperties: false - }], - - messages: { - missingReturn: "Expected to return a value at the end of {{name}}.", - missingReturnValue: "{{name}} expected a return value.", - unexpectedReturnValue: "{{name}} expected no return value." - } - }, - - create(context) { - const options = context.options[0] || {}; - const treatUndefinedAsUnspecified = options.treatUndefinedAsUnspecified === true; - let funcInfo = null; - - /** - * Checks whether of not the implicit returning is consistent if the last - * code path segment is reachable. - * @param {ASTNode} node A program/function node to check. - * @returns {void} - */ - function checkLastSegment(node) { - let loc, name; - - /* - * Skip if it expected no return value or unreachable. - * When unreachable, all paths are returned or thrown. - */ - if (!funcInfo.hasReturnValue || - funcInfo.codePath.currentSegments.every(isUnreachable$1) || - astUtils.isES5Constructor(node) || - isClassConstructor(node) - ) { - return; - } - - // Adjust a location and a message. - if (node.type === "Program") { - - // The head of program. - loc = { line: 1, column: 0 }; - name = "program"; - } else if (node.type === "ArrowFunctionExpression") { - - // `=>` token - loc = context.getSourceCode().getTokenBefore(node.body, astUtils.isArrowToken).loc.start; - } else if ( - node.parent.type === "MethodDefinition" || - (node.parent.type === "Property" && node.parent.method) - ) { - - // Method name. - loc = node.parent.key.loc.start; - } else { - - // Function name or `function` keyword. - loc = (node.id || node).loc.start; - } - - if (!name) { - name = astUtils.getFunctionNameWithKind(node); - } - - // Reports. - context.report({ - node, - loc, - messageId: "missingReturn", - data: { name } - }); - } - - return { - - // Initializes/Disposes state of each code path. - onCodePathStart(codePath, node) { - funcInfo = { - upper: funcInfo, - codePath, - hasReturn: false, - hasReturnValue: false, - messageId: "", - node - }; - }, - onCodePathEnd() { - funcInfo = funcInfo.upper; - }, - - // Reports a given return statement if it's inconsistent. - ReturnStatement(node) { - const argument = node.argument; - let hasReturnValue = Boolean(argument); - - if (treatUndefinedAsUnspecified && hasReturnValue) { - hasReturnValue = !astUtils.isSpecificId(argument, "undefined") && argument.operator !== "void"; - } - - if (!funcInfo.hasReturn) { - funcInfo.hasReturn = true; - funcInfo.hasReturnValue = hasReturnValue; - funcInfo.messageId = hasReturnValue ? "missingReturnValue" : "unexpectedReturnValue"; - funcInfo.data = { - name: funcInfo.node.type === "Program" - ? "Program" - : lodash__default['default'].upperFirst(astUtils.getFunctionNameWithKind(funcInfo.node)) - }; - } else if (funcInfo.hasReturnValue !== hasReturnValue) { - context.report({ - node, - messageId: funcInfo.messageId, - data: funcInfo.data - }); - } - }, - - // Reports a given program/function if the implicit returning is not consistent. - "Program:exit": checkLastSegment, - "FunctionDeclaration:exit": checkLastSegment, - "FunctionExpression:exit": checkLastSegment, - "ArrowFunctionExpression:exit": checkLastSegment - }; - } -}; - -/** - * @fileoverview Rule to enforce consistent naming of "this" context variables - * @author Raphael Pigulla - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var consistentThis = { - meta: { - type: "suggestion", - - docs: { - description: "enforce consistent naming when capturing the current execution context", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/consistent-this" - }, - - schema: { - type: "array", - items: { - type: "string", - minLength: 1 - }, - uniqueItems: true - }, - - messages: { - aliasNotAssignedToThis: "Designated alias '{{name}}' is not assigned to 'this'.", - unexpectedAlias: "Unexpected alias '{{name}}' for 'this'." - } - }, - - create(context) { - let aliases = []; - - if (context.options.length === 0) { - aliases.push("that"); - } else { - aliases = context.options; - } - - /** - * Reports that a variable declarator or assignment expression is assigning - * a non-'this' value to the specified alias. - * @param {ASTNode} node The assigning node. - * @param {string} name the name of the alias that was incorrectly used. - * @returns {void} - */ - function reportBadAssignment(node, name) { - context.report({ node, messageId: "aliasNotAssignedToThis", data: { name } }); - } - - /** - * Checks that an assignment to an identifier only assigns 'this' to the - * appropriate alias, and the alias is only assigned to 'this'. - * @param {ASTNode} node The assigning node. - * @param {Identifier} name The name of the variable assigned to. - * @param {Expression} value The value of the assignment. - * @returns {void} - */ - function checkAssignment(node, name, value) { - const isThis = value.type === "ThisExpression"; - - if (aliases.indexOf(name) !== -1) { - if (!isThis || node.operator && node.operator !== "=") { - reportBadAssignment(node, name); - } - } else if (isThis) { - context.report({ node, messageId: "unexpectedAlias", data: { name } }); - } - } - - /** - * Ensures that a variable declaration of the alias in a program or function - * is assigned to the correct value. - * @param {string} alias alias the check the assignment of. - * @param {Object} scope scope of the current code we are checking. - * @private - * @returns {void} - */ - function checkWasAssigned(alias, scope) { - const variable = scope.set.get(alias); - - if (!variable) { - return; - } - - if (variable.defs.some(def => def.node.type === "VariableDeclarator" && - def.node.init !== null)) { - return; - } - - /* - * The alias has been declared and not assigned: check it was - * assigned later in the same scope. - */ - if (!variable.references.some(reference => { - const write = reference.writeExpr; - - return ( - reference.from === scope && - write && write.type === "ThisExpression" && - write.parent.operator === "=" - ); - })) { - variable.defs.map(def => def.node).forEach(node => { - reportBadAssignment(node, alias); - }); - } - } - - /** - * Check each alias to ensure that is was assigned to the correct value. - * @returns {void} - */ - function ensureWasAssigned() { - const scope = context.getScope(); - - aliases.forEach(alias => { - checkWasAssigned(alias, scope); - }); - } - - return { - "Program:exit": ensureWasAssigned, - "FunctionExpression:exit": ensureWasAssigned, - "FunctionDeclaration:exit": ensureWasAssigned, - - VariableDeclarator(node) { - const id = node.id; - const isDestructuring = - id.type === "ArrayPattern" || id.type === "ObjectPattern"; - - if (node.init !== null && !isDestructuring) { - checkAssignment(node, id.name, node.init); - } - }, - - AssignmentExpression(node) { - if (node.left.type === "Identifier") { - checkAssignment(node, node.left.name, node.right); - } - } - }; - - } -}; - -/** - * @fileoverview A rule to verify `super()` callings in constructor. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether a given code path segment is reachable or not. - * @param {CodePathSegment} segment A code path segment to check. - * @returns {boolean} `true` if the segment is reachable. - */ -function isReachable$2(segment) { - return segment.reachable; -} - -/** - * Checks whether or not a given node is a constructor. - * @param {ASTNode} node A node to check. This node type is one of - * `Program`, `FunctionDeclaration`, `FunctionExpression`, and - * `ArrowFunctionExpression`. - * @returns {boolean} `true` if the node is a constructor. - */ -function isConstructorFunction$1(node) { - return ( - node.type === "FunctionExpression" && - node.parent.type === "MethodDefinition" && - node.parent.kind === "constructor" - ); -} - -/** - * Checks whether a given node can be a constructor or not. - * @param {ASTNode} node A node to check. - * @returns {boolean} `true` if the node can be a constructor. - */ -function isPossibleConstructor(node) { - if (!node) { - return false; - } - - switch (node.type) { - case "ClassExpression": - case "FunctionExpression": - case "ThisExpression": - case "MemberExpression": - case "CallExpression": - case "NewExpression": - case "ChainExpression": - case "YieldExpression": - case "TaggedTemplateExpression": - case "MetaProperty": - return true; - - case "Identifier": - return node.name !== "undefined"; - - case "AssignmentExpression": - if (["=", "&&="].includes(node.operator)) { - return isPossibleConstructor(node.right); - } - - if (["||=", "??="].includes(node.operator)) { - return ( - isPossibleConstructor(node.left) || - isPossibleConstructor(node.right) - ); - } - - /** - * All other assignment operators are mathematical assignment operators (arithmetic or bitwise). - * An assignment expression with a mathematical operator can either evaluate to a primitive value, - * or throw, depending on the operands. Thus, it cannot evaluate to a constructor function. - */ - return false; - - case "LogicalExpression": - - /* - * If the && operator short-circuits, the left side was falsy and therefore not a constructor, and if - * it doesn't short-circuit, it takes the value from the right side, so the right side must always be a - * possible constructor. A future improvement could verify that the left side could be truthy by - * excluding falsy literals. - */ - if (node.operator === "&&") { - return isPossibleConstructor(node.right); - } - - return ( - isPossibleConstructor(node.left) || - isPossibleConstructor(node.right) - ); - - case "ConditionalExpression": - return ( - isPossibleConstructor(node.alternate) || - isPossibleConstructor(node.consequent) - ); - - case "SequenceExpression": { - const lastExpression = node.expressions[node.expressions.length - 1]; - - return isPossibleConstructor(lastExpression); - } - - default: - return false; - } -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var constructorSuper = { - meta: { - type: "problem", - - docs: { - description: "require `super()` calls in constructors", - category: "ECMAScript 6", - recommended: true, - url: "https://eslint.org/docs/rules/constructor-super" - }, - - schema: [], - - messages: { - missingSome: "Lacked a call of 'super()' in some code paths.", - missingAll: "Expected to call 'super()'.", - - duplicate: "Unexpected duplicate 'super()'.", - badSuper: "Unexpected 'super()' because 'super' is not a constructor.", - unexpected: "Unexpected 'super()'." - } - }, - - create(context) { - - /* - * {{hasExtends: boolean, scope: Scope, codePath: CodePath}[]} - * Information for each constructor. - * - upper: Information of the upper constructor. - * - hasExtends: A flag which shows whether own class has a valid `extends` - * part. - * - scope: The scope of own class. - * - codePath: The code path object of the constructor. - */ - let funcInfo = null; - - /* - * {Map} - * Information for each code path segment. - * - calledInSomePaths: A flag of be called `super()` in some code paths. - * - calledInEveryPaths: A flag of be called `super()` in all code paths. - * - validNodes: - */ - let segInfoMap = Object.create(null); - - /** - * Gets the flag which shows `super()` is called in some paths. - * @param {CodePathSegment} segment A code path segment to get. - * @returns {boolean} The flag which shows `super()` is called in some paths - */ - function isCalledInSomePath(segment) { - return segment.reachable && segInfoMap[segment.id].calledInSomePaths; - } - - /** - * Gets the flag which shows `super()` is called in all paths. - * @param {CodePathSegment} segment A code path segment to get. - * @returns {boolean} The flag which shows `super()` is called in all paths. - */ - function isCalledInEveryPath(segment) { - - /* - * If specific segment is the looped segment of the current segment, - * skip the segment. - * If not skipped, this never becomes true after a loop. - */ - if (segment.nextSegments.length === 1 && - segment.nextSegments[0].isLoopedPrevSegment(segment) - ) { - return true; - } - return segment.reachable && segInfoMap[segment.id].calledInEveryPaths; - } - - return { - - /** - * Stacks a constructor information. - * @param {CodePath} codePath A code path which was started. - * @param {ASTNode} node The current node. - * @returns {void} - */ - onCodePathStart(codePath, node) { - if (isConstructorFunction$1(node)) { - - // Class > ClassBody > MethodDefinition > FunctionExpression - const classNode = node.parent.parent.parent; - const superClass = classNode.superClass; - - funcInfo = { - upper: funcInfo, - isConstructor: true, - hasExtends: Boolean(superClass), - superIsConstructor: isPossibleConstructor(superClass), - codePath - }; - } else { - funcInfo = { - upper: funcInfo, - isConstructor: false, - hasExtends: false, - superIsConstructor: false, - codePath - }; - } - }, - - /** - * Pops a constructor information. - * And reports if `super()` lacked. - * @param {CodePath} codePath A code path which was ended. - * @param {ASTNode} node The current node. - * @returns {void} - */ - onCodePathEnd(codePath, node) { - const hasExtends = funcInfo.hasExtends; - - // Pop. - funcInfo = funcInfo.upper; - - if (!hasExtends) { - return; - } - - // Reports if `super()` lacked. - const segments = codePath.returnedSegments; - const calledInEveryPaths = segments.every(isCalledInEveryPath); - const calledInSomePaths = segments.some(isCalledInSomePath); - - if (!calledInEveryPaths) { - context.report({ - messageId: calledInSomePaths - ? "missingSome" - : "missingAll", - node: node.parent - }); - } - }, - - /** - * Initialize information of a given code path segment. - * @param {CodePathSegment} segment A code path segment to initialize. - * @returns {void} - */ - onCodePathSegmentStart(segment) { - if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) { - return; - } - - // Initialize info. - const info = segInfoMap[segment.id] = { - calledInSomePaths: false, - calledInEveryPaths: false, - validNodes: [] - }; - - // When there are previous segments, aggregates these. - const prevSegments = segment.prevSegments; - - if (prevSegments.length > 0) { - info.calledInSomePaths = prevSegments.some(isCalledInSomePath); - info.calledInEveryPaths = prevSegments.every(isCalledInEveryPath); - } - }, - - /** - * Update information of the code path segment when a code path was - * looped. - * @param {CodePathSegment} fromSegment The code path segment of the - * end of a loop. - * @param {CodePathSegment} toSegment A code path segment of the head - * of a loop. - * @returns {void} - */ - onCodePathSegmentLoop(fromSegment, toSegment) { - if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) { - return; - } - - // Update information inside of the loop. - const isRealLoop = toSegment.prevSegments.length >= 2; - - funcInfo.codePath.traverseSegments( - { first: toSegment, last: fromSegment }, - segment => { - const info = segInfoMap[segment.id]; - const prevSegments = segment.prevSegments; - - // Updates flags. - info.calledInSomePaths = prevSegments.some(isCalledInSomePath); - info.calledInEveryPaths = prevSegments.every(isCalledInEveryPath); - - // If flags become true anew, reports the valid nodes. - if (info.calledInSomePaths || isRealLoop) { - const nodes = info.validNodes; - - info.validNodes = []; - - for (let i = 0; i < nodes.length; ++i) { - const node = nodes[i]; - - context.report({ - messageId: "duplicate", - node - }); - } - } - } - ); - }, - - /** - * Checks for a call of `super()`. - * @param {ASTNode} node A CallExpression node to check. - * @returns {void} - */ - "CallExpression:exit"(node) { - if (!(funcInfo && funcInfo.isConstructor)) { - return; - } - - // Skips except `super()`. - if (node.callee.type !== "Super") { - return; - } - - // Reports if needed. - if (funcInfo.hasExtends) { - const segments = funcInfo.codePath.currentSegments; - let duplicate = false; - let info = null; - - for (let i = 0; i < segments.length; ++i) { - const segment = segments[i]; - - if (segment.reachable) { - info = segInfoMap[segment.id]; - - duplicate = duplicate || info.calledInSomePaths; - info.calledInSomePaths = info.calledInEveryPaths = true; - } - } - - if (info) { - if (duplicate) { - context.report({ - messageId: "duplicate", - node - }); - } else if (!funcInfo.superIsConstructor) { - context.report({ - messageId: "badSuper", - node - }); - } else { - info.validNodes.push(node); - } - } - } else if (funcInfo.codePath.currentSegments.some(isReachable$2)) { - context.report({ - messageId: "unexpected", - node - }); - } - }, - - /** - * Set the mark to the returned path as `super()` was called. - * @param {ASTNode} node A ReturnStatement node to check. - * @returns {void} - */ - ReturnStatement(node) { - if (!(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends)) { - return; - } - - // Skips if no argument. - if (!node.argument) { - return; - } - - // Returning argument is a substitute of 'super()'. - const segments = funcInfo.codePath.currentSegments; - - for (let i = 0; i < segments.length; ++i) { - const segment = segments[i]; - - if (segment.reachable) { - const info = segInfoMap[segment.id]; - - info.calledInSomePaths = info.calledInEveryPaths = true; - } - } - }, - - /** - * Resets state. - * @returns {void} - */ - "Program:exit"() { - segInfoMap = Object.create(null); - } - }; - } -}; - -/** - * @fileoverview Rule to flag statements without curly braces - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var curly = { - meta: { - type: "suggestion", - - docs: { - description: "enforce consistent brace style for all control statements", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/curly" - }, - - schema: { - anyOf: [ - { - type: "array", - items: [ - { - enum: ["all"] - } - ], - minItems: 0, - maxItems: 1 - }, - { - type: "array", - items: [ - { - enum: ["multi", "multi-line", "multi-or-nest"] - }, - { - enum: ["consistent"] - } - ], - minItems: 0, - maxItems: 2 - } - ] - }, - - fixable: "code", - - messages: { - missingCurlyAfter: "Expected { after '{{name}}'.", - missingCurlyAfterCondition: "Expected { after '{{name}}' condition.", - unexpectedCurlyAfter: "Unnecessary { after '{{name}}'.", - unexpectedCurlyAfterCondition: "Unnecessary { after '{{name}}' condition." - } - }, - - create(context) { - - const multiOnly = (context.options[0] === "multi"); - const multiLine = (context.options[0] === "multi-line"); - const multiOrNest = (context.options[0] === "multi-or-nest"); - const consistent = (context.options[1] === "consistent"); - - const sourceCode = context.getSourceCode(); - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Determines if a given node is a one-liner that's on the same line as it's preceding code. - * @param {ASTNode} node The node to check. - * @returns {boolean} True if the node is a one-liner that's on the same line as it's preceding code. - * @private - */ - function isCollapsedOneLiner(node) { - const before = sourceCode.getTokenBefore(node); - const last = sourceCode.getLastToken(node); - const lastExcludingSemicolon = astUtils.isSemicolonToken(last) ? sourceCode.getTokenBefore(last) : last; - - return before.loc.start.line === lastExcludingSemicolon.loc.end.line; - } - - /** - * Determines if a given node is a one-liner. - * @param {ASTNode} node The node to check. - * @returns {boolean} True if the node is a one-liner. - * @private - */ - function isOneLiner(node) { - if (node.type === "EmptyStatement") { - return true; - } - - const first = sourceCode.getFirstToken(node); - const last = sourceCode.getLastToken(node); - const lastExcludingSemicolon = astUtils.isSemicolonToken(last) ? sourceCode.getTokenBefore(last) : last; - - return first.loc.start.line === lastExcludingSemicolon.loc.end.line; - } - - /** - * Determines if the given node is a lexical declaration (let, const, function, or class) - * @param {ASTNode} node The node to check - * @returns {boolean} True if the node is a lexical declaration - * @private - */ - function isLexicalDeclaration(node) { - if (node.type === "VariableDeclaration") { - return node.kind === "const" || node.kind === "let"; - } - - return node.type === "FunctionDeclaration" || node.type === "ClassDeclaration"; - } - - /** - * Checks if the given token is an `else` token or not. - * @param {Token} token The token to check. - * @returns {boolean} `true` if the token is an `else` token. - */ - function isElseKeywordToken(token) { - return token.value === "else" && token.type === "Keyword"; - } - - /** - * Gets the `else` keyword token of a given `IfStatement` node. - * @param {ASTNode} node A `IfStatement` node to get. - * @returns {Token} The `else` keyword token. - */ - function getElseKeyword(node) { - return node.alternate && sourceCode.getFirstTokenBetween(node.consequent, node.alternate, isElseKeywordToken); - } - - /** - * Determines whether the given node has an `else` keyword token as the first token after. - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if the node is followed by an `else` keyword token. - */ - function isFollowedByElseKeyword(node) { - const nextToken = sourceCode.getTokenAfter(node); - - return Boolean(nextToken) && isElseKeywordToken(nextToken); - } - - /** - * Determines if a semicolon needs to be inserted after removing a set of curly brackets, in order to avoid a SyntaxError. - * @param {Token} closingBracket The } token - * @returns {boolean} `true` if a semicolon needs to be inserted after the last statement in the block. - */ - function needsSemicolon(closingBracket) { - const tokenBefore = sourceCode.getTokenBefore(closingBracket); - const tokenAfter = sourceCode.getTokenAfter(closingBracket); - const lastBlockNode = sourceCode.getNodeByRangeIndex(tokenBefore.range[0]); - - if (astUtils.isSemicolonToken(tokenBefore)) { - - // If the last statement already has a semicolon, don't add another one. - return false; - } - - if (!tokenAfter) { - - // If there are no statements after this block, there is no need to add a semicolon. - return false; - } - - if (lastBlockNode.type === "BlockStatement" && lastBlockNode.parent.type !== "FunctionExpression" && lastBlockNode.parent.type !== "ArrowFunctionExpression") { - - /* - * If the last node surrounded by curly brackets is a BlockStatement (other than a FunctionExpression or an ArrowFunctionExpression), - * don't insert a semicolon. Otherwise, the semicolon would be parsed as a separate statement, which would cause - * a SyntaxError if it was followed by `else`. - */ - return false; - } - - if (tokenBefore.loc.end.line === tokenAfter.loc.start.line) { - - // If the next token is on the same line, insert a semicolon. - return true; - } - - if (/^[([/`+-]/u.test(tokenAfter.value)) { - - // If the next token starts with a character that would disrupt ASI, insert a semicolon. - return true; - } - - if (tokenBefore.type === "Punctuator" && (tokenBefore.value === "++" || tokenBefore.value === "--")) { - - // If the last token is ++ or --, insert a semicolon to avoid disrupting ASI. - return true; - } - - // Otherwise, do not insert a semicolon. - return false; - } - - /** - * Determines whether the code represented by the given node contains an `if` statement - * that would become associated with an `else` keyword directly appended to that code. - * - * Examples where it returns `true`: - * - * if (a) - * foo(); - * - * if (a) { - * foo(); - * } - * - * if (a) - * foo(); - * else if (b) - * bar(); - * - * while (a) - * if (b) - * if(c) - * foo(); - * else - * bar(); - * - * Examples where it returns `false`: - * - * if (a) - * foo(); - * else - * bar(); - * - * while (a) { - * if (b) - * if(c) - * foo(); - * else - * bar(); - * } - * - * while (a) - * if (b) { - * if(c) - * foo(); - * } - * else - * bar(); - * @param {ASTNode} node Node representing the code to check. - * @returns {boolean} `true` if an `if` statement within the code would become associated with an `else` appended to that code. - */ - function hasUnsafeIf(node) { - switch (node.type) { - case "IfStatement": - if (!node.alternate) { - return true; - } - return hasUnsafeIf(node.alternate); - case "ForStatement": - case "ForInStatement": - case "ForOfStatement": - case "LabeledStatement": - case "WithStatement": - case "WhileStatement": - return hasUnsafeIf(node.body); - default: - return false; - } - } - - /** - * Determines whether the existing curly braces around the single statement are necessary to preserve the semantics of the code. - * The braces, which make the given block body, are necessary in either of the following situations: - * - * 1. The statement is a lexical declaration. - * 2. Without the braces, an `if` within the statement would become associated with an `else` after the closing brace: - * - * if (a) { - * if (b) - * foo(); - * } - * else - * bar(); - * - * if (a) - * while (b) - * while (c) { - * while (d) - * if (e) - * while(f) - * foo(); - * } - * else - * bar(); - * @param {ASTNode} node `BlockStatement` body with exactly one statement directly inside. The statement can have its own nested statements. - * @returns {boolean} `true` if the braces are necessary - removing them (replacing the given `BlockStatement` body with its single statement content) - * would change the semantics of the code or produce a syntax error. - */ - function areBracesNecessary(node) { - const statement = node.body[0]; - - return isLexicalDeclaration(statement) || - hasUnsafeIf(statement) && isFollowedByElseKeyword(node); - } - - /** - * Prepares to check the body of a node to see if it's a block statement. - * @param {ASTNode} node The node to report if there's a problem. - * @param {ASTNode} body The body node to check for blocks. - * @param {string} name The name to report if there's a problem. - * @param {{ condition: boolean }} opts Options to pass to the report functions - * @returns {Object} a prepared check object, with "actual", "expected", "check" properties. - * "actual" will be `true` or `false` whether the body is already a block statement. - * "expected" will be `true` or `false` if the body should be a block statement or not, or - * `null` if it doesn't matter, depending on the rule options. It can be modified to change - * the final behavior of "check". - * "check" will be a function reporting appropriate problems depending on the other - * properties. - */ - function prepareCheck(node, body, name, opts) { - const hasBlock = (body.type === "BlockStatement"); - let expected = null; - - if (hasBlock && (body.body.length !== 1 || areBracesNecessary(body))) { - expected = true; - } else if (multiOnly) { - expected = false; - } else if (multiLine) { - if (!isCollapsedOneLiner(body)) { - expected = true; - } - - // otherwise, the body is allowed to have braces or not to have braces - - } else if (multiOrNest) { - if (hasBlock) { - const statement = body.body[0]; - const leadingCommentsInBlock = sourceCode.getCommentsBefore(statement); - - expected = !isOneLiner(statement) || leadingCommentsInBlock.length > 0; - } else { - expected = !isOneLiner(body); - } - } else { - - // default "all" - expected = true; - } - - return { - actual: hasBlock, - expected, - check() { - if (this.expected !== null && this.expected !== this.actual) { - if (this.expected) { - context.report({ - node, - loc: (name !== "else" ? node : getElseKeyword(node)).loc.start, - messageId: opts && opts.condition ? "missingCurlyAfterCondition" : "missingCurlyAfter", - data: { - name - }, - fix: fixer => fixer.replaceText(body, `{${sourceCode.getText(body)}}`) - }); - } else { - context.report({ - node, - loc: (name !== "else" ? node : getElseKeyword(node)).loc.start, - messageId: opts && opts.condition ? "unexpectedCurlyAfterCondition" : "unexpectedCurlyAfter", - data: { - name - }, - fix(fixer) { - - /* - * `do while` expressions sometimes need a space to be inserted after `do`. - * e.g. `do{foo()} while (bar)` should be corrected to `do foo() while (bar)` - */ - const needsPrecedingSpace = node.type === "DoWhileStatement" && - sourceCode.getTokenBefore(body).range[1] === body.range[0] && - !astUtils.canTokensBeAdjacent("do", sourceCode.getFirstToken(body, { skip: 1 })); - - const openingBracket = sourceCode.getFirstToken(body); - const closingBracket = sourceCode.getLastToken(body); - const lastTokenInBlock = sourceCode.getTokenBefore(closingBracket); - - if (needsSemicolon(closingBracket)) { - - /* - * If removing braces would cause a SyntaxError due to multiple statements on the same line (or - * change the semantics of the code due to ASI), don't perform a fix. - */ - return null; - } - - const resultingBodyText = sourceCode.getText().slice(openingBracket.range[1], lastTokenInBlock.range[0]) + - sourceCode.getText(lastTokenInBlock) + - sourceCode.getText().slice(lastTokenInBlock.range[1], closingBracket.range[0]); - - return fixer.replaceText(body, (needsPrecedingSpace ? " " : "") + resultingBodyText); - } - }); - } - } - } - }; - } - - /** - * Prepares to check the bodies of a "if", "else if" and "else" chain. - * @param {ASTNode} node The first IfStatement node of the chain. - * @returns {Object[]} prepared checks for each body of the chain. See `prepareCheck` for more - * information. - */ - function prepareIfChecks(node) { - const preparedChecks = []; - - for (let currentNode = node; currentNode; currentNode = currentNode.alternate) { - preparedChecks.push(prepareCheck(currentNode, currentNode.consequent, "if", { condition: true })); - if (currentNode.alternate && currentNode.alternate.type !== "IfStatement") { - preparedChecks.push(prepareCheck(currentNode, currentNode.alternate, "else")); - break; - } - } - - if (consistent) { - - /* - * If any node should have or already have braces, make sure they - * all have braces. - * If all nodes shouldn't have braces, make sure they don't. - */ - const expected = preparedChecks.some(preparedCheck => { - if (preparedCheck.expected !== null) { - return preparedCheck.expected; - } - return preparedCheck.actual; - }); - - preparedChecks.forEach(preparedCheck => { - preparedCheck.expected = expected; - }); - } - - return preparedChecks; - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - IfStatement(node) { - const parent = node.parent; - const isElseIf = parent.type === "IfStatement" && parent.alternate === node; - - if (!isElseIf) { - - // This is a top `if`, check the whole `if-else-if` chain - prepareIfChecks(node).forEach(preparedCheck => { - preparedCheck.check(); - }); - } - - // Skip `else if`, it's already checked (when the top `if` was visited) - }, - - WhileStatement(node) { - prepareCheck(node, node.body, "while", { condition: true }).check(); - }, - - DoWhileStatement(node) { - prepareCheck(node, node.body, "do").check(); - }, - - ForStatement(node) { - prepareCheck(node, node.body, "for", { condition: true }).check(); - }, - - ForInStatement(node) { - prepareCheck(node, node.body, "for-in").check(); - }, - - ForOfStatement(node) { - prepareCheck(node, node.body, "for-of").check(); - } - }; - } -}; - -/** - * @fileoverview require default case in switch statements - * @author Aliaksei Shytkin - */ - -const DEFAULT_COMMENT_PATTERN = /^no default$/iu; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var defaultCase = { - meta: { - type: "suggestion", - - docs: { - description: "require `default` cases in `switch` statements", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/default-case" - }, - - schema: [{ - type: "object", - properties: { - commentPattern: { - type: "string" - } - }, - additionalProperties: false - }], - - messages: { - missingDefaultCase: "Expected a default case." - } - }, - - create(context) { - const options = context.options[0] || {}; - const commentPattern = options.commentPattern - ? new RegExp(options.commentPattern, "u") - : DEFAULT_COMMENT_PATTERN; - - const sourceCode = context.getSourceCode(); - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Shortcut to get last element of array - * @param {*[]} collection Array - * @returns {*} Last element - */ - function last(collection) { - return collection[collection.length - 1]; - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - - SwitchStatement(node) { - - if (!node.cases.length) { - - /* - * skip check of empty switch because there is no easy way - * to extract comments inside it now - */ - return; - } - - const hasDefault = node.cases.some(v => v.test === null); - - if (!hasDefault) { - - let comment; - - const lastCase = last(node.cases); - const comments = sourceCode.getCommentsAfter(lastCase); - - if (comments.length) { - comment = last(comments); - } - - if (!comment || !commentPattern.test(comment.value.trim())) { - context.report({ node, messageId: "missingDefaultCase" }); - } - } - } - }; - } -}; - -/** - * @fileoverview Rule to enforce default clauses in switch statements to be last - * @author Milos Djermanovic - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var defaultCaseLast = { - meta: { - type: "suggestion", - - docs: { - description: "enforce default clauses in switch statements to be last", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/default-case-last" - }, - - schema: [], - - messages: { - notLast: "Default clause should be the last clause." - } - }, - - create(context) { - return { - SwitchStatement(node) { - const cases = node.cases, - indexOfDefault = cases.findIndex(c => c.test === null); - - if (indexOfDefault !== -1 && indexOfDefault !== cases.length - 1) { - const defaultClause = cases[indexOfDefault]; - - context.report({ node: defaultClause, messageId: "notLast" }); - } - } - }; - } -}; - -/** - * @fileoverview enforce default parameters to be last - * @author Chiawen Chen - */ - -var defaultParamLast = { - meta: { - type: "suggestion", - - docs: { - description: "enforce default parameters to be last", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/default-param-last" - }, - - schema: [], - - messages: { - shouldBeLast: "Default parameters should be last." - } - }, - - create(context) { - - // eslint-disable-next-line jsdoc/require-description - /** - * @param {ASTNode} node function node - * @returns {void} - */ - function handleFunction(node) { - let hasSeenPlainParam = false; - - for (let i = node.params.length - 1; i >= 0; i -= 1) { - const param = node.params[i]; - - if ( - param.type !== "AssignmentPattern" && - param.type !== "RestElement" - ) { - hasSeenPlainParam = true; - continue; - } - - if (hasSeenPlainParam && param.type === "AssignmentPattern") { - context.report({ - node: param, - messageId: "shouldBeLast" - }); - } - } - } - - return { - FunctionDeclaration: handleFunction, - FunctionExpression: handleFunction, - ArrowFunctionExpression: handleFunction - }; - } -}; - -/** - * @fileoverview Validates newlines before and after dots - * @author Greg Cochard - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var dotLocation = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent newlines before and after dots", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/dot-location" - }, - - schema: [ - { - enum: ["object", "property"] - } - ], - - fixable: "code", - - messages: { - expectedDotAfterObject: "Expected dot to be on same line as object.", - expectedDotBeforeProperty: "Expected dot to be on same line as property." - } - }, - - create(context) { - - const config = context.options[0]; - - // default to onObject if no preference is passed - const onObject = config === "object" || !config; - - const sourceCode = context.getSourceCode(); - - /** - * Reports if the dot between object and property is on the correct location. - * @param {ASTNode} node The `MemberExpression` node. - * @returns {void} - */ - function checkDotLocation(node) { - const property = node.property; - const dotToken = sourceCode.getTokenBefore(property); - - if (onObject) { - - // `obj` expression can be parenthesized, but those paren tokens are not a part of the `obj` node. - const tokenBeforeDot = sourceCode.getTokenBefore(dotToken); - - if (!astUtils.isTokenOnSameLine(tokenBeforeDot, dotToken)) { - context.report({ - node, - loc: dotToken.loc, - messageId: "expectedDotAfterObject", - *fix(fixer) { - if (dotToken.value.startsWith(".") && astUtils.isDecimalIntegerNumericToken(tokenBeforeDot)) { - yield fixer.insertTextAfter(tokenBeforeDot, ` ${dotToken.value}`); - } else { - yield fixer.insertTextAfter(tokenBeforeDot, dotToken.value); - } - yield fixer.remove(dotToken); - } - }); - } - } else if (!astUtils.isTokenOnSameLine(dotToken, property)) { - context.report({ - node, - loc: dotToken.loc, - messageId: "expectedDotBeforeProperty", - *fix(fixer) { - yield fixer.remove(dotToken); - yield fixer.insertTextBefore(property, dotToken.value); - } - }); - } - } - - /** - * Checks the spacing of the dot within a member expression. - * @param {ASTNode} node The node to check. - * @returns {void} - */ - function checkNode(node) { - if (!node.computed) { - checkDotLocation(node); - } - } - - return { - MemberExpression: checkNode - }; - } -}; - -/** - * @fileoverview A shared list of ES3 keywords. - * @author Josh Perez - */ - -var keywords = [ - "abstract", - "boolean", - "break", - "byte", - "case", - "catch", - "char", - "class", - "const", - "continue", - "debugger", - "default", - "delete", - "do", - "double", - "else", - "enum", - "export", - "extends", - "false", - "final", - "finally", - "float", - "for", - "function", - "goto", - "if", - "implements", - "import", - "in", - "instanceof", - "int", - "interface", - "long", - "native", - "new", - "null", - "package", - "private", - "protected", - "public", - "return", - "short", - "static", - "super", - "switch", - "synchronized", - "this", - "throw", - "throws", - "transient", - "true", - "try", - "typeof", - "var", - "void", - "volatile", - "while", - "with" -]; - -/** - * @fileoverview Rule to warn about using dot notation instead of square bracket notation when possible. - * @author Josh Perez - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -const validIdentifier = /^[a-zA-Z_$][a-zA-Z0-9_$]*$/u; - -// `null` literal must be handled separately. -const literalTypesToCheck = new Set(["string", "boolean"]); - -var dotNotation = { - meta: { - type: "suggestion", - - docs: { - description: "enforce dot notation whenever possible", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/dot-notation" - }, - - schema: [ - { - type: "object", - properties: { - allowKeywords: { - type: "boolean", - default: true - }, - allowPattern: { - type: "string", - default: "" - } - }, - additionalProperties: false - } - ], - - fixable: "code", - - messages: { - useDot: "[{{key}}] is better written in dot notation.", - useBrackets: ".{{key}} is a syntax error." - } - }, - - create(context) { - const options = context.options[0] || {}; - const allowKeywords = options.allowKeywords === void 0 || options.allowKeywords; - const sourceCode = context.getSourceCode(); - - let allowPattern; - - if (options.allowPattern) { - allowPattern = new RegExp(options.allowPattern, "u"); - } - - /** - * Check if the property is valid dot notation - * @param {ASTNode} node The dot notation node - * @param {string} value Value which is to be checked - * @returns {void} - */ - function checkComputedProperty(node, value) { - if ( - validIdentifier.test(value) && - (allowKeywords || keywords.indexOf(String(value)) === -1) && - !(allowPattern && allowPattern.test(value)) - ) { - const formattedValue = node.property.type === "Literal" ? JSON.stringify(value) : `\`${value}\``; - - context.report({ - node: node.property, - messageId: "useDot", - data: { - key: formattedValue - }, - *fix(fixer) { - const leftBracket = sourceCode.getTokenAfter(node.object, astUtils.isOpeningBracketToken); - const rightBracket = sourceCode.getLastToken(node); - const nextToken = sourceCode.getTokenAfter(node); - - // Don't perform any fixes if there are comments inside the brackets. - if (sourceCode.commentsExistBetween(leftBracket, rightBracket)) { - return; // eslint-disable-line eslint-plugin/fixer-return -- false positive - } - - // Replace the brackets by an identifier. - if (!node.optional) { - yield fixer.insertTextBefore( - leftBracket, - astUtils.isDecimalInteger(node.object) ? " ." : "." - ); - } - yield fixer.replaceTextRange( - [leftBracket.range[0], rightBracket.range[1]], - value - ); - - // Insert a space after the property if it will be connected to the next token. - if ( - nextToken && - rightBracket.range[1] === nextToken.range[0] && - !astUtils.canTokensBeAdjacent(String(value), nextToken) - ) { - yield fixer.insertTextAfter(node, " "); - } - } - }); - } - } - - return { - MemberExpression(node) { - if ( - node.computed && - node.property.type === "Literal" && - (literalTypesToCheck.has(typeof node.property.value) || astUtils.isNullLiteral(node.property)) - ) { - checkComputedProperty(node, node.property.value); - } - if ( - node.computed && - node.property.type === "TemplateLiteral" && - node.property.expressions.length === 0 - ) { - checkComputedProperty(node, node.property.quasis[0].value.cooked); - } - if ( - !allowKeywords && - !node.computed && - keywords.indexOf(String(node.property.name)) !== -1 - ) { - context.report({ - node: node.property, - messageId: "useBrackets", - data: { - key: node.property.name - }, - *fix(fixer) { - const dotToken = sourceCode.getTokenBefore(node.property); - - // A statement that starts with `let[` is parsed as a destructuring variable declaration, not a MemberExpression. - if (node.object.type === "Identifier" && node.object.name === "let" && !node.optional) { - return; // eslint-disable-line eslint-plugin/fixer-return -- false positive - } - - // Don't perform any fixes if there are comments between the dot and the property name. - if (sourceCode.commentsExistBetween(dotToken, node.property)) { - return; // eslint-disable-line eslint-plugin/fixer-return -- false positive - } - - // Replace the identifier to brackets. - if (!node.optional) { - yield fixer.remove(dotToken); - } - yield fixer.replaceText(node.property, `["${node.property.name}"]`); - } - }); - } - } - }; - } -}; - -/** - * @fileoverview Require or disallow newline at the end of files - * @author Nodeca Team - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var eolLast = { - meta: { - type: "layout", - - docs: { - description: "require or disallow newline at the end of files", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/eol-last" - }, - - fixable: "whitespace", - - schema: [ - { - enum: ["always", "never", "unix", "windows"] - } - ], - - messages: { - missing: "Newline required at end of file but not found.", - unexpected: "Newline not allowed at end of file." - } - }, - create(context) { - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - Program: function checkBadEOF(node) { - const sourceCode = context.getSourceCode(), - src = sourceCode.getText(), - location = { - column: lodash__default['default'].last(sourceCode.lines).length, - line: sourceCode.lines.length - }, - LF = "\n", - CRLF = `\r${LF}`, - endsWithNewline = src.endsWith(LF); - - /* - * Empty source is always valid: No content in file so we don't - * need to lint for a newline on the last line of content. - */ - if (!src.length) { - return; - } - - let mode = context.options[0] || "always", - appendCRLF = false; - - if (mode === "unix") { - - // `"unix"` should behave exactly as `"always"` - mode = "always"; - } - if (mode === "windows") { - - // `"windows"` should behave exactly as `"always"`, but append CRLF in the fixer for backwards compatibility - mode = "always"; - appendCRLF = true; - } - if (mode === "always" && !endsWithNewline) { - - // File is not newline-terminated, but should be - context.report({ - node, - loc: location, - messageId: "missing", - fix(fixer) { - return fixer.insertTextAfterRange([0, src.length], appendCRLF ? CRLF : LF); - } - }); - } else if (mode === "never" && endsWithNewline) { - - // File is newline-terminated, but shouldn't be - context.report({ - node, - loc: location, - messageId: "unexpected", - fix(fixer) { - const finalEOLs = /(?:\r?\n)+$/u, - match = finalEOLs.exec(sourceCode.text), - start = match.index, - end = sourceCode.text.length; - - return fixer.replaceTextRange([start, end], ""); - } - }); - } - } - }; - } -}; - -/** - * @fileoverview Rule to flag statements that use != and == instead of !== and === - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var eqeqeq = { - meta: { - type: "suggestion", - - docs: { - description: "require the use of `===` and `!==`", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/eqeqeq" - }, - - schema: { - anyOf: [ - { - type: "array", - items: [ - { - enum: ["always"] - }, - { - type: "object", - properties: { - null: { - enum: ["always", "never", "ignore"] - } - }, - additionalProperties: false - } - ], - additionalItems: false - }, - { - type: "array", - items: [ - { - enum: ["smart", "allow-null"] - } - ], - additionalItems: false - } - ] - }, - - fixable: "code", - - messages: { - unexpected: "Expected '{{expectedOperator}}' and instead saw '{{actualOperator}}'." - } - }, - - create(context) { - const config = context.options[0] || "always"; - const options = context.options[1] || {}; - const sourceCode = context.getSourceCode(); - - const nullOption = (config === "always") - ? options.null || "always" - : "ignore"; - const enforceRuleForNull = (nullOption === "always"); - const enforceInverseRuleForNull = (nullOption === "never"); - - /** - * Checks if an expression is a typeof expression - * @param {ASTNode} node The node to check - * @returns {boolean} if the node is a typeof expression - */ - function isTypeOf(node) { - return node.type === "UnaryExpression" && node.operator === "typeof"; - } - - /** - * Checks if either operand of a binary expression is a typeof operation - * @param {ASTNode} node The node to check - * @returns {boolean} if one of the operands is typeof - * @private - */ - function isTypeOfBinary(node) { - return isTypeOf(node.left) || isTypeOf(node.right); - } - - /** - * Checks if operands are literals of the same type (via typeof) - * @param {ASTNode} node The node to check - * @returns {boolean} if operands are of same type - * @private - */ - function areLiteralsAndSameType(node) { - return node.left.type === "Literal" && node.right.type === "Literal" && - typeof node.left.value === typeof node.right.value; - } - - /** - * Checks if one of the operands is a literal null - * @param {ASTNode} node The node to check - * @returns {boolean} if operands are null - * @private - */ - function isNullCheck(node) { - return astUtils.isNullLiteral(node.right) || astUtils.isNullLiteral(node.left); - } - - /** - * Reports a message for this rule. - * @param {ASTNode} node The binary expression node that was checked - * @param {string} expectedOperator The operator that was expected (either '==', '!=', '===', or '!==') - * @returns {void} - * @private - */ - function report(node, expectedOperator) { - const operatorToken = sourceCode.getFirstTokenBetween( - node.left, - node.right, - token => token.value === node.operator - ); - - context.report({ - node, - loc: operatorToken.loc, - messageId: "unexpected", - data: { expectedOperator, actualOperator: node.operator }, - fix(fixer) { - - // If the comparison is a `typeof` comparison or both sides are literals with the same type, then it's safe to fix. - if (isTypeOfBinary(node) || areLiteralsAndSameType(node)) { - return fixer.replaceText(operatorToken, expectedOperator); - } - return null; - } - }); - } - - return { - BinaryExpression(node) { - const isNull = isNullCheck(node); - - if (node.operator !== "==" && node.operator !== "!=") { - if (enforceInverseRuleForNull && isNull) { - report(node, node.operator.slice(0, -1)); - } - return; - } - - if (config === "smart" && (isTypeOfBinary(node) || - areLiteralsAndSameType(node) || isNull)) { - return; - } - - if (!enforceRuleForNull && isNull) { - return; - } - - report(node, `${node.operator}=`); - } - }; - - } -}; - -/** - * @fileoverview enforce "for" loop update clause moving the counter in the right direction.(for-direction) - * @author Aladdin-ADD - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var forDirection = { - meta: { - type: "problem", - - docs: { - description: "enforce \"for\" loop update clause moving the counter in the right direction.", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/for-direction" - }, - - fixable: null, - schema: [], - - messages: { - incorrectDirection: "The update clause in this loop moves the variable in the wrong direction." - } - }, - - create(context) { - - /** - * report an error. - * @param {ASTNode} node the node to report. - * @returns {void} - */ - function report(node) { - context.report({ - node, - messageId: "incorrectDirection" - }); - } - - /** - * check the right side of the assignment - * @param {ASTNode} update UpdateExpression to check - * @param {int} dir expected direction that could either be turned around or invalidated - * @returns {int} return dir, the negated dir or zero if it's not clear for identifiers - */ - function getRightDirection(update, dir) { - if (update.right.type === "UnaryExpression") { - if (update.right.operator === "-") { - return -dir; - } - } else if (update.right.type === "Identifier") { - return 0; - } - return dir; - } - - /** - * check UpdateExpression add/sub the counter - * @param {ASTNode} update UpdateExpression to check - * @param {string} counter variable name to check - * @returns {int} if add return 1, if sub return -1, if nochange, return 0 - */ - function getUpdateDirection(update, counter) { - if (update.argument.type === "Identifier" && update.argument.name === counter) { - if (update.operator === "++") { - return 1; - } - if (update.operator === "--") { - return -1; - } - } - return 0; - } - - /** - * check AssignmentExpression add/sub the counter - * @param {ASTNode} update AssignmentExpression to check - * @param {string} counter variable name to check - * @returns {int} if add return 1, if sub return -1, if nochange, return 0 - */ - function getAssignmentDirection(update, counter) { - if (update.left.name === counter) { - if (update.operator === "+=") { - return getRightDirection(update, 1); - } - if (update.operator === "-=") { - return getRightDirection(update, -1); - } - } - return 0; - } - return { - ForStatement(node) { - - if (node.test && node.test.type === "BinaryExpression" && node.test.left.type === "Identifier" && node.update) { - const counter = node.test.left.name; - const operator = node.test.operator; - const update = node.update; - - let wrongDirection; - - if (operator === "<" || operator === "<=") { - wrongDirection = -1; - } else if (operator === ">" || operator === ">=") { - wrongDirection = 1; - } else { - return; - } - - if (update.type === "UpdateExpression") { - if (getUpdateDirection(update, counter) === wrongDirection) { - report(node); - } - } else if (update.type === "AssignmentExpression" && getAssignmentDirection(update, counter) === wrongDirection) { - report(node); - } - } - } - }; - } -}; - -/** - * @fileoverview Rule to control spacing within function calls - * @author Matt DuVall - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var funcCallSpacing = { - meta: { - type: "layout", - - docs: { - description: "require or disallow spacing between function identifiers and their invocations", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/func-call-spacing" - }, - - fixable: "whitespace", - - schema: { - anyOf: [ - { - type: "array", - items: [ - { - enum: ["never"] - } - ], - minItems: 0, - maxItems: 1 - }, - { - type: "array", - items: [ - { - enum: ["always"] - }, - { - type: "object", - properties: { - allowNewlines: { - type: "boolean" - } - }, - additionalProperties: false - } - ], - minItems: 0, - maxItems: 2 - } - ] - }, - - messages: { - unexpectedWhitespace: "Unexpected whitespace between function name and paren.", - unexpectedNewline: "Unexpected newline between function name and paren.", - missing: "Missing space between function name and paren." - } - }, - - create(context) { - - const never = context.options[0] !== "always"; - const allowNewlines = !never && context.options[1] && context.options[1].allowNewlines; - const sourceCode = context.getSourceCode(); - const text = sourceCode.getText(); - - /** - * Check if open space is present in a function name - * @param {ASTNode} node node to evaluate - * @param {Token} leftToken The last token of the callee. This may be the closing parenthesis that encloses the callee. - * @param {Token} rightToken Tha first token of the arguments. this is the opening parenthesis that encloses the arguments. - * @returns {void} - * @private - */ - function checkSpacing(node, leftToken, rightToken) { - const textBetweenTokens = text.slice(leftToken.range[1], rightToken.range[0]).replace(/\/\*.*?\*\//gu, ""); - const hasWhitespace = /\s/u.test(textBetweenTokens); - const hasNewline = hasWhitespace && astUtils.LINEBREAK_MATCHER.test(textBetweenTokens); - - /* - * never allowNewlines hasWhitespace hasNewline message - * F F F F Missing space between function name and paren. - * F F F T (Invalid `!hasWhitespace && hasNewline`) - * F F T T Unexpected newline between function name and paren. - * F F T F (OK) - * F T T F (OK) - * F T T T (OK) - * F T F T (Invalid `!hasWhitespace && hasNewline`) - * F T F F Missing space between function name and paren. - * T T F F (Invalid `never && allowNewlines`) - * T T F T (Invalid `!hasWhitespace && hasNewline`) - * T T T T (Invalid `never && allowNewlines`) - * T T T F (Invalid `never && allowNewlines`) - * T F T F Unexpected space between function name and paren. - * T F T T Unexpected space between function name and paren. - * T F F T (Invalid `!hasWhitespace && hasNewline`) - * T F F F (OK) - * - * T T Unexpected space between function name and paren. - * F F Missing space between function name and paren. - * F F T Unexpected newline between function name and paren. - */ - - if (never && hasWhitespace) { - context.report({ - node, - loc: { - start: leftToken.loc.end, - end: { - line: rightToken.loc.start.line, - column: rightToken.loc.start.column - 1 - } - }, - messageId: "unexpectedWhitespace", - fix(fixer) { - - // Don't remove comments. - if (sourceCode.commentsExistBetween(leftToken, rightToken)) { - return null; - } - - // If `?.` exists, it doesn't hide no-unexpected-multiline errors - if (node.optional) { - return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], "?."); - } - - /* - * Only autofix if there is no newline - * https://github.com/eslint/eslint/issues/7787 - */ - if (hasNewline) { - return null; - } - return fixer.removeRange([leftToken.range[1], rightToken.range[0]]); - } - }); - } else if (!never && !hasWhitespace) { - context.report({ - node, - loc: { - start: { - line: leftToken.loc.end.line, - column: leftToken.loc.end.column - 1 - }, - end: rightToken.loc.start - }, - messageId: "missing", - fix(fixer) { - if (node.optional) { - return null; // Not sure if inserting a space to either before/after `?.` token. - } - return fixer.insertTextBefore(rightToken, " "); - } - }); - } else if (!never && !allowNewlines && hasNewline) { - context.report({ - node, - loc: { - start: leftToken.loc.end, - end: rightToken.loc.start - }, - messageId: "unexpectedNewline", - fix(fixer) { - - /* - * Only autofix if there is no newline - * https://github.com/eslint/eslint/issues/7787 - * But if `?.` exists, it doesn't hide no-unexpected-multiline errors - */ - if (!node.optional) { - return null; - } - - // Don't remove comments. - if (sourceCode.commentsExistBetween(leftToken, rightToken)) { - return null; - } - - const range = [leftToken.range[1], rightToken.range[0]]; - const qdToken = sourceCode.getTokenAfter(leftToken); - - if (qdToken.range[0] === leftToken.range[1]) { - return fixer.replaceTextRange(range, "?. "); - } - if (qdToken.range[1] === rightToken.range[0]) { - return fixer.replaceTextRange(range, " ?."); - } - return fixer.replaceTextRange(range, " ?. "); - } - }); - } - } - - return { - "CallExpression, NewExpression"(node) { - const lastToken = sourceCode.getLastToken(node); - const lastCalleeToken = sourceCode.getLastToken(node.callee); - const parenToken = sourceCode.getFirstTokenBetween(lastCalleeToken, lastToken, astUtils.isOpeningParenToken); - const prevToken = parenToken && sourceCode.getTokenBefore(parenToken, astUtils.isNotQuestionDotToken); - - // Parens in NewExpression are optional - if (!(parenToken && parenToken.range[1] < node.range[1])) { - return; - } - - checkSpacing(node, prevToken, parenToken); - }, - - ImportExpression(node) { - const leftToken = sourceCode.getFirstToken(node); - const rightToken = sourceCode.getTokenAfter(leftToken); - - checkSpacing(node, leftToken, rightToken); - } - }; - - } -}; - -/** - * @fileoverview Rule to require function names to match the name of the variable or property to which they are assigned. - * @author Annie Zhang, Pavel Strashkin - */ - -//-------------------------------------------------------------------------- -// Requirements -//-------------------------------------------------------------------------- - - - - -//-------------------------------------------------------------------------- -// Helpers -//-------------------------------------------------------------------------- - -/** - * Determines if a pattern is `module.exports` or `module["exports"]` - * @param {ASTNode} pattern The left side of the AssignmentExpression - * @returns {boolean} True if the pattern is `module.exports` or `module["exports"]` - */ -function isModuleExports(pattern) { - if (pattern.type === "MemberExpression" && pattern.object.type === "Identifier" && pattern.object.name === "module") { - - // module.exports - if (pattern.property.type === "Identifier" && pattern.property.name === "exports") { - return true; - } - - // module["exports"] - if (pattern.property.type === "Literal" && pattern.property.value === "exports") { - return true; - } - } - return false; -} - -/** - * Determines if a string name is a valid identifier - * @param {string} name The string to be checked - * @param {int} ecmaVersion The ECMAScript version if specified in the parserOptions config - * @returns {boolean} True if the string is a valid identifier - */ -function isIdentifier(name, ecmaVersion) { - if (ecmaVersion >= 6) { - return esutils__default['default'].keyword.isIdentifierES6(name); - } - return esutils__default['default'].keyword.isIdentifierES5(name); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -const alwaysOrNever = { enum: ["always", "never"] }; -const optionsObject = { - type: "object", - properties: { - considerPropertyDescriptor: { - type: "boolean" - }, - includeCommonJSModuleExports: { - type: "boolean" - } - }, - additionalProperties: false -}; - -var funcNameMatching = { - meta: { - type: "suggestion", - - docs: { - description: "require function names to match the name of the variable or property to which they are assigned", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/func-name-matching" - }, - - schema: { - anyOf: [{ - type: "array", - additionalItems: false, - items: [alwaysOrNever, optionsObject] - }, { - type: "array", - additionalItems: false, - items: [optionsObject] - }] - }, - - messages: { - matchProperty: "Function name `{{funcName}}` should match property name `{{name}}`.", - matchVariable: "Function name `{{funcName}}` should match variable name `{{name}}`.", - notMatchProperty: "Function name `{{funcName}}` should not match property name `{{name}}`.", - notMatchVariable: "Function name `{{funcName}}` should not match variable name `{{name}}`." - } - }, - - create(context) { - const options = (typeof context.options[0] === "object" ? context.options[0] : context.options[1]) || {}; - const nameMatches = typeof context.options[0] === "string" ? context.options[0] : "always"; - const considerPropertyDescriptor = options.considerPropertyDescriptor; - const includeModuleExports = options.includeCommonJSModuleExports; - const ecmaVersion = context.parserOptions && context.parserOptions.ecmaVersion ? context.parserOptions.ecmaVersion : 5; - - /** - * Check whether node is a certain CallExpression. - * @param {string} objName object name - * @param {string} funcName function name - * @param {ASTNode} node The node to check - * @returns {boolean} `true` if node matches CallExpression - */ - function isPropertyCall(objName, funcName, node) { - if (!node) { - return false; - } - return node.type === "CallExpression" && astUtils.isSpecificMemberAccess(node.callee, objName, funcName); - } - - /** - * Compares identifiers based on the nameMatches option - * @param {string} x the first identifier - * @param {string} y the second identifier - * @returns {boolean} whether the two identifiers should warn. - */ - function shouldWarn(x, y) { - return (nameMatches === "always" && x !== y) || (nameMatches === "never" && x === y); - } - - /** - * Reports - * @param {ASTNode} node The node to report - * @param {string} name The variable or property name - * @param {string} funcName The function name - * @param {boolean} isProp True if the reported node is a property assignment - * @returns {void} - */ - function report(node, name, funcName, isProp) { - let messageId; - - if (nameMatches === "always" && isProp) { - messageId = "matchProperty"; - } else if (nameMatches === "always") { - messageId = "matchVariable"; - } else if (isProp) { - messageId = "notMatchProperty"; - } else { - messageId = "notMatchVariable"; - } - context.report({ - node, - messageId, - data: { - name, - funcName - } - }); - } - - /** - * Determines whether a given node is a string literal - * @param {ASTNode} node The node to check - * @returns {boolean} `true` if the node is a string literal - */ - function isStringLiteral(node) { - return node.type === "Literal" && typeof node.value === "string"; - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - VariableDeclarator(node) { - if (!node.init || node.init.type !== "FunctionExpression" || node.id.type !== "Identifier") { - return; - } - if (node.init.id && shouldWarn(node.id.name, node.init.id.name)) { - report(node, node.id.name, node.init.id.name, false); - } - }, - - AssignmentExpression(node) { - if ( - node.right.type !== "FunctionExpression" || - (node.left.computed && node.left.property.type !== "Literal") || - (!includeModuleExports && isModuleExports(node.left)) || - (node.left.type !== "Identifier" && node.left.type !== "MemberExpression") - ) { - return; - } - - const isProp = node.left.type === "MemberExpression"; - const name = isProp ? astUtils.getStaticPropertyName(node.left) : node.left.name; - - if (node.right.id && isIdentifier(name) && shouldWarn(name, node.right.id.name)) { - report(node, name, node.right.id.name, isProp); - } - }, - - Property(node) { - if (node.value.type !== "FunctionExpression" || !node.value.id || node.computed && !isStringLiteral(node.key)) { - return; - } - - if (node.key.type === "Identifier") { - const functionName = node.value.id.name; - let propertyName = node.key.name; - - if (considerPropertyDescriptor && propertyName === "value") { - if (isPropertyCall("Object", "defineProperty", node.parent.parent) || isPropertyCall("Reflect", "defineProperty", node.parent.parent)) { - const property = node.parent.parent.arguments[1]; - - if (isStringLiteral(property) && shouldWarn(property.value, functionName)) { - report(node, property.value, functionName, true); - } - } else if (isPropertyCall("Object", "defineProperties", node.parent.parent.parent.parent)) { - propertyName = node.parent.parent.key.name; - if (!node.parent.parent.computed && shouldWarn(propertyName, functionName)) { - report(node, propertyName, functionName, true); - } - } else if (isPropertyCall("Object", "create", node.parent.parent.parent.parent)) { - propertyName = node.parent.parent.key.name; - if (!node.parent.parent.computed && shouldWarn(propertyName, functionName)) { - report(node, propertyName, functionName, true); - } - } else if (shouldWarn(propertyName, functionName)) { - report(node, propertyName, functionName, true); - } - } else if (shouldWarn(propertyName, functionName)) { - report(node, propertyName, functionName, true); - } - return; - } - - if ( - isStringLiteral(node.key) && - isIdentifier(node.key.value, ecmaVersion) && - shouldWarn(node.key.value, node.value.id.name) - ) { - report(node, node.key.value, node.value.id.name, true); - } - } - }; - } -}; - -/** - * @fileoverview Rule to warn when a function expression does not have a name. - * @author Kyle T. Nunery - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -/** - * Checks whether or not a given variable is a function name. - * @param {eslint-scope.Variable} variable A variable to check. - * @returns {boolean} `true` if the variable is a function name. - */ -function isFunctionName$1(variable) { - return variable && variable.defs[0].type === "FunctionName"; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var funcNames = { - meta: { - type: "suggestion", - - docs: { - description: "require or disallow named `function` expressions", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/func-names" - }, - - schema: { - definitions: { - value: { - enum: [ - "always", - "as-needed", - "never" - ] - } - }, - items: [ - { - $ref: "#/definitions/value" - }, - { - type: "object", - properties: { - generators: { - $ref: "#/definitions/value" - } - }, - additionalProperties: false - } - ] - }, - - messages: { - unnamed: "Unexpected unnamed {{name}}.", - named: "Unexpected named {{name}}." - } - }, - - create(context) { - - const sourceCode = context.getSourceCode(); - - /** - * Returns the config option for the given node. - * @param {ASTNode} node A node to get the config for. - * @returns {string} The config option. - */ - function getConfigForNode(node) { - if ( - node.generator && - context.options.length > 1 && - context.options[1].generators - ) { - return context.options[1].generators; - } - - return context.options[0] || "always"; - } - - /** - * Determines whether the current FunctionExpression node is a get, set, or - * shorthand method in an object literal or a class. - * @param {ASTNode} node A node to check. - * @returns {boolean} True if the node is a get, set, or shorthand method. - */ - function isObjectOrClassMethod(node) { - const parent = node.parent; - - return (parent.type === "MethodDefinition" || ( - parent.type === "Property" && ( - parent.method || - parent.kind === "get" || - parent.kind === "set" - ) - )); - } - - /** - * Determines whether the current FunctionExpression node has a name that would be - * inferred from context in a conforming ES6 environment. - * @param {ASTNode} node A node to check. - * @returns {boolean} True if the node would have a name assigned automatically. - */ - function hasInferredName(node) { - const parent = node.parent; - - return isObjectOrClassMethod(node) || - (parent.type === "VariableDeclarator" && parent.id.type === "Identifier" && parent.init === node) || - (parent.type === "Property" && parent.value === node) || - (parent.type === "AssignmentExpression" && parent.left.type === "Identifier" && parent.right === node) || - (parent.type === "AssignmentPattern" && parent.left.type === "Identifier" && parent.right === node); - } - - /** - * Reports that an unnamed function should be named - * @param {ASTNode} node The node to report in the event of an error. - * @returns {void} - */ - function reportUnexpectedUnnamedFunction(node) { - context.report({ - node, - messageId: "unnamed", - loc: astUtils.getFunctionHeadLoc(node, sourceCode), - data: { name: astUtils.getFunctionNameWithKind(node) } - }); - } - - /** - * Reports that a named function should be unnamed - * @param {ASTNode} node The node to report in the event of an error. - * @returns {void} - */ - function reportUnexpectedNamedFunction(node) { - context.report({ - node, - messageId: "named", - loc: astUtils.getFunctionHeadLoc(node, sourceCode), - data: { name: astUtils.getFunctionNameWithKind(node) } - }); - } - - /** - * The listener for function nodes. - * @param {ASTNode} node function node - * @returns {void} - */ - function handleFunction(node) { - - // Skip recursive functions. - const nameVar = context.getDeclaredVariables(node)[0]; - - if (isFunctionName$1(nameVar) && nameVar.references.length > 0) { - return; - } - - const hasName = Boolean(node.id && node.id.name); - const config = getConfigForNode(node); - - if (config === "never") { - if (hasName && node.type !== "FunctionDeclaration") { - reportUnexpectedNamedFunction(node); - } - } else if (config === "as-needed") { - if (!hasName && !hasInferredName(node)) { - reportUnexpectedUnnamedFunction(node); - } - } else { - if (!hasName && !isObjectOrClassMethod(node)) { - reportUnexpectedUnnamedFunction(node); - } - } - } - - return { - "FunctionExpression:exit": handleFunction, - "ExportDefaultDeclaration > FunctionDeclaration": handleFunction - }; - } -}; - -/** - * @fileoverview Rule to enforce a particular function style - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var funcStyle = { - meta: { - type: "suggestion", - - docs: { - description: "enforce the consistent use of either `function` declarations or expressions", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/func-style" - }, - - schema: [ - { - enum: ["declaration", "expression"] - }, - { - type: "object", - properties: { - allowArrowFunctions: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - messages: { - expression: "Expected a function expression.", - declaration: "Expected a function declaration." - } - }, - - create(context) { - - const style = context.options[0], - allowArrowFunctions = context.options[1] && context.options[1].allowArrowFunctions, - enforceDeclarations = (style === "declaration"), - stack = []; - - const nodesToCheck = { - FunctionDeclaration(node) { - stack.push(false); - - if (!enforceDeclarations && node.parent.type !== "ExportDefaultDeclaration") { - context.report({ node, messageId: "expression" }); - } - }, - "FunctionDeclaration:exit"() { - stack.pop(); - }, - - FunctionExpression(node) { - stack.push(false); - - if (enforceDeclarations && node.parent.type === "VariableDeclarator") { - context.report({ node: node.parent, messageId: "declaration" }); - } - }, - "FunctionExpression:exit"() { - stack.pop(); - }, - - ThisExpression() { - if (stack.length > 0) { - stack[stack.length - 1] = true; - } - } - }; - - if (!allowArrowFunctions) { - nodesToCheck.ArrowFunctionExpression = function() { - stack.push(false); - }; - - nodesToCheck["ArrowFunctionExpression:exit"] = function(node) { - const hasThisExpr = stack.pop(); - - if (enforceDeclarations && !hasThisExpr && node.parent.type === "VariableDeclarator") { - context.report({ node: node.parent, messageId: "declaration" }); - } - }; - } - - return nodesToCheck; - - } -}; - -/** - * @fileoverview Rule to enforce line breaks between arguments of a function call - * @author Alexey Gonchar - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var functionCallArgumentNewline = { - meta: { - type: "layout", - - docs: { - description: "enforce line breaks between arguments of a function call", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/function-call-argument-newline" - }, - - fixable: "whitespace", - - schema: [ - { - enum: ["always", "never", "consistent"] - } - ], - - messages: { - unexpectedLineBreak: "There should be no line break here.", - missingLineBreak: "There should be a line break after this argument." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - const checkers = { - unexpected: { - messageId: "unexpectedLineBreak", - check: (prevToken, currentToken) => prevToken.loc.end.line !== currentToken.loc.start.line, - createFix: (token, tokenBefore) => fixer => - fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], " ") - }, - missing: { - messageId: "missingLineBreak", - check: (prevToken, currentToken) => prevToken.loc.end.line === currentToken.loc.start.line, - createFix: (token, tokenBefore) => fixer => - fixer.replaceTextRange([tokenBefore.range[1], token.range[0]], "\n") - } - }; - - /** - * Check all arguments for line breaks in the CallExpression - * @param {CallExpression} node node to evaluate - * @param {{ messageId: string, check: Function }} checker selected checker - * @returns {void} - * @private - */ - function checkArguments(node, checker) { - for (let i = 1; i < node.arguments.length; i++) { - const prevArgToken = sourceCode.getLastToken(node.arguments[i - 1]); - const currentArgToken = sourceCode.getFirstToken(node.arguments[i]); - - if (checker.check(prevArgToken, currentArgToken)) { - const tokenBefore = sourceCode.getTokenBefore( - currentArgToken, - { includeComments: true } - ); - - const hasLineCommentBefore = tokenBefore.type === "Line"; - - context.report({ - node, - loc: { - start: tokenBefore.loc.end, - end: currentArgToken.loc.start - }, - messageId: checker.messageId, - fix: hasLineCommentBefore ? null : checker.createFix(currentArgToken, tokenBefore) - }); - } - } - } - - /** - * Check if open space is present in a function name - * @param {CallExpression} node node to evaluate - * @returns {void} - * @private - */ - function check(node) { - if (node.arguments.length < 2) { - return; - } - - const option = context.options[0] || "always"; - - if (option === "never") { - checkArguments(node, checkers.unexpected); - } else if (option === "always") { - checkArguments(node, checkers.missing); - } else if (option === "consistent") { - const firstArgToken = sourceCode.getLastToken(node.arguments[0]); - const secondArgToken = sourceCode.getFirstToken(node.arguments[1]); - - if (firstArgToken.loc.end.line === secondArgToken.loc.start.line) { - checkArguments(node, checkers.unexpected); - } else { - checkArguments(node, checkers.missing); - } - } - } - - return { - CallExpression: check, - NewExpression: check - }; - } -}; - -/** - * @fileoverview enforce consistent line breaks inside function parentheses - * @author Teddy Katz - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var functionParenNewline = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent line breaks inside function parentheses", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/function-paren-newline" - }, - - fixable: "whitespace", - - schema: [ - { - oneOf: [ - { - enum: ["always", "never", "consistent", "multiline", "multiline-arguments"] - }, - { - type: "object", - properties: { - minItems: { - type: "integer", - minimum: 0 - } - }, - additionalProperties: false - } - ] - } - ], - - messages: { - expectedBefore: "Expected newline before ')'.", - expectedAfter: "Expected newline after '('.", - expectedBetween: "Expected newline between arguments/params.", - unexpectedBefore: "Unexpected newline before ')'.", - unexpectedAfter: "Unexpected newline after '('." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const rawOption = context.options[0] || "multiline"; - const multilineOption = rawOption === "multiline"; - const multilineArgumentsOption = rawOption === "multiline-arguments"; - const consistentOption = rawOption === "consistent"; - let minItems; - - if (typeof rawOption === "object") { - minItems = rawOption.minItems; - } else if (rawOption === "always") { - minItems = 0; - } else if (rawOption === "never") { - minItems = Infinity; - } else { - minItems = null; - } - - //---------------------------------------------------------------------- - // Helpers - //---------------------------------------------------------------------- - - /** - * Determines whether there should be newlines inside function parens - * @param {ASTNode[]} elements The arguments or parameters in the list - * @param {boolean} hasLeftNewline `true` if the left paren has a newline in the current code. - * @returns {boolean} `true` if there should be newlines inside the function parens - */ - function shouldHaveNewlines(elements, hasLeftNewline) { - if (multilineArgumentsOption && elements.length === 1) { - return hasLeftNewline; - } - if (multilineOption || multilineArgumentsOption) { - return elements.some((element, index) => index !== elements.length - 1 && element.loc.end.line !== elements[index + 1].loc.start.line); - } - if (consistentOption) { - return hasLeftNewline; - } - return elements.length >= minItems; - } - - /** - * Validates parens - * @param {Object} parens An object with keys `leftParen` for the left paren token, and `rightParen` for the right paren token - * @param {ASTNode[]} elements The arguments or parameters in the list - * @returns {void} - */ - function validateParens(parens, elements) { - const leftParen = parens.leftParen; - const rightParen = parens.rightParen; - const tokenAfterLeftParen = sourceCode.getTokenAfter(leftParen); - const tokenBeforeRightParen = sourceCode.getTokenBefore(rightParen); - const hasLeftNewline = !astUtils.isTokenOnSameLine(leftParen, tokenAfterLeftParen); - const hasRightNewline = !astUtils.isTokenOnSameLine(tokenBeforeRightParen, rightParen); - const needsNewlines = shouldHaveNewlines(elements, hasLeftNewline); - - if (hasLeftNewline && !needsNewlines) { - context.report({ - node: leftParen, - messageId: "unexpectedAfter", - fix(fixer) { - return sourceCode.getText().slice(leftParen.range[1], tokenAfterLeftParen.range[0]).trim() - - // If there is a comment between the ( and the first element, don't do a fix. - ? null - : fixer.removeRange([leftParen.range[1], tokenAfterLeftParen.range[0]]); - } - }); - } else if (!hasLeftNewline && needsNewlines) { - context.report({ - node: leftParen, - messageId: "expectedAfter", - fix: fixer => fixer.insertTextAfter(leftParen, "\n") - }); - } - - if (hasRightNewline && !needsNewlines) { - context.report({ - node: rightParen, - messageId: "unexpectedBefore", - fix(fixer) { - return sourceCode.getText().slice(tokenBeforeRightParen.range[1], rightParen.range[0]).trim() - - // If there is a comment between the last element and the ), don't do a fix. - ? null - : fixer.removeRange([tokenBeforeRightParen.range[1], rightParen.range[0]]); - } - }); - } else if (!hasRightNewline && needsNewlines) { - context.report({ - node: rightParen, - messageId: "expectedBefore", - fix: fixer => fixer.insertTextBefore(rightParen, "\n") - }); - } - } - - /** - * Validates a list of arguments or parameters - * @param {Object} parens An object with keys `leftParen` for the left paren token, and `rightParen` for the right paren token - * @param {ASTNode[]} elements The arguments or parameters in the list - * @returns {void} - */ - function validateArguments(parens, elements) { - const leftParen = parens.leftParen; - const tokenAfterLeftParen = sourceCode.getTokenAfter(leftParen); - const hasLeftNewline = !astUtils.isTokenOnSameLine(leftParen, tokenAfterLeftParen); - const needsNewlines = shouldHaveNewlines(elements, hasLeftNewline); - - for (let i = 0; i <= elements.length - 2; i++) { - const currentElement = elements[i]; - const nextElement = elements[i + 1]; - const hasNewLine = currentElement.loc.end.line !== nextElement.loc.start.line; - - if (!hasNewLine && needsNewlines) { - context.report({ - node: currentElement, - messageId: "expectedBetween", - fix: fixer => fixer.insertTextBefore(nextElement, "\n") - }); - } - } - } - - /** - * Gets the left paren and right paren tokens of a node. - * @param {ASTNode} node The node with parens - * @returns {Object} An object with keys `leftParen` for the left paren token, and `rightParen` for the right paren token. - * Can also return `null` if an expression has no parens (e.g. a NewExpression with no arguments, or an ArrowFunctionExpression - * with a single parameter) - */ - function getParenTokens(node) { - switch (node.type) { - case "NewExpression": - if (!node.arguments.length && !( - astUtils.isOpeningParenToken(sourceCode.getLastToken(node, { skip: 1 })) && - astUtils.isClosingParenToken(sourceCode.getLastToken(node)) - )) { - - // If the NewExpression does not have parens (e.g. `new Foo`), return null. - return null; - } - - // falls through - - case "CallExpression": - return { - leftParen: sourceCode.getTokenAfter(node.callee, astUtils.isOpeningParenToken), - rightParen: sourceCode.getLastToken(node) - }; - - case "FunctionDeclaration": - case "FunctionExpression": { - const leftParen = sourceCode.getFirstToken(node, astUtils.isOpeningParenToken); - const rightParen = node.params.length - ? sourceCode.getTokenAfter(node.params[node.params.length - 1], astUtils.isClosingParenToken) - : sourceCode.getTokenAfter(leftParen); - - return { leftParen, rightParen }; - } - - case "ArrowFunctionExpression": { - const firstToken = sourceCode.getFirstToken(node, { skip: (node.async ? 1 : 0) }); - - if (!astUtils.isOpeningParenToken(firstToken)) { - - // If the ArrowFunctionExpression has a single param without parens, return null. - return null; - } - - return { - leftParen: firstToken, - rightParen: sourceCode.getTokenBefore(node.body, astUtils.isClosingParenToken) - }; - } - - case "ImportExpression": { - const leftParen = sourceCode.getFirstToken(node, 1); - const rightParen = sourceCode.getLastToken(node); - - return { leftParen, rightParen }; - } - - default: - throw new TypeError(`unexpected node with type ${node.type}`); - } - } - - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - - return { - [[ - "ArrowFunctionExpression", - "CallExpression", - "FunctionDeclaration", - "FunctionExpression", - "ImportExpression", - "NewExpression" - ]](node) { - const parens = getParenTokens(node); - let params; - - if (node.type === "ImportExpression") { - params = [node.source]; - } else if (astUtils.isFunction(node)) { - params = node.params; - } else { - params = node.arguments; - } - - if (parens) { - validateParens(parens, params); - - if (multilineArgumentsOption) { - validateArguments(parens, params); - } - } - } - }; - } -}; - -/** - * @fileoverview Rule to check the spacing around the * in generator functions. - * @author Jamund Ferguson - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -const OVERRIDE_SCHEMA = { - oneOf: [ - { - enum: ["before", "after", "both", "neither"] - }, - { - type: "object", - properties: { - before: { type: "boolean" }, - after: { type: "boolean" } - }, - additionalProperties: false - } - ] -}; - -var generatorStarSpacing = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent spacing around `*` operators in generator functions", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/generator-star-spacing" - }, - - fixable: "whitespace", - - schema: [ - { - oneOf: [ - { - enum: ["before", "after", "both", "neither"] - }, - { - type: "object", - properties: { - before: { type: "boolean" }, - after: { type: "boolean" }, - named: OVERRIDE_SCHEMA, - anonymous: OVERRIDE_SCHEMA, - method: OVERRIDE_SCHEMA - }, - additionalProperties: false - } - ] - } - ], - - messages: { - missingBefore: "Missing space before *.", - missingAfter: "Missing space after *.", - unexpectedBefore: "Unexpected space before *.", - unexpectedAfter: "Unexpected space after *." - } - }, - - create(context) { - - const optionDefinitions = { - before: { before: true, after: false }, - after: { before: false, after: true }, - both: { before: true, after: true }, - neither: { before: false, after: false } - }; - - /** - * Returns resolved option definitions based on an option and defaults - * @param {any} option The option object or string value - * @param {Object} defaults The defaults to use if options are not present - * @returns {Object} the resolved object definition - */ - function optionToDefinition(option, defaults) { - if (!option) { - return defaults; - } - - return typeof option === "string" - ? optionDefinitions[option] - : Object.assign({}, defaults, option); - } - - const modes = (function(option) { - const defaults = optionToDefinition(option, optionDefinitions.before); - - return { - named: optionToDefinition(option.named, defaults), - anonymous: optionToDefinition(option.anonymous, defaults), - method: optionToDefinition(option.method, defaults) - }; - }(context.options[0] || {})); - - const sourceCode = context.getSourceCode(); - - /** - * Checks if the given token is a star token or not. - * @param {Token} token The token to check. - * @returns {boolean} `true` if the token is a star token. - */ - function isStarToken(token) { - return token.value === "*" && token.type === "Punctuator"; - } - - /** - * Gets the generator star token of the given function node. - * @param {ASTNode} node The function node to get. - * @returns {Token} Found star token. - */ - function getStarToken(node) { - return sourceCode.getFirstToken( - (node.parent.method || node.parent.type === "MethodDefinition") ? node.parent : node, - isStarToken - ); - } - - /** - * capitalize a given string. - * @param {string} str the given string. - * @returns {string} the capitalized string. - */ - function capitalize(str) { - return str[0].toUpperCase() + str.slice(1); - } - - /** - * Checks the spacing between two tokens before or after the star token. - * @param {string} kind Either "named", "anonymous", or "method" - * @param {string} side Either "before" or "after". - * @param {Token} leftToken `function` keyword token if side is "before", or - * star token if side is "after". - * @param {Token} rightToken Star token if side is "before", or identifier - * token if side is "after". - * @returns {void} - */ - function checkSpacing(kind, side, leftToken, rightToken) { - if (!!(rightToken.range[0] - leftToken.range[1]) !== modes[kind][side]) { - const after = leftToken.value === "*"; - const spaceRequired = modes[kind][side]; - const node = after ? leftToken : rightToken; - const messageId = `${spaceRequired ? "missing" : "unexpected"}${capitalize(side)}`; - - context.report({ - node, - messageId, - fix(fixer) { - if (spaceRequired) { - if (after) { - return fixer.insertTextAfter(node, " "); - } - return fixer.insertTextBefore(node, " "); - } - return fixer.removeRange([leftToken.range[1], rightToken.range[0]]); - } - }); - } - } - - /** - * Enforces the spacing around the star if node is a generator function. - * @param {ASTNode} node A function expression or declaration node. - * @returns {void} - */ - function checkFunction(node) { - if (!node.generator) { - return; - } - - const starToken = getStarToken(node); - const prevToken = sourceCode.getTokenBefore(starToken); - const nextToken = sourceCode.getTokenAfter(starToken); - - let kind = "named"; - - if (node.parent.type === "MethodDefinition" || (node.parent.type === "Property" && node.parent.method)) { - kind = "method"; - } else if (!node.id) { - kind = "anonymous"; - } - - // Only check before when preceded by `function`|`static` keyword - if (!(kind === "method" && starToken === sourceCode.getFirstToken(node.parent))) { - checkSpacing(kind, "before", prevToken, starToken); - } - - checkSpacing(kind, "after", starToken, nextToken); - } - - return { - FunctionDeclaration: checkFunction, - FunctionExpression: checkFunction - }; - - } -}; - -/** - * @fileoverview Enforces that a return statement is present in property getters. - * @author Aladdin-ADD(hh_2013@foxmail.com) - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ -const TARGET_NODE_TYPE$1 = /^(?:Arrow)?FunctionExpression$/u; - -/** - * Checks a given code path segment is reachable. - * @param {CodePathSegment} segment A segment to check. - * @returns {boolean} `true` if the segment is reachable. - */ -function isReachable$1(segment) { - return segment.reachable; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var getterReturn = { - meta: { - type: "problem", - - docs: { - description: "enforce `return` statements in getters", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/getter-return" - }, - - fixable: null, - - schema: [ - { - type: "object", - properties: { - allowImplicit: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - messages: { - expected: "Expected to return a value in {{name}}.", - expectedAlways: "Expected {{name}} to always return a value." - } - }, - - create(context) { - - const options = context.options[0] || { allowImplicit: false }; - const sourceCode = context.getSourceCode(); - - let funcInfo = { - upper: null, - codePath: null, - hasReturn: false, - shouldCheck: false, - node: null - }; - - /** - * Checks whether or not the last code path segment is reachable. - * Then reports this function if the segment is reachable. - * - * If the last code path segment is reachable, there are paths which are not - * returned or thrown. - * @param {ASTNode} node A node to check. - * @returns {void} - */ - function checkLastSegment(node) { - if (funcInfo.shouldCheck && - funcInfo.codePath.currentSegments.some(isReachable$1) - ) { - context.report({ - node, - loc: astUtils.getFunctionHeadLoc(node, sourceCode), - messageId: funcInfo.hasReturn ? "expectedAlways" : "expected", - data: { - name: astUtils.getFunctionNameWithKind(funcInfo.node) - } - }); - } - } - - /** - * Checks whether a node means a getter function. - * @param {ASTNode} node a node to check. - * @returns {boolean} if node means a getter, return true; else return false. - */ - function isGetter(node) { - const parent = node.parent; - - if (TARGET_NODE_TYPE$1.test(node.type) && node.body.type === "BlockStatement") { - if (parent.kind === "get") { - return true; - } - if (parent.type === "Property" && astUtils.getStaticPropertyName(parent) === "get" && parent.parent.type === "ObjectExpression") { - - // Object.defineProperty() - if (parent.parent.parent.type === "CallExpression" && - astUtils.getStaticPropertyName(parent.parent.parent.callee) === "defineProperty") { - return true; - } - - // Object.defineProperties() - if (parent.parent.parent.type === "Property" && - parent.parent.parent.parent.type === "ObjectExpression" && - parent.parent.parent.parent.parent.type === "CallExpression" && - astUtils.getStaticPropertyName(parent.parent.parent.parent.parent.callee) === "defineProperties") { - return true; - } - } - } - return false; - } - return { - - // Stacks this function's information. - onCodePathStart(codePath, node) { - funcInfo = { - upper: funcInfo, - codePath, - hasReturn: false, - shouldCheck: isGetter(node), - node - }; - }, - - // Pops this function's information. - onCodePathEnd() { - funcInfo = funcInfo.upper; - }, - - // Checks the return statement is valid. - ReturnStatement(node) { - if (funcInfo.shouldCheck) { - funcInfo.hasReturn = true; - - // if allowImplicit: false, should also check node.argument - if (!options.allowImplicit && !node.argument) { - context.report({ - node, - messageId: "expected", - data: { - name: astUtils.getFunctionNameWithKind(funcInfo.node) - } - }); - } - } - }, - - // Reports a given function if the last path is reachable. - "FunctionExpression:exit": checkLastSegment, - "ArrowFunctionExpression:exit": checkLastSegment - }; - } -}; - -/** - * @fileoverview Rule for disallowing require() outside of the top-level module context - * @author Jamund Ferguson - */ - -const ACCEPTABLE_PARENTS = [ - "AssignmentExpression", - "VariableDeclarator", - "MemberExpression", - "ExpressionStatement", - "CallExpression", - "ConditionalExpression", - "Program", - "VariableDeclaration", - "ChainExpression" -]; - -/** - * Finds the eslint-scope reference in the given scope. - * @param {Object} scope The scope to search. - * @param {ASTNode} node The identifier node. - * @returns {Reference|null} Returns the found reference or null if none were found. - */ -function findReference$1(scope, node) { - const references = scope.references.filter(reference => reference.identifier.range[0] === node.range[0] && - reference.identifier.range[1] === node.range[1]); - - /* istanbul ignore else: correctly returns null */ - if (references.length === 1) { - return references[0]; - } - return null; - -} - -/** - * Checks if the given identifier node is shadowed in the given scope. - * @param {Object} scope The current scope. - * @param {ASTNode} node The identifier node to check. - * @returns {boolean} Whether or not the name is shadowed. - */ -function isShadowed$2(scope, node) { - const reference = findReference$1(scope, node); - - return reference && reference.resolved && reference.resolved.defs.length > 0; -} - -var globalRequire = { - meta: { - deprecated: true, - - replacedBy: [], - - type: "suggestion", - - docs: { - description: "require `require()` calls to be placed at top-level module scope", - category: "Node.js and CommonJS", - recommended: false, - url: "https://eslint.org/docs/rules/global-require" - }, - - schema: [], - messages: { - unexpected: "Unexpected require()." - } - }, - - create(context) { - return { - CallExpression(node) { - const currentScope = context.getScope(); - - if (node.callee.name === "require" && !isShadowed$2(currentScope, node.callee)) { - const isGoodRequire = context.getAncestors().every(parent => ACCEPTABLE_PARENTS.indexOf(parent.type) > -1); - - if (!isGoodRequire) { - context.report({ node, messageId: "unexpected" }); - } - } - } - }; - } -}; - -/** - * @fileoverview Rule to require grouped accessor pairs in object literals and classes - * @author Milos Djermanovic - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Typedefs -//------------------------------------------------------------------------------ - -/** - * Property name if it can be computed statically, otherwise the list of the tokens of the key node. - * @typedef {string|Token[]} Key - */ - -/** - * Accessor nodes with the same key. - * @typedef {Object} AccessorData - * @property {Key} key Accessor's key - * @property {ASTNode[]} getters List of getter nodes. - * @property {ASTNode[]} setters List of setter nodes. - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether or not the given lists represent the equal tokens in the same order. - * Tokens are compared by their properties, not by instance. - * @param {Token[]} left First list of tokens. - * @param {Token[]} right Second list of tokens. - * @returns {boolean} `true` if the lists have same tokens. - */ -function areEqualTokenLists(left, right) { - if (left.length !== right.length) { - return false; - } - - for (let i = 0; i < left.length; i++) { - const leftToken = left[i], - rightToken = right[i]; - - if (leftToken.type !== rightToken.type || leftToken.value !== rightToken.value) { - return false; - } - } - - return true; -} - -/** - * Checks whether or not the given keys are equal. - * @param {Key} left First key. - * @param {Key} right Second key. - * @returns {boolean} `true` if the keys are equal. - */ -function areEqualKeys(left, right) { - if (typeof left === "string" && typeof right === "string") { - - // Statically computed names. - return left === right; - } - if (Array.isArray(left) && Array.isArray(right)) { - - // Token lists. - return areEqualTokenLists(left, right); - } - - return false; -} - -/** - * Checks whether or not a given node is of an accessor kind ('get' or 'set'). - * @param {ASTNode} node A node to check. - * @returns {boolean} `true` if the node is of an accessor kind. - */ -function isAccessorKind(node) { - return node.kind === "get" || node.kind === "set"; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var groupedAccessorPairs = { - meta: { - type: "suggestion", - - docs: { - description: "require grouped accessor pairs in object literals and classes", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/grouped-accessor-pairs" - }, - - schema: [ - { - enum: ["anyOrder", "getBeforeSet", "setBeforeGet"] - } - ], - - messages: { - notGrouped: "Accessor pair {{ formerName }} and {{ latterName }} should be grouped.", - invalidOrder: "Expected {{ latterName }} to be before {{ formerName }}." - } - }, - - create(context) { - const order = context.options[0] || "anyOrder"; - const sourceCode = context.getSourceCode(); - - /** - * Reports the given accessor pair. - * @param {string} messageId messageId to report. - * @param {ASTNode} formerNode getter/setter node that is defined before `latterNode`. - * @param {ASTNode} latterNode getter/setter node that is defined after `formerNode`. - * @returns {void} - * @private - */ - function report(messageId, formerNode, latterNode) { - context.report({ - node: latterNode, - messageId, - loc: astUtils.getFunctionHeadLoc(latterNode.value, sourceCode), - data: { - formerName: astUtils.getFunctionNameWithKind(formerNode.value), - latterName: astUtils.getFunctionNameWithKind(latterNode.value) - } - }); - } - - /** - * Creates a new `AccessorData` object for the given getter or setter node. - * @param {ASTNode} node A getter or setter node. - * @returns {AccessorData} New `AccessorData` object that contains the given node. - * @private - */ - function createAccessorData(node) { - const name = astUtils.getStaticPropertyName(node); - const key = (name !== null) ? name : sourceCode.getTokens(node.key); - - return { - key, - getters: node.kind === "get" ? [node] : [], - setters: node.kind === "set" ? [node] : [] - }; - } - - /** - * Merges the given `AccessorData` object into the given accessors list. - * @param {AccessorData[]} accessors The list to merge into. - * @param {AccessorData} accessorData The object to merge. - * @returns {AccessorData[]} The same instance with the merged object. - * @private - */ - function mergeAccessorData(accessors, accessorData) { - const equalKeyElement = accessors.find(a => areEqualKeys(a.key, accessorData.key)); - - if (equalKeyElement) { - equalKeyElement.getters.push(...accessorData.getters); - equalKeyElement.setters.push(...accessorData.setters); - } else { - accessors.push(accessorData); - } - - return accessors; - } - - /** - * Checks accessor pairs in the given list of nodes. - * @param {ASTNode[]} nodes The list to check. - * @param {Function} shouldCheck – Predicate that returns `true` if the node should be checked. - * @returns {void} - * @private - */ - function checkList(nodes, shouldCheck) { - const accessors = nodes - .filter(shouldCheck) - .filter(isAccessorKind) - .map(createAccessorData) - .reduce(mergeAccessorData, []); - - for (const { getters, setters } of accessors) { - - // Don't report accessor properties that have duplicate getters or setters. - if (getters.length === 1 && setters.length === 1) { - const [getter] = getters, - [setter] = setters, - getterIndex = nodes.indexOf(getter), - setterIndex = nodes.indexOf(setter), - formerNode = getterIndex < setterIndex ? getter : setter, - latterNode = getterIndex < setterIndex ? setter : getter; - - if (Math.abs(getterIndex - setterIndex) > 1) { - report("notGrouped", formerNode, latterNode); - } else if ( - (order === "getBeforeSet" && getterIndex > setterIndex) || - (order === "setBeforeGet" && getterIndex < setterIndex) - ) { - report("invalidOrder", formerNode, latterNode); - } - } - } - } - - return { - ObjectExpression(node) { - checkList(node.properties, n => n.type === "Property"); - }, - ClassBody(node) { - checkList(node.body, n => n.type === "MethodDefinition" && !n.static); - checkList(node.body, n => n.type === "MethodDefinition" && n.static); - } - }; - } -}; - -/** - * @fileoverview Rule to flag for-in loops without if statements inside - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var guardForIn = { - meta: { - type: "suggestion", - - docs: { - description: "require `for-in` loops to include an `if` statement", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/guard-for-in" - }, - - schema: [], - messages: { - wrap: "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype." - } - }, - - create(context) { - - return { - - ForInStatement(node) { - const body = node.body; - - // empty statement - if (body.type === "EmptyStatement") { - return; - } - - // if statement - if (body.type === "IfStatement") { - return; - } - - // empty block - if (body.type === "BlockStatement" && body.body.length === 0) { - return; - } - - // block with just if statement - if (body.type === "BlockStatement" && body.body.length === 1 && body.body[0].type === "IfStatement") { - return; - } - - // block that starts with if statement - if (body.type === "BlockStatement" && body.body.length >= 1 && body.body[0].type === "IfStatement") { - const i = body.body[0]; - - // ... whose consequent is a continue - if (i.consequent.type === "ContinueStatement") { - return; - } - - // ... whose consequent is a block that contains only a continue - if (i.consequent.type === "BlockStatement" && i.consequent.body.length === 1 && i.consequent.body[0].type === "ContinueStatement") { - return; - } - } - - context.report({ node, messageId: "wrap" }); - } - }; - - } -}; - -/** - * @fileoverview Ensure handling of errors when we know they exist. - * @author Jamund Ferguson - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var handleCallbackErr = { - meta: { - deprecated: true, - - replacedBy: [], - - type: "suggestion", - - docs: { - description: "require error handling in callbacks", - category: "Node.js and CommonJS", - recommended: false, - url: "https://eslint.org/docs/rules/handle-callback-err" - }, - - schema: [ - { - type: "string" - } - ], - messages: { - expected: "Expected error to be handled." - } - }, - - create(context) { - - const errorArgument = context.options[0] || "err"; - - /** - * Checks if the given argument should be interpreted as a regexp pattern. - * @param {string} stringToCheck The string which should be checked. - * @returns {boolean} Whether or not the string should be interpreted as a pattern. - */ - function isPattern(stringToCheck) { - const firstChar = stringToCheck[0]; - - return firstChar === "^"; - } - - /** - * Checks if the given name matches the configured error argument. - * @param {string} name The name which should be compared. - * @returns {boolean} Whether or not the given name matches the configured error variable name. - */ - function matchesConfiguredErrorName(name) { - if (isPattern(errorArgument)) { - const regexp = new RegExp(errorArgument, "u"); - - return regexp.test(name); - } - return name === errorArgument; - } - - /** - * Get the parameters of a given function scope. - * @param {Object} scope The function scope. - * @returns {Array} All parameters of the given scope. - */ - function getParameters(scope) { - return scope.variables.filter(variable => variable.defs[0] && variable.defs[0].type === "Parameter"); - } - - /** - * Check to see if we're handling the error object properly. - * @param {ASTNode} node The AST node to check. - * @returns {void} - */ - function checkForError(node) { - const scope = context.getScope(), - parameters = getParameters(scope), - firstParameter = parameters[0]; - - if (firstParameter && matchesConfiguredErrorName(firstParameter.name)) { - if (firstParameter.references.length === 0) { - context.report({ node, messageId: "expected" }); - } - } - } - - return { - FunctionDeclaration: checkForError, - FunctionExpression: checkForError, - ArrowFunctionExpression: checkForError - }; - - } -}; - -/** - * @fileoverview Rule that warns when identifier names that are - * specified in the configuration are used. - * @author Keith Cirkel (http://keithcirkel.co.uk) - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether the given node represents assignment target in a normal assignment or destructuring. - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if the node is assignment target. - */ -function isAssignmentTarget$1(node) { - const parent = node.parent; - - return ( - - // normal assignment - ( - parent.type === "AssignmentExpression" && - parent.left === node - ) || - - // destructuring - parent.type === "ArrayPattern" || - parent.type === "RestElement" || - ( - parent.type === "Property" && - parent.value === node && - parent.parent.type === "ObjectPattern" - ) || - ( - parent.type === "AssignmentPattern" && - parent.left === node - ) - ); -} - -/** - * Checks whether the given node represents an imported name that is renamed in the same import/export specifier. - * - * Examples: - * import { a as b } from 'mod'; // node `a` is renamed import - * export { a as b } from 'mod'; // node `a` is renamed import - * @param {ASTNode} node `Identifier` node to check. - * @returns {boolean} `true` if the node is a renamed import. - */ -function isRenamedImport$1(node) { - const parent = node.parent; - - return ( - ( - parent.type === "ImportSpecifier" && - parent.imported !== parent.local && - parent.imported === node - ) || - ( - parent.type === "ExportSpecifier" && - parent.parent.source && // re-export - parent.local !== parent.exported && - parent.local === node - ) - ); -} - -/** - * Checks whether the given node is a renamed identifier node in an ObjectPattern destructuring. - * - * Examples: - * const { a : b } = foo; // node `a` is renamed node. - * @param {ASTNode} node `Identifier` node to check. - * @returns {boolean} `true` if the node is a renamed node in an ObjectPattern destructuring. - */ -function isRenamedInDestructuring$1(node) { - const parent = node.parent; - - return ( - ( - !parent.computed && - parent.type === "Property" && - parent.parent.type === "ObjectPattern" && - parent.value !== node && - parent.key === node - ) - ); -} - -/** - * Checks whether the given node represents shorthand definition of a property in an object literal. - * @param {ASTNode} node `Identifier` node to check. - * @returns {boolean} `true` if the node is a shorthand property definition. - */ -function isShorthandPropertyDefinition$1(node) { - const parent = node.parent; - - return ( - parent.type === "Property" && - parent.parent.type === "ObjectExpression" && - parent.shorthand - ); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var idBlacklist = { - meta: { - deprecated: true, - replacedBy: ["id-denylist"], - - type: "suggestion", - - docs: { - description: "disallow specified identifiers", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/id-blacklist" - }, - - schema: { - type: "array", - items: { - type: "string" - }, - uniqueItems: true - }, - messages: { - restricted: "Identifier '{{name}}' is restricted." - } - }, - - create(context) { - - const denyList = new Set(context.options); - const reportedNodes = new Set(); - - let globalScope; - - /** - * Checks whether the given name is restricted. - * @param {string} name The name to check. - * @returns {boolean} `true` if the name is restricted. - * @private - */ - function isRestricted(name) { - return denyList.has(name); - } - - /** - * Checks whether the given node represents a reference to a global variable that is not declared in the source code. - * These identifiers will be allowed, as it is assumed that user has no control over the names of external global variables. - * @param {ASTNode} node `Identifier` node to check. - * @returns {boolean} `true` if the node is a reference to a global variable. - */ - function isReferenceToGlobalVariable(node) { - const variable = globalScope.set.get(node.name); - - return variable && variable.defs.length === 0 && - variable.references.some(ref => ref.identifier === node); - } - - /** - * Determines whether the given node should be checked. - * @param {ASTNode} node `Identifier` node. - * @returns {boolean} `true` if the node should be checked. - */ - function shouldCheck(node) { - const parent = node.parent; - - /* - * Member access has special rules for checking property names. - * Read access to a property with a restricted name is allowed, because it can be on an object that user has no control over. - * Write access isn't allowed, because it potentially creates a new property with a restricted name. - */ - if ( - parent.type === "MemberExpression" && - parent.property === node && - !parent.computed - ) { - return isAssignmentTarget$1(parent); - } - - return ( - parent.type !== "CallExpression" && - parent.type !== "NewExpression" && - !isRenamedImport$1(node) && - !isRenamedInDestructuring$1(node) && - !( - isReferenceToGlobalVariable(node) && - !isShorthandPropertyDefinition$1(node) - ) - ); - } - - /** - * Reports an AST node as a rule violation. - * @param {ASTNode} node The node to report. - * @returns {void} - * @private - */ - function report(node) { - if (!reportedNodes.has(node)) { - context.report({ - node, - messageId: "restricted", - data: { - name: node.name - } - }); - reportedNodes.add(node); - } - } - - return { - - Program() { - globalScope = context.getScope(); - }, - - Identifier(node) { - if (isRestricted(node.name) && shouldCheck(node)) { - report(node); - } - } - }; - } -}; - -/** - * @fileoverview Rule that warns when identifier names that are - * specified in the configuration are used. - * @author Keith Cirkel (http://keithcirkel.co.uk) - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether the given node represents assignment target in a normal assignment or destructuring. - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if the node is assignment target. - */ -function isAssignmentTarget(node) { - const parent = node.parent; - - return ( - - // normal assignment - ( - parent.type === "AssignmentExpression" && - parent.left === node - ) || - - // destructuring - parent.type === "ArrayPattern" || - parent.type === "RestElement" || - ( - parent.type === "Property" && - parent.value === node && - parent.parent.type === "ObjectPattern" - ) || - ( - parent.type === "AssignmentPattern" && - parent.left === node - ) - ); -} - -/** - * Checks whether the given node represents an imported name that is renamed in the same import/export specifier. - * - * Examples: - * import { a as b } from 'mod'; // node `a` is renamed import - * export { a as b } from 'mod'; // node `a` is renamed import - * @param {ASTNode} node `Identifier` node to check. - * @returns {boolean} `true` if the node is a renamed import. - */ -function isRenamedImport(node) { - const parent = node.parent; - - return ( - ( - parent.type === "ImportSpecifier" && - parent.imported !== parent.local && - parent.imported === node - ) || - ( - parent.type === "ExportSpecifier" && - parent.parent.source && // re-export - parent.local !== parent.exported && - parent.local === node - ) - ); -} - -/** - * Checks whether the given node is a renamed identifier node in an ObjectPattern destructuring. - * - * Examples: - * const { a : b } = foo; // node `a` is renamed node. - * @param {ASTNode} node `Identifier` node to check. - * @returns {boolean} `true` if the node is a renamed node in an ObjectPattern destructuring. - */ -function isRenamedInDestructuring(node) { - const parent = node.parent; - - return ( - ( - !parent.computed && - parent.type === "Property" && - parent.parent.type === "ObjectPattern" && - parent.value !== node && - parent.key === node - ) - ); -} - -/** - * Checks whether the given node represents shorthand definition of a property in an object literal. - * @param {ASTNode} node `Identifier` node to check. - * @returns {boolean} `true` if the node is a shorthand property definition. - */ -function isShorthandPropertyDefinition(node) { - const parent = node.parent; - - return ( - parent.type === "Property" && - parent.parent.type === "ObjectExpression" && - parent.shorthand - ); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var idDenylist = { - meta: { - type: "suggestion", - - docs: { - description: "disallow specified identifiers", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/id-denylist" - }, - - schema: { - type: "array", - items: { - type: "string" - }, - uniqueItems: true - }, - messages: { - restricted: "Identifier '{{name}}' is restricted." - } - }, - - create(context) { - - const denyList = new Set(context.options); - const reportedNodes = new Set(); - - let globalScope; - - /** - * Checks whether the given name is restricted. - * @param {string} name The name to check. - * @returns {boolean} `true` if the name is restricted. - * @private - */ - function isRestricted(name) { - return denyList.has(name); - } - - /** - * Checks whether the given node represents a reference to a global variable that is not declared in the source code. - * These identifiers will be allowed, as it is assumed that user has no control over the names of external global variables. - * @param {ASTNode} node `Identifier` node to check. - * @returns {boolean} `true` if the node is a reference to a global variable. - */ - function isReferenceToGlobalVariable(node) { - const variable = globalScope.set.get(node.name); - - return variable && variable.defs.length === 0 && - variable.references.some(ref => ref.identifier === node); - } - - /** - * Determines whether the given node should be checked. - * @param {ASTNode} node `Identifier` node. - * @returns {boolean} `true` if the node should be checked. - */ - function shouldCheck(node) { - const parent = node.parent; - - /* - * Member access has special rules for checking property names. - * Read access to a property with a restricted name is allowed, because it can be on an object that user has no control over. - * Write access isn't allowed, because it potentially creates a new property with a restricted name. - */ - if ( - parent.type === "MemberExpression" && - parent.property === node && - !parent.computed - ) { - return isAssignmentTarget(parent); - } - - return ( - parent.type !== "CallExpression" && - parent.type !== "NewExpression" && - !isRenamedImport(node) && - !isRenamedInDestructuring(node) && - !( - isReferenceToGlobalVariable(node) && - !isShorthandPropertyDefinition(node) - ) - ); - } - - /** - * Reports an AST node as a rule violation. - * @param {ASTNode} node The node to report. - * @returns {void} - * @private - */ - function report(node) { - if (!reportedNodes.has(node)) { - context.report({ - node, - messageId: "restricted", - data: { - name: node.name - } - }); - reportedNodes.add(node); - } - } - - return { - - Program() { - globalScope = context.getScope(); - }, - - Identifier(node) { - if (isRestricted(node.name) && shouldCheck(node)) { - report(node); - } - } - }; - } -}; - -/** - * @fileoverview Rule that warns when identifier names are shorter or longer - * than the values provided in configuration. - * @author Burak Yigit Kaya aka BYK - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var idLength = { - meta: { - type: "suggestion", - - docs: { - description: "enforce minimum and maximum identifier lengths", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/id-length" - }, - - schema: [ - { - type: "object", - properties: { - min: { - type: "integer", - default: 2 - }, - max: { - type: "integer" - }, - exceptions: { - type: "array", - uniqueItems: true, - items: { - type: "string" - } - }, - exceptionPatterns: { - type: "array", - uniqueItems: true, - items: { - type: "string" - } - }, - properties: { - enum: ["always", "never"] - } - }, - additionalProperties: false - } - ], - messages: { - tooShort: "Identifier name '{{name}}' is too short (< {{min}}).", - tooLong: "Identifier name '{{name}}' is too long (> {{max}})." - } - }, - - create(context) { - const options = context.options[0] || {}; - const minLength = typeof options.min !== "undefined" ? options.min : 2; - const maxLength = typeof options.max !== "undefined" ? options.max : Infinity; - const properties = options.properties !== "never"; - const exceptions = new Set(options.exceptions); - const exceptionPatterns = (options.exceptionPatterns || []).map(pattern => new RegExp(pattern, "u")); - const reportedNode = new Set(); - - /** - * Checks if a string matches the provided exception patterns - * @param {string} name The string to check. - * @returns {boolean} if the string is a match - * @private - */ - function matchesExceptionPattern(name) { - return exceptionPatterns.some(pattern => pattern.test(name)); - } - - const SUPPORTED_EXPRESSIONS = { - MemberExpression: properties && function(parent) { - return !parent.computed && ( - - // regular property assignment - (parent.parent.left === parent && parent.parent.type === "AssignmentExpression" || - - // or the last identifier in an ObjectPattern destructuring - parent.parent.type === "Property" && parent.parent.value === parent && - parent.parent.parent.type === "ObjectPattern" && parent.parent.parent.parent.left === parent.parent.parent) - ); - }, - AssignmentPattern(parent, node) { - return parent.left === node; - }, - VariableDeclarator(parent, node) { - return parent.id === node; - }, - Property(parent, node) { - - if (parent.parent.type === "ObjectPattern") { - return ( - parent.value !== parent.key && parent.value === node || - parent.value === parent.key && parent.key === node && properties - ); - } - return properties && !parent.computed && parent.key === node; - }, - ImportDefaultSpecifier: true, - RestElement: true, - FunctionExpression: true, - ArrowFunctionExpression: true, - ClassDeclaration: true, - FunctionDeclaration: true, - MethodDefinition: true, - CatchClause: true, - ArrayPattern: true - }; - - return { - Identifier(node) { - const name = node.name; - const parent = node.parent; - - const isShort = name.length < minLength; - const isLong = name.length > maxLength; - - if (!(isShort || isLong) || exceptions.has(name) || matchesExceptionPattern(name)) { - return; // Nothing to report - } - - const isValidExpression = SUPPORTED_EXPRESSIONS[parent.type]; - - if (isValidExpression && !reportedNode.has(node) && (isValidExpression === true || isValidExpression(parent, node))) { - reportedNode.add(node); - context.report({ - node, - messageId: isShort ? "tooShort" : "tooLong", - data: { name, min: minLength, max: maxLength } - }); - } - } - }; - } -}; - -/** - * @fileoverview Rule to flag non-matching identifiers - * @author Matthieu Larcher - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var idMatch = { - meta: { - type: "suggestion", - - docs: { - description: "require identifiers to match a specified regular expression", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/id-match" - }, - - schema: [ - { - type: "string" - }, - { - type: "object", - properties: { - properties: { - type: "boolean", - default: false - }, - onlyDeclarations: { - type: "boolean", - default: false - }, - ignoreDestructuring: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - messages: { - notMatch: "Identifier '{{name}}' does not match the pattern '{{pattern}}'." - } - }, - - create(context) { - - //-------------------------------------------------------------------------- - // Options - //-------------------------------------------------------------------------- - const pattern = context.options[0] || "^.+$", - regexp = new RegExp(pattern, "u"); - - const options = context.options[1] || {}, - properties = !!options.properties, - onlyDeclarations = !!options.onlyDeclarations, - ignoreDestructuring = !!options.ignoreDestructuring; - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - // contains reported nodes to avoid reporting twice on destructuring with shorthand notation - const reported = new Map(); - const ALLOWED_PARENT_TYPES = new Set(["CallExpression", "NewExpression"]); - const DECLARATION_TYPES = new Set(["FunctionDeclaration", "VariableDeclarator"]); - const IMPORT_TYPES = new Set(["ImportSpecifier", "ImportNamespaceSpecifier", "ImportDefaultSpecifier"]); - - /** - * Checks if a string matches the provided pattern - * @param {string} name The string to check. - * @returns {boolean} if the string is a match - * @private - */ - function isInvalid(name) { - return !regexp.test(name); - } - - /** - * Checks if a parent of a node is an ObjectPattern. - * @param {ASTNode} node The node to check. - * @returns {boolean} if the node is inside an ObjectPattern - * @private - */ - function isInsideObjectPattern(node) { - let { parent } = node; - - while (parent) { - if (parent.type === "ObjectPattern") { - return true; - } - - parent = parent.parent; - } - - return false; - } - - /** - * Verifies if we should report an error or not based on the effective - * parent node and the identifier name. - * @param {ASTNode} effectiveParent The effective parent node of the node to be reported - * @param {string} name The identifier name of the identifier node - * @returns {boolean} whether an error should be reported or not - */ - function shouldReport(effectiveParent, name) { - return (!onlyDeclarations || DECLARATION_TYPES.has(effectiveParent.type)) && - !ALLOWED_PARENT_TYPES.has(effectiveParent.type) && isInvalid(name); - } - - /** - * Reports an AST node as a rule violation. - * @param {ASTNode} node The node to report. - * @returns {void} - * @private - */ - function report(node) { - if (!reported.has(node)) { - context.report({ - node, - messageId: "notMatch", - data: { - name: node.name, - pattern - } - }); - reported.set(node, true); - } - } - - return { - - Identifier(node) { - const name = node.name, - parent = node.parent, - effectiveParent = (parent.type === "MemberExpression") ? parent.parent : parent; - - if (parent.type === "MemberExpression") { - - if (!properties) { - return; - } - - // Always check object names - if (parent.object.type === "Identifier" && - parent.object.name === name) { - if (isInvalid(name)) { - report(node); - } - - // Report AssignmentExpressions left side's assigned variable id - } else if (effectiveParent.type === "AssignmentExpression" && - effectiveParent.left.type === "MemberExpression" && - effectiveParent.left.property.name === node.name) { - if (isInvalid(name)) { - report(node); - } - - // Report AssignmentExpressions only if they are the left side of the assignment - } else if (effectiveParent.type === "AssignmentExpression" && effectiveParent.right.type !== "MemberExpression") { - if (isInvalid(name)) { - report(node); - } - } - - /* - * Properties have their own rules, and - * AssignmentPattern nodes can be treated like Properties: - * e.g.: const { no_camelcased = false } = bar; - */ - } else if (parent.type === "Property" || parent.type === "AssignmentPattern") { - - if (parent.parent && parent.parent.type === "ObjectPattern") { - if (parent.shorthand && parent.value.left && isInvalid(name)) { - - report(node); - } - - const assignmentKeyEqualsValue = parent.key.name === parent.value.name; - - // prevent checking righthand side of destructured object - if (!assignmentKeyEqualsValue && parent.key === node) { - return; - } - - const valueIsInvalid = parent.value.name && isInvalid(name); - - // ignore destructuring if the option is set, unless a new identifier is created - if (valueIsInvalid && !(assignmentKeyEqualsValue && ignoreDestructuring)) { - report(node); - } - } - - // never check properties or always ignore destructuring - if (!properties || (ignoreDestructuring && isInsideObjectPattern(node))) { - return; - } - - // don't check right hand side of AssignmentExpression to prevent duplicate warnings - if (parent.right !== node && shouldReport(effectiveParent, name)) { - report(node); - } - - // Check if it's an import specifier - } else if (IMPORT_TYPES.has(parent.type)) { - - // Report only if the local imported identifier is invalid - if (parent.local && parent.local.name === node.name && isInvalid(name)) { - report(node); - } - - // Report anything that is invalid that isn't a CallExpression - } else if (shouldReport(effectiveParent, name)) { - report(node); - } - } - - }; - - } -}; - -/** - * @fileoverview enforce the location of arrow function bodies - * @author Sharmila Jesupaul - */ - -const { isCommentToken, isNotOpeningParenToken } = astUtils; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ -var implicitArrowLinebreak = { - meta: { - type: "layout", - - docs: { - description: "enforce the location of arrow function bodies", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/implicit-arrow-linebreak" - }, - - fixable: "whitespace", - - schema: [ - { - enum: ["beside", "below"] - } - ], - messages: { - expected: "Expected a linebreak before this expression.", - unexpected: "Expected no linebreak before this expression." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const option = context.options[0] || "beside"; - - /** - * Validates the location of an arrow function body - * @param {ASTNode} node The arrow function body - * @returns {void} - */ - function validateExpression(node) { - if (node.body.type === "BlockStatement") { - return; - } - - const arrowToken = sourceCode.getTokenBefore(node.body, isNotOpeningParenToken); - const firstTokenOfBody = sourceCode.getTokenAfter(arrowToken); - - if (arrowToken.loc.end.line === firstTokenOfBody.loc.start.line && option === "below") { - context.report({ - node: firstTokenOfBody, - messageId: "expected", - fix: fixer => fixer.insertTextBefore(firstTokenOfBody, "\n") - }); - } else if (arrowToken.loc.end.line !== firstTokenOfBody.loc.start.line && option === "beside") { - context.report({ - node: firstTokenOfBody, - messageId: "unexpected", - fix(fixer) { - if (sourceCode.getFirstTokenBetween(arrowToken, firstTokenOfBody, { includeComments: true, filter: isCommentToken })) { - return null; - } - - return fixer.replaceTextRange([arrowToken.range[1], firstTokenOfBody.range[0]], " "); - } - }); - } - } - - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - return { - ArrowFunctionExpression: node => validateExpression(node) - }; - } -}; - -/** - * @fileoverview This rule sets a specific indentation style and width for your code - * - * @author Teddy Katz - * @author Vitaly Puzrin - * @author Gyandeep Singh - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -const KNOWN_NODES = new Set([ - "AssignmentExpression", - "AssignmentPattern", - "ArrayExpression", - "ArrayPattern", - "ArrowFunctionExpression", - "AwaitExpression", - "BlockStatement", - "BinaryExpression", - "BreakStatement", - "CallExpression", - "CatchClause", - "ChainExpression", - "ClassBody", - "ClassDeclaration", - "ClassExpression", - "ConditionalExpression", - "ContinueStatement", - "DoWhileStatement", - "DebuggerStatement", - "EmptyStatement", - "ExperimentalRestProperty", - "ExperimentalSpreadProperty", - "ExpressionStatement", - "ForStatement", - "ForInStatement", - "ForOfStatement", - "FunctionDeclaration", - "FunctionExpression", - "Identifier", - "IfStatement", - "Literal", - "LabeledStatement", - "LogicalExpression", - "MemberExpression", - "MetaProperty", - "MethodDefinition", - "NewExpression", - "ObjectExpression", - "ObjectPattern", - "Program", - "Property", - "RestElement", - "ReturnStatement", - "SequenceExpression", - "SpreadElement", - "Super", - "SwitchCase", - "SwitchStatement", - "TaggedTemplateExpression", - "TemplateElement", - "TemplateLiteral", - "ThisExpression", - "ThrowStatement", - "TryStatement", - "UnaryExpression", - "UpdateExpression", - "VariableDeclaration", - "VariableDeclarator", - "WhileStatement", - "WithStatement", - "YieldExpression", - "JSXFragment", - "JSXOpeningFragment", - "JSXClosingFragment", - "JSXIdentifier", - "JSXNamespacedName", - "JSXMemberExpression", - "JSXEmptyExpression", - "JSXExpressionContainer", - "JSXElement", - "JSXClosingElement", - "JSXOpeningElement", - "JSXAttribute", - "JSXSpreadAttribute", - "JSXText", - "ExportDefaultDeclaration", - "ExportNamedDeclaration", - "ExportAllDeclaration", - "ExportSpecifier", - "ImportDeclaration", - "ImportSpecifier", - "ImportDefaultSpecifier", - "ImportNamespaceSpecifier", - "ImportExpression" -]); - -/* - * General rule strategy: - * 1. An OffsetStorage instance stores a map of desired offsets, where each token has a specified offset from another - * specified token or to the first column. - * 2. As the AST is traversed, modify the desired offsets of tokens accordingly. For example, when entering a - * BlockStatement, offset all of the tokens in the BlockStatement by 1 indent level from the opening curly - * brace of the BlockStatement. - * 3. After traversing the AST, calculate the expected indentation levels of every token according to the - * OffsetStorage container. - * 4. For each line, compare the expected indentation of the first token to the actual indentation in the file, - * and report the token if the two values are not equal. - */ - - -/** - * A mutable balanced binary search tree that stores (key, value) pairs. The keys are numeric, and must be unique. - * This is intended to be a generic wrapper around a balanced binary search tree library, so that the underlying implementation - * can easily be swapped out. - */ -class BinarySearchTree { - - /** - * Creates an empty tree - */ - constructor() { - this._rbTree = createTree__default['default'](); - } - - /** - * Inserts an entry into the tree. - * @param {number} key The entry's key - * @param {*} value The entry's value - * @returns {void} - */ - insert(key, value) { - const iterator = this._rbTree.find(key); - - if (iterator.valid) { - this._rbTree = iterator.update(value); - } else { - this._rbTree = this._rbTree.insert(key, value); - } - } - - /** - * Finds the entry with the largest key less than or equal to the provided key - * @param {number} key The provided key - * @returns {{key: number, value: *}|null} The found entry, or null if no such entry exists. - */ - findLe(key) { - const iterator = this._rbTree.le(key); - - return iterator && { key: iterator.key, value: iterator.value }; - } - - /** - * Deletes all of the keys in the interval [start, end) - * @param {number} start The start of the range - * @param {number} end The end of the range - * @returns {void} - */ - deleteRange(start, end) { - - // Exit without traversing the tree if the range has zero size. - if (start === end) { - return; - } - const iterator = this._rbTree.ge(start); - - while (iterator.valid && iterator.key < end) { - this._rbTree = this._rbTree.remove(iterator.key); - iterator.next(); - } - } -} - -/** - * A helper class to get token-based info related to indentation - */ -class TokenInfo { - - // eslint-disable-next-line jsdoc/require-description - /** - * @param {SourceCode} sourceCode A SourceCode object - */ - constructor(sourceCode) { - this.sourceCode = sourceCode; - this.firstTokensByLineNumber = sourceCode.tokensAndComments.reduce((map, token) => { - if (!map.has(token.loc.start.line)) { - map.set(token.loc.start.line, token); - } - if (!map.has(token.loc.end.line) && sourceCode.text.slice(token.range[1] - token.loc.end.column, token.range[1]).trim()) { - map.set(token.loc.end.line, token); - } - return map; - }, new Map()); - } - - /** - * Gets the first token on a given token's line - * @param {Token|ASTNode} token a node or token - * @returns {Token} The first token on the given line - */ - getFirstTokenOfLine(token) { - return this.firstTokensByLineNumber.get(token.loc.start.line); - } - - /** - * Determines whether a token is the first token in its line - * @param {Token} token The token - * @returns {boolean} `true` if the token is the first on its line - */ - isFirstTokenOfLine(token) { - return this.getFirstTokenOfLine(token) === token; - } - - /** - * Get the actual indent of a token - * @param {Token} token Token to examine. This should be the first token on its line. - * @returns {string} The indentation characters that precede the token - */ - getTokenIndent(token) { - return this.sourceCode.text.slice(token.range[0] - token.loc.start.column, token.range[0]); - } -} - -/** - * A class to store information on desired offsets of tokens from each other - */ -class OffsetStorage { - - // eslint-disable-next-line jsdoc/require-description - /** - * @param {TokenInfo} tokenInfo a TokenInfo instance - * @param {number} indentSize The desired size of each indentation level - * @param {string} indentType The indentation character - */ - constructor(tokenInfo, indentSize, indentType) { - this._tokenInfo = tokenInfo; - this._indentSize = indentSize; - this._indentType = indentType; - - this._tree = new BinarySearchTree(); - this._tree.insert(0, { offset: 0, from: null, force: false }); - - this._lockedFirstTokens = new WeakMap(); - this._desiredIndentCache = new WeakMap(); - this._ignoredTokens = new WeakSet(); - } - - _getOffsetDescriptor(token) { - return this._tree.findLe(token.range[0]).value; - } - - /** - * Sets the offset column of token B to match the offset column of token A. - * **WARNING**: This matches a *column*, even if baseToken is not the first token on its line. In - * most cases, `setDesiredOffset` should be used instead. - * @param {Token} baseToken The first token - * @param {Token} offsetToken The second token, whose offset should be matched to the first token - * @returns {void} - */ - matchOffsetOf(baseToken, offsetToken) { - - /* - * lockedFirstTokens is a map from a token whose indentation is controlled by the "first" option to - * the token that it depends on. For example, with the `ArrayExpression: first` option, the first - * token of each element in the array after the first will be mapped to the first token of the first - * element. The desired indentation of each of these tokens is computed based on the desired indentation - * of the "first" element, rather than through the normal offset mechanism. - */ - this._lockedFirstTokens.set(offsetToken, baseToken); - } - - /** - * Sets the desired offset of a token. - * - * This uses a line-based offset collapsing behavior to handle tokens on the same line. - * For example, consider the following two cases: - * - * ( - * [ - * bar - * ] - * ) - * - * ([ - * bar - * ]) - * - * Based on the first case, it's clear that the `bar` token needs to have an offset of 1 indent level (4 spaces) from - * the `[` token, and the `[` token has to have an offset of 1 indent level from the `(` token. Since the `(` token is - * the first on its line (with an indent of 0 spaces), the `bar` token needs to be offset by 2 indent levels (8 spaces) - * from the start of its line. - * - * However, in the second case `bar` should only be indented by 4 spaces. This is because the offset of 1 indent level - * between the `(` and the `[` tokens gets "collapsed" because the two tokens are on the same line. As a result, the - * `(` token is mapped to the `[` token with an offset of 0, and the rule correctly decides that `bar` should be indented - * by 1 indent level from the start of the line. - * - * This is useful because rule listeners can usually just call `setDesiredOffset` for all the tokens in the node, - * without needing to check which lines those tokens are on. - * - * Note that since collapsing only occurs when two tokens are on the same line, there are a few cases where non-intuitive - * behavior can occur. For example, consider the following cases: - * - * foo( - * ). - * bar( - * baz - * ) - * - * foo( - * ).bar( - * baz - * ) - * - * Based on the first example, it would seem that `bar` should be offset by 1 indent level from `foo`, and `baz` - * should be offset by 1 indent level from `bar`. However, this is not correct, because it would result in `baz` - * being indented by 2 indent levels in the second case (since `foo`, `bar`, and `baz` are all on separate lines, no - * collapsing would occur). - * - * Instead, the correct way would be to offset `baz` by 1 level from `bar`, offset `bar` by 1 level from the `)`, and - * offset the `)` by 0 levels from `foo`. This ensures that the offset between `bar` and the `)` are correctly collapsed - * in the second case. - * @param {Token} token The token - * @param {Token} fromToken The token that `token` should be offset from - * @param {number} offset The desired indent level - * @returns {void} - */ - setDesiredOffset(token, fromToken, offset) { - return this.setDesiredOffsets(token.range, fromToken, offset); - } - - /** - * Sets the desired offset of all tokens in a range - * It's common for node listeners in this file to need to apply the same offset to a large, contiguous range of tokens. - * Moreover, the offset of any given token is usually updated multiple times (roughly once for each node that contains - * it). This means that the offset of each token is updated O(AST depth) times. - * It would not be performant to store and update the offsets for each token independently, because the rule would end - * up having a time complexity of O(number of tokens * AST depth), which is quite slow for large files. - * - * Instead, the offset tree is represented as a collection of contiguous offset ranges in a file. For example, the following - * list could represent the state of the offset tree at a given point: - * - * * Tokens starting in the interval [0, 15) are aligned with the beginning of the file - * * Tokens starting in the interval [15, 30) are offset by 1 indent level from the `bar` token - * * Tokens starting in the interval [30, 43) are offset by 1 indent level from the `foo` token - * * Tokens starting in the interval [43, 820) are offset by 2 indent levels from the `bar` token - * * Tokens starting in the interval [820, ∞) are offset by 1 indent level from the `baz` token - * - * The `setDesiredOffsets` methods inserts ranges like the ones above. The third line above would be inserted by using: - * `setDesiredOffsets([30, 43], fooToken, 1);` - * @param {[number, number]} range A [start, end] pair. All tokens with range[0] <= token.start < range[1] will have the offset applied. - * @param {Token} fromToken The token that this is offset from - * @param {number} offset The desired indent level - * @param {boolean} force `true` if this offset should not use the normal collapsing behavior. This should almost always be false. - * @returns {void} - */ - setDesiredOffsets(range, fromToken, offset, force) { - - /* - * Offset ranges are stored as a collection of nodes, where each node maps a numeric key to an offset - * descriptor. The tree for the example above would have the following nodes: - * - * * key: 0, value: { offset: 0, from: null } - * * key: 15, value: { offset: 1, from: barToken } - * * key: 30, value: { offset: 1, from: fooToken } - * * key: 43, value: { offset: 2, from: barToken } - * * key: 820, value: { offset: 1, from: bazToken } - * - * To find the offset descriptor for any given token, one needs to find the node with the largest key - * which is <= token.start. To make this operation fast, the nodes are stored in a balanced binary - * search tree indexed by key. - */ - - const descriptorToInsert = { offset, from: fromToken, force }; - - const descriptorAfterRange = this._tree.findLe(range[1]).value; - - const fromTokenIsInRange = fromToken && fromToken.range[0] >= range[0] && fromToken.range[1] <= range[1]; - const fromTokenDescriptor = fromTokenIsInRange && this._getOffsetDescriptor(fromToken); - - // First, remove any existing nodes in the range from the tree. - this._tree.deleteRange(range[0] + 1, range[1]); - - // Insert a new node into the tree for this range - this._tree.insert(range[0], descriptorToInsert); - - /* - * To avoid circular offset dependencies, keep the `fromToken` token mapped to whatever it was mapped to previously, - * even if it's in the current range. - */ - if (fromTokenIsInRange) { - this._tree.insert(fromToken.range[0], fromTokenDescriptor); - this._tree.insert(fromToken.range[1], descriptorToInsert); - } - - /* - * To avoid modifying the offset of tokens after the range, insert another node to keep the offset of the following - * tokens the same as it was before. - */ - this._tree.insert(range[1], descriptorAfterRange); - } - - /** - * Gets the desired indent of a token - * @param {Token} token The token - * @returns {string} The desired indent of the token - */ - getDesiredIndent(token) { - if (!this._desiredIndentCache.has(token)) { - - if (this._ignoredTokens.has(token)) { - - /* - * If the token is ignored, use the actual indent of the token as the desired indent. - * This ensures that no errors are reported for this token. - */ - this._desiredIndentCache.set( - token, - this._tokenInfo.getTokenIndent(token) - ); - } else if (this._lockedFirstTokens.has(token)) { - const firstToken = this._lockedFirstTokens.get(token); - - this._desiredIndentCache.set( - token, - - // (indentation for the first element's line) - this.getDesiredIndent(this._tokenInfo.getFirstTokenOfLine(firstToken)) + - - // (space between the start of the first element's line and the first element) - this._indentType.repeat(firstToken.loc.start.column - this._tokenInfo.getFirstTokenOfLine(firstToken).loc.start.column) - ); - } else { - const offsetInfo = this._getOffsetDescriptor(token); - const offset = ( - offsetInfo.from && - offsetInfo.from.loc.start.line === token.loc.start.line && - !/^\s*?\n/u.test(token.value) && - !offsetInfo.force - ) ? 0 : offsetInfo.offset * this._indentSize; - - this._desiredIndentCache.set( - token, - (offsetInfo.from ? this.getDesiredIndent(offsetInfo.from) : "") + this._indentType.repeat(offset) - ); - } - } - return this._desiredIndentCache.get(token); - } - - /** - * Ignores a token, preventing it from being reported. - * @param {Token} token The token - * @returns {void} - */ - ignoreToken(token) { - if (this._tokenInfo.isFirstTokenOfLine(token)) { - this._ignoredTokens.add(token); - } - } - - /** - * Gets the first token that the given token's indentation is dependent on - * @param {Token} token The token - * @returns {Token} The token that the given token depends on, or `null` if the given token is at the top level - */ - getFirstDependency(token) { - return this._getOffsetDescriptor(token).from; - } -} - -const ELEMENT_LIST_SCHEMA = { - oneOf: [ - { - type: "integer", - minimum: 0 - }, - { - enum: ["first", "off"] - } - ] -}; - -var indent = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent indentation", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/indent" - }, - - fixable: "whitespace", - - schema: [ - { - oneOf: [ - { - enum: ["tab"] - }, - { - type: "integer", - minimum: 0 - } - ] - }, - { - type: "object", - properties: { - SwitchCase: { - type: "integer", - minimum: 0, - default: 0 - }, - VariableDeclarator: { - oneOf: [ - ELEMENT_LIST_SCHEMA, - { - type: "object", - properties: { - var: ELEMENT_LIST_SCHEMA, - let: ELEMENT_LIST_SCHEMA, - const: ELEMENT_LIST_SCHEMA - }, - additionalProperties: false - } - ] - }, - outerIIFEBody: { - oneOf: [ - { - type: "integer", - minimum: 0 - }, - { - enum: ["off"] - } - ] - }, - MemberExpression: { - oneOf: [ - { - type: "integer", - minimum: 0 - }, - { - enum: ["off"] - } - ] - }, - FunctionDeclaration: { - type: "object", - properties: { - parameters: ELEMENT_LIST_SCHEMA, - body: { - type: "integer", - minimum: 0 - } - }, - additionalProperties: false - }, - FunctionExpression: { - type: "object", - properties: { - parameters: ELEMENT_LIST_SCHEMA, - body: { - type: "integer", - minimum: 0 - } - }, - additionalProperties: false - }, - CallExpression: { - type: "object", - properties: { - arguments: ELEMENT_LIST_SCHEMA - }, - additionalProperties: false - }, - ArrayExpression: ELEMENT_LIST_SCHEMA, - ObjectExpression: ELEMENT_LIST_SCHEMA, - ImportDeclaration: ELEMENT_LIST_SCHEMA, - flatTernaryExpressions: { - type: "boolean", - default: false - }, - offsetTernaryExpressions: { - type: "boolean", - default: false - }, - ignoredNodes: { - type: "array", - items: { - type: "string", - not: { - pattern: ":exit$" - } - } - }, - ignoreComments: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - messages: { - wrongIndentation: "Expected indentation of {{expected}} but found {{actual}}." - } - }, - - create(context) { - const DEFAULT_VARIABLE_INDENT = 1; - const DEFAULT_PARAMETER_INDENT = 1; - const DEFAULT_FUNCTION_BODY_INDENT = 1; - - let indentType = "space"; - let indentSize = 4; - const options = { - SwitchCase: 0, - VariableDeclarator: { - var: DEFAULT_VARIABLE_INDENT, - let: DEFAULT_VARIABLE_INDENT, - const: DEFAULT_VARIABLE_INDENT - }, - outerIIFEBody: 1, - FunctionDeclaration: { - parameters: DEFAULT_PARAMETER_INDENT, - body: DEFAULT_FUNCTION_BODY_INDENT - }, - FunctionExpression: { - parameters: DEFAULT_PARAMETER_INDENT, - body: DEFAULT_FUNCTION_BODY_INDENT - }, - CallExpression: { - arguments: DEFAULT_PARAMETER_INDENT - }, - MemberExpression: 1, - ArrayExpression: 1, - ObjectExpression: 1, - ImportDeclaration: 1, - flatTernaryExpressions: false, - ignoredNodes: [], - ignoreComments: false - }; - - if (context.options.length) { - if (context.options[0] === "tab") { - indentSize = 1; - indentType = "tab"; - } else { - indentSize = context.options[0]; - indentType = "space"; - } - - if (context.options[1]) { - Object.assign(options, context.options[1]); - - if (typeof options.VariableDeclarator === "number" || options.VariableDeclarator === "first") { - options.VariableDeclarator = { - var: options.VariableDeclarator, - let: options.VariableDeclarator, - const: options.VariableDeclarator - }; - } - } - } - - const sourceCode = context.getSourceCode(); - const tokenInfo = new TokenInfo(sourceCode); - const offsets = new OffsetStorage(tokenInfo, indentSize, indentType === "space" ? " " : "\t"); - const parameterParens = new WeakSet(); - - /** - * Creates an error message for a line, given the expected/actual indentation. - * @param {int} expectedAmount The expected amount of indentation characters for this line - * @param {int} actualSpaces The actual number of indentation spaces that were found on this line - * @param {int} actualTabs The actual number of indentation tabs that were found on this line - * @returns {string} An error message for this line - */ - function createErrorMessageData(expectedAmount, actualSpaces, actualTabs) { - const expectedStatement = `${expectedAmount} ${indentType}${expectedAmount === 1 ? "" : "s"}`; // e.g. "2 tabs" - const foundSpacesWord = `space${actualSpaces === 1 ? "" : "s"}`; // e.g. "space" - const foundTabsWord = `tab${actualTabs === 1 ? "" : "s"}`; // e.g. "tabs" - let foundStatement; - - if (actualSpaces > 0) { - - /* - * Abbreviate the message if the expected indentation is also spaces. - * e.g. 'Expected 4 spaces but found 2' rather than 'Expected 4 spaces but found 2 spaces' - */ - foundStatement = indentType === "space" ? actualSpaces : `${actualSpaces} ${foundSpacesWord}`; - } else if (actualTabs > 0) { - foundStatement = indentType === "tab" ? actualTabs : `${actualTabs} ${foundTabsWord}`; - } else { - foundStatement = "0"; - } - return { - expected: expectedStatement, - actual: foundStatement - }; - } - - /** - * Reports a given indent violation - * @param {Token} token Token violating the indent rule - * @param {string} neededIndent Expected indentation string - * @returns {void} - */ - function report(token, neededIndent) { - const actualIndent = Array.from(tokenInfo.getTokenIndent(token)); - const numSpaces = actualIndent.filter(char => char === " ").length; - const numTabs = actualIndent.filter(char => char === "\t").length; - - context.report({ - node: token, - messageId: "wrongIndentation", - data: createErrorMessageData(neededIndent.length, numSpaces, numTabs), - loc: { - start: { line: token.loc.start.line, column: 0 }, - end: { line: token.loc.start.line, column: token.loc.start.column } - }, - fix(fixer) { - const range = [token.range[0] - token.loc.start.column, token.range[0]]; - const newText = neededIndent; - - return fixer.replaceTextRange(range, newText); - } - }); - } - - /** - * Checks if a token's indentation is correct - * @param {Token} token Token to examine - * @param {string} desiredIndent Desired indentation of the string - * @returns {boolean} `true` if the token's indentation is correct - */ - function validateTokenIndent(token, desiredIndent) { - const indentation = tokenInfo.getTokenIndent(token); - - return indentation === desiredIndent || - - // To avoid conflicts with no-mixed-spaces-and-tabs, don't report mixed spaces and tabs. - indentation.includes(" ") && indentation.includes("\t"); - } - - /** - * Check to see if the node is a file level IIFE - * @param {ASTNode} node The function node to check. - * @returns {boolean} True if the node is the outer IIFE - */ - function isOuterIIFE(node) { - - /* - * Verify that the node is an IIFE - */ - if (!node.parent || node.parent.type !== "CallExpression" || node.parent.callee !== node) { - return false; - } - - /* - * Navigate legal ancestors to determine whether this IIFE is outer. - * A "legal ancestor" is an expression or statement that causes the function to get executed immediately. - * For example, `!(function(){})()` is an outer IIFE even though it is preceded by a ! operator. - */ - let statement = node.parent && node.parent.parent; - - while ( - statement.type === "UnaryExpression" && ["!", "~", "+", "-"].indexOf(statement.operator) > -1 || - statement.type === "AssignmentExpression" || - statement.type === "LogicalExpression" || - statement.type === "SequenceExpression" || - statement.type === "VariableDeclarator" - ) { - statement = statement.parent; - } - - return (statement.type === "ExpressionStatement" || statement.type === "VariableDeclaration") && statement.parent.type === "Program"; - } - - /** - * Counts the number of linebreaks that follow the last non-whitespace character in a string - * @param {string} string The string to check - * @returns {number} The number of JavaScript linebreaks that follow the last non-whitespace character, - * or the total number of linebreaks if the string is all whitespace. - */ - function countTrailingLinebreaks(string) { - const trailingWhitespace = string.match(/\s*$/u)[0]; - const linebreakMatches = trailingWhitespace.match(astUtils.createGlobalLinebreakMatcher()); - - return linebreakMatches === null ? 0 : linebreakMatches.length; - } - - /** - * Check indentation for lists of elements (arrays, objects, function params) - * @param {ASTNode[]} elements List of elements that should be offset - * @param {Token} startToken The start token of the list that element should be aligned against, e.g. '[' - * @param {Token} endToken The end token of the list, e.g. ']' - * @param {number|string} offset The amount that the elements should be offset - * @returns {void} - */ - function addElementListIndent(elements, startToken, endToken, offset) { - - /** - * Gets the first token of a given element, including surrounding parentheses. - * @param {ASTNode} element A node in the `elements` list - * @returns {Token} The first token of this element - */ - function getFirstToken(element) { - let token = sourceCode.getTokenBefore(element); - - while (astUtils.isOpeningParenToken(token) && token !== startToken) { - token = sourceCode.getTokenBefore(token); - } - return sourceCode.getTokenAfter(token); - } - - // Run through all the tokens in the list, and offset them by one indent level (mainly for comments, other things will end up overridden) - offsets.setDesiredOffsets( - [startToken.range[1], endToken.range[0]], - startToken, - typeof offset === "number" ? offset : 1 - ); - offsets.setDesiredOffset(endToken, startToken, 0); - - // If the preference is "first" but there is no first element (e.g. sparse arrays w/ empty first slot), fall back to 1 level. - if (offset === "first" && elements.length && !elements[0]) { - return; - } - elements.forEach((element, index) => { - if (!element) { - - // Skip holes in arrays - return; - } - if (offset === "off") { - - // Ignore the first token of every element if the "off" option is used - offsets.ignoreToken(getFirstToken(element)); - } - - // Offset the following elements correctly relative to the first element - if (index === 0) { - return; - } - if (offset === "first" && tokenInfo.isFirstTokenOfLine(getFirstToken(element))) { - offsets.matchOffsetOf(getFirstToken(elements[0]), getFirstToken(element)); - } else { - const previousElement = elements[index - 1]; - const firstTokenOfPreviousElement = previousElement && getFirstToken(previousElement); - const previousElementLastToken = previousElement && sourceCode.getLastToken(previousElement); - - if ( - previousElement && - previousElementLastToken.loc.end.line - countTrailingLinebreaks(previousElementLastToken.value) > startToken.loc.end.line - ) { - offsets.setDesiredOffsets( - [previousElement.range[1], element.range[1]], - firstTokenOfPreviousElement, - 0 - ); - } - } - }); - } - - /** - * Check and decide whether to check for indentation for blockless nodes - * Scenarios are for or while statements without braces around them - * @param {ASTNode} node node to examine - * @returns {void} - */ - function addBlocklessNodeIndent(node) { - if (node.type !== "BlockStatement") { - const lastParentToken = sourceCode.getTokenBefore(node, astUtils.isNotOpeningParenToken); - - let firstBodyToken = sourceCode.getFirstToken(node); - let lastBodyToken = sourceCode.getLastToken(node); - - while ( - astUtils.isOpeningParenToken(sourceCode.getTokenBefore(firstBodyToken)) && - astUtils.isClosingParenToken(sourceCode.getTokenAfter(lastBodyToken)) - ) { - firstBodyToken = sourceCode.getTokenBefore(firstBodyToken); - lastBodyToken = sourceCode.getTokenAfter(lastBodyToken); - } - - offsets.setDesiredOffsets([firstBodyToken.range[0], lastBodyToken.range[1]], lastParentToken, 1); - - /* - * For blockless nodes with semicolon-first style, don't indent the semicolon. - * e.g. - * if (foo) bar() - * ; [1, 2, 3].map(foo) - */ - const lastToken = sourceCode.getLastToken(node); - - if (node.type !== "EmptyStatement" && astUtils.isSemicolonToken(lastToken)) { - offsets.setDesiredOffset(lastToken, lastParentToken, 0); - } - } - } - - /** - * Checks the indentation for nodes that are like function calls (`CallExpression` and `NewExpression`) - * @param {ASTNode} node A CallExpression or NewExpression node - * @returns {void} - */ - function addFunctionCallIndent(node) { - let openingParen; - - if (node.arguments.length) { - openingParen = sourceCode.getFirstTokenBetween(node.callee, node.arguments[0], astUtils.isOpeningParenToken); - } else { - openingParen = sourceCode.getLastToken(node, 1); - } - const closingParen = sourceCode.getLastToken(node); - - parameterParens.add(openingParen); - parameterParens.add(closingParen); - - /* - * If `?.` token exists, set desired offset for that. - * This logic is copied from `MemberExpression`'s. - */ - if (node.optional) { - const dotToken = sourceCode.getTokenAfter(node.callee, astUtils.isQuestionDotToken); - const calleeParenCount = sourceCode.getTokensBetween(node.callee, dotToken, { filter: astUtils.isClosingParenToken }).length; - const firstTokenOfCallee = calleeParenCount - ? sourceCode.getTokenBefore(node.callee, { skip: calleeParenCount - 1 }) - : sourceCode.getFirstToken(node.callee); - const lastTokenOfCallee = sourceCode.getTokenBefore(dotToken); - const offsetBase = lastTokenOfCallee.loc.end.line === openingParen.loc.start.line - ? lastTokenOfCallee - : firstTokenOfCallee; - - offsets.setDesiredOffset(dotToken, offsetBase, 1); - } - - const offsetAfterToken = node.callee.type === "TaggedTemplateExpression" ? sourceCode.getFirstToken(node.callee.quasi) : openingParen; - const offsetToken = sourceCode.getTokenBefore(offsetAfterToken); - - offsets.setDesiredOffset(openingParen, offsetToken, 0); - - addElementListIndent(node.arguments, openingParen, closingParen, options.CallExpression.arguments); - } - - /** - * Checks the indentation of parenthesized values, given a list of tokens in a program - * @param {Token[]} tokens A list of tokens - * @returns {void} - */ - function addParensIndent(tokens) { - const parenStack = []; - const parenPairs = []; - - tokens.forEach(nextToken => { - - // Accumulate a list of parenthesis pairs - if (astUtils.isOpeningParenToken(nextToken)) { - parenStack.push(nextToken); - } else if (astUtils.isClosingParenToken(nextToken)) { - parenPairs.unshift({ left: parenStack.pop(), right: nextToken }); - } - }); - - parenPairs.forEach(pair => { - const leftParen = pair.left; - const rightParen = pair.right; - - // We only want to handle parens around expressions, so exclude parentheses that are in function parameters and function call arguments. - if (!parameterParens.has(leftParen) && !parameterParens.has(rightParen)) { - const parenthesizedTokens = new Set(sourceCode.getTokensBetween(leftParen, rightParen)); - - parenthesizedTokens.forEach(token => { - if (!parenthesizedTokens.has(offsets.getFirstDependency(token))) { - offsets.setDesiredOffset(token, leftParen, 1); - } - }); - } - - offsets.setDesiredOffset(rightParen, leftParen, 0); - }); - } - - /** - * Ignore all tokens within an unknown node whose offset do not depend - * on another token's offset within the unknown node - * @param {ASTNode} node Unknown Node - * @returns {void} - */ - function ignoreNode(node) { - const unknownNodeTokens = new Set(sourceCode.getTokens(node, { includeComments: true })); - - unknownNodeTokens.forEach(token => { - if (!unknownNodeTokens.has(offsets.getFirstDependency(token))) { - const firstTokenOfLine = tokenInfo.getFirstTokenOfLine(token); - - if (token === firstTokenOfLine) { - offsets.ignoreToken(token); - } else { - offsets.setDesiredOffset(token, firstTokenOfLine, 0); - } - } - }); - } - - /** - * Check whether the given token is on the first line of a statement. - * @param {Token} token The token to check. - * @param {ASTNode} leafNode The expression node that the token belongs directly. - * @returns {boolean} `true` if the token is on the first line of a statement. - */ - function isOnFirstLineOfStatement(token, leafNode) { - let node = leafNode; - - while (node.parent && !node.parent.type.endsWith("Statement") && !node.parent.type.endsWith("Declaration")) { - node = node.parent; - } - node = node.parent; - - return !node || node.loc.start.line === token.loc.start.line; - } - - /** - * Check whether there are any blank (whitespace-only) lines between - * two tokens on separate lines. - * @param {Token} firstToken The first token. - * @param {Token} secondToken The second token. - * @returns {boolean} `true` if the tokens are on separate lines and - * there exists a blank line between them, `false` otherwise. - */ - function hasBlankLinesBetween(firstToken, secondToken) { - const firstTokenLine = firstToken.loc.end.line; - const secondTokenLine = secondToken.loc.start.line; - - if (firstTokenLine === secondTokenLine || firstTokenLine === secondTokenLine - 1) { - return false; - } - - for (let line = firstTokenLine + 1; line < secondTokenLine; ++line) { - if (!tokenInfo.firstTokensByLineNumber.has(line)) { - return true; - } - } - - return false; - } - - const ignoredNodeFirstTokens = new Set(); - - const baseOffsetListeners = { - "ArrayExpression, ArrayPattern"(node) { - const openingBracket = sourceCode.getFirstToken(node); - const closingBracket = sourceCode.getTokenAfter(lodash__default['default'].findLast(node.elements) || openingBracket, astUtils.isClosingBracketToken); - - addElementListIndent(node.elements, openingBracket, closingBracket, options.ArrayExpression); - }, - - "ObjectExpression, ObjectPattern"(node) { - const openingCurly = sourceCode.getFirstToken(node); - const closingCurly = sourceCode.getTokenAfter( - node.properties.length ? node.properties[node.properties.length - 1] : openingCurly, - astUtils.isClosingBraceToken - ); - - addElementListIndent(node.properties, openingCurly, closingCurly, options.ObjectExpression); - }, - - ArrowFunctionExpression(node) { - const maybeOpeningParen = sourceCode.getFirstToken(node, { skip: node.async ? 1 : 0 }); - - if (astUtils.isOpeningParenToken(maybeOpeningParen)) { - const openingParen = maybeOpeningParen; - const closingParen = sourceCode.getTokenBefore(node.body, astUtils.isClosingParenToken); - - parameterParens.add(openingParen); - parameterParens.add(closingParen); - addElementListIndent(node.params, openingParen, closingParen, options.FunctionExpression.parameters); - } - - addBlocklessNodeIndent(node.body); - }, - - AssignmentExpression(node) { - const operator = sourceCode.getFirstTokenBetween(node.left, node.right, token => token.value === node.operator); - - offsets.setDesiredOffsets([operator.range[0], node.range[1]], sourceCode.getLastToken(node.left), 1); - offsets.ignoreToken(operator); - offsets.ignoreToken(sourceCode.getTokenAfter(operator)); - }, - - "BinaryExpression, LogicalExpression"(node) { - const operator = sourceCode.getFirstTokenBetween(node.left, node.right, token => token.value === node.operator); - - /* - * For backwards compatibility, don't check BinaryExpression indents, e.g. - * var foo = bar && - * baz; - */ - - const tokenAfterOperator = sourceCode.getTokenAfter(operator); - - offsets.ignoreToken(operator); - offsets.ignoreToken(tokenAfterOperator); - offsets.setDesiredOffset(tokenAfterOperator, operator, 0); - }, - - "BlockStatement, ClassBody"(node) { - let blockIndentLevel; - - if (node.parent && isOuterIIFE(node.parent)) { - blockIndentLevel = options.outerIIFEBody; - } else if (node.parent && (node.parent.type === "FunctionExpression" || node.parent.type === "ArrowFunctionExpression")) { - blockIndentLevel = options.FunctionExpression.body; - } else if (node.parent && node.parent.type === "FunctionDeclaration") { - blockIndentLevel = options.FunctionDeclaration.body; - } else { - blockIndentLevel = 1; - } - - /* - * For blocks that aren't lone statements, ensure that the opening curly brace - * is aligned with the parent. - */ - if (!astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type)) { - offsets.setDesiredOffset(sourceCode.getFirstToken(node), sourceCode.getFirstToken(node.parent), 0); - } - - addElementListIndent(node.body, sourceCode.getFirstToken(node), sourceCode.getLastToken(node), blockIndentLevel); - }, - - CallExpression: addFunctionCallIndent, - - "ClassDeclaration[superClass], ClassExpression[superClass]"(node) { - const classToken = sourceCode.getFirstToken(node); - const extendsToken = sourceCode.getTokenBefore(node.superClass, astUtils.isNotOpeningParenToken); - - offsets.setDesiredOffsets([extendsToken.range[0], node.body.range[0]], classToken, 1); - }, - - ConditionalExpression(node) { - const firstToken = sourceCode.getFirstToken(node); - - // `flatTernaryExpressions` option is for the following style: - // var a = - // foo > 0 ? bar : - // foo < 0 ? baz : - // /*else*/ qiz ; - if (!options.flatTernaryExpressions || - !astUtils.isTokenOnSameLine(node.test, node.consequent) || - isOnFirstLineOfStatement(firstToken, node) - ) { - const questionMarkToken = sourceCode.getFirstTokenBetween(node.test, node.consequent, token => token.type === "Punctuator" && token.value === "?"); - const colonToken = sourceCode.getFirstTokenBetween(node.consequent, node.alternate, token => token.type === "Punctuator" && token.value === ":"); - - const firstConsequentToken = sourceCode.getTokenAfter(questionMarkToken); - const lastConsequentToken = sourceCode.getTokenBefore(colonToken); - const firstAlternateToken = sourceCode.getTokenAfter(colonToken); - - offsets.setDesiredOffset(questionMarkToken, firstToken, 1); - offsets.setDesiredOffset(colonToken, firstToken, 1); - - offsets.setDesiredOffset(firstConsequentToken, firstToken, - firstConsequentToken.type === "Punctuator" && - options.offsetTernaryExpressions ? 2 : 1); - - /* - * The alternate and the consequent should usually have the same indentation. - * If they share part of a line, align the alternate against the first token of the consequent. - * This allows the alternate to be indented correctly in cases like this: - * foo ? ( - * bar - * ) : ( // this '(' is aligned with the '(' above, so it's considered to be aligned with `foo` - * baz // as a result, `baz` is offset by 1 rather than 2 - * ) - */ - if (lastConsequentToken.loc.end.line === firstAlternateToken.loc.start.line) { - offsets.setDesiredOffset(firstAlternateToken, firstConsequentToken, 0); - } else { - - /** - * If the alternate and consequent do not share part of a line, offset the alternate from the first - * token of the conditional expression. For example: - * foo ? bar - * : baz - * - * If `baz` were aligned with `bar` rather than being offset by 1 from `foo`, `baz` would end up - * having no expected indentation. - */ - offsets.setDesiredOffset(firstAlternateToken, firstToken, - firstAlternateToken.type === "Punctuator" && - options.offsetTernaryExpressions ? 2 : 1); - } - } - }, - - "DoWhileStatement, WhileStatement, ForInStatement, ForOfStatement": node => addBlocklessNodeIndent(node.body), - - ExportNamedDeclaration(node) { - if (node.declaration === null) { - const closingCurly = sourceCode.getLastToken(node, astUtils.isClosingBraceToken); - - // Indent the specifiers in `export {foo, bar, baz}` - addElementListIndent(node.specifiers, sourceCode.getFirstToken(node, { skip: 1 }), closingCurly, 1); - - if (node.source) { - - // Indent everything after and including the `from` token in `export {foo, bar, baz} from 'qux'` - offsets.setDesiredOffsets([closingCurly.range[1], node.range[1]], sourceCode.getFirstToken(node), 1); - } - } - }, - - ForStatement(node) { - const forOpeningParen = sourceCode.getFirstToken(node, 1); - - if (node.init) { - offsets.setDesiredOffsets(node.init.range, forOpeningParen, 1); - } - if (node.test) { - offsets.setDesiredOffsets(node.test.range, forOpeningParen, 1); - } - if (node.update) { - offsets.setDesiredOffsets(node.update.range, forOpeningParen, 1); - } - addBlocklessNodeIndent(node.body); - }, - - "FunctionDeclaration, FunctionExpression"(node) { - const closingParen = sourceCode.getTokenBefore(node.body); - const openingParen = sourceCode.getTokenBefore(node.params.length ? node.params[0] : closingParen); - - parameterParens.add(openingParen); - parameterParens.add(closingParen); - addElementListIndent(node.params, openingParen, closingParen, options[node.type].parameters); - }, - - IfStatement(node) { - addBlocklessNodeIndent(node.consequent); - if (node.alternate && node.alternate.type !== "IfStatement") { - addBlocklessNodeIndent(node.alternate); - } - }, - - ImportDeclaration(node) { - if (node.specifiers.some(specifier => specifier.type === "ImportSpecifier")) { - const openingCurly = sourceCode.getFirstToken(node, astUtils.isOpeningBraceToken); - const closingCurly = sourceCode.getLastToken(node, astUtils.isClosingBraceToken); - - addElementListIndent(node.specifiers.filter(specifier => specifier.type === "ImportSpecifier"), openingCurly, closingCurly, options.ImportDeclaration); - } - - const fromToken = sourceCode.getLastToken(node, token => token.type === "Identifier" && token.value === "from"); - const sourceToken = sourceCode.getLastToken(node, token => token.type === "String"); - const semiToken = sourceCode.getLastToken(node, token => token.type === "Punctuator" && token.value === ";"); - - if (fromToken) { - const end = semiToken && semiToken.range[1] === sourceToken.range[1] ? node.range[1] : sourceToken.range[1]; - - offsets.setDesiredOffsets([fromToken.range[0], end], sourceCode.getFirstToken(node), 1); - } - }, - - ImportExpression(node) { - const openingParen = sourceCode.getFirstToken(node, 1); - const closingParen = sourceCode.getLastToken(node); - - parameterParens.add(openingParen); - parameterParens.add(closingParen); - offsets.setDesiredOffset(openingParen, sourceCode.getTokenBefore(openingParen), 0); - - addElementListIndent([node.source], openingParen, closingParen, options.CallExpression.arguments); - }, - - "MemberExpression, JSXMemberExpression, MetaProperty"(node) { - const object = node.type === "MetaProperty" ? node.meta : node.object; - const firstNonObjectToken = sourceCode.getFirstTokenBetween(object, node.property, astUtils.isNotClosingParenToken); - const secondNonObjectToken = sourceCode.getTokenAfter(firstNonObjectToken); - - const objectParenCount = sourceCode.getTokensBetween(object, node.property, { filter: astUtils.isClosingParenToken }).length; - const firstObjectToken = objectParenCount - ? sourceCode.getTokenBefore(object, { skip: objectParenCount - 1 }) - : sourceCode.getFirstToken(object); - const lastObjectToken = sourceCode.getTokenBefore(firstNonObjectToken); - const firstPropertyToken = node.computed ? firstNonObjectToken : secondNonObjectToken; - - if (node.computed) { - - // For computed MemberExpressions, match the closing bracket with the opening bracket. - offsets.setDesiredOffset(sourceCode.getLastToken(node), firstNonObjectToken, 0); - offsets.setDesiredOffsets(node.property.range, firstNonObjectToken, 1); - } - - /* - * If the object ends on the same line that the property starts, match against the last token - * of the object, to ensure that the MemberExpression is not indented. - * - * Otherwise, match against the first token of the object, e.g. - * foo - * .bar - * .baz // <-- offset by 1 from `foo` - */ - const offsetBase = lastObjectToken.loc.end.line === firstPropertyToken.loc.start.line - ? lastObjectToken - : firstObjectToken; - - if (typeof options.MemberExpression === "number") { - - // Match the dot (for non-computed properties) or the opening bracket (for computed properties) against the object. - offsets.setDesiredOffset(firstNonObjectToken, offsetBase, options.MemberExpression); - - /* - * For computed MemberExpressions, match the first token of the property against the opening bracket. - * Otherwise, match the first token of the property against the object. - */ - offsets.setDesiredOffset(secondNonObjectToken, node.computed ? firstNonObjectToken : offsetBase, options.MemberExpression); - } else { - - // If the MemberExpression option is off, ignore the dot and the first token of the property. - offsets.ignoreToken(firstNonObjectToken); - offsets.ignoreToken(secondNonObjectToken); - - // To ignore the property indentation, ensure that the property tokens depend on the ignored tokens. - offsets.setDesiredOffset(firstNonObjectToken, offsetBase, 0); - offsets.setDesiredOffset(secondNonObjectToken, firstNonObjectToken, 0); - } - }, - - NewExpression(node) { - - // Only indent the arguments if the NewExpression has parens (e.g. `new Foo(bar)` or `new Foo()`, but not `new Foo` - if (node.arguments.length > 0 || - astUtils.isClosingParenToken(sourceCode.getLastToken(node)) && - astUtils.isOpeningParenToken(sourceCode.getLastToken(node, 1))) { - addFunctionCallIndent(node); - } - }, - - Property(node) { - if (!node.shorthand && !node.method && node.kind === "init") { - const colon = sourceCode.getFirstTokenBetween(node.key, node.value, astUtils.isColonToken); - - offsets.ignoreToken(sourceCode.getTokenAfter(colon)); - } - }, - - SwitchStatement(node) { - const openingCurly = sourceCode.getTokenAfter(node.discriminant, astUtils.isOpeningBraceToken); - const closingCurly = sourceCode.getLastToken(node); - - offsets.setDesiredOffsets([openingCurly.range[1], closingCurly.range[0]], openingCurly, options.SwitchCase); - - if (node.cases.length) { - sourceCode.getTokensBetween( - node.cases[node.cases.length - 1], - closingCurly, - { includeComments: true, filter: astUtils.isCommentToken } - ).forEach(token => offsets.ignoreToken(token)); - } - }, - - SwitchCase(node) { - if (!(node.consequent.length === 1 && node.consequent[0].type === "BlockStatement")) { - const caseKeyword = sourceCode.getFirstToken(node); - const tokenAfterCurrentCase = sourceCode.getTokenAfter(node); - - offsets.setDesiredOffsets([caseKeyword.range[1], tokenAfterCurrentCase.range[0]], caseKeyword, 1); - } - }, - - TemplateLiteral(node) { - node.expressions.forEach((expression, index) => { - const previousQuasi = node.quasis[index]; - const nextQuasi = node.quasis[index + 1]; - const tokenToAlignFrom = previousQuasi.loc.start.line === previousQuasi.loc.end.line - ? sourceCode.getFirstToken(previousQuasi) - : null; - - offsets.setDesiredOffsets([previousQuasi.range[1], nextQuasi.range[0]], tokenToAlignFrom, 1); - offsets.setDesiredOffset(sourceCode.getFirstToken(nextQuasi), tokenToAlignFrom, 0); - }); - }, - - VariableDeclaration(node) { - let variableIndent = Object.prototype.hasOwnProperty.call(options.VariableDeclarator, node.kind) - ? options.VariableDeclarator[node.kind] - : DEFAULT_VARIABLE_INDENT; - - const firstToken = sourceCode.getFirstToken(node), - lastToken = sourceCode.getLastToken(node); - - if (options.VariableDeclarator[node.kind] === "first") { - if (node.declarations.length > 1) { - addElementListIndent( - node.declarations, - firstToken, - lastToken, - "first" - ); - return; - } - - variableIndent = DEFAULT_VARIABLE_INDENT; - } - - if (node.declarations[node.declarations.length - 1].loc.start.line > node.loc.start.line) { - - /* - * VariableDeclarator indentation is a bit different from other forms of indentation, in that the - * indentation of an opening bracket sometimes won't match that of a closing bracket. For example, - * the following indentations are correct: - * - * var foo = { - * ok: true - * }; - * - * var foo = { - * ok: true, - * }, - * bar = 1; - * - * Account for when exiting the AST (after indentations have already been set for the nodes in - * the declaration) by manually increasing the indentation level of the tokens in this declarator - * on the same line as the start of the declaration, provided that there are declarators that - * follow this one. - */ - offsets.setDesiredOffsets(node.range, firstToken, variableIndent, true); - } else { - offsets.setDesiredOffsets(node.range, firstToken, variableIndent); - } - - if (astUtils.isSemicolonToken(lastToken)) { - offsets.ignoreToken(lastToken); - } - }, - - VariableDeclarator(node) { - if (node.init) { - const equalOperator = sourceCode.getTokenBefore(node.init, astUtils.isNotOpeningParenToken); - const tokenAfterOperator = sourceCode.getTokenAfter(equalOperator); - - offsets.ignoreToken(equalOperator); - offsets.ignoreToken(tokenAfterOperator); - offsets.setDesiredOffsets([tokenAfterOperator.range[0], node.range[1]], equalOperator, 1); - offsets.setDesiredOffset(equalOperator, sourceCode.getLastToken(node.id), 0); - } - }, - - "JSXAttribute[value]"(node) { - const equalsToken = sourceCode.getFirstTokenBetween(node.name, node.value, token => token.type === "Punctuator" && token.value === "="); - - offsets.setDesiredOffsets([equalsToken.range[0], node.value.range[1]], sourceCode.getFirstToken(node.name), 1); - }, - - JSXElement(node) { - if (node.closingElement) { - addElementListIndent(node.children, sourceCode.getFirstToken(node.openingElement), sourceCode.getFirstToken(node.closingElement), 1); - } - }, - - JSXOpeningElement(node) { - const firstToken = sourceCode.getFirstToken(node); - let closingToken; - - if (node.selfClosing) { - closingToken = sourceCode.getLastToken(node, { skip: 1 }); - offsets.setDesiredOffset(sourceCode.getLastToken(node), closingToken, 0); - } else { - closingToken = sourceCode.getLastToken(node); - } - offsets.setDesiredOffsets(node.name.range, sourceCode.getFirstToken(node)); - addElementListIndent(node.attributes, firstToken, closingToken, 1); - }, - - JSXClosingElement(node) { - const firstToken = sourceCode.getFirstToken(node); - - offsets.setDesiredOffsets(node.name.range, firstToken, 1); - }, - - JSXFragment(node) { - const firstOpeningToken = sourceCode.getFirstToken(node.openingFragment); - const firstClosingToken = sourceCode.getFirstToken(node.closingFragment); - - addElementListIndent(node.children, firstOpeningToken, firstClosingToken, 1); - }, - - JSXOpeningFragment(node) { - const firstToken = sourceCode.getFirstToken(node); - const closingToken = sourceCode.getLastToken(node); - - offsets.setDesiredOffsets(node.range, firstToken, 1); - offsets.matchOffsetOf(firstToken, closingToken); - }, - - JSXClosingFragment(node) { - const firstToken = sourceCode.getFirstToken(node); - const slashToken = sourceCode.getLastToken(node, { skip: 1 }); - const closingToken = sourceCode.getLastToken(node); - const tokenToMatch = astUtils.isTokenOnSameLine(slashToken, closingToken) ? slashToken : closingToken; - - offsets.setDesiredOffsets(node.range, firstToken, 1); - offsets.matchOffsetOf(firstToken, tokenToMatch); - }, - - JSXExpressionContainer(node) { - const openingCurly = sourceCode.getFirstToken(node); - const closingCurly = sourceCode.getLastToken(node); - - offsets.setDesiredOffsets( - [openingCurly.range[1], closingCurly.range[0]], - openingCurly, - 1 - ); - }, - - JSXSpreadAttribute(node) { - const openingCurly = sourceCode.getFirstToken(node); - const closingCurly = sourceCode.getLastToken(node); - - offsets.setDesiredOffsets( - [openingCurly.range[1], closingCurly.range[0]], - openingCurly, - 1 - ); - }, - - "*"(node) { - const firstToken = sourceCode.getFirstToken(node); - - // Ensure that the children of every node are indented at least as much as the first token. - if (firstToken && !ignoredNodeFirstTokens.has(firstToken)) { - offsets.setDesiredOffsets(node.range, firstToken, 0); - } - } - }; - - const listenerCallQueue = []; - - /* - * To ignore the indentation of a node: - * 1. Don't call the node's listener when entering it (if it has a listener) - * 2. Don't set any offsets against the first token of the node. - * 3. Call `ignoreNode` on the node sometime after exiting it and before validating offsets. - */ - const offsetListeners = lodash__default['default'].mapValues( - baseOffsetListeners, - - /* - * Offset listener calls are deferred until traversal is finished, and are called as - * part of the final `Program:exit` listener. This is necessary because a node might - * be matched by multiple selectors. - * - * Example: Suppose there is an offset listener for `Identifier`, and the user has - * specified in configuration that `MemberExpression > Identifier` should be ignored. - * Due to selector specificity rules, the `Identifier` listener will get called first. However, - * if a given Identifier node is supposed to be ignored, then the `Identifier` offset listener - * should not have been called at all. Without doing extra selector matching, we don't know - * whether the Identifier matches the `MemberExpression > Identifier` selector until the - * `MemberExpression > Identifier` listener is called. - * - * To avoid this, the `Identifier` listener isn't called until traversal finishes and all - * ignored nodes are known. - */ - listener => - node => - listenerCallQueue.push({ listener, node }) - ); - - // For each ignored node selector, set up a listener to collect it into the `ignoredNodes` set. - const ignoredNodes = new Set(); - - /** - * Ignores a node - * @param {ASTNode} node The node to ignore - * @returns {void} - */ - function addToIgnoredNodes(node) { - ignoredNodes.add(node); - ignoredNodeFirstTokens.add(sourceCode.getFirstToken(node)); - } - - const ignoredNodeListeners = options.ignoredNodes.reduce( - (listeners, ignoredSelector) => Object.assign(listeners, { [ignoredSelector]: addToIgnoredNodes }), - {} - ); - - /* - * Join the listeners, and add a listener to verify that all tokens actually have the correct indentation - * at the end. - * - * Using Object.assign will cause some offset listeners to be overwritten if the same selector also appears - * in `ignoredNodeListeners`. This isn't a problem because all of the matching nodes will be ignored, - * so those listeners wouldn't be called anyway. - */ - return Object.assign( - offsetListeners, - ignoredNodeListeners, - { - "*:exit"(node) { - - // If a node's type is nonstandard, we can't tell how its children should be offset, so ignore it. - if (!KNOWN_NODES.has(node.type)) { - addToIgnoredNodes(node); - } - }, - "Program:exit"() { - - // If ignoreComments option is enabled, ignore all comment tokens. - if (options.ignoreComments) { - sourceCode.getAllComments() - .forEach(comment => offsets.ignoreToken(comment)); - } - - // Invoke the queued offset listeners for the nodes that aren't ignored. - listenerCallQueue - .filter(nodeInfo => !ignoredNodes.has(nodeInfo.node)) - .forEach(nodeInfo => nodeInfo.listener(nodeInfo.node)); - - // Update the offsets for ignored nodes to prevent their child tokens from being reported. - ignoredNodes.forEach(ignoreNode); - - addParensIndent(sourceCode.ast.tokens); - - /* - * Create a Map from (tokenOrComment) => (precedingToken). - * This is necessary because sourceCode.getTokenBefore does not handle a comment as an argument correctly. - */ - const precedingTokens = sourceCode.ast.comments.reduce((commentMap, comment) => { - const tokenOrCommentBefore = sourceCode.getTokenBefore(comment, { includeComments: true }); - - return commentMap.set(comment, commentMap.has(tokenOrCommentBefore) ? commentMap.get(tokenOrCommentBefore) : tokenOrCommentBefore); - }, new WeakMap()); - - sourceCode.lines.forEach((line, lineIndex) => { - const lineNumber = lineIndex + 1; - - if (!tokenInfo.firstTokensByLineNumber.has(lineNumber)) { - - // Don't check indentation on blank lines - return; - } - - const firstTokenOfLine = tokenInfo.firstTokensByLineNumber.get(lineNumber); - - if (firstTokenOfLine.loc.start.line !== lineNumber) { - - // Don't check the indentation of multi-line tokens (e.g. template literals or block comments) twice. - return; - } - - if (astUtils.isCommentToken(firstTokenOfLine)) { - const tokenBefore = precedingTokens.get(firstTokenOfLine); - const tokenAfter = tokenBefore ? sourceCode.getTokenAfter(tokenBefore) : sourceCode.ast.tokens[0]; - const mayAlignWithBefore = tokenBefore && !hasBlankLinesBetween(tokenBefore, firstTokenOfLine); - const mayAlignWithAfter = tokenAfter && !hasBlankLinesBetween(firstTokenOfLine, tokenAfter); - - /* - * If a comment precedes a line that begins with a semicolon token, align to that token, i.e. - * - * let foo - * // comment - * ;(async () => {})() - */ - if (tokenAfter && astUtils.isSemicolonToken(tokenAfter) && !astUtils.isTokenOnSameLine(firstTokenOfLine, tokenAfter)) { - offsets.setDesiredOffset(firstTokenOfLine, tokenAfter, 0); - } - - // If a comment matches the expected indentation of the token immediately before or after, don't report it. - if ( - mayAlignWithBefore && validateTokenIndent(firstTokenOfLine, offsets.getDesiredIndent(tokenBefore)) || - mayAlignWithAfter && validateTokenIndent(firstTokenOfLine, offsets.getDesiredIndent(tokenAfter)) - ) { - return; - } - } - - // If the token matches the expected indentation, don't report it. - if (validateTokenIndent(firstTokenOfLine, offsets.getDesiredIndent(firstTokenOfLine))) { - return; - } - - // Otherwise, report the token/comment. - report(firstTokenOfLine, offsets.getDesiredIndent(firstTokenOfLine)); - }); - } - } - ); - } -}; - -/** - * @fileoverview This option sets a specific tab width for your code - * - * This rule has been ported and modified from nodeca. - * @author Vitaly Puzrin - * @author Gyandeep Singh - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -/* istanbul ignore next: this rule has known coverage issues, but it's deprecated and shouldn't be updated in the future anyway. */ -var indentLegacy = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent indentation", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/indent-legacy" - }, - - deprecated: true, - - replacedBy: ["indent"], - - fixable: "whitespace", - - schema: [ - { - oneOf: [ - { - enum: ["tab"] - }, - { - type: "integer", - minimum: 0 - } - ] - }, - { - type: "object", - properties: { - SwitchCase: { - type: "integer", - minimum: 0 - }, - VariableDeclarator: { - oneOf: [ - { - type: "integer", - minimum: 0 - }, - { - type: "object", - properties: { - var: { - type: "integer", - minimum: 0 - }, - let: { - type: "integer", - minimum: 0 - }, - const: { - type: "integer", - minimum: 0 - } - } - } - ] - }, - outerIIFEBody: { - type: "integer", - minimum: 0 - }, - MemberExpression: { - type: "integer", - minimum: 0 - }, - FunctionDeclaration: { - type: "object", - properties: { - parameters: { - oneOf: [ - { - type: "integer", - minimum: 0 - }, - { - enum: ["first"] - } - ] - }, - body: { - type: "integer", - minimum: 0 - } - } - }, - FunctionExpression: { - type: "object", - properties: { - parameters: { - oneOf: [ - { - type: "integer", - minimum: 0 - }, - { - enum: ["first"] - } - ] - }, - body: { - type: "integer", - minimum: 0 - } - } - }, - CallExpression: { - type: "object", - properties: { - parameters: { - oneOf: [ - { - type: "integer", - minimum: 0 - }, - { - enum: ["first"] - } - ] - } - } - }, - ArrayExpression: { - oneOf: [ - { - type: "integer", - minimum: 0 - }, - { - enum: ["first"] - } - ] - }, - ObjectExpression: { - oneOf: [ - { - type: "integer", - minimum: 0 - }, - { - enum: ["first"] - } - ] - } - }, - additionalProperties: false - } - ], - messages: { - expected: "Expected indentation of {{expected}} but found {{actual}}." - } - }, - - create(context) { - const DEFAULT_VARIABLE_INDENT = 1; - const DEFAULT_PARAMETER_INDENT = null; // For backwards compatibility, don't check parameter indentation unless specified in the config - const DEFAULT_FUNCTION_BODY_INDENT = 1; - - let indentType = "space"; - let indentSize = 4; - const options = { - SwitchCase: 0, - VariableDeclarator: { - var: DEFAULT_VARIABLE_INDENT, - let: DEFAULT_VARIABLE_INDENT, - const: DEFAULT_VARIABLE_INDENT - }, - outerIIFEBody: null, - FunctionDeclaration: { - parameters: DEFAULT_PARAMETER_INDENT, - body: DEFAULT_FUNCTION_BODY_INDENT - }, - FunctionExpression: { - parameters: DEFAULT_PARAMETER_INDENT, - body: DEFAULT_FUNCTION_BODY_INDENT - }, - CallExpression: { - arguments: DEFAULT_PARAMETER_INDENT - }, - ArrayExpression: 1, - ObjectExpression: 1 - }; - - const sourceCode = context.getSourceCode(); - - if (context.options.length) { - if (context.options[0] === "tab") { - indentSize = 1; - indentType = "tab"; - } else /* istanbul ignore else : this will be caught by options validation */ if (typeof context.options[0] === "number") { - indentSize = context.options[0]; - indentType = "space"; - } - - if (context.options[1]) { - const opts = context.options[1]; - - options.SwitchCase = opts.SwitchCase || 0; - const variableDeclaratorRules = opts.VariableDeclarator; - - if (typeof variableDeclaratorRules === "number") { - options.VariableDeclarator = { - var: variableDeclaratorRules, - let: variableDeclaratorRules, - const: variableDeclaratorRules - }; - } else if (typeof variableDeclaratorRules === "object") { - Object.assign(options.VariableDeclarator, variableDeclaratorRules); - } - - if (typeof opts.outerIIFEBody === "number") { - options.outerIIFEBody = opts.outerIIFEBody; - } - - if (typeof opts.MemberExpression === "number") { - options.MemberExpression = opts.MemberExpression; - } - - if (typeof opts.FunctionDeclaration === "object") { - Object.assign(options.FunctionDeclaration, opts.FunctionDeclaration); - } - - if (typeof opts.FunctionExpression === "object") { - Object.assign(options.FunctionExpression, opts.FunctionExpression); - } - - if (typeof opts.CallExpression === "object") { - Object.assign(options.CallExpression, opts.CallExpression); - } - - if (typeof opts.ArrayExpression === "number" || typeof opts.ArrayExpression === "string") { - options.ArrayExpression = opts.ArrayExpression; - } - - if (typeof opts.ObjectExpression === "number" || typeof opts.ObjectExpression === "string") { - options.ObjectExpression = opts.ObjectExpression; - } - } - } - - const caseIndentStore = {}; - - /** - * Creates an error message for a line, given the expected/actual indentation. - * @param {int} expectedAmount The expected amount of indentation characters for this line - * @param {int} actualSpaces The actual number of indentation spaces that were found on this line - * @param {int} actualTabs The actual number of indentation tabs that were found on this line - * @returns {string} An error message for this line - */ - function createErrorMessageData(expectedAmount, actualSpaces, actualTabs) { - const expectedStatement = `${expectedAmount} ${indentType}${expectedAmount === 1 ? "" : "s"}`; // e.g. "2 tabs" - const foundSpacesWord = `space${actualSpaces === 1 ? "" : "s"}`; // e.g. "space" - const foundTabsWord = `tab${actualTabs === 1 ? "" : "s"}`; // e.g. "tabs" - let foundStatement; - - if (actualSpaces > 0 && actualTabs > 0) { - foundStatement = `${actualSpaces} ${foundSpacesWord} and ${actualTabs} ${foundTabsWord}`; // e.g. "1 space and 2 tabs" - } else if (actualSpaces > 0) { - - /* - * Abbreviate the message if the expected indentation is also spaces. - * e.g. 'Expected 4 spaces but found 2' rather than 'Expected 4 spaces but found 2 spaces' - */ - foundStatement = indentType === "space" ? actualSpaces : `${actualSpaces} ${foundSpacesWord}`; - } else if (actualTabs > 0) { - foundStatement = indentType === "tab" ? actualTabs : `${actualTabs} ${foundTabsWord}`; - } else { - foundStatement = "0"; - } - return { - expected: expectedStatement, - actual: foundStatement - }; - } - - /** - * Reports a given indent violation - * @param {ASTNode} node Node violating the indent rule - * @param {int} needed Expected indentation character count - * @param {int} gottenSpaces Indentation space count in the actual node/code - * @param {int} gottenTabs Indentation tab count in the actual node/code - * @param {Object} [loc] Error line and column location - * @param {boolean} isLastNodeCheck Is the error for last node check - * @returns {void} - */ - function report(node, needed, gottenSpaces, gottenTabs, loc, isLastNodeCheck) { - if (gottenSpaces && gottenTabs) { - - // To avoid conflicts with `no-mixed-spaces-and-tabs`, don't report lines that have both spaces and tabs. - return; - } - - const desiredIndent = (indentType === "space" ? " " : "\t").repeat(needed); - - const textRange = isLastNodeCheck - ? [node.range[1] - node.loc.end.column, node.range[1] - node.loc.end.column + gottenSpaces + gottenTabs] - : [node.range[0] - node.loc.start.column, node.range[0] - node.loc.start.column + gottenSpaces + gottenTabs]; - - context.report({ - node, - loc, - messageId: "expected", - data: createErrorMessageData(needed, gottenSpaces, gottenTabs), - fix: fixer => fixer.replaceTextRange(textRange, desiredIndent) - }); - } - - /** - * Get the actual indent of node - * @param {ASTNode|Token} node Node to examine - * @param {boolean} [byLastLine=false] get indent of node's last line - * @returns {Object} The node's indent. Contains keys `space` and `tab`, representing the indent of each character. Also - * contains keys `goodChar` and `badChar`, where `goodChar` is the amount of the user's desired indentation character, and - * `badChar` is the amount of the other indentation character. - */ - function getNodeIndent(node, byLastLine) { - const token = byLastLine ? sourceCode.getLastToken(node) : sourceCode.getFirstToken(node); - const srcCharsBeforeNode = sourceCode.getText(token, token.loc.start.column).split(""); - const indentChars = srcCharsBeforeNode.slice(0, srcCharsBeforeNode.findIndex(char => char !== " " && char !== "\t")); - const spaces = indentChars.filter(char => char === " ").length; - const tabs = indentChars.filter(char => char === "\t").length; - - return { - space: spaces, - tab: tabs, - goodChar: indentType === "space" ? spaces : tabs, - badChar: indentType === "space" ? tabs : spaces - }; - } - - /** - * Checks node is the first in its own start line. By default it looks by start line. - * @param {ASTNode} node The node to check - * @param {boolean} [byEndLocation=false] Lookup based on start position or end - * @returns {boolean} true if its the first in the its start line - */ - function isNodeFirstInLine(node, byEndLocation) { - const firstToken = byEndLocation === true ? sourceCode.getLastToken(node, 1) : sourceCode.getTokenBefore(node), - startLine = byEndLocation === true ? node.loc.end.line : node.loc.start.line, - endLine = firstToken ? firstToken.loc.end.line : -1; - - return startLine !== endLine; - } - - /** - * Check indent for node - * @param {ASTNode} node Node to check - * @param {int} neededIndent needed indent - * @returns {void} - */ - function checkNodeIndent(node, neededIndent) { - const actualIndent = getNodeIndent(node, false); - - if ( - node.type !== "ArrayExpression" && - node.type !== "ObjectExpression" && - (actualIndent.goodChar !== neededIndent || actualIndent.badChar !== 0) && - isNodeFirstInLine(node) - ) { - report(node, neededIndent, actualIndent.space, actualIndent.tab); - } - - if (node.type === "IfStatement" && node.alternate) { - const elseToken = sourceCode.getTokenBefore(node.alternate); - - checkNodeIndent(elseToken, neededIndent); - - if (!isNodeFirstInLine(node.alternate)) { - checkNodeIndent(node.alternate, neededIndent); - } - } - - if (node.type === "TryStatement" && node.handler) { - const catchToken = sourceCode.getFirstToken(node.handler); - - checkNodeIndent(catchToken, neededIndent); - } - - if (node.type === "TryStatement" && node.finalizer) { - const finallyToken = sourceCode.getTokenBefore(node.finalizer); - - checkNodeIndent(finallyToken, neededIndent); - } - - if (node.type === "DoWhileStatement") { - const whileToken = sourceCode.getTokenAfter(node.body); - - checkNodeIndent(whileToken, neededIndent); - } - } - - /** - * Check indent for nodes list - * @param {ASTNode[]} nodes list of node objects - * @param {int} indent needed indent - * @returns {void} - */ - function checkNodesIndent(nodes, indent) { - nodes.forEach(node => checkNodeIndent(node, indent)); - } - - /** - * Check last node line indent this detects, that block closed correctly - * @param {ASTNode} node Node to examine - * @param {int} lastLineIndent needed indent - * @returns {void} - */ - function checkLastNodeLineIndent(node, lastLineIndent) { - const lastToken = sourceCode.getLastToken(node); - const endIndent = getNodeIndent(lastToken, true); - - if ((endIndent.goodChar !== lastLineIndent || endIndent.badChar !== 0) && isNodeFirstInLine(node, true)) { - report( - node, - lastLineIndent, - endIndent.space, - endIndent.tab, - { line: lastToken.loc.start.line, column: lastToken.loc.start.column }, - true - ); - } - } - - /** - * Check last node line indent this detects, that block closed correctly - * This function for more complicated return statement case, where closing parenthesis may be followed by ';' - * @param {ASTNode} node Node to examine - * @param {int} firstLineIndent first line needed indent - * @returns {void} - */ - function checkLastReturnStatementLineIndent(node, firstLineIndent) { - - /* - * in case if return statement ends with ');' we have traverse back to ')' - * otherwise we'll measure indent for ';' and replace ')' - */ - const lastToken = sourceCode.getLastToken(node, astUtils.isClosingParenToken); - const textBeforeClosingParenthesis = sourceCode.getText(lastToken, lastToken.loc.start.column).slice(0, -1); - - if (textBeforeClosingParenthesis.trim()) { - - // There are tokens before the closing paren, don't report this case - return; - } - - const endIndent = getNodeIndent(lastToken, true); - - if (endIndent.goodChar !== firstLineIndent) { - report( - node, - firstLineIndent, - endIndent.space, - endIndent.tab, - { line: lastToken.loc.start.line, column: lastToken.loc.start.column }, - true - ); - } - } - - /** - * Check first node line indent is correct - * @param {ASTNode} node Node to examine - * @param {int} firstLineIndent needed indent - * @returns {void} - */ - function checkFirstNodeLineIndent(node, firstLineIndent) { - const startIndent = getNodeIndent(node, false); - - if ((startIndent.goodChar !== firstLineIndent || startIndent.badChar !== 0) && isNodeFirstInLine(node)) { - report( - node, - firstLineIndent, - startIndent.space, - startIndent.tab, - { line: node.loc.start.line, column: node.loc.start.column } - ); - } - } - - /** - * Returns a parent node of given node based on a specified type - * if not present then return null - * @param {ASTNode} node node to examine - * @param {string} type type that is being looked for - * @param {string} stopAtList end points for the evaluating code - * @returns {ASTNode|void} if found then node otherwise null - */ - function getParentNodeByType(node, type, stopAtList) { - let parent = node.parent; - const stopAtSet = new Set(stopAtList || ["Program"]); - - while (parent.type !== type && !stopAtSet.has(parent.type) && parent.type !== "Program") { - parent = parent.parent; - } - - return parent.type === type ? parent : null; - } - - /** - * Returns the VariableDeclarator based on the current node - * if not present then return null - * @param {ASTNode} node node to examine - * @returns {ASTNode|void} if found then node otherwise null - */ - function getVariableDeclaratorNode(node) { - return getParentNodeByType(node, "VariableDeclarator"); - } - - /** - * Check to see if the node is part of the multi-line variable declaration. - * Also if its on the same line as the varNode - * @param {ASTNode} node node to check - * @param {ASTNode} varNode variable declaration node to check against - * @returns {boolean} True if all the above condition satisfy - */ - function isNodeInVarOnTop(node, varNode) { - return varNode && - varNode.parent.loc.start.line === node.loc.start.line && - varNode.parent.declarations.length > 1; - } - - /** - * Check to see if the argument before the callee node is multi-line and - * there should only be 1 argument before the callee node - * @param {ASTNode} node node to check - * @returns {boolean} True if arguments are multi-line - */ - function isArgBeforeCalleeNodeMultiline(node) { - const parent = node.parent; - - if (parent.arguments.length >= 2 && parent.arguments[1] === node) { - return parent.arguments[0].loc.end.line > parent.arguments[0].loc.start.line; - } - - return false; - } - - /** - * Check to see if the node is a file level IIFE - * @param {ASTNode} node The function node to check. - * @returns {boolean} True if the node is the outer IIFE - */ - function isOuterIIFE(node) { - const parent = node.parent; - let stmt = parent.parent; - - /* - * Verify that the node is an IIEF - */ - if ( - parent.type !== "CallExpression" || - parent.callee !== node) { - - return false; - } - - /* - * Navigate legal ancestors to determine whether this IIEF is outer - */ - while ( - stmt.type === "UnaryExpression" && ( - stmt.operator === "!" || - stmt.operator === "~" || - stmt.operator === "+" || - stmt.operator === "-") || - stmt.type === "AssignmentExpression" || - stmt.type === "LogicalExpression" || - stmt.type === "SequenceExpression" || - stmt.type === "VariableDeclarator") { - - stmt = stmt.parent; - } - - return (( - stmt.type === "ExpressionStatement" || - stmt.type === "VariableDeclaration") && - stmt.parent && stmt.parent.type === "Program" - ); - } - - /** - * Check indent for function block content - * @param {ASTNode} node A BlockStatement node that is inside of a function. - * @returns {void} - */ - function checkIndentInFunctionBlock(node) { - - /* - * Search first caller in chain. - * Ex.: - * - * Models <- Identifier - * .User - * .find() - * .exec(function() { - * // function body - * }); - * - * Looks for 'Models' - */ - const calleeNode = node.parent; // FunctionExpression - let indent; - - if (calleeNode.parent && - (calleeNode.parent.type === "Property" || - calleeNode.parent.type === "ArrayExpression")) { - - // If function is part of array or object, comma can be put at left - indent = getNodeIndent(calleeNode, false).goodChar; - } else { - - // If function is standalone, simple calculate indent - indent = getNodeIndent(calleeNode).goodChar; - } - - if (calleeNode.parent.type === "CallExpression") { - const calleeParent = calleeNode.parent; - - if (calleeNode.type !== "FunctionExpression" && calleeNode.type !== "ArrowFunctionExpression") { - if (calleeParent && calleeParent.loc.start.line < node.loc.start.line) { - indent = getNodeIndent(calleeParent).goodChar; - } - } else { - if (isArgBeforeCalleeNodeMultiline(calleeNode) && - calleeParent.callee.loc.start.line === calleeParent.callee.loc.end.line && - !isNodeFirstInLine(calleeNode)) { - indent = getNodeIndent(calleeParent).goodChar; - } - } - } - - /* - * function body indent should be indent + indent size, unless this - * is a FunctionDeclaration, FunctionExpression, or outer IIFE and the corresponding options are enabled. - */ - let functionOffset = indentSize; - - if (options.outerIIFEBody !== null && isOuterIIFE(calleeNode)) { - functionOffset = options.outerIIFEBody * indentSize; - } else if (calleeNode.type === "FunctionExpression") { - functionOffset = options.FunctionExpression.body * indentSize; - } else if (calleeNode.type === "FunctionDeclaration") { - functionOffset = options.FunctionDeclaration.body * indentSize; - } - indent += functionOffset; - - // check if the node is inside a variable - const parentVarNode = getVariableDeclaratorNode(node); - - if (parentVarNode && isNodeInVarOnTop(node, parentVarNode)) { - indent += indentSize * options.VariableDeclarator[parentVarNode.parent.kind]; - } - - if (node.body.length > 0) { - checkNodesIndent(node.body, indent); - } - - checkLastNodeLineIndent(node, indent - functionOffset); - } - - - /** - * Checks if the given node starts and ends on the same line - * @param {ASTNode} node The node to check - * @returns {boolean} Whether or not the block starts and ends on the same line. - */ - function isSingleLineNode(node) { - const lastToken = sourceCode.getLastToken(node), - startLine = node.loc.start.line, - endLine = lastToken.loc.end.line; - - return startLine === endLine; - } - - /** - * Check indent for array block content or object block content - * @param {ASTNode} node node to examine - * @returns {void} - */ - function checkIndentInArrayOrObjectBlock(node) { - - // Skip inline - if (isSingleLineNode(node)) { - return; - } - - let elements = (node.type === "ArrayExpression") ? node.elements : node.properties; - - // filter out empty elements example would be [ , 2] so remove first element as espree considers it as null - elements = elements.filter(elem => elem !== null); - - let nodeIndent; - let elementsIndent; - const parentVarNode = getVariableDeclaratorNode(node); - - // TODO - come up with a better strategy in future - if (isNodeFirstInLine(node)) { - const parent = node.parent; - - nodeIndent = getNodeIndent(parent).goodChar; - if (!parentVarNode || parentVarNode.loc.start.line !== node.loc.start.line) { - if (parent.type !== "VariableDeclarator" || parentVarNode === parentVarNode.parent.declarations[0]) { - if (parent.type === "VariableDeclarator" && parentVarNode.loc.start.line === parent.loc.start.line) { - nodeIndent += (indentSize * options.VariableDeclarator[parentVarNode.parent.kind]); - } else if (parent.type === "ObjectExpression" || parent.type === "ArrayExpression") { - const parentElements = node.parent.type === "ObjectExpression" ? node.parent.properties : node.parent.elements; - - if (parentElements[0] && - parentElements[0].loc.start.line === parent.loc.start.line && - parentElements[0].loc.end.line !== parent.loc.start.line) ; else if (typeof options[parent.type] === "number") { - nodeIndent += options[parent.type] * indentSize; - } else { - nodeIndent = parentElements[0].loc.start.column; - } - } else if (parent.type === "CallExpression" || parent.type === "NewExpression") { - if (typeof options.CallExpression.arguments === "number") { - nodeIndent += options.CallExpression.arguments * indentSize; - } else if (options.CallExpression.arguments === "first") { - if (parent.arguments.indexOf(node) !== -1) { - nodeIndent = parent.arguments[0].loc.start.column; - } - } else { - nodeIndent += indentSize; - } - } else if (parent.type === "LogicalExpression" || parent.type === "ArrowFunctionExpression") { - nodeIndent += indentSize; - } - } - } - - checkFirstNodeLineIndent(node, nodeIndent); - } else { - nodeIndent = getNodeIndent(node).goodChar; - } - - if (options[node.type] === "first") { - elementsIndent = elements.length ? elements[0].loc.start.column : 0; // If there are no elements, elementsIndent doesn't matter. - } else { - elementsIndent = nodeIndent + indentSize * options[node.type]; - } - - /* - * Check if the node is a multiple variable declaration; if so, then - * make sure indentation takes that into account. - */ - if (isNodeInVarOnTop(node, parentVarNode)) { - elementsIndent += indentSize * options.VariableDeclarator[parentVarNode.parent.kind]; - } - - checkNodesIndent(elements, elementsIndent); - - if (elements.length > 0) { - - // Skip last block line check if last item in same line - if (elements[elements.length - 1].loc.end.line === node.loc.end.line) { - return; - } - } - - checkLastNodeLineIndent(node, nodeIndent + - (isNodeInVarOnTop(node, parentVarNode) ? options.VariableDeclarator[parentVarNode.parent.kind] * indentSize : 0)); - } - - /** - * Check if the node or node body is a BlockStatement or not - * @param {ASTNode} node node to test - * @returns {boolean} True if it or its body is a block statement - */ - function isNodeBodyBlock(node) { - return node.type === "BlockStatement" || node.type === "ClassBody" || (node.body && node.body.type === "BlockStatement") || - (node.consequent && node.consequent.type === "BlockStatement"); - } - - /** - * Check indentation for blocks - * @param {ASTNode} node node to check - * @returns {void} - */ - function blockIndentationCheck(node) { - - // Skip inline blocks - if (isSingleLineNode(node)) { - return; - } - - if (node.parent && ( - node.parent.type === "FunctionExpression" || - node.parent.type === "FunctionDeclaration" || - node.parent.type === "ArrowFunctionExpression") - ) { - checkIndentInFunctionBlock(node); - return; - } - - let indent; - let nodesToCheck = []; - - /* - * For this statements we should check indent from statement beginning, - * not from the beginning of the block. - */ - const statementsWithProperties = [ - "IfStatement", "WhileStatement", "ForStatement", "ForInStatement", "ForOfStatement", "DoWhileStatement", "ClassDeclaration", "TryStatement" - ]; - - if (node.parent && statementsWithProperties.indexOf(node.parent.type) !== -1 && isNodeBodyBlock(node)) { - indent = getNodeIndent(node.parent).goodChar; - } else if (node.parent && node.parent.type === "CatchClause") { - indent = getNodeIndent(node.parent.parent).goodChar; - } else { - indent = getNodeIndent(node).goodChar; - } - - if (node.type === "IfStatement" && node.consequent.type !== "BlockStatement") { - nodesToCheck = [node.consequent]; - } else if (Array.isArray(node.body)) { - nodesToCheck = node.body; - } else { - nodesToCheck = [node.body]; - } - - if (nodesToCheck.length > 0) { - checkNodesIndent(nodesToCheck, indent + indentSize); - } - - if (node.type === "BlockStatement") { - checkLastNodeLineIndent(node, indent); - } - } - - /** - * Filter out the elements which are on the same line of each other or the node. - * basically have only 1 elements from each line except the variable declaration line. - * @param {ASTNode} node Variable declaration node - * @returns {ASTNode[]} Filtered elements - */ - function filterOutSameLineVars(node) { - return node.declarations.reduce((finalCollection, elem) => { - const lastElem = finalCollection[finalCollection.length - 1]; - - if ((elem.loc.start.line !== node.loc.start.line && !lastElem) || - (lastElem && lastElem.loc.start.line !== elem.loc.start.line)) { - finalCollection.push(elem); - } - - return finalCollection; - }, []); - } - - /** - * Check indentation for variable declarations - * @param {ASTNode} node node to examine - * @returns {void} - */ - function checkIndentInVariableDeclarations(node) { - const elements = filterOutSameLineVars(node); - const nodeIndent = getNodeIndent(node).goodChar; - const lastElement = elements[elements.length - 1]; - - const elementsIndent = nodeIndent + indentSize * options.VariableDeclarator[node.kind]; - - checkNodesIndent(elements, elementsIndent); - - // Only check the last line if there is any token after the last item - if (sourceCode.getLastToken(node).loc.end.line <= lastElement.loc.end.line) { - return; - } - - const tokenBeforeLastElement = sourceCode.getTokenBefore(lastElement); - - if (tokenBeforeLastElement.value === ",") { - - // Special case for comma-first syntax where the semicolon is indented - checkLastNodeLineIndent(node, getNodeIndent(tokenBeforeLastElement).goodChar); - } else { - checkLastNodeLineIndent(node, elementsIndent - indentSize); - } - } - - /** - * Check and decide whether to check for indentation for blockless nodes - * Scenarios are for or while statements without braces around them - * @param {ASTNode} node node to examine - * @returns {void} - */ - function blockLessNodes(node) { - if (node.body.type !== "BlockStatement") { - blockIndentationCheck(node); - } - } - - /** - * Returns the expected indentation for the case statement - * @param {ASTNode} node node to examine - * @param {int} [providedSwitchIndent] indent for switch statement - * @returns {int} indent size - */ - function expectedCaseIndent(node, providedSwitchIndent) { - const switchNode = (node.type === "SwitchStatement") ? node : node.parent; - const switchIndent = typeof providedSwitchIndent === "undefined" - ? getNodeIndent(switchNode).goodChar - : providedSwitchIndent; - let caseIndent; - - if (caseIndentStore[switchNode.loc.start.line]) { - return caseIndentStore[switchNode.loc.start.line]; - } - - if (switchNode.cases.length > 0 && options.SwitchCase === 0) { - caseIndent = switchIndent; - } else { - caseIndent = switchIndent + (indentSize * options.SwitchCase); - } - - caseIndentStore[switchNode.loc.start.line] = caseIndent; - return caseIndent; - - } - - /** - * Checks whether a return statement is wrapped in () - * @param {ASTNode} node node to examine - * @returns {boolean} the result - */ - function isWrappedInParenthesis(node) { - const regex = /^return\s*?\(\s*?\);*?/u; - - const statementWithoutArgument = sourceCode.getText(node).replace( - sourceCode.getText(node.argument), "" - ); - - return regex.test(statementWithoutArgument); - } - - return { - Program(node) { - if (node.body.length > 0) { - - // Root nodes should have no indent - checkNodesIndent(node.body, getNodeIndent(node).goodChar); - } - }, - - ClassBody: blockIndentationCheck, - - BlockStatement: blockIndentationCheck, - - WhileStatement: blockLessNodes, - - ForStatement: blockLessNodes, - - ForInStatement: blockLessNodes, - - ForOfStatement: blockLessNodes, - - DoWhileStatement: blockLessNodes, - - IfStatement(node) { - if (node.consequent.type !== "BlockStatement" && node.consequent.loc.start.line > node.loc.start.line) { - blockIndentationCheck(node); - } - }, - - VariableDeclaration(node) { - if (node.declarations[node.declarations.length - 1].loc.start.line > node.declarations[0].loc.start.line) { - checkIndentInVariableDeclarations(node); - } - }, - - ObjectExpression(node) { - checkIndentInArrayOrObjectBlock(node); - }, - - ArrayExpression(node) { - checkIndentInArrayOrObjectBlock(node); - }, - - MemberExpression(node) { - - if (typeof options.MemberExpression === "undefined") { - return; - } - - if (isSingleLineNode(node)) { - return; - } - - /* - * The typical layout of variable declarations and assignments - * alter the expectation of correct indentation. Skip them. - * TODO: Add appropriate configuration options for variable - * declarations and assignments. - */ - if (getParentNodeByType(node, "VariableDeclarator", ["FunctionExpression", "ArrowFunctionExpression"])) { - return; - } - - if (getParentNodeByType(node, "AssignmentExpression", ["FunctionExpression"])) { - return; - } - - const propertyIndent = getNodeIndent(node).goodChar + indentSize * options.MemberExpression; - - const checkNodes = [node.property]; - - const dot = sourceCode.getTokenBefore(node.property); - - if (dot.type === "Punctuator" && dot.value === ".") { - checkNodes.push(dot); - } - - checkNodesIndent(checkNodes, propertyIndent); - }, - - SwitchStatement(node) { - - // Switch is not a 'BlockStatement' - const switchIndent = getNodeIndent(node).goodChar; - const caseIndent = expectedCaseIndent(node, switchIndent); - - checkNodesIndent(node.cases, caseIndent); - - - checkLastNodeLineIndent(node, switchIndent); - }, - - SwitchCase(node) { - - // Skip inline cases - if (isSingleLineNode(node)) { - return; - } - const caseIndent = expectedCaseIndent(node); - - checkNodesIndent(node.consequent, caseIndent + indentSize); - }, - - FunctionDeclaration(node) { - if (isSingleLineNode(node)) { - return; - } - if (options.FunctionDeclaration.parameters === "first" && node.params.length) { - checkNodesIndent(node.params.slice(1), node.params[0].loc.start.column); - } else if (options.FunctionDeclaration.parameters !== null) { - checkNodesIndent(node.params, getNodeIndent(node).goodChar + indentSize * options.FunctionDeclaration.parameters); - } - }, - - FunctionExpression(node) { - if (isSingleLineNode(node)) { - return; - } - if (options.FunctionExpression.parameters === "first" && node.params.length) { - checkNodesIndent(node.params.slice(1), node.params[0].loc.start.column); - } else if (options.FunctionExpression.parameters !== null) { - checkNodesIndent(node.params, getNodeIndent(node).goodChar + indentSize * options.FunctionExpression.parameters); - } - }, - - ReturnStatement(node) { - if (isSingleLineNode(node)) { - return; - } - - const firstLineIndent = getNodeIndent(node).goodChar; - - // in case if return statement is wrapped in parenthesis - if (isWrappedInParenthesis(node)) { - checkLastReturnStatementLineIndent(node, firstLineIndent); - } else { - checkNodeIndent(node, firstLineIndent); - } - }, - - CallExpression(node) { - if (isSingleLineNode(node)) { - return; - } - if (options.CallExpression.arguments === "first" && node.arguments.length) { - checkNodesIndent(node.arguments.slice(1), node.arguments[0].loc.start.column); - } else if (options.CallExpression.arguments !== null) { - checkNodesIndent(node.arguments, getNodeIndent(node).goodChar + indentSize * options.CallExpression.arguments); - } - } - - }; - - } -}; - -/** - * @fileoverview A rule to control the style of variable initializations. - * @author Colin Ihrig - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether or not a given node is a for loop. - * @param {ASTNode} block A node to check. - * @returns {boolean} `true` when the node is a for loop. - */ -function isForLoop(block) { - return block.type === "ForInStatement" || - block.type === "ForOfStatement" || - block.type === "ForStatement"; -} - -/** - * Checks whether or not a given declarator node has its initializer. - * @param {ASTNode} node A declarator node to check. - * @returns {boolean} `true` when the node has its initializer. - */ -function isInitialized$1(node) { - const declaration = node.parent; - const block = declaration.parent; - - if (isForLoop(block)) { - if (block.type === "ForStatement") { - return block.init === declaration; - } - return block.left === declaration; - } - return Boolean(node.init); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var initDeclarations = { - meta: { - type: "suggestion", - - docs: { - description: "require or disallow initialization in variable declarations", - category: "Variables", - recommended: false, - url: "https://eslint.org/docs/rules/init-declarations" - }, - - schema: { - anyOf: [ - { - type: "array", - items: [ - { - enum: ["always"] - } - ], - minItems: 0, - maxItems: 1 - }, - { - type: "array", - items: [ - { - enum: ["never"] - }, - { - type: "object", - properties: { - ignoreForLoopInit: { - type: "boolean" - } - }, - additionalProperties: false - } - ], - minItems: 0, - maxItems: 2 - } - ] - }, - messages: { - initialized: "Variable '{{idName}}' should be initialized on declaration.", - notInitialized: "Variable '{{idName}}' should not be initialized on declaration." - } - }, - - create(context) { - - const MODE_ALWAYS = "always", - MODE_NEVER = "never"; - - const mode = context.options[0] || MODE_ALWAYS; - const params = context.options[1] || {}; - - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- - - return { - "VariableDeclaration:exit"(node) { - - const kind = node.kind, - declarations = node.declarations; - - for (let i = 0; i < declarations.length; ++i) { - const declaration = declarations[i], - id = declaration.id, - initialized = isInitialized$1(declaration), - isIgnoredForLoop = params.ignoreForLoopInit && isForLoop(node.parent); - let messageId = ""; - - if (mode === MODE_ALWAYS && !initialized) { - messageId = "initialized"; - } else if (mode === MODE_NEVER && kind !== "const" && initialized && !isIgnoredForLoop) { - messageId = "notInitialized"; - } - - if (id.type === "Identifier" && messageId) { - context.report({ - node: declaration, - messageId, - data: { - idName: id.name - } - }); - } - } - } - }; - } -}; - -/** - * @fileoverview A rule to ensure consistent quotes used in jsx syntax. - * @author Mathias Schreck - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Constants -//------------------------------------------------------------------------------ - -const QUOTE_SETTINGS$1 = { - "prefer-double": { - quote: "\"", - description: "singlequote", - convert(str) { - return str.replace(/'/gu, "\""); - } - }, - "prefer-single": { - quote: "'", - description: "doublequote", - convert(str) { - return str.replace(/"/gu, "'"); - } - } -}; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var jsxQuotes = { - meta: { - type: "layout", - - docs: { - description: "enforce the consistent use of either double or single quotes in JSX attributes", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/jsx-quotes" - }, - - fixable: "whitespace", - - schema: [ - { - enum: ["prefer-single", "prefer-double"] - } - ], - messages: { - unexpected: "Unexpected usage of {{description}}." - } - }, - - create(context) { - const quoteOption = context.options[0] || "prefer-double", - setting = QUOTE_SETTINGS$1[quoteOption]; - - /** - * Checks if the given string literal node uses the expected quotes - * @param {ASTNode} node A string literal node. - * @returns {boolean} Whether or not the string literal used the expected quotes. - * @public - */ - function usesExpectedQuotes(node) { - return node.value.indexOf(setting.quote) !== -1 || astUtils.isSurroundedBy(node.raw, setting.quote); - } - - return { - JSXAttribute(node) { - const attributeValue = node.value; - - if (attributeValue && astUtils.isStringLiteral(attributeValue) && !usesExpectedQuotes(attributeValue)) { - context.report({ - node: attributeValue, - messageId: "unexpected", - data: { - description: setting.description - }, - fix(fixer) { - return fixer.replaceText(attributeValue, setting.convert(attributeValue.raw)); - } - }); - } - } - }; - } -}; - -/** - * @fileoverview Rule to specify spacing of object literal keys and values - * @author Brandon Mills - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether a string contains a line terminator as defined in - * http://www.ecma-international.org/ecma-262/5.1/#sec-7.3 - * @param {string} str String to test. - * @returns {boolean} True if str contains a line terminator. - */ -function containsLineTerminator(str) { - return astUtils.LINEBREAK_MATCHER.test(str); -} - -/** - * Gets the last element of an array. - * @param {Array} arr An array. - * @returns {any} Last element of arr. - */ -function last(arr) { - return arr[arr.length - 1]; -} - -/** - * Checks whether a node is contained on a single line. - * @param {ASTNode} node AST Node being evaluated. - * @returns {boolean} True if the node is a single line. - */ -function isSingleLine(node) { - return (node.loc.end.line === node.loc.start.line); -} - -/** - * Checks whether the properties on a single line. - * @param {ASTNode[]} properties List of Property AST nodes. - * @returns {boolean} True if all properties is on a single line. - */ -function isSingleLineProperties(properties) { - const [firstProp] = properties, - lastProp = last(properties); - - return firstProp.loc.start.line === lastProp.loc.end.line; -} - -/** - * Initializes a single option property from the configuration with defaults for undefined values - * @param {Object} toOptions Object to be initialized - * @param {Object} fromOptions Object to be initialized from - * @returns {Object} The object with correctly initialized options and values - */ -function initOptionProperty(toOptions, fromOptions) { - toOptions.mode = fromOptions.mode || "strict"; - - // Set value of beforeColon - if (typeof fromOptions.beforeColon !== "undefined") { - toOptions.beforeColon = +fromOptions.beforeColon; - } else { - toOptions.beforeColon = 0; - } - - // Set value of afterColon - if (typeof fromOptions.afterColon !== "undefined") { - toOptions.afterColon = +fromOptions.afterColon; - } else { - toOptions.afterColon = 1; - } - - // Set align if exists - if (typeof fromOptions.align !== "undefined") { - if (typeof fromOptions.align === "object") { - toOptions.align = fromOptions.align; - } else { // "string" - toOptions.align = { - on: fromOptions.align, - mode: toOptions.mode, - beforeColon: toOptions.beforeColon, - afterColon: toOptions.afterColon - }; - } - } - - return toOptions; -} - -/** - * Initializes all the option values (singleLine, multiLine and align) from the configuration with defaults for undefined values - * @param {Object} toOptions Object to be initialized - * @param {Object} fromOptions Object to be initialized from - * @returns {Object} The object with correctly initialized options and values - */ -function initOptions(toOptions, fromOptions) { - if (typeof fromOptions.align === "object") { - - // Initialize the alignment configuration - toOptions.align = initOptionProperty({}, fromOptions.align); - toOptions.align.on = fromOptions.align.on || "colon"; - toOptions.align.mode = fromOptions.align.mode || "strict"; - - toOptions.multiLine = initOptionProperty({}, (fromOptions.multiLine || fromOptions)); - toOptions.singleLine = initOptionProperty({}, (fromOptions.singleLine || fromOptions)); - - } else { // string or undefined - toOptions.multiLine = initOptionProperty({}, (fromOptions.multiLine || fromOptions)); - toOptions.singleLine = initOptionProperty({}, (fromOptions.singleLine || fromOptions)); - - // If alignment options are defined in multiLine, pull them out into the general align configuration - if (toOptions.multiLine.align) { - toOptions.align = { - on: toOptions.multiLine.align.on, - mode: toOptions.multiLine.align.mode || toOptions.multiLine.mode, - beforeColon: toOptions.multiLine.align.beforeColon, - afterColon: toOptions.multiLine.align.afterColon - }; - } - } - - return toOptions; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var keySpacing = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent spacing between keys and values in object literal properties", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/key-spacing" - }, - - fixable: "whitespace", - - schema: [{ - anyOf: [ - { - type: "object", - properties: { - align: { - anyOf: [ - { - enum: ["colon", "value"] - }, - { - type: "object", - properties: { - mode: { - enum: ["strict", "minimum"] - }, - on: { - enum: ["colon", "value"] - }, - beforeColon: { - type: "boolean" - }, - afterColon: { - type: "boolean" - } - }, - additionalProperties: false - } - ] - }, - mode: { - enum: ["strict", "minimum"] - }, - beforeColon: { - type: "boolean" - }, - afterColon: { - type: "boolean" - } - }, - additionalProperties: false - }, - { - type: "object", - properties: { - singleLine: { - type: "object", - properties: { - mode: { - enum: ["strict", "minimum"] - }, - beforeColon: { - type: "boolean" - }, - afterColon: { - type: "boolean" - } - }, - additionalProperties: false - }, - multiLine: { - type: "object", - properties: { - align: { - anyOf: [ - { - enum: ["colon", "value"] - }, - { - type: "object", - properties: { - mode: { - enum: ["strict", "minimum"] - }, - on: { - enum: ["colon", "value"] - }, - beforeColon: { - type: "boolean" - }, - afterColon: { - type: "boolean" - } - }, - additionalProperties: false - } - ] - }, - mode: { - enum: ["strict", "minimum"] - }, - beforeColon: { - type: "boolean" - }, - afterColon: { - type: "boolean" - } - }, - additionalProperties: false - } - }, - additionalProperties: false - }, - { - type: "object", - properties: { - singleLine: { - type: "object", - properties: { - mode: { - enum: ["strict", "minimum"] - }, - beforeColon: { - type: "boolean" - }, - afterColon: { - type: "boolean" - } - }, - additionalProperties: false - }, - multiLine: { - type: "object", - properties: { - mode: { - enum: ["strict", "minimum"] - }, - beforeColon: { - type: "boolean" - }, - afterColon: { - type: "boolean" - } - }, - additionalProperties: false - }, - align: { - type: "object", - properties: { - mode: { - enum: ["strict", "minimum"] - }, - on: { - enum: ["colon", "value"] - }, - beforeColon: { - type: "boolean" - }, - afterColon: { - type: "boolean" - } - }, - additionalProperties: false - } - }, - additionalProperties: false - } - ] - }], - messages: { - extraKey: "Extra space after {{computed}}key '{{key}}'.", - extraValue: "Extra space before value for {{computed}}key '{{key}}'.", - missingKey: "Missing space after {{computed}}key '{{key}}'.", - missingValue: "Missing space before value for {{computed}}key '{{key}}'." - } - }, - - create(context) { - - /** - * OPTIONS - * "key-spacing": [2, { - * beforeColon: false, - * afterColon: true, - * align: "colon" // Optional, or "value" - * } - */ - const options = context.options[0] || {}, - ruleOptions = initOptions({}, options), - multiLineOptions = ruleOptions.multiLine, - singleLineOptions = ruleOptions.singleLine, - alignmentOptions = ruleOptions.align || null; - - const sourceCode = context.getSourceCode(); - - /** - * Checks whether a property is a member of the property group it follows. - * @param {ASTNode} lastMember The last Property known to be in the group. - * @param {ASTNode} candidate The next Property that might be in the group. - * @returns {boolean} True if the candidate property is part of the group. - */ - function continuesPropertyGroup(lastMember, candidate) { - const groupEndLine = lastMember.loc.start.line, - candidateStartLine = candidate.loc.start.line; - - if (candidateStartLine - groupEndLine <= 1) { - return true; - } - - /* - * Check that the first comment is adjacent to the end of the group, the - * last comment is adjacent to the candidate property, and that successive - * comments are adjacent to each other. - */ - const leadingComments = sourceCode.getCommentsBefore(candidate); - - if ( - leadingComments.length && - leadingComments[0].loc.start.line - groupEndLine <= 1 && - candidateStartLine - last(leadingComments).loc.end.line <= 1 - ) { - for (let i = 1; i < leadingComments.length; i++) { - if (leadingComments[i].loc.start.line - leadingComments[i - 1].loc.end.line > 1) { - return false; - } - } - return true; - } - - return false; - } - - /** - * Determines if the given property is key-value property. - * @param {ASTNode} property Property node to check. - * @returns {boolean} Whether the property is a key-value property. - */ - function isKeyValueProperty(property) { - return !( - (property.method || - property.shorthand || - property.kind !== "init" || property.type !== "Property") // Could be "ExperimentalSpreadProperty" or "SpreadElement" - ); - } - - /** - * Starting from the given a node (a property.key node here) looks forward - * until it finds the last token before a colon punctuator and returns it. - * @param {ASTNode} node The node to start looking from. - * @returns {ASTNode} The last token before a colon punctuator. - */ - function getLastTokenBeforeColon(node) { - const colonToken = sourceCode.getTokenAfter(node, astUtils.isColonToken); - - return sourceCode.getTokenBefore(colonToken); - } - - /** - * Starting from the given a node (a property.key node here) looks forward - * until it finds the colon punctuator and returns it. - * @param {ASTNode} node The node to start looking from. - * @returns {ASTNode} The colon punctuator. - */ - function getNextColon(node) { - return sourceCode.getTokenAfter(node, astUtils.isColonToken); - } - - /** - * Gets an object literal property's key as the identifier name or string value. - * @param {ASTNode} property Property node whose key to retrieve. - * @returns {string} The property's key. - */ - function getKey(property) { - const key = property.key; - - if (property.computed) { - return sourceCode.getText().slice(key.range[0], key.range[1]); - } - return astUtils.getStaticPropertyName(property); - } - - /** - * Reports an appropriately-formatted error if spacing is incorrect on one - * side of the colon. - * @param {ASTNode} property Key-value pair in an object literal. - * @param {string} side Side being verified - either "key" or "value". - * @param {string} whitespace Actual whitespace string. - * @param {int} expected Expected whitespace length. - * @param {string} mode Value of the mode as "strict" or "minimum" - * @returns {void} - */ - function report(property, side, whitespace, expected, mode) { - const diff = whitespace.length - expected, - nextColon = getNextColon(property.key), - tokenBeforeColon = sourceCode.getTokenBefore(nextColon, { includeComments: true }), - tokenAfterColon = sourceCode.getTokenAfter(nextColon, { includeComments: true }), - isKeySide = side === "key", - isExtra = diff > 0, - diffAbs = Math.abs(diff), - spaces = Array(diffAbs + 1).join(" "); - - const locStart = isKeySide ? tokenBeforeColon.loc.end : nextColon.loc.start; - const locEnd = isKeySide ? nextColon.loc.start : tokenAfterColon.loc.start; - const missingLoc = isKeySide ? tokenBeforeColon.loc : tokenAfterColon.loc; - const loc = isExtra ? { start: locStart, end: locEnd } : missingLoc; - - if (( - diff && mode === "strict" || - diff < 0 && mode === "minimum" || - diff > 0 && !expected && mode === "minimum") && - !(expected && containsLineTerminator(whitespace)) - ) { - let fix; - - if (isExtra) { - let range; - - // Remove whitespace - if (isKeySide) { - range = [tokenBeforeColon.range[1], tokenBeforeColon.range[1] + diffAbs]; - } else { - range = [tokenAfterColon.range[0] - diffAbs, tokenAfterColon.range[0]]; - } - fix = function(fixer) { - return fixer.removeRange(range); - }; - } else { - - // Add whitespace - if (isKeySide) { - fix = function(fixer) { - return fixer.insertTextAfter(tokenBeforeColon, spaces); - }; - } else { - fix = function(fixer) { - return fixer.insertTextBefore(tokenAfterColon, spaces); - }; - } - } - - let messageId = ""; - - if (isExtra) { - messageId = side === "key" ? "extraKey" : "extraValue"; - } else { - messageId = side === "key" ? "missingKey" : "missingValue"; - } - - context.report({ - node: property[side], - loc, - messageId, - data: { - computed: property.computed ? "computed " : "", - key: getKey(property) - }, - fix - }); - } - } - - /** - * Gets the number of characters in a key, including quotes around string - * keys and braces around computed property keys. - * @param {ASTNode} property Property of on object literal. - * @returns {int} Width of the key. - */ - function getKeyWidth(property) { - const startToken = sourceCode.getFirstToken(property); - const endToken = getLastTokenBeforeColon(property.key); - - return endToken.range[1] - startToken.range[0]; - } - - /** - * Gets the whitespace around the colon in an object literal property. - * @param {ASTNode} property Property node from an object literal. - * @returns {Object} Whitespace before and after the property's colon. - */ - function getPropertyWhitespace(property) { - const whitespace = /(\s*):(\s*)/u.exec(sourceCode.getText().slice( - property.key.range[1], property.value.range[0] - )); - - if (whitespace) { - return { - beforeColon: whitespace[1], - afterColon: whitespace[2] - }; - } - return null; - } - - /** - * Creates groups of properties. - * @param {ASTNode} node ObjectExpression node being evaluated. - * @returns {Array.} Groups of property AST node lists. - */ - function createGroups(node) { - if (node.properties.length === 1) { - return [node.properties]; - } - - return node.properties.reduce((groups, property) => { - const currentGroup = last(groups), - prev = last(currentGroup); - - if (!prev || continuesPropertyGroup(prev, property)) { - currentGroup.push(property); - } else { - groups.push([property]); - } - - return groups; - }, [ - [] - ]); - } - - /** - * Verifies correct vertical alignment of a group of properties. - * @param {ASTNode[]} properties List of Property AST nodes. - * @returns {void} - */ - function verifyGroupAlignment(properties) { - const length = properties.length, - widths = properties.map(getKeyWidth), // Width of keys, including quotes - align = alignmentOptions.on; // "value" or "colon" - let targetWidth = Math.max(...widths), - beforeColon, afterColon, mode; - - if (alignmentOptions && length > 1) { // When aligning values within a group, use the alignment configuration. - beforeColon = alignmentOptions.beforeColon; - afterColon = alignmentOptions.afterColon; - mode = alignmentOptions.mode; - } else { - beforeColon = multiLineOptions.beforeColon; - afterColon = multiLineOptions.afterColon; - mode = alignmentOptions.mode; - } - - // Conditionally include one space before or after colon - targetWidth += (align === "colon" ? beforeColon : afterColon); - - for (let i = 0; i < length; i++) { - const property = properties[i]; - const whitespace = getPropertyWhitespace(property); - - if (whitespace) { // Object literal getters/setters lack a colon - const width = widths[i]; - - if (align === "value") { - report(property, "key", whitespace.beforeColon, beforeColon, mode); - report(property, "value", whitespace.afterColon, targetWidth - width, mode); - } else { // align = "colon" - report(property, "key", whitespace.beforeColon, targetWidth - width, mode); - report(property, "value", whitespace.afterColon, afterColon, mode); - } - } - } - } - - /** - * Verifies spacing of property conforms to specified options. - * @param {ASTNode} node Property node being evaluated. - * @param {Object} lineOptions Configured singleLine or multiLine options - * @returns {void} - */ - function verifySpacing(node, lineOptions) { - const actual = getPropertyWhitespace(node); - - if (actual) { // Object literal getters/setters lack colons - report(node, "key", actual.beforeColon, lineOptions.beforeColon, lineOptions.mode); - report(node, "value", actual.afterColon, lineOptions.afterColon, lineOptions.mode); - } - } - - /** - * Verifies spacing of each property in a list. - * @param {ASTNode[]} properties List of Property AST nodes. - * @param {Object} lineOptions Configured singleLine or multiLine options - * @returns {void} - */ - function verifyListSpacing(properties, lineOptions) { - const length = properties.length; - - for (let i = 0; i < length; i++) { - verifySpacing(properties[i], lineOptions); - } - } - - /** - * Verifies vertical alignment, taking into account groups of properties. - * @param {ASTNode} node ObjectExpression node being evaluated. - * @returns {void} - */ - function verifyAlignment(node) { - createGroups(node).forEach(group => { - const properties = group.filter(isKeyValueProperty); - - if (properties.length > 0 && isSingleLineProperties(properties)) { - verifyListSpacing(properties, multiLineOptions); - } else { - verifyGroupAlignment(properties); - } - }); - } - - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- - - if (alignmentOptions) { // Verify vertical alignment - - return { - ObjectExpression(node) { - if (isSingleLine(node)) { - verifyListSpacing(node.properties.filter(isKeyValueProperty), singleLineOptions); - } else { - verifyAlignment(node); - } - } - }; - - } - - // Obey beforeColon and afterColon in each property as configured - return { - Property(node) { - verifySpacing(node, isSingleLine(node.parent) ? singleLineOptions : multiLineOptions); - } - }; - - - } -}; - -/** - * @fileoverview Rule to enforce spacing before and after keywords. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Constants -//------------------------------------------------------------------------------ - -const PREV_TOKEN = /^[)\]}>]$/u; -const NEXT_TOKEN = /^(?:[([{<~!]|\+\+?|--?)$/u; -const PREV_TOKEN_M = /^[)\]}>*]$/u; -const NEXT_TOKEN_M = /^[{*]$/u; -const TEMPLATE_OPEN_PAREN = /\$\{$/u; -const TEMPLATE_CLOSE_PAREN = /^\}/u; -const CHECK_TYPE = /^(?:JSXElement|RegularExpression|String|Template)$/u; -const KEYS = keywords.concat(["as", "async", "await", "from", "get", "let", "of", "set", "yield"]); - -// check duplications. -(function() { - KEYS.sort(); - for (let i = 1; i < KEYS.length; ++i) { - if (KEYS[i] === KEYS[i - 1]) { - throw new Error(`Duplication was found in the keyword list: ${KEYS[i]}`); - } - } -}()); - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether or not a given token is a "Template" token ends with "${". - * @param {Token} token A token to check. - * @returns {boolean} `true` if the token is a "Template" token ends with "${". - */ -function isOpenParenOfTemplate(token) { - return token.type === "Template" && TEMPLATE_OPEN_PAREN.test(token.value); -} - -/** - * Checks whether or not a given token is a "Template" token starts with "}". - * @param {Token} token A token to check. - * @returns {boolean} `true` if the token is a "Template" token starts with "}". - */ -function isCloseParenOfTemplate(token) { - return token.type === "Template" && TEMPLATE_CLOSE_PAREN.test(token.value); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var keywordSpacing = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent spacing before and after keywords", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/keyword-spacing" - }, - - fixable: "whitespace", - - schema: [ - { - type: "object", - properties: { - before: { type: "boolean", default: true }, - after: { type: "boolean", default: true }, - overrides: { - type: "object", - properties: KEYS.reduce((retv, key) => { - retv[key] = { - type: "object", - properties: { - before: { type: "boolean" }, - after: { type: "boolean" } - }, - additionalProperties: false - }; - return retv; - }, {}), - additionalProperties: false - } - }, - additionalProperties: false - } - ], - messages: { - expectedBefore: "Expected space(s) before \"{{value}}\".", - expectedAfter: "Expected space(s) after \"{{value}}\".", - unexpectedBefore: "Unexpected space(s) before \"{{value}}\".", - unexpectedAfter: "Unexpected space(s) after \"{{value}}\"." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - /** - * Reports a given token if there are not space(s) before the token. - * @param {Token} token A token to report. - * @param {RegExp} pattern A pattern of the previous token to check. - * @returns {void} - */ - function expectSpaceBefore(token, pattern) { - const prevToken = sourceCode.getTokenBefore(token); - - if (prevToken && - (CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) && - !isOpenParenOfTemplate(prevToken) && - astUtils.isTokenOnSameLine(prevToken, token) && - !sourceCode.isSpaceBetweenTokens(prevToken, token) - ) { - context.report({ - loc: token.loc, - messageId: "expectedBefore", - data: token, - fix(fixer) { - return fixer.insertTextBefore(token, " "); - } - }); - } - } - - /** - * Reports a given token if there are space(s) before the token. - * @param {Token} token A token to report. - * @param {RegExp} pattern A pattern of the previous token to check. - * @returns {void} - */ - function unexpectSpaceBefore(token, pattern) { - const prevToken = sourceCode.getTokenBefore(token); - - if (prevToken && - (CHECK_TYPE.test(prevToken.type) || pattern.test(prevToken.value)) && - !isOpenParenOfTemplate(prevToken) && - astUtils.isTokenOnSameLine(prevToken, token) && - sourceCode.isSpaceBetweenTokens(prevToken, token) - ) { - context.report({ - loc: { start: prevToken.loc.end, end: token.loc.start }, - messageId: "unexpectedBefore", - data: token, - fix(fixer) { - return fixer.removeRange([prevToken.range[1], token.range[0]]); - } - }); - } - } - - /** - * Reports a given token if there are not space(s) after the token. - * @param {Token} token A token to report. - * @param {RegExp} pattern A pattern of the next token to check. - * @returns {void} - */ - function expectSpaceAfter(token, pattern) { - const nextToken = sourceCode.getTokenAfter(token); - - if (nextToken && - (CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) && - !isCloseParenOfTemplate(nextToken) && - astUtils.isTokenOnSameLine(token, nextToken) && - !sourceCode.isSpaceBetweenTokens(token, nextToken) - ) { - context.report({ - loc: token.loc, - messageId: "expectedAfter", - data: token, - fix(fixer) { - return fixer.insertTextAfter(token, " "); - } - }); - } - } - - /** - * Reports a given token if there are space(s) after the token. - * @param {Token} token A token to report. - * @param {RegExp} pattern A pattern of the next token to check. - * @returns {void} - */ - function unexpectSpaceAfter(token, pattern) { - const nextToken = sourceCode.getTokenAfter(token); - - if (nextToken && - (CHECK_TYPE.test(nextToken.type) || pattern.test(nextToken.value)) && - !isCloseParenOfTemplate(nextToken) && - astUtils.isTokenOnSameLine(token, nextToken) && - sourceCode.isSpaceBetweenTokens(token, nextToken) - ) { - - context.report({ - loc: { start: token.loc.end, end: nextToken.loc.start }, - messageId: "unexpectedAfter", - data: token, - fix(fixer) { - return fixer.removeRange([token.range[1], nextToken.range[0]]); - } - }); - } - } - - /** - * Parses the option object and determines check methods for each keyword. - * @param {Object|undefined} options The option object to parse. - * @returns {Object} - Normalized option object. - * Keys are keywords (there are for every keyword). - * Values are instances of `{"before": function, "after": function}`. - */ - function parseOptions(options = {}) { - const before = options.before !== false; - const after = options.after !== false; - const defaultValue = { - before: before ? expectSpaceBefore : unexpectSpaceBefore, - after: after ? expectSpaceAfter : unexpectSpaceAfter - }; - const overrides = (options && options.overrides) || {}; - const retv = Object.create(null); - - for (let i = 0; i < KEYS.length; ++i) { - const key = KEYS[i]; - const override = overrides[key]; - - if (override) { - const thisBefore = ("before" in override) ? override.before : before; - const thisAfter = ("after" in override) ? override.after : after; - - retv[key] = { - before: thisBefore ? expectSpaceBefore : unexpectSpaceBefore, - after: thisAfter ? expectSpaceAfter : unexpectSpaceAfter - }; - } else { - retv[key] = defaultValue; - } - } - - return retv; - } - - const checkMethodMap = parseOptions(context.options[0]); - - /** - * Reports a given token if usage of spacing followed by the token is - * invalid. - * @param {Token} token A token to report. - * @param {RegExp} [pattern] Optional. A pattern of the previous - * token to check. - * @returns {void} - */ - function checkSpacingBefore(token, pattern) { - checkMethodMap[token.value].before(token, pattern || PREV_TOKEN); - } - - /** - * Reports a given token if usage of spacing preceded by the token is - * invalid. - * @param {Token} token A token to report. - * @param {RegExp} [pattern] Optional. A pattern of the next - * token to check. - * @returns {void} - */ - function checkSpacingAfter(token, pattern) { - checkMethodMap[token.value].after(token, pattern || NEXT_TOKEN); - } - - /** - * Reports a given token if usage of spacing around the token is invalid. - * @param {Token} token A token to report. - * @returns {void} - */ - function checkSpacingAround(token) { - checkSpacingBefore(token); - checkSpacingAfter(token); - } - - /** - * Reports the first token of a given node if the first token is a keyword - * and usage of spacing around the token is invalid. - * @param {ASTNode|null} node A node to report. - * @returns {void} - */ - function checkSpacingAroundFirstToken(node) { - const firstToken = node && sourceCode.getFirstToken(node); - - if (firstToken && firstToken.type === "Keyword") { - checkSpacingAround(firstToken); - } - } - - /** - * Reports the first token of a given node if the first token is a keyword - * and usage of spacing followed by the token is invalid. - * - * This is used for unary operators (e.g. `typeof`), `function`, and `super`. - * Other rules are handling usage of spacing preceded by those keywords. - * @param {ASTNode|null} node A node to report. - * @returns {void} - */ - function checkSpacingBeforeFirstToken(node) { - const firstToken = node && sourceCode.getFirstToken(node); - - if (firstToken && firstToken.type === "Keyword") { - checkSpacingBefore(firstToken); - } - } - - /** - * Reports the previous token of a given node if the token is a keyword and - * usage of spacing around the token is invalid. - * @param {ASTNode|null} node A node to report. - * @returns {void} - */ - function checkSpacingAroundTokenBefore(node) { - if (node) { - const token = sourceCode.getTokenBefore(node, astUtils.isKeywordToken); - - checkSpacingAround(token); - } - } - - /** - * Reports `async` or `function` keywords of a given node if usage of - * spacing around those keywords is invalid. - * @param {ASTNode} node A node to report. - * @returns {void} - */ - function checkSpacingForFunction(node) { - const firstToken = node && sourceCode.getFirstToken(node); - - if (firstToken && - ((firstToken.type === "Keyword" && firstToken.value === "function") || - firstToken.value === "async") - ) { - checkSpacingBefore(firstToken); - } - } - - /** - * Reports `class` and `extends` keywords of a given node if usage of - * spacing around those keywords is invalid. - * @param {ASTNode} node A node to report. - * @returns {void} - */ - function checkSpacingForClass(node) { - checkSpacingAroundFirstToken(node); - checkSpacingAroundTokenBefore(node.superClass); - } - - /** - * Reports `if` and `else` keywords of a given node if usage of spacing - * around those keywords is invalid. - * @param {ASTNode} node A node to report. - * @returns {void} - */ - function checkSpacingForIfStatement(node) { - checkSpacingAroundFirstToken(node); - checkSpacingAroundTokenBefore(node.alternate); - } - - /** - * Reports `try`, `catch`, and `finally` keywords of a given node if usage - * of spacing around those keywords is invalid. - * @param {ASTNode} node A node to report. - * @returns {void} - */ - function checkSpacingForTryStatement(node) { - checkSpacingAroundFirstToken(node); - checkSpacingAroundFirstToken(node.handler); - checkSpacingAroundTokenBefore(node.finalizer); - } - - /** - * Reports `do` and `while` keywords of a given node if usage of spacing - * around those keywords is invalid. - * @param {ASTNode} node A node to report. - * @returns {void} - */ - function checkSpacingForDoWhileStatement(node) { - checkSpacingAroundFirstToken(node); - checkSpacingAroundTokenBefore(node.test); - } - - /** - * Reports `for` and `in` keywords of a given node if usage of spacing - * around those keywords is invalid. - * @param {ASTNode} node A node to report. - * @returns {void} - */ - function checkSpacingForForInStatement(node) { - checkSpacingAroundFirstToken(node); - checkSpacingAroundTokenBefore(node.right); - } - - /** - * Reports `for` and `of` keywords of a given node if usage of spacing - * around those keywords is invalid. - * @param {ASTNode} node A node to report. - * @returns {void} - */ - function checkSpacingForForOfStatement(node) { - if (node.await) { - checkSpacingBefore(sourceCode.getFirstToken(node, 0)); - checkSpacingAfter(sourceCode.getFirstToken(node, 1)); - } else { - checkSpacingAroundFirstToken(node); - } - checkSpacingAround(sourceCode.getTokenBefore(node.right, astUtils.isNotOpeningParenToken)); - } - - /** - * Reports `import`, `export`, `as`, and `from` keywords of a given node if - * usage of spacing around those keywords is invalid. - * - * This rule handles the `*` token in module declarations. - * - * import*as A from "./a"; /*error Expected space(s) after "import". - * error Expected space(s) before "as". - * @param {ASTNode} node A node to report. - * @returns {void} - */ - function checkSpacingForModuleDeclaration(node) { - const firstToken = sourceCode.getFirstToken(node); - - checkSpacingBefore(firstToken, PREV_TOKEN_M); - checkSpacingAfter(firstToken, NEXT_TOKEN_M); - - if (node.type === "ExportDefaultDeclaration") { - checkSpacingAround(sourceCode.getTokenAfter(firstToken)); - } - - if (node.type === "ExportAllDeclaration" && node.exported) { - const asToken = sourceCode.getTokenBefore(node.exported); - - checkSpacingBefore(asToken, PREV_TOKEN_M); - } - - if (node.source) { - const fromToken = sourceCode.getTokenBefore(node.source); - - checkSpacingBefore(fromToken, PREV_TOKEN_M); - checkSpacingAfter(fromToken, NEXT_TOKEN_M); - } - } - - /** - * Reports `as` keyword of a given node if usage of spacing around this - * keyword is invalid. - * @param {ASTNode} node A node to report. - * @returns {void} - */ - function checkSpacingForImportNamespaceSpecifier(node) { - const asToken = sourceCode.getFirstToken(node, 1); - - checkSpacingBefore(asToken, PREV_TOKEN_M); - } - - /** - * Reports `static`, `get`, and `set` keywords of a given node if usage of - * spacing around those keywords is invalid. - * @param {ASTNode} node A node to report. - * @returns {void} - */ - function checkSpacingForProperty(node) { - if (node.static) { - checkSpacingAroundFirstToken(node); - } - if (node.kind === "get" || - node.kind === "set" || - ( - (node.method || node.type === "MethodDefinition") && - node.value.async - ) - ) { - const token = sourceCode.getTokenBefore( - node.key, - tok => { - switch (tok.value) { - case "get": - case "set": - case "async": - return true; - default: - return false; - } - } - ); - - if (!token) { - throw new Error("Failed to find token get, set, or async beside method name"); - } - - - checkSpacingAround(token); - } - } - - /** - * Reports `await` keyword of a given node if usage of spacing before - * this keyword is invalid. - * @param {ASTNode} node A node to report. - * @returns {void} - */ - function checkSpacingForAwaitExpression(node) { - checkSpacingBefore(sourceCode.getFirstToken(node)); - } - - return { - - // Statements - DebuggerStatement: checkSpacingAroundFirstToken, - WithStatement: checkSpacingAroundFirstToken, - - // Statements - Control flow - BreakStatement: checkSpacingAroundFirstToken, - ContinueStatement: checkSpacingAroundFirstToken, - ReturnStatement: checkSpacingAroundFirstToken, - ThrowStatement: checkSpacingAroundFirstToken, - TryStatement: checkSpacingForTryStatement, - - // Statements - Choice - IfStatement: checkSpacingForIfStatement, - SwitchStatement: checkSpacingAroundFirstToken, - SwitchCase: checkSpacingAroundFirstToken, - - // Statements - Loops - DoWhileStatement: checkSpacingForDoWhileStatement, - ForInStatement: checkSpacingForForInStatement, - ForOfStatement: checkSpacingForForOfStatement, - ForStatement: checkSpacingAroundFirstToken, - WhileStatement: checkSpacingAroundFirstToken, - - // Statements - Declarations - ClassDeclaration: checkSpacingForClass, - ExportNamedDeclaration: checkSpacingForModuleDeclaration, - ExportDefaultDeclaration: checkSpacingForModuleDeclaration, - ExportAllDeclaration: checkSpacingForModuleDeclaration, - FunctionDeclaration: checkSpacingForFunction, - ImportDeclaration: checkSpacingForModuleDeclaration, - VariableDeclaration: checkSpacingAroundFirstToken, - - // Expressions - ArrowFunctionExpression: checkSpacingForFunction, - AwaitExpression: checkSpacingForAwaitExpression, - ClassExpression: checkSpacingForClass, - FunctionExpression: checkSpacingForFunction, - NewExpression: checkSpacingBeforeFirstToken, - Super: checkSpacingBeforeFirstToken, - ThisExpression: checkSpacingBeforeFirstToken, - UnaryExpression: checkSpacingBeforeFirstToken, - YieldExpression: checkSpacingBeforeFirstToken, - - // Others - ImportNamespaceSpecifier: checkSpacingForImportNamespaceSpecifier, - MethodDefinition: checkSpacingForProperty, - Property: checkSpacingForProperty - }; - } -}; - -/** - * @fileoverview Rule to enforce the position of line comments - * @author Alberto Rodríguez - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var lineCommentPosition = { - meta: { - type: "layout", - - docs: { - description: "enforce position of line comments", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/line-comment-position" - }, - - schema: [ - { - oneOf: [ - { - enum: ["above", "beside"] - }, - { - type: "object", - properties: { - position: { - enum: ["above", "beside"] - }, - ignorePattern: { - type: "string" - }, - applyDefaultPatterns: { - type: "boolean" - }, - applyDefaultIgnorePatterns: { - type: "boolean" - } - }, - additionalProperties: false - } - ] - } - ], - messages: { - above: "Expected comment to be above code.", - beside: "Expected comment to be beside code." - } - }, - - create(context) { - const options = context.options[0]; - - let above, - ignorePattern, - applyDefaultIgnorePatterns = true; - - if (!options || typeof options === "string") { - above = !options || options === "above"; - - } else { - above = !options.position || options.position === "above"; - ignorePattern = options.ignorePattern; - - if (Object.prototype.hasOwnProperty.call(options, "applyDefaultIgnorePatterns")) { - applyDefaultIgnorePatterns = options.applyDefaultIgnorePatterns; - } else { - applyDefaultIgnorePatterns = options.applyDefaultPatterns !== false; - } - } - - const defaultIgnoreRegExp = astUtils.COMMENTS_IGNORE_PATTERN; - const fallThroughRegExp = /^\s*falls?\s?through/u; - const customIgnoreRegExp = new RegExp(ignorePattern, "u"); - const sourceCode = context.getSourceCode(); - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - Program() { - const comments = sourceCode.getAllComments(); - - comments.filter(token => token.type === "Line").forEach(node => { - if (applyDefaultIgnorePatterns && (defaultIgnoreRegExp.test(node.value) || fallThroughRegExp.test(node.value))) { - return; - } - - if (ignorePattern && customIgnoreRegExp.test(node.value)) { - return; - } - - const previous = sourceCode.getTokenBefore(node, { includeComments: true }); - const isOnSameLine = previous && previous.loc.end.line === node.loc.start.line; - - if (above) { - if (isOnSameLine) { - context.report({ - node, - messageId: "above" - }); - } - } else { - if (!isOnSameLine) { - context.report({ - node, - messageId: "beside" - }); - } - } - }); - } - }; - } -}; - -/** - * @fileoverview Rule to enforce a single linebreak style. - * @author Erik Mueller - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var linebreakStyle = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent linebreak style", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/linebreak-style" - }, - - fixable: "whitespace", - - schema: [ - { - enum: ["unix", "windows"] - } - ], - messages: { - expectedLF: "Expected linebreaks to be 'LF' but found 'CRLF'.", - expectedCRLF: "Expected linebreaks to be 'CRLF' but found 'LF'." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Builds a fix function that replaces text at the specified range in the source text. - * @param {int[]} range The range to replace - * @param {string} text The text to insert. - * @returns {Function} Fixer function - * @private - */ - function createFix(range, text) { - return function(fixer) { - return fixer.replaceTextRange(range, text); - }; - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - Program: function checkForLinebreakStyle(node) { - const linebreakStyle = context.options[0] || "unix", - expectedLF = linebreakStyle === "unix", - expectedLFChars = expectedLF ? "\n" : "\r\n", - source = sourceCode.getText(), - pattern = astUtils.createGlobalLinebreakMatcher(); - let match; - - let i = 0; - - while ((match = pattern.exec(source)) !== null) { - i++; - if (match[0] === expectedLFChars) { - continue; - } - - const index = match.index; - const range = [index, index + match[0].length]; - - context.report({ - node, - loc: { - start: { - line: i, - column: sourceCode.lines[i - 1].length - }, - end: { - line: i + 1, - column: 0 - } - }, - messageId: expectedLF ? "expectedLF" : "expectedCRLF", - fix: createFix(range, expectedLFChars) - }); - } - } - }; - } -}; - -/** - * @fileoverview Enforces empty lines around comments. - * @author Jamund Ferguson - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Return an array with with any line numbers that are empty. - * @param {Array} lines An array of each line of the file. - * @returns {Array} An array of line numbers. - */ -function getEmptyLineNums(lines) { - const emptyLines = lines.map((line, i) => ({ - code: line.trim(), - num: i + 1 - })).filter(line => !line.code).map(line => line.num); - - return emptyLines; -} - -/** - * Return an array with with any line numbers that contain comments. - * @param {Array} comments An array of comment tokens. - * @returns {Array} An array of line numbers. - */ -function getCommentLineNums(comments) { - const lines = []; - - comments.forEach(token => { - const start = token.loc.start.line; - const end = token.loc.end.line; - - lines.push(start, end); - }); - return lines; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var linesAroundComment = { - meta: { - type: "layout", - - docs: { - description: "require empty lines around comments", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/lines-around-comment" - }, - - fixable: "whitespace", - - schema: [ - { - type: "object", - properties: { - beforeBlockComment: { - type: "boolean", - default: true - }, - afterBlockComment: { - type: "boolean", - default: false - }, - beforeLineComment: { - type: "boolean", - default: false - }, - afterLineComment: { - type: "boolean", - default: false - }, - allowBlockStart: { - type: "boolean", - default: false - }, - allowBlockEnd: { - type: "boolean", - default: false - }, - allowClassStart: { - type: "boolean" - }, - allowClassEnd: { - type: "boolean" - }, - allowObjectStart: { - type: "boolean" - }, - allowObjectEnd: { - type: "boolean" - }, - allowArrayStart: { - type: "boolean" - }, - allowArrayEnd: { - type: "boolean" - }, - ignorePattern: { - type: "string" - }, - applyDefaultIgnorePatterns: { - type: "boolean" - } - }, - additionalProperties: false - } - ], - messages: { - after: "Expected line after comment.", - before: "Expected line before comment." - } - }, - - create(context) { - - const options = Object.assign({}, context.options[0]); - const ignorePattern = options.ignorePattern; - const defaultIgnoreRegExp = astUtils.COMMENTS_IGNORE_PATTERN; - const customIgnoreRegExp = new RegExp(ignorePattern, "u"); - const applyDefaultIgnorePatterns = options.applyDefaultIgnorePatterns !== false; - - options.beforeBlockComment = typeof options.beforeBlockComment !== "undefined" ? options.beforeBlockComment : true; - - const sourceCode = context.getSourceCode(); - - const lines = sourceCode.lines, - numLines = lines.length + 1, - comments = sourceCode.getAllComments(), - commentLines = getCommentLineNums(comments), - emptyLines = getEmptyLineNums(lines), - commentAndEmptyLines = commentLines.concat(emptyLines); - - /** - * Returns whether or not comments are on lines starting with or ending with code - * @param {token} token The comment token to check. - * @returns {boolean} True if the comment is not alone. - */ - function codeAroundComment(token) { - let currentToken = token; - - do { - currentToken = sourceCode.getTokenBefore(currentToken, { includeComments: true }); - } while (currentToken && astUtils.isCommentToken(currentToken)); - - if (currentToken && astUtils.isTokenOnSameLine(currentToken, token)) { - return true; - } - - currentToken = token; - do { - currentToken = sourceCode.getTokenAfter(currentToken, { includeComments: true }); - } while (currentToken && astUtils.isCommentToken(currentToken)); - - if (currentToken && astUtils.isTokenOnSameLine(token, currentToken)) { - return true; - } - - return false; - } - - /** - * Returns whether or not comments are inside a node type or not. - * @param {ASTNode} parent The Comment parent node. - * @param {string} nodeType The parent type to check against. - * @returns {boolean} True if the comment is inside nodeType. - */ - function isParentNodeType(parent, nodeType) { - return parent.type === nodeType || - (parent.body && parent.body.type === nodeType) || - (parent.consequent && parent.consequent.type === nodeType); - } - - /** - * Returns the parent node that contains the given token. - * @param {token} token The token to check. - * @returns {ASTNode} The parent node that contains the given token. - */ - function getParentNodeOfToken(token) { - return sourceCode.getNodeByRangeIndex(token.range[0]); - } - - /** - * Returns whether or not comments are at the parent start or not. - * @param {token} token The Comment token. - * @param {string} nodeType The parent type to check against. - * @returns {boolean} True if the comment is at parent start. - */ - function isCommentAtParentStart(token, nodeType) { - const parent = getParentNodeOfToken(token); - - return parent && isParentNodeType(parent, nodeType) && - token.loc.start.line - parent.loc.start.line === 1; - } - - /** - * Returns whether or not comments are at the parent end or not. - * @param {token} token The Comment token. - * @param {string} nodeType The parent type to check against. - * @returns {boolean} True if the comment is at parent end. - */ - function isCommentAtParentEnd(token, nodeType) { - const parent = getParentNodeOfToken(token); - - return parent && isParentNodeType(parent, nodeType) && - parent.loc.end.line - token.loc.end.line === 1; - } - - /** - * Returns whether or not comments are at the block start or not. - * @param {token} token The Comment token. - * @returns {boolean} True if the comment is at block start. - */ - function isCommentAtBlockStart(token) { - return isCommentAtParentStart(token, "ClassBody") || isCommentAtParentStart(token, "BlockStatement") || isCommentAtParentStart(token, "SwitchCase"); - } - - /** - * Returns whether or not comments are at the block end or not. - * @param {token} token The Comment token. - * @returns {boolean} True if the comment is at block end. - */ - function isCommentAtBlockEnd(token) { - return isCommentAtParentEnd(token, "ClassBody") || isCommentAtParentEnd(token, "BlockStatement") || isCommentAtParentEnd(token, "SwitchCase") || isCommentAtParentEnd(token, "SwitchStatement"); - } - - /** - * Returns whether or not comments are at the class start or not. - * @param {token} token The Comment token. - * @returns {boolean} True if the comment is at class start. - */ - function isCommentAtClassStart(token) { - return isCommentAtParentStart(token, "ClassBody"); - } - - /** - * Returns whether or not comments are at the class end or not. - * @param {token} token The Comment token. - * @returns {boolean} True if the comment is at class end. - */ - function isCommentAtClassEnd(token) { - return isCommentAtParentEnd(token, "ClassBody"); - } - - /** - * Returns whether or not comments are at the object start or not. - * @param {token} token The Comment token. - * @returns {boolean} True if the comment is at object start. - */ - function isCommentAtObjectStart(token) { - return isCommentAtParentStart(token, "ObjectExpression") || isCommentAtParentStart(token, "ObjectPattern"); - } - - /** - * Returns whether or not comments are at the object end or not. - * @param {token} token The Comment token. - * @returns {boolean} True if the comment is at object end. - */ - function isCommentAtObjectEnd(token) { - return isCommentAtParentEnd(token, "ObjectExpression") || isCommentAtParentEnd(token, "ObjectPattern"); - } - - /** - * Returns whether or not comments are at the array start or not. - * @param {token} token The Comment token. - * @returns {boolean} True if the comment is at array start. - */ - function isCommentAtArrayStart(token) { - return isCommentAtParentStart(token, "ArrayExpression") || isCommentAtParentStart(token, "ArrayPattern"); - } - - /** - * Returns whether or not comments are at the array end or not. - * @param {token} token The Comment token. - * @returns {boolean} True if the comment is at array end. - */ - function isCommentAtArrayEnd(token) { - return isCommentAtParentEnd(token, "ArrayExpression") || isCommentAtParentEnd(token, "ArrayPattern"); - } - - /** - * Checks if a comment token has lines around it (ignores inline comments) - * @param {token} token The Comment token. - * @param {Object} opts Options to determine the newline. - * @param {boolean} opts.after Should have a newline after this line. - * @param {boolean} opts.before Should have a newline before this line. - * @returns {void} - */ - function checkForEmptyLine(token, opts) { - if (applyDefaultIgnorePatterns && defaultIgnoreRegExp.test(token.value)) { - return; - } - - if (ignorePattern && customIgnoreRegExp.test(token.value)) { - return; - } - - let after = opts.after, - before = opts.before; - - const prevLineNum = token.loc.start.line - 1, - nextLineNum = token.loc.end.line + 1, - commentIsNotAlone = codeAroundComment(token); - - const blockStartAllowed = options.allowBlockStart && - isCommentAtBlockStart(token) && - !(options.allowClassStart === false && - isCommentAtClassStart(token)), - blockEndAllowed = options.allowBlockEnd && isCommentAtBlockEnd(token) && !(options.allowClassEnd === false && isCommentAtClassEnd(token)), - classStartAllowed = options.allowClassStart && isCommentAtClassStart(token), - classEndAllowed = options.allowClassEnd && isCommentAtClassEnd(token), - objectStartAllowed = options.allowObjectStart && isCommentAtObjectStart(token), - objectEndAllowed = options.allowObjectEnd && isCommentAtObjectEnd(token), - arrayStartAllowed = options.allowArrayStart && isCommentAtArrayStart(token), - arrayEndAllowed = options.allowArrayEnd && isCommentAtArrayEnd(token); - - const exceptionStartAllowed = blockStartAllowed || classStartAllowed || objectStartAllowed || arrayStartAllowed; - const exceptionEndAllowed = blockEndAllowed || classEndAllowed || objectEndAllowed || arrayEndAllowed; - - // ignore top of the file and bottom of the file - if (prevLineNum < 1) { - before = false; - } - if (nextLineNum >= numLines) { - after = false; - } - - // we ignore all inline comments - if (commentIsNotAlone) { - return; - } - - const previousTokenOrComment = sourceCode.getTokenBefore(token, { includeComments: true }); - const nextTokenOrComment = sourceCode.getTokenAfter(token, { includeComments: true }); - - // check for newline before - if (!exceptionStartAllowed && before && !commentAndEmptyLines.includes(prevLineNum) && - !(astUtils.isCommentToken(previousTokenOrComment) && astUtils.isTokenOnSameLine(previousTokenOrComment, token))) { - const lineStart = token.range[0] - token.loc.start.column; - const range = [lineStart, lineStart]; - - context.report({ - node: token, - messageId: "before", - fix(fixer) { - return fixer.insertTextBeforeRange(range, "\n"); - } - }); - } - - // check for newline after - if (!exceptionEndAllowed && after && !commentAndEmptyLines.includes(nextLineNum) && - !(astUtils.isCommentToken(nextTokenOrComment) && astUtils.isTokenOnSameLine(token, nextTokenOrComment))) { - context.report({ - node: token, - messageId: "after", - fix(fixer) { - return fixer.insertTextAfter(token, "\n"); - } - }); - } - - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - Program() { - comments.forEach(token => { - if (token.type === "Line") { - if (options.beforeLineComment || options.afterLineComment) { - checkForEmptyLine(token, { - after: options.afterLineComment, - before: options.beforeLineComment - }); - } - } else if (token.type === "Block") { - if (options.beforeBlockComment || options.afterBlockComment) { - checkForEmptyLine(token, { - after: options.afterBlockComment, - before: options.beforeBlockComment - }); - } - } - }); - } - }; - } -}; - -/** - * @fileoverview Require or disallow newlines around directives. - * @author Kai Cataldo - * @deprecated - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var linesAroundDirective = { - meta: { - type: "layout", - - docs: { - description: "require or disallow newlines around directives", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/lines-around-directive" - }, - - schema: [{ - oneOf: [ - { - enum: ["always", "never"] - }, - { - type: "object", - properties: { - before: { - enum: ["always", "never"] - }, - after: { - enum: ["always", "never"] - } - }, - additionalProperties: false, - minProperties: 2 - } - ] - }], - - fixable: "whitespace", - messages: { - expected: "Expected newline {{location}} \"{{value}}\" directive.", - unexpected: "Unexpected newline {{location}} \"{{value}}\" directive." - }, - deprecated: true, - replacedBy: ["padding-line-between-statements"] - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const config = context.options[0] || "always"; - const expectLineBefore = typeof config === "string" ? config : config.before; - const expectLineAfter = typeof config === "string" ? config : config.after; - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Check if node is preceded by a blank newline. - * @param {ASTNode} node Node to check. - * @returns {boolean} Whether or not the passed in node is preceded by a blank newline. - */ - function hasNewlineBefore(node) { - const tokenBefore = sourceCode.getTokenBefore(node, { includeComments: true }); - const tokenLineBefore = tokenBefore ? tokenBefore.loc.end.line : 0; - - return node.loc.start.line - tokenLineBefore >= 2; - } - - /** - * Gets the last token of a node that is on the same line as the rest of the node. - * This will usually be the last token of the node, but it will be the second-to-last token if the node has a trailing - * semicolon on a different line. - * @param {ASTNode} node A directive node - * @returns {Token} The last token of the node on the line - */ - function getLastTokenOnLine(node) { - const lastToken = sourceCode.getLastToken(node); - const secondToLastToken = sourceCode.getTokenBefore(lastToken); - - return astUtils.isSemicolonToken(lastToken) && lastToken.loc.start.line > secondToLastToken.loc.end.line - ? secondToLastToken - : lastToken; - } - - /** - * Check if node is followed by a blank newline. - * @param {ASTNode} node Node to check. - * @returns {boolean} Whether or not the passed in node is followed by a blank newline. - */ - function hasNewlineAfter(node) { - const lastToken = getLastTokenOnLine(node); - const tokenAfter = sourceCode.getTokenAfter(lastToken, { includeComments: true }); - - return tokenAfter.loc.start.line - lastToken.loc.end.line >= 2; - } - - /** - * Report errors for newlines around directives. - * @param {ASTNode} node Node to check. - * @param {string} location Whether the error was found before or after the directive. - * @param {boolean} expected Whether or not a newline was expected or unexpected. - * @returns {void} - */ - function reportError(node, location, expected) { - context.report({ - node, - messageId: expected ? "expected" : "unexpected", - data: { - value: node.expression.value, - location - }, - fix(fixer) { - const lastToken = getLastTokenOnLine(node); - - if (expected) { - return location === "before" ? fixer.insertTextBefore(node, "\n") : fixer.insertTextAfter(lastToken, "\n"); - } - return fixer.removeRange(location === "before" ? [node.range[0] - 1, node.range[0]] : [lastToken.range[1], lastToken.range[1] + 1]); - } - }); - } - - /** - * Check lines around directives in node - * @param {ASTNode} node node to check - * @returns {void} - */ - function checkDirectives(node) { - const directives = astUtils.getDirectivePrologue(node); - - if (!directives.length) { - return; - } - - const firstDirective = directives[0]; - const leadingComments = sourceCode.getCommentsBefore(firstDirective); - - /* - * Only check before the first directive if it is preceded by a comment or if it is at the top of - * the file and expectLineBefore is set to "never". This is to not force a newline at the top of - * the file if there are no comments as well as for compatibility with padded-blocks. - */ - if (leadingComments.length) { - if (expectLineBefore === "always" && !hasNewlineBefore(firstDirective)) { - reportError(firstDirective, "before", true); - } - - if (expectLineBefore === "never" && hasNewlineBefore(firstDirective)) { - reportError(firstDirective, "before", false); - } - } else if ( - node.type === "Program" && - expectLineBefore === "never" && - !leadingComments.length && - hasNewlineBefore(firstDirective) - ) { - reportError(firstDirective, "before", false); - } - - const lastDirective = directives[directives.length - 1]; - const statements = node.type === "Program" ? node.body : node.body.body; - - /* - * Do not check after the last directive if the body only - * contains a directive prologue and isn't followed by a comment to ensure - * this rule behaves well with padded-blocks. - */ - if (lastDirective === statements[statements.length - 1] && !lastDirective.trailingComments) { - return; - } - - if (expectLineAfter === "always" && !hasNewlineAfter(lastDirective)) { - reportError(lastDirective, "after", true); - } - - if (expectLineAfter === "never" && hasNewlineAfter(lastDirective)) { - reportError(lastDirective, "after", false); - } - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - Program: checkDirectives, - FunctionDeclaration: checkDirectives, - FunctionExpression: checkDirectives, - ArrowFunctionExpression: checkDirectives - }; - } -}; - -/** - * @fileoverview Rule to check empty newline between class members - * @author 薛定谔的猫 - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var linesBetweenClassMembers = { - meta: { - type: "layout", - - docs: { - description: "require or disallow an empty line between class members", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/lines-between-class-members" - }, - - fixable: "whitespace", - - schema: [ - { - enum: ["always", "never"] - }, - { - type: "object", - properties: { - exceptAfterSingleLine: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - messages: { - never: "Unexpected blank line between class members.", - always: "Expected blank line between class members." - } - }, - - create(context) { - - const options = []; - - options[0] = context.options[0] || "always"; - options[1] = context.options[1] || { exceptAfterSingleLine: false }; - - const sourceCode = context.getSourceCode(); - - /** - * Return the last token among the consecutive tokens that have no exceed max line difference in between, before the first token in the next member. - * @param {Token} prevLastToken The last token in the previous member node. - * @param {Token} nextFirstToken The first token in the next member node. - * @param {number} maxLine The maximum number of allowed line difference between consecutive tokens. - * @returns {Token} The last token among the consecutive tokens. - */ - function findLastConsecutiveTokenAfter(prevLastToken, nextFirstToken, maxLine) { - const after = sourceCode.getTokenAfter(prevLastToken, { includeComments: true }); - - if (after !== nextFirstToken && after.loc.start.line - prevLastToken.loc.end.line <= maxLine) { - return findLastConsecutiveTokenAfter(after, nextFirstToken, maxLine); - } - return prevLastToken; - } - - /** - * Return the first token among the consecutive tokens that have no exceed max line difference in between, after the last token in the previous member. - * @param {Token} nextFirstToken The first token in the next member node. - * @param {Token} prevLastToken The last token in the previous member node. - * @param {number} maxLine The maximum number of allowed line difference between consecutive tokens. - * @returns {Token} The first token among the consecutive tokens. - */ - function findFirstConsecutiveTokenBefore(nextFirstToken, prevLastToken, maxLine) { - const before = sourceCode.getTokenBefore(nextFirstToken, { includeComments: true }); - - if (before !== prevLastToken && nextFirstToken.loc.start.line - before.loc.end.line <= maxLine) { - return findFirstConsecutiveTokenBefore(before, prevLastToken, maxLine); - } - return nextFirstToken; - } - - /** - * Checks if there is a token or comment between two tokens. - * @param {Token} before The token before. - * @param {Token} after The token after. - * @returns {boolean} True if there is a token or comment between two tokens. - */ - function hasTokenOrCommentBetween(before, after) { - return sourceCode.getTokensBetween(before, after, { includeComments: true }).length !== 0; - } - - return { - ClassBody(node) { - const body = node.body; - - for (let i = 0; i < body.length - 1; i++) { - const curFirst = sourceCode.getFirstToken(body[i]); - const curLast = sourceCode.getLastToken(body[i]); - const nextFirst = sourceCode.getFirstToken(body[i + 1]); - const isMulti = !astUtils.isTokenOnSameLine(curFirst, curLast); - const skip = !isMulti && options[1].exceptAfterSingleLine; - const beforePadding = findLastConsecutiveTokenAfter(curLast, nextFirst, 1); - const afterPadding = findFirstConsecutiveTokenBefore(nextFirst, curLast, 1); - const isPadded = afterPadding.loc.start.line - beforePadding.loc.end.line > 1; - const hasTokenInPadding = hasTokenOrCommentBetween(beforePadding, afterPadding); - const curLineLastToken = findLastConsecutiveTokenAfter(curLast, nextFirst, 0); - - if ((options[0] === "always" && !skip && !isPadded) || - (options[0] === "never" && isPadded)) { - context.report({ - node: body[i + 1], - messageId: isPadded ? "never" : "always", - fix(fixer) { - if (hasTokenInPadding) { - return null; - } - return isPadded - ? fixer.replaceTextRange([beforePadding.range[1], afterPadding.range[0]], "\n") - : fixer.insertTextAfter(curLineLastToken, "\n"); - } - }); - } - } - } - }; - } -}; - -/** - * @fileoverview Enforce a maximum number of classes per file - * @author James Garbutt - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var maxClassesPerFile = { - meta: { - type: "suggestion", - - docs: { - description: "enforce a maximum number of classes per file", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/max-classes-per-file" - }, - - schema: [ - { - type: "integer", - minimum: 1 - } - ], - - messages: { - maximumExceeded: "File has too many classes ({{ classCount }}). Maximum allowed is {{ max }}." - } - }, - create(context) { - - const maxClasses = context.options[0] || 1; - - let classCount = 0; - - return { - Program() { - classCount = 0; - }, - "Program:exit"(node) { - if (classCount > maxClasses) { - context.report({ - node, - messageId: "maximumExceeded", - data: { - classCount, - max: maxClasses - } - }); - } - }, - "ClassDeclaration, ClassExpression"() { - classCount++; - } - }; - } -}; - -/** - * @fileoverview A rule to set the maximum depth block can be nested in a function. - * @author Ian Christian Myers - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var maxDepth = { - meta: { - type: "suggestion", - - docs: { - description: "enforce a maximum depth that blocks can be nested", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/max-depth" - }, - - schema: [ - { - oneOf: [ - { - type: "integer", - minimum: 0 - }, - { - type: "object", - properties: { - maximum: { - type: "integer", - minimum: 0 - }, - max: { - type: "integer", - minimum: 0 - } - }, - additionalProperties: false - } - ] - } - ], - messages: { - tooDeeply: "Blocks are nested too deeply ({{depth}}). Maximum allowed is {{maxDepth}}." - } - }, - - create(context) { - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - const functionStack = [], - option = context.options[0]; - let maxDepth = 4; - - if ( - typeof option === "object" && - (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max")) - ) { - maxDepth = option.maximum || option.max; - } - if (typeof option === "number") { - maxDepth = option; - } - - /** - * When parsing a new function, store it in our function stack - * @returns {void} - * @private - */ - function startFunction() { - functionStack.push(0); - } - - /** - * When parsing is done then pop out the reference - * @returns {void} - * @private - */ - function endFunction() { - functionStack.pop(); - } - - /** - * Save the block and Evaluate the node - * @param {ASTNode} node node to evaluate - * @returns {void} - * @private - */ - function pushBlock(node) { - const len = ++functionStack[functionStack.length - 1]; - - if (len > maxDepth) { - context.report({ node, messageId: "tooDeeply", data: { depth: len, maxDepth } }); - } - } - - /** - * Pop the saved block - * @returns {void} - * @private - */ - function popBlock() { - functionStack[functionStack.length - 1]--; - } - - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- - - return { - Program: startFunction, - FunctionDeclaration: startFunction, - FunctionExpression: startFunction, - ArrowFunctionExpression: startFunction, - - IfStatement(node) { - if (node.parent.type !== "IfStatement") { - pushBlock(node); - } - }, - SwitchStatement: pushBlock, - TryStatement: pushBlock, - DoWhileStatement: pushBlock, - WhileStatement: pushBlock, - WithStatement: pushBlock, - ForStatement: pushBlock, - ForInStatement: pushBlock, - ForOfStatement: pushBlock, - - "IfStatement:exit": popBlock, - "SwitchStatement:exit": popBlock, - "TryStatement:exit": popBlock, - "DoWhileStatement:exit": popBlock, - "WhileStatement:exit": popBlock, - "WithStatement:exit": popBlock, - "ForStatement:exit": popBlock, - "ForInStatement:exit": popBlock, - "ForOfStatement:exit": popBlock, - - "FunctionDeclaration:exit": endFunction, - "FunctionExpression:exit": endFunction, - "ArrowFunctionExpression:exit": endFunction, - "Program:exit": endFunction - }; - - } -}; - -/** - * @fileoverview Rule to check for max length on a line. - * @author Matt DuVall - */ - -//------------------------------------------------------------------------------ -// Constants -//------------------------------------------------------------------------------ - -const OPTIONS_SCHEMA$1 = { - type: "object", - properties: { - code: { - type: "integer", - minimum: 0 - }, - comments: { - type: "integer", - minimum: 0 - }, - tabWidth: { - type: "integer", - minimum: 0 - }, - ignorePattern: { - type: "string" - }, - ignoreComments: { - type: "boolean" - }, - ignoreStrings: { - type: "boolean" - }, - ignoreUrls: { - type: "boolean" - }, - ignoreTemplateLiterals: { - type: "boolean" - }, - ignoreRegExpLiterals: { - type: "boolean" - }, - ignoreTrailingComments: { - type: "boolean" - } - }, - additionalProperties: false -}; - -const OPTIONS_OR_INTEGER_SCHEMA$1 = { - anyOf: [ - OPTIONS_SCHEMA$1, - { - type: "integer", - minimum: 0 - } - ] -}; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var maxLen = { - meta: { - type: "layout", - - docs: { - description: "enforce a maximum line length", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/max-len" - }, - - schema: [ - OPTIONS_OR_INTEGER_SCHEMA$1, - OPTIONS_OR_INTEGER_SCHEMA$1, - OPTIONS_SCHEMA$1 - ], - messages: { - max: "This line has a length of {{lineLength}}. Maximum allowed is {{maxLength}}.", - maxComment: "This line has a comment length of {{lineLength}}. Maximum allowed is {{maxCommentLength}}." - } - }, - - create(context) { - - /* - * Inspired by http://tools.ietf.org/html/rfc3986#appendix-B, however: - * - They're matching an entire string that we know is a URI - * - We're matching part of a string where we think there *might* be a URL - * - We're only concerned about URLs, as picking out any URI would cause - * too many false positives - * - We don't care about matching the entire URL, any small segment is fine - */ - const URL_REGEXP = /[^:/?#]:\/\/[^?#]/u; - - const sourceCode = context.getSourceCode(); - - /** - * Computes the length of a line that may contain tabs. The width of each - * tab will be the number of spaces to the next tab stop. - * @param {string} line The line. - * @param {int} tabWidth The width of each tab stop in spaces. - * @returns {int} The computed line length. - * @private - */ - function computeLineLength(line, tabWidth) { - let extraCharacterCount = 0; - - line.replace(/\t/gu, (match, offset) => { - const totalOffset = offset + extraCharacterCount, - previousTabStopOffset = tabWidth ? totalOffset % tabWidth : 0, - spaceCount = tabWidth - previousTabStopOffset; - - extraCharacterCount += spaceCount - 1; // -1 for the replaced tab - }); - return Array.from(line).length + extraCharacterCount; - } - - // The options object must be the last option specified… - const options = Object.assign({}, context.options[context.options.length - 1]); - - // …but max code length… - if (typeof context.options[0] === "number") { - options.code = context.options[0]; - } - - // …and tabWidth can be optionally specified directly as integers. - if (typeof context.options[1] === "number") { - options.tabWidth = context.options[1]; - } - - const maxLength = typeof options.code === "number" ? options.code : 80, - tabWidth = typeof options.tabWidth === "number" ? options.tabWidth : 4, - ignoreComments = !!options.ignoreComments, - ignoreStrings = !!options.ignoreStrings, - ignoreTemplateLiterals = !!options.ignoreTemplateLiterals, - ignoreRegExpLiterals = !!options.ignoreRegExpLiterals, - ignoreTrailingComments = !!options.ignoreTrailingComments || !!options.ignoreComments, - ignoreUrls = !!options.ignoreUrls, - maxCommentLength = options.comments; - let ignorePattern = options.ignorePattern || null; - - if (ignorePattern) { - ignorePattern = new RegExp(ignorePattern, "u"); - } - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Tells if a given comment is trailing: it starts on the current line and - * extends to or past the end of the current line. - * @param {string} line The source line we want to check for a trailing comment on - * @param {number} lineNumber The one-indexed line number for line - * @param {ASTNode} comment The comment to inspect - * @returns {boolean} If the comment is trailing on the given line - */ - function isTrailingComment(line, lineNumber, comment) { - return comment && - (comment.loc.start.line === lineNumber && lineNumber <= comment.loc.end.line) && - (comment.loc.end.line > lineNumber || comment.loc.end.column === line.length); - } - - /** - * Tells if a comment encompasses the entire line. - * @param {string} line The source line with a trailing comment - * @param {number} lineNumber The one-indexed line number this is on - * @param {ASTNode} comment The comment to remove - * @returns {boolean} If the comment covers the entire line - */ - function isFullLineComment(line, lineNumber, comment) { - const start = comment.loc.start, - end = comment.loc.end, - isFirstTokenOnLine = !line.slice(0, comment.loc.start.column).trim(); - - return comment && - (start.line < lineNumber || (start.line === lineNumber && isFirstTokenOnLine)) && - (end.line > lineNumber || (end.line === lineNumber && end.column === line.length)); - } - - /** - * Check if a node is a JSXEmptyExpression contained in a single line JSXExpressionContainer. - * @param {ASTNode} node A node to check. - * @returns {boolean} True if the node is a JSXEmptyExpression contained in a single line JSXExpressionContainer. - */ - function isJSXEmptyExpressionInSingleLineContainer(node) { - if (!node || !node.parent || node.type !== "JSXEmptyExpression" || node.parent.type !== "JSXExpressionContainer") { - return false; - } - - const parent = node.parent; - - return parent.loc.start.line === parent.loc.end.line; - } - - /** - * Gets the line after the comment and any remaining trailing whitespace is - * stripped. - * @param {string} line The source line with a trailing comment - * @param {ASTNode} comment The comment to remove - * @returns {string} Line without comment and trailing whitespace - */ - function stripTrailingComment(line, comment) { - - // loc.column is zero-indexed - return line.slice(0, comment.loc.start.column).replace(/\s+$/u, ""); - } - - /** - * Ensure that an array exists at [key] on `object`, and add `value` to it. - * @param {Object} object the object to mutate - * @param {string} key the object's key - * @param {*} value the value to add - * @returns {void} - * @private - */ - function ensureArrayAndPush(object, key, value) { - if (!Array.isArray(object[key])) { - object[key] = []; - } - object[key].push(value); - } - - /** - * Retrieves an array containing all strings (" or ') in the source code. - * @returns {ASTNode[]} An array of string nodes. - */ - function getAllStrings() { - return sourceCode.ast.tokens.filter(token => (token.type === "String" || - (token.type === "JSXText" && sourceCode.getNodeByRangeIndex(token.range[0] - 1).type === "JSXAttribute"))); - } - - /** - * Retrieves an array containing all template literals in the source code. - * @returns {ASTNode[]} An array of template literal nodes. - */ - function getAllTemplateLiterals() { - return sourceCode.ast.tokens.filter(token => token.type === "Template"); - } - - - /** - * Retrieves an array containing all RegExp literals in the source code. - * @returns {ASTNode[]} An array of RegExp literal nodes. - */ - function getAllRegExpLiterals() { - return sourceCode.ast.tokens.filter(token => token.type === "RegularExpression"); - } - - - /** - * A reducer to group an AST node by line number, both start and end. - * @param {Object} acc the accumulator - * @param {ASTNode} node the AST node in question - * @returns {Object} the modified accumulator - * @private - */ - function groupByLineNumber(acc, node) { - for (let i = node.loc.start.line; i <= node.loc.end.line; ++i) { - ensureArrayAndPush(acc, i, node); - } - return acc; - } - - /** - * Returns an array of all comments in the source code. - * If the element in the array is a JSXEmptyExpression contained with a single line JSXExpressionContainer, - * the element is changed with JSXExpressionContainer node. - * @returns {ASTNode[]} An array of comment nodes - */ - function getAllComments() { - const comments = []; - - sourceCode.getAllComments() - .forEach(commentNode => { - const containingNode = sourceCode.getNodeByRangeIndex(commentNode.range[0]); - - if (isJSXEmptyExpressionInSingleLineContainer(containingNode)) { - - // push a unique node only - if (comments[comments.length - 1] !== containingNode.parent) { - comments.push(containingNode.parent); - } - } else { - comments.push(commentNode); - } - }); - - return comments; - } - - /** - * Check the program for max length - * @param {ASTNode} node Node to examine - * @returns {void} - * @private - */ - function checkProgramForMaxLength(node) { - - // split (honors line-ending) - const lines = sourceCode.lines, - - // list of comments to ignore - comments = ignoreComments || maxCommentLength || ignoreTrailingComments ? getAllComments() : []; - - // we iterate over comments in parallel with the lines - let commentsIndex = 0; - - const strings = getAllStrings(); - const stringsByLine = strings.reduce(groupByLineNumber, {}); - - const templateLiterals = getAllTemplateLiterals(); - const templateLiteralsByLine = templateLiterals.reduce(groupByLineNumber, {}); - - const regExpLiterals = getAllRegExpLiterals(); - const regExpLiteralsByLine = regExpLiterals.reduce(groupByLineNumber, {}); - - lines.forEach((line, i) => { - - // i is zero-indexed, line numbers are one-indexed - const lineNumber = i + 1; - - /* - * if we're checking comment length; we need to know whether this - * line is a comment - */ - let lineIsComment = false; - let textToMeasure; - - /* - * We can short-circuit the comment checks if we're already out of - * comments to check. - */ - if (commentsIndex < comments.length) { - let comment = null; - - // iterate over comments until we find one past the current line - do { - comment = comments[++commentsIndex]; - } while (comment && comment.loc.start.line <= lineNumber); - - // and step back by one - comment = comments[--commentsIndex]; - - if (isFullLineComment(line, lineNumber, comment)) { - lineIsComment = true; - textToMeasure = line; - } else if (ignoreTrailingComments && isTrailingComment(line, lineNumber, comment)) { - textToMeasure = stripTrailingComment(line, comment); - - // ignore multiple trailing comments in the same line - let lastIndex = commentsIndex; - - while (isTrailingComment(textToMeasure, lineNumber, comments[--lastIndex])) { - textToMeasure = stripTrailingComment(textToMeasure, comments[lastIndex]); - } - } else { - textToMeasure = line; - } - } else { - textToMeasure = line; - } - if (ignorePattern && ignorePattern.test(textToMeasure) || - ignoreUrls && URL_REGEXP.test(textToMeasure) || - ignoreStrings && stringsByLine[lineNumber] || - ignoreTemplateLiterals && templateLiteralsByLine[lineNumber] || - ignoreRegExpLiterals && regExpLiteralsByLine[lineNumber] - ) { - - // ignore this line - return; - } - - const lineLength = computeLineLength(textToMeasure, tabWidth); - const commentLengthApplies = lineIsComment && maxCommentLength; - - if (lineIsComment && ignoreComments) { - return; - } - - const loc = { - start: { - line: lineNumber, - column: 0 - }, - end: { - line: lineNumber, - column: textToMeasure.length - } - }; - - if (commentLengthApplies) { - if (lineLength > maxCommentLength) { - context.report({ - node, - loc, - messageId: "maxComment", - data: { - lineLength, - maxCommentLength - } - }); - } - } else if (lineLength > maxLength) { - context.report({ - node, - loc, - messageId: "max", - data: { - lineLength, - maxLength - } - }); - } - }); - } - - - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- - - return { - Program: checkProgramForMaxLength - }; - - } -}; - -/** - * @fileoverview enforce a maximum file length - * @author Alberto Rodríguez - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var maxLines = { - meta: { - type: "suggestion", - - docs: { - description: "enforce a maximum number of lines per file", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/max-lines" - }, - - schema: [ - { - oneOf: [ - { - type: "integer", - minimum: 0 - }, - { - type: "object", - properties: { - max: { - type: "integer", - minimum: 0 - }, - skipComments: { - type: "boolean" - }, - skipBlankLines: { - type: "boolean" - } - }, - additionalProperties: false - } - ] - } - ], - messages: { - exceed: - "File has too many lines ({{actual}}). Maximum allowed is {{max}}." - } - }, - - create(context) { - const option = context.options[0]; - let max = 300; - - if ( - typeof option === "object" && - Object.prototype.hasOwnProperty.call(option, "max") - ) { - max = option.max; - } else if (typeof option === "number") { - max = option; - } - - const skipComments = option && option.skipComments; - const skipBlankLines = option && option.skipBlankLines; - - const sourceCode = context.getSourceCode(); - - /** - * Returns whether or not a token is a comment node type - * @param {Token} token The token to check - * @returns {boolean} True if the token is a comment node - */ - function isCommentNodeType(token) { - return token && (token.type === "Block" || token.type === "Line"); - } - - /** - * Returns the line numbers of a comment that don't have any code on the same line - * @param {Node} comment The comment node to check - * @returns {number[]} The line numbers - */ - function getLinesWithoutCode(comment) { - let start = comment.loc.start.line; - let end = comment.loc.end.line; - - let token; - - token = comment; - do { - token = sourceCode.getTokenBefore(token, { - includeComments: true - }); - } while (isCommentNodeType(token)); - - if (token && astUtils.isTokenOnSameLine(token, comment)) { - start += 1; - } - - token = comment; - do { - token = sourceCode.getTokenAfter(token, { - includeComments: true - }); - } while (isCommentNodeType(token)); - - if (token && astUtils.isTokenOnSameLine(comment, token)) { - end -= 1; - } - - if (start <= end) { - return lodash__default['default'].range(start, end + 1); - } - return []; - } - - return { - "Program:exit"() { - let lines = sourceCode.lines.map((text, i) => ({ - lineNumber: i + 1, - text - })); - - /* - * If file ends with a linebreak, `sourceCode.lines` will have one extra empty line at the end. - * That isn't a real line, so we shouldn't count it. - */ - if (lines.length > 1 && lodash__default['default'].last(lines).text === "") { - lines.pop(); - } - - if (skipBlankLines) { - lines = lines.filter(l => l.text.trim() !== ""); - } - - if (skipComments) { - const comments = sourceCode.getAllComments(); - - const commentLines = lodash__default['default'].flatten( - comments.map(comment => getLinesWithoutCode(comment)) - ); - - lines = lines.filter( - l => !commentLines.includes(l.lineNumber) - ); - } - - if (lines.length > max) { - const loc = { - start: { - line: lines[max].lineNumber, - column: 0 - }, - end: { - line: sourceCode.lines.length, - column: lodash__default['default'].last(sourceCode.lines).length - } - }; - - context.report({ - loc, - messageId: "exceed", - data: { - max, - actual: lines.length - } - }); - } - } - }; - } -}; - -/** - * @fileoverview A rule to set the maximum number of line of code in a function. - * @author Pete Ward - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - - -//------------------------------------------------------------------------------ -// Constants -//------------------------------------------------------------------------------ - -const OPTIONS_SCHEMA = { - type: "object", - properties: { - max: { - type: "integer", - minimum: 0 - }, - skipComments: { - type: "boolean" - }, - skipBlankLines: { - type: "boolean" - }, - IIFEs: { - type: "boolean" - } - }, - additionalProperties: false -}; - -const OPTIONS_OR_INTEGER_SCHEMA = { - oneOf: [ - OPTIONS_SCHEMA, - { - type: "integer", - minimum: 1 - } - ] -}; - -/** - * Given a list of comment nodes, return a map with numeric keys (source code line numbers) and comment token values. - * @param {Array} comments An array of comment nodes. - * @returns {Map.} A map with numeric keys (source code line numbers) and comment token values. - */ -function getCommentLineNumbers(comments) { - const map = new Map(); - - comments.forEach(comment => { - for (let i = comment.loc.start.line; i <= comment.loc.end.line; i++) { - map.set(i, comment); - } - }); - return map; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var maxLinesPerFunction = { - meta: { - type: "suggestion", - - docs: { - description: "enforce a maximum number of lines of code in a function", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/max-lines-per-function" - }, - - schema: [ - OPTIONS_OR_INTEGER_SCHEMA - ], - messages: { - exceed: "{{name}} has too many lines ({{lineCount}}). Maximum allowed is {{maxLines}}." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const lines = sourceCode.lines; - - const option = context.options[0]; - let maxLines = 50; - let skipComments = false; - let skipBlankLines = false; - let IIFEs = false; - - if (typeof option === "object") { - maxLines = typeof option.max === "number" ? option.max : 50; - skipComments = !!option.skipComments; - skipBlankLines = !!option.skipBlankLines; - IIFEs = !!option.IIFEs; - } else if (typeof option === "number") { - maxLines = option; - } - - const commentLineNumbers = getCommentLineNumbers(sourceCode.getAllComments()); - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Tells if a comment encompasses the entire line. - * @param {string} line The source line with a trailing comment - * @param {number} lineNumber The one-indexed line number this is on - * @param {ASTNode} comment The comment to remove - * @returns {boolean} If the comment covers the entire line - */ - function isFullLineComment(line, lineNumber, comment) { - const start = comment.loc.start, - end = comment.loc.end, - isFirstTokenOnLine = start.line === lineNumber && !line.slice(0, start.column).trim(), - isLastTokenOnLine = end.line === lineNumber && !line.slice(end.column).trim(); - - return comment && - (start.line < lineNumber || isFirstTokenOnLine) && - (end.line > lineNumber || isLastTokenOnLine); - } - - /** - * Identifies is a node is a FunctionExpression which is part of an IIFE - * @param {ASTNode} node Node to test - * @returns {boolean} True if it's an IIFE - */ - function isIIFE(node) { - return (node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression") && node.parent && node.parent.type === "CallExpression" && node.parent.callee === node; - } - - /** - * Identifies is a node is a FunctionExpression which is embedded within a MethodDefinition or Property - * @param {ASTNode} node Node to test - * @returns {boolean} True if it's a FunctionExpression embedded within a MethodDefinition or Property - */ - function isEmbedded(node) { - if (!node.parent) { - return false; - } - if (node !== node.parent.value) { - return false; - } - if (node.parent.type === "MethodDefinition") { - return true; - } - if (node.parent.type === "Property") { - return node.parent.method === true || node.parent.kind === "get" || node.parent.kind === "set"; - } - return false; - } - - /** - * Count the lines in the function - * @param {ASTNode} funcNode Function AST node - * @returns {void} - * @private - */ - function processFunction(funcNode) { - const node = isEmbedded(funcNode) ? funcNode.parent : funcNode; - - if (!IIFEs && isIIFE(node)) { - return; - } - let lineCount = 0; - - for (let i = node.loc.start.line - 1; i < node.loc.end.line; ++i) { - const line = lines[i]; - - if (skipComments) { - if (commentLineNumbers.has(i + 1) && isFullLineComment(line, i + 1, commentLineNumbers.get(i + 1))) { - continue; - } - } - - if (skipBlankLines) { - if (line.match(/^\s*$/u)) { - continue; - } - } - - lineCount++; - } - - if (lineCount > maxLines) { - const name = lodash__default['default'].upperFirst(astUtils.getFunctionNameWithKind(funcNode)); - - context.report({ - node, - messageId: "exceed", - data: { name, lineCount, maxLines } - }); - } - } - - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- - - return { - FunctionDeclaration: processFunction, - FunctionExpression: processFunction, - ArrowFunctionExpression: processFunction - }; - } -}; - -/** - * @fileoverview Rule to enforce a maximum number of nested callbacks. - * @author Ian Christian Myers - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var maxNestedCallbacks = { - meta: { - type: "suggestion", - - docs: { - description: "enforce a maximum depth that callbacks can be nested", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/max-nested-callbacks" - }, - - schema: [ - { - oneOf: [ - { - type: "integer", - minimum: 0 - }, - { - type: "object", - properties: { - maximum: { - type: "integer", - minimum: 0 - }, - max: { - type: "integer", - minimum: 0 - } - }, - additionalProperties: false - } - ] - } - ], - messages: { - exceed: "Too many nested callbacks ({{num}}). Maximum allowed is {{max}}." - } - }, - - create(context) { - - //-------------------------------------------------------------------------- - // Constants - //-------------------------------------------------------------------------- - const option = context.options[0]; - let THRESHOLD = 10; - - if ( - typeof option === "object" && - (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max")) - ) { - THRESHOLD = option.maximum || option.max; - } else if (typeof option === "number") { - THRESHOLD = option; - } - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - const callbackStack = []; - - /** - * Checks a given function node for too many callbacks. - * @param {ASTNode} node The node to check. - * @returns {void} - * @private - */ - function checkFunction(node) { - const parent = node.parent; - - if (parent.type === "CallExpression") { - callbackStack.push(node); - } - - if (callbackStack.length > THRESHOLD) { - const opts = { num: callbackStack.length, max: THRESHOLD }; - - context.report({ node, messageId: "exceed", data: opts }); - } - } - - /** - * Pops the call stack. - * @returns {void} - * @private - */ - function popStack() { - callbackStack.pop(); - } - - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- - - return { - ArrowFunctionExpression: checkFunction, - "ArrowFunctionExpression:exit": popStack, - - FunctionExpression: checkFunction, - "FunctionExpression:exit": popStack - }; - - } -}; - -/** - * @fileoverview Rule to flag when a function has too many parameters - * @author Ilya Volodin - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var maxParams = { - meta: { - type: "suggestion", - - docs: { - description: "enforce a maximum number of parameters in function definitions", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/max-params" - }, - - schema: [ - { - oneOf: [ - { - type: "integer", - minimum: 0 - }, - { - type: "object", - properties: { - maximum: { - type: "integer", - minimum: 0 - }, - max: { - type: "integer", - minimum: 0 - } - }, - additionalProperties: false - } - ] - } - ], - messages: { - exceed: "{{name}} has too many parameters ({{count}}). Maximum allowed is {{max}}." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const option = context.options[0]; - let numParams = 3; - - if ( - typeof option === "object" && - (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max")) - ) { - numParams = option.maximum || option.max; - } - if (typeof option === "number") { - numParams = option; - } - - /** - * Checks a function to see if it has too many parameters. - * @param {ASTNode} node The node to check. - * @returns {void} - * @private - */ - function checkFunction(node) { - if (node.params.length > numParams) { - context.report({ - loc: astUtils.getFunctionHeadLoc(node, sourceCode), - node, - messageId: "exceed", - data: { - name: lodash__default['default'].upperFirst(astUtils.getFunctionNameWithKind(node)), - count: node.params.length, - max: numParams - } - }); - } - } - - return { - FunctionDeclaration: checkFunction, - ArrowFunctionExpression: checkFunction, - FunctionExpression: checkFunction - }; - - } -}; - -/** - * @fileoverview A rule to set the maximum number of statements in a function. - * @author Ian Christian Myers - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var maxStatements = { - meta: { - type: "suggestion", - - docs: { - description: "enforce a maximum number of statements allowed in function blocks", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/max-statements" - }, - - schema: [ - { - oneOf: [ - { - type: "integer", - minimum: 0 - }, - { - type: "object", - properties: { - maximum: { - type: "integer", - minimum: 0 - }, - max: { - type: "integer", - minimum: 0 - } - }, - additionalProperties: false - } - ] - }, - { - type: "object", - properties: { - ignoreTopLevelFunctions: { - type: "boolean" - } - }, - additionalProperties: false - } - ], - messages: { - exceed: "{{name}} has too many statements ({{count}}). Maximum allowed is {{max}}." - } - }, - - create(context) { - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - const functionStack = [], - option = context.options[0], - ignoreTopLevelFunctions = context.options[1] && context.options[1].ignoreTopLevelFunctions || false, - topLevelFunctions = []; - let maxStatements = 10; - - if ( - typeof option === "object" && - (Object.prototype.hasOwnProperty.call(option, "maximum") || Object.prototype.hasOwnProperty.call(option, "max")) - ) { - maxStatements = option.maximum || option.max; - } else if (typeof option === "number") { - maxStatements = option; - } - - /** - * Reports a node if it has too many statements - * @param {ASTNode} node node to evaluate - * @param {int} count Number of statements in node - * @param {int} max Maximum number of statements allowed - * @returns {void} - * @private - */ - function reportIfTooManyStatements(node, count, max) { - if (count > max) { - const name = lodash__default['default'].upperFirst(astUtils.getFunctionNameWithKind(node)); - - context.report({ - node, - messageId: "exceed", - data: { name, count, max } - }); - } - } - - /** - * When parsing a new function, store it in our function stack - * @returns {void} - * @private - */ - function startFunction() { - functionStack.push(0); - } - - /** - * Evaluate the node at the end of function - * @param {ASTNode} node node to evaluate - * @returns {void} - * @private - */ - function endFunction(node) { - const count = functionStack.pop(); - - if (ignoreTopLevelFunctions && functionStack.length === 0) { - topLevelFunctions.push({ node, count }); - } else { - reportIfTooManyStatements(node, count, maxStatements); - } - } - - /** - * Increment the count of the functions - * @param {ASTNode} node node to evaluate - * @returns {void} - * @private - */ - function countStatements(node) { - functionStack[functionStack.length - 1] += node.body.length; - } - - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- - - return { - FunctionDeclaration: startFunction, - FunctionExpression: startFunction, - ArrowFunctionExpression: startFunction, - - BlockStatement: countStatements, - - "FunctionDeclaration:exit": endFunction, - "FunctionExpression:exit": endFunction, - "ArrowFunctionExpression:exit": endFunction, - - "Program:exit"() { - if (topLevelFunctions.length === 1) { - return; - } - - topLevelFunctions.forEach(element => { - const count = element.count; - const node = element.node; - - reportIfTooManyStatements(node, count, maxStatements); - }); - } - }; - - } -}; - -/** - * @fileoverview Specify the maximum number of statements allowed per line. - * @author Kenneth Williams - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var maxStatementsPerLine = { - meta: { - type: "layout", - - docs: { - description: "enforce a maximum number of statements allowed per line", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/max-statements-per-line" - }, - - schema: [ - { - type: "object", - properties: { - max: { - type: "integer", - minimum: 1, - default: 1 - } - }, - additionalProperties: false - } - ], - messages: { - exceed: "This line has {{numberOfStatementsOnThisLine}} {{statements}}. Maximum allowed is {{maxStatementsPerLine}}." - } - }, - - create(context) { - - const sourceCode = context.getSourceCode(), - options = context.options[0] || {}, - maxStatementsPerLine = typeof options.max !== "undefined" ? options.max : 1; - - let lastStatementLine = 0, - numberOfStatementsOnThisLine = 0, - firstExtraStatement; - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - const SINGLE_CHILD_ALLOWED = /^(?:(?:DoWhile|For|ForIn|ForOf|If|Labeled|While)Statement|Export(?:Default|Named)Declaration)$/u; - - /** - * Reports with the first extra statement, and clears it. - * @returns {void} - */ - function reportFirstExtraStatementAndClear() { - if (firstExtraStatement) { - context.report({ - node: firstExtraStatement, - messageId: "exceed", - data: { - numberOfStatementsOnThisLine, - maxStatementsPerLine, - statements: numberOfStatementsOnThisLine === 1 ? "statement" : "statements" - } - }); - } - firstExtraStatement = null; - } - - /** - * Gets the actual last token of a given node. - * @param {ASTNode} node A node to get. This is a node except EmptyStatement. - * @returns {Token} The actual last token. - */ - function getActualLastToken(node) { - return sourceCode.getLastToken(node, astUtils.isNotSemicolonToken); - } - - /** - * Addresses a given node. - * It updates the state of this rule, then reports the node if the node violated this rule. - * @param {ASTNode} node A node to check. - * @returns {void} - */ - function enterStatement(node) { - const line = node.loc.start.line; - - /* - * Skip to allow non-block statements if this is direct child of control statements. - * `if (a) foo();` is counted as 1. - * But `if (a) foo(); else foo();` should be counted as 2. - */ - if (SINGLE_CHILD_ALLOWED.test(node.parent.type) && - node.parent.alternate !== node - ) { - return; - } - - // Update state. - if (line === lastStatementLine) { - numberOfStatementsOnThisLine += 1; - } else { - reportFirstExtraStatementAndClear(); - numberOfStatementsOnThisLine = 1; - lastStatementLine = line; - } - - // Reports if the node violated this rule. - if (numberOfStatementsOnThisLine === maxStatementsPerLine + 1) { - firstExtraStatement = firstExtraStatement || node; - } - } - - /** - * Updates the state of this rule with the end line of leaving node to check with the next statement. - * @param {ASTNode} node A node to check. - * @returns {void} - */ - function leaveStatement(node) { - const line = getActualLastToken(node).loc.end.line; - - // Update state. - if (line !== lastStatementLine) { - reportFirstExtraStatementAndClear(); - numberOfStatementsOnThisLine = 1; - lastStatementLine = line; - } - } - - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- - - return { - BreakStatement: enterStatement, - ClassDeclaration: enterStatement, - ContinueStatement: enterStatement, - DebuggerStatement: enterStatement, - DoWhileStatement: enterStatement, - ExpressionStatement: enterStatement, - ForInStatement: enterStatement, - ForOfStatement: enterStatement, - ForStatement: enterStatement, - FunctionDeclaration: enterStatement, - IfStatement: enterStatement, - ImportDeclaration: enterStatement, - LabeledStatement: enterStatement, - ReturnStatement: enterStatement, - SwitchStatement: enterStatement, - ThrowStatement: enterStatement, - TryStatement: enterStatement, - VariableDeclaration: enterStatement, - WhileStatement: enterStatement, - WithStatement: enterStatement, - ExportNamedDeclaration: enterStatement, - ExportDefaultDeclaration: enterStatement, - ExportAllDeclaration: enterStatement, - - "BreakStatement:exit": leaveStatement, - "ClassDeclaration:exit": leaveStatement, - "ContinueStatement:exit": leaveStatement, - "DebuggerStatement:exit": leaveStatement, - "DoWhileStatement:exit": leaveStatement, - "ExpressionStatement:exit": leaveStatement, - "ForInStatement:exit": leaveStatement, - "ForOfStatement:exit": leaveStatement, - "ForStatement:exit": leaveStatement, - "FunctionDeclaration:exit": leaveStatement, - "IfStatement:exit": leaveStatement, - "ImportDeclaration:exit": leaveStatement, - "LabeledStatement:exit": leaveStatement, - "ReturnStatement:exit": leaveStatement, - "SwitchStatement:exit": leaveStatement, - "ThrowStatement:exit": leaveStatement, - "TryStatement:exit": leaveStatement, - "VariableDeclaration:exit": leaveStatement, - "WhileStatement:exit": leaveStatement, - "WithStatement:exit": leaveStatement, - "ExportNamedDeclaration:exit": leaveStatement, - "ExportDefaultDeclaration:exit": leaveStatement, - "ExportAllDeclaration:exit": leaveStatement, - "Program:exit": reportFirstExtraStatementAndClear - }; - } -}; - -/** - * @fileoverview enforce a particular style for multiline comments - * @author Teddy Katz - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var multilineCommentStyle = { - meta: { - type: "suggestion", - - docs: { - description: "enforce a particular style for multiline comments", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/multiline-comment-style" - }, - - fixable: "whitespace", - schema: [{ enum: ["starred-block", "separate-lines", "bare-block"] }], - messages: { - expectedBlock: "Expected a block comment instead of consecutive line comments.", - expectedBareBlock: "Expected a block comment without padding stars.", - startNewline: "Expected a linebreak after '/*'.", - endNewline: "Expected a linebreak before '*/'.", - missingStar: "Expected a '*' at the start of this line.", - alignment: "Expected this line to be aligned with the start of the comment.", - expectedLines: "Expected multiple line comments instead of a block comment." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const option = context.options[0] || "starred-block"; - - //---------------------------------------------------------------------- - // Helpers - //---------------------------------------------------------------------- - - /** - * Checks if a comment line is starred. - * @param {string} line A string representing a comment line. - * @returns {boolean} Whether or not the comment line is starred. - */ - function isStarredCommentLine(line) { - return /^\s*\*/u.test(line); - } - - /** - * Checks if a comment group is in starred-block form. - * @param {Token[]} commentGroup A group of comments, containing either multiple line comments or a single block comment. - * @returns {boolean} Whether or not the comment group is in starred block form. - */ - function isStarredBlockComment([firstComment]) { - if (firstComment.type !== "Block") { - return false; - } - - const lines = firstComment.value.split(astUtils.LINEBREAK_MATCHER); - - // The first and last lines can only contain whitespace. - return lines.length > 0 && lines.every((line, i) => (i === 0 || i === lines.length - 1 ? /^\s*$/u : /^\s*\*/u).test(line)); - } - - /** - * Checks if a comment group is in JSDoc form. - * @param {Token[]} commentGroup A group of comments, containing either multiple line comments or a single block comment. - * @returns {boolean} Whether or not the comment group is in JSDoc form. - */ - function isJSDocComment([firstComment]) { - if (firstComment.type !== "Block") { - return false; - } - - const lines = firstComment.value.split(astUtils.LINEBREAK_MATCHER); - - return /^\*\s*$/u.test(lines[0]) && - lines.slice(1, -1).every(line => /^\s* /u.test(line)) && - /^\s*$/u.test(lines[lines.length - 1]); - } - - /** - * Processes a comment group that is currently in separate-line form, calculating the offset for each line. - * @param {Token[]} commentGroup A group of comments containing multiple line comments. - * @returns {string[]} An array of the processed lines. - */ - function processSeparateLineComments(commentGroup) { - const allLinesHaveLeadingSpace = commentGroup - .map(({ value }) => value) - .filter(line => line.trim().length) - .every(line => line.startsWith(" ")); - - return commentGroup.map(({ value }) => (allLinesHaveLeadingSpace ? value.replace(/^ /u, "") : value)); - } - - /** - * Processes a comment group that is currently in starred-block form, calculating the offset for each line. - * @param {Token} comment A single block comment token in starred-block form. - * @returns {string[]} An array of the processed lines. - */ - function processStarredBlockComment(comment) { - const lines = comment.value.split(astUtils.LINEBREAK_MATCHER) - .filter((line, i, linesArr) => !(i === 0 || i === linesArr.length - 1)) - .map(line => line.replace(/^\s*$/u, "")); - const allLinesHaveLeadingSpace = lines - .map(line => line.replace(/\s*\*/u, "")) - .filter(line => line.trim().length) - .every(line => line.startsWith(" ")); - - return lines.map(line => line.replace(allLinesHaveLeadingSpace ? /\s*\* ?/u : /\s*\*/u, "")); - } - - /** - * Processes a comment group that is currently in bare-block form, calculating the offset for each line. - * @param {Token} comment A single block comment token in bare-block form. - * @returns {string[]} An array of the processed lines. - */ - function processBareBlockComment(comment) { - const lines = comment.value.split(astUtils.LINEBREAK_MATCHER).map(line => line.replace(/^\s*$/u, "")); - const leadingWhitespace = `${sourceCode.text.slice(comment.range[0] - comment.loc.start.column, comment.range[0])} `; - let offset = ""; - - /* - * Calculate the offset of the least indented line and use that as the basis for offsetting all the lines. - * The first line should not be checked because it is inline with the opening block comment delimiter. - */ - for (const [i, line] of lines.entries()) { - if (!line.trim().length || i === 0) { - continue; - } - - const [, lineOffset] = line.match(/^(\s*\*?\s*)/u); - - if (lineOffset.length < leadingWhitespace.length) { - const newOffset = leadingWhitespace.slice(lineOffset.length - leadingWhitespace.length); - - if (newOffset.length > offset.length) { - offset = newOffset; - } - } - } - - return lines.map(line => { - const match = line.match(/^(\s*\*?\s*)(.*)/u); - const [, lineOffset, lineContents] = match; - - if (lineOffset.length > leadingWhitespace.length) { - return `${lineOffset.slice(leadingWhitespace.length - (offset.length + lineOffset.length))}${lineContents}`; - } - - if (lineOffset.length < leadingWhitespace.length) { - return `${lineOffset.slice(leadingWhitespace.length)}${lineContents}`; - } - - return lineContents; - }); - } - - /** - * Gets a list of comment lines in a group, formatting leading whitespace as necessary. - * @param {Token[]} commentGroup A group of comments containing either multiple line comments or a single block comment. - * @returns {string[]} A list of comment lines. - */ - function getCommentLines(commentGroup) { - const [firstComment] = commentGroup; - - if (firstComment.type === "Line") { - return processSeparateLineComments(commentGroup); - } - - if (isStarredBlockComment(commentGroup)) { - return processStarredBlockComment(firstComment); - } - - return processBareBlockComment(firstComment); - } - - /** - * Gets the initial offset (whitespace) from the beginning of a line to a given comment token. - * @param {Token} comment The token to check. - * @returns {string} The offset from the beginning of a line to the token. - */ - function getInitialOffset(comment) { - return sourceCode.text.slice(comment.range[0] - comment.loc.start.column, comment.range[0]); - } - - /** - * Converts a comment into starred-block form - * @param {Token} firstComment The first comment of the group being converted - * @param {string[]} commentLinesList A list of lines to appear in the new starred-block comment - * @returns {string} A representation of the comment value in starred-block form, excluding start and end markers - */ - function convertToStarredBlock(firstComment, commentLinesList) { - const initialOffset = getInitialOffset(firstComment); - - return `/*\n${commentLinesList.map(line => `${initialOffset} * ${line}`).join("\n")}\n${initialOffset} */`; - } - - /** - * Converts a comment into separate-line form - * @param {Token} firstComment The first comment of the group being converted - * @param {string[]} commentLinesList A list of lines to appear in the new starred-block comment - * @returns {string} A representation of the comment value in separate-line form - */ - function convertToSeparateLines(firstComment, commentLinesList) { - return commentLinesList.map(line => `// ${line}`).join(`\n${getInitialOffset(firstComment)}`); - } - - /** - * Converts a comment into bare-block form - * @param {Token} firstComment The first comment of the group being converted - * @param {string[]} commentLinesList A list of lines to appear in the new starred-block comment - * @returns {string} A representation of the comment value in bare-block form - */ - function convertToBlock(firstComment, commentLinesList) { - return `/* ${commentLinesList.join(`\n${getInitialOffset(firstComment)} `)} */`; - } - - /** - * Each method checks a group of comments to see if it's valid according to the given option. - * @param {Token[]} commentGroup A list of comments that appear together. This will either contain a single - * block comment or multiple line comments. - * @returns {void} - */ - const commentGroupCheckers = { - "starred-block"(commentGroup) { - const [firstComment] = commentGroup; - const commentLines = getCommentLines(commentGroup); - - if (commentLines.some(value => value.includes("*/"))) { - return; - } - - if (commentGroup.length > 1) { - context.report({ - loc: { - start: firstComment.loc.start, - end: commentGroup[commentGroup.length - 1].loc.end - }, - messageId: "expectedBlock", - fix(fixer) { - const range = [firstComment.range[0], commentGroup[commentGroup.length - 1].range[1]]; - - return commentLines.some(value => value.startsWith("/")) - ? null - : fixer.replaceTextRange(range, convertToStarredBlock(firstComment, commentLines)); - } - }); - } else { - const lines = firstComment.value.split(astUtils.LINEBREAK_MATCHER); - const expectedLeadingWhitespace = getInitialOffset(firstComment); - const expectedLinePrefix = `${expectedLeadingWhitespace} *`; - - if (!/^\*?\s*$/u.test(lines[0])) { - const start = firstComment.value.startsWith("*") ? firstComment.range[0] + 1 : firstComment.range[0]; - - context.report({ - loc: { - start: firstComment.loc.start, - end: { line: firstComment.loc.start.line, column: firstComment.loc.start.column + 2 } - }, - messageId: "startNewline", - fix: fixer => fixer.insertTextAfterRange([start, start + 2], `\n${expectedLinePrefix}`) - }); - } - - if (!/^\s*$/u.test(lines[lines.length - 1])) { - context.report({ - loc: { - start: { line: firstComment.loc.end.line, column: firstComment.loc.end.column - 2 }, - end: firstComment.loc.end - }, - messageId: "endNewline", - fix: fixer => fixer.replaceTextRange([firstComment.range[1] - 2, firstComment.range[1]], `\n${expectedLinePrefix}/`) - }); - } - - for (let lineNumber = firstComment.loc.start.line + 1; lineNumber <= firstComment.loc.end.line; lineNumber++) { - const lineText = sourceCode.lines[lineNumber - 1]; - const errorType = isStarredCommentLine(lineText) - ? "alignment" - : "missingStar"; - - if (!lineText.startsWith(expectedLinePrefix)) { - context.report({ - loc: { - start: { line: lineNumber, column: 0 }, - end: { line: lineNumber, column: lineText.length } - }, - messageId: errorType, - fix(fixer) { - const lineStartIndex = sourceCode.getIndexFromLoc({ line: lineNumber, column: 0 }); - - if (errorType === "alignment") { - const [, commentTextPrefix = ""] = lineText.match(/^(\s*\*)/u) || []; - const commentTextStartIndex = lineStartIndex + commentTextPrefix.length; - - return fixer.replaceTextRange([lineStartIndex, commentTextStartIndex], expectedLinePrefix); - } - - const [, commentTextPrefix = ""] = lineText.match(/^(\s*)/u) || []; - const commentTextStartIndex = lineStartIndex + commentTextPrefix.length; - let offset; - - for (const [idx, line] of lines.entries()) { - if (!/\S+/u.test(line)) { - continue; - } - - const lineTextToAlignWith = sourceCode.lines[firstComment.loc.start.line - 1 + idx]; - const [, prefix = "", initialOffset = ""] = lineTextToAlignWith.match(/^(\s*(?:\/?\*)?(\s*))/u) || []; - - offset = `${commentTextPrefix.slice(prefix.length)}${initialOffset}`; - - if (/^\s*\//u.test(lineText) && offset.length === 0) { - offset += " "; - } - break; - } - - return fixer.replaceTextRange([lineStartIndex, commentTextStartIndex], `${expectedLinePrefix}${offset}`); - } - }); - } - } - } - }, - "separate-lines"(commentGroup) { - const [firstComment] = commentGroup; - - if (firstComment.type !== "Block" || isJSDocComment(commentGroup)) { - return; - } - - const commentLines = getCommentLines(commentGroup); - const tokenAfter = sourceCode.getTokenAfter(firstComment, { includeComments: true }); - - if (tokenAfter && firstComment.loc.end.line === tokenAfter.loc.start.line) { - return; - } - - context.report({ - loc: { - start: firstComment.loc.start, - end: { line: firstComment.loc.start.line, column: firstComment.loc.start.column + 2 } - }, - messageId: "expectedLines", - fix(fixer) { - return fixer.replaceText(firstComment, convertToSeparateLines(firstComment, commentLines)); - } - }); - }, - "bare-block"(commentGroup) { - if (isJSDocComment(commentGroup)) { - return; - } - - const [firstComment] = commentGroup; - const commentLines = getCommentLines(commentGroup); - - // Disallows consecutive line comments in favor of using a block comment. - if (firstComment.type === "Line" && commentLines.length > 1 && - !commentLines.some(value => value.includes("*/"))) { - context.report({ - loc: { - start: firstComment.loc.start, - end: commentGroup[commentGroup.length - 1].loc.end - }, - messageId: "expectedBlock", - fix(fixer) { - return fixer.replaceTextRange( - [firstComment.range[0], commentGroup[commentGroup.length - 1].range[1]], - convertToBlock(firstComment, commentLines) - ); - } - }); - } - - // Prohibits block comments from having a * at the beginning of each line. - if (isStarredBlockComment(commentGroup)) { - context.report({ - loc: { - start: firstComment.loc.start, - end: { line: firstComment.loc.start.line, column: firstComment.loc.start.column + 2 } - }, - messageId: "expectedBareBlock", - fix(fixer) { - return fixer.replaceText(firstComment, convertToBlock(firstComment, commentLines)); - } - }); - } - } - }; - - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - - return { - Program() { - return sourceCode.getAllComments() - .filter(comment => comment.type !== "Shebang") - .filter(comment => !astUtils.COMMENTS_IGNORE_PATTERN.test(comment.value)) - .filter(comment => { - const tokenBefore = sourceCode.getTokenBefore(comment, { includeComments: true }); - - return !tokenBefore || tokenBefore.loc.end.line < comment.loc.start.line; - }) - .reduce((commentGroups, comment, index, commentList) => { - const tokenBefore = sourceCode.getTokenBefore(comment, { includeComments: true }); - - if ( - comment.type === "Line" && - index && commentList[index - 1].type === "Line" && - tokenBefore && tokenBefore.loc.end.line === comment.loc.start.line - 1 && - tokenBefore === commentList[index - 1] - ) { - commentGroups[commentGroups.length - 1].push(comment); - } else { - commentGroups.push([comment]); - } - - return commentGroups; - }, []) - .filter(commentGroup => !(commentGroup.length === 1 && commentGroup[0].loc.start.line === commentGroup[0].loc.end.line)) - .forEach(commentGroupCheckers[option]); - } - }; - } -}; - -/** - * @fileoverview Enforce newlines between operands of ternary expressions - * @author Kai Cataldo - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var multilineTernary = { - meta: { - type: "layout", - - docs: { - description: "enforce newlines between operands of ternary expressions", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/multiline-ternary" - }, - - schema: [ - { - enum: ["always", "always-multiline", "never"] - } - ], - - messages: { - expectedTestCons: "Expected newline between test and consequent of ternary expression.", - expectedConsAlt: "Expected newline between consequent and alternate of ternary expression.", - unexpectedTestCons: "Unexpected newline between test and consequent of ternary expression.", - unexpectedConsAlt: "Unexpected newline between consequent and alternate of ternary expression." - }, - - fixable: "whitespace" - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const option = context.options[0]; - const multiline = option !== "never"; - const allowSingleLine = option === "always-multiline"; - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - ConditionalExpression(node) { - const questionToken = sourceCode.getTokenAfter(node.test, astUtils.isNotClosingParenToken); - const colonToken = sourceCode.getTokenAfter(node.consequent, astUtils.isNotClosingParenToken); - - const firstTokenOfTest = sourceCode.getFirstToken(node); - const lastTokenOfTest = sourceCode.getTokenBefore(questionToken); - const firstTokenOfConsequent = sourceCode.getTokenAfter(questionToken); - const lastTokenOfConsequent = sourceCode.getTokenBefore(colonToken); - const firstTokenOfAlternate = sourceCode.getTokenAfter(colonToken); - - const areTestAndConsequentOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfTest, firstTokenOfConsequent); - const areConsequentAndAlternateOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfConsequent, firstTokenOfAlternate); - - const hasComments = !!sourceCode.getCommentsInside(node).length; - - if (!multiline) { - if (!areTestAndConsequentOnSameLine) { - context.report({ - node: node.test, - loc: { - start: firstTokenOfTest.loc.start, - end: lastTokenOfTest.loc.end - }, - messageId: "unexpectedTestCons", - fix: fixer => { - if (hasComments) { - return null; - } - const fixers = []; - const areTestAndQuestionOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfTest, questionToken); - const areQuestionAndConsOnSameLine = astUtils.isTokenOnSameLine(questionToken, firstTokenOfConsequent); - - if (!areTestAndQuestionOnSameLine) { - fixers.push(fixer.removeRange([lastTokenOfTest.range[1], questionToken.range[0]])); - } - if (!areQuestionAndConsOnSameLine) { - fixers.push(fixer.removeRange([questionToken.range[1], firstTokenOfConsequent.range[0]])); - } - - return fixers; - } - }); - } - - if (!areConsequentAndAlternateOnSameLine) { - context.report({ - node: node.consequent, - loc: { - start: firstTokenOfConsequent.loc.start, - end: lastTokenOfConsequent.loc.end - }, - messageId: "unexpectedConsAlt", - fix: fixer => { - if (hasComments) { - return null; - } - const fixers = []; - const areConsAndColonOnSameLine = astUtils.isTokenOnSameLine(lastTokenOfConsequent, colonToken); - const areColonAndAltOnSameLine = astUtils.isTokenOnSameLine(colonToken, firstTokenOfAlternate); - - if (!areConsAndColonOnSameLine) { - fixers.push(fixer.removeRange([lastTokenOfConsequent.range[1], colonToken.range[0]])); - } - if (!areColonAndAltOnSameLine) { - fixers.push(fixer.removeRange([colonToken.range[1], firstTokenOfAlternate.range[0]])); - } - - return fixers; - } - }); - } - } else { - if (allowSingleLine && node.loc.start.line === node.loc.end.line) { - return; - } - - if (areTestAndConsequentOnSameLine) { - context.report({ - node: node.test, - loc: { - start: firstTokenOfTest.loc.start, - end: lastTokenOfTest.loc.end - }, - messageId: "expectedTestCons", - fix: fixer => (hasComments ? null : ( - fixer.replaceTextRange( - [ - lastTokenOfTest.range[1], - questionToken.range[0] - ], - "\n" - ) - )) - }); - } - - if (areConsequentAndAlternateOnSameLine) { - context.report({ - node: node.consequent, - loc: { - start: firstTokenOfConsequent.loc.start, - end: lastTokenOfConsequent.loc.end - }, - messageId: "expectedConsAlt", - fix: (fixer => (hasComments ? null : ( - fixer.replaceTextRange( - [ - lastTokenOfConsequent.range[1], - colonToken.range[0] - ], - "\n" - ) - ))) - }); - } - } - } - }; - } -}; - -/** - * @fileoverview Rule to flag use of constructors without capital letters - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const CAPS_ALLOWED = [ - "Array", - "Boolean", - "Date", - "Error", - "Function", - "Number", - "Object", - "RegExp", - "String", - "Symbol", - "BigInt" -]; - -/** - * Ensure that if the key is provided, it must be an array. - * @param {Object} obj Object to check with `key`. - * @param {string} key Object key to check on `obj`. - * @param {*} fallback If obj[key] is not present, this will be returned. - * @returns {string[]} Returns obj[key] if it's an Array, otherwise `fallback` - */ -function checkArray(obj, key, fallback) { - - /* istanbul ignore if */ - if (Object.prototype.hasOwnProperty.call(obj, key) && !Array.isArray(obj[key])) { - throw new TypeError(`${key}, if provided, must be an Array`); - } - return obj[key] || fallback; -} - -/** - * A reducer function to invert an array to an Object mapping the string form of the key, to `true`. - * @param {Object} map Accumulator object for the reduce. - * @param {string} key Object key to set to `true`. - * @returns {Object} Returns the updated Object for further reduction. - */ -function invert(map, key) { - map[key] = true; - return map; -} - -/** - * Creates an object with the cap is new exceptions as its keys and true as their values. - * @param {Object} config Rule configuration - * @returns {Object} Object with cap is new exceptions. - */ -function calculateCapIsNewExceptions(config) { - let capIsNewExceptions = checkArray(config, "capIsNewExceptions", CAPS_ALLOWED); - - if (capIsNewExceptions !== CAPS_ALLOWED) { - capIsNewExceptions = capIsNewExceptions.concat(CAPS_ALLOWED); - } - - return capIsNewExceptions.reduce(invert, {}); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var newCap = { - meta: { - type: "suggestion", - - docs: { - description: "require constructor names to begin with a capital letter", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/new-cap" - }, - - schema: [ - { - type: "object", - properties: { - newIsCap: { - type: "boolean", - default: true - }, - capIsNew: { - type: "boolean", - default: true - }, - newIsCapExceptions: { - type: "array", - items: { - type: "string" - } - }, - newIsCapExceptionPattern: { - type: "string" - }, - capIsNewExceptions: { - type: "array", - items: { - type: "string" - } - }, - capIsNewExceptionPattern: { - type: "string" - }, - properties: { - type: "boolean", - default: true - } - }, - additionalProperties: false - } - ], - messages: { - upper: "A function with a name starting with an uppercase letter should only be used as a constructor.", - lower: "A constructor name should not start with a lowercase letter." - } - }, - - create(context) { - - const config = Object.assign({}, context.options[0]); - - config.newIsCap = config.newIsCap !== false; - config.capIsNew = config.capIsNew !== false; - const skipProperties = config.properties === false; - - const newIsCapExceptions = checkArray(config, "newIsCapExceptions", []).reduce(invert, {}); - const newIsCapExceptionPattern = config.newIsCapExceptionPattern ? new RegExp(config.newIsCapExceptionPattern, "u") : null; - - const capIsNewExceptions = calculateCapIsNewExceptions(config); - const capIsNewExceptionPattern = config.capIsNewExceptionPattern ? new RegExp(config.capIsNewExceptionPattern, "u") : null; - - const listeners = {}; - - const sourceCode = context.getSourceCode(); - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Get exact callee name from expression - * @param {ASTNode} node CallExpression or NewExpression node - * @returns {string} name - */ - function extractNameFromExpression(node) { - return node.callee.type === "Identifier" - ? node.callee.name - : astUtils.getStaticPropertyName(node.callee) || ""; - } - - /** - * Returns the capitalization state of the string - - * Whether the first character is uppercase, lowercase, or non-alphabetic - * @param {string} str String - * @returns {string} capitalization state: "non-alpha", "lower", or "upper" - */ - function getCap(str) { - const firstChar = str.charAt(0); - - const firstCharLower = firstChar.toLowerCase(); - const firstCharUpper = firstChar.toUpperCase(); - - if (firstCharLower === firstCharUpper) { - - // char has no uppercase variant, so it's non-alphabetic - return "non-alpha"; - } - if (firstChar === firstCharLower) { - return "lower"; - } - return "upper"; - - } - - /** - * Check if capitalization is allowed for a CallExpression - * @param {Object} allowedMap Object mapping calleeName to a Boolean - * @param {ASTNode} node CallExpression node - * @param {string} calleeName Capitalized callee name from a CallExpression - * @param {Object} pattern RegExp object from options pattern - * @returns {boolean} Returns true if the callee may be capitalized - */ - function isCapAllowed(allowedMap, node, calleeName, pattern) { - const sourceText = sourceCode.getText(node.callee); - - if (allowedMap[calleeName] || allowedMap[sourceText]) { - return true; - } - - if (pattern && pattern.test(sourceText)) { - return true; - } - - const callee = astUtils.skipChainExpression(node.callee); - - if (calleeName === "UTC" && callee.type === "MemberExpression") { - - // allow if callee is Date.UTC - return callee.object.type === "Identifier" && - callee.object.name === "Date"; - } - - return skipProperties && callee.type === "MemberExpression"; - } - - /** - * Reports the given messageId for the given node. The location will be the start of the property or the callee. - * @param {ASTNode} node CallExpression or NewExpression node. - * @param {string} messageId The messageId to report. - * @returns {void} - */ - function report(node, messageId) { - let callee = astUtils.skipChainExpression(node.callee); - - if (callee.type === "MemberExpression") { - callee = callee.property; - } - - context.report({ node, loc: callee.loc, messageId }); - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - if (config.newIsCap) { - listeners.NewExpression = function(node) { - - const constructorName = extractNameFromExpression(node); - - if (constructorName) { - const capitalization = getCap(constructorName); - const isAllowed = capitalization !== "lower" || isCapAllowed(newIsCapExceptions, node, constructorName, newIsCapExceptionPattern); - - if (!isAllowed) { - report(node, "lower"); - } - } - }; - } - - if (config.capIsNew) { - listeners.CallExpression = function(node) { - - const calleeName = extractNameFromExpression(node); - - if (calleeName) { - const capitalization = getCap(calleeName); - const isAllowed = capitalization !== "upper" || isCapAllowed(capIsNewExceptions, node, calleeName, capIsNewExceptionPattern); - - if (!isAllowed) { - report(node, "upper"); - } - } - }; - } - - return listeners; - } -}; - -/** - * @fileoverview Rule to flag when using constructor without parentheses - * @author Ilya Volodin - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var newParens = { - meta: { - type: "layout", - - docs: { - description: "enforce or disallow parentheses when invoking a constructor with no arguments", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/new-parens" - }, - - fixable: "code", - schema: { - anyOf: [ - { - type: "array", - items: [ - { - enum: ["always", "never"] - } - ], - minItems: 0, - maxItems: 1 - } - ] - }, - messages: { - missing: "Missing '()' invoking a constructor.", - unnecessary: "Unnecessary '()' invoking a constructor with no arguments." - } - }, - - create(context) { - const options = context.options; - const always = options[0] !== "never"; // Default is always - - const sourceCode = context.getSourceCode(); - - return { - NewExpression(node) { - if (node.arguments.length !== 0) { - return; // if there are arguments, there have to be parens - } - - const lastToken = sourceCode.getLastToken(node); - const hasLastParen = lastToken && astUtils.isClosingParenToken(lastToken); - - // `hasParens` is true only if the new expression ends with its own parens, e.g., new new foo() does not end with its own parens - const hasParens = hasLastParen && - astUtils.isOpeningParenToken(sourceCode.getTokenBefore(lastToken)) && - node.callee.range[1] < node.range[1]; - - if (always) { - if (!hasParens) { - context.report({ - node, - messageId: "missing", - fix: fixer => fixer.insertTextAfter(node, "()") - }); - } - } else { - if (hasParens) { - context.report({ - node, - messageId: "unnecessary", - fix: fixer => [ - fixer.remove(sourceCode.getTokenBefore(lastToken)), - fixer.remove(lastToken), - fixer.insertTextBefore(node, "("), - fixer.insertTextAfter(node, ")") - ] - }); - } - } - } - }; - } -}; - -/** - * @fileoverview Rule to check empty newline after "var" statement - * @author Gopal Venkatesan - * @deprecated - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var newlineAfterVar = { - meta: { - type: "layout", - - docs: { - description: "require or disallow an empty line after variable declarations", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/newline-after-var" - }, - schema: [ - { - enum: ["never", "always"] - } - ], - fixable: "whitespace", - messages: { - expected: "Expected blank line after variable declarations.", - unexpected: "Unexpected blank line after variable declarations." - }, - - deprecated: true, - - replacedBy: ["padding-line-between-statements"] - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - // Default `mode` to "always". - const mode = context.options[0] === "never" ? "never" : "always"; - - // Cache starting and ending line numbers of comments for faster lookup - const commentEndLine = sourceCode.getAllComments().reduce((result, token) => { - result[token.loc.start.line] = token.loc.end.line; - return result; - }, {}); - - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Gets a token from the given node to compare line to the next statement. - * - * In general, the token is the last token of the node. However, the token is the second last token if the following conditions satisfy. - * - * - The last token is semicolon. - * - The semicolon is on a different line from the previous token of the semicolon. - * - * This behavior would address semicolon-less style code. e.g.: - * - * var foo = 1 - * - * ;(a || b).doSomething() - * @param {ASTNode} node The node to get. - * @returns {Token} The token to compare line to the next statement. - */ - function getLastToken(node) { - const lastToken = sourceCode.getLastToken(node); - - if (lastToken.type === "Punctuator" && lastToken.value === ";") { - const prevToken = sourceCode.getTokenBefore(lastToken); - - if (prevToken.loc.end.line !== lastToken.loc.start.line) { - return prevToken; - } - } - - return lastToken; - } - - /** - * Determine if provided keyword is a variable declaration - * @private - * @param {string} keyword keyword to test - * @returns {boolean} True if `keyword` is a type of var - */ - function isVar(keyword) { - return keyword === "var" || keyword === "let" || keyword === "const"; - } - - /** - * Determine if provided keyword is a variant of for specifiers - * @private - * @param {string} keyword keyword to test - * @returns {boolean} True if `keyword` is a variant of for specifier - */ - function isForTypeSpecifier(keyword) { - return keyword === "ForStatement" || keyword === "ForInStatement" || keyword === "ForOfStatement"; - } - - /** - * Determine if provided keyword is an export specifiers - * @private - * @param {string} nodeType nodeType to test - * @returns {boolean} True if `nodeType` is an export specifier - */ - function isExportSpecifier(nodeType) { - return nodeType === "ExportNamedDeclaration" || nodeType === "ExportSpecifier" || - nodeType === "ExportDefaultDeclaration" || nodeType === "ExportAllDeclaration"; - } - - /** - * Determine if provided node is the last of their parent block. - * @private - * @param {ASTNode} node node to test - * @returns {boolean} True if `node` is last of their parent block. - */ - function isLastNode(node) { - const token = sourceCode.getTokenAfter(node); - - return !token || (token.type === "Punctuator" && token.value === "}"); - } - - /** - * Gets the last line of a group of consecutive comments - * @param {number} commentStartLine The starting line of the group - * @returns {number} The number of the last comment line of the group - */ - function getLastCommentLineOfBlock(commentStartLine) { - const currentCommentEnd = commentEndLine[commentStartLine]; - - return commentEndLine[currentCommentEnd + 1] ? getLastCommentLineOfBlock(currentCommentEnd + 1) : currentCommentEnd; - } - - /** - * Determine if a token starts more than one line after a comment ends - * @param {token} token The token being checked - * @param {integer} commentStartLine The line number on which the comment starts - * @returns {boolean} True if `token` does not start immediately after a comment - */ - function hasBlankLineAfterComment(token, commentStartLine) { - return token.loc.start.line > getLastCommentLineOfBlock(commentStartLine) + 1; - } - - /** - * Checks that a blank line exists after a variable declaration when mode is - * set to "always", or checks that there is no blank line when mode is set - * to "never" - * @private - * @param {ASTNode} node `VariableDeclaration` node to test - * @returns {void} - */ - function checkForBlankLine(node) { - - /* - * lastToken is the last token on the node's line. It will usually also be the last token of the node, but it will - * sometimes be second-last if there is a semicolon on a different line. - */ - const lastToken = getLastToken(node), - - /* - * If lastToken is the last token of the node, nextToken should be the token after the node. Otherwise, nextToken - * is the last token of the node. - */ - nextToken = lastToken === sourceCode.getLastToken(node) ? sourceCode.getTokenAfter(node) : sourceCode.getLastToken(node), - nextLineNum = lastToken.loc.end.line + 1; - - // Ignore if there is no following statement - if (!nextToken) { - return; - } - - // Ignore if parent of node is a for variant - if (isForTypeSpecifier(node.parent.type)) { - return; - } - - // Ignore if parent of node is an export specifier - if (isExportSpecifier(node.parent.type)) { - return; - } - - /* - * Some coding styles use multiple `var` statements, so do nothing if - * the next token is a `var` statement. - */ - if (nextToken.type === "Keyword" && isVar(nextToken.value)) { - return; - } - - // Ignore if it is last statement in a block - if (isLastNode(node)) { - return; - } - - // Next statement is not a `var`... - const noNextLineToken = nextToken.loc.start.line > nextLineNum; - const hasNextLineComment = (typeof commentEndLine[nextLineNum] !== "undefined"); - - if (mode === "never" && noNextLineToken && !hasNextLineComment) { - context.report({ - node, - messageId: "unexpected", - data: { identifier: node.name }, - fix(fixer) { - const linesBetween = sourceCode.getText().slice(lastToken.range[1], nextToken.range[0]).split(astUtils.LINEBREAK_MATCHER); - - return fixer.replaceTextRange([lastToken.range[1], nextToken.range[0]], `${linesBetween.slice(0, -1).join("")}\n${linesBetween[linesBetween.length - 1]}`); - } - }); - } - - // Token on the next line, or comment without blank line - if ( - mode === "always" && ( - !noNextLineToken || - hasNextLineComment && !hasBlankLineAfterComment(nextToken, nextLineNum) - ) - ) { - context.report({ - node, - messageId: "expected", - data: { identifier: node.name }, - fix(fixer) { - if ((noNextLineToken ? getLastCommentLineOfBlock(nextLineNum) : lastToken.loc.end.line) === nextToken.loc.start.line) { - return fixer.insertTextBefore(nextToken, "\n\n"); - } - - return fixer.insertTextBeforeRange([nextToken.range[0] - nextToken.loc.start.column, nextToken.range[1]], "\n"); - } - }); - } - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - VariableDeclaration: checkForBlankLine - }; - - } -}; - -/** - * @fileoverview Rule to require newlines before `return` statement - * @author Kai Cataldo - * @deprecated - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var newlineBeforeReturn = { - meta: { - type: "layout", - - docs: { - description: "require an empty line before `return` statements", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/newline-before-return" - }, - - fixable: "whitespace", - schema: [], - messages: { - expected: "Expected newline before return statement." - }, - - deprecated: true, - replacedBy: ["padding-line-between-statements"] - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Tests whether node is preceded by supplied tokens - * @param {ASTNode} node node to check - * @param {Array} testTokens array of tokens to test against - * @returns {boolean} Whether or not the node is preceded by one of the supplied tokens - * @private - */ - function isPrecededByTokens(node, testTokens) { - const tokenBefore = sourceCode.getTokenBefore(node); - - return testTokens.some(token => tokenBefore.value === token); - } - - /** - * Checks whether node is the first node after statement or in block - * @param {ASTNode} node node to check - * @returns {boolean} Whether or not the node is the first node after statement or in block - * @private - */ - function isFirstNode(node) { - const parentType = node.parent.type; - - if (node.parent.body) { - return Array.isArray(node.parent.body) - ? node.parent.body[0] === node - : node.parent.body === node; - } - - if (parentType === "IfStatement") { - return isPrecededByTokens(node, ["else", ")"]); - } - if (parentType === "DoWhileStatement") { - return isPrecededByTokens(node, ["do"]); - } - if (parentType === "SwitchCase") { - return isPrecededByTokens(node, [":"]); - } - return isPrecededByTokens(node, [")"]); - - } - - /** - * Returns the number of lines of comments that precede the node - * @param {ASTNode} node node to check for overlapping comments - * @param {number} lineNumTokenBefore line number of previous token, to check for overlapping comments - * @returns {number} Number of lines of comments that precede the node - * @private - */ - function calcCommentLines(node, lineNumTokenBefore) { - const comments = sourceCode.getCommentsBefore(node); - let numLinesComments = 0; - - if (!comments.length) { - return numLinesComments; - } - - comments.forEach(comment => { - numLinesComments++; - - if (comment.type === "Block") { - numLinesComments += comment.loc.end.line - comment.loc.start.line; - } - - // avoid counting lines with inline comments twice - if (comment.loc.start.line === lineNumTokenBefore) { - numLinesComments--; - } - - if (comment.loc.end.line === node.loc.start.line) { - numLinesComments--; - } - }); - - return numLinesComments; - } - - /** - * Returns the line number of the token before the node that is passed in as an argument - * @param {ASTNode} node The node to use as the start of the calculation - * @returns {number} Line number of the token before `node` - * @private - */ - function getLineNumberOfTokenBefore(node) { - const tokenBefore = sourceCode.getTokenBefore(node); - let lineNumTokenBefore; - - /** - * Global return (at the beginning of a script) is a special case. - * If there is no token before `return`, then we expect no line - * break before the return. Comments are allowed to occupy lines - * before the global return, just no blank lines. - * Setting lineNumTokenBefore to zero in that case results in the - * desired behavior. - */ - if (tokenBefore) { - lineNumTokenBefore = tokenBefore.loc.end.line; - } else { - lineNumTokenBefore = 0; // global return at beginning of script - } - - return lineNumTokenBefore; - } - - /** - * Checks whether node is preceded by a newline - * @param {ASTNode} node node to check - * @returns {boolean} Whether or not the node is preceded by a newline - * @private - */ - function hasNewlineBefore(node) { - const lineNumNode = node.loc.start.line; - const lineNumTokenBefore = getLineNumberOfTokenBefore(node); - const commentLines = calcCommentLines(node, lineNumTokenBefore); - - return (lineNumNode - lineNumTokenBefore - commentLines) > 1; - } - - /** - * Checks whether it is safe to apply a fix to a given return statement. - * - * The fix is not considered safe if the given return statement has leading comments, - * as we cannot safely determine if the newline should be added before or after the comments. - * For more information, see: https://github.com/eslint/eslint/issues/5958#issuecomment-222767211 - * @param {ASTNode} node The return statement node to check. - * @returns {boolean} `true` if it can fix the node. - * @private - */ - function canFix(node) { - const leadingComments = sourceCode.getCommentsBefore(node); - const lastLeadingComment = leadingComments[leadingComments.length - 1]; - const tokenBefore = sourceCode.getTokenBefore(node); - - if (leadingComments.length === 0) { - return true; - } - - /* - * if the last leading comment ends in the same line as the previous token and - * does not share a line with the `return` node, we can consider it safe to fix. - * Example: - * function a() { - * var b; //comment - * return; - * } - */ - if (lastLeadingComment.loc.end.line === tokenBefore.loc.end.line && - lastLeadingComment.loc.end.line !== node.loc.start.line) { - return true; - } - - return false; - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - ReturnStatement(node) { - if (!isFirstNode(node) && !hasNewlineBefore(node)) { - context.report({ - node, - messageId: "expected", - fix(fixer) { - if (canFix(node)) { - const tokenBefore = sourceCode.getTokenBefore(node); - const newlines = node.loc.start.line === tokenBefore.loc.end.line ? "\n\n" : "\n"; - - return fixer.insertTextBefore(node, newlines); - } - return null; - } - }); - } - } - }; - } -}; - -/** - * @fileoverview Rule to ensure newline per method call when chaining calls - * @author Rajendra Patil - * @author Burak Yigit Kaya - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var newlinePerChainedCall = { - meta: { - type: "layout", - - docs: { - description: "require a newline after each call in a method chain", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/newline-per-chained-call" - }, - - fixable: "whitespace", - - schema: [{ - type: "object", - properties: { - ignoreChainWithDepth: { - type: "integer", - minimum: 1, - maximum: 10, - default: 2 - } - }, - additionalProperties: false - }], - messages: { - expected: "Expected line break before `{{callee}}`." - } - }, - - create(context) { - - const options = context.options[0] || {}, - ignoreChainWithDepth = options.ignoreChainWithDepth || 2; - - const sourceCode = context.getSourceCode(); - - /** - * Get the prefix of a given MemberExpression node. - * If the MemberExpression node is a computed value it returns a - * left bracket. If not it returns a period. - * @param {ASTNode} node A MemberExpression node to get - * @returns {string} The prefix of the node. - */ - function getPrefix(node) { - if (node.computed) { - if (node.optional) { - return "?.["; - } - return "["; - } - if (node.optional) { - return "?."; - } - return "."; - } - - /** - * Gets the property text of a given MemberExpression node. - * If the text is multiline, this returns only the first line. - * @param {ASTNode} node A MemberExpression node to get. - * @returns {string} The property text of the node. - */ - function getPropertyText(node) { - const prefix = getPrefix(node); - const lines = sourceCode.getText(node.property).split(astUtils.LINEBREAK_MATCHER); - const suffix = node.computed && lines.length === 1 ? "]" : ""; - - return prefix + lines[0] + suffix; - } - - return { - "CallExpression:exit"(node) { - const callee = astUtils.skipChainExpression(node.callee); - - if (callee.type !== "MemberExpression") { - return; - } - - let parent = astUtils.skipChainExpression(callee.object); - let depth = 1; - - while (parent && parent.callee) { - depth += 1; - parent = astUtils.skipChainExpression(astUtils.skipChainExpression(parent.callee).object); - } - - if (depth > ignoreChainWithDepth && astUtils.isTokenOnSameLine(callee.object, callee.property)) { - const firstTokenAfterObject = sourceCode.getTokenAfter(callee.object, astUtils.isNotClosingParenToken); - - context.report({ - node: callee.property, - loc: { - start: firstTokenAfterObject.loc.start, - end: callee.loc.end - }, - messageId: "expected", - data: { - callee: getPropertyText(callee) - }, - fix(fixer) { - return fixer.insertTextBefore(firstTokenAfterObject, "\n"); - } - }); - } - } - }; - } -}; - -/** - * @fileoverview Rule to flag use of alert, confirm, prompt - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -const { - getStaticPropertyName: getPropertyName$2, - getVariableByName, - skipChainExpression -} = astUtils; - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks if the given name is a prohibited identifier. - * @param {string} name The name to check - * @returns {boolean} Whether or not the name is prohibited. - */ -function isProhibitedIdentifier(name) { - return /^(alert|confirm|prompt)$/u.test(name); -} - -/** - * Finds the eslint-scope reference in the given scope. - * @param {Object} scope The scope to search. - * @param {ASTNode} node The identifier node. - * @returns {Reference|null} Returns the found reference or null if none were found. - */ -function findReference(scope, node) { - const references = scope.references.filter(reference => reference.identifier.range[0] === node.range[0] && - reference.identifier.range[1] === node.range[1]); - - if (references.length === 1) { - return references[0]; - } - return null; -} - -/** - * Checks if the given identifier node is shadowed in the given scope. - * @param {Object} scope The current scope. - * @param {string} node The identifier node to check - * @returns {boolean} Whether or not the name is shadowed. - */ -function isShadowed$1(scope, node) { - const reference = findReference(scope, node); - - return reference && reference.resolved && reference.resolved.defs.length > 0; -} - -/** - * Checks if the given identifier node is a ThisExpression in the global scope or the global window property. - * @param {Object} scope The current scope. - * @param {string} node The identifier node to check - * @returns {boolean} Whether or not the node is a reference to the global object. - */ -function isGlobalThisReferenceOrGlobalWindow(scope, node) { - if (scope.type === "global" && node.type === "ThisExpression") { - return true; - } - if ( - node.type === "Identifier" && - ( - node.name === "window" || - (node.name === "globalThis" && getVariableByName(scope, "globalThis")) - ) - ) { - return !isShadowed$1(scope, node); - } - - return false; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noAlert = { - meta: { - type: "suggestion", - - docs: { - description: "disallow the use of `alert`, `confirm`, and `prompt`", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-alert" - }, - - schema: [], - - messages: { - unexpected: "Unexpected {{name}}." - } - }, - - create(context) { - return { - CallExpression(node) { - const callee = skipChainExpression(node.callee), - currentScope = context.getScope(); - - // without window. - if (callee.type === "Identifier") { - const name = callee.name; - - if (!isShadowed$1(currentScope, callee) && isProhibitedIdentifier(callee.name)) { - context.report({ - node, - messageId: "unexpected", - data: { name } - }); - } - - } else if (callee.type === "MemberExpression" && isGlobalThisReferenceOrGlobalWindow(currentScope, callee.object)) { - const name = getPropertyName$2(callee); - - if (isProhibitedIdentifier(name)) { - context.report({ - node, - messageId: "unexpected", - data: { name } - }); - } - } - } - }; - - } -}; - -/** - * @fileoverview Disallow construction of dense arrays using the Array constructor - * @author Matt DuVall - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noArrayConstructor = { - meta: { - type: "suggestion", - - docs: { - description: "disallow `Array` constructors", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/no-array-constructor" - }, - - schema: [], - - messages: { - preferLiteral: "The array literal notation [] is preferable." - } - }, - - create(context) { - - /** - * Disallow construction of dense arrays using the Array constructor - * @param {ASTNode} node node to evaluate - * @returns {void} - * @private - */ - function check(node) { - if ( - node.arguments.length !== 1 && - node.callee.type === "Identifier" && - node.callee.name === "Array" - ) { - context.report({ node, messageId: "preferLiteral" }); - } - } - - return { - CallExpression: check, - NewExpression: check - }; - - } -}; - -/** - * @fileoverview disallow using an async function as a Promise executor - * @author Teddy Katz - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noAsyncPromiseExecutor = { - meta: { - type: "problem", - - docs: { - description: "disallow using an async function as a Promise executor", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-async-promise-executor" - }, - - fixable: null, - schema: [], - messages: { - async: "Promise executor functions should not be async." - } - }, - - create(context) { - return { - "NewExpression[callee.name='Promise'][arguments.0.async=true]"(node) { - context.report({ - node: context.getSourceCode().getFirstToken(node.arguments[0], token => token.value === "async"), - messageId: "async" - }); - } - }; - } -}; - -/** - * @fileoverview Rule to disallow uses of await inside of loops. - * @author Nat Mote (nmote) - */ - -/** - * Check whether it should stop traversing ancestors at the given node. - * @param {ASTNode} node A node to check. - * @returns {boolean} `true` if it should stop traversing. - */ -function isBoundary(node) { - const t = node.type; - - return ( - t === "FunctionDeclaration" || - t === "FunctionExpression" || - t === "ArrowFunctionExpression" || - - /* - * Don't report the await expressions on for-await-of loop since it's - * asynchronous iteration intentionally. - */ - (t === "ForOfStatement" && node.await === true) - ); -} - -/** - * Check whether the given node is in loop. - * @param {ASTNode} node A node to check. - * @param {ASTNode} parent A parent node to check. - * @returns {boolean} `true` if the node is in loop. - */ -function isLooped(node, parent) { - switch (parent.type) { - case "ForStatement": - return ( - node === parent.test || - node === parent.update || - node === parent.body - ); - - case "ForOfStatement": - case "ForInStatement": - return node === parent.body; - - case "WhileStatement": - case "DoWhileStatement": - return node === parent.test || node === parent.body; - - default: - return false; - } -} - -var noAwaitInLoop = { - meta: { - type: "problem", - - docs: { - description: "disallow `await` inside of loops", - category: "Possible Errors", - recommended: false, - url: "https://eslint.org/docs/rules/no-await-in-loop" - }, - - schema: [], - - messages: { - unexpectedAwait: "Unexpected `await` inside a loop." - } - }, - create(context) { - - /** - * Validate an await expression. - * @param {ASTNode} awaitNode An AwaitExpression or ForOfStatement node to validate. - * @returns {void} - */ - function validate(awaitNode) { - if (awaitNode.type === "ForOfStatement" && !awaitNode.await) { - return; - } - - let node = awaitNode; - let parent = node.parent; - - while (parent && !isBoundary(parent)) { - if (isLooped(node, parent)) { - context.report({ - node: awaitNode, - messageId: "unexpectedAwait" - }); - return; - } - node = parent; - parent = parent.parent; - } - } - - return { - AwaitExpression: validate, - ForOfStatement: validate - }; - } -}; - -/** - * @fileoverview Rule to flag bitwise identifiers - * @author Nicholas C. Zakas - */ - -/* - * - * Set of bitwise operators. - * - */ -const BITWISE_OPERATORS$1 = [ - "^", "|", "&", "<<", ">>", ">>>", - "^=", "|=", "&=", "<<=", ">>=", ">>>=", - "~" -]; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noBitwise = { - meta: { - type: "suggestion", - - docs: { - description: "disallow bitwise operators", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/no-bitwise" - }, - - schema: [ - { - type: "object", - properties: { - allow: { - type: "array", - items: { - enum: BITWISE_OPERATORS$1 - }, - uniqueItems: true - }, - int32Hint: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - messages: { - unexpected: "Unexpected use of '{{operator}}'." - } - }, - - create(context) { - const options = context.options[0] || {}; - const allowed = options.allow || []; - const int32Hint = options.int32Hint === true; - - /** - * Reports an unexpected use of a bitwise operator. - * @param {ASTNode} node Node which contains the bitwise operator. - * @returns {void} - */ - function report(node) { - context.report({ node, messageId: "unexpected", data: { operator: node.operator } }); - } - - /** - * Checks if the given node has a bitwise operator. - * @param {ASTNode} node The node to check. - * @returns {boolean} Whether or not the node has a bitwise operator. - */ - function hasBitwiseOperator(node) { - return BITWISE_OPERATORS$1.indexOf(node.operator) !== -1; - } - - /** - * Checks if exceptions were provided, e.g. `{ allow: ['~', '|'] }`. - * @param {ASTNode} node The node to check. - * @returns {boolean} Whether or not the node has a bitwise operator. - */ - function allowedOperator(node) { - return allowed.indexOf(node.operator) !== -1; - } - - /** - * Checks if the given bitwise operator is used for integer typecasting, i.e. "|0" - * @param {ASTNode} node The node to check. - * @returns {boolean} whether the node is used in integer typecasting. - */ - function isInt32Hint(node) { - return int32Hint && node.operator === "|" && node.right && - node.right.type === "Literal" && node.right.value === 0; - } - - /** - * Report if the given node contains a bitwise operator. - * @param {ASTNode} node The node to check. - * @returns {void} - */ - function checkNodeForBitwiseOperator(node) { - if (hasBitwiseOperator(node) && !allowedOperator(node) && !isInt32Hint(node)) { - report(node); - } - } - - return { - AssignmentExpression: checkNodeForBitwiseOperator, - BinaryExpression: checkNodeForBitwiseOperator, - UnaryExpression: checkNodeForBitwiseOperator - }; - - } -}; - -/** - * @fileoverview disallow use of the Buffer() constructor - * @author Teddy Katz - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noBufferConstructor = { - meta: { - deprecated: true, - - replacedBy: [], - - type: "problem", - - docs: { - description: "disallow use of the `Buffer()` constructor", - category: "Node.js and CommonJS", - recommended: false, - url: "https://eslint.org/docs/rules/no-buffer-constructor" - }, - - schema: [], - - messages: { - deprecated: "{{expr}} is deprecated. Use Buffer.from(), Buffer.alloc(), or Buffer.allocUnsafe() instead." - } - }, - - create(context) { - - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - - return { - "CallExpression[callee.name='Buffer'], NewExpression[callee.name='Buffer']"(node) { - context.report({ - node, - messageId: "deprecated", - data: { expr: node.type === "CallExpression" ? "Buffer()" : "new Buffer()" } - }); - } - }; - } -}; - -/** - * @fileoverview Rule to flag use of arguments.callee and arguments.caller. - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noCaller = { - meta: { - type: "suggestion", - - docs: { - description: "disallow the use of `arguments.caller` or `arguments.callee`", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-caller" - }, - - schema: [], - - messages: { - unexpected: "Avoid arguments.{{prop}}." - } - }, - - create(context) { - - return { - - MemberExpression(node) { - const objectName = node.object.name, - propertyName = node.property.name; - - if (objectName === "arguments" && !node.computed && propertyName && propertyName.match(/^calle[er]$/u)) { - context.report({ node, messageId: "unexpected", data: { prop: propertyName } }); - } - - } - }; - - } -}; - -/** - * @fileoverview Rule to flag use of an lexical declarations inside a case clause - * @author Erik Arvidsson - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noCaseDeclarations = { - meta: { - type: "suggestion", - - docs: { - description: "disallow lexical declarations in case clauses", - category: "Best Practices", - recommended: true, - url: "https://eslint.org/docs/rules/no-case-declarations" - }, - - schema: [], - - messages: { - unexpected: "Unexpected lexical declaration in case block." - } - }, - - create(context) { - - /** - * Checks whether or not a node is a lexical declaration. - * @param {ASTNode} node A direct child statement of a switch case. - * @returns {boolean} Whether or not the node is a lexical declaration. - */ - function isLexicalDeclaration(node) { - switch (node.type) { - case "FunctionDeclaration": - case "ClassDeclaration": - return true; - case "VariableDeclaration": - return node.kind !== "var"; - default: - return false; - } - } - - return { - SwitchCase(node) { - for (let i = 0; i < node.consequent.length; i++) { - const statement = node.consequent[i]; - - if (isLexicalDeclaration(statement)) { - context.report({ - node: statement, - messageId: "unexpected" - }); - } - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag variable leak in CatchClauses in IE 8 and earlier - * @author Ian Christian Myers - * @deprecated in ESLint v5.1.0 - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noCatchShadow = { - meta: { - type: "suggestion", - - docs: { - description: "disallow `catch` clause parameters from shadowing variables in the outer scope", - category: "Variables", - recommended: false, - url: "https://eslint.org/docs/rules/no-catch-shadow" - }, - - replacedBy: ["no-shadow"], - - deprecated: true, - schema: [], - - messages: { - mutable: "Value of '{{name}}' may be overwritten in IE 8 and earlier." - } - }, - - create(context) { - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Check if the parameters are been shadowed - * @param {Object} scope current scope - * @param {string} name parameter name - * @returns {boolean} True is its been shadowed - */ - function paramIsShadowing(scope, name) { - return astUtils.getVariableByName(scope, name) !== null; - } - - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- - - return { - - "CatchClause[param!=null]"(node) { - let scope = context.getScope(); - - /* - * When ecmaVersion >= 6, CatchClause creates its own scope - * so start from one upper scope to exclude the current node - */ - if (scope.block === node) { - scope = scope.upper; - } - - if (paramIsShadowing(scope, node.param.name)) { - context.report({ node, messageId: "mutable", data: { name: node.param.name } }); - } - } - }; - - } -}; - -/** - * @fileoverview A rule to disallow modifying variables of class declarations - * @author Toru Nagashima - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noClassAssign = { - meta: { - type: "problem", - - docs: { - description: "disallow reassigning class members", - category: "ECMAScript 6", - recommended: true, - url: "https://eslint.org/docs/rules/no-class-assign" - }, - - schema: [], - - messages: { - class: "'{{name}}' is a class." - } - }, - - create(context) { - - /** - * Finds and reports references that are non initializer and writable. - * @param {Variable} variable A variable to check. - * @returns {void} - */ - function checkVariable(variable) { - astUtils.getModifyingReferences(variable.references).forEach(reference => { - context.report({ node: reference.identifier, messageId: "class", data: { name: reference.identifier.name } }); - - }); - } - - /** - * Finds and reports references that are non initializer and writable. - * @param {ASTNode} node A ClassDeclaration/ClassExpression node to check. - * @returns {void} - */ - function checkForClass(node) { - context.getDeclaredVariables(node).forEach(checkVariable); - } - - return { - ClassDeclaration: checkForClass, - ClassExpression: checkForClass - }; - - } -}; - -/** - * @fileoverview The rule should warn against code that tries to compare against -0. - * @author Aladdin-ADD - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noCompareNegZero = { - meta: { - type: "problem", - - docs: { - description: "disallow comparing against -0", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-compare-neg-zero" - }, - - fixable: null, - schema: [], - - messages: { - unexpected: "Do not use the '{{operator}}' operator to compare against -0." - } - }, - - create(context) { - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Checks a given node is -0 - * @param {ASTNode} node A node to check. - * @returns {boolean} `true` if the node is -0. - */ - function isNegZero(node) { - return node.type === "UnaryExpression" && node.operator === "-" && node.argument.type === "Literal" && node.argument.value === 0; - } - const OPERATORS_TO_CHECK = new Set([">", ">=", "<", "<=", "==", "===", "!=", "!=="]); - - return { - BinaryExpression(node) { - if (OPERATORS_TO_CHECK.has(node.operator)) { - if (isNegZero(node.left) || isNegZero(node.right)) { - context.report({ - node, - messageId: "unexpected", - data: { operator: node.operator } - }); - } - } - } - }; - } -}; - -/** - * @fileoverview Rule to flag assignment in a conditional statement's test expression - * @author Stephen Murray - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const TEST_CONDITION_PARENT_TYPES = new Set(["IfStatement", "WhileStatement", "DoWhileStatement", "ForStatement", "ConditionalExpression"]); - -const NODE_DESCRIPTIONS = { - DoWhileStatement: "a 'do...while' statement", - ForStatement: "a 'for' statement", - IfStatement: "an 'if' statement", - WhileStatement: "a 'while' statement" -}; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noCondAssign = { - meta: { - type: "problem", - - docs: { - description: "disallow assignment operators in conditional expressions", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-cond-assign" - }, - - schema: [ - { - enum: ["except-parens", "always"] - } - ], - - messages: { - unexpected: "Unexpected assignment within {{type}}.", - - // must match JSHint's error message - missing: "Expected a conditional expression and instead saw an assignment." - } - }, - - create(context) { - - const prohibitAssign = (context.options[0] || "except-parens"); - - const sourceCode = context.getSourceCode(); - - /** - * Check whether an AST node is the test expression for a conditional statement. - * @param {!Object} node The node to test. - * @returns {boolean} `true` if the node is the text expression for a conditional statement; otherwise, `false`. - */ - function isConditionalTestExpression(node) { - return node.parent && - TEST_CONDITION_PARENT_TYPES.has(node.parent.type) && - node === node.parent.test; - } - - /** - * Given an AST node, perform a bottom-up search for the first ancestor that represents a conditional statement. - * @param {!Object} node The node to use at the start of the search. - * @returns {?Object} The closest ancestor node that represents a conditional statement. - */ - function findConditionalAncestor(node) { - let currentAncestor = node; - - do { - if (isConditionalTestExpression(currentAncestor)) { - return currentAncestor.parent; - } - } while ((currentAncestor = currentAncestor.parent) && !astUtils.isFunction(currentAncestor)); - - return null; - } - - /** - * Check whether the code represented by an AST node is enclosed in two sets of parentheses. - * @param {!Object} node The node to test. - * @returns {boolean} `true` if the code is enclosed in two sets of parentheses; otherwise, `false`. - */ - function isParenthesisedTwice(node) { - const previousToken = sourceCode.getTokenBefore(node, 1), - nextToken = sourceCode.getTokenAfter(node, 1); - - return astUtils.isParenthesised(sourceCode, node) && - previousToken && astUtils.isOpeningParenToken(previousToken) && previousToken.range[1] <= node.range[0] && - astUtils.isClosingParenToken(nextToken) && nextToken.range[0] >= node.range[1]; - } - - /** - * Check a conditional statement's test expression for top-level assignments that are not enclosed in parentheses. - * @param {!Object} node The node for the conditional statement. - * @returns {void} - */ - function testForAssign(node) { - if (node.test && - (node.test.type === "AssignmentExpression") && - (node.type === "ForStatement" - ? !astUtils.isParenthesised(sourceCode, node.test) - : !isParenthesisedTwice(node.test) - ) - ) { - - context.report({ - node: node.test, - messageId: "missing" - }); - } - } - - /** - * Check whether an assignment expression is descended from a conditional statement's test expression. - * @param {!Object} node The node for the assignment expression. - * @returns {void} - */ - function testForConditionalAncestor(node) { - const ancestor = findConditionalAncestor(node); - - if (ancestor) { - context.report({ - node, - messageId: "unexpected", - data: { - type: NODE_DESCRIPTIONS[ancestor.type] || ancestor.type - } - }); - } - } - - if (prohibitAssign === "always") { - return { - AssignmentExpression: testForConditionalAncestor - }; - } - - return { - DoWhileStatement: testForAssign, - ForStatement: testForAssign, - IfStatement: testForAssign, - WhileStatement: testForAssign, - ConditionalExpression: testForAssign - }; - - } -}; - -/** - * @fileoverview A rule to warn against using arrow functions when they could be - * confused with comparisons - * @author Jxck - */ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether or not a node is a conditional expression. - * @param {ASTNode} node node to test - * @returns {boolean} `true` if the node is a conditional expression. - */ -function isConditional(node) { - return node && node.type === "ConditionalExpression"; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noConfusingArrow = { - meta: { - type: "suggestion", - - docs: { - description: "disallow arrow functions where they could be confused with comparisons", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/no-confusing-arrow" - }, - - fixable: "code", - - schema: [{ - type: "object", - properties: { - allowParens: { type: "boolean", default: true } - }, - additionalProperties: false - }], - - messages: { - confusing: "Arrow function used ambiguously with a conditional expression." - } - }, - - create(context) { - const config = context.options[0] || {}; - const allowParens = config.allowParens || (config.allowParens === void 0); - const sourceCode = context.getSourceCode(); - - - /** - * Reports if an arrow function contains an ambiguous conditional. - * @param {ASTNode} node A node to check and report. - * @returns {void} - */ - function checkArrowFunc(node) { - const body = node.body; - - if (isConditional(body) && !(allowParens && astUtils.isParenthesised(sourceCode, body))) { - context.report({ - node, - messageId: "confusing", - fix(fixer) { - - // if `allowParens` is not set to true don't bother wrapping in parens - return allowParens && fixer.replaceText(node.body, `(${sourceCode.getText(node.body)})`); - } - }); - } - } - - return { - ArrowFunctionExpression: checkArrowFunc - }; - } -}; - -/** - * @fileoverview Rule to flag use of console object - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noConsole = { - meta: { - type: "suggestion", - - docs: { - description: "disallow the use of `console`", - category: "Possible Errors", - recommended: false, - url: "https://eslint.org/docs/rules/no-console" - }, - - schema: [ - { - type: "object", - properties: { - allow: { - type: "array", - items: { - type: "string" - }, - minItems: 1, - uniqueItems: true - } - }, - additionalProperties: false - } - ], - - messages: { - unexpected: "Unexpected console statement." - } - }, - - create(context) { - const options = context.options[0] || {}; - const allowed = options.allow || []; - - /** - * Checks whether the given reference is 'console' or not. - * @param {eslint-scope.Reference} reference The reference to check. - * @returns {boolean} `true` if the reference is 'console'. - */ - function isConsole(reference) { - const id = reference.identifier; - - return id && id.name === "console"; - } - - /** - * Checks whether the property name of the given MemberExpression node - * is allowed by options or not. - * @param {ASTNode} node The MemberExpression node to check. - * @returns {boolean} `true` if the property name of the node is allowed. - */ - function isAllowed(node) { - const propertyName = astUtils.getStaticPropertyName(node); - - return propertyName && allowed.indexOf(propertyName) !== -1; - } - - /** - * Checks whether the given reference is a member access which is not - * allowed by options or not. - * @param {eslint-scope.Reference} reference The reference to check. - * @returns {boolean} `true` if the reference is a member access which - * is not allowed by options. - */ - function isMemberAccessExceptAllowed(reference) { - const node = reference.identifier; - const parent = node.parent; - - return ( - parent.type === "MemberExpression" && - parent.object === node && - !isAllowed(parent) - ); - } - - /** - * Reports the given reference as a violation. - * @param {eslint-scope.Reference} reference The reference to report. - * @returns {void} - */ - function report(reference) { - const node = reference.identifier.parent; - - context.report({ - node, - loc: node.loc, - messageId: "unexpected" - }); - } - - return { - "Program:exit"() { - const scope = context.getScope(); - const consoleVar = astUtils.getVariableByName(scope, "console"); - const shadowed = consoleVar && consoleVar.defs.length > 0; - - /* - * 'scope.through' includes all references to undefined - * variables. If the variable 'console' is not defined, it uses - * 'scope.through'. - */ - const references = consoleVar - ? consoleVar.references - : scope.through.filter(isConsole); - - if (!shadowed) { - references - .filter(isMemberAccessExceptAllowed) - .forEach(report); - } - } - }; - } -}; - -/** - * @fileoverview A rule to disallow modifying variables that are declared using `const` - * @author Toru Nagashima - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noConstAssign = { - meta: { - type: "problem", - - docs: { - description: "disallow reassigning `const` variables", - category: "ECMAScript 6", - recommended: true, - url: "https://eslint.org/docs/rules/no-const-assign" - }, - - schema: [], - - messages: { - const: "'{{name}}' is constant." - } - }, - - create(context) { - - /** - * Finds and reports references that are non initializer and writable. - * @param {Variable} variable A variable to check. - * @returns {void} - */ - function checkVariable(variable) { - astUtils.getModifyingReferences(variable.references).forEach(reference => { - context.report({ node: reference.identifier, messageId: "const", data: { name: reference.identifier.name } }); - }); - } - - return { - VariableDeclaration(node) { - if (node.kind === "const") { - context.getDeclaredVariables(node).forEach(checkVariable); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag use constant conditions - * @author Christian Schulz - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noConstantCondition = { - meta: { - type: "problem", - - docs: { - description: "disallow constant expressions in conditions", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-constant-condition" - }, - - schema: [ - { - type: "object", - properties: { - checkLoops: { - type: "boolean", - default: true - } - }, - additionalProperties: false - } - ], - - messages: { - unexpected: "Unexpected constant condition." - } - }, - - create(context) { - const options = context.options[0] || {}, - checkLoops = options.checkLoops !== false, - loopSetStack = []; - - let loopsInCurrentScope = new Set(); - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Returns literal's value converted to the Boolean type - * @param {ASTNode} node any `Literal` node - * @returns {boolean | null} `true` when node is truthy, `false` when node is falsy, - * `null` when it cannot be determined. - */ - function getBooleanValue(node) { - if (node.value === null) { - - /* - * it might be a null literal or bigint/regex literal in unsupported environments . - * https://github.com/estree/estree/blob/14df8a024956ea289bd55b9c2226a1d5b8a473ee/es5.md#regexpliteral - * https://github.com/estree/estree/blob/14df8a024956ea289bd55b9c2226a1d5b8a473ee/es2020.md#bigintliteral - */ - - if (node.raw === "null") { - return false; - } - - // regex is always truthy - if (typeof node.regex === "object") { - return true; - } - - return null; - } - - return !!node.value; - } - - /** - * Checks if a branch node of LogicalExpression short circuits the whole condition - * @param {ASTNode} node The branch of main condition which needs to be checked - * @param {string} operator The operator of the main LogicalExpression. - * @returns {boolean} true when condition short circuits whole condition - */ - function isLogicalIdentity(node, operator) { - switch (node.type) { - case "Literal": - return (operator === "||" && getBooleanValue(node) === true) || - (operator === "&&" && getBooleanValue(node) === false); - - case "UnaryExpression": - return (operator === "&&" && node.operator === "void"); - - case "LogicalExpression": - - /* - * handles `a && false || b` - * `false` is an identity element of `&&` but not `||` - */ - return operator === node.operator && - ( - isLogicalIdentity(node.left, operator) || - isLogicalIdentity(node.right, operator) - ); - - case "AssignmentExpression": - return ["||=", "&&="].includes(node.operator) && - operator === node.operator.slice(0, -1) && - isLogicalIdentity(node.right, operator); - - // no default - } - return false; - } - - /** - * Checks if a node has a constant truthiness value. - * @param {ASTNode} node The AST node to check. - * @param {boolean} inBooleanPosition `false` if checking branch of a condition. - * `true` in all other cases - * @returns {Bool} true when node's truthiness is constant - * @private - */ - function isConstant(node, inBooleanPosition) { - - // node.elements can return null values in the case of sparse arrays ex. [,] - if (!node) { - return true; - } - switch (node.type) { - case "Literal": - case "ArrowFunctionExpression": - case "FunctionExpression": - case "ObjectExpression": - return true; - case "TemplateLiteral": - return (inBooleanPosition && node.quasis.some(quasi => quasi.value.cooked.length)) || - node.expressions.every(exp => isConstant(exp, inBooleanPosition)); - - case "ArrayExpression": { - if (node.parent.type === "BinaryExpression" && node.parent.operator === "+") { - return node.elements.every(element => isConstant(element, false)); - } - return true; - } - - case "UnaryExpression": - if ( - node.operator === "void" || - node.operator === "typeof" && inBooleanPosition - ) { - return true; - } - - if (node.operator === "!") { - return isConstant(node.argument, true); - } - - return isConstant(node.argument, false); - - case "BinaryExpression": - return isConstant(node.left, false) && - isConstant(node.right, false) && - node.operator !== "in"; - - case "LogicalExpression": { - const isLeftConstant = isConstant(node.left, inBooleanPosition); - const isRightConstant = isConstant(node.right, inBooleanPosition); - const isLeftShortCircuit = (isLeftConstant && isLogicalIdentity(node.left, node.operator)); - const isRightShortCircuit = (inBooleanPosition && isRightConstant && isLogicalIdentity(node.right, node.operator)); - - return (isLeftConstant && isRightConstant) || - isLeftShortCircuit || - isRightShortCircuit; - } - - case "AssignmentExpression": - if (node.operator === "=") { - return isConstant(node.right, inBooleanPosition); - } - - if (["||=", "&&="].includes(node.operator) && inBooleanPosition) { - return isLogicalIdentity(node.right, node.operator.slice(0, -1)); - } - - return false; - - case "SequenceExpression": - return isConstant(node.expressions[node.expressions.length - 1], inBooleanPosition); - - // no default - } - return false; - } - - /** - * Tracks when the given node contains a constant condition. - * @param {ASTNode} node The AST node to check. - * @returns {void} - * @private - */ - function trackConstantConditionLoop(node) { - if (node.test && isConstant(node.test, true)) { - loopsInCurrentScope.add(node); - } - } - - /** - * Reports when the set contains the given constant condition node - * @param {ASTNode} node The AST node to check. - * @returns {void} - * @private - */ - function checkConstantConditionLoopInSet(node) { - if (loopsInCurrentScope.has(node)) { - loopsInCurrentScope.delete(node); - context.report({ node: node.test, messageId: "unexpected" }); - } - } - - /** - * Reports when the given node contains a constant condition. - * @param {ASTNode} node The AST node to check. - * @returns {void} - * @private - */ - function reportIfConstant(node) { - if (node.test && isConstant(node.test, true)) { - context.report({ node: node.test, messageId: "unexpected" }); - } - } - - /** - * Stores current set of constant loops in loopSetStack temporarily - * and uses a new set to track constant loops - * @returns {void} - * @private - */ - function enterFunction() { - loopSetStack.push(loopsInCurrentScope); - loopsInCurrentScope = new Set(); - } - - /** - * Reports when the set still contains stored constant conditions - * @returns {void} - * @private - */ - function exitFunction() { - loopsInCurrentScope = loopSetStack.pop(); - } - - /** - * Checks node when checkLoops option is enabled - * @param {ASTNode} node The AST node to check. - * @returns {void} - * @private - */ - function checkLoop(node) { - if (checkLoops) { - trackConstantConditionLoop(node); - } - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - ConditionalExpression: reportIfConstant, - IfStatement: reportIfConstant, - WhileStatement: checkLoop, - "WhileStatement:exit": checkConstantConditionLoopInSet, - DoWhileStatement: checkLoop, - "DoWhileStatement:exit": checkConstantConditionLoopInSet, - ForStatement: checkLoop, - "ForStatement > .test": node => checkLoop(node.parent), - "ForStatement:exit": checkConstantConditionLoopInSet, - FunctionDeclaration: enterFunction, - "FunctionDeclaration:exit": exitFunction, - FunctionExpression: enterFunction, - "FunctionExpression:exit": exitFunction, - YieldExpression: () => loopsInCurrentScope.clear() - }; - - } -}; - -/** - * @fileoverview Rule to disallow returning value from constructor. - * @author Pig Fang - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noConstructorReturn = { - meta: { - type: "problem", - - docs: { - description: "disallow returning value from constructor", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-constructor-return" - }, - - schema: {}, - - fixable: null, - - messages: { - unexpected: "Unexpected return statement in constructor." - } - }, - - create(context) { - const stack = []; - - return { - onCodePathStart(_, node) { - stack.push(node); - }, - onCodePathEnd() { - stack.pop(); - }, - ReturnStatement(node) { - const last = stack[stack.length - 1]; - - if (!last.parent) { - return; - } - - if ( - last.parent.type === "MethodDefinition" && - last.parent.kind === "constructor" && - (node.parent.parent === last || node.argument) - ) { - context.report({ - node, - messageId: "unexpected" - }); - } - } - }; - } -}; - -/** - * @fileoverview Rule to flag use of continue statement - * @author Borislav Zhivkov - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noContinue = { - meta: { - type: "suggestion", - - docs: { - description: "disallow `continue` statements", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/no-continue" - }, - - schema: [], - - messages: { - unexpected: "Unexpected use of continue statement." - } - }, - - create(context) { - - return { - ContinueStatement(node) { - context.report({ node, messageId: "unexpected" }); - } - }; - - } -}; - -/** - * @fileoverview Rule to forbid control characters from regular expressions. - * @author Nicholas C. Zakas - */ - -const RegExpValidator$1 = regexpp__default['default'].RegExpValidator; -const collector = new (class { - constructor() { - this._source = ""; - this._controlChars = []; - this._validator = new RegExpValidator$1(this); - } - - onPatternEnter() { - this._controlChars = []; - } - - onCharacter(start, end, cp) { - if (cp >= 0x00 && - cp <= 0x1F && - ( - this._source.codePointAt(start) === cp || - this._source.slice(start, end).startsWith("\\x") || - this._source.slice(start, end).startsWith("\\u") - ) - ) { - this._controlChars.push(`\\x${`0${cp.toString(16)}`.slice(-2)}`); - } - } - - collectControlChars(regexpStr) { - try { - this._source = regexpStr; - this._validator.validatePattern(regexpStr); // Call onCharacter hook - } catch { - - // Ignore syntax errors in RegExp. - } - return this._controlChars; - } -})(); - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noControlRegex = { - meta: { - type: "problem", - - docs: { - description: "disallow control characters in regular expressions", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-control-regex" - }, - - schema: [], - - messages: { - unexpected: "Unexpected control character(s) in regular expression: {{controlChars}}." - } - }, - - create(context) { - - /** - * Get the regex expression - * @param {ASTNode} node node to evaluate - * @returns {RegExp|null} Regex if found else null - * @private - */ - function getRegExpPattern(node) { - if (node.regex) { - return node.regex.pattern; - } - if (typeof node.value === "string" && - (node.parent.type === "NewExpression" || node.parent.type === "CallExpression") && - node.parent.callee.type === "Identifier" && - node.parent.callee.name === "RegExp" && - node.parent.arguments[0] === node - ) { - return node.value; - } - - return null; - } - - return { - Literal(node) { - const pattern = getRegExpPattern(node); - - if (pattern) { - const controlCharacters = collector.collectControlChars(pattern); - - if (controlCharacters.length > 0) { - context.report({ - node, - messageId: "unexpected", - data: { - controlChars: controlCharacters.join(", ") - } - }); - } - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag use of a debugger statement - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noDebugger = { - meta: { - type: "problem", - - docs: { - description: "disallow the use of `debugger`", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-debugger" - }, - - fixable: null, - schema: [], - - messages: { - unexpected: "Unexpected 'debugger' statement." - } - }, - - create(context) { - - return { - DebuggerStatement(node) { - context.report({ - node, - messageId: "unexpected" - }); - } - }; - - } -}; - -/** - * @fileoverview Rule to flag when deleting variables - * @author Ilya Volodin - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noDeleteVar = { - meta: { - type: "suggestion", - - docs: { - description: "disallow deleting variables", - category: "Variables", - recommended: true, - url: "https://eslint.org/docs/rules/no-delete-var" - }, - - schema: [], - - messages: { - unexpected: "Variables should not be deleted." - } - }, - - create(context) { - - return { - - UnaryExpression(node) { - if (node.operator === "delete" && node.argument.type === "Identifier") { - context.report({ node, messageId: "unexpected" }); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to check for ambiguous div operator in regexes - * @author Matt DuVall - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noDivRegex = { - meta: { - type: "suggestion", - - docs: { - description: "disallow division operators explicitly at the beginning of regular expressions", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-div-regex" - }, - - fixable: "code", - - schema: [], - - messages: { - unexpected: "A regular expression literal can be confused with '/='." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - return { - - Literal(node) { - const token = sourceCode.getFirstToken(node); - - if (token.type === "RegularExpression" && token.value[1] === "=") { - context.report({ - node, - messageId: "unexpected", - fix(fixer) { - return fixer.replaceTextRange([token.range[0] + 1, token.range[0] + 2], "[=]"); - } - }); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag duplicate arguments - * @author Jamund Ferguson - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noDupeArgs = { - meta: { - type: "problem", - - docs: { - description: "disallow duplicate arguments in `function` definitions", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-dupe-args" - }, - - schema: [], - - messages: { - unexpected: "Duplicate param '{{name}}'." - } - }, - - create(context) { - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Checks whether or not a given definition is a parameter's. - * @param {eslint-scope.DefEntry} def A definition to check. - * @returns {boolean} `true` if the definition is a parameter's. - */ - function isParameter(def) { - return def.type === "Parameter"; - } - - /** - * Determines if a given node has duplicate parameters. - * @param {ASTNode} node The node to check. - * @returns {void} - * @private - */ - function checkParams(node) { - const variables = context.getDeclaredVariables(node); - - for (let i = 0; i < variables.length; ++i) { - const variable = variables[i]; - - // Checks and reports duplications. - const defs = variable.defs.filter(isParameter); - - if (defs.length >= 2) { - context.report({ - node, - messageId: "unexpected", - data: { name: variable.name } - }); - } - } - } - - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- - - return { - FunctionDeclaration: checkParams, - FunctionExpression: checkParams - }; - - } -}; - -/** - * @fileoverview A rule to disallow duplicate name in class members. - * @author Toru Nagashima - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noDupeClassMembers = { - meta: { - type: "problem", - - docs: { - description: "disallow duplicate class members", - category: "ECMAScript 6", - recommended: true, - url: "https://eslint.org/docs/rules/no-dupe-class-members" - }, - - schema: [], - - messages: { - unexpected: "Duplicate name '{{name}}'." - } - }, - - create(context) { - let stack = []; - - /** - * Gets state of a given member name. - * @param {string} name A name of a member. - * @param {boolean} isStatic A flag which specifies that is a static member. - * @returns {Object} A state of a given member name. - * - retv.init {boolean} A flag which shows the name is declared as normal member. - * - retv.get {boolean} A flag which shows the name is declared as getter. - * - retv.set {boolean} A flag which shows the name is declared as setter. - */ - function getState(name, isStatic) { - const stateMap = stack[stack.length - 1]; - const key = `$${name}`; // to avoid "__proto__". - - if (!stateMap[key]) { - stateMap[key] = { - nonStatic: { init: false, get: false, set: false }, - static: { init: false, get: false, set: false } - }; - } - - return stateMap[key][isStatic ? "static" : "nonStatic"]; - } - - return { - - // Initializes the stack of state of member declarations. - Program() { - stack = []; - }, - - // Initializes state of member declarations for the class. - ClassBody() { - stack.push(Object.create(null)); - }, - - // Disposes the state for the class. - "ClassBody:exit"() { - stack.pop(); - }, - - // Reports the node if its name has been declared already. - MethodDefinition(node) { - const name = astUtils.getStaticPropertyName(node); - - if (name === null || node.kind === "constructor") { - return; - } - - const state = getState(name, node.static); - let isDuplicate = false; - - if (node.kind === "get") { - isDuplicate = (state.init || state.get); - state.get = true; - } else if (node.kind === "set") { - isDuplicate = (state.init || state.set); - state.set = true; - } else { - isDuplicate = (state.init || state.get || state.set); - state.init = true; - } - - if (isDuplicate) { - context.report({ node, messageId: "unexpected", data: { name } }); - } - } - }; - } -}; - -/** - * @fileoverview Rule to disallow duplicate conditions in if-else-if chains - * @author Milos Djermanovic - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Determines whether the first given array is a subset of the second given array. - * @param {Function} comparator A function to compare two elements, should return `true` if they are equal. - * @param {Array} arrA The array to compare from. - * @param {Array} arrB The array to compare against. - * @returns {boolean} `true` if the array `arrA` is a subset of the array `arrB`. - */ -function isSubsetByComparator(comparator, arrA, arrB) { - return arrA.every(a => arrB.some(b => comparator(a, b))); -} - -/** - * Splits the given node by the given logical operator. - * @param {string} operator Logical operator `||` or `&&`. - * @param {ASTNode} node The node to split. - * @returns {ASTNode[]} Array of conditions that makes the node when joined by the operator. - */ -function splitByLogicalOperator(operator, node) { - if (node.type === "LogicalExpression" && node.operator === operator) { - return [...splitByLogicalOperator(operator, node.left), ...splitByLogicalOperator(operator, node.right)]; - } - return [node]; -} - -const splitByOr = splitByLogicalOperator.bind(null, "||"); -const splitByAnd = splitByLogicalOperator.bind(null, "&&"); - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noDupeElseIf = { - meta: { - type: "problem", - - docs: { - description: "disallow duplicate conditions in if-else-if chains", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-dupe-else-if" - }, - - schema: [], - - messages: { - unexpected: "This branch can never execute. Its condition is a duplicate or covered by previous conditions in the if-else-if chain." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - /** - * Determines whether the two given nodes are considered to be equal. In particular, given that the nodes - * represent expressions in a boolean context, `||` and `&&` can be considered as commutative operators. - * @param {ASTNode} a First node. - * @param {ASTNode} b Second node. - * @returns {boolean} `true` if the nodes are considered to be equal. - */ - function equal(a, b) { - if (a.type !== b.type) { - return false; - } - - if ( - a.type === "LogicalExpression" && - (a.operator === "||" || a.operator === "&&") && - a.operator === b.operator - ) { - return equal(a.left, b.left) && equal(a.right, b.right) || - equal(a.left, b.right) && equal(a.right, b.left); - } - - return astUtils.equalTokens(a, b, sourceCode); - } - - const isSubset = isSubsetByComparator.bind(null, equal); - - return { - IfStatement(node) { - const test = node.test, - conditionsToCheck = test.type === "LogicalExpression" && test.operator === "&&" - ? [test, ...splitByAnd(test)] - : [test]; - let current = node, - listToCheck = conditionsToCheck.map(c => splitByOr(c).map(splitByAnd)); - - while (current.parent && current.parent.type === "IfStatement" && current.parent.alternate === current) { - current = current.parent; - - const currentOrOperands = splitByOr(current.test).map(splitByAnd); - - listToCheck = listToCheck.map(orOperands => orOperands.filter( - orOperand => !currentOrOperands.some(currentOrOperand => isSubset(currentOrOperand, orOperand)) - )); - - if (listToCheck.some(orOperands => orOperands.length === 0)) { - context.report({ node: test, messageId: "unexpected" }); - break; - } - } - } - }; - } -}; - -/** - * @fileoverview Rule to flag use of duplicate keys in an object. - * @author Ian Christian Myers - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const GET_KIND = /^(?:init|get)$/u; -const SET_KIND = /^(?:init|set)$/u; - -/** - * The class which stores properties' information of an object. - */ -class ObjectInfo { - - // eslint-disable-next-line jsdoc/require-description - /** - * @param {ObjectInfo|null} upper The information of the outer object. - * @param {ASTNode} node The ObjectExpression node of this information. - */ - constructor(upper, node) { - this.upper = upper; - this.node = node; - this.properties = new Map(); - } - - /** - * Gets the information of the given Property node. - * @param {ASTNode} node The Property node to get. - * @returns {{get: boolean, set: boolean}} The information of the property. - */ - getPropertyInfo(node) { - const name = astUtils.getStaticPropertyName(node); - - if (!this.properties.has(name)) { - this.properties.set(name, { get: false, set: false }); - } - return this.properties.get(name); - } - - /** - * Checks whether the given property has been defined already or not. - * @param {ASTNode} node The Property node to check. - * @returns {boolean} `true` if the property has been defined. - */ - isPropertyDefined(node) { - const entry = this.getPropertyInfo(node); - - return ( - (GET_KIND.test(node.kind) && entry.get) || - (SET_KIND.test(node.kind) && entry.set) - ); - } - - /** - * Defines the given property. - * @param {ASTNode} node The Property node to define. - * @returns {void} - */ - defineProperty(node) { - const entry = this.getPropertyInfo(node); - - if (GET_KIND.test(node.kind)) { - entry.get = true; - } - if (SET_KIND.test(node.kind)) { - entry.set = true; - } - } -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noDupeKeys = { - meta: { - type: "problem", - - docs: { - description: "disallow duplicate keys in object literals", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-dupe-keys" - }, - - schema: [], - - messages: { - unexpected: "Duplicate key '{{name}}'." - } - }, - - create(context) { - let info = null; - - return { - ObjectExpression(node) { - info = new ObjectInfo(info, node); - }, - "ObjectExpression:exit"() { - info = info.upper; - }, - - Property(node) { - const name = astUtils.getStaticPropertyName(node); - - // Skip destructuring. - if (node.parent.type !== "ObjectExpression") { - return; - } - - // Skip if the name is not static. - if (name === null) { - return; - } - - // Reports if the name is defined already. - if (info.isPropertyDefined(node)) { - context.report({ - node: info.node, - loc: node.key.loc, - messageId: "unexpected", - data: { name } - }); - } - - // Update info. - info.defineProperty(node); - } - }; - } -}; - -/** - * @fileoverview Rule to disallow a duplicate case label. - * @author Dieter Oberkofler - * @author Burak Yigit Kaya - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noDuplicateCase = { - meta: { - type: "problem", - - docs: { - description: "disallow duplicate case labels", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-duplicate-case" - }, - - schema: [], - - messages: { - unexpected: "Duplicate case label." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - /** - * Determines whether the two given nodes are considered to be equal. - * @param {ASTNode} a First node. - * @param {ASTNode} b Second node. - * @returns {boolean} `true` if the nodes are considered to be equal. - */ - function equal(a, b) { - if (a.type !== b.type) { - return false; - } - - return astUtils.equalTokens(a, b, sourceCode); - } - return { - SwitchStatement(node) { - const previousTests = []; - - for (const switchCase of node.cases) { - if (switchCase.test) { - const test = switchCase.test; - - if (previousTests.some(previousTest => equal(previousTest, test))) { - context.report({ node: switchCase, messageId: "unexpected" }); - } else { - previousTests.push(test); - } - } - } - } - }; - } -}; - -/** - * @fileoverview Restrict usage of duplicate imports. - * @author Simen Bekkhus - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -/** - * Returns the name of the module imported or re-exported. - * @param {ASTNode} node A node to get. - * @returns {string} the name of the module, or empty string if no name. - */ -function getValue(node) { - if (node && node.source && node.source.value) { - return node.source.value.trim(); - } - - return ""; -} - -/** - * Checks if the name of the import or export exists in the given array, and reports if so. - * @param {RuleContext} context The ESLint rule context object. - * @param {ASTNode} node A node to get. - * @param {string} value The name of the imported or exported module. - * @param {string[]} array The array containing other imports or exports in the file. - * @param {string} messageId A messageId to be reported after the name of the module - * - * @returns {void} No return value - */ -function checkAndReport(context, node, value, array, messageId) { - if (array.indexOf(value) !== -1) { - context.report({ - node, - messageId, - data: { - module: value - } - }); - } -} - -/** - * @callback nodeCallback - * @param {ASTNode} node A node to handle. - */ - -/** - * Returns a function handling the imports of a given file - * @param {RuleContext} context The ESLint rule context object. - * @param {boolean} includeExports Whether or not to check for exports in addition to imports. - * @param {string[]} importsInFile The array containing other imports in the file. - * @param {string[]} exportsInFile The array containing other exports in the file. - * - * @returns {nodeCallback} A function passed to ESLint to handle the statement. - */ -function handleImports(context, includeExports, importsInFile, exportsInFile) { - return function(node) { - const value = getValue(node); - - if (value) { - checkAndReport(context, node, value, importsInFile, "import"); - - if (includeExports) { - checkAndReport(context, node, value, exportsInFile, "importAs"); - } - - importsInFile.push(value); - } - }; -} - -/** - * Returns a function handling the exports of a given file - * @param {RuleContext} context The ESLint rule context object. - * @param {string[]} importsInFile The array containing other imports in the file. - * @param {string[]} exportsInFile The array containing other exports in the file. - * - * @returns {nodeCallback} A function passed to ESLint to handle the statement. - */ -function handleExports(context, importsInFile, exportsInFile) { - return function(node) { - const value = getValue(node); - - if (value) { - checkAndReport(context, node, value, exportsInFile, "export"); - checkAndReport(context, node, value, importsInFile, "exportAs"); - - exportsInFile.push(value); - } - }; -} - -var noDuplicateImports = { - meta: { - type: "problem", - - docs: { - description: "disallow duplicate module imports", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/no-duplicate-imports" - }, - - schema: [{ - type: "object", - properties: { - includeExports: { - type: "boolean", - default: false - } - }, - additionalProperties: false - }], - messages: { - import: "'{{module}}' import is duplicated.", - importAs: "'{{module}}' import is duplicated as export.", - export: "'{{module}}' export is duplicated.", - exportAs: "'{{module}}' export is duplicated as import." - } - }, - - create(context) { - const includeExports = (context.options[0] || {}).includeExports, - importsInFile = [], - exportsInFile = []; - - const handlers = { - ImportDeclaration: handleImports(context, includeExports, importsInFile, exportsInFile) - }; - - if (includeExports) { - handlers.ExportNamedDeclaration = handleExports(context, importsInFile, exportsInFile); - handlers.ExportAllDeclaration = handleExports(context, importsInFile, exportsInFile); - } - - return handlers; - } -}; - -/** - * @fileoverview Helper class to aid in constructing fix commands. - * @author Alan Pierce - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -/** - * A helper class to combine fix options into a fix command. Currently, it - * exposes some "retain" methods that extend the range of the text being - * replaced so that other fixes won't touch that region in the same pass. - */ -class FixTracker { - - /** - * Create a new FixTracker. - * @param {ruleFixer} fixer A ruleFixer instance. - * @param {SourceCode} sourceCode A SourceCode object for the current code. - */ - constructor(fixer, sourceCode) { - this.fixer = fixer; - this.sourceCode = sourceCode; - this.retainedRange = null; - } - - /** - * Mark the given range as "retained", meaning that other fixes may not - * may not modify this region in the same pass. - * @param {int[]} range The range to retain. - * @returns {FixTracker} The same RuleFixer, for chained calls. - */ - retainRange(range) { - this.retainedRange = range; - return this; - } - - /** - * Given a node, find the function containing it (or the entire program) and - * mark it as retained, meaning that other fixes may not modify it in this - * pass. This is useful for avoiding conflicts in fixes that modify control - * flow. - * @param {ASTNode} node The node to use as a starting point. - * @returns {FixTracker} The same RuleFixer, for chained calls. - */ - retainEnclosingFunction(node) { - const functionNode = astUtils.getUpperFunction(node); - - return this.retainRange(functionNode ? functionNode.range : this.sourceCode.ast.range); - } - - /** - * Given a node or token, find the token before and afterward, and mark that - * range as retained, meaning that other fixes may not modify it in this - * pass. This is useful for avoiding conflicts in fixes that make a small - * change to the code where the AST should not be changed. - * @param {ASTNode|Token} nodeOrToken The node or token to use as a starting - * point. The token to the left and right are use in the range. - * @returns {FixTracker} The same RuleFixer, for chained calls. - */ - retainSurroundingTokens(nodeOrToken) { - const tokenBefore = this.sourceCode.getTokenBefore(nodeOrToken) || nodeOrToken; - const tokenAfter = this.sourceCode.getTokenAfter(nodeOrToken) || nodeOrToken; - - return this.retainRange([tokenBefore.range[0], tokenAfter.range[1]]); - } - - /** - * Create a fix command that replaces the given range with the given text, - * accounting for any retained ranges. - * @param {int[]} range The range to remove in the fix. - * @param {string} text The text to insert in place of the range. - * @returns {Object} The fix command. - */ - replaceTextRange(range, text) { - let actualRange; - - if (this.retainedRange) { - actualRange = [ - Math.min(this.retainedRange[0], range[0]), - Math.max(this.retainedRange[1], range[1]) - ]; - } else { - actualRange = range; - } - - return this.fixer.replaceTextRange( - actualRange, - this.sourceCode.text.slice(actualRange[0], range[0]) + - text + - this.sourceCode.text.slice(range[1], actualRange[1]) - ); - } - - /** - * Create a fix command that removes the given node or token, accounting for - * any retained ranges. - * @param {ASTNode|Token} nodeOrToken The node or token to remove. - * @returns {Object} The fix command. - */ - remove(nodeOrToken) { - return this.replaceTextRange(nodeOrToken.range, ""); - } -} - -var fixTracker = FixTracker; - -/** - * @fileoverview Rule to flag `else` after a `return` in `if` - * @author Ian Christian Myers - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noElseReturn = { - meta: { - type: "suggestion", - - docs: { - description: "disallow `else` blocks after `return` statements in `if` statements", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-else-return" - }, - - schema: [{ - type: "object", - properties: { - allowElseIf: { - type: "boolean", - default: true - } - }, - additionalProperties: false - }], - - fixable: "code", - - messages: { - unexpected: "Unnecessary 'else' after 'return'." - } - }, - - create(context) { - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Checks whether the given names can be safely used to declare block-scoped variables - * in the given scope. Name collisions can produce redeclaration syntax errors, - * or silently change references and modify behavior of the original code. - * - * This is not a generic function. In particular, it is assumed that the scope is a function scope or - * a function's inner scope, and that the names can be valid identifiers in the given scope. - * @param {string[]} names Array of variable names. - * @param {eslint-scope.Scope} scope Function scope or a function's inner scope. - * @returns {boolean} True if all names can be safely declared, false otherwise. - */ - function isSafeToDeclare(names, scope) { - - if (names.length === 0) { - return true; - } - - const functionScope = scope.variableScope; - - /* - * If this is a function scope, scope.variables will contain parameters, implicit variables such as "arguments", - * all function-scoped variables ('var'), and block-scoped variables defined in the scope. - * If this is an inner scope, scope.variables will contain block-scoped variables defined in the scope. - * - * Redeclaring any of these would cause a syntax error, except for the implicit variables. - */ - const declaredVariables = scope.variables.filter(({ defs }) => defs.length > 0); - - if (declaredVariables.some(({ name }) => names.includes(name))) { - return false; - } - - // Redeclaring a catch variable would also cause a syntax error. - if (scope !== functionScope && scope.upper.type === "catch") { - if (scope.upper.variables.some(({ name }) => names.includes(name))) { - return false; - } - } - - /* - * Redeclaring an implicit variable, such as "arguments", would not cause a syntax error. - * However, if the variable was used, declaring a new one with the same name would change references - * and modify behavior. - */ - const usedImplicitVariables = scope.variables.filter(({ defs, references }) => - defs.length === 0 && references.length > 0); - - if (usedImplicitVariables.some(({ name }) => names.includes(name))) { - return false; - } - - /* - * Declaring a variable with a name that was already used to reference a variable from an upper scope - * would change references and modify behavior. - */ - if (scope.through.some(t => names.includes(t.identifier.name))) { - return false; - } - - /* - * If the scope is an inner scope (not the function scope), an uninitialized `var` variable declared inside - * the scope node (directly or in one of its descendants) is neither declared nor 'through' in the scope. - * - * For example, this would be a syntax error "Identifier 'a' has already been declared": - * function foo() { if (bar) { let a; if (baz) { var a; } } } - */ - if (scope !== functionScope) { - const scopeNodeRange = scope.block.range; - const variablesToCheck = functionScope.variables.filter(({ name }) => names.includes(name)); - - if (variablesToCheck.some(v => v.defs.some(({ node: { range } }) => - scopeNodeRange[0] <= range[0] && range[1] <= scopeNodeRange[1]))) { - return false; - } - } - - return true; - } - - - /** - * Checks whether the removal of `else` and its braces is safe from variable name collisions. - * @param {Node} node The 'else' node. - * @param {eslint-scope.Scope} scope The scope in which the node and the whole 'if' statement is. - * @returns {boolean} True if it is safe, false otherwise. - */ - function isSafeFromNameCollisions(node, scope) { - - if (node.type === "FunctionDeclaration") { - - // Conditional function declaration. Scope and hoisting are unpredictable, different engines work differently. - return false; - } - - if (node.type !== "BlockStatement") { - return true; - } - - const elseBlockScope = scope.childScopes.find(({ block }) => block === node); - - if (!elseBlockScope) { - - // ecmaVersion < 6, `else` block statement cannot have its own scope, no possible collisions. - return true; - } - - /* - * elseBlockScope is supposed to merge into its upper scope. elseBlockScope.variables array contains - * only block-scoped variables (such as let and const variables or class and function declarations) - * defined directly in the elseBlockScope. These are exactly the only names that could cause collisions. - */ - const namesToCheck = elseBlockScope.variables.map(({ name }) => name); - - return isSafeToDeclare(namesToCheck, scope); - } - - /** - * Display the context report if rule is violated - * @param {Node} node The 'else' node - * @returns {void} - */ - function displayReport(node) { - const currentScope = context.getScope(); - - context.report({ - node, - messageId: "unexpected", - fix: fixer => { - - if (!isSafeFromNameCollisions(node, currentScope)) { - return null; - } - - const sourceCode = context.getSourceCode(); - const startToken = sourceCode.getFirstToken(node); - const elseToken = sourceCode.getTokenBefore(startToken); - const source = sourceCode.getText(node); - const lastIfToken = sourceCode.getTokenBefore(elseToken); - let fixedSource, firstTokenOfElseBlock; - - if (startToken.type === "Punctuator" && startToken.value === "{") { - firstTokenOfElseBlock = sourceCode.getTokenAfter(startToken); - } else { - firstTokenOfElseBlock = startToken; - } - - /* - * If the if block does not have curly braces and does not end in a semicolon - * and the else block starts with (, [, /, +, ` or -, then it is not - * safe to remove the else keyword, because ASI will not add a semicolon - * after the if block - */ - const ifBlockMaybeUnsafe = node.parent.consequent.type !== "BlockStatement" && lastIfToken.value !== ";"; - const elseBlockUnsafe = /^[([/+`-]/u.test(firstTokenOfElseBlock.value); - - if (ifBlockMaybeUnsafe && elseBlockUnsafe) { - return null; - } - - const endToken = sourceCode.getLastToken(node); - const lastTokenOfElseBlock = sourceCode.getTokenBefore(endToken); - - if (lastTokenOfElseBlock.value !== ";") { - const nextToken = sourceCode.getTokenAfter(endToken); - - const nextTokenUnsafe = nextToken && /^[([/+`-]/u.test(nextToken.value); - const nextTokenOnSameLine = nextToken && nextToken.loc.start.line === lastTokenOfElseBlock.loc.start.line; - - /* - * If the else block contents does not end in a semicolon, - * and the else block starts with (, [, /, +, ` or -, then it is not - * safe to remove the else block, because ASI will not add a semicolon - * after the remaining else block contents - */ - if (nextTokenUnsafe || (nextTokenOnSameLine && nextToken.value !== "}")) { - return null; - } - } - - if (startToken.type === "Punctuator" && startToken.value === "{") { - fixedSource = source.slice(1, -1); - } else { - fixedSource = source; - } - - /* - * Extend the replacement range to include the entire - * function to avoid conflicting with no-useless-return. - * https://github.com/eslint/eslint/issues/8026 - * - * Also, to avoid name collisions between two else blocks. - */ - return new fixTracker(fixer, sourceCode) - .retainEnclosingFunction(node) - .replaceTextRange([elseToken.range[0], node.range[1]], fixedSource); - } - }); - } - - /** - * Check to see if the node is a ReturnStatement - * @param {Node} node The node being evaluated - * @returns {boolean} True if node is a return - */ - function checkForReturn(node) { - return node.type === "ReturnStatement"; - } - - /** - * Naive return checking, does not iterate through the whole - * BlockStatement because we make the assumption that the ReturnStatement - * will be the last node in the body of the BlockStatement. - * @param {Node} node The consequent/alternate node - * @returns {boolean} True if it has a return - */ - function naiveHasReturn(node) { - if (node.type === "BlockStatement") { - const body = node.body, - lastChildNode = body[body.length - 1]; - - return lastChildNode && checkForReturn(lastChildNode); - } - return checkForReturn(node); - } - - /** - * Check to see if the node is valid for evaluation, - * meaning it has an else. - * @param {Node} node The node being evaluated - * @returns {boolean} True if the node is valid - */ - function hasElse(node) { - return node.alternate && node.consequent; - } - - /** - * If the consequent is an IfStatement, check to see if it has an else - * and both its consequent and alternate path return, meaning this is - * a nested case of rule violation. If-Else not considered currently. - * @param {Node} node The consequent node - * @returns {boolean} True if this is a nested rule violation - */ - function checkForIf(node) { - return node.type === "IfStatement" && hasElse(node) && - naiveHasReturn(node.alternate) && naiveHasReturn(node.consequent); - } - - /** - * Check the consequent/body node to make sure it is not - * a ReturnStatement or an IfStatement that returns on both - * code paths. - * @param {Node} node The consequent or body node - * @returns {boolean} `true` if it is a Return/If node that always returns. - */ - function checkForReturnOrIf(node) { - return checkForReturn(node) || checkForIf(node); - } - - - /** - * Check whether a node returns in every codepath. - * @param {Node} node The node to be checked - * @returns {boolean} `true` if it returns on every codepath. - */ - function alwaysReturns(node) { - if (node.type === "BlockStatement") { - - // If we have a BlockStatement, check each consequent body node. - return node.body.some(checkForReturnOrIf); - } - - /* - * If not a block statement, make sure the consequent isn't a - * ReturnStatement or an IfStatement with returns on both paths. - */ - return checkForReturnOrIf(node); - } - - - /** - * Check the if statement, but don't catch else-if blocks. - * @returns {void} - * @param {Node} node The node for the if statement to check - * @private - */ - function checkIfWithoutElse(node) { - const parent = node.parent; - - /* - * Fixing this would require splitting one statement into two, so no error should - * be reported if this node is in a position where only one statement is allowed. - */ - if (!astUtils.STATEMENT_LIST_PARENTS.has(parent.type)) { - return; - } - - const consequents = []; - let alternate; - - for (let currentNode = node; currentNode.type === "IfStatement"; currentNode = currentNode.alternate) { - if (!currentNode.alternate) { - return; - } - consequents.push(currentNode.consequent); - alternate = currentNode.alternate; - } - - if (consequents.every(alwaysReturns)) { - displayReport(alternate); - } - } - - /** - * Check the if statement - * @returns {void} - * @param {Node} node The node for the if statement to check - * @private - */ - function checkIfWithElse(node) { - const parent = node.parent; - - - /* - * Fixing this would require splitting one statement into two, so no error should - * be reported if this node is in a position where only one statement is allowed. - */ - if (!astUtils.STATEMENT_LIST_PARENTS.has(parent.type)) { - return; - } - - const alternate = node.alternate; - - if (alternate && alwaysReturns(node.consequent)) { - displayReport(alternate); - } - } - - const allowElseIf = !(context.options[0] && context.options[0].allowElseIf === false); - - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- - - return { - - "IfStatement:exit": allowElseIf ? checkIfWithoutElse : checkIfWithElse - - }; - - } -}; - -/** - * @fileoverview Rule to flag use of an empty block statement - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noEmpty = { - meta: { - type: "suggestion", - - docs: { - description: "disallow empty block statements", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-empty" - }, - - schema: [ - { - type: "object", - properties: { - allowEmptyCatch: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - messages: { - unexpected: "Empty {{type}} statement." - } - }, - - create(context) { - const options = context.options[0] || {}, - allowEmptyCatch = options.allowEmptyCatch || false; - - const sourceCode = context.getSourceCode(); - - return { - BlockStatement(node) { - - // if the body is not empty, we can just return immediately - if (node.body.length !== 0) { - return; - } - - // a function is generally allowed to be empty - if (astUtils.isFunction(node.parent)) { - return; - } - - if (allowEmptyCatch && node.parent.type === "CatchClause") { - return; - } - - // any other block is only allowed to be empty, if it contains a comment - if (sourceCode.getCommentsInside(node).length > 0) { - return; - } - - context.report({ node, messageId: "unexpected", data: { type: "block" } }); - }, - - SwitchStatement(node) { - - if (typeof node.cases === "undefined" || node.cases.length === 0) { - context.report({ node, messageId: "unexpected", data: { type: "switch" } }); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag the use of empty character classes in regular expressions - * @author Ian Christian Myers - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/* - * plain-English description of the following regexp: - * 0. `^` fix the match at the beginning of the string - * 1. `\/`: the `/` that begins the regexp - * 2. `([^\\[]|\\.|\[([^\\\]]|\\.)+\])*`: regexp contents; 0 or more of the following - * 2.0. `[^\\[]`: any character that's not a `\` or a `[` (anything but escape sequences and character classes) - * 2.1. `\\.`: an escape sequence - * 2.2. `\[([^\\\]]|\\.)+\]`: a character class that isn't empty - * 3. `\/` the `/` that ends the regexp - * 4. `[gimuy]*`: optional regexp flags - * 5. `$`: fix the match at the end of the string - */ -const regex = /^\/([^\\[]|\\.|\[([^\\\]]|\\.)+\])*\/[gimuys]*$/u; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noEmptyCharacterClass = { - meta: { - type: "problem", - - docs: { - description: "disallow empty character classes in regular expressions", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-empty-character-class" - }, - - schema: [], - - messages: { - unexpected: "Empty class." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - return { - - Literal(node) { - const token = sourceCode.getFirstToken(node); - - if (token.type === "RegularExpression" && !regex.test(token.value)) { - context.report({ node, messageId: "unexpected" }); - } - } - - }; - - } -}; - -/** - * @fileoverview Rule to disallow empty functions. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const ALLOW_OPTIONS = Object.freeze([ - "functions", - "arrowFunctions", - "generatorFunctions", - "methods", - "generatorMethods", - "getters", - "setters", - "constructors", - "asyncFunctions", - "asyncMethods" -]); - -/** - * Gets the kind of a given function node. - * @param {ASTNode} node A function node to get. This is one of - * an ArrowFunctionExpression, a FunctionDeclaration, or a - * FunctionExpression. - * @returns {string} The kind of the function. This is one of "functions", - * "arrowFunctions", "generatorFunctions", "asyncFunctions", "methods", - * "generatorMethods", "asyncMethods", "getters", "setters", and - * "constructors". - */ -function getKind(node) { - const parent = node.parent; - let kind = ""; - - if (node.type === "ArrowFunctionExpression") { - return "arrowFunctions"; - } - - // Detects main kind. - if (parent.type === "Property") { - if (parent.kind === "get") { - return "getters"; - } - if (parent.kind === "set") { - return "setters"; - } - kind = parent.method ? "methods" : "functions"; - - } else if (parent.type === "MethodDefinition") { - if (parent.kind === "get") { - return "getters"; - } - if (parent.kind === "set") { - return "setters"; - } - if (parent.kind === "constructor") { - return "constructors"; - } - kind = "methods"; - - } else { - kind = "functions"; - } - - // Detects prefix. - let prefix = ""; - - if (node.generator) { - prefix = "generator"; - } else if (node.async) { - prefix = "async"; - } else { - return kind; - } - return prefix + kind[0].toUpperCase() + kind.slice(1); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noEmptyFunction = { - meta: { - type: "suggestion", - - docs: { - description: "disallow empty functions", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-empty-function" - }, - - schema: [ - { - type: "object", - properties: { - allow: { - type: "array", - items: { enum: ALLOW_OPTIONS }, - uniqueItems: true - } - }, - additionalProperties: false - } - ], - - messages: { - unexpected: "Unexpected empty {{name}}." - } - }, - - create(context) { - const options = context.options[0] || {}; - const allowed = options.allow || []; - - const sourceCode = context.getSourceCode(); - - /** - * Reports a given function node if the node matches the following patterns. - * - * - Not allowed by options. - * - The body is empty. - * - The body doesn't have any comments. - * @param {ASTNode} node A function node to report. This is one of - * an ArrowFunctionExpression, a FunctionDeclaration, or a - * FunctionExpression. - * @returns {void} - */ - function reportIfEmpty(node) { - const kind = getKind(node); - const name = astUtils.getFunctionNameWithKind(node); - const innerComments = sourceCode.getTokens(node.body, { - includeComments: true, - filter: astUtils.isCommentToken - }); - - if (allowed.indexOf(kind) === -1 && - node.body.type === "BlockStatement" && - node.body.body.length === 0 && - innerComments.length === 0 - ) { - context.report({ - node, - loc: node.body.loc, - messageId: "unexpected", - data: { name } - }); - } - } - - return { - ArrowFunctionExpression: reportIfEmpty, - FunctionDeclaration: reportIfEmpty, - FunctionExpression: reportIfEmpty - }; - } -}; - -/** - * @fileoverview Rule to disallow an empty pattern - * @author Alberto Rodríguez - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noEmptyPattern = { - meta: { - type: "problem", - - docs: { - description: "disallow empty destructuring patterns", - category: "Best Practices", - recommended: true, - url: "https://eslint.org/docs/rules/no-empty-pattern" - }, - - schema: [], - - messages: { - unexpected: "Unexpected empty {{type}} pattern." - } - }, - - create(context) { - return { - ObjectPattern(node) { - if (node.properties.length === 0) { - context.report({ node, messageId: "unexpected", data: { type: "object" } }); - } - }, - ArrayPattern(node) { - if (node.elements.length === 0) { - context.report({ node, messageId: "unexpected", data: { type: "array" } }); - } - } - }; - } -}; - -/** - * @fileoverview Rule to flag comparisons to null without a type-checking - * operator. - * @author Ian Christian Myers - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noEqNull = { - meta: { - type: "suggestion", - - docs: { - description: "disallow `null` comparisons without type-checking operators", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-eq-null" - }, - - schema: [], - - messages: { - unexpected: "Use '===' to compare with null." - } - }, - - create(context) { - - return { - - BinaryExpression(node) { - const badOperator = node.operator === "==" || node.operator === "!="; - - if (node.right.type === "Literal" && node.right.raw === "null" && badOperator || - node.left.type === "Literal" && node.left.raw === "null" && badOperator) { - context.report({ node, messageId: "unexpected" }); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag use of eval() statement - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const candidatesOfGlobalObject = Object.freeze([ - "global", - "window", - "globalThis" -]); - -/** - * Checks a given node is a MemberExpression node which has the specified name's - * property. - * @param {ASTNode} node A node to check. - * @param {string} name A name to check. - * @returns {boolean} `true` if the node is a MemberExpression node which has - * the specified name's property - */ -function isMember(node, name) { - return astUtils.isSpecificMemberAccess(node, null, name); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noEval = { - meta: { - type: "suggestion", - - docs: { - description: "disallow the use of `eval()`", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-eval" - }, - - schema: [ - { - type: "object", - properties: { - allowIndirect: { type: "boolean", default: false } - }, - additionalProperties: false - } - ], - - messages: { - unexpected: "eval can be harmful." - } - }, - - create(context) { - const allowIndirect = Boolean( - context.options[0] && - context.options[0].allowIndirect - ); - const sourceCode = context.getSourceCode(); - let funcInfo = null; - - /** - * Pushs a variable scope (Program or Function) information to the stack. - * - * This is used in order to check whether or not `this` binding is a - * reference to the global object. - * @param {ASTNode} node A node of the scope. This is one of Program, - * FunctionDeclaration, FunctionExpression, and ArrowFunctionExpression. - * @returns {void} - */ - function enterVarScope(node) { - const strict = context.getScope().isStrict; - - funcInfo = { - upper: funcInfo, - node, - strict, - defaultThis: false, - initialized: strict - }; - } - - /** - * Pops a variable scope from the stack. - * @returns {void} - */ - function exitVarScope() { - funcInfo = funcInfo.upper; - } - - /** - * Reports a given node. - * - * `node` is `Identifier` or `MemberExpression`. - * The parent of `node` might be `CallExpression`. - * - * The location of the report is always `eval` `Identifier` (or possibly - * `Literal`). The type of the report is `CallExpression` if the parent is - * `CallExpression`. Otherwise, it's the given node type. - * @param {ASTNode} node A node to report. - * @returns {void} - */ - function report(node) { - const parent = node.parent; - const locationNode = node.type === "MemberExpression" - ? node.property - : node; - - const reportNode = parent.type === "CallExpression" && parent.callee === node - ? parent - : node; - - context.report({ - node: reportNode, - loc: locationNode.loc, - messageId: "unexpected" - }); - } - - /** - * Reports accesses of `eval` via the global object. - * @param {eslint-scope.Scope} globalScope The global scope. - * @returns {void} - */ - function reportAccessingEvalViaGlobalObject(globalScope) { - for (let i = 0; i < candidatesOfGlobalObject.length; ++i) { - const name = candidatesOfGlobalObject[i]; - const variable = astUtils.getVariableByName(globalScope, name); - - if (!variable) { - continue; - } - - const references = variable.references; - - for (let j = 0; j < references.length; ++j) { - const identifier = references[j].identifier; - let node = identifier.parent; - - // To detect code like `window.window.eval`. - while (isMember(node, name)) { - node = node.parent; - } - - // Reports. - if (isMember(node, "eval")) { - report(node); - } - } - } - } - - /** - * Reports all accesses of `eval` (excludes direct calls to eval). - * @param {eslint-scope.Scope} globalScope The global scope. - * @returns {void} - */ - function reportAccessingEval(globalScope) { - const variable = astUtils.getVariableByName(globalScope, "eval"); - - if (!variable) { - return; - } - - const references = variable.references; - - for (let i = 0; i < references.length; ++i) { - const reference = references[i]; - const id = reference.identifier; - - if (id.name === "eval" && !astUtils.isCallee(id)) { - - // Is accessing to eval (excludes direct calls to eval) - report(id); - } - } - } - - if (allowIndirect) { - - // Checks only direct calls to eval. It's simple! - return { - "CallExpression:exit"(node) { - const callee = node.callee; - - /* - * Optional call (`eval?.("code")`) is not direct eval. - * The direct eval is only step 6.a.vi of https://tc39.es/ecma262/#sec-function-calls-runtime-semantics-evaluation - * But the optional call is https://tc39.es/ecma262/#sec-optional-chaining-chain-evaluation - */ - if (!node.optional && astUtils.isSpecificId(callee, "eval")) { - report(callee); - } - } - }; - } - - return { - "CallExpression:exit"(node) { - const callee = node.callee; - - if (astUtils.isSpecificId(callee, "eval")) { - report(callee); - } - }, - - Program(node) { - const scope = context.getScope(), - features = context.parserOptions.ecmaFeatures || {}, - strict = - scope.isStrict || - node.sourceType === "module" || - (features.globalReturn && scope.childScopes[0].isStrict); - - funcInfo = { - upper: null, - node, - strict, - defaultThis: true, - initialized: true - }; - }, - - "Program:exit"() { - const globalScope = context.getScope(); - - exitVarScope(); - reportAccessingEval(globalScope); - reportAccessingEvalViaGlobalObject(globalScope); - }, - - FunctionDeclaration: enterVarScope, - "FunctionDeclaration:exit": exitVarScope, - FunctionExpression: enterVarScope, - "FunctionExpression:exit": exitVarScope, - ArrowFunctionExpression: enterVarScope, - "ArrowFunctionExpression:exit": exitVarScope, - - ThisExpression(node) { - if (!isMember(node.parent, "eval")) { - return; - } - - /* - * `this.eval` is found. - * Checks whether or not the value of `this` is the global object. - */ - if (!funcInfo.initialized) { - funcInfo.initialized = true; - funcInfo.defaultThis = astUtils.isDefaultThisBinding( - funcInfo.node, - sourceCode - ); - } - - if (!funcInfo.strict && funcInfo.defaultThis) { - - // `this.eval` is possible built-in `eval`. - report(node.parent); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag assignment of the exception parameter - * @author Stephen Murray - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noExAssign = { - meta: { - type: "problem", - - docs: { - description: "disallow reassigning exceptions in `catch` clauses", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-ex-assign" - }, - - schema: [], - - messages: { - unexpected: "Do not assign to the exception parameter." - } - }, - - create(context) { - - /** - * Finds and reports references that are non initializer and writable. - * @param {Variable} variable A variable to check. - * @returns {void} - */ - function checkVariable(variable) { - astUtils.getModifyingReferences(variable.references).forEach(reference => { - context.report({ node: reference.identifier, messageId: "unexpected" }); - }); - } - - return { - CatchClause(node) { - context.getDeclaredVariables(node).forEach(checkVariable); - } - }; - - } -}; - -/** - * @fileoverview Rule to flag adding properties to native object's prototypes. - * @author David Nelson - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noExtendNative = { - meta: { - type: "suggestion", - - docs: { - description: "disallow extending native types", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-extend-native" - }, - - schema: [ - { - type: "object", - properties: { - exceptions: { - type: "array", - items: { - type: "string" - }, - uniqueItems: true - } - }, - additionalProperties: false - } - ], - - messages: { - unexpected: "{{builtin}} prototype is read only, properties should not be added." - } - }, - - create(context) { - - const config = context.options[0] || {}; - const exceptions = new Set(config.exceptions || []); - const modifiedBuiltins = new Set( - Object.keys(globals__default['default'].builtin) - .filter(builtin => builtin[0].toUpperCase() === builtin[0]) - .filter(builtin => !exceptions.has(builtin)) - ); - - /** - * Reports a lint error for the given node. - * @param {ASTNode} node The node to report. - * @param {string} builtin The name of the native builtin being extended. - * @returns {void} - */ - function reportNode(node, builtin) { - context.report({ - node, - messageId: "unexpected", - data: { - builtin - } - }); - } - - /** - * Check to see if the `prototype` property of the given object - * identifier node is being accessed. - * @param {ASTNode} identifierNode The Identifier representing the object - * to check. - * @returns {boolean} True if the identifier is the object of a - * MemberExpression and its `prototype` property is being accessed, - * false otherwise. - */ - function isPrototypePropertyAccessed(identifierNode) { - return Boolean( - identifierNode && - identifierNode.parent && - identifierNode.parent.type === "MemberExpression" && - identifierNode.parent.object === identifierNode && - astUtils.getStaticPropertyName(identifierNode.parent) === "prototype" - ); - } - - /** - * Check if it's an assignment to the property of the given node. - * Example: `*.prop = 0` // the `*` is the given node. - * @param {ASTNode} node The node to check. - * @returns {boolean} True if an assignment to the property of the node. - */ - function isAssigningToPropertyOf(node) { - return ( - node.parent.type === "MemberExpression" && - node.parent.object === node && - node.parent.parent.type === "AssignmentExpression" && - node.parent.parent.left === node.parent - ); - } - - /** - * Checks if the given node is at the first argument of the method call of `Object.defineProperty()` or `Object.defineProperties()`. - * @param {ASTNode} node The node to check. - * @returns {boolean} True if the node is at the first argument of the method call of `Object.defineProperty()` or `Object.defineProperties()`. - */ - function isInDefinePropertyCall(node) { - return ( - node.parent.type === "CallExpression" && - node.parent.arguments[0] === node && - astUtils.isSpecificMemberAccess(node.parent.callee, "Object", /^definePropert(?:y|ies)$/u) - ); - } - - /** - * Check to see if object prototype access is part of a prototype - * extension. There are three ways a prototype can be extended: - * 1. Assignment to prototype property (Object.prototype.foo = 1) - * 2. Object.defineProperty()/Object.defineProperties() on a prototype - * If prototype extension is detected, report the AssignmentExpression - * or CallExpression node. - * @param {ASTNode} identifierNode The Identifier representing the object - * which prototype is being accessed and possibly extended. - * @returns {void} - */ - function checkAndReportPrototypeExtension(identifierNode) { - if (!isPrototypePropertyAccessed(identifierNode)) { - return; // This is not `*.prototype` access. - } - - /* - * `identifierNode.parent` is a MemberExpression `*.prototype`. - * If it's an optional member access, it may be wrapped by a `ChainExpression` node. - */ - const prototypeNode = - identifierNode.parent.parent.type === "ChainExpression" - ? identifierNode.parent.parent - : identifierNode.parent; - - if (isAssigningToPropertyOf(prototypeNode)) { - - // `*.prototype` -> MemberExpression -> AssignmentExpression - reportNode(prototypeNode.parent.parent, identifierNode.name); - } else if (isInDefinePropertyCall(prototypeNode)) { - - // `*.prototype` -> CallExpression - reportNode(prototypeNode.parent, identifierNode.name); - } - } - - return { - - "Program:exit"() { - const globalScope = context.getScope(); - - modifiedBuiltins.forEach(builtin => { - const builtinVar = globalScope.set.get(builtin); - - if (builtinVar && builtinVar.references) { - builtinVar.references - .map(ref => ref.identifier) - .forEach(checkAndReportPrototypeExtension); - } - }); - } - }; - - } -}; - -/** - * @fileoverview Rule to flag unnecessary bind calls - * @author Bence Dányi - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const SIDE_EFFECT_FREE_NODE_TYPES = new Set(["Literal", "Identifier", "ThisExpression", "FunctionExpression"]); - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noExtraBind = { - meta: { - type: "suggestion", - - docs: { - description: "disallow unnecessary calls to `.bind()`", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-extra-bind" - }, - - schema: [], - fixable: "code", - - messages: { - unexpected: "The function binding is unnecessary." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - let scopeInfo = null; - - /** - * Checks if a node is free of side effects. - * - * This check is stricter than it needs to be, in order to keep the implementation simple. - * @param {ASTNode} node A node to check. - * @returns {boolean} True if the node is known to be side-effect free, false otherwise. - */ - function isSideEffectFree(node) { - return SIDE_EFFECT_FREE_NODE_TYPES.has(node.type); - } - - /** - * Reports a given function node. - * @param {ASTNode} node A node to report. This is a FunctionExpression or - * an ArrowFunctionExpression. - * @returns {void} - */ - function report(node) { - const memberNode = node.parent; - const callNode = memberNode.parent.type === "ChainExpression" - ? memberNode.parent.parent - : memberNode.parent; - - context.report({ - node: callNode, - messageId: "unexpected", - loc: memberNode.property.loc, - - fix(fixer) { - if (!isSideEffectFree(callNode.arguments[0])) { - return null; - } - - /* - * The list of the first/last token pair of a removal range. - * This is two parts because closing parentheses may exist between the method name and arguments. - * E.g. `(function(){}.bind ) (obj)` - * ^^^^^ ^^^^^ < removal ranges - * E.g. `(function(){}?.['bind'] ) ?.(obj)` - * ^^^^^^^^^^ ^^^^^^^ < removal ranges - */ - const tokenPairs = [ - [ - - // `.`, `?.`, or `[` token. - sourceCode.getTokenAfter( - memberNode.object, - astUtils.isNotClosingParenToken - ), - - // property name or `]` token. - sourceCode.getLastToken(memberNode) - ], - [ - - // `?.` or `(` token of arguments. - sourceCode.getTokenAfter( - memberNode, - astUtils.isNotClosingParenToken - ), - - // `)` token of arguments. - sourceCode.getLastToken(callNode) - ] - ]; - const firstTokenToRemove = tokenPairs[0][0]; - const lastTokenToRemove = tokenPairs[1][1]; - - if (sourceCode.commentsExistBetween(firstTokenToRemove, lastTokenToRemove)) { - return null; - } - - return tokenPairs.map(([start, end]) => - fixer.removeRange([start.range[0], end.range[1]])); - } - }); - } - - /** - * Checks whether or not a given function node is the callee of `.bind()` - * method. - * - * e.g. `(function() {}.bind(foo))` - * @param {ASTNode} node A node to report. This is a FunctionExpression or - * an ArrowFunctionExpression. - * @returns {boolean} `true` if the node is the callee of `.bind()` method. - */ - function isCalleeOfBindMethod(node) { - if (!astUtils.isSpecificMemberAccess(node.parent, null, "bind")) { - return false; - } - - // The node of `*.bind` member access. - const bindNode = node.parent.parent.type === "ChainExpression" - ? node.parent.parent - : node.parent; - - return ( - bindNode.parent.type === "CallExpression" && - bindNode.parent.callee === bindNode && - bindNode.parent.arguments.length === 1 && - bindNode.parent.arguments[0].type !== "SpreadElement" - ); - } - - /** - * Adds a scope information object to the stack. - * @param {ASTNode} node A node to add. This node is a FunctionExpression - * or a FunctionDeclaration node. - * @returns {void} - */ - function enterFunction(node) { - scopeInfo = { - isBound: isCalleeOfBindMethod(node), - thisFound: false, - upper: scopeInfo - }; - } - - /** - * Removes the scope information object from the top of the stack. - * At the same time, this reports the function node if the function has - * `.bind()` and the `this` keywords found. - * @param {ASTNode} node A node to remove. This node is a - * FunctionExpression or a FunctionDeclaration node. - * @returns {void} - */ - function exitFunction(node) { - if (scopeInfo.isBound && !scopeInfo.thisFound) { - report(node); - } - - scopeInfo = scopeInfo.upper; - } - - /** - * Reports a given arrow function if the function is callee of `.bind()` - * method. - * @param {ASTNode} node A node to report. This node is an - * ArrowFunctionExpression. - * @returns {void} - */ - function exitArrowFunction(node) { - if (isCalleeOfBindMethod(node)) { - report(node); - } - } - - /** - * Set the mark as the `this` keyword was found in this scope. - * @returns {void} - */ - function markAsThisFound() { - if (scopeInfo) { - scopeInfo.thisFound = true; - } - } - - return { - "ArrowFunctionExpression:exit": exitArrowFunction, - FunctionDeclaration: enterFunction, - "FunctionDeclaration:exit": exitFunction, - FunctionExpression: enterFunction, - "FunctionExpression:exit": exitFunction, - ThisExpression: markAsThisFound - }; - } -}; - -/** - * @fileoverview Rule to flag unnecessary double negation in Boolean contexts - * @author Brandon Mills - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -const precedence = astUtils.getPrecedence; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noExtraBooleanCast = { - meta: { - type: "suggestion", - - docs: { - description: "disallow unnecessary boolean casts", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-extra-boolean-cast" - }, - - schema: [{ - type: "object", - properties: { - enforceForLogicalOperands: { - type: "boolean", - default: false - } - }, - additionalProperties: false - }], - fixable: "code", - - messages: { - unexpectedCall: "Redundant Boolean call.", - unexpectedNegation: "Redundant double negation." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - // Node types which have a test which will coerce values to booleans. - const BOOLEAN_NODE_TYPES = [ - "IfStatement", - "DoWhileStatement", - "WhileStatement", - "ConditionalExpression", - "ForStatement" - ]; - - /** - * Check if a node is a Boolean function or constructor. - * @param {ASTNode} node the node - * @returns {boolean} If the node is Boolean function or constructor - */ - function isBooleanFunctionOrConstructorCall(node) { - - // Boolean() and new Boolean() - return (node.type === "CallExpression" || node.type === "NewExpression") && - node.callee.type === "Identifier" && - node.callee.name === "Boolean"; - } - - /** - * Checks whether the node is a logical expression and that the option is enabled - * @param {ASTNode} node the node - * @returns {boolean} if the node is a logical expression and option is enabled - */ - function isLogicalContext(node) { - return node.type === "LogicalExpression" && - (node.operator === "||" || node.operator === "&&") && - (context.options.length && context.options[0].enforceForLogicalOperands === true); - - } - - - /** - * Check if a node is in a context where its value would be coerced to a boolean at runtime. - * @param {ASTNode} node The node - * @returns {boolean} If it is in a boolean context - */ - function isInBooleanContext(node) { - return ( - (isBooleanFunctionOrConstructorCall(node.parent) && - node === node.parent.arguments[0]) || - - (BOOLEAN_NODE_TYPES.indexOf(node.parent.type) !== -1 && - node === node.parent.test) || - - // ! - (node.parent.type === "UnaryExpression" && - node.parent.operator === "!") - ); - } - - /** - * Checks whether the node is a context that should report an error - * Acts recursively if it is in a logical context - * @param {ASTNode} node the node - * @returns {boolean} If the node is in one of the flagged contexts - */ - function isInFlaggedContext(node) { - if (node.parent.type === "ChainExpression") { - return isInFlaggedContext(node.parent); - } - - return isInBooleanContext(node) || - (isLogicalContext(node.parent) && - - // For nested logical statements - isInFlaggedContext(node.parent) - ); - } - - - /** - * Check if a node has comments inside. - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if it has comments inside. - */ - function hasCommentsInside(node) { - return Boolean(sourceCode.getCommentsInside(node).length); - } - - /** - * Checks if the given node is wrapped in grouping parentheses. Parentheses for constructs such as if() don't count. - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if the node is parenthesized. - * @private - */ - function isParenthesized(node) { - return require$$0__default$1['default'].isParenthesized(1, node, sourceCode); - } - - /** - * Determines whether the given node needs to be parenthesized when replacing the previous node. - * It assumes that `previousNode` is the node to be reported by this rule, so it has a limited list - * of possible parent node types. By the same assumption, the node's role in a particular parent is already known. - * For example, if the parent is `ConditionalExpression`, `previousNode` must be its `test` child. - * @param {ASTNode} previousNode Previous node. - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if the node needs to be parenthesized. - */ - function needsParens(previousNode, node) { - if (previousNode.parent.type === "ChainExpression") { - return needsParens(previousNode.parent, node); - } - if (isParenthesized(previousNode)) { - - // parentheses around the previous node will stay, so there is no need for an additional pair - return false; - } - - // parent of the previous node will become parent of the replacement node - const parent = previousNode.parent; - - switch (parent.type) { - case "CallExpression": - case "NewExpression": - return node.type === "SequenceExpression"; - case "IfStatement": - case "DoWhileStatement": - case "WhileStatement": - case "ForStatement": - return false; - case "ConditionalExpression": - return precedence(node) <= precedence(parent); - case "UnaryExpression": - return precedence(node) < precedence(parent); - case "LogicalExpression": - if (astUtils.isMixedLogicalAndCoalesceExpressions(node, parent)) { - return true; - } - if (previousNode === parent.left) { - return precedence(node) < precedence(parent); - } - return precedence(node) <= precedence(parent); - - /* istanbul ignore next */ - default: - throw new Error(`Unexpected parent type: ${parent.type}`); - } - } - - return { - UnaryExpression(node) { - const parent = node.parent; - - - // Exit early if it's guaranteed not to match - if (node.operator !== "!" || - parent.type !== "UnaryExpression" || - parent.operator !== "!") { - return; - } - - - if (isInFlaggedContext(parent)) { - context.report({ - node: parent, - messageId: "unexpectedNegation", - fix(fixer) { - if (hasCommentsInside(parent)) { - return null; - } - - if (needsParens(parent, node.argument)) { - return fixer.replaceText(parent, `(${sourceCode.getText(node.argument)})`); - } - - let prefix = ""; - const tokenBefore = sourceCode.getTokenBefore(parent); - const firstReplacementToken = sourceCode.getFirstToken(node.argument); - - if ( - tokenBefore && - tokenBefore.range[1] === parent.range[0] && - !astUtils.canTokensBeAdjacent(tokenBefore, firstReplacementToken) - ) { - prefix = " "; - } - - return fixer.replaceText(parent, prefix + sourceCode.getText(node.argument)); - } - }); - } - }, - - CallExpression(node) { - if (node.callee.type !== "Identifier" || node.callee.name !== "Boolean") { - return; - } - - if (isInFlaggedContext(node)) { - context.report({ - node, - messageId: "unexpectedCall", - fix(fixer) { - const parent = node.parent; - - if (node.arguments.length === 0) { - if (parent.type === "UnaryExpression" && parent.operator === "!") { - - /* - * !Boolean() -> true - */ - - if (hasCommentsInside(parent)) { - return null; - } - - const replacement = "true"; - let prefix = ""; - const tokenBefore = sourceCode.getTokenBefore(parent); - - if ( - tokenBefore && - tokenBefore.range[1] === parent.range[0] && - !astUtils.canTokensBeAdjacent(tokenBefore, replacement) - ) { - prefix = " "; - } - - return fixer.replaceText(parent, prefix + replacement); - } - - /* - * Boolean() -> false - */ - - if (hasCommentsInside(node)) { - return null; - } - - return fixer.replaceText(node, "false"); - } - - if (node.arguments.length === 1) { - const argument = node.arguments[0]; - - if (argument.type === "SpreadElement" || hasCommentsInside(node)) { - return null; - } - - /* - * Boolean(expression) -> expression - */ - - if (needsParens(node, argument)) { - return fixer.replaceText(node, `(${sourceCode.getText(argument)})`); - } - - return fixer.replaceText(node, sourceCode.getText(argument)); - } - - // two or more arguments - return null; - } - }); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to disallow unnecessary labels - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noExtraLabel = { - meta: { - type: "suggestion", - - docs: { - description: "disallow unnecessary labels", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-extra-label" - }, - - schema: [], - fixable: "code", - - messages: { - unexpected: "This label '{{name}}' is unnecessary." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - let scopeInfo = null; - - /** - * Creates a new scope with a breakable statement. - * @param {ASTNode} node A node to create. This is a BreakableStatement. - * @returns {void} - */ - function enterBreakableStatement(node) { - scopeInfo = { - label: node.parent.type === "LabeledStatement" ? node.parent.label : null, - breakable: true, - upper: scopeInfo - }; - } - - /** - * Removes the top scope of the stack. - * @returns {void} - */ - function exitBreakableStatement() { - scopeInfo = scopeInfo.upper; - } - - /** - * Creates a new scope with a labeled statement. - * - * This ignores it if the body is a breakable statement. - * In this case it's handled in the `enterBreakableStatement` function. - * @param {ASTNode} node A node to create. This is a LabeledStatement. - * @returns {void} - */ - function enterLabeledStatement(node) { - if (!astUtils.isBreakableStatement(node.body)) { - scopeInfo = { - label: node.label, - breakable: false, - upper: scopeInfo - }; - } - } - - /** - * Removes the top scope of the stack. - * - * This ignores it if the body is a breakable statement. - * In this case it's handled in the `exitBreakableStatement` function. - * @param {ASTNode} node A node. This is a LabeledStatement. - * @returns {void} - */ - function exitLabeledStatement(node) { - if (!astUtils.isBreakableStatement(node.body)) { - scopeInfo = scopeInfo.upper; - } - } - - /** - * Reports a given control node if it's unnecessary. - * @param {ASTNode} node A node. This is a BreakStatement or a - * ContinueStatement. - * @returns {void} - */ - function reportIfUnnecessary(node) { - if (!node.label) { - return; - } - - const labelNode = node.label; - - for (let info = scopeInfo; info !== null; info = info.upper) { - if (info.breakable || info.label && info.label.name === labelNode.name) { - if (info.breakable && info.label && info.label.name === labelNode.name) { - context.report({ - node: labelNode, - messageId: "unexpected", - data: labelNode, - fix(fixer) { - const breakOrContinueToken = sourceCode.getFirstToken(node); - - if (sourceCode.commentsExistBetween(breakOrContinueToken, labelNode)) { - return null; - } - - return fixer.removeRange([breakOrContinueToken.range[1], labelNode.range[1]]); - } - }); - } - return; - } - } - } - - return { - WhileStatement: enterBreakableStatement, - "WhileStatement:exit": exitBreakableStatement, - DoWhileStatement: enterBreakableStatement, - "DoWhileStatement:exit": exitBreakableStatement, - ForStatement: enterBreakableStatement, - "ForStatement:exit": exitBreakableStatement, - ForInStatement: enterBreakableStatement, - "ForInStatement:exit": exitBreakableStatement, - ForOfStatement: enterBreakableStatement, - "ForOfStatement:exit": exitBreakableStatement, - SwitchStatement: enterBreakableStatement, - "SwitchStatement:exit": exitBreakableStatement, - LabeledStatement: enterLabeledStatement, - "LabeledStatement:exit": exitLabeledStatement, - BreakStatement: reportIfUnnecessary, - ContinueStatement: reportIfUnnecessary - }; - } -}; - -/** - * @fileoverview Disallow parenthesising higher precedence subexpressions. - * @author Michael Ficarra - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -const { isParenthesized: isParenthesizedRaw } = require$$0__default$1['default']; - - -var noExtraParens = { - meta: { - type: "layout", - - docs: { - description: "disallow unnecessary parentheses", - category: "Possible Errors", - recommended: false, - url: "https://eslint.org/docs/rules/no-extra-parens" - }, - - fixable: "code", - - schema: { - anyOf: [ - { - type: "array", - items: [ - { - enum: ["functions"] - } - ], - minItems: 0, - maxItems: 1 - }, - { - type: "array", - items: [ - { - enum: ["all"] - }, - { - type: "object", - properties: { - conditionalAssign: { type: "boolean" }, - nestedBinaryExpressions: { type: "boolean" }, - returnAssign: { type: "boolean" }, - ignoreJSX: { enum: ["none", "all", "single-line", "multi-line"] }, - enforceForArrowConditionals: { type: "boolean" }, - enforceForSequenceExpressions: { type: "boolean" }, - enforceForNewInMemberExpressions: { type: "boolean" }, - enforceForFunctionPrototypeMethods: { type: "boolean" } - }, - additionalProperties: false - } - ], - minItems: 0, - maxItems: 2 - } - ] - }, - - messages: { - unexpected: "Unnecessary parentheses around expression." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - const tokensToIgnore = new WeakSet(); - const precedence = astUtils.getPrecedence; - const ALL_NODES = context.options[0] !== "functions"; - const EXCEPT_COND_ASSIGN = ALL_NODES && context.options[1] && context.options[1].conditionalAssign === false; - const NESTED_BINARY = ALL_NODES && context.options[1] && context.options[1].nestedBinaryExpressions === false; - const EXCEPT_RETURN_ASSIGN = ALL_NODES && context.options[1] && context.options[1].returnAssign === false; - const IGNORE_JSX = ALL_NODES && context.options[1] && context.options[1].ignoreJSX; - const IGNORE_ARROW_CONDITIONALS = ALL_NODES && context.options[1] && - context.options[1].enforceForArrowConditionals === false; - const IGNORE_SEQUENCE_EXPRESSIONS = ALL_NODES && context.options[1] && - context.options[1].enforceForSequenceExpressions === false; - const IGNORE_NEW_IN_MEMBER_EXPR = ALL_NODES && context.options[1] && - context.options[1].enforceForNewInMemberExpressions === false; - const IGNORE_FUNCTION_PROTOTYPE_METHODS = ALL_NODES && context.options[1] && - context.options[1].enforceForFunctionPrototypeMethods === false; - - const PRECEDENCE_OF_ASSIGNMENT_EXPR = precedence({ type: "AssignmentExpression" }); - const PRECEDENCE_OF_UPDATE_EXPR = precedence({ type: "UpdateExpression" }); - - let reportsBuffer; - - /** - * Determines whether the given node is a `call` or `apply` method call, invoked directly on a `FunctionExpression` node. - * Example: function(){}.call() - * @param {ASTNode} node The node to be checked. - * @returns {boolean} True if the node is an immediate `call` or `apply` method call. - * @private - */ - function isImmediateFunctionPrototypeMethodCall(node) { - const callNode = astUtils.skipChainExpression(node); - - if (callNode.type !== "CallExpression") { - return false; - } - const callee = astUtils.skipChainExpression(callNode.callee); - - return ( - callee.type === "MemberExpression" && - callee.object.type === "FunctionExpression" && - ["call", "apply"].includes(astUtils.getStaticPropertyName(callee)) - ); - } - - /** - * Determines if this rule should be enforced for a node given the current configuration. - * @param {ASTNode} node The node to be checked. - * @returns {boolean} True if the rule should be enforced for this node. - * @private - */ - function ruleApplies(node) { - if (node.type === "JSXElement" || node.type === "JSXFragment") { - const isSingleLine = node.loc.start.line === node.loc.end.line; - - switch (IGNORE_JSX) { - - // Exclude this JSX element from linting - case "all": - return false; - - // Exclude this JSX element if it is multi-line element - case "multi-line": - return isSingleLine; - - // Exclude this JSX element if it is single-line element - case "single-line": - return !isSingleLine; - - // no default - } - } - - if (node.type === "SequenceExpression" && IGNORE_SEQUENCE_EXPRESSIONS) { - return false; - } - - if (isImmediateFunctionPrototypeMethodCall(node) && IGNORE_FUNCTION_PROTOTYPE_METHODS) { - return false; - } - - return ALL_NODES || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression"; - } - - /** - * Determines if a node is surrounded by parentheses. - * @param {ASTNode} node The node to be checked. - * @returns {boolean} True if the node is parenthesised. - * @private - */ - function isParenthesised(node) { - return isParenthesizedRaw(1, node, sourceCode); - } - - /** - * Determines if a node is surrounded by parentheses twice. - * @param {ASTNode} node The node to be checked. - * @returns {boolean} True if the node is doubly parenthesised. - * @private - */ - function isParenthesisedTwice(node) { - return isParenthesizedRaw(2, node, sourceCode); - } - - /** - * Determines if a node is surrounded by (potentially) invalid parentheses. - * @param {ASTNode} node The node to be checked. - * @returns {boolean} True if the node is incorrectly parenthesised. - * @private - */ - function hasExcessParens(node) { - return ruleApplies(node) && isParenthesised(node); - } - - /** - * Determines if a node that is expected to be parenthesised is surrounded by - * (potentially) invalid extra parentheses. - * @param {ASTNode} node The node to be checked. - * @returns {boolean} True if the node is has an unexpected extra pair of parentheses. - * @private - */ - function hasDoubleExcessParens(node) { - return ruleApplies(node) && isParenthesisedTwice(node); - } - - /** - * Determines if a node that is expected to be parenthesised is surrounded by - * (potentially) invalid extra parentheses with considering precedence level of the node. - * If the preference level of the node is not higher or equal to precedence lower limit, it also checks - * whether the node is surrounded by parentheses twice or not. - * @param {ASTNode} node The node to be checked. - * @param {number} precedenceLowerLimit The lower limit of precedence. - * @returns {boolean} True if the node is has an unexpected extra pair of parentheses. - * @private - */ - function hasExcessParensWithPrecedence(node, precedenceLowerLimit) { - if (ruleApplies(node) && isParenthesised(node)) { - if ( - precedence(node) >= precedenceLowerLimit || - isParenthesisedTwice(node) - ) { - return true; - } - } - return false; - } - - /** - * Determines if a node test expression is allowed to have a parenthesised assignment - * @param {ASTNode} node The node to be checked. - * @returns {boolean} True if the assignment can be parenthesised. - * @private - */ - function isCondAssignException(node) { - return EXCEPT_COND_ASSIGN && node.test.type === "AssignmentExpression"; - } - - /** - * Determines if a node is in a return statement - * @param {ASTNode} node The node to be checked. - * @returns {boolean} True if the node is in a return statement. - * @private - */ - function isInReturnStatement(node) { - for (let currentNode = node; currentNode; currentNode = currentNode.parent) { - if ( - currentNode.type === "ReturnStatement" || - (currentNode.type === "ArrowFunctionExpression" && currentNode.body.type !== "BlockStatement") - ) { - return true; - } - } - - return false; - } - - /** - * Determines if a constructor function is newed-up with parens - * @param {ASTNode} newExpression The NewExpression node to be checked. - * @returns {boolean} True if the constructor is called with parens. - * @private - */ - function isNewExpressionWithParens(newExpression) { - const lastToken = sourceCode.getLastToken(newExpression); - const penultimateToken = sourceCode.getTokenBefore(lastToken); - - return newExpression.arguments.length > 0 || - ( - - // The expression should end with its own parens, e.g., new new foo() is not a new expression with parens - astUtils.isOpeningParenToken(penultimateToken) && - astUtils.isClosingParenToken(lastToken) && - newExpression.callee.range[1] < newExpression.range[1] - ); - } - - /** - * Determines if a node is or contains an assignment expression - * @param {ASTNode} node The node to be checked. - * @returns {boolean} True if the node is or contains an assignment expression. - * @private - */ - function containsAssignment(node) { - if (node.type === "AssignmentExpression") { - return true; - } - if (node.type === "ConditionalExpression" && - (node.consequent.type === "AssignmentExpression" || node.alternate.type === "AssignmentExpression")) { - return true; - } - if ((node.left && node.left.type === "AssignmentExpression") || - (node.right && node.right.type === "AssignmentExpression")) { - return true; - } - - return false; - } - - /** - * Determines if a node is contained by or is itself a return statement and is allowed to have a parenthesised assignment - * @param {ASTNode} node The node to be checked. - * @returns {boolean} True if the assignment can be parenthesised. - * @private - */ - function isReturnAssignException(node) { - if (!EXCEPT_RETURN_ASSIGN || !isInReturnStatement(node)) { - return false; - } - - if (node.type === "ReturnStatement") { - return node.argument && containsAssignment(node.argument); - } - if (node.type === "ArrowFunctionExpression" && node.body.type !== "BlockStatement") { - return containsAssignment(node.body); - } - return containsAssignment(node); - - } - - /** - * Determines if a node following a [no LineTerminator here] restriction is - * surrounded by (potentially) invalid extra parentheses. - * @param {Token} token The token preceding the [no LineTerminator here] restriction. - * @param {ASTNode} node The node to be checked. - * @returns {boolean} True if the node is incorrectly parenthesised. - * @private - */ - function hasExcessParensNoLineTerminator(token, node) { - if (token.loc.end.line === node.loc.start.line) { - return hasExcessParens(node); - } - - return hasDoubleExcessParens(node); - } - - /** - * Determines whether a node should be preceded by an additional space when removing parens - * @param {ASTNode} node node to evaluate; must be surrounded by parentheses - * @returns {boolean} `true` if a space should be inserted before the node - * @private - */ - function requiresLeadingSpace(node) { - const leftParenToken = sourceCode.getTokenBefore(node); - const tokenBeforeLeftParen = sourceCode.getTokenBefore(leftParenToken, { includeComments: true }); - const tokenAfterLeftParen = sourceCode.getTokenAfter(leftParenToken, { includeComments: true }); - - return tokenBeforeLeftParen && - tokenBeforeLeftParen.range[1] === leftParenToken.range[0] && - leftParenToken.range[1] === tokenAfterLeftParen.range[0] && - !astUtils.canTokensBeAdjacent(tokenBeforeLeftParen, tokenAfterLeftParen); - } - - /** - * Determines whether a node should be followed by an additional space when removing parens - * @param {ASTNode} node node to evaluate; must be surrounded by parentheses - * @returns {boolean} `true` if a space should be inserted after the node - * @private - */ - function requiresTrailingSpace(node) { - const nextTwoTokens = sourceCode.getTokensAfter(node, { count: 2 }); - const rightParenToken = nextTwoTokens[0]; - const tokenAfterRightParen = nextTwoTokens[1]; - const tokenBeforeRightParen = sourceCode.getLastToken(node); - - return rightParenToken && tokenAfterRightParen && - !sourceCode.isSpaceBetweenTokens(rightParenToken, tokenAfterRightParen) && - !astUtils.canTokensBeAdjacent(tokenBeforeRightParen, tokenAfterRightParen); - } - - /** - * Determines if a given expression node is an IIFE - * @param {ASTNode} node The node to check - * @returns {boolean} `true` if the given node is an IIFE - */ - function isIIFE(node) { - const maybeCallNode = astUtils.skipChainExpression(node); - - return maybeCallNode.type === "CallExpression" && maybeCallNode.callee.type === "FunctionExpression"; - } - - /** - * Determines if the given node can be the assignment target in destructuring or the LHS of an assignment. - * This is to avoid an autofix that could change behavior because parsers mistakenly allow invalid syntax, - * such as `(a = b) = c` and `[(a = b) = c] = []`. Ideally, this function shouldn't be necessary. - * @param {ASTNode} [node] The node to check - * @returns {boolean} `true` if the given node can be a valid assignment target - */ - function canBeAssignmentTarget(node) { - return node && (node.type === "Identifier" || node.type === "MemberExpression"); - } - - /** - * Report the node - * @param {ASTNode} node node to evaluate - * @returns {void} - * @private - */ - function report(node) { - const leftParenToken = sourceCode.getTokenBefore(node); - const rightParenToken = sourceCode.getTokenAfter(node); - - if (!isParenthesisedTwice(node)) { - if (tokensToIgnore.has(sourceCode.getFirstToken(node))) { - return; - } - - if (isIIFE(node) && !isParenthesised(node.callee)) { - return; - } - } - - /** - * Finishes reporting - * @returns {void} - * @private - */ - function finishReport() { - context.report({ - node, - loc: leftParenToken.loc, - messageId: "unexpected", - fix(fixer) { - const parenthesizedSource = sourceCode.text.slice(leftParenToken.range[1], rightParenToken.range[0]); - - return fixer.replaceTextRange([ - leftParenToken.range[0], - rightParenToken.range[1] - ], (requiresLeadingSpace(node) ? " " : "") + parenthesizedSource + (requiresTrailingSpace(node) ? " " : "")); - } - }); - } - - if (reportsBuffer) { - reportsBuffer.reports.push({ node, finishReport }); - return; - } - - finishReport(); - } - - /** - * Evaluate a argument of the node. - * @param {ASTNode} node node to evaluate - * @returns {void} - * @private - */ - function checkArgumentWithPrecedence(node) { - if (hasExcessParensWithPrecedence(node.argument, precedence(node))) { - report(node.argument); - } - } - - /** - * Check if a member expression contains a call expression - * @param {ASTNode} node MemberExpression node to evaluate - * @returns {boolean} true if found, false if not - */ - function doesMemberExpressionContainCallExpression(node) { - let currentNode = node.object; - let currentNodeType = node.object.type; - - while (currentNodeType === "MemberExpression") { - currentNode = currentNode.object; - currentNodeType = currentNode.type; - } - - return currentNodeType === "CallExpression"; - } - - /** - * Evaluate a new call - * @param {ASTNode} node node to evaluate - * @returns {void} - * @private - */ - function checkCallNew(node) { - const callee = node.callee; - - if (hasExcessParensWithPrecedence(callee, precedence(node))) { - if ( - hasDoubleExcessParens(callee) || - !( - isIIFE(node) || - - // (new A)(); new (new A)(); - ( - callee.type === "NewExpression" && - !isNewExpressionWithParens(callee) && - !( - node.type === "NewExpression" && - !isNewExpressionWithParens(node) - ) - ) || - - // new (a().b)(); new (a.b().c); - ( - node.type === "NewExpression" && - callee.type === "MemberExpression" && - doesMemberExpressionContainCallExpression(callee) - ) || - - // (a?.b)(); (a?.())(); - ( - !node.optional && - callee.type === "ChainExpression" - ) - ) - ) { - report(node.callee); - } - } - node.arguments - .filter(arg => hasExcessParensWithPrecedence(arg, PRECEDENCE_OF_ASSIGNMENT_EXPR)) - .forEach(report); - } - - /** - * Evaluate binary logicals - * @param {ASTNode} node node to evaluate - * @returns {void} - * @private - */ - function checkBinaryLogical(node) { - const prec = precedence(node); - const leftPrecedence = precedence(node.left); - const rightPrecedence = precedence(node.right); - const isExponentiation = node.operator === "**"; - const shouldSkipLeft = NESTED_BINARY && (node.left.type === "BinaryExpression" || node.left.type === "LogicalExpression"); - const shouldSkipRight = NESTED_BINARY && (node.right.type === "BinaryExpression" || node.right.type === "LogicalExpression"); - - if (!shouldSkipLeft && hasExcessParens(node.left)) { - if ( - !(["AwaitExpression", "UnaryExpression"].includes(node.left.type) && isExponentiation) && - !astUtils.isMixedLogicalAndCoalesceExpressions(node.left, node) && - (leftPrecedence > prec || (leftPrecedence === prec && !isExponentiation)) || - isParenthesisedTwice(node.left) - ) { - report(node.left); - } - } - - if (!shouldSkipRight && hasExcessParens(node.right)) { - if ( - !astUtils.isMixedLogicalAndCoalesceExpressions(node.right, node) && - (rightPrecedence > prec || (rightPrecedence === prec && isExponentiation)) || - isParenthesisedTwice(node.right) - ) { - report(node.right); - } - } - } - - /** - * Check the parentheses around the super class of the given class definition. - * @param {ASTNode} node The node of class declarations to check. - * @returns {void} - */ - function checkClass(node) { - if (!node.superClass) { - return; - } - - /* - * If `node.superClass` is a LeftHandSideExpression, parentheses are extra. - * Otherwise, parentheses are needed. - */ - const hasExtraParens = precedence(node.superClass) > PRECEDENCE_OF_UPDATE_EXPR - ? hasExcessParens(node.superClass) - : hasDoubleExcessParens(node.superClass); - - if (hasExtraParens) { - report(node.superClass); - } - } - - /** - * Check the parentheses around the argument of the given spread operator. - * @param {ASTNode} node The node of spread elements/properties to check. - * @returns {void} - */ - function checkSpreadOperator(node) { - if (hasExcessParensWithPrecedence(node.argument, PRECEDENCE_OF_ASSIGNMENT_EXPR)) { - report(node.argument); - } - } - - /** - * Checks the parentheses for an ExpressionStatement or ExportDefaultDeclaration - * @param {ASTNode} node The ExpressionStatement.expression or ExportDefaultDeclaration.declaration node - * @returns {void} - */ - function checkExpressionOrExportStatement(node) { - const firstToken = isParenthesised(node) ? sourceCode.getTokenBefore(node) : sourceCode.getFirstToken(node); - const secondToken = sourceCode.getTokenAfter(firstToken, astUtils.isNotOpeningParenToken); - const thirdToken = secondToken ? sourceCode.getTokenAfter(secondToken) : null; - const tokenAfterClosingParens = secondToken ? sourceCode.getTokenAfter(secondToken, astUtils.isNotClosingParenToken) : null; - - if ( - astUtils.isOpeningParenToken(firstToken) && - ( - astUtils.isOpeningBraceToken(secondToken) || - secondToken.type === "Keyword" && ( - secondToken.value === "function" || - secondToken.value === "class" || - secondToken.value === "let" && - tokenAfterClosingParens && - ( - astUtils.isOpeningBracketToken(tokenAfterClosingParens) || - tokenAfterClosingParens.type === "Identifier" - ) - ) || - secondToken && secondToken.type === "Identifier" && secondToken.value === "async" && thirdToken && thirdToken.type === "Keyword" && thirdToken.value === "function" - ) - ) { - tokensToIgnore.add(secondToken); - } - - const hasExtraParens = node.parent.type === "ExportDefaultDeclaration" - ? hasExcessParensWithPrecedence(node, PRECEDENCE_OF_ASSIGNMENT_EXPR) - : hasExcessParens(node); - - if (hasExtraParens) { - report(node); - } - } - - /** - * Finds the path from the given node to the specified ancestor. - * @param {ASTNode} node First node in the path. - * @param {ASTNode} ancestor Last node in the path. - * @returns {ASTNode[]} Path, including both nodes. - * @throws {Error} If the given node does not have the specified ancestor. - */ - function pathToAncestor(node, ancestor) { - const path = [node]; - let currentNode = node; - - while (currentNode !== ancestor) { - - currentNode = currentNode.parent; - - /* istanbul ignore if */ - if (currentNode === null) { - throw new Error("Nodes are not in the ancestor-descendant relationship."); - } - - path.push(currentNode); - } - - return path; - } - - /** - * Finds the path from the given node to the specified descendant. - * @param {ASTNode} node First node in the path. - * @param {ASTNode} descendant Last node in the path. - * @returns {ASTNode[]} Path, including both nodes. - * @throws {Error} If the given node does not have the specified descendant. - */ - function pathToDescendant(node, descendant) { - return pathToAncestor(descendant, node).reverse(); - } - - /** - * Checks whether the syntax of the given ancestor of an 'in' expression inside a for-loop initializer - * is preventing the 'in' keyword from being interpreted as a part of an ill-formed for-in loop. - * @param {ASTNode} node Ancestor of an 'in' expression. - * @param {ASTNode} child Child of the node, ancestor of the same 'in' expression or the 'in' expression itself. - * @returns {boolean} True if the keyword 'in' would be interpreted as the 'in' operator, without any parenthesis. - */ - function isSafelyEnclosingInExpression(node, child) { - switch (node.type) { - case "ArrayExpression": - case "ArrayPattern": - case "BlockStatement": - case "ObjectExpression": - case "ObjectPattern": - case "TemplateLiteral": - return true; - case "ArrowFunctionExpression": - case "FunctionExpression": - return node.params.includes(child); - case "CallExpression": - case "NewExpression": - return node.arguments.includes(child); - case "MemberExpression": - return node.computed && node.property === child; - case "ConditionalExpression": - return node.consequent === child; - default: - return false; - } - } - - /** - * Starts a new reports buffering. Warnings will be stored in a buffer instead of being reported immediately. - * An additional logic that requires multiple nodes (e.g. a whole subtree) may dismiss some of the stored warnings. - * @returns {void} - */ - function startNewReportsBuffering() { - reportsBuffer = { - upper: reportsBuffer, - inExpressionNodes: [], - reports: [] - }; - } - - /** - * Ends the current reports buffering. - * @returns {void} - */ - function endCurrentReportsBuffering() { - const { upper, inExpressionNodes, reports } = reportsBuffer; - - if (upper) { - upper.inExpressionNodes.push(...inExpressionNodes); - upper.reports.push(...reports); - } else { - - // flush remaining reports - reports.forEach(({ finishReport }) => finishReport()); - } - - reportsBuffer = upper; - } - - /** - * Checks whether the given node is in the current reports buffer. - * @param {ASTNode} node Node to check. - * @returns {boolean} True if the node is in the current buffer, false otherwise. - */ - function isInCurrentReportsBuffer(node) { - return reportsBuffer.reports.some(r => r.node === node); - } - - /** - * Removes the given node from the current reports buffer. - * @param {ASTNode} node Node to remove. - * @returns {void} - */ - function removeFromCurrentReportsBuffer(node) { - reportsBuffer.reports = reportsBuffer.reports.filter(r => r.node !== node); - } - - /** - * Checks whether a node is a MemberExpression at NewExpression's callee. - * @param {ASTNode} node node to check. - * @returns {boolean} True if the node is a MemberExpression at NewExpression's callee. false otherwise. - */ - function isMemberExpInNewCallee(node) { - if (node.type === "MemberExpression") { - return node.parent.type === "NewExpression" && node.parent.callee === node - ? true - : node.parent.object === node && isMemberExpInNewCallee(node.parent); - } - return false; - } - - return { - ArrayExpression(node) { - node.elements - .filter(e => e && hasExcessParensWithPrecedence(e, PRECEDENCE_OF_ASSIGNMENT_EXPR)) - .forEach(report); - }, - - ArrayPattern(node) { - node.elements - .filter(e => canBeAssignmentTarget(e) && hasExcessParens(e)) - .forEach(report); - }, - - ArrowFunctionExpression(node) { - if (isReturnAssignException(node)) { - return; - } - - if (node.body.type === "ConditionalExpression" && - IGNORE_ARROW_CONDITIONALS - ) { - return; - } - - if (node.body.type !== "BlockStatement") { - const firstBodyToken = sourceCode.getFirstToken(node.body, astUtils.isNotOpeningParenToken); - const tokenBeforeFirst = sourceCode.getTokenBefore(firstBodyToken); - - if (astUtils.isOpeningParenToken(tokenBeforeFirst) && astUtils.isOpeningBraceToken(firstBodyToken)) { - tokensToIgnore.add(firstBodyToken); - } - if (hasExcessParensWithPrecedence(node.body, PRECEDENCE_OF_ASSIGNMENT_EXPR)) { - report(node.body); - } - } - }, - - AssignmentExpression(node) { - if (canBeAssignmentTarget(node.left) && hasExcessParens(node.left)) { - report(node.left); - } - - if (!isReturnAssignException(node) && hasExcessParensWithPrecedence(node.right, precedence(node))) { - report(node.right); - } - }, - - BinaryExpression(node) { - if (reportsBuffer && node.operator === "in") { - reportsBuffer.inExpressionNodes.push(node); - } - - checkBinaryLogical(node); - }, - - CallExpression: checkCallNew, - - ClassBody(node) { - node.body - .filter(member => member.type === "MethodDefinition" && member.computed && member.key) - .filter(member => hasExcessParensWithPrecedence(member.key, PRECEDENCE_OF_ASSIGNMENT_EXPR)) - .forEach(member => report(member.key)); - }, - - ConditionalExpression(node) { - if (isReturnAssignException(node)) { - return; - } - if ( - !isCondAssignException(node) && - hasExcessParensWithPrecedence(node.test, precedence({ type: "LogicalExpression", operator: "||" })) - ) { - report(node.test); - } - - if (hasExcessParensWithPrecedence(node.consequent, PRECEDENCE_OF_ASSIGNMENT_EXPR)) { - report(node.consequent); - } - - if (hasExcessParensWithPrecedence(node.alternate, PRECEDENCE_OF_ASSIGNMENT_EXPR)) { - report(node.alternate); - } - }, - - DoWhileStatement(node) { - if (hasExcessParens(node.test) && !isCondAssignException(node)) { - report(node.test); - } - }, - - ExportDefaultDeclaration: node => checkExpressionOrExportStatement(node.declaration), - ExpressionStatement: node => checkExpressionOrExportStatement(node.expression), - - ForInStatement(node) { - if (node.left.type !== "VariableDeclaration") { - const firstLeftToken = sourceCode.getFirstToken(node.left, astUtils.isNotOpeningParenToken); - - if ( - firstLeftToken.value === "let" && - astUtils.isOpeningBracketToken( - sourceCode.getTokenAfter(firstLeftToken, astUtils.isNotClosingParenToken) - ) - ) { - - // ForInStatement#left expression cannot start with `let[`. - tokensToIgnore.add(firstLeftToken); - } - } - - if (hasExcessParens(node.left)) { - report(node.left); - } - - if (hasExcessParens(node.right)) { - report(node.right); - } - }, - - ForOfStatement(node) { - if (node.left.type !== "VariableDeclaration") { - const firstLeftToken = sourceCode.getFirstToken(node.left, astUtils.isNotOpeningParenToken); - - if (firstLeftToken.value === "let") { - - // ForOfStatement#left expression cannot start with `let`. - tokensToIgnore.add(firstLeftToken); - } - } - - if (hasExcessParens(node.left)) { - report(node.left); - } - - if (hasExcessParensWithPrecedence(node.right, PRECEDENCE_OF_ASSIGNMENT_EXPR)) { - report(node.right); - } - }, - - ForStatement(node) { - if (node.test && hasExcessParens(node.test) && !isCondAssignException(node)) { - report(node.test); - } - - if (node.update && hasExcessParens(node.update)) { - report(node.update); - } - - if (node.init) { - - if (node.init.type !== "VariableDeclaration") { - const firstToken = sourceCode.getFirstToken(node.init, astUtils.isNotOpeningParenToken); - - if ( - firstToken.value === "let" && - astUtils.isOpeningBracketToken( - sourceCode.getTokenAfter(firstToken, astUtils.isNotClosingParenToken) - ) - ) { - - // ForStatement#init expression cannot start with `let[`. - tokensToIgnore.add(firstToken); - } - } - - startNewReportsBuffering(); - - if (hasExcessParens(node.init)) { - report(node.init); - } - } - }, - - "ForStatement > *.init:exit"(node) { - - /* - * Removing parentheses around `in` expressions might change semantics and cause errors. - * - * For example, this valid for loop: - * for (let a = (b in c); ;); - * after removing parentheses would be treated as an invalid for-in loop: - * for (let a = b in c; ;); - */ - - if (reportsBuffer.reports.length) { - reportsBuffer.inExpressionNodes.forEach(inExpressionNode => { - const path = pathToDescendant(node, inExpressionNode); - let nodeToExclude; - - for (let i = 0; i < path.length; i++) { - const pathNode = path[i]; - - if (i < path.length - 1) { - const nextPathNode = path[i + 1]; - - if (isSafelyEnclosingInExpression(pathNode, nextPathNode)) { - - // The 'in' expression in safely enclosed by the syntax of its ancestor nodes (e.g. by '{}' or '[]'). - return; - } - } - - if (isParenthesised(pathNode)) { - if (isInCurrentReportsBuffer(pathNode)) { - - // This node was supposed to be reported, but parentheses might be necessary. - - if (isParenthesisedTwice(pathNode)) { - - /* - * This node is parenthesised twice, it certainly has at least one pair of `extra` parentheses. - * If the --fix option is on, the current fixing iteration will remove only one pair of parentheses. - * The remaining pair is safely enclosing the 'in' expression. - */ - return; - } - - // Exclude the outermost node only. - if (!nodeToExclude) { - nodeToExclude = pathNode; - } - - // Don't break the loop here, there might be some safe nodes or parentheses that will stay inside. - - } else { - - // This node will stay parenthesised, the 'in' expression in safely enclosed by '()'. - return; - } - } - } - - // Exclude the node from the list (i.e. treat parentheses as necessary) - removeFromCurrentReportsBuffer(nodeToExclude); - }); - } - - endCurrentReportsBuffering(); - }, - - IfStatement(node) { - if (hasExcessParens(node.test) && !isCondAssignException(node)) { - report(node.test); - } - }, - - ImportExpression(node) { - const { source } = node; - - if (source.type === "SequenceExpression") { - if (hasDoubleExcessParens(source)) { - report(source); - } - } else if (hasExcessParens(source)) { - report(source); - } - }, - - LogicalExpression: checkBinaryLogical, - - MemberExpression(node) { - const shouldAllowWrapOnce = isMemberExpInNewCallee(node) && - doesMemberExpressionContainCallExpression(node); - const nodeObjHasExcessParens = shouldAllowWrapOnce - ? hasDoubleExcessParens(node.object) - : hasExcessParens(node.object) && - !( - isImmediateFunctionPrototypeMethodCall(node.parent) && - node.parent.callee === node && - IGNORE_FUNCTION_PROTOTYPE_METHODS - ); - - if ( - nodeObjHasExcessParens && - precedence(node.object) >= precedence(node) && - ( - node.computed || - !( - astUtils.isDecimalInteger(node.object) || - - // RegExp literal is allowed to have parens (#1589) - (node.object.type === "Literal" && node.object.regex) - ) - ) - ) { - report(node.object); - } - - if (nodeObjHasExcessParens && - node.object.type === "CallExpression" - ) { - report(node.object); - } - - if (nodeObjHasExcessParens && - !IGNORE_NEW_IN_MEMBER_EXPR && - node.object.type === "NewExpression" && - isNewExpressionWithParens(node.object)) { - report(node.object); - } - - if (nodeObjHasExcessParens && - node.optional && - node.object.type === "ChainExpression" - ) { - report(node.object); - } - - if (node.computed && hasExcessParens(node.property)) { - report(node.property); - } - }, - - NewExpression: checkCallNew, - - ObjectExpression(node) { - node.properties - .filter(property => property.value && hasExcessParensWithPrecedence(property.value, PRECEDENCE_OF_ASSIGNMENT_EXPR)) - .forEach(property => report(property.value)); - }, - - ObjectPattern(node) { - node.properties - .filter(property => { - const value = property.value; - - return canBeAssignmentTarget(value) && hasExcessParens(value); - }).forEach(property => report(property.value)); - }, - - Property(node) { - if (node.computed) { - const { key } = node; - - if (key && hasExcessParensWithPrecedence(key, PRECEDENCE_OF_ASSIGNMENT_EXPR)) { - report(key); - } - } - }, - - RestElement(node) { - const argument = node.argument; - - if (canBeAssignmentTarget(argument) && hasExcessParens(argument)) { - report(argument); - } - }, - - ReturnStatement(node) { - const returnToken = sourceCode.getFirstToken(node); - - if (isReturnAssignException(node)) { - return; - } - - if (node.argument && - hasExcessParensNoLineTerminator(returnToken, node.argument) && - - // RegExp literal is allowed to have parens (#1589) - !(node.argument.type === "Literal" && node.argument.regex)) { - report(node.argument); - } - }, - - SequenceExpression(node) { - const precedenceOfNode = precedence(node); - - node.expressions - .filter(e => hasExcessParensWithPrecedence(e, precedenceOfNode)) - .forEach(report); - }, - - SwitchCase(node) { - if (node.test && hasExcessParens(node.test)) { - report(node.test); - } - }, - - SwitchStatement(node) { - if (hasExcessParens(node.discriminant)) { - report(node.discriminant); - } - }, - - ThrowStatement(node) { - const throwToken = sourceCode.getFirstToken(node); - - if (hasExcessParensNoLineTerminator(throwToken, node.argument)) { - report(node.argument); - } - }, - - UnaryExpression: checkArgumentWithPrecedence, - UpdateExpression(node) { - if (node.prefix) { - checkArgumentWithPrecedence(node); - } else { - const { argument } = node; - const operatorToken = sourceCode.getLastToken(node); - - if (argument.loc.end.line === operatorToken.loc.start.line) { - checkArgumentWithPrecedence(node); - } else { - if (hasDoubleExcessParens(argument)) { - report(argument); - } - } - } - }, - AwaitExpression: checkArgumentWithPrecedence, - - VariableDeclarator(node) { - if ( - node.init && hasExcessParensWithPrecedence(node.init, PRECEDENCE_OF_ASSIGNMENT_EXPR) && - - // RegExp literal is allowed to have parens (#1589) - !(node.init.type === "Literal" && node.init.regex) - ) { - report(node.init); - } - }, - - WhileStatement(node) { - if (hasExcessParens(node.test) && !isCondAssignException(node)) { - report(node.test); - } - }, - - WithStatement(node) { - if (hasExcessParens(node.object)) { - report(node.object); - } - }, - - YieldExpression(node) { - if (node.argument) { - const yieldToken = sourceCode.getFirstToken(node); - - if ((precedence(node.argument) >= precedence(node) && - hasExcessParensNoLineTerminator(yieldToken, node.argument)) || - hasDoubleExcessParens(node.argument)) { - report(node.argument); - } - } - }, - - ClassDeclaration: checkClass, - ClassExpression: checkClass, - - SpreadElement: checkSpreadOperator, - SpreadProperty: checkSpreadOperator, - ExperimentalSpreadProperty: checkSpreadOperator, - - TemplateLiteral(node) { - node.expressions - .filter(e => e && hasExcessParens(e)) - .forEach(report); - }, - - AssignmentPattern(node) { - const { left, right } = node; - - if (canBeAssignmentTarget(left) && hasExcessParens(left)) { - report(left); - } - - if (right && hasExcessParensWithPrecedence(right, PRECEDENCE_OF_ASSIGNMENT_EXPR)) { - report(right); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag use of unnecessary semicolons - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noExtraSemi = { - meta: { - type: "suggestion", - - docs: { - description: "disallow unnecessary semicolons", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-extra-semi" - }, - - fixable: "code", - schema: [], - - messages: { - unexpected: "Unnecessary semicolon." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - /** - * Reports an unnecessary semicolon error. - * @param {Node|Token} nodeOrToken A node or a token to be reported. - * @returns {void} - */ - function report(nodeOrToken) { - context.report({ - node: nodeOrToken, - messageId: "unexpected", - fix(fixer) { - - /* - * Expand the replacement range to include the surrounding - * tokens to avoid conflicting with semi. - * https://github.com/eslint/eslint/issues/7928 - */ - return new fixTracker(fixer, context.getSourceCode()) - .retainSurroundingTokens(nodeOrToken) - .remove(nodeOrToken); - } - }); - } - - /** - * Checks for a part of a class body. - * This checks tokens from a specified token to a next MethodDefinition or the end of class body. - * @param {Token} firstToken The first token to check. - * @returns {void} - */ - function checkForPartOfClassBody(firstToken) { - for (let token = firstToken; - token.type === "Punctuator" && !astUtils.isClosingBraceToken(token); - token = sourceCode.getTokenAfter(token) - ) { - if (astUtils.isSemicolonToken(token)) { - report(token); - } - } - } - - return { - - /** - * Reports this empty statement, except if the parent node is a loop. - * @param {Node} node A EmptyStatement node to be reported. - * @returns {void} - */ - EmptyStatement(node) { - const parent = node.parent, - allowedParentTypes = [ - "ForStatement", - "ForInStatement", - "ForOfStatement", - "WhileStatement", - "DoWhileStatement", - "IfStatement", - "LabeledStatement", - "WithStatement" - ]; - - if (allowedParentTypes.indexOf(parent.type) === -1) { - report(node); - } - }, - - /** - * Checks tokens from the head of this class body to the first MethodDefinition or the end of this class body. - * @param {Node} node A ClassBody node to check. - * @returns {void} - */ - ClassBody(node) { - checkForPartOfClassBody(sourceCode.getFirstToken(node, 1)); // 0 is `{`. - }, - - /** - * Checks tokens from this MethodDefinition to the next MethodDefinition or the end of this class body. - * @param {Node} node A MethodDefinition node of the start point. - * @returns {void} - */ - MethodDefinition(node) { - checkForPartOfClassBody(sourceCode.getTokenAfter(node)); - } - }; - - } -}; - -/** - * @fileoverview Rule to flag fall-through cases in switch statements. - * @author Matt DuVall - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const DEFAULT_FALLTHROUGH_COMMENT = /falls?\s?through/iu; - -/** - * Checks whether or not a given node has a fallthrough comment. - * @param {ASTNode} node A SwitchCase node to get comments. - * @param {RuleContext} context A rule context which stores comments. - * @param {RegExp} fallthroughCommentPattern A pattern to match comment to. - * @returns {boolean} `true` if the node has a valid fallthrough comment. - */ -function hasFallthroughComment(node, context, fallthroughCommentPattern) { - const sourceCode = context.getSourceCode(); - const comment = lodash__default['default'].last(sourceCode.getCommentsBefore(node)); - - return Boolean(comment && fallthroughCommentPattern.test(comment.value)); -} - -/** - * Checks whether or not a given code path segment is reachable. - * @param {CodePathSegment} segment A CodePathSegment to check. - * @returns {boolean} `true` if the segment is reachable. - */ -function isReachable(segment) { - return segment.reachable; -} - -/** - * Checks whether a node and a token are separated by blank lines - * @param {ASTNode} node The node to check - * @param {Token} token The token to compare against - * @returns {boolean} `true` if there are blank lines between node and token - */ -function hasBlankLinesBetween(node, token) { - return token.loc.start.line > node.loc.end.line + 1; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noFallthrough = { - meta: { - type: "problem", - - docs: { - description: "disallow fallthrough of `case` statements", - category: "Best Practices", - recommended: true, - url: "https://eslint.org/docs/rules/no-fallthrough" - }, - - schema: [ - { - type: "object", - properties: { - commentPattern: { - type: "string", - default: "" - } - }, - additionalProperties: false - } - ], - messages: { - case: "Expected a 'break' statement before 'case'.", - default: "Expected a 'break' statement before 'default'." - } - }, - - create(context) { - const options = context.options[0] || {}; - let currentCodePath = null; - const sourceCode = context.getSourceCode(); - - /* - * We need to use leading comments of the next SwitchCase node because - * trailing comments is wrong if semicolons are omitted. - */ - let fallthroughCase = null; - let fallthroughCommentPattern = null; - - if (options.commentPattern) { - fallthroughCommentPattern = new RegExp(options.commentPattern, "u"); - } else { - fallthroughCommentPattern = DEFAULT_FALLTHROUGH_COMMENT; - } - - return { - onCodePathStart(codePath) { - currentCodePath = codePath; - }, - onCodePathEnd() { - currentCodePath = currentCodePath.upper; - }, - - SwitchCase(node) { - - /* - * Checks whether or not there is a fallthrough comment. - * And reports the previous fallthrough node if that does not exist. - */ - if (fallthroughCase && !hasFallthroughComment(node, context, fallthroughCommentPattern)) { - context.report({ - messageId: node.test ? "case" : "default", - node - }); - } - fallthroughCase = null; - }, - - "SwitchCase:exit"(node) { - const nextToken = sourceCode.getTokenAfter(node); - - /* - * `reachable` meant fall through because statements preceded by - * `break`, `return`, or `throw` are unreachable. - * And allows empty cases and the last case. - */ - if (currentCodePath.currentSegments.some(isReachable) && - (node.consequent.length > 0 || hasBlankLinesBetween(node, nextToken)) && - lodash__default['default'].last(node.parent.cases) !== node) { - fallthroughCase = node; - } - } - }; - } -}; - -/** - * @fileoverview Rule to flag use of a leading/trailing decimal point in a numeric literal - * @author James Allardice - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noFloatingDecimal = { - meta: { - type: "suggestion", - - docs: { - description: "disallow leading or trailing decimal points in numeric literals", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-floating-decimal" - }, - - schema: [], - fixable: "code", - messages: { - leading: "A leading decimal point can be confused with a dot.", - trailing: "A trailing decimal point can be confused with a dot." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - return { - Literal(node) { - - if (typeof node.value === "number") { - if (node.raw.startsWith(".")) { - context.report({ - node, - messageId: "leading", - fix(fixer) { - const tokenBefore = sourceCode.getTokenBefore(node); - const needsSpaceBefore = tokenBefore && - tokenBefore.range[1] === node.range[0] && - !astUtils.canTokensBeAdjacent(tokenBefore, `0${node.raw}`); - - return fixer.insertTextBefore(node, needsSpaceBefore ? " 0" : "0"); - } - }); - } - if (node.raw.indexOf(".") === node.raw.length - 1) { - context.report({ - node, - messageId: "trailing", - fix: fixer => fixer.insertTextAfter(node, "0") - }); - } - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag use of function declaration identifiers as variables. - * @author Ian Christian Myers - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noFuncAssign = { - meta: { - type: "problem", - - docs: { - description: "disallow reassigning `function` declarations", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-func-assign" - }, - - schema: [], - - messages: { - isAFunction: "'{{name}}' is a function." - } - }, - - create(context) { - - /** - * Reports a reference if is non initializer and writable. - * @param {References} references Collection of reference to check. - * @returns {void} - */ - function checkReference(references) { - astUtils.getModifyingReferences(references).forEach(reference => { - context.report({ - node: reference.identifier, - messageId: "isAFunction", - data: { - name: reference.identifier.name - } - }); - }); - } - - /** - * Finds and reports references that are non initializer and writable. - * @param {Variable} variable A variable to check. - * @returns {void} - */ - function checkVariable(variable) { - if (variable.defs[0].type === "FunctionName") { - checkReference(variable.references); - } - } - - /** - * Checks parameters of a given function node. - * @param {ASTNode} node A function node to check. - * @returns {void} - */ - function checkForFunction(node) { - context.getDeclaredVariables(node).forEach(checkVariable); - } - - return { - FunctionDeclaration: checkForFunction, - FunctionExpression: checkForFunction - }; - } -}; - -/** - * @fileoverview Rule to disallow assignments to native objects or read-only global variables - * @author Ilya Volodin - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noGlobalAssign = { - meta: { - type: "suggestion", - - docs: { - description: "disallow assignments to native objects or read-only global variables", - category: "Best Practices", - recommended: true, - url: "https://eslint.org/docs/rules/no-global-assign" - }, - - schema: [ - { - type: "object", - properties: { - exceptions: { - type: "array", - items: { type: "string" }, - uniqueItems: true - } - }, - additionalProperties: false - } - ], - - messages: { - globalShouldNotBeModified: "Read-only global '{{name}}' should not be modified." - } - }, - - create(context) { - const config = context.options[0]; - const exceptions = (config && config.exceptions) || []; - - /** - * Reports write references. - * @param {Reference} reference A reference to check. - * @param {int} index The index of the reference in the references. - * @param {Reference[]} references The array that the reference belongs to. - * @returns {void} - */ - function checkReference(reference, index, references) { - const identifier = reference.identifier; - - if (reference.init === false && - reference.isWrite() && - - /* - * Destructuring assignments can have multiple default value, - * so possibly there are multiple writeable references for the same identifier. - */ - (index === 0 || references[index - 1].identifier !== identifier) - ) { - context.report({ - node: identifier, - messageId: "globalShouldNotBeModified", - data: { - name: identifier.name - } - }); - } - } - - /** - * Reports write references if a given variable is read-only builtin. - * @param {Variable} variable A variable to check. - * @returns {void} - */ - function checkVariable(variable) { - if (variable.writeable === false && exceptions.indexOf(variable.name) === -1) { - variable.references.forEach(checkReference); - } - } - - return { - Program() { - const globalScope = context.getScope(); - - globalScope.variables.forEach(checkVariable); - } - }; - } -}; - -/** - * @fileoverview A rule to disallow the type conversions with shorter notations. - * @author Toru Nagashima - */ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const INDEX_OF_PATTERN = /^(?:i|lastI)ndexOf$/u; -const ALLOWABLE_OPERATORS = ["~", "!!", "+", "*"]; - -/** - * Parses and normalizes an option object. - * @param {Object} options An option object to parse. - * @returns {Object} The parsed and normalized option object. - */ -function parseOptions$1(options) { - return { - boolean: "boolean" in options ? options.boolean : true, - number: "number" in options ? options.number : true, - string: "string" in options ? options.string : true, - disallowTemplateShorthand: "disallowTemplateShorthand" in options ? options.disallowTemplateShorthand : false, - allow: options.allow || [] - }; -} - -/** - * Checks whether or not a node is a double logical nigating. - * @param {ASTNode} node An UnaryExpression node to check. - * @returns {boolean} Whether or not the node is a double logical nigating. - */ -function isDoubleLogicalNegating(node) { - return ( - node.operator === "!" && - node.argument.type === "UnaryExpression" && - node.argument.operator === "!" - ); -} - -/** - * Checks whether or not a node is a binary negating of `.indexOf()` method calling. - * @param {ASTNode} node An UnaryExpression node to check. - * @returns {boolean} Whether or not the node is a binary negating of `.indexOf()` method calling. - */ -function isBinaryNegatingOfIndexOf(node) { - if (node.operator !== "~") { - return false; - } - const callNode = astUtils.skipChainExpression(node.argument); - - return ( - callNode.type === "CallExpression" && - astUtils.isSpecificMemberAccess(callNode.callee, null, INDEX_OF_PATTERN) - ); -} - -/** - * Checks whether or not a node is a multiplying by one. - * @param {BinaryExpression} node A BinaryExpression node to check. - * @returns {boolean} Whether or not the node is a multiplying by one. - */ -function isMultiplyByOne(node) { - return node.operator === "*" && ( - node.left.type === "Literal" && node.left.value === 1 || - node.right.type === "Literal" && node.right.value === 1 - ); -} - -/** - * Checks whether the result of a node is numeric or not - * @param {ASTNode} node The node to test - * @returns {boolean} true if the node is a number literal or a `Number()`, `parseInt` or `parseFloat` call - */ -function isNumeric(node) { - return ( - node.type === "Literal" && typeof node.value === "number" || - node.type === "CallExpression" && ( - node.callee.name === "Number" || - node.callee.name === "parseInt" || - node.callee.name === "parseFloat" - ) - ); -} - -/** - * Returns the first non-numeric operand in a BinaryExpression. Designed to be - * used from bottom to up since it walks up the BinaryExpression trees using - * node.parent to find the result. - * @param {BinaryExpression} node The BinaryExpression node to be walked up on - * @returns {ASTNode|null} The first non-numeric item in the BinaryExpression tree or null - */ -function getNonNumericOperand(node) { - const left = node.left, - right = node.right; - - if (right.type !== "BinaryExpression" && !isNumeric(right)) { - return right; - } - - if (left.type !== "BinaryExpression" && !isNumeric(left)) { - return left; - } - - return null; -} - -/** - * Checks whether a node is an empty string literal or not. - * @param {ASTNode} node The node to check. - * @returns {boolean} Whether or not the passed in node is an - * empty string literal or not. - */ -function isEmptyString(node) { - return astUtils.isStringLiteral(node) && (node.value === "" || (node.type === "TemplateLiteral" && node.quasis.length === 1 && node.quasis[0].value.cooked === "")); -} - -/** - * Checks whether or not a node is a concatenating with an empty string. - * @param {ASTNode} node A BinaryExpression node to check. - * @returns {boolean} Whether or not the node is a concatenating with an empty string. - */ -function isConcatWithEmptyString(node) { - return node.operator === "+" && ( - (isEmptyString(node.left) && !astUtils.isStringLiteral(node.right)) || - (isEmptyString(node.right) && !astUtils.isStringLiteral(node.left)) - ); -} - -/** - * Checks whether or not a node is appended with an empty string. - * @param {ASTNode} node An AssignmentExpression node to check. - * @returns {boolean} Whether or not the node is appended with an empty string. - */ -function isAppendEmptyString(node) { - return node.operator === "+=" && isEmptyString(node.right); -} - -/** - * Returns the operand that is not an empty string from a flagged BinaryExpression. - * @param {ASTNode} node The flagged BinaryExpression node to check. - * @returns {ASTNode} The operand that is not an empty string from a flagged BinaryExpression. - */ -function getNonEmptyOperand(node) { - return isEmptyString(node.left) ? node.right : node.left; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noImplicitCoercion = { - meta: { - type: "suggestion", - - docs: { - description: "disallow shorthand type conversions", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-implicit-coercion" - }, - - fixable: "code", - - schema: [{ - type: "object", - properties: { - boolean: { - type: "boolean", - default: true - }, - number: { - type: "boolean", - default: true - }, - string: { - type: "boolean", - default: true - }, - disallowTemplateShorthand: { - type: "boolean", - default: false - }, - allow: { - type: "array", - items: { - enum: ALLOWABLE_OPERATORS - }, - uniqueItems: true - } - }, - additionalProperties: false - }], - - messages: { - useRecommendation: "use `{{recommendation}}` instead." - } - }, - - create(context) { - const options = parseOptions$1(context.options[0] || {}); - const sourceCode = context.getSourceCode(); - - /** - * Reports an error and autofixes the node - * @param {ASTNode} node An ast node to report the error on. - * @param {string} recommendation The recommended code for the issue - * @param {bool} shouldFix Whether this report should fix the node - * @returns {void} - */ - function report(node, recommendation, shouldFix) { - context.report({ - node, - messageId: "useRecommendation", - data: { - recommendation - }, - fix(fixer) { - if (!shouldFix) { - return null; - } - - const tokenBefore = sourceCode.getTokenBefore(node); - - if ( - tokenBefore && - tokenBefore.range[1] === node.range[0] && - !astUtils.canTokensBeAdjacent(tokenBefore, recommendation) - ) { - return fixer.replaceText(node, ` ${recommendation}`); - } - return fixer.replaceText(node, recommendation); - } - }); - } - - return { - UnaryExpression(node) { - let operatorAllowed; - - // !!foo - operatorAllowed = options.allow.indexOf("!!") >= 0; - if (!operatorAllowed && options.boolean && isDoubleLogicalNegating(node)) { - const recommendation = `Boolean(${sourceCode.getText(node.argument.argument)})`; - - report(node, recommendation, true); - } - - // ~foo.indexOf(bar) - operatorAllowed = options.allow.indexOf("~") >= 0; - if (!operatorAllowed && options.boolean && isBinaryNegatingOfIndexOf(node)) { - - // `foo?.indexOf(bar) !== -1` will be true (== found) if the `foo` is nullish. So use `>= 0` in that case. - const comparison = node.argument.type === "ChainExpression" ? ">= 0" : "!== -1"; - const recommendation = `${sourceCode.getText(node.argument)} ${comparison}`; - - report(node, recommendation, false); - } - - // +foo - operatorAllowed = options.allow.indexOf("+") >= 0; - if (!operatorAllowed && options.number && node.operator === "+" && !isNumeric(node.argument)) { - const recommendation = `Number(${sourceCode.getText(node.argument)})`; - - report(node, recommendation, true); - } - }, - - // Use `:exit` to prevent double reporting - "BinaryExpression:exit"(node) { - let operatorAllowed; - - // 1 * foo - operatorAllowed = options.allow.indexOf("*") >= 0; - const nonNumericOperand = !operatorAllowed && options.number && isMultiplyByOne(node) && getNonNumericOperand(node); - - if (nonNumericOperand) { - const recommendation = `Number(${sourceCode.getText(nonNumericOperand)})`; - - report(node, recommendation, true); - } - - // "" + foo - operatorAllowed = options.allow.indexOf("+") >= 0; - if (!operatorAllowed && options.string && isConcatWithEmptyString(node)) { - const recommendation = `String(${sourceCode.getText(getNonEmptyOperand(node))})`; - - report(node, recommendation, true); - } - }, - - AssignmentExpression(node) { - - // foo += "" - const operatorAllowed = options.allow.indexOf("+") >= 0; - - if (!operatorAllowed && options.string && isAppendEmptyString(node)) { - const code = sourceCode.getText(getNonEmptyOperand(node)); - const recommendation = `${code} = String(${code})`; - - report(node, recommendation, true); - } - }, - - TemplateLiteral(node) { - if (!options.disallowTemplateShorthand) { - return; - } - - // tag`${foo}` - if (node.parent.type === "TaggedTemplateExpression") { - return; - } - - // `` or `${foo}${bar}` - if (node.expressions.length !== 1) { - return; - } - - - // `prefix${foo}` - if (node.quasis[0].value.cooked !== "") { - return; - } - - // `${foo}postfix` - if (node.quasis[1].value.cooked !== "") { - return; - } - - const code = sourceCode.getText(node.expressions[0]); - const recommendation = `String(${code})`; - - report(node, recommendation, true); - } - }; - } -}; - -/** - * @fileoverview Rule to check for implicit global variables, functions and classes. - * @author Joshua Peek - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noImplicitGlobals = { - meta: { - type: "suggestion", - - docs: { - description: "disallow declarations in the global scope", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-implicit-globals" - }, - - schema: [{ - type: "object", - properties: { - lexicalBindings: { - type: "boolean", - default: false - } - }, - additionalProperties: false - }], - - messages: { - globalNonLexicalBinding: "Unexpected {{kind}} declaration in the global scope, wrap in an IIFE for a local variable, assign as global property for a global variable.", - globalLexicalBinding: "Unexpected {{kind}} declaration in the global scope, wrap in a block or in an IIFE.", - globalVariableLeak: "Global variable leak, declare the variable if it is intended to be local.", - assignmentToReadonlyGlobal: "Unexpected assignment to read-only global variable.", - redeclarationOfReadonlyGlobal: "Unexpected redeclaration of read-only global variable." - } - }, - - create(context) { - - const checkLexicalBindings = context.options[0] && context.options[0].lexicalBindings === true; - - /** - * Reports the node. - * @param {ASTNode} node Node to report. - * @param {string} messageId Id of the message to report. - * @param {string|undefined} kind Declaration kind, can be 'var', 'const', 'let', function or class. - * @returns {void} - */ - function report(node, messageId, kind) { - context.report({ - node, - messageId, - data: { - kind - } - }); - } - - return { - Program() { - const scope = context.getScope(); - - scope.variables.forEach(variable => { - - // Only ESLint global variables have the `writable` key. - const isReadonlyEslintGlobalVariable = variable.writeable === false; - const isWritableEslintGlobalVariable = variable.writeable === true; - - if (isWritableEslintGlobalVariable) { - - // Everything is allowed with writable ESLint global variables. - return; - } - - variable.defs.forEach(def => { - const defNode = def.node; - - if (def.type === "FunctionName" || (def.type === "Variable" && def.parent.kind === "var")) { - if (isReadonlyEslintGlobalVariable) { - report(defNode, "redeclarationOfReadonlyGlobal"); - } else { - report( - defNode, - "globalNonLexicalBinding", - def.type === "FunctionName" ? "function" : `'${def.parent.kind}'` - ); - } - } - - if (checkLexicalBindings) { - if (def.type === "ClassName" || - (def.type === "Variable" && (def.parent.kind === "let" || def.parent.kind === "const"))) { - if (isReadonlyEslintGlobalVariable) { - report(defNode, "redeclarationOfReadonlyGlobal"); - } else { - report( - defNode, - "globalLexicalBinding", - def.type === "ClassName" ? "class" : `'${def.parent.kind}'` - ); - } - } - } - }); - }); - - // Undeclared assigned variables. - scope.implicit.variables.forEach(variable => { - const scopeVariable = scope.set.get(variable.name); - let messageId; - - if (scopeVariable) { - - // ESLint global variable - if (scopeVariable.writeable) { - return; - } - messageId = "assignmentToReadonlyGlobal"; - - } else { - - // Reference to an unknown variable, possible global leak. - messageId = "globalVariableLeak"; - } - - // def.node is an AssignmentExpression, ForInStatement or ForOfStatement. - variable.defs.forEach(def => { - report(def.node, messageId); - }); - }); - } - }; - - } -}; - -/** - * @fileoverview Rule to flag use of implied eval via setTimeout and setInterval - * @author James Allardice - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - -const { getStaticValue } = require$$0__default$1['default']; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noImpliedEval = { - meta: { - type: "suggestion", - - docs: { - description: "disallow the use of `eval()`-like methods", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-implied-eval" - }, - - schema: [], - - messages: { - impliedEval: "Implied eval. Consider passing a function instead of a string." - } - }, - - create(context) { - const GLOBAL_CANDIDATES = Object.freeze(["global", "window", "globalThis"]); - const EVAL_LIKE_FUNC_PATTERN = /^(?:set(?:Interval|Timeout)|execScript)$/u; - - /** - * Checks whether a node is evaluated as a string or not. - * @param {ASTNode} node A node to check. - * @returns {boolean} True if the node is evaluated as a string. - */ - function isEvaluatedString(node) { - if ( - (node.type === "Literal" && typeof node.value === "string") || - node.type === "TemplateLiteral" - ) { - return true; - } - if (node.type === "BinaryExpression" && node.operator === "+") { - return isEvaluatedString(node.left) || isEvaluatedString(node.right); - } - return false; - } - - /** - * Reports if the `CallExpression` node has evaluated argument. - * @param {ASTNode} node A CallExpression to check. - * @returns {void} - */ - function reportImpliedEvalCallExpression(node) { - const [firstArgument] = node.arguments; - - if (firstArgument) { - - const staticValue = getStaticValue(firstArgument, context.getScope()); - const isStaticString = staticValue && typeof staticValue.value === "string"; - const isString = isStaticString || isEvaluatedString(firstArgument); - - if (isString) { - context.report({ - node, - messageId: "impliedEval" - }); - } - } - - } - - /** - * Reports calls of `implied eval` via the global references. - * @param {Variable} globalVar A global variable to check. - * @returns {void} - */ - function reportImpliedEvalViaGlobal(globalVar) { - const { references, name } = globalVar; - - references.forEach(ref => { - const identifier = ref.identifier; - let node = identifier.parent; - - while (astUtils.isSpecificMemberAccess(node, null, name)) { - node = node.parent; - } - - if (astUtils.isSpecificMemberAccess(node, null, EVAL_LIKE_FUNC_PATTERN)) { - const calleeNode = node.parent.type === "ChainExpression" ? node.parent : node; - const parent = calleeNode.parent; - - if (parent.type === "CallExpression" && parent.callee === calleeNode) { - reportImpliedEvalCallExpression(parent); - } - } - }); - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - CallExpression(node) { - if (astUtils.isSpecificId(node.callee, EVAL_LIKE_FUNC_PATTERN)) { - reportImpliedEvalCallExpression(node); - } - }, - "Program:exit"() { - const globalScope = context.getScope(); - - GLOBAL_CANDIDATES - .map(candidate => astUtils.getVariableByName(globalScope, candidate)) - .filter(globalVar => !!globalVar && globalVar.defs.length === 0) - .forEach(reportImpliedEvalViaGlobal); - } - }; - - } -}; - -/** - * @fileoverview Rule to flag updates of imported bindings. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const { findVariable: findVariable$3 } = require$$0__default$1['default']; - - -const WellKnownMutationFunctions = { - Object: /^(?:assign|definePropert(?:y|ies)|freeze|setPrototypeOf)$/u, - Reflect: /^(?:(?:define|delete)Property|set(?:PrototypeOf)?)$/u -}; - -/** - * Check if a given node is LHS of an assignment node. - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if the node is LHS. - */ -function isAssignmentLeft(node) { - const { parent } = node; - - return ( - ( - parent.type === "AssignmentExpression" && - parent.left === node - ) || - - // Destructuring assignments - parent.type === "ArrayPattern" || - ( - parent.type === "Property" && - parent.value === node && - parent.parent.type === "ObjectPattern" - ) || - parent.type === "RestElement" || - ( - parent.type === "AssignmentPattern" && - parent.left === node - ) - ); -} - -/** - * Check if a given node is the operand of mutation unary operator. - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if the node is the operand of mutation unary operator. - */ -function isOperandOfMutationUnaryOperator(node) { - const argumentNode = node.parent.type === "ChainExpression" - ? node.parent - : node; - const { parent } = argumentNode; - - return ( - ( - parent.type === "UpdateExpression" && - parent.argument === argumentNode - ) || - ( - parent.type === "UnaryExpression" && - parent.operator === "delete" && - parent.argument === argumentNode - ) - ); -} - -/** - * Check if a given node is the iteration variable of `for-in`/`for-of` syntax. - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if the node is the iteration variable. - */ -function isIterationVariable(node) { - const { parent } = node; - - return ( - ( - parent.type === "ForInStatement" && - parent.left === node - ) || - ( - parent.type === "ForOfStatement" && - parent.left === node - ) - ); -} - -/** - * Check if a given node is at the first argument of a well-known mutation function. - * - `Object.assign` - * - `Object.defineProperty` - * - `Object.defineProperties` - * - `Object.freeze` - * - `Object.setPrototypeOf` - * - `Reflect.defineProperty` - * - `Reflect.deleteProperty` - * - `Reflect.set` - * - `Reflect.setPrototypeOf` - * @param {ASTNode} node The node to check. - * @param {Scope} scope A `escope.Scope` object to find variable (whichever). - * @returns {boolean} `true` if the node is at the first argument of a well-known mutation function. - */ -function isArgumentOfWellKnownMutationFunction(node, scope) { - const { parent } = node; - - if (parent.type !== "CallExpression" || parent.arguments[0] !== node) { - return false; - } - const callee = astUtils.skipChainExpression(parent.callee); - - if ( - !astUtils.isSpecificMemberAccess(callee, "Object", WellKnownMutationFunctions.Object) && - !astUtils.isSpecificMemberAccess(callee, "Reflect", WellKnownMutationFunctions.Reflect) - ) { - return false; - } - const variable = findVariable$3(scope, callee.object); - - return variable !== null && variable.scope.type === "global"; -} - -/** - * Check if the identifier node is placed at to update members. - * @param {ASTNode} id The Identifier node to check. - * @param {Scope} scope A `escope.Scope` object to find variable (whichever). - * @returns {boolean} `true` if the member of `id` was updated. - */ -function isMemberWrite(id, scope) { - const { parent } = id; - - return ( - ( - parent.type === "MemberExpression" && - parent.object === id && - ( - isAssignmentLeft(parent) || - isOperandOfMutationUnaryOperator(parent) || - isIterationVariable(parent) - ) - ) || - isArgumentOfWellKnownMutationFunction(id, scope) - ); -} - -/** - * Get the mutation node. - * @param {ASTNode} id The Identifier node to get. - * @returns {ASTNode} The mutation node. - */ -function getWriteNode(id) { - let node = id.parent; - - while ( - node && - node.type !== "AssignmentExpression" && - node.type !== "UpdateExpression" && - node.type !== "UnaryExpression" && - node.type !== "CallExpression" && - node.type !== "ForInStatement" && - node.type !== "ForOfStatement" - ) { - node = node.parent; - } - - return node || id; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noImportAssign = { - meta: { - type: "problem", - - docs: { - description: "disallow assigning to imported bindings", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-import-assign" - }, - - schema: [], - - messages: { - readonly: "'{{name}}' is read-only.", - readonlyMember: "The members of '{{name}}' are read-only." - } - }, - - create(context) { - return { - ImportDeclaration(node) { - const scope = context.getScope(); - - for (const variable of context.getDeclaredVariables(node)) { - const shouldCheckMembers = variable.defs.some( - d => d.node.type === "ImportNamespaceSpecifier" - ); - let prevIdNode = null; - - for (const reference of variable.references) { - const idNode = reference.identifier; - - /* - * AssignmentPattern (e.g. `[a = 0] = b`) makes two write - * references for the same identifier. This should skip - * the one of the two in order to prevent redundant reports. - */ - if (idNode === prevIdNode) { - continue; - } - prevIdNode = idNode; - - if (reference.isWrite()) { - context.report({ - node: getWriteNode(idNode), - messageId: "readonly", - data: { name: idNode.name } - }); - } else if (shouldCheckMembers && isMemberWrite(idNode, scope)) { - context.report({ - node: getWriteNode(idNode), - messageId: "readonlyMember", - data: { name: idNode.name } - }); - } - } - } - } - }; - - } -}; - -/** - * @fileoverview Enforces or disallows inline comments. - * @author Greg Cochard - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noInlineComments = { - meta: { - type: "suggestion", - - docs: { - description: "disallow inline comments after code", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/no-inline-comments" - }, - - schema: [ - { - type: "object", - properties: { - ignorePattern: { - type: "string" - } - }, - additionalProperties: false - } - ], - - messages: { - unexpectedInlineComment: "Unexpected comment inline with code." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const options = context.options[0]; - let customIgnoreRegExp; - - if (options && options.ignorePattern) { - customIgnoreRegExp = new RegExp(options.ignorePattern, "u"); - } - - /** - * Will check that comments are not on lines starting with or ending with code - * @param {ASTNode} node The comment node to check - * @private - * @returns {void} - */ - function testCodeAroundComment(node) { - - const startLine = String(sourceCode.lines[node.loc.start.line - 1]), - endLine = String(sourceCode.lines[node.loc.end.line - 1]), - preamble = startLine.slice(0, node.loc.start.column).trim(), - postamble = endLine.slice(node.loc.end.column).trim(), - isPreambleEmpty = !preamble, - isPostambleEmpty = !postamble; - - // Nothing on both sides - if (isPreambleEmpty && isPostambleEmpty) { - return; - } - - // Matches the ignore pattern - if (customIgnoreRegExp && customIgnoreRegExp.test(node.value)) { - return; - } - - // JSX Exception - if ( - (isPreambleEmpty || preamble === "{") && - (isPostambleEmpty || postamble === "}") - ) { - const enclosingNode = sourceCode.getNodeByRangeIndex(node.range[0]); - - if (enclosingNode && enclosingNode.type === "JSXEmptyExpression") { - return; - } - } - - // Don't report ESLint directive comments - if (astUtils.isDirectiveComment(node)) { - return; - } - - context.report({ - node, - messageId: "unexpectedInlineComment" - }); - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - Program() { - sourceCode.getAllComments() - .filter(token => token.type !== "Shebang") - .forEach(testCodeAroundComment); - } - }; - } -}; - -/** - * @fileoverview Rule to enforce declarations in program or function body root. - * @author Brandon Mills - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -const validParent = new Set(["Program", "ExportNamedDeclaration", "ExportDefaultDeclaration"]); -const validBlockStatementParent = new Set(["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"]); - -var noInnerDeclarations = { - meta: { - type: "problem", - - docs: { - description: "disallow variable or `function` declarations in nested blocks", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-inner-declarations" - }, - - schema: [ - { - enum: ["functions", "both"] - } - ], - - messages: { - moveDeclToRoot: "Move {{type}} declaration to {{body}} root." - } - }, - - create(context) { - - /** - * Ensure that a given node is at a program or function body's root. - * @param {ASTNode} node Declaration node to check. - * @returns {void} - */ - function check(node) { - const parent = node.parent; - - if ( - parent.type === "BlockStatement" && validBlockStatementParent.has(parent.parent.type) - ) { - return; - } - - if (validParent.has(parent.type)) { - return; - } - - const upperFunction = astUtils.getUpperFunction(parent); - - context.report({ - node, - messageId: "moveDeclToRoot", - data: { - type: (node.type === "FunctionDeclaration" ? "function" : "variable"), - body: (upperFunction === null ? "program" : "function body") - } - }); - } - - - return { - - FunctionDeclaration: check, - VariableDeclaration(node) { - if (context.options[0] === "both" && node.kind === "var") { - check(node); - } - } - - }; - - } -}; - -/** - * @fileoverview Validate strings passed to the RegExp constructor - * @author Michael Ficarra - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -const RegExpValidator = regexpp__default['default'].RegExpValidator; -const validator = new RegExpValidator(); -const validFlags = /[gimuys]/gu; -const undefined1 = void 0; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noInvalidRegexp = { - meta: { - type: "problem", - - docs: { - description: "disallow invalid regular expression strings in `RegExp` constructors", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-invalid-regexp" - }, - - schema: [{ - type: "object", - properties: { - allowConstructorFlags: { - type: "array", - items: { - type: "string" - } - } - }, - additionalProperties: false - }], - - messages: { - regexMessage: "{{message}}." - } - }, - - create(context) { - - const options = context.options[0]; - let allowedFlags = null; - - if (options && options.allowConstructorFlags) { - const temp = options.allowConstructorFlags.join("").replace(validFlags, ""); - - if (temp) { - allowedFlags = new RegExp(`[${temp}]`, "giu"); - } - } - - /** - * Check if node is a string - * @param {ASTNode} node node to evaluate - * @returns {boolean} True if its a string - * @private - */ - function isString(node) { - return node && node.type === "Literal" && typeof node.value === "string"; - } - - /** - * Gets flags of a regular expression created by the given `RegExp()` or `new RegExp()` call - * Examples: - * new RegExp(".") // => "" - * new RegExp(".", "gu") // => "gu" - * new RegExp(".", flags) // => null - * @param {ASTNode} node `CallExpression` or `NewExpression` node - * @returns {string|null} flags if they can be determined, `null` otherwise - * @private - */ - function getFlags(node) { - if (node.arguments.length < 2) { - return ""; - } - - if (isString(node.arguments[1])) { - return node.arguments[1].value; - } - - return null; - } - - /** - * Check syntax error in a given pattern. - * @param {string} pattern The RegExp pattern to validate. - * @param {boolean} uFlag The Unicode flag. - * @returns {string|null} The syntax error. - */ - function validateRegExpPattern(pattern, uFlag) { - try { - validator.validatePattern(pattern, undefined1, undefined1, uFlag); - return null; - } catch (err) { - return err.message; - } - } - - /** - * Check syntax error in a given flags. - * @param {string} flags The RegExp flags to validate. - * @returns {string|null} The syntax error. - */ - function validateRegExpFlags(flags) { - try { - validator.validateFlags(flags); - return null; - } catch { - return `Invalid flags supplied to RegExp constructor '${flags}'`; - } - } - - return { - "CallExpression, NewExpression"(node) { - if (node.callee.type !== "Identifier" || node.callee.name !== "RegExp" || !isString(node.arguments[0])) { - return; - } - const pattern = node.arguments[0].value; - let flags = getFlags(node); - - if (flags && allowedFlags) { - flags = flags.replace(allowedFlags, ""); - } - - const message = - ( - flags && validateRegExpFlags(flags) - ) || - ( - - // If flags are unknown, report the regex only if its pattern is invalid both with and without the "u" flag - flags === null - ? validateRegExpPattern(pattern, true) && validateRegExpPattern(pattern, false) - : validateRegExpPattern(pattern, flags.includes("u")) - ); - - if (message) { - context.report({ - node, - messageId: "regexMessage", - data: { message } - }); - } - } - }; - } -}; - -/** - * @fileoverview A rule to disallow `this` keywords outside of classes or class-like objects. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noInvalidThis = { - meta: { - type: "suggestion", - - docs: { - description: "disallow `this` keywords outside of classes or class-like objects", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-invalid-this" - }, - - schema: [ - { - type: "object", - properties: { - capIsConstructor: { - type: "boolean", - default: true - } - }, - additionalProperties: false - } - ], - - messages: { - unexpectedThis: "Unexpected 'this'." - } - }, - - create(context) { - const options = context.options[0] || {}; - const capIsConstructor = options.capIsConstructor !== false; - const stack = [], - sourceCode = context.getSourceCode(); - - /** - * Gets the current checking context. - * - * The return value has a flag that whether or not `this` keyword is valid. - * The flag is initialized when got at the first time. - * @returns {{valid: boolean}} - * an object which has a flag that whether or not `this` keyword is valid. - */ - stack.getCurrent = function() { - const current = this[this.length - 1]; - - if (!current.init) { - current.init = true; - current.valid = !astUtils.isDefaultThisBinding( - current.node, - sourceCode, - { capIsConstructor } - ); - } - return current; - }; - - /** - * Pushs new checking context into the stack. - * - * The checking context is not initialized yet. - * Because most functions don't have `this` keyword. - * When `this` keyword was found, the checking context is initialized. - * @param {ASTNode} node A function node that was entered. - * @returns {void} - */ - function enterFunction(node) { - - // `this` can be invalid only under strict mode. - stack.push({ - init: !context.getScope().isStrict, - node, - valid: true - }); - } - - /** - * Pops the current checking context from the stack. - * @returns {void} - */ - function exitFunction() { - stack.pop(); - } - - return { - - /* - * `this` is invalid only under strict mode. - * Modules is always strict mode. - */ - Program(node) { - const scope = context.getScope(), - features = context.parserOptions.ecmaFeatures || {}; - - stack.push({ - init: true, - node, - valid: !( - scope.isStrict || - node.sourceType === "module" || - (features.globalReturn && scope.childScopes[0].isStrict) - ) - }); - }, - - "Program:exit"() { - stack.pop(); - }, - - FunctionDeclaration: enterFunction, - "FunctionDeclaration:exit": exitFunction, - FunctionExpression: enterFunction, - "FunctionExpression:exit": exitFunction, - - // Reports if `this` of the current context is invalid. - ThisExpression(node) { - const current = stack.getCurrent(); - - if (current && !current.valid) { - context.report({ - node, - messageId: "unexpectedThis" - }); - } - } - }; - } -}; - -/** - * @fileoverview Rule to disallow whitespace that is not a tab or space, whitespace inside strings and comments are allowed - * @author Jonathan Kingston - * @author Christophe Porteneuve - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Constants -//------------------------------------------------------------------------------ - -const ALL_IRREGULARS = /[\f\v\u0085\ufeff\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000\u2028\u2029]/u; -const IRREGULAR_WHITESPACE = /[\f\v\u0085\ufeff\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000]+/mgu; -const IRREGULAR_LINE_TERMINATORS = /[\u2028\u2029]/mgu; -const LINE_BREAK = astUtils.createGlobalLinebreakMatcher(); - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noIrregularWhitespace = { - meta: { - type: "problem", - - docs: { - description: "disallow irregular whitespace", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-irregular-whitespace" - }, - - schema: [ - { - type: "object", - properties: { - skipComments: { - type: "boolean", - default: false - }, - skipStrings: { - type: "boolean", - default: true - }, - skipTemplates: { - type: "boolean", - default: false - }, - skipRegExps: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - messages: { - noIrregularWhitespace: "Irregular whitespace not allowed." - } - }, - - create(context) { - - // Module store of errors that we have found - let errors = []; - - // Lookup the `skipComments` option, which defaults to `false`. - const options = context.options[0] || {}; - const skipComments = !!options.skipComments; - const skipStrings = options.skipStrings !== false; - const skipRegExps = !!options.skipRegExps; - const skipTemplates = !!options.skipTemplates; - - const sourceCode = context.getSourceCode(); - const commentNodes = sourceCode.getAllComments(); - - /** - * Removes errors that occur inside the given node - * @param {ASTNode} node to check for matching errors. - * @returns {void} - * @private - */ - function removeWhitespaceError(node) { - const locStart = node.loc.start; - const locEnd = node.loc.end; - - errors = errors.filter(({ loc: { start: errorLocStart } }) => ( - errorLocStart.line < locStart.line || - errorLocStart.line === locStart.line && errorLocStart.column < locStart.column || - errorLocStart.line === locEnd.line && errorLocStart.column >= locEnd.column || - errorLocStart.line > locEnd.line - )); - } - - /** - * Checks identifier or literal nodes for errors that we are choosing to ignore and calls the relevant methods to remove the errors - * @param {ASTNode} node to check for matching errors. - * @returns {void} - * @private - */ - function removeInvalidNodeErrorsInIdentifierOrLiteral(node) { - const shouldCheckStrings = skipStrings && (typeof node.value === "string"); - const shouldCheckRegExps = skipRegExps && Boolean(node.regex); - - if (shouldCheckStrings || shouldCheckRegExps) { - - // If we have irregular characters remove them from the errors list - if (ALL_IRREGULARS.test(node.raw)) { - removeWhitespaceError(node); - } - } - } - - /** - * Checks template string literal nodes for errors that we are choosing to ignore and calls the relevant methods to remove the errors - * @param {ASTNode} node to check for matching errors. - * @returns {void} - * @private - */ - function removeInvalidNodeErrorsInTemplateLiteral(node) { - if (typeof node.value.raw === "string") { - if (ALL_IRREGULARS.test(node.value.raw)) { - removeWhitespaceError(node); - } - } - } - - /** - * Checks comment nodes for errors that we are choosing to ignore and calls the relevant methods to remove the errors - * @param {ASTNode} node to check for matching errors. - * @returns {void} - * @private - */ - function removeInvalidNodeErrorsInComment(node) { - if (ALL_IRREGULARS.test(node.value)) { - removeWhitespaceError(node); - } - } - - /** - * Checks the program source for irregular whitespace - * @param {ASTNode} node The program node - * @returns {void} - * @private - */ - function checkForIrregularWhitespace(node) { - const sourceLines = sourceCode.lines; - - sourceLines.forEach((sourceLine, lineIndex) => { - const lineNumber = lineIndex + 1; - let match; - - while ((match = IRREGULAR_WHITESPACE.exec(sourceLine)) !== null) { - errors.push({ - node, - messageId: "noIrregularWhitespace", - loc: { - start: { - line: lineNumber, - column: match.index - }, - end: { - line: lineNumber, - column: match.index + match[0].length - } - } - }); - } - }); - } - - /** - * Checks the program source for irregular line terminators - * @param {ASTNode} node The program node - * @returns {void} - * @private - */ - function checkForIrregularLineTerminators(node) { - const source = sourceCode.getText(), - sourceLines = sourceCode.lines, - linebreaks = source.match(LINE_BREAK); - let lastLineIndex = -1, - match; - - while ((match = IRREGULAR_LINE_TERMINATORS.exec(source)) !== null) { - const lineIndex = linebreaks.indexOf(match[0], lastLineIndex + 1) || 0; - - errors.push({ - node, - messageId: "noIrregularWhitespace", - loc: { - start: { - line: lineIndex + 1, - column: sourceLines[lineIndex].length - }, - end: { - line: lineIndex + 2, - column: 0 - } - } - }); - - lastLineIndex = lineIndex; - } - } - - /** - * A no-op function to act as placeholder for comment accumulation when the `skipComments` option is `false`. - * @returns {void} - * @private - */ - function noop() {} - - const nodes = {}; - - if (ALL_IRREGULARS.test(sourceCode.getText())) { - nodes.Program = function(node) { - - /* - * As we can easily fire warnings for all white space issues with - * all the source its simpler to fire them here. - * This means we can check all the application code without having - * to worry about issues caused in the parser tokens. - * When writing this code also evaluating per node was missing out - * connecting tokens in some cases. - * We can later filter the errors when they are found to be not an - * issue in nodes we don't care about. - */ - checkForIrregularWhitespace(node); - checkForIrregularLineTerminators(node); - }; - - nodes.Identifier = removeInvalidNodeErrorsInIdentifierOrLiteral; - nodes.Literal = removeInvalidNodeErrorsInIdentifierOrLiteral; - nodes.TemplateElement = skipTemplates ? removeInvalidNodeErrorsInTemplateLiteral : noop; - nodes["Program:exit"] = function() { - if (skipComments) { - - // First strip errors occurring in comment nodes. - commentNodes.forEach(removeInvalidNodeErrorsInComment); - } - - // If we have any errors remaining report on them - errors.forEach(error => context.report(error)); - }; - } else { - nodes.Program = noop; - } - - return nodes; - } -}; - -/** - * @fileoverview Rule to flag usage of __iterator__ property - * @author Ian Christian Myers - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -const { getStaticPropertyName: getStaticPropertyName$1 } = astUtils; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noIterator = { - meta: { - type: "suggestion", - - docs: { - description: "disallow the use of the `__iterator__` property", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-iterator" - }, - - schema: [], - - messages: { - noIterator: "Reserved name '__iterator__'." - } - }, - - create(context) { - - return { - - MemberExpression(node) { - - if (getStaticPropertyName$1(node) === "__iterator__") { - context.report({ - node, - messageId: "noIterator" - }); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag labels that are the same as an identifier - * @author Ian Christian Myers - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noLabelVar = { - meta: { - type: "suggestion", - - docs: { - description: "disallow labels that share a name with a variable", - category: "Variables", - recommended: false, - url: "https://eslint.org/docs/rules/no-label-var" - }, - - schema: [], - - messages: { - identifierClashWithLabel: "Found identifier with same name as label." - } - }, - - create(context) { - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Check if the identifier is present inside current scope - * @param {Object} scope current scope - * @param {string} name To evaluate - * @returns {boolean} True if its present - * @private - */ - function findIdentifier(scope, name) { - return astUtils.getVariableByName(scope, name) !== null; - } - - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- - - return { - - LabeledStatement(node) { - - // Fetch the innermost scope. - const scope = context.getScope(); - - /* - * Recursively find the identifier walking up the scope, starting - * with the innermost scope. - */ - if (findIdentifier(scope, node.label.name)) { - context.report({ - node, - messageId: "identifierClashWithLabel" - }); - } - } - - }; - - } -}; - -/** - * @fileoverview Disallow Labeled Statements - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noLabels = { - meta: { - type: "suggestion", - - docs: { - description: "disallow labeled statements", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-labels" - }, - - schema: [ - { - type: "object", - properties: { - allowLoop: { - type: "boolean", - default: false - }, - allowSwitch: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - messages: { - unexpectedLabel: "Unexpected labeled statement.", - unexpectedLabelInBreak: "Unexpected label in break statement.", - unexpectedLabelInContinue: "Unexpected label in continue statement." - } - }, - - create(context) { - const options = context.options[0]; - const allowLoop = options && options.allowLoop; - const allowSwitch = options && options.allowSwitch; - let scopeInfo = null; - - /** - * Gets the kind of a given node. - * @param {ASTNode} node A node to get. - * @returns {string} The kind of the node. - */ - function getBodyKind(node) { - if (astUtils.isLoop(node)) { - return "loop"; - } - if (node.type === "SwitchStatement") { - return "switch"; - } - return "other"; - } - - /** - * Checks whether the label of a given kind is allowed or not. - * @param {string} kind A kind to check. - * @returns {boolean} `true` if the kind is allowed. - */ - function isAllowed(kind) { - switch (kind) { - case "loop": return allowLoop; - case "switch": return allowSwitch; - default: return false; - } - } - - /** - * Checks whether a given name is a label of a loop or not. - * @param {string} label A name of a label to check. - * @returns {boolean} `true` if the name is a label of a loop. - */ - function getKind(label) { - let info = scopeInfo; - - while (info) { - if (info.label === label) { - return info.kind; - } - info = info.upper; - } - - /* istanbul ignore next: syntax error */ - return "other"; - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - LabeledStatement(node) { - scopeInfo = { - label: node.label.name, - kind: getBodyKind(node.body), - upper: scopeInfo - }; - }, - - "LabeledStatement:exit"(node) { - if (!isAllowed(scopeInfo.kind)) { - context.report({ - node, - messageId: "unexpectedLabel" - }); - } - - scopeInfo = scopeInfo.upper; - }, - - BreakStatement(node) { - if (node.label && !isAllowed(getKind(node.label.name))) { - context.report({ - node, - messageId: "unexpectedLabelInBreak" - }); - } - }, - - ContinueStatement(node) { - if (node.label && !isAllowed(getKind(node.label.name))) { - context.report({ - node, - messageId: "unexpectedLabelInContinue" - }); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag blocks with no reason to exist - * @author Brandon Mills - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noLoneBlocks = { - meta: { - type: "suggestion", - - docs: { - description: "disallow unnecessary nested blocks", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-lone-blocks" - }, - - schema: [], - - messages: { - redundantBlock: "Block is redundant.", - redundantNestedBlock: "Nested block is redundant." - } - }, - - create(context) { - - // A stack of lone blocks to be checked for block-level bindings - const loneBlocks = []; - let ruleDef; - - /** - * Reports a node as invalid. - * @param {ASTNode} node The node to be reported. - * @returns {void} - */ - function report(node) { - const messageId = node.parent.type === "BlockStatement" ? "redundantNestedBlock" : "redundantBlock"; - - context.report({ - node, - messageId - }); - } - - /** - * Checks for any occurrence of a BlockStatement in a place where lists of statements can appear - * @param {ASTNode} node The node to check - * @returns {boolean} True if the node is a lone block. - */ - function isLoneBlock(node) { - return node.parent.type === "BlockStatement" || - node.parent.type === "Program" || - - // Don't report blocks in switch cases if the block is the only statement of the case. - node.parent.type === "SwitchCase" && !(node.parent.consequent[0] === node && node.parent.consequent.length === 1); - } - - /** - * Checks the enclosing block of the current node for block-level bindings, - * and "marks it" as valid if any. - * @returns {void} - */ - function markLoneBlock() { - if (loneBlocks.length === 0) { - return; - } - - const block = context.getAncestors().pop(); - - if (loneBlocks[loneBlocks.length - 1] === block) { - loneBlocks.pop(); - } - } - - // Default rule definition: report all lone blocks - ruleDef = { - BlockStatement(node) { - if (isLoneBlock(node)) { - report(node); - } - } - }; - - // ES6: report blocks without block-level bindings, or that's only child of another block - if (context.parserOptions.ecmaVersion >= 6) { - ruleDef = { - BlockStatement(node) { - if (isLoneBlock(node)) { - loneBlocks.push(node); - } - }, - "BlockStatement:exit"(node) { - if (loneBlocks.length > 0 && loneBlocks[loneBlocks.length - 1] === node) { - loneBlocks.pop(); - report(node); - } else if ( - node.parent.type === "BlockStatement" && - node.parent.body.length === 1 - ) { - report(node); - } - } - }; - - ruleDef.VariableDeclaration = function(node) { - if (node.kind === "let" || node.kind === "const") { - markLoneBlock(); - } - }; - - ruleDef.FunctionDeclaration = function() { - if (context.getScope().isStrict) { - markLoneBlock(); - } - }; - - ruleDef.ClassDeclaration = markLoneBlock; - } - - return ruleDef; - } -}; - -/** - * @fileoverview Rule to disallow if as the only statement in an else block - * @author Brandon Mills - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noLonelyIf = { - meta: { - type: "suggestion", - - docs: { - description: "disallow `if` statements as the only statement in `else` blocks", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/no-lonely-if" - }, - - schema: [], - fixable: "code", - - messages: { - unexpectedLonelyIf: "Unexpected if as the only statement in an else block." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - return { - IfStatement(node) { - const ancestors = context.getAncestors(), - parent = ancestors.pop(), - grandparent = ancestors.pop(); - - if (parent && parent.type === "BlockStatement" && - parent.body.length === 1 && grandparent && - grandparent.type === "IfStatement" && - parent === grandparent.alternate) { - context.report({ - node, - messageId: "unexpectedLonelyIf", - fix(fixer) { - const openingElseCurly = sourceCode.getFirstToken(parent); - const closingElseCurly = sourceCode.getLastToken(parent); - const elseKeyword = sourceCode.getTokenBefore(openingElseCurly); - const tokenAfterElseBlock = sourceCode.getTokenAfter(closingElseCurly); - const lastIfToken = sourceCode.getLastToken(node.consequent); - const sourceText = sourceCode.getText(); - - if (sourceText.slice(openingElseCurly.range[1], - node.range[0]).trim() || sourceText.slice(node.range[1], closingElseCurly.range[0]).trim()) { - - // Don't fix if there are any non-whitespace characters interfering (e.g. comments) - return null; - } - - if ( - node.consequent.type !== "BlockStatement" && lastIfToken.value !== ";" && tokenAfterElseBlock && - ( - node.consequent.loc.end.line === tokenAfterElseBlock.loc.start.line || - /^[([/+`-]/u.test(tokenAfterElseBlock.value) || - lastIfToken.value === "++" || - lastIfToken.value === "--" - ) - ) { - - /* - * If the `if` statement has no block, and is not followed by a semicolon, make sure that fixing - * the issue would not change semantics due to ASI. If this would happen, don't do a fix. - */ - return null; - } - - return fixer.replaceTextRange( - [openingElseCurly.range[0], closingElseCurly.range[1]], - (elseKeyword.range[1] === openingElseCurly.range[0] ? " " : "") + sourceCode.getText(node) - ); - } - }); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag creation of function inside a loop - * @author Ilya Volodin - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Gets the containing loop node of a specified node. - * - * We don't need to check nested functions, so this ignores those. - * `Scope.through` contains references of nested functions. - * @param {ASTNode} node An AST node to get. - * @returns {ASTNode|null} The containing loop node of the specified node, or - * `null`. - */ -function getContainingLoopNode(node) { - for (let currentNode = node; currentNode.parent; currentNode = currentNode.parent) { - const parent = currentNode.parent; - - switch (parent.type) { - case "WhileStatement": - case "DoWhileStatement": - return parent; - - case "ForStatement": - - // `init` is outside of the loop. - if (parent.init !== currentNode) { - return parent; - } - break; - - case "ForInStatement": - case "ForOfStatement": - - // `right` is outside of the loop. - if (parent.right !== currentNode) { - return parent; - } - break; - - case "ArrowFunctionExpression": - case "FunctionExpression": - case "FunctionDeclaration": - - // We don't need to check nested functions. - return null; - } - } - - return null; -} - -/** - * Gets the containing loop node of a given node. - * If the loop was nested, this returns the most outer loop. - * @param {ASTNode} node A node to get. This is a loop node. - * @param {ASTNode|null} excludedNode A node that the result node should not - * include. - * @returns {ASTNode} The most outer loop node. - */ -function getTopLoopNode(node, excludedNode) { - const border = excludedNode ? excludedNode.range[1] : 0; - let retv = node; - let containingLoopNode = node; - - while (containingLoopNode && containingLoopNode.range[0] >= border) { - retv = containingLoopNode; - containingLoopNode = getContainingLoopNode(containingLoopNode); - } - - return retv; -} - -/** - * Checks whether a given reference which refers to an upper scope's variable is - * safe or not. - * @param {ASTNode} loopNode A containing loop node. - * @param {eslint-scope.Reference} reference A reference to check. - * @returns {boolean} `true` if the reference is safe or not. - */ -function isSafe(loopNode, reference) { - const variable = reference.resolved; - const definition = variable && variable.defs[0]; - const declaration = definition && definition.parent; - const kind = (declaration && declaration.type === "VariableDeclaration") - ? declaration.kind - : ""; - - // Variables which are declared by `const` is safe. - if (kind === "const") { - return true; - } - - /* - * Variables which are declared by `let` in the loop is safe. - * It's a different instance from the next loop step's. - */ - if (kind === "let" && - declaration.range[0] > loopNode.range[0] && - declaration.range[1] < loopNode.range[1] - ) { - return true; - } - - /* - * WriteReferences which exist after this border are unsafe because those - * can modify the variable. - */ - const border = getTopLoopNode( - loopNode, - (kind === "let") ? declaration : null - ).range[0]; - - /** - * Checks whether a given reference is safe or not. - * The reference is every reference of the upper scope's variable we are - * looking now. - * - * It's safeafe if the reference matches one of the following condition. - * - is readonly. - * - doesn't exist inside a local function and after the border. - * @param {eslint-scope.Reference} upperRef A reference to check. - * @returns {boolean} `true` if the reference is safe. - */ - function isSafeReference(upperRef) { - const id = upperRef.identifier; - - return ( - !upperRef.isWrite() || - variable.scope.variableScope === upperRef.from.variableScope && - id.range[0] < border - ); - } - - return Boolean(variable) && variable.references.every(isSafeReference); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noLoopFunc = { - meta: { - type: "suggestion", - - docs: { - description: "disallow function declarations that contain unsafe references inside loop statements", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-loop-func" - }, - - schema: [], - - messages: { - unsafeRefs: "Function declared in a loop contains unsafe references to variable(s) {{ varNames }}." - } - }, - - create(context) { - - /** - * Reports functions which match the following condition: - * - * - has a loop node in ancestors. - * - has any references which refers to an unsafe variable. - * @param {ASTNode} node The AST node to check. - * @returns {boolean} Whether or not the node is within a loop. - */ - function checkForLoops(node) { - const loopNode = getContainingLoopNode(node); - - if (!loopNode) { - return; - } - - const references = context.getScope().through; - const unsafeRefs = references.filter(r => !isSafe(loopNode, r)).map(r => r.identifier.name); - - if (unsafeRefs.length > 0) { - context.report({ - node, - messageId: "unsafeRefs", - data: { varNames: `'${unsafeRefs.join("', '")}'` } - }); - } - } - - return { - ArrowFunctionExpression: checkForLoops, - FunctionExpression: checkForLoops, - FunctionDeclaration: checkForLoops - }; - } -}; - -/** - * @fileoverview Rule to flag numbers that will lose significant figure precision at runtime - * @author Jacob Moore - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noLossOfPrecision = { - meta: { - type: "problem", - - docs: { - description: "disallow literal numbers that lose precision", - category: "Possible Errors", - recommended: false, - url: "https://eslint.org/docs/rules/no-loss-of-precision" - }, - schema: [], - messages: { - noLossOfPrecision: "This number literal will lose precision at runtime." - } - }, - - create(context) { - - /** - * Returns whether the node is number literal - * @param {Node} node the node literal being evaluated - * @returns {boolean} true if the node is a number literal - */ - function isNumber(node) { - return typeof node.value === "number"; - } - - /** - * Gets the source code of the given number literal. Removes `_` numeric separators from the result. - * @param {Node} node the number `Literal` node - * @returns {string} raw source code of the literal, without numeric separators - */ - function getRaw(node) { - return node.raw.replace(/_/gu, ""); - } - - /** - * Checks whether the number is base ten - * @param {ASTNode} node the node being evaluated - * @returns {boolean} true if the node is in base ten - */ - function isBaseTen(node) { - const prefixes = ["0x", "0X", "0b", "0B", "0o", "0O"]; - - return prefixes.every(prefix => !node.raw.startsWith(prefix)) && - !/^0[0-7]+$/u.test(node.raw); - } - - /** - * Checks that the user-intended non-base ten number equals the actual number after is has been converted to the Number type - * @param {Node} node the node being evaluated - * @returns {boolean} true if they do not match - */ - function notBaseTenLosesPrecision(node) { - const rawString = getRaw(node).toUpperCase(); - let base = 0; - - if (rawString.startsWith("0B")) { - base = 2; - } else if (rawString.startsWith("0X")) { - base = 16; - } else { - base = 8; - } - - return !rawString.endsWith(node.value.toString(base).toUpperCase()); - } - - /** - * Adds a decimal point to the numeric string at index 1 - * @param {string} stringNumber the numeric string without any decimal point - * @returns {string} the numeric string with a decimal point in the proper place - */ - function addDecimalPointToNumber(stringNumber) { - return `${stringNumber.slice(0, 1)}.${stringNumber.slice(1)}`; - } - - /** - * Returns the number stripped of leading zeros - * @param {string} numberAsString the string representation of the number - * @returns {string} the stripped string - */ - function removeLeadingZeros(numberAsString) { - return numberAsString.replace(/^0*/u, ""); - } - - /** - * Returns the number stripped of trailing zeros - * @param {string} numberAsString the string representation of the number - * @returns {string} the stripped string - */ - function removeTrailingZeros(numberAsString) { - return numberAsString.replace(/0*$/u, ""); - } - - /** - * Converts an integer to to an object containing the integer's coefficient and order of magnitude - * @param {string} stringInteger the string representation of the integer being converted - * @returns {Object} the object containing the integer's coefficient and order of magnitude - */ - function normalizeInteger(stringInteger) { - const significantDigits = removeTrailingZeros(removeLeadingZeros(stringInteger)); - - return { - magnitude: stringInteger.startsWith("0") ? stringInteger.length - 2 : stringInteger.length - 1, - coefficient: addDecimalPointToNumber(significantDigits) - }; - } - - /** - * - * Converts a float to to an object containing the floats's coefficient and order of magnitude - * @param {string} stringFloat the string representation of the float being converted - * @returns {Object} the object containing the integer's coefficient and order of magnitude - */ - function normalizeFloat(stringFloat) { - const trimmedFloat = removeLeadingZeros(stringFloat); - - if (trimmedFloat.startsWith(".")) { - const decimalDigits = trimmedFloat.split(".").pop(); - const significantDigits = removeLeadingZeros(decimalDigits); - - return { - magnitude: significantDigits.length - decimalDigits.length - 1, - coefficient: addDecimalPointToNumber(significantDigits) - }; - - } - return { - magnitude: trimmedFloat.indexOf(".") - 1, - coefficient: addDecimalPointToNumber(trimmedFloat.replace(".", "")) - - }; - } - - - /** - * Converts a base ten number to proper scientific notation - * @param {string} stringNumber the string representation of the base ten number to be converted - * @returns {string} the number converted to scientific notation - */ - function convertNumberToScientificNotation(stringNumber) { - const splitNumber = stringNumber.replace("E", "e").split("e"); - const originalCoefficient = splitNumber[0]; - const normalizedNumber = stringNumber.includes(".") ? normalizeFloat(originalCoefficient) - : normalizeInteger(originalCoefficient); - const normalizedCoefficient = normalizedNumber.coefficient; - const magnitude = splitNumber.length > 1 ? (parseInt(splitNumber[1], 10) + normalizedNumber.magnitude) - : normalizedNumber.magnitude; - - return `${normalizedCoefficient}e${magnitude}`; - - } - - /** - * Checks that the user-intended base ten number equals the actual number after is has been converted to the Number type - * @param {Node} node the node being evaluated - * @returns {boolean} true if they do not match - */ - function baseTenLosesPrecision(node) { - const normalizedRawNumber = convertNumberToScientificNotation(getRaw(node)); - const requestedPrecision = normalizedRawNumber.split("e")[0].replace(".", "").length; - - if (requestedPrecision > 100) { - return true; - } - const storedNumber = node.value.toPrecision(requestedPrecision); - const normalizedStoredNumber = convertNumberToScientificNotation(storedNumber); - - return normalizedRawNumber !== normalizedStoredNumber; - } - - - /** - * Checks that the user-intended number equals the actual number after is has been converted to the Number type - * @param {Node} node the node being evaluated - * @returns {boolean} true if they do not match - */ - function losesPrecision(node) { - return isBaseTen(node) ? baseTenLosesPrecision(node) : notBaseTenLosesPrecision(node); - } - - - return { - Literal(node) { - if (node.value && isNumber(node) && losesPrecision(node)) { - context.report({ - messageId: "noLossOfPrecision", - node - }); - } - } - }; - } -}; - -/** - * @fileoverview Rule to flag statements that use magic numbers (adapted from https://github.com/danielstjules/buddy.js) - * @author Vincent Lemeunier - */ - - - -// Maximum array length by the ECMAScript Specification. -const MAX_ARRAY_LENGTH = 2 ** 32 - 1; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -/** - * Convert the value to bigint if it's a string. Otherwise return the value as-is. - * @param {bigint|number|string} x The value to normalize. - * @returns {bigint|number} The normalized value. - */ -function normalizeIgnoreValue(x) { - if (typeof x === "string") { - return BigInt(x.slice(0, -1)); - } - return x; -} - -var noMagicNumbers = { - meta: { - type: "suggestion", - - docs: { - description: "disallow magic numbers", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-magic-numbers" - }, - - schema: [{ - type: "object", - properties: { - detectObjects: { - type: "boolean", - default: false - }, - enforceConst: { - type: "boolean", - default: false - }, - ignore: { - type: "array", - items: { - anyOf: [ - { type: "number" }, - { type: "string", pattern: "^[+-]?(?:0|[1-9][0-9]*)n$" } - ] - }, - uniqueItems: true - }, - ignoreArrayIndexes: { - type: "boolean", - default: false - }, - ignoreDefaultValues: { - type: "boolean", - default: false - } - }, - additionalProperties: false - }], - - messages: { - useConst: "Number constants declarations must use 'const'.", - noMagic: "No magic number: {{raw}}." - } - }, - - create(context) { - const config = context.options[0] || {}, - detectObjects = !!config.detectObjects, - enforceConst = !!config.enforceConst, - ignore = (config.ignore || []).map(normalizeIgnoreValue), - ignoreArrayIndexes = !!config.ignoreArrayIndexes, - ignoreDefaultValues = !!config.ignoreDefaultValues; - - const okTypes = detectObjects ? [] : ["ObjectExpression", "Property", "AssignmentExpression"]; - - /** - * Returns whether the rule is configured to ignore the given value - * @param {bigint|number} value The value to check - * @returns {boolean} true if the value is ignored - */ - function isIgnoredValue(value) { - return ignore.indexOf(value) !== -1; - } - - /** - * Returns whether the number is a default value assignment. - * @param {ASTNode} fullNumberNode `Literal` or `UnaryExpression` full number node - * @returns {boolean} true if the number is a default value - */ - function isDefaultValue(fullNumberNode) { - const parent = fullNumberNode.parent; - - return parent.type === "AssignmentPattern" && parent.right === fullNumberNode; - } - - /** - * Returns whether the given node is used as a radix within parseInt() or Number.parseInt() - * @param {ASTNode} fullNumberNode `Literal` or `UnaryExpression` full number node - * @returns {boolean} true if the node is radix - */ - function isParseIntRadix(fullNumberNode) { - const parent = fullNumberNode.parent; - - return parent.type === "CallExpression" && fullNumberNode === parent.arguments[1] && - ( - astUtils.isSpecificId(parent.callee, "parseInt") || - astUtils.isSpecificMemberAccess(parent.callee, "Number", "parseInt") - ); - } - - /** - * Returns whether the given node is a direct child of a JSX node. - * In particular, it aims to detect numbers used as prop values in JSX tags. - * Example: - * @param {ASTNode} fullNumberNode `Literal` or `UnaryExpression` full number node - * @returns {boolean} true if the node is a JSX number - */ - function isJSXNumber(fullNumberNode) { - return fullNumberNode.parent.type.indexOf("JSX") === 0; - } - - /** - * Returns whether the given node is used as an array index. - * Value must coerce to a valid array index name: "0", "1", "2" ... "4294967294". - * - * All other values, like "-1", "2.5", or "4294967295", are just "normal" object properties, - * which can be created and accessed on an array in addition to the array index properties, - * but they don't affect array's length and are not considered by methods such as .map(), .forEach() etc. - * - * The maximum array length by the specification is 2 ** 32 - 1 = 4294967295, - * thus the maximum valid index is 2 ** 32 - 2 = 4294967294. - * - * All notations are allowed, as long as the value coerces to one of "0", "1", "2" ... "4294967294". - * - * Valid examples: - * a[0], a[1], a[1.2e1], a[0xAB], a[0n], a[1n] - * a[-0] (same as a[0] because -0 coerces to "0") - * a[-0n] (-0n evaluates to 0n) - * - * Invalid examples: - * a[-1], a[-0xAB], a[-1n], a[2.5], a[1.23e1], a[12e-1] - * a[4294967295] (above the max index, it's an access to a regular property a["4294967295"]) - * a[999999999999999999999] (even if it wasn't above the max index, it would be a["1e+21"]) - * a[1e310] (same as a["Infinity"]) - * @param {ASTNode} fullNumberNode `Literal` or `UnaryExpression` full number node - * @param {bigint|number} value Value expressed by the fullNumberNode - * @returns {boolean} true if the node is a valid array index - */ - function isArrayIndex(fullNumberNode, value) { - const parent = fullNumberNode.parent; - - return parent.type === "MemberExpression" && parent.property === fullNumberNode && - (Number.isInteger(value) || typeof value === "bigint") && - value >= 0 && value < MAX_ARRAY_LENGTH; - } - - return { - Literal(node) { - if (!astUtils.isNumericLiteral(node)) { - return; - } - - let fullNumberNode; - let value; - let raw; - - // Treat unary minus as a part of the number - if (node.parent.type === "UnaryExpression" && node.parent.operator === "-") { - fullNumberNode = node.parent; - value = -node.value; - raw = `-${node.raw}`; - } else { - fullNumberNode = node; - value = node.value; - raw = node.raw; - } - - const parent = fullNumberNode.parent; - - // Always allow radix arguments and JSX props - if ( - isIgnoredValue(value) || - (ignoreDefaultValues && isDefaultValue(fullNumberNode)) || - isParseIntRadix(fullNumberNode) || - isJSXNumber(fullNumberNode) || - (ignoreArrayIndexes && isArrayIndex(fullNumberNode, value)) - ) { - return; - } - - if (parent.type === "VariableDeclarator") { - if (enforceConst && parent.parent.kind !== "const") { - context.report({ - node: fullNumberNode, - messageId: "useConst" - }); - } - } else if ( - okTypes.indexOf(parent.type) === -1 || - (parent.type === "AssignmentExpression" && parent.left.type === "Identifier") - ) { - context.report({ - node: fullNumberNode, - messageId: "noMagic", - data: { - raw - } - }); - } - } - }; - } -}; - -/** - * @author Toru Nagashima - */ - -/** - * Check whether a given character is a combining mark or not. - * @param {number} codePoint The character code to check. - * @returns {boolean} `true` if the character belongs to the category, any of `Mc`, `Me`, and `Mn`. - */ -var isCombiningCharacter$1 = function isCombiningCharacter(codePoint) { - return /^[\p{Mc}\p{Me}\p{Mn}]$/u.test(String.fromCodePoint(codePoint)); -}; - -/** - * @author Toru Nagashima - */ - -/** - * Check whether a given character is an emoji modifier. - * @param {number} code The character code to check. - * @returns {boolean} `true` if the character is an emoji modifier. - */ -var isEmojiModifier$1 = function isEmojiModifier(code) { - return code >= 0x1F3FB && code <= 0x1F3FF; -}; - -/** - * @author Toru Nagashima - */ - -/** - * Check whether a given character is a regional indicator symbol. - * @param {number} code The character code to check. - * @returns {boolean} `true` if the character is a regional indicator symbol. - */ -var isRegionalIndicatorSymbol$1 = function isRegionalIndicatorSymbol(code) { - return code >= 0x1F1E6 && code <= 0x1F1FF; -}; - -/** - * @author Toru Nagashima - */ - -/** - * Check whether given two characters are a surrogate pair. - * @param {number} lead The code of the lead character. - * @param {number} tail The code of the tail character. - * @returns {boolean} `true` if the character pair is a surrogate pair. - */ -var isSurrogatePair$1 = function isSurrogatePair(lead, tail) { - return lead >= 0xD800 && lead < 0xDC00 && tail >= 0xDC00 && tail < 0xE000; -}; - -/** - * @author Toru Nagashima - */ - -var unicode = { - isCombiningCharacter: isCombiningCharacter$1, - isEmojiModifier: isEmojiModifier$1, - isRegionalIndicatorSymbol: isRegionalIndicatorSymbol$1, - isSurrogatePair: isSurrogatePair$1 -}; - -/** - * @author Toru Nagashima - */ - -const { CALL: CALL$7, CONSTRUCT: CONSTRUCT$5, ReferenceTracker: ReferenceTracker$7, getStringIfConstant: getStringIfConstant$3 } = require$$0__default$1['default']; -const { RegExpParser: RegExpParser$1, visitRegExpAST: visitRegExpAST$1 } = regexpp__default['default']; -const { isCombiningCharacter, isEmojiModifier, isRegionalIndicatorSymbol, isSurrogatePair } = unicode; - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Iterate character sequences of a given nodes. - * - * CharacterClassRange syntax can steal a part of character sequence, - * so this function reverts CharacterClassRange syntax and restore the sequence. - * @param {regexpp.AST.CharacterClassElement[]} nodes The node list to iterate character sequences. - * @returns {IterableIterator} The list of character sequences. - */ -function *iterateCharacterSequence(nodes) { - let seq = []; - - for (const node of nodes) { - switch (node.type) { - case "Character": - seq.push(node.value); - break; - - case "CharacterClassRange": - seq.push(node.min.value); - yield seq; - seq = [node.max.value]; - break; - - case "CharacterSet": - if (seq.length > 0) { - yield seq; - seq = []; - } - break; - - // no default - } - } - - if (seq.length > 0) { - yield seq; - } -} - -const hasCharacterSequence = { - surrogatePairWithoutUFlag(chars) { - return chars.some((c, i) => i !== 0 && isSurrogatePair(chars[i - 1], c)); - }, - - combiningClass(chars) { - return chars.some((c, i) => ( - i !== 0 && - isCombiningCharacter(c) && - !isCombiningCharacter(chars[i - 1]) - )); - }, - - emojiModifier(chars) { - return chars.some((c, i) => ( - i !== 0 && - isEmojiModifier(c) && - !isEmojiModifier(chars[i - 1]) - )); - }, - - regionalIndicatorSymbol(chars) { - return chars.some((c, i) => ( - i !== 0 && - isRegionalIndicatorSymbol(c) && - isRegionalIndicatorSymbol(chars[i - 1]) - )); - }, - - zwj(chars) { - const lastIndex = chars.length - 1; - - return chars.some((c, i) => ( - i !== 0 && - i !== lastIndex && - c === 0x200d && - chars[i - 1] !== 0x200d && - chars[i + 1] !== 0x200d - )); - } -}; - -const kinds = Object.keys(hasCharacterSequence); - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noMisleadingCharacterClass = { - meta: { - type: "problem", - - docs: { - description: "disallow characters which are made with multiple code points in character class syntax", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-misleading-character-class" - }, - - schema: [], - - messages: { - surrogatePairWithoutUFlag: "Unexpected surrogate pair in character class. Use 'u' flag.", - combiningClass: "Unexpected combined character in character class.", - emojiModifier: "Unexpected modified Emoji in character class.", - regionalIndicatorSymbol: "Unexpected national flag in character class.", - zwj: "Unexpected joined character sequence in character class." - } - }, - create(context) { - const parser = new RegExpParser$1(); - - /** - * Verify a given regular expression. - * @param {Node} node The node to report. - * @param {string} pattern The regular expression pattern to verify. - * @param {string} flags The flags of the regular expression. - * @returns {void} - */ - function verify(node, pattern, flags) { - const has = { - surrogatePairWithoutUFlag: false, - combiningClass: false, - variationSelector: false, - emojiModifier: false, - regionalIndicatorSymbol: false, - zwj: false - }; - let patternNode; - - try { - patternNode = parser.parsePattern( - pattern, - 0, - pattern.length, - flags.includes("u") - ); - } catch { - - // Ignore regular expressions with syntax errors - return; - } - - visitRegExpAST$1(patternNode, { - onCharacterClassEnter(ccNode) { - for (const chars of iterateCharacterSequence(ccNode.elements)) { - for (const kind of kinds) { - has[kind] = has[kind] || hasCharacterSequence[kind](chars); - } - } - } - }); - - for (const kind of kinds) { - if (has[kind]) { - context.report({ node, messageId: kind }); - } - } - } - - return { - "Literal[regex]"(node) { - verify(node, node.regex.pattern, node.regex.flags); - }, - "Program"() { - const scope = context.getScope(); - const tracker = new ReferenceTracker$7(scope); - - /* - * Iterate calls of RegExp. - * E.g., `new RegExp()`, `RegExp()`, `new window.RegExp()`, - * `const {RegExp: a} = window; new a()`, etc... - */ - for (const { node } of tracker.iterateGlobalReferences({ - RegExp: { [CALL$7]: true, [CONSTRUCT$5]: true } - })) { - const [patternNode, flagsNode] = node.arguments; - const pattern = getStringIfConstant$3(patternNode, scope); - const flags = getStringIfConstant$3(flagsNode, scope); - - if (typeof pattern === "string") { - verify(node, pattern, flags || ""); - } - } - } - }; - } -}; - -/** - * @fileoverview Rule to disallow mixed binary operators. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const ARITHMETIC_OPERATORS = ["+", "-", "*", "/", "%", "**"]; -const BITWISE_OPERATORS = ["&", "|", "^", "~", "<<", ">>", ">>>"]; -const COMPARISON_OPERATORS = ["==", "!=", "===", "!==", ">", ">=", "<", "<="]; -const LOGICAL_OPERATORS = ["&&", "||"]; -const RELATIONAL_OPERATORS = ["in", "instanceof"]; -const TERNARY_OPERATOR = ["?:"]; -const COALESCE_OPERATOR = ["??"]; -const ALL_OPERATORS = [].concat( - ARITHMETIC_OPERATORS, - BITWISE_OPERATORS, - COMPARISON_OPERATORS, - LOGICAL_OPERATORS, - RELATIONAL_OPERATORS, - TERNARY_OPERATOR, - COALESCE_OPERATOR -); -const DEFAULT_GROUPS = [ - ARITHMETIC_OPERATORS, - BITWISE_OPERATORS, - COMPARISON_OPERATORS, - LOGICAL_OPERATORS, - RELATIONAL_OPERATORS -]; -const TARGET_NODE_TYPE = /^(?:Binary|Logical|Conditional)Expression$/u; - -/** - * Normalizes options. - * @param {Object|undefined} options A options object to normalize. - * @returns {Object} Normalized option object. - */ -function normalizeOptions$1(options = {}) { - const hasGroups = options.groups && options.groups.length > 0; - const groups = hasGroups ? options.groups : DEFAULT_GROUPS; - const allowSamePrecedence = options.allowSamePrecedence !== false; - - return { - groups, - allowSamePrecedence - }; -} - -/** - * Checks whether any group which includes both given operator exists or not. - * @param {Array.} groups A list of groups to check. - * @param {string} left An operator. - * @param {string} right Another operator. - * @returns {boolean} `true` if such group existed. - */ -function includesBothInAGroup(groups, left, right) { - return groups.some(group => group.indexOf(left) !== -1 && group.indexOf(right) !== -1); -} - -/** - * Checks whether the given node is a conditional expression and returns the test node else the left node. - * @param {ASTNode} node A node which can be a BinaryExpression or a LogicalExpression node. - * This parent node can be BinaryExpression, LogicalExpression - * , or a ConditionalExpression node - * @returns {ASTNode} node the appropriate node(left or test). - */ -function getChildNode(node) { - return node.type === "ConditionalExpression" ? node.test : node.left; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noMixedOperators = { - meta: { - type: "suggestion", - - docs: { - description: "disallow mixed binary operators", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/no-mixed-operators" - }, - - schema: [ - { - type: "object", - properties: { - groups: { - type: "array", - items: { - type: "array", - items: { enum: ALL_OPERATORS }, - minItems: 2, - uniqueItems: true - }, - uniqueItems: true - }, - allowSamePrecedence: { - type: "boolean", - default: true - } - }, - additionalProperties: false - } - ], - - messages: { - unexpectedMixedOperator: "Unexpected mix of '{{leftOperator}}' and '{{rightOperator}}'." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const options = normalizeOptions$1(context.options[0]); - - /** - * Checks whether a given node should be ignored by options or not. - * @param {ASTNode} node A node to check. This is a BinaryExpression - * node or a LogicalExpression node. This parent node is one of - * them, too. - * @returns {boolean} `true` if the node should be ignored. - */ - function shouldIgnore(node) { - const a = node; - const b = node.parent; - - return ( - !includesBothInAGroup(options.groups, a.operator, b.type === "ConditionalExpression" ? "?:" : b.operator) || - ( - options.allowSamePrecedence && - astUtils.getPrecedence(a) === astUtils.getPrecedence(b) - ) - ); - } - - /** - * Checks whether the operator of a given node is mixed with parent - * node's operator or not. - * @param {ASTNode} node A node to check. This is a BinaryExpression - * node or a LogicalExpression node. This parent node is one of - * them, too. - * @returns {boolean} `true` if the node was mixed. - */ - function isMixedWithParent(node) { - - return ( - node.operator !== node.parent.operator && - !astUtils.isParenthesised(sourceCode, node) - ); - } - - /** - * Gets the operator token of a given node. - * @param {ASTNode} node A node to check. This is a BinaryExpression - * node or a LogicalExpression node. - * @returns {Token} The operator token of the node. - */ - function getOperatorToken(node) { - return sourceCode.getTokenAfter(getChildNode(node), astUtils.isNotClosingParenToken); - } - - /** - * Reports both the operator of a given node and the operator of the - * parent node. - * @param {ASTNode} node A node to check. This is a BinaryExpression - * node or a LogicalExpression node. This parent node is one of - * them, too. - * @returns {void} - */ - function reportBothOperators(node) { - const parent = node.parent; - const left = (getChildNode(parent) === node) ? node : parent; - const right = (getChildNode(parent) !== node) ? node : parent; - const data = { - leftOperator: left.operator || "?:", - rightOperator: right.operator || "?:" - }; - - context.report({ - node: left, - loc: getOperatorToken(left).loc, - messageId: "unexpectedMixedOperator", - data - }); - context.report({ - node: right, - loc: getOperatorToken(right).loc, - messageId: "unexpectedMixedOperator", - data - }); - } - - /** - * Checks between the operator of this node and the operator of the - * parent node. - * @param {ASTNode} node A node to check. - * @returns {void} - */ - function check(node) { - if ( - TARGET_NODE_TYPE.test(node.parent.type) && - isMixedWithParent(node) && - !shouldIgnore(node) - ) { - reportBothOperators(node); - } - } - - return { - BinaryExpression: check, - LogicalExpression: check - }; - } -}; - -/** - * @fileoverview Rule to enforce grouped require statements for Node.JS - * @author Raphael Pigulla - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noMixedRequires = { - meta: { - deprecated: true, - - replacedBy: [], - - type: "suggestion", - - docs: { - description: "disallow `require` calls to be mixed with regular variable declarations", - category: "Node.js and CommonJS", - recommended: false, - url: "https://eslint.org/docs/rules/no-mixed-requires" - }, - - schema: [ - { - oneOf: [ - { - type: "boolean" - }, - { - type: "object", - properties: { - grouping: { - type: "boolean" - }, - allowCall: { - type: "boolean" - } - }, - additionalProperties: false - } - ] - } - ], - - messages: { - noMixRequire: "Do not mix 'require' and other declarations.", - noMixCoreModuleFileComputed: "Do not mix core, module, file and computed requires." - } - }, - - create(context) { - - const options = context.options[0]; - let grouping = false, - allowCall = false; - - if (typeof options === "object") { - grouping = options.grouping; - allowCall = options.allowCall; - } else { - grouping = !!options; - } - - /** - * Returns the list of built-in modules. - * @returns {string[]} An array of built-in Node.js modules. - */ - function getBuiltinModules() { - - /* - * This list is generated using: - * `require("repl")._builtinLibs.concat('repl').sort()` - * This particular list is as per nodejs v0.12.2 and iojs v0.7.1 - */ - return [ - "assert", "buffer", "child_process", "cluster", "crypto", - "dgram", "dns", "domain", "events", "fs", "http", "https", - "net", "os", "path", "punycode", "querystring", "readline", - "repl", "smalloc", "stream", "string_decoder", "tls", "tty", - "url", "util", "v8", "vm", "zlib" - ]; - } - - const BUILTIN_MODULES = getBuiltinModules(); - - const DECL_REQUIRE = "require", - DECL_UNINITIALIZED = "uninitialized", - DECL_OTHER = "other"; - - const REQ_CORE = "core", - REQ_FILE = "file", - REQ_MODULE = "module", - REQ_COMPUTED = "computed"; - - /** - * Determines the type of a declaration statement. - * @param {ASTNode} initExpression The init node of the VariableDeclarator. - * @returns {string} The type of declaration represented by the expression. - */ - function getDeclarationType(initExpression) { - if (!initExpression) { - - // "var x;" - return DECL_UNINITIALIZED; - } - - if (initExpression.type === "CallExpression" && - initExpression.callee.type === "Identifier" && - initExpression.callee.name === "require" - ) { - - // "var x = require('util');" - return DECL_REQUIRE; - } - if (allowCall && - initExpression.type === "CallExpression" && - initExpression.callee.type === "CallExpression" - ) { - - // "var x = require('diagnose')('sub-module');" - return getDeclarationType(initExpression.callee); - } - if (initExpression.type === "MemberExpression") { - - // "var x = require('glob').Glob;" - return getDeclarationType(initExpression.object); - } - - // "var x = 42;" - return DECL_OTHER; - } - - /** - * Determines the type of module that is loaded via require. - * @param {ASTNode} initExpression The init node of the VariableDeclarator. - * @returns {string} The module type. - */ - function inferModuleType(initExpression) { - if (initExpression.type === "MemberExpression") { - - // "var x = require('glob').Glob;" - return inferModuleType(initExpression.object); - } - if (initExpression.arguments.length === 0) { - - // "var x = require();" - return REQ_COMPUTED; - } - - const arg = initExpression.arguments[0]; - - if (arg.type !== "Literal" || typeof arg.value !== "string") { - - // "var x = require(42);" - return REQ_COMPUTED; - } - - if (BUILTIN_MODULES.indexOf(arg.value) !== -1) { - - // "var fs = require('fs');" - return REQ_CORE; - } - if (/^\.{0,2}\//u.test(arg.value)) { - - // "var utils = require('./utils');" - return REQ_FILE; - } - - // "var async = require('async');" - return REQ_MODULE; - - } - - /** - * Check if the list of variable declarations is mixed, i.e. whether it - * contains both require and other declarations. - * @param {ASTNode} declarations The list of VariableDeclarators. - * @returns {boolean} True if the declarations are mixed, false if not. - */ - function isMixed(declarations) { - const contains = {}; - - declarations.forEach(declaration => { - const type = getDeclarationType(declaration.init); - - contains[type] = true; - }); - - return !!( - contains[DECL_REQUIRE] && - (contains[DECL_UNINITIALIZED] || contains[DECL_OTHER]) - ); - } - - /** - * Check if all require declarations in the given list are of the same - * type. - * @param {ASTNode} declarations The list of VariableDeclarators. - * @returns {boolean} True if the declarations are grouped, false if not. - */ - function isGrouped(declarations) { - const found = {}; - - declarations.forEach(declaration => { - if (getDeclarationType(declaration.init) === DECL_REQUIRE) { - found[inferModuleType(declaration.init)] = true; - } - }); - - return Object.keys(found).length <= 1; - } - - - return { - - VariableDeclaration(node) { - - if (isMixed(node.declarations)) { - context.report({ - node, - messageId: "noMixRequire" - }); - } else if (grouping && !isGrouped(node.declarations)) { - context.report({ - node, - messageId: "noMixCoreModuleFileComputed" - }); - } - } - }; - - } -}; - -/** - * @fileoverview Disallow mixed spaces and tabs for indentation - * @author Jary Niebur - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noMixedSpacesAndTabs = { - meta: { - type: "layout", - - docs: { - description: "disallow mixed spaces and tabs for indentation", - category: "Stylistic Issues", - recommended: true, - url: "https://eslint.org/docs/rules/no-mixed-spaces-and-tabs" - }, - - schema: [ - { - enum: ["smart-tabs", true, false] - } - ], - - messages: { - mixedSpacesAndTabs: "Mixed spaces and tabs." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - let smartTabs; - - switch (context.options[0]) { - case true: // Support old syntax, maybe add deprecation warning here - case "smart-tabs": - smartTabs = true; - break; - default: - smartTabs = false; - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - - "Program:exit"(node) { - const lines = sourceCode.lines, - comments = sourceCode.getAllComments(), - ignoredCommentLines = new Set(); - - // Add all lines except the first ones. - comments.forEach(comment => { - for (let i = comment.loc.start.line + 1; i <= comment.loc.end.line; i++) { - ignoredCommentLines.add(i); - } - }); - - /* - * At least one space followed by a tab - * or the reverse before non-tab/-space - * characters begin. - */ - let regex = /^(?=( +|\t+))\1(?:\t| )/u; - - if (smartTabs) { - - /* - * At least one space followed by a tab - * before non-tab/-space characters begin. - */ - regex = /^(?=(\t*))\1(?=( +))\2\t/u; - } - - lines.forEach((line, i) => { - const match = regex.exec(line); - - if (match) { - const lineNumber = i + 1; - const loc = { - start: { - line: lineNumber, - column: match[0].length - 2 - }, - end: { - line: lineNumber, - column: match[0].length - } - }; - - if (!ignoredCommentLines.has(lineNumber)) { - const containingNode = sourceCode.getNodeByRangeIndex(sourceCode.getIndexFromLoc(loc.start)); - - if (!(containingNode && ["Literal", "TemplateElement"].includes(containingNode.type))) { - context.report({ - node, - loc, - messageId: "mixedSpacesAndTabs" - }); - } - } - } - }); - } - }; - } -}; - -/** - * @fileoverview Rule to check use of chained assignment expressions - * @author Stewart Rand - */ - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noMultiAssign = { - meta: { - type: "suggestion", - - docs: { - description: "disallow use of chained assignment expressions", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/no-multi-assign" - }, - - schema: [{ - type: "object", - properties: { - ignoreNonDeclaration: { - type: "boolean", - default: false - } - }, - additionalProperties: false - }], - - messages: { - unexpectedChain: "Unexpected chained assignment." - } - }, - - create(context) { - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - const options = context.options[0] || { - ignoreNonDeclaration: false - }; - const targetParent = options.ignoreNonDeclaration ? ["VariableDeclarator"] : ["AssignmentExpression", "VariableDeclarator"]; - - return { - AssignmentExpression(node) { - if (targetParent.indexOf(node.parent.type) !== -1) { - context.report({ - node, - messageId: "unexpectedChain" - }); - } - } - }; - - } -}; - -/** - * @fileoverview Disallow use of multiple spaces. - * @author Nicholas C. Zakas - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noMultiSpaces = { - meta: { - type: "layout", - - docs: { - description: "disallow multiple spaces", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-multi-spaces" - }, - - fixable: "whitespace", - - schema: [ - { - type: "object", - properties: { - exceptions: { - type: "object", - patternProperties: { - "^([A-Z][a-z]*)+$": { - type: "boolean" - } - }, - additionalProperties: false - }, - ignoreEOLComments: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - messages: { - multipleSpaces: "Multiple spaces found before '{{displayValue}}'." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const options = context.options[0] || {}; - const ignoreEOLComments = options.ignoreEOLComments; - const exceptions = Object.assign({ Property: true }, options.exceptions); - const hasExceptions = Object.keys(exceptions).filter(key => exceptions[key]).length > 0; - - /** - * Formats value of given comment token for error message by truncating its length. - * @param {Token} token comment token - * @returns {string} formatted value - * @private - */ - function formatReportedCommentValue(token) { - const valueLines = token.value.split("\n"); - const value = valueLines[0]; - const formattedValue = `${value.slice(0, 12)}...`; - - return valueLines.length === 1 && value.length <= 12 ? value : formattedValue; - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - Program() { - sourceCode.tokensAndComments.forEach((leftToken, leftIndex, tokensAndComments) => { - if (leftIndex === tokensAndComments.length - 1) { - return; - } - const rightToken = tokensAndComments[leftIndex + 1]; - - // Ignore tokens that don't have 2 spaces between them or are on different lines - if ( - !sourceCode.text.slice(leftToken.range[1], rightToken.range[0]).includes(" ") || - leftToken.loc.end.line < rightToken.loc.start.line - ) { - return; - } - - // Ignore comments that are the last token on their line if `ignoreEOLComments` is active. - if ( - ignoreEOLComments && - astUtils.isCommentToken(rightToken) && - ( - leftIndex === tokensAndComments.length - 2 || - rightToken.loc.end.line < tokensAndComments[leftIndex + 2].loc.start.line - ) - ) { - return; - } - - // Ignore tokens that are in a node in the "exceptions" object - if (hasExceptions) { - const parentNode = sourceCode.getNodeByRangeIndex(rightToken.range[0] - 1); - - if (parentNode && exceptions[parentNode.type]) { - return; - } - } - - let displayValue; - - if (rightToken.type === "Block") { - displayValue = `/*${formatReportedCommentValue(rightToken)}*/`; - } else if (rightToken.type === "Line") { - displayValue = `//${formatReportedCommentValue(rightToken)}`; - } else { - displayValue = rightToken.value; - } - - context.report({ - node: rightToken, - loc: { start: leftToken.loc.end, end: rightToken.loc.start }, - messageId: "multipleSpaces", - data: { displayValue }, - fix: fixer => fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], " ") - }); - }); - } - }; - - } -}; - -/** - * @fileoverview Rule to flag when using multiline strings - * @author Ilya Volodin - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noMultiStr = { - meta: { - type: "suggestion", - - docs: { - description: "disallow multiline strings", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-multi-str" - }, - - schema: [], - - messages: { - multilineString: "Multiline support is limited to browsers supporting ES5 only." - } - }, - - create(context) { - - /** - * Determines if a given node is part of JSX syntax. - * @param {ASTNode} node The node to check. - * @returns {boolean} True if the node is a JSX node, false if not. - * @private - */ - function isJSXElement(node) { - return node.type.indexOf("JSX") === 0; - } - - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- - - return { - - Literal(node) { - if (astUtils.LINEBREAK_MATCHER.test(node.raw) && !isJSXElement(node.parent)) { - context.report({ - node, - messageId: "multilineString" - }); - } - } - }; - - } -}; - -/** - * @fileoverview Disallows multiple blank lines. - * implementation adapted from the no-trailing-spaces rule. - * @author Greg Cochard - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noMultipleEmptyLines = { - meta: { - type: "layout", - - docs: { - description: "disallow multiple empty lines", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/no-multiple-empty-lines" - }, - - fixable: "whitespace", - - schema: [ - { - type: "object", - properties: { - max: { - type: "integer", - minimum: 0 - }, - maxEOF: { - type: "integer", - minimum: 0 - }, - maxBOF: { - type: "integer", - minimum: 0 - } - }, - required: ["max"], - additionalProperties: false - } - ], - - messages: { - blankBeginningOfFile: "Too many blank lines at the beginning of file. Max of {{max}} allowed.", - blankEndOfFile: "Too many blank lines at the end of file. Max of {{max}} allowed.", - consecutiveBlank: "More than {{max}} blank {{pluralizedLines}} not allowed." - } - }, - - create(context) { - - // Use options.max or 2 as default - let max = 2, - maxEOF = max, - maxBOF = max; - - if (context.options.length) { - max = context.options[0].max; - maxEOF = typeof context.options[0].maxEOF !== "undefined" ? context.options[0].maxEOF : max; - maxBOF = typeof context.options[0].maxBOF !== "undefined" ? context.options[0].maxBOF : max; - } - - const sourceCode = context.getSourceCode(); - - // Swallow the final newline, as some editors add it automatically and we don't want it to cause an issue - const allLines = sourceCode.lines[sourceCode.lines.length - 1] === "" ? sourceCode.lines.slice(0, -1) : sourceCode.lines; - const templateLiteralLines = new Set(); - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - TemplateLiteral(node) { - node.quasis.forEach(literalPart => { - - // Empty lines have a semantic meaning if they're inside template literals. Don't count these as empty lines. - for (let ignoredLine = literalPart.loc.start.line; ignoredLine < literalPart.loc.end.line; ignoredLine++) { - templateLiteralLines.add(ignoredLine); - } - }); - }, - "Program:exit"(node) { - return allLines - - // Given a list of lines, first get a list of line numbers that are non-empty. - .reduce((nonEmptyLineNumbers, line, index) => { - if (line.trim() || templateLiteralLines.has(index + 1)) { - nonEmptyLineNumbers.push(index + 1); - } - return nonEmptyLineNumbers; - }, []) - - // Add a value at the end to allow trailing empty lines to be checked. - .concat(allLines.length + 1) - - // Given two line numbers of non-empty lines, report the lines between if the difference is too large. - .reduce((lastLineNumber, lineNumber) => { - let messageId, maxAllowed; - - if (lastLineNumber === 0) { - messageId = "blankBeginningOfFile"; - maxAllowed = maxBOF; - } else if (lineNumber === allLines.length + 1) { - messageId = "blankEndOfFile"; - maxAllowed = maxEOF; - } else { - messageId = "consecutiveBlank"; - maxAllowed = max; - } - - if (lineNumber - lastLineNumber - 1 > maxAllowed) { - context.report({ - node, - loc: { - start: { line: lastLineNumber + maxAllowed + 1, column: 0 }, - end: { line: lineNumber, column: 0 } - }, - messageId, - data: { - max: maxAllowed, - pluralizedLines: maxAllowed === 1 ? "line" : "lines" - }, - fix(fixer) { - const rangeStart = sourceCode.getIndexFromLoc({ line: lastLineNumber + 1, column: 0 }); - - /* - * The end of the removal range is usually the start index of the next line. - * However, at the end of the file there is no next line, so the end of the - * range is just the length of the text. - */ - const lineNumberAfterRemovedLines = lineNumber - maxAllowed; - const rangeEnd = lineNumberAfterRemovedLines <= allLines.length - ? sourceCode.getIndexFromLoc({ line: lineNumberAfterRemovedLines, column: 0 }) - : sourceCode.text.length; - - return fixer.removeRange([rangeStart, rangeEnd]); - } - }); - } - - return lineNumber; - }, 0); - } - }; - } -}; - -/** - * @fileoverview Rule to disallow assignments to native objects or read-only global variables - * @author Ilya Volodin - * @deprecated in ESLint v3.3.0 - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noNativeReassign = { - meta: { - type: "suggestion", - - docs: { - description: "disallow assignments to native objects or read-only global variables", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-native-reassign" - }, - - deprecated: true, - - replacedBy: ["no-global-assign"], - - schema: [ - { - type: "object", - properties: { - exceptions: { - type: "array", - items: { type: "string" }, - uniqueItems: true - } - }, - additionalProperties: false - } - ], - - messages: { - nativeReassign: "Read-only global '{{name}}' should not be modified." - } - }, - - create(context) { - const config = context.options[0]; - const exceptions = (config && config.exceptions) || []; - - /** - * Reports write references. - * @param {Reference} reference A reference to check. - * @param {int} index The index of the reference in the references. - * @param {Reference[]} references The array that the reference belongs to. - * @returns {void} - */ - function checkReference(reference, index, references) { - const identifier = reference.identifier; - - if (reference.init === false && - reference.isWrite() && - - /* - * Destructuring assignments can have multiple default value, - * so possibly there are multiple writeable references for the same identifier. - */ - (index === 0 || references[index - 1].identifier !== identifier) - ) { - context.report({ - node: identifier, - messageId: "nativeReassign", - data: identifier - }); - } - } - - /** - * Reports write references if a given variable is read-only builtin. - * @param {Variable} variable A variable to check. - * @returns {void} - */ - function checkVariable(variable) { - if (variable.writeable === false && exceptions.indexOf(variable.name) === -1) { - variable.references.forEach(checkReference); - } - } - - return { - Program() { - const globalScope = context.getScope(); - - globalScope.variables.forEach(checkVariable); - } - }; - } -}; - -/** - * @fileoverview Rule to disallow a negated condition - * @author Alberto Rodríguez - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noNegatedCondition = { - meta: { - type: "suggestion", - - docs: { - description: "disallow negated conditions", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/no-negated-condition" - }, - - schema: [], - - messages: { - unexpectedNegated: "Unexpected negated condition." - } - }, - - create(context) { - - /** - * Determines if a given node is an if-else without a condition on the else - * @param {ASTNode} node The node to check. - * @returns {boolean} True if the node has an else without an if. - * @private - */ - function hasElseWithoutCondition(node) { - return node.alternate && node.alternate.type !== "IfStatement"; - } - - /** - * Determines if a given node is a negated unary expression - * @param {Object} test The test object to check. - * @returns {boolean} True if the node is a negated unary expression. - * @private - */ - function isNegatedUnaryExpression(test) { - return test.type === "UnaryExpression" && test.operator === "!"; - } - - /** - * Determines if a given node is a negated binary expression - * @param {Test} test The test to check. - * @returns {boolean} True if the node is a negated binary expression. - * @private - */ - function isNegatedBinaryExpression(test) { - return test.type === "BinaryExpression" && - (test.operator === "!=" || test.operator === "!=="); - } - - /** - * Determines if a given node has a negated if expression - * @param {ASTNode} node The node to check. - * @returns {boolean} True if the node has a negated if expression. - * @private - */ - function isNegatedIf(node) { - return isNegatedUnaryExpression(node.test) || isNegatedBinaryExpression(node.test); - } - - return { - IfStatement(node) { - if (!hasElseWithoutCondition(node)) { - return; - } - - if (isNegatedIf(node)) { - context.report({ - node, - messageId: "unexpectedNegated" - }); - } - }, - ConditionalExpression(node) { - if (isNegatedIf(node)) { - context.report({ - node, - messageId: "unexpectedNegated" - }); - } - } - }; - } -}; - -/** - * @fileoverview A rule to disallow negated left operands of the `in` operator - * @author Michael Ficarra - * @deprecated in ESLint v3.3.0 - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noNegatedInLhs = { - meta: { - type: "problem", - - docs: { - description: "disallow negating the left operand in `in` expressions", - category: "Possible Errors", - recommended: false, - url: "https://eslint.org/docs/rules/no-negated-in-lhs" - }, - - replacedBy: ["no-unsafe-negation"], - - deprecated: true, - schema: [], - - messages: { - negatedLHS: "The 'in' expression's left operand is negated." - } - }, - - create(context) { - - return { - - BinaryExpression(node) { - if (node.operator === "in" && node.left.type === "UnaryExpression" && node.left.operator === "!") { - context.report({ node, messageId: "negatedLHS" }); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag nested ternary expressions - * @author Ian Christian Myers - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noNestedTernary = { - meta: { - type: "suggestion", - - docs: { - description: "disallow nested ternary expressions", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/no-nested-ternary" - }, - - schema: [], - - messages: { - noNestedTernary: "Do not nest ternary expressions." - } - }, - - create(context) { - - return { - ConditionalExpression(node) { - if (node.alternate.type === "ConditionalExpression" || - node.consequent.type === "ConditionalExpression") { - context.report({ - node, - messageId: "noNestedTernary" - }); - } - } - }; - } -}; - -/** - * @fileoverview Rule to flag statements with function invocation preceded by - * "new" and not part of assignment - * @author Ilya Volodin - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noNew = { - meta: { - type: "suggestion", - - docs: { - description: "disallow `new` operators outside of assignments or comparisons", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-new" - }, - - schema: [], - - messages: { - noNewStatement: "Do not use 'new' for side effects." - } - }, - - create(context) { - - return { - "ExpressionStatement > NewExpression"(node) { - context.report({ - node: node.parent, - messageId: "noNewStatement" - }); - } - }; - - } -}; - -/** - * @fileoverview Rule to flag when using new Function - * @author Ilya Volodin - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noNewFunc = { - meta: { - type: "suggestion", - - docs: { - description: "disallow `new` operators with the `Function` object", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-new-func" - }, - - schema: [], - - messages: { - noFunctionConstructor: "The Function constructor is eval." - } - }, - - create(context) { - - return { - "Program:exit"() { - const globalScope = context.getScope(); - const variable = globalScope.set.get("Function"); - - if (variable && variable.defs.length === 0) { - variable.references.forEach(ref => { - const node = ref.identifier; - const { parent } = node; - - if ( - parent && - (parent.type === "NewExpression" || parent.type === "CallExpression") && - node === parent.callee - ) { - context.report({ - node: parent, - messageId: "noFunctionConstructor" - }); - } - }); - } - } - }; - - } -}; - -/** - * @fileoverview A rule to disallow calls to the Object constructor - * @author Matt DuVall - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noNewObject = { - meta: { - type: "suggestion", - - docs: { - description: "disallow `Object` constructors", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/no-new-object" - }, - - schema: [], - - messages: { - preferLiteral: "The object literal notation {} is preferrable." - } - }, - - create(context) { - return { - NewExpression(node) { - const variable = astUtils.getVariableByName( - context.getScope(), - node.callee.name - ); - - if (variable && variable.identifiers.length > 0) { - return; - } - - if (node.callee.name === "Object") { - context.report({ - node, - messageId: "preferLiteral" - }); - } - } - }; - } -}; - -/** - * @fileoverview Rule to disallow use of new operator with the `require` function - * @author Wil Moore III - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noNewRequire = { - meta: { - deprecated: true, - - replacedBy: [], - - type: "suggestion", - - docs: { - description: "disallow `new` operators with calls to `require`", - category: "Node.js and CommonJS", - recommended: false, - url: "https://eslint.org/docs/rules/no-new-require" - }, - - schema: [], - - messages: { - noNewRequire: "Unexpected use of new with require." - } - }, - - create(context) { - - return { - - NewExpression(node) { - if (node.callee.type === "Identifier" && node.callee.name === "require") { - context.report({ - node, - messageId: "noNewRequire" - }); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to disallow use of the new operator with the `Symbol` object - * @author Alberto Rodríguez - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noNewSymbol = { - meta: { - type: "problem", - - docs: { - description: "disallow `new` operators with the `Symbol` object", - category: "ECMAScript 6", - recommended: true, - url: "https://eslint.org/docs/rules/no-new-symbol" - }, - - schema: [], - - messages: { - noNewSymbol: "`Symbol` cannot be called as a constructor." - } - }, - - create(context) { - - return { - "Program:exit"() { - const globalScope = context.getScope(); - const variable = globalScope.set.get("Symbol"); - - if (variable && variable.defs.length === 0) { - variable.references.forEach(ref => { - const node = ref.identifier; - const parent = node.parent; - - if (parent && parent.type === "NewExpression" && parent.callee === node) { - context.report({ - node, - messageId: "noNewSymbol" - }); - } - }); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag when using constructor for wrapper objects - * @author Ilya Volodin - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noNewWrappers = { - meta: { - type: "suggestion", - - docs: { - description: "disallow `new` operators with the `String`, `Number`, and `Boolean` objects", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-new-wrappers" - }, - - schema: [], - - messages: { - noConstructor: "Do not use {{fn}} as a constructor." - } - }, - - create(context) { - - return { - - NewExpression(node) { - const wrapperObjects = ["String", "Number", "Boolean"]; - - if (wrapperObjects.indexOf(node.callee.name) > -1) { - context.report({ - node, - messageId: "noConstructor", - data: { fn: node.callee.name } - }); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to disallow `\8` and `\9` escape sequences in string literals. - * @author Milos Djermanovic - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const QUICK_TEST_REGEX = /\\[89]/u; - -/** - * Returns unicode escape sequence that represents the given character. - * @param {string} character A single code unit. - * @returns {string} "\uXXXX" sequence. - */ -function getUnicodeEscape(character) { - return `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noNonoctalDecimalEscape = { - meta: { - type: "suggestion", - - docs: { - description: "disallow `\\8` and `\\9` escape sequences in string literals", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-nonoctal-decimal-escape", - suggestion: true - }, - - schema: [], - - messages: { - decimalEscape: "Don't use '{{decimalEscape}}' escape sequence.", - - // suggestions - refactor: "Replace '{{original}}' with '{{replacement}}'. This maintains the current functionality.", - escapeBackslash: "Replace '{{original}}' with '{{replacement}}' to include the actual backslash character." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - /** - * Creates a new Suggestion object. - * @param {string} messageId "refactor" or "escapeBackslash". - * @param {int[]} range The range to replace. - * @param {string} replacement New text for the range. - * @returns {Object} Suggestion - */ - function createSuggestion(messageId, range, replacement) { - return { - messageId, - data: { - original: sourceCode.getText().slice(...range), - replacement - }, - fix(fixer) { - return fixer.replaceTextRange(range, replacement); - } - }; - } - - return { - Literal(node) { - if (typeof node.value !== "string") { - return; - } - - if (!QUICK_TEST_REGEX.test(node.raw)) { - return; - } - - const regex = /(?:[^\\]|(?\\.))*?(?\\[89])/suy; - let match; - - while ((match = regex.exec(node.raw))) { - const { previousEscape, decimalEscape } = match.groups; - const decimalEscapeRangeEnd = node.range[0] + match.index + match[0].length; - const decimalEscapeRangeStart = decimalEscapeRangeEnd - decimalEscape.length; - const decimalEscapeRange = [decimalEscapeRangeStart, decimalEscapeRangeEnd]; - const suggest = []; - - // When `regex` is matched, `previousEscape` can only capture characters adjacent to `decimalEscape` - if (previousEscape === "\\0") { - - /* - * Now we have a NULL escape "\0" immediately followed by a decimal escape, e.g.: "\0\8". - * Fixing this to "\08" would turn "\0" into a legacy octal escape. To avoid producing - * an octal escape while fixing a decimal escape, we provide different suggestions. - */ - suggest.push( - createSuggestion( // "\0\8" -> "\u00008" - "refactor", - [decimalEscapeRangeStart - previousEscape.length, decimalEscapeRangeEnd], - `${getUnicodeEscape("\0")}${decimalEscape[1]}` - ), - createSuggestion( // "\8" -> "\u0038" - "refactor", - decimalEscapeRange, - getUnicodeEscape(decimalEscape[1]) - ) - ); - } else { - suggest.push( - createSuggestion( // "\8" -> "8" - "refactor", - decimalEscapeRange, - decimalEscape[1] - ) - ); - } - - suggest.push( - createSuggestion( // "\8" -> "\\8" - "escapeBackslash", - decimalEscapeRange, - `\\${decimalEscape}` - ) - ); - - context.report({ - node, - loc: { - start: sourceCode.getLocFromIndex(decimalEscapeRangeStart), - end: sourceCode.getLocFromIndex(decimalEscapeRangeEnd) - }, - messageId: "decimalEscape", - data: { - decimalEscape - }, - suggest - }); - } - } - }; - } -}; - -/** - * @fileoverview Rule to flag use of an object property of the global object (Math and JSON) as a function - * @author James Allardice - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -const { CALL: CALL$6, CONSTRUCT: CONSTRUCT$4, ReferenceTracker: ReferenceTracker$6 } = require$$0__default$1['default']; -const getPropertyName$1 = astUtils.getStaticPropertyName; - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const nonCallableGlobals = ["Atomics", "JSON", "Math", "Reflect"]; - -/** - * Returns the name of the node to report - * @param {ASTNode} node A node to report - * @returns {string} name to report - */ -function getReportNodeName(node) { - if (node.type === "ChainExpression") { - return getReportNodeName(node.expression); - } - if (node.type === "MemberExpression") { - return getPropertyName$1(node); - } - return node.name; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noObjCalls = { - meta: { - type: "problem", - - docs: { - description: "disallow calling global object properties as functions", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-obj-calls" - }, - - schema: [], - - messages: { - unexpectedCall: "'{{name}}' is not a function.", - unexpectedRefCall: "'{{name}}' is reference to '{{ref}}', which is not a function." - } - }, - - create(context) { - - return { - Program() { - const scope = context.getScope(); - const tracker = new ReferenceTracker$6(scope); - const traceMap = {}; - - for (const g of nonCallableGlobals) { - traceMap[g] = { - [CALL$6]: true, - [CONSTRUCT$4]: true - }; - } - - for (const { node, path } of tracker.iterateGlobalReferences(traceMap)) { - const name = getReportNodeName(node.callee); - const ref = path[0]; - const messageId = name === ref ? "unexpectedCall" : "unexpectedRefCall"; - - context.report({ node, messageId, data: { name, ref } }); - } - } - }; - } -}; - -/** - * @fileoverview Rule to flag when initializing octal literal - * @author Ilya Volodin - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noOctal = { - meta: { - type: "suggestion", - - docs: { - description: "disallow octal literals", - category: "Best Practices", - recommended: true, - url: "https://eslint.org/docs/rules/no-octal" - }, - - schema: [], - - messages: { - noOcatal: "Octal literals should not be used." - } - }, - - create(context) { - - return { - - Literal(node) { - if (typeof node.value === "number" && /^0[0-9]/u.test(node.raw)) { - context.report({ - node, - messageId: "noOcatal" - }); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag octal escape sequences in string literals. - * @author Ian Christian Myers - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noOctalEscape = { - meta: { - type: "suggestion", - - docs: { - description: "disallow octal escape sequences in string literals", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-octal-escape" - }, - - schema: [], - - messages: { - octalEscapeSequence: "Don't use octal: '\\{{sequence}}'. Use '\\u....' instead." - } - }, - - create(context) { - - return { - - Literal(node) { - if (typeof node.value !== "string") { - return; - } - - // \0 represents a valid NULL character if it isn't followed by a digit. - const match = node.raw.match( - /^(?:[^\\]|\\.)*?\\([0-3][0-7]{1,2}|[4-7][0-7]|0(?=[89])|[1-7])/su - ); - - if (match) { - context.report({ - node, - messageId: "octalEscapeSequence", - data: { sequence: match[1] } - }); - } - } - - }; - - } -}; - -/** - * @fileoverview Disallow reassignment of function parameters. - * @author Nat Burns - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -const stopNodePattern = /(?:Statement|Declaration|Function(?:Expression)?|Program)$/u; - -var noParamReassign = { - meta: { - type: "suggestion", - - docs: { - description: "disallow reassigning `function` parameters", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-param-reassign" - }, - - schema: [ - { - oneOf: [ - { - type: "object", - properties: { - props: { - enum: [false] - } - }, - additionalProperties: false - }, - { - type: "object", - properties: { - props: { - enum: [true] - }, - ignorePropertyModificationsFor: { - type: "array", - items: { - type: "string" - }, - uniqueItems: true - }, - ignorePropertyModificationsForRegex: { - type: "array", - items: { - type: "string" - }, - uniqueItems: true - } - }, - additionalProperties: false - } - ] - } - ], - - messages: { - assignmentToFunctionParam: "Assignment to function parameter '{{name}}'.", - assignmentToFunctionParamProp: "Assignment to property of function parameter '{{name}}'." - } - }, - - create(context) { - const props = context.options[0] && context.options[0].props; - const ignoredPropertyAssignmentsFor = context.options[0] && context.options[0].ignorePropertyModificationsFor || []; - const ignoredPropertyAssignmentsForRegex = context.options[0] && context.options[0].ignorePropertyModificationsForRegex || []; - - /** - * Checks whether or not the reference modifies properties of its variable. - * @param {Reference} reference A reference to check. - * @returns {boolean} Whether or not the reference modifies properties of its variable. - */ - function isModifyingProp(reference) { - let node = reference.identifier; - let parent = node.parent; - - while (parent && (!stopNodePattern.test(parent.type) || - parent.type === "ForInStatement" || parent.type === "ForOfStatement")) { - switch (parent.type) { - - // e.g. foo.a = 0; - case "AssignmentExpression": - return parent.left === node; - - // e.g. ++foo.a; - case "UpdateExpression": - return true; - - // e.g. delete foo.a; - case "UnaryExpression": - if (parent.operator === "delete") { - return true; - } - break; - - // e.g. for (foo.a in b) {} - case "ForInStatement": - case "ForOfStatement": - if (parent.left === node) { - return true; - } - - // this is a stop node for parent.right and parent.body - return false; - - // EXCLUDES: e.g. cache.get(foo.a).b = 0; - case "CallExpression": - if (parent.callee !== node) { - return false; - } - break; - - // EXCLUDES: e.g. cache[foo.a] = 0; - case "MemberExpression": - if (parent.property === node) { - return false; - } - break; - - // EXCLUDES: e.g. ({ [foo]: a }) = bar; - case "Property": - if (parent.key === node) { - return false; - } - - break; - - // EXCLUDES: e.g. (foo ? a : b).c = bar; - case "ConditionalExpression": - if (parent.test === node) { - return false; - } - - break; - - // no default - } - - node = parent; - parent = node.parent; - } - - return false; - } - - /** - * Tests that an identifier name matches any of the ignored property assignments. - * First we test strings in ignoredPropertyAssignmentsFor. - * Then we instantiate and test RegExp objects from ignoredPropertyAssignmentsForRegex strings. - * @param {string} identifierName A string that describes the name of an identifier to - * ignore property assignments for. - * @returns {boolean} Whether the string matches an ignored property assignment regular expression or not. - */ - function isIgnoredPropertyAssignment(identifierName) { - return ignoredPropertyAssignmentsFor.includes(identifierName) || - ignoredPropertyAssignmentsForRegex.some(ignored => new RegExp(ignored, "u").test(identifierName)); - } - - /** - * Reports a reference if is non initializer and writable. - * @param {Reference} reference A reference to check. - * @param {int} index The index of the reference in the references. - * @param {Reference[]} references The array that the reference belongs to. - * @returns {void} - */ - function checkReference(reference, index, references) { - const identifier = reference.identifier; - - if (identifier && - !reference.init && - - /* - * Destructuring assignments can have multiple default value, - * so possibly there are multiple writeable references for the same identifier. - */ - (index === 0 || references[index - 1].identifier !== identifier) - ) { - if (reference.isWrite()) { - context.report({ - node: identifier, - messageId: "assignmentToFunctionParam", - data: { name: identifier.name } - }); - } else if (props && isModifyingProp(reference) && !isIgnoredPropertyAssignment(identifier.name)) { - context.report({ - node: identifier, - messageId: "assignmentToFunctionParamProp", - data: { name: identifier.name } - }); - } - } - } - - /** - * Finds and reports references that are non initializer and writable. - * @param {Variable} variable A variable to check. - * @returns {void} - */ - function checkVariable(variable) { - if (variable.defs[0].type === "Parameter") { - variable.references.forEach(checkReference); - } - } - - /** - * Checks parameters of a given function node. - * @param {ASTNode} node A function node to check. - * @returns {void} - */ - function checkForFunction(node) { - context.getDeclaredVariables(node).forEach(checkVariable); - } - - return { - - // `:exit` is needed for the `node.parent` property of identifier nodes. - "FunctionDeclaration:exit": checkForFunction, - "FunctionExpression:exit": checkForFunction, - "ArrowFunctionExpression:exit": checkForFunction - }; - - } -}; - -/** - * @fileoverview Disallow string concatenation when using __dirname and __filename - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noPathConcat = { - meta: { - deprecated: true, - - replacedBy: [], - - type: "suggestion", - - docs: { - description: "disallow string concatenation with `__dirname` and `__filename`", - category: "Node.js and CommonJS", - recommended: false, - url: "https://eslint.org/docs/rules/no-path-concat" - }, - - schema: [], - - messages: { - usePathFunctions: "Use path.join() or path.resolve() instead of + to create paths." - } - }, - - create(context) { - - const MATCHER = /^__(?:dir|file)name$/u; - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - - BinaryExpression(node) { - - const left = node.left, - right = node.right; - - if (node.operator === "+" && - ((left.type === "Identifier" && MATCHER.test(left.name)) || - (right.type === "Identifier" && MATCHER.test(right.name))) - ) { - - context.report({ - node, - messageId: "usePathFunctions" - }); - } - } - - }; - - } -}; - -/** - * @fileoverview Rule to flag use of unary increment and decrement operators. - * @author Ian Christian Myers - * @author Brody McKee (github.com/mrmckeb) - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Determines whether the given node is the update node of a `ForStatement`. - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if the node is `ForStatement` update. - */ -function isForStatementUpdate(node) { - const parent = node.parent; - - return parent.type === "ForStatement" && parent.update === node; -} - -/** - * Determines whether the given node is considered to be a for loop "afterthought" by the logic of this rule. - * In particular, it returns `true` if the given node is either: - * - The update node of a `ForStatement`: for (;; i++) {} - * - An operand of a sequence expression that is the update node: for (;; foo(), i++) {} - * - An operand of a sequence expression that is child of another sequence expression, etc., - * up to the sequence expression that is the update node: for (;; foo(), (bar(), (baz(), i++))) {} - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if the node is a for loop afterthought. - */ -function isForLoopAfterthought(node) { - const parent = node.parent; - - if (parent.type === "SequenceExpression") { - return isForLoopAfterthought(parent); - } - - return isForStatementUpdate(node); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noPlusplus = { - meta: { - type: "suggestion", - - docs: { - description: "disallow the unary operators `++` and `--`", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/no-plusplus" - }, - - schema: [ - { - type: "object", - properties: { - allowForLoopAfterthoughts: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - messages: { - unexpectedUnaryOp: "Unary operator '{{operator}}' used." - } - }, - - create(context) { - - const config = context.options[0]; - let allowForLoopAfterthoughts = false; - - if (typeof config === "object") { - allowForLoopAfterthoughts = config.allowForLoopAfterthoughts === true; - } - - return { - - UpdateExpression(node) { - if (allowForLoopAfterthoughts && isForLoopAfterthought(node)) { - return; - } - - context.report({ - node, - messageId: "unexpectedUnaryOp", - data: { - operator: node.operator - } - }); - } - - }; - - } -}; - -/** - * @fileoverview Disallow the use of process.env() - * @author Vignesh Anand - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noProcessEnv = { - meta: { - deprecated: true, - - replacedBy: [], - - type: "suggestion", - - docs: { - description: "disallow the use of `process.env`", - category: "Node.js and CommonJS", - recommended: false, - url: "https://eslint.org/docs/rules/no-process-env" - }, - - schema: [], - - messages: { - unexpectedProcessEnv: "Unexpected use of process.env." - } - }, - - create(context) { - - return { - - MemberExpression(node) { - const objectName = node.object.name, - propertyName = node.property.name; - - if (objectName === "process" && !node.computed && propertyName && propertyName === "env") { - context.report({ node, messageId: "unexpectedProcessEnv" }); - } - - } - - }; - - } -}; - -/** - * @fileoverview Disallow the use of process.exit() - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noProcessExit = { - meta: { - deprecated: true, - - replacedBy: [], - - type: "suggestion", - - docs: { - description: "disallow the use of `process.exit()`", - category: "Node.js and CommonJS", - recommended: false, - url: "https://eslint.org/docs/rules/no-process-exit" - }, - - schema: [], - - messages: { - noProcessExit: "Don't use process.exit(); throw an error instead." - } - }, - - create(context) { - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - "CallExpression > MemberExpression.callee[object.name = 'process'][property.name = 'exit']"(node) { - context.report({ node: node.parent, messageId: "noProcessExit" }); - } - }; - - } -}; - -/** - * @fileoverview Rule to disallow returning values from Promise executor functions - * @author Milos Djermanovic - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -const { findVariable: findVariable$2 } = require$$0__default$1['default']; - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const functionTypesToCheck = new Set(["ArrowFunctionExpression", "FunctionExpression"]); - -/** - * Determines whether the given identifier node is a reference to a global variable. - * @param {ASTNode} node `Identifier` node to check. - * @param {Scope} scope Scope to which the node belongs. - * @returns {boolean} True if the identifier is a reference to a global variable. - */ -function isGlobalReference$1(node, scope) { - const variable = findVariable$2(scope, node); - - return variable !== null && variable.scope.type === "global" && variable.defs.length === 0; -} - -/** - * Finds function's outer scope. - * @param {Scope} scope Function's own scope. - * @returns {Scope} Function's outer scope. - */ -function getOuterScope$1(scope) { - const upper = scope.upper; - - if (upper.type === "function-expression-name") { - return upper.upper; - } - return upper; -} - -/** - * Determines whether the given function node is used as a Promise executor. - * @param {ASTNode} node The node to check. - * @param {Scope} scope Function's own scope. - * @returns {boolean} `true` if the node is a Promise executor. - */ -function isPromiseExecutor(node, scope) { - const parent = node.parent; - - return parent.type === "NewExpression" && - parent.arguments[0] === node && - parent.callee.type === "Identifier" && - parent.callee.name === "Promise" && - isGlobalReference$1(parent.callee, getOuterScope$1(scope)); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noPromiseExecutorReturn = { - meta: { - type: "problem", - - docs: { - description: "disallow returning values from Promise executor functions", - category: "Possible Errors", - recommended: false, - url: "https://eslint.org/docs/rules/no-promise-executor-return" - }, - - schema: [], - - messages: { - returnsValue: "Return values from promise executor functions cannot be read." - } - }, - - create(context) { - - let funcInfo = null; - - /** - * Reports the given node. - * @param {ASTNode} node Node to report. - * @returns {void} - */ - function report(node) { - context.report({ node, messageId: "returnsValue" }); - } - - return { - - onCodePathStart(_, node) { - funcInfo = { - upper: funcInfo, - shouldCheck: functionTypesToCheck.has(node.type) && isPromiseExecutor(node, context.getScope()) - }; - - if (funcInfo.shouldCheck && node.type === "ArrowFunctionExpression" && node.expression) { - report(node.body); - } - }, - - onCodePathEnd() { - funcInfo = funcInfo.upper; - }, - - ReturnStatement(node) { - if (funcInfo.shouldCheck && node.argument) { - report(node); - } - } - }; - } -}; - -/** - * @fileoverview Rule to flag usage of __proto__ property - * @author Ilya Volodin - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -const { getStaticPropertyName } = astUtils; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noProto = { - meta: { - type: "suggestion", - - docs: { - description: "disallow the use of the `__proto__` property", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-proto" - }, - - schema: [], - - messages: { - unexpectedProto: "The '__proto__' property is deprecated." - } - }, - - create(context) { - - return { - - MemberExpression(node) { - if (getStaticPropertyName(node) === "__proto__") { - context.report({ node, messageId: "unexpectedProto" }); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to disallow use of Object.prototype builtins on objects - * @author Andrew Levine - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noPrototypeBuiltins = { - meta: { - type: "problem", - - docs: { - description: "disallow calling some `Object.prototype` methods directly on objects", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-prototype-builtins" - }, - - schema: [], - - messages: { - prototypeBuildIn: "Do not access Object.prototype method '{{prop}}' from target object." - } - }, - - create(context) { - const DISALLOWED_PROPS = [ - "hasOwnProperty", - "isPrototypeOf", - "propertyIsEnumerable" - ]; - - /** - * Reports if a disallowed property is used in a CallExpression - * @param {ASTNode} node The CallExpression node. - * @returns {void} - */ - function disallowBuiltIns(node) { - - const callee = astUtils.skipChainExpression(node.callee); - - if (callee.type !== "MemberExpression") { - return; - } - - const propName = astUtils.getStaticPropertyName(callee); - - if (propName !== null && DISALLOWED_PROPS.indexOf(propName) > -1) { - context.report({ - messageId: "prototypeBuildIn", - loc: callee.property.loc, - data: { prop: propName }, - node - }); - } - } - - return { - CallExpression: disallowBuiltIns - }; - } -}; - -/** - * @fileoverview Rule to flag when the same variable is declared more then once. - * @author Ilya Volodin - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noRedeclare = { - meta: { - type: "suggestion", - - docs: { - description: "disallow variable redeclaration", - category: "Best Practices", - recommended: true, - url: "https://eslint.org/docs/rules/no-redeclare" - }, - - messages: { - redeclared: "'{{id}}' is already defined.", - redeclaredAsBuiltin: "'{{id}}' is already defined as a built-in global variable.", - redeclaredBySyntax: "'{{id}}' is already defined by a variable declaration." - }, - - schema: [ - { - type: "object", - properties: { - builtinGlobals: { type: "boolean", default: true } - }, - additionalProperties: false - } - ] - }, - - create(context) { - const options = { - builtinGlobals: Boolean( - context.options.length === 0 || - context.options[0].builtinGlobals - ) - }; - const sourceCode = context.getSourceCode(); - - /** - * Iterate declarations of a given variable. - * @param {escope.variable} variable The variable object to iterate declarations. - * @returns {IterableIterator<{type:string,node:ASTNode,loc:SourceLocation}>} The declarations. - */ - function *iterateDeclarations(variable) { - if (options.builtinGlobals && ( - variable.eslintImplicitGlobalSetting === "readonly" || - variable.eslintImplicitGlobalSetting === "writable" - )) { - yield { type: "builtin" }; - } - - for (const id of variable.identifiers) { - yield { type: "syntax", node: id, loc: id.loc }; - } - - if (variable.eslintExplicitGlobalComments) { - for (const comment of variable.eslintExplicitGlobalComments) { - yield { - type: "comment", - node: comment, - loc: astUtils.getNameLocationInGlobalDirectiveComment( - sourceCode, - comment, - variable.name - ) - }; - } - } - } - - /** - * Find variables in a given scope and flag redeclared ones. - * @param {Scope} scope An eslint-scope scope object. - * @returns {void} - * @private - */ - function findVariablesInScope(scope) { - for (const variable of scope.variables) { - const [ - declaration, - ...extraDeclarations - ] = iterateDeclarations(variable); - - if (extraDeclarations.length === 0) { - continue; - } - - /* - * If the type of a declaration is different from the type of - * the first declaration, it shows the location of the first - * declaration. - */ - const detailMessageId = declaration.type === "builtin" - ? "redeclaredAsBuiltin" - : "redeclaredBySyntax"; - const data = { id: variable.name }; - - // Report extra declarations. - for (const { type, node, loc } of extraDeclarations) { - const messageId = type === declaration.type - ? "redeclared" - : detailMessageId; - - context.report({ node, loc, messageId, data }); - } - } - } - - /** - * Find variables in the current scope. - * @param {ASTNode} node The node of the current scope. - * @returns {void} - * @private - */ - function checkForBlock(node) { - const scope = context.getScope(); - - /* - * In ES5, some node type such as `BlockStatement` doesn't have that scope. - * `scope.block` is a different node in such a case. - */ - if (scope.block === node) { - findVariablesInScope(scope); - } - } - - return { - Program() { - const scope = context.getScope(); - - findVariablesInScope(scope); - - // Node.js or ES modules has a special scope. - if ( - scope.type === "global" && - scope.childScopes[0] && - - // The special scope's block is the Program node. - scope.block === scope.childScopes[0].block - ) { - findVariablesInScope(scope.childScopes[0]); - } - }, - - FunctionDeclaration: checkForBlock, - FunctionExpression: checkForBlock, - ArrowFunctionExpression: checkForBlock, - - BlockStatement: checkForBlock, - ForStatement: checkForBlock, - ForInStatement: checkForBlock, - ForOfStatement: checkForBlock, - SwitchStatement: checkForBlock - }; - } -}; - -/** - * @fileoverview Rule to count multiple spaces in regular expressions - * @author Matt DuVall - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const regExpParser = new regexpp__default['default'].RegExpParser(); -const DOUBLE_SPACE = / {2}/u; - -/** - * Check if node is a string - * @param {ASTNode} node node to evaluate - * @returns {boolean} True if its a string - * @private - */ -function isString(node) { - return node && node.type === "Literal" && typeof node.value === "string"; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noRegexSpaces = { - meta: { - type: "suggestion", - - docs: { - description: "disallow multiple spaces in regular expressions", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-regex-spaces" - }, - - schema: [], - fixable: "code", - - messages: { - multipleSpaces: "Spaces are hard to count. Use {{{length}}}." - } - }, - - create(context) { - - /** - * Validate regular expression - * @param {ASTNode} nodeToReport Node to report. - * @param {string} pattern Regular expression pattern to validate. - * @param {string} rawPattern Raw representation of the pattern in the source code. - * @param {number} rawPatternStartRange Start range of the pattern in the source code. - * @param {string} flags Regular expression flags. - * @returns {void} - * @private - */ - function checkRegex(nodeToReport, pattern, rawPattern, rawPatternStartRange, flags) { - - // Skip if there are no consecutive spaces in the source code, to avoid reporting e.g., RegExp(' \ '). - if (!DOUBLE_SPACE.test(rawPattern)) { - return; - } - - const characterClassNodes = []; - let regExpAST; - - try { - regExpAST = regExpParser.parsePattern(pattern, 0, pattern.length, flags.includes("u")); - } catch { - - // Ignore regular expressions with syntax errors - return; - } - - regexpp__default['default'].visitRegExpAST(regExpAST, { - onCharacterClassEnter(ccNode) { - characterClassNodes.push(ccNode); - } - }); - - const spacesPattern = /( {2,})(?: [+*{?]|[^+*{?]|$)/gu; - let match; - - while ((match = spacesPattern.exec(pattern))) { - const { 1: { length }, index } = match; - - // Report only consecutive spaces that are not in character classes. - if ( - characterClassNodes.every(({ start, end }) => index < start || end <= index) - ) { - context.report({ - node: nodeToReport, - messageId: "multipleSpaces", - data: { length }, - fix(fixer) { - if (pattern !== rawPattern) { - return null; - } - return fixer.replaceTextRange( - [rawPatternStartRange + index, rawPatternStartRange + index + length], - ` {${length}}` - ); - } - }); - - // Report only the first occurrence of consecutive spaces - return; - } - } - } - - /** - * Validate regular expression literals - * @param {ASTNode} node node to validate - * @returns {void} - * @private - */ - function checkLiteral(node) { - if (node.regex) { - const pattern = node.regex.pattern; - const rawPattern = node.raw.slice(1, node.raw.lastIndexOf("/")); - const rawPatternStartRange = node.range[0] + 1; - const flags = node.regex.flags; - - checkRegex( - node, - pattern, - rawPattern, - rawPatternStartRange, - flags - ); - } - } - - /** - * Validate strings passed to the RegExp constructor - * @param {ASTNode} node node to validate - * @returns {void} - * @private - */ - function checkFunction(node) { - const scope = context.getScope(); - const regExpVar = astUtils.getVariableByName(scope, "RegExp"); - const shadowed = regExpVar && regExpVar.defs.length > 0; - const patternNode = node.arguments[0]; - const flagsNode = node.arguments[1]; - - if (node.callee.type === "Identifier" && node.callee.name === "RegExp" && isString(patternNode) && !shadowed) { - const pattern = patternNode.value; - const rawPattern = patternNode.raw.slice(1, -1); - const rawPatternStartRange = patternNode.range[0] + 1; - const flags = isString(flagsNode) ? flagsNode.value : ""; - - checkRegex( - node, - pattern, - rawPattern, - rawPatternStartRange, - flags - ); - } - } - - return { - Literal: checkLiteral, - CallExpression: checkFunction, - NewExpression: checkFunction - }; - } -}; - -/** - * @fileoverview Rule to disallow specified names in exports - * @author Milos Djermanovic - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noRestrictedExports = { - meta: { - type: "suggestion", - - docs: { - description: "disallow specified names in exports", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/no-restricted-exports" - }, - - schema: [{ - type: "object", - properties: { - restrictedNamedExports: { - type: "array", - items: { - type: "string" - }, - uniqueItems: true - } - }, - additionalProperties: false - }], - - messages: { - restrictedNamed: "'{{name}}' is restricted from being used as an exported name." - } - }, - - create(context) { - - const restrictedNames = new Set(context.options[0] && context.options[0].restrictedNamedExports); - - /** - * Checks and reports given exported identifier. - * @param {ASTNode} node exported `Identifier` node to check. - * @returns {void} - */ - function checkExportedName(node) { - const name = node.name; - - if (restrictedNames.has(name)) { - context.report({ - node, - messageId: "restrictedNamed", - data: { name } - }); - } - } - - return { - ExportAllDeclaration(node) { - if (node.exported) { - checkExportedName(node.exported); - } - }, - - ExportNamedDeclaration(node) { - const declaration = node.declaration; - - if (declaration) { - if (declaration.type === "FunctionDeclaration" || declaration.type === "ClassDeclaration") { - checkExportedName(declaration.id); - } else if (declaration.type === "VariableDeclaration") { - context.getDeclaredVariables(declaration) - .map(v => v.defs.find(d => d.parent === declaration)) - .map(d => d.name) // Identifier nodes - .forEach(checkExportedName); - } - } else { - node.specifiers - .map(s => s.exported) - .forEach(checkExportedName); - } - } - }; - } -}; - -/** - * @fileoverview Restrict usage of specified globals. - * @author Benoît Zugmeyer - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noRestrictedGlobals = { - meta: { - type: "suggestion", - - docs: { - description: "disallow specified global variables", - category: "Variables", - recommended: false, - url: "https://eslint.org/docs/rules/no-restricted-globals" - }, - - schema: { - type: "array", - items: { - oneOf: [ - { - type: "string" - }, - { - type: "object", - properties: { - name: { type: "string" }, - message: { type: "string" } - }, - required: ["name"], - additionalProperties: false - } - ] - }, - uniqueItems: true, - minItems: 0 - }, - - messages: { - defaultMessage: "Unexpected use of '{{name}}'.", - // eslint-disable-next-line eslint-plugin/report-message-format - customMessage: "Unexpected use of '{{name}}'. {{customMessage}}" - } - }, - - create(context) { - - // If no globals are restricted, we don't need to do anything - if (context.options.length === 0) { - return {}; - } - - const restrictedGlobalMessages = context.options.reduce((memo, option) => { - if (typeof option === "string") { - memo[option] = null; - } else { - memo[option.name] = option.message; - } - - return memo; - }, {}); - - /** - * Report a variable to be used as a restricted global. - * @param {Reference} reference the variable reference - * @returns {void} - * @private - */ - function reportReference(reference) { - const name = reference.identifier.name, - customMessage = restrictedGlobalMessages[name], - messageId = customMessage - ? "customMessage" - : "defaultMessage"; - - context.report({ - node: reference.identifier, - messageId, - data: { - name, - customMessage - } - }); - } - - /** - * Check if the given name is a restricted global name. - * @param {string} name name of a variable - * @returns {boolean} whether the variable is a restricted global or not - * @private - */ - function isRestricted(name) { - return Object.prototype.hasOwnProperty.call(restrictedGlobalMessages, name); - } - - return { - Program() { - const scope = context.getScope(); - - // Report variables declared elsewhere (ex: variables defined as "global" by eslint) - scope.variables.forEach(variable => { - if (!variable.defs.length && isRestricted(variable.name)) { - variable.references.forEach(reportReference); - } - }); - - // Report variables not declared at all - scope.through.forEach(reference => { - if (isRestricted(reference.identifier.name)) { - reportReference(reference); - } - }); - - } - }; - } -}; - -/** - * @fileoverview Restrict usage of specified node imports. - * @author Guy Ellis - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - - - -const arrayOfStrings$1 = { - type: "array", - items: { type: "string" }, - uniqueItems: true -}; - -const arrayOfStringsOrObjects$1 = { - type: "array", - items: { - anyOf: [ - { type: "string" }, - { - type: "object", - properties: { - name: { type: "string" }, - message: { - type: "string", - minLength: 1 - }, - importNames: { - type: "array", - items: { - type: "string" - } - } - }, - additionalProperties: false, - required: ["name"] - } - ] - }, - uniqueItems: true -}; - -var noRestrictedImports = { - meta: { - type: "suggestion", - - docs: { - description: "disallow specified modules when loaded by `import`", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/no-restricted-imports" - }, - - messages: { - path: "'{{importSource}}' import is restricted from being used.", - // eslint-disable-next-line eslint-plugin/report-message-format - pathWithCustomMessage: "'{{importSource}}' import is restricted from being used. {{customMessage}}", - - patterns: "'{{importSource}}' import is restricted from being used by a pattern.", - - everything: "* import is invalid because '{{importNames}}' from '{{importSource}}' is restricted.", - // eslint-disable-next-line eslint-plugin/report-message-format - everythingWithCustomMessage: "* import is invalid because '{{importNames}}' from '{{importSource}}' is restricted. {{customMessage}}", - - importName: "'{{importName}}' import from '{{importSource}}' is restricted.", - // eslint-disable-next-line eslint-plugin/report-message-format - importNameWithCustomMessage: "'{{importName}}' import from '{{importSource}}' is restricted. {{customMessage}}" - }, - - schema: { - anyOf: [ - arrayOfStringsOrObjects$1, - { - type: "array", - items: [{ - type: "object", - properties: { - paths: arrayOfStringsOrObjects$1, - patterns: arrayOfStrings$1 - }, - additionalProperties: false - }], - additionalItems: false - } - ] - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const options = Array.isArray(context.options) ? context.options : []; - const isPathAndPatternsObject = - typeof options[0] === "object" && - (Object.prototype.hasOwnProperty.call(options[0], "paths") || Object.prototype.hasOwnProperty.call(options[0], "patterns")); - - const restrictedPaths = (isPathAndPatternsObject ? options[0].paths : context.options) || []; - const restrictedPatterns = (isPathAndPatternsObject ? options[0].patterns : []) || []; - - // if no imports are restricted we don"t need to check - if (Object.keys(restrictedPaths).length === 0 && restrictedPatterns.length === 0) { - return {}; - } - - const restrictedPathMessages = restrictedPaths.reduce((memo, importSource) => { - if (typeof importSource === "string") { - memo[importSource] = { message: null }; - } else { - memo[importSource.name] = { - message: importSource.message, - importNames: importSource.importNames - }; - } - return memo; - }, {}); - - const restrictedPatternsMatcher = ignore__default['default']().add(restrictedPatterns); - - /** - * Report a restricted path. - * @param {string} importSource path of the import - * @param {Map} importNames Map of import names that are being imported - * @param {node} node representing the restricted path reference - * @returns {void} - * @private - */ - function checkRestrictedPathAndReport(importSource, importNames, node) { - if (!Object.prototype.hasOwnProperty.call(restrictedPathMessages, importSource)) { - return; - } - - const customMessage = restrictedPathMessages[importSource].message; - const restrictedImportNames = restrictedPathMessages[importSource].importNames; - - if (restrictedImportNames) { - if (importNames.has("*")) { - const specifierData = importNames.get("*")[0]; - - context.report({ - node, - messageId: customMessage ? "everythingWithCustomMessage" : "everything", - loc: specifierData.loc, - data: { - importSource, - importNames: restrictedImportNames, - customMessage - } - }); - } - - restrictedImportNames.forEach(importName => { - if (importNames.has(importName)) { - const specifiers = importNames.get(importName); - - specifiers.forEach(specifier => { - context.report({ - node, - messageId: customMessage ? "importNameWithCustomMessage" : "importName", - loc: specifier.loc, - data: { - importSource, - customMessage, - importName - } - }); - }); - } - }); - } else { - context.report({ - node, - messageId: customMessage ? "pathWithCustomMessage" : "path", - data: { - importSource, - customMessage - } - }); - } - } - - /** - * Report a restricted path specifically for patterns. - * @param {node} node representing the restricted path reference - * @returns {void} - * @private - */ - function reportPathForPatterns(node) { - const importSource = node.source.value.trim(); - - context.report({ - node, - messageId: "patterns", - data: { - importSource - } - }); - } - - /** - * Check if the given importSource is restricted by a pattern. - * @param {string} importSource path of the import - * @returns {boolean} whether the variable is a restricted pattern or not - * @private - */ - function isRestrictedPattern(importSource) { - return restrictedPatterns.length > 0 && restrictedPatternsMatcher.ignores(importSource); - } - - /** - * Checks a node to see if any problems should be reported. - * @param {ASTNode} node The node to check. - * @returns {void} - * @private - */ - function checkNode(node) { - const importSource = node.source.value.trim(); - const importNames = new Map(); - - if (node.type === "ExportAllDeclaration") { - const starToken = sourceCode.getFirstToken(node, 1); - - importNames.set("*", [{ loc: starToken.loc }]); - } else if (node.specifiers) { - for (const specifier of node.specifiers) { - let name; - const specifierData = { loc: specifier.loc }; - - if (specifier.type === "ImportDefaultSpecifier") { - name = "default"; - } else if (specifier.type === "ImportNamespaceSpecifier") { - name = "*"; - } else if (specifier.imported) { - name = specifier.imported.name; - } else if (specifier.local) { - name = specifier.local.name; - } - - if (name) { - if (importNames.has(name)) { - importNames.get(name).push(specifierData); - } else { - importNames.set(name, [specifierData]); - } - } - } - } - - checkRestrictedPathAndReport(importSource, importNames, node); - - if (isRestrictedPattern(importSource)) { - reportPathForPatterns(node); - } - } - - return { - ImportDeclaration: checkNode, - ExportNamedDeclaration(node) { - if (node.source) { - checkNode(node); - } - }, - ExportAllDeclaration: checkNode - }; - } -}; - -/** - * @fileoverview Restrict usage of specified node modules. - * @author Christian Schulz - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - - - -const arrayOfStrings = { - type: "array", - items: { type: "string" }, - uniqueItems: true -}; - -const arrayOfStringsOrObjects = { - type: "array", - items: { - anyOf: [ - { type: "string" }, - { - type: "object", - properties: { - name: { type: "string" }, - message: { - type: "string", - minLength: 1 - } - }, - additionalProperties: false, - required: ["name"] - } - ] - }, - uniqueItems: true -}; - -var noRestrictedModules = { - meta: { - deprecated: true, - - replacedBy: [], - - type: "suggestion", - - docs: { - description: "disallow specified modules when loaded by `require`", - category: "Node.js and CommonJS", - recommended: false, - url: "https://eslint.org/docs/rules/no-restricted-modules" - }, - - schema: { - anyOf: [ - arrayOfStringsOrObjects, - { - type: "array", - items: { - type: "object", - properties: { - paths: arrayOfStringsOrObjects, - patterns: arrayOfStrings - }, - additionalProperties: false - }, - additionalItems: false - } - ] - }, - - messages: { - defaultMessage: "'{{name}}' module is restricted from being used.", - // eslint-disable-next-line eslint-plugin/report-message-format - customMessage: "'{{name}}' module is restricted from being used. {{customMessage}}", - patternMessage: "'{{name}}' module is restricted from being used by a pattern." - } - }, - - create(context) { - const options = Array.isArray(context.options) ? context.options : []; - const isPathAndPatternsObject = - typeof options[0] === "object" && - (Object.prototype.hasOwnProperty.call(options[0], "paths") || Object.prototype.hasOwnProperty.call(options[0], "patterns")); - - const restrictedPaths = (isPathAndPatternsObject ? options[0].paths : context.options) || []; - const restrictedPatterns = (isPathAndPatternsObject ? options[0].patterns : []) || []; - - const restrictedPathMessages = restrictedPaths.reduce((memo, importName) => { - if (typeof importName === "string") { - memo[importName] = null; - } else { - memo[importName.name] = importName.message; - } - return memo; - }, {}); - - // if no imports are restricted we don"t need to check - if (Object.keys(restrictedPaths).length === 0 && restrictedPatterns.length === 0) { - return {}; - } - - const ig = ignore__default['default']().add(restrictedPatterns); - - - /** - * Function to check if a node is a string literal. - * @param {ASTNode} node The node to check. - * @returns {boolean} If the node is a string literal. - */ - function isStringLiteral(node) { - return node && node.type === "Literal" && typeof node.value === "string"; - } - - /** - * Function to check if a node is a static string template literal. - * @param {ASTNode} node The node to check. - * @returns {boolean} If the node is a string template literal. - */ - function isStaticTemplateLiteral(node) { - return node && node.type === "TemplateLiteral" && node.expressions.length === 0; - } - - /** - * Function to check if a node is a require call. - * @param {ASTNode} node The node to check. - * @returns {boolean} If the node is a require call. - */ - function isRequireCall(node) { - return node.callee.type === "Identifier" && node.callee.name === "require"; - } - - /** - * Extract string from Literal or TemplateLiteral node - * @param {ASTNode} node The node to extract from - * @returns {string|null} Extracted string or null if node doesn't represent a string - */ - function getFirstArgumentString(node) { - if (isStringLiteral(node)) { - return node.value.trim(); - } - - if (isStaticTemplateLiteral(node)) { - return node.quasis[0].value.cooked.trim(); - } - - return null; - } - - /** - * Report a restricted path. - * @param {node} node representing the restricted path reference - * @param {string} name restricted path - * @returns {void} - * @private - */ - function reportPath(node, name) { - const customMessage = restrictedPathMessages[name]; - const messageId = customMessage - ? "customMessage" - : "defaultMessage"; - - context.report({ - node, - messageId, - data: { - name, - customMessage - } - }); - } - - /** - * Check if the given name is a restricted path name - * @param {string} name name of a variable - * @returns {boolean} whether the variable is a restricted path or not - * @private - */ - function isRestrictedPath(name) { - return Object.prototype.hasOwnProperty.call(restrictedPathMessages, name); - } - - return { - CallExpression(node) { - if (isRequireCall(node)) { - - // node has arguments - if (node.arguments.length) { - const name = getFirstArgumentString(node.arguments[0]); - - // if first argument is a string literal or a static string template literal - if (name) { - - // check if argument value is in restricted modules array - if (isRestrictedPath(name)) { - reportPath(node, name); - } - - if (restrictedPatterns.length > 0 && ig.ignores(name)) { - context.report({ - node, - messageId: "patternMessage", - data: { name } - }); - } - } - } - } - } - }; - } -}; - -/** - * @fileoverview Rule to disallow certain object properties - * @author Will Klein & Eli White - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noRestrictedProperties = { - meta: { - type: "suggestion", - - docs: { - description: "disallow certain properties on certain objects", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-restricted-properties" - }, - - schema: { - type: "array", - items: { - anyOf: [ // `object` and `property` are both optional, but at least one of them must be provided. - { - type: "object", - properties: { - object: { - type: "string" - }, - property: { - type: "string" - }, - message: { - type: "string" - } - }, - additionalProperties: false, - required: ["object"] - }, - { - type: "object", - properties: { - object: { - type: "string" - }, - property: { - type: "string" - }, - message: { - type: "string" - } - }, - additionalProperties: false, - required: ["property"] - } - ] - }, - uniqueItems: true - }, - - messages: { - // eslint-disable-next-line eslint-plugin/report-message-format - restrictedObjectProperty: "'{{objectName}}.{{propertyName}}' is restricted from being used.{{message}}", - // eslint-disable-next-line eslint-plugin/report-message-format - restrictedProperty: "'{{propertyName}}' is restricted from being used.{{message}}" - } - }, - - create(context) { - const restrictedCalls = context.options; - - if (restrictedCalls.length === 0) { - return {}; - } - - const restrictedProperties = new Map(); - const globallyRestrictedObjects = new Map(); - const globallyRestrictedProperties = new Map(); - - restrictedCalls.forEach(option => { - const objectName = option.object; - const propertyName = option.property; - - if (typeof objectName === "undefined") { - globallyRestrictedProperties.set(propertyName, { message: option.message }); - } else if (typeof propertyName === "undefined") { - globallyRestrictedObjects.set(objectName, { message: option.message }); - } else { - if (!restrictedProperties.has(objectName)) { - restrictedProperties.set(objectName, new Map()); - } - - restrictedProperties.get(objectName).set(propertyName, { - message: option.message - }); - } - }); - - /** - * Checks to see whether a property access is restricted, and reports it if so. - * @param {ASTNode} node The node to report - * @param {string} objectName The name of the object - * @param {string} propertyName The name of the property - * @returns {undefined} - */ - function checkPropertyAccess(node, objectName, propertyName) { - if (propertyName === null) { - return; - } - const matchedObject = restrictedProperties.get(objectName); - const matchedObjectProperty = matchedObject ? matchedObject.get(propertyName) : globallyRestrictedObjects.get(objectName); - const globalMatchedProperty = globallyRestrictedProperties.get(propertyName); - - if (matchedObjectProperty) { - const message = matchedObjectProperty.message ? ` ${matchedObjectProperty.message}` : ""; - - context.report({ - node, - messageId: "restrictedObjectProperty", - data: { - objectName, - propertyName, - message - } - }); - } else if (globalMatchedProperty) { - const message = globalMatchedProperty.message ? ` ${globalMatchedProperty.message}` : ""; - - context.report({ - node, - messageId: "restrictedProperty", - data: { - propertyName, - message - } - }); - } - } - - /** - * Checks property accesses in a destructuring assignment expression, e.g. `var foo; ({foo} = bar);` - * @param {ASTNode} node An AssignmentExpression or AssignmentPattern node - * @returns {undefined} - */ - function checkDestructuringAssignment(node) { - if (node.right.type === "Identifier") { - const objectName = node.right.name; - - if (node.left.type === "ObjectPattern") { - node.left.properties.forEach(property => { - checkPropertyAccess(node.left, objectName, astUtils.getStaticPropertyName(property)); - }); - } - } - } - - return { - MemberExpression(node) { - checkPropertyAccess(node, node.object && node.object.name, astUtils.getStaticPropertyName(node)); - }, - VariableDeclarator(node) { - if (node.init && node.init.type === "Identifier") { - const objectName = node.init.name; - - if (node.id.type === "ObjectPattern") { - node.id.properties.forEach(property => { - checkPropertyAccess(node.id, objectName, astUtils.getStaticPropertyName(property)); - }); - } - } - }, - AssignmentExpression: checkDestructuringAssignment, - AssignmentPattern: checkDestructuringAssignment - }; - } -}; - -/** - * @fileoverview Rule to flag use of certain node types - * @author Burak Yigit Kaya - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noRestrictedSyntax = { - meta: { - type: "suggestion", - - docs: { - description: "disallow specified syntax", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/no-restricted-syntax" - }, - - schema: { - type: "array", - items: { - oneOf: [ - { - type: "string" - }, - { - type: "object", - properties: { - selector: { type: "string" }, - message: { type: "string" } - }, - required: ["selector"], - additionalProperties: false - } - ] - }, - uniqueItems: true, - minItems: 0 - }, - - messages: { - // eslint-disable-next-line eslint-plugin/report-message-format - restrictedSyntax: "{{message}}" - } - }, - - create(context) { - return context.options.reduce((result, selectorOrObject) => { - const isStringFormat = (typeof selectorOrObject === "string"); - const hasCustomMessage = !isStringFormat && Boolean(selectorOrObject.message); - - const selector = isStringFormat ? selectorOrObject : selectorOrObject.selector; - const message = hasCustomMessage ? selectorOrObject.message : `Using '${selector}' is not allowed.`; - - return Object.assign(result, { - [selector](node) { - context.report({ - node, - messageId: "restrictedSyntax", - data: { message } - }); - } - }); - }, {}); - - } -}; - -/** - * @fileoverview Rule to flag when return statement contains assignment - * @author Ilya Volodin - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const SENTINEL_TYPE$1 = /^(?:[a-zA-Z]+?Statement|ArrowFunctionExpression|FunctionExpression|ClassExpression)$/u; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noReturnAssign = { - meta: { - type: "suggestion", - - docs: { - description: "disallow assignment operators in `return` statements", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-return-assign" - }, - - schema: [ - { - enum: ["except-parens", "always"] - } - ], - - messages: { - returnAssignment: "Return statement should not contain assignment.", - arrowAssignment: "Arrow function should not return assignment." - } - }, - - create(context) { - const always = (context.options[0] || "except-parens") !== "except-parens"; - const sourceCode = context.getSourceCode(); - - return { - AssignmentExpression(node) { - if (!always && astUtils.isParenthesised(sourceCode, node)) { - return; - } - - let currentChild = node; - let parent = currentChild.parent; - - // Find ReturnStatement or ArrowFunctionExpression in ancestors. - while (parent && !SENTINEL_TYPE$1.test(parent.type)) { - currentChild = parent; - parent = parent.parent; - } - - // Reports. - if (parent && parent.type === "ReturnStatement") { - context.report({ - node: parent, - messageId: "returnAssignment" - }); - } else if (parent && parent.type === "ArrowFunctionExpression" && parent.body === currentChild) { - context.report({ - node: parent, - messageId: "arrowAssignment" - }); - } - } - }; - } -}; - -/** - * @fileoverview Disallows unnecessary `return await` - * @author Jordan Harband - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noReturnAwait = { - meta: { - type: "suggestion", - - docs: { - description: "disallow unnecessary `return await`", - category: "Best Practices", - - recommended: false, - - url: "https://eslint.org/docs/rules/no-return-await" - }, - - fixable: null, - - schema: [ - ], - - messages: { - redundantUseOfAwait: "Redundant use of `await` on a return value." - } - }, - - create(context) { - - /** - * Reports a found unnecessary `await` expression. - * @param {ASTNode} node The node representing the `await` expression to report - * @returns {void} - */ - function reportUnnecessaryAwait(node) { - context.report({ - node: context.getSourceCode().getFirstToken(node), - loc: node.loc, - messageId: "redundantUseOfAwait" - }); - } - - /** - * Determines whether a thrown error from this node will be caught/handled within this function rather than immediately halting - * this function. For example, a statement in a `try` block will always have an error handler. A statement in - * a `catch` block will only have an error handler if there is also a `finally` block. - * @param {ASTNode} node A node representing a location where an could be thrown - * @returns {boolean} `true` if a thrown error will be caught/handled in this function - */ - function hasErrorHandler(node) { - let ancestor = node; - - while (!astUtils.isFunction(ancestor) && ancestor.type !== "Program") { - if (ancestor.parent.type === "TryStatement" && (ancestor === ancestor.parent.block || ancestor === ancestor.parent.handler && ancestor.parent.finalizer)) { - return true; - } - ancestor = ancestor.parent; - } - return false; - } - - /** - * Checks if a node is placed in tail call position. Once `return` arguments (or arrow function expressions) can be a complex expression, - * an `await` expression could or could not be unnecessary by the definition of this rule. So we're looking for `await` expressions that are in tail position. - * @param {ASTNode} node A node representing the `await` expression to check - * @returns {boolean} The checking result - */ - function isInTailCallPosition(node) { - if (node.parent.type === "ArrowFunctionExpression") { - return true; - } - if (node.parent.type === "ReturnStatement") { - return !hasErrorHandler(node.parent); - } - if (node.parent.type === "ConditionalExpression" && (node === node.parent.consequent || node === node.parent.alternate)) { - return isInTailCallPosition(node.parent); - } - if (node.parent.type === "LogicalExpression" && node === node.parent.right) { - return isInTailCallPosition(node.parent); - } - if (node.parent.type === "SequenceExpression" && node === node.parent.expressions[node.parent.expressions.length - 1]) { - return isInTailCallPosition(node.parent); - } - return false; - } - - return { - AwaitExpression(node) { - if (isInTailCallPosition(node) && !hasErrorHandler(node)) { - reportUnnecessaryAwait(node); - } - } - }; - } -}; - -/** - * @fileoverview Rule to flag when using javascript: urls - * @author Ilya Volodin - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noScriptUrl = { - meta: { - type: "suggestion", - - docs: { - description: "disallow `javascript:` urls", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-script-url" - }, - - schema: [], - - messages: { - unexpectedScriptURL: "Script URL is a form of eval." - } - }, - - create(context) { - - /** - * Check whether a node's static value starts with "javascript:" or not. - * And report an error for unexpected script URL. - * @param {ASTNode} node node to check - * @returns {void} - */ - function check(node) { - const value = astUtils.getStaticStringValue(node); - - if (typeof value === "string" && value.toLowerCase().indexOf("javascript:") === 0) { - context.report({ node, messageId: "unexpectedScriptURL" }); - } - } - return { - Literal(node) { - if (node.value && typeof node.value === "string") { - check(node); - } - }, - TemplateLiteral(node) { - if (!(node.parent && node.parent.type === "TaggedTemplateExpression")) { - check(node); - } - } - }; - } -}; - -/** - * @fileoverview Rule to disallow assignments where both sides are exactly the same - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const SPACES = /\s+/gu; - -/** - * Traverses 2 Pattern nodes in parallel, then reports self-assignments. - * @param {ASTNode|null} left A left node to traverse. This is a Pattern or - * a Property. - * @param {ASTNode|null} right A right node to traverse. This is a Pattern or - * a Property. - * @param {boolean} props The flag to check member expressions as well. - * @param {Function} report A callback function to report. - * @returns {void} - */ -function eachSelfAssignment(left, right, props, report) { - if (!left || !right) ; else if ( - left.type === "Identifier" && - right.type === "Identifier" && - left.name === right.name - ) { - report(right); - } else if ( - left.type === "ArrayPattern" && - right.type === "ArrayExpression" - ) { - const end = Math.min(left.elements.length, right.elements.length); - - for (let i = 0; i < end; ++i) { - const leftElement = left.elements[i]; - const rightElement = right.elements[i]; - - // Avoid cases such as [...a] = [...a, 1] - if ( - leftElement && - leftElement.type === "RestElement" && - i < right.elements.length - 1 - ) { - break; - } - - eachSelfAssignment(leftElement, rightElement, props, report); - - // After a spread element, those indices are unknown. - if (rightElement && rightElement.type === "SpreadElement") { - break; - } - } - } else if ( - left.type === "RestElement" && - right.type === "SpreadElement" - ) { - eachSelfAssignment(left.argument, right.argument, props, report); - } else if ( - left.type === "ObjectPattern" && - right.type === "ObjectExpression" && - right.properties.length >= 1 - ) { - - /* - * Gets the index of the last spread property. - * It's possible to overwrite properties followed by it. - */ - let startJ = 0; - - for (let i = right.properties.length - 1; i >= 0; --i) { - const propType = right.properties[i].type; - - if (propType === "SpreadElement" || propType === "ExperimentalSpreadProperty") { - startJ = i + 1; - break; - } - } - - for (let i = 0; i < left.properties.length; ++i) { - for (let j = startJ; j < right.properties.length; ++j) { - eachSelfAssignment( - left.properties[i], - right.properties[j], - props, - report - ); - } - } - } else if ( - left.type === "Property" && - right.type === "Property" && - right.kind === "init" && - !right.method - ) { - const leftName = astUtils.getStaticPropertyName(left); - - if (leftName !== null && leftName === astUtils.getStaticPropertyName(right)) { - eachSelfAssignment(left.value, right.value, props, report); - } - } else if ( - props && - astUtils.skipChainExpression(left).type === "MemberExpression" && - astUtils.skipChainExpression(right).type === "MemberExpression" && - astUtils.isSameReference(left, right) - ) { - report(right); - } -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noSelfAssign = { - meta: { - type: "problem", - - docs: { - description: "disallow assignments where both sides are exactly the same", - category: "Best Practices", - recommended: true, - url: "https://eslint.org/docs/rules/no-self-assign" - }, - - schema: [ - { - type: "object", - properties: { - props: { - type: "boolean", - default: true - } - }, - additionalProperties: false - } - ], - - messages: { - selfAssignment: "'{{name}}' is assigned to itself." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const [{ props = true } = {}] = context.options; - - /** - * Reports a given node as self assignments. - * @param {ASTNode} node A node to report. This is an Identifier node. - * @returns {void} - */ - function report(node) { - context.report({ - node, - messageId: "selfAssignment", - data: { - name: sourceCode.getText(node).replace(SPACES, "") - } - }); - } - - return { - AssignmentExpression(node) { - if (node.operator === "=") { - eachSelfAssignment(node.left, node.right, props, report); - } - } - }; - } -}; - -/** - * @fileoverview Rule to flag comparison where left part is the same as the right - * part. - * @author Ilya Volodin - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noSelfCompare = { - meta: { - type: "problem", - - docs: { - description: "disallow comparisons where both sides are exactly the same", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-self-compare" - }, - - schema: [], - - messages: { - comparingToSelf: "Comparing to itself is potentially pointless." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - /** - * Determines whether two nodes are composed of the same tokens. - * @param {ASTNode} nodeA The first node - * @param {ASTNode} nodeB The second node - * @returns {boolean} true if the nodes have identical token representations - */ - function hasSameTokens(nodeA, nodeB) { - const tokensA = sourceCode.getTokens(nodeA); - const tokensB = sourceCode.getTokens(nodeB); - - return tokensA.length === tokensB.length && - tokensA.every((token, index) => token.type === tokensB[index].type && token.value === tokensB[index].value); - } - - return { - - BinaryExpression(node) { - const operators = new Set(["===", "==", "!==", "!=", ">", "<", ">=", "<="]); - - if (operators.has(node.operator) && hasSameTokens(node.left, node.right)) { - context.report({ node, messageId: "comparingToSelf" }); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag use of comma operator - * @author Brandon Mills - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const DEFAULT_OPTIONS = { - allowInParentheses: true -}; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noSequences = { - meta: { - type: "suggestion", - - docs: { - description: "disallow comma operators", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-sequences" - }, - - schema: [{ - properties: { - allowInParentheses: { - type: "boolean", - default: true - } - }, - additionalProperties: false - }], - - messages: { - unexpectedCommaExpression: "Unexpected use of comma operator." - } - }, - - create(context) { - const options = Object.assign({}, DEFAULT_OPTIONS, context.options[0]); - const sourceCode = context.getSourceCode(); - - /** - * Parts of the grammar that are required to have parens. - */ - const parenthesized = { - DoWhileStatement: "test", - IfStatement: "test", - SwitchStatement: "discriminant", - WhileStatement: "test", - WithStatement: "object", - ArrowFunctionExpression: "body" - - /* - * Omitting CallExpression - commas are parsed as argument separators - * Omitting NewExpression - commas are parsed as argument separators - * Omitting ForInStatement - parts aren't individually parenthesised - * Omitting ForStatement - parts aren't individually parenthesised - */ - }; - - /** - * Determines whether a node is required by the grammar to be wrapped in - * parens, e.g. the test of an if statement. - * @param {ASTNode} node The AST node - * @returns {boolean} True if parens around node belong to parent node. - */ - function requiresExtraParens(node) { - return node.parent && parenthesized[node.parent.type] && - node === node.parent[parenthesized[node.parent.type]]; - } - - /** - * Check if a node is wrapped in parens. - * @param {ASTNode} node The AST node - * @returns {boolean} True if the node has a paren on each side. - */ - function isParenthesised(node) { - return astUtils.isParenthesised(sourceCode, node); - } - - /** - * Check if a node is wrapped in two levels of parens. - * @param {ASTNode} node The AST node - * @returns {boolean} True if two parens surround the node on each side. - */ - function isParenthesisedTwice(node) { - const previousToken = sourceCode.getTokenBefore(node, 1), - nextToken = sourceCode.getTokenAfter(node, 1); - - return isParenthesised(node) && previousToken && nextToken && - astUtils.isOpeningParenToken(previousToken) && previousToken.range[1] <= node.range[0] && - astUtils.isClosingParenToken(nextToken) && nextToken.range[0] >= node.range[1]; - } - - return { - SequenceExpression(node) { - - // Always allow sequences in for statement update - if (node.parent.type === "ForStatement" && - (node === node.parent.init || node === node.parent.update)) { - return; - } - - // Wrapping a sequence in extra parens indicates intent - if (options.allowInParentheses) { - if (requiresExtraParens(node)) { - if (isParenthesisedTwice(node)) { - return; - } - } else { - if (isParenthesised(node)) { - return; - } - } - } - - const firstCommaToken = sourceCode.getTokenAfter(node.expressions[0], astUtils.isCommaToken); - - context.report({ node, loc: firstCommaToken.loc, messageId: "unexpectedCommaExpression" }); - } - }; - - } -}; - -/** - * @fileoverview Rule to disallow returning values from setters - * @author Milos Djermanovic - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - -const { findVariable: findVariable$1 } = require$$0__default$1['default']; - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Determines whether the given identifier node is a reference to a global variable. - * @param {ASTNode} node `Identifier` node to check. - * @param {Scope} scope Scope to which the node belongs. - * @returns {boolean} True if the identifier is a reference to a global variable. - */ -function isGlobalReference(node, scope) { - const variable = findVariable$1(scope, node); - - return variable !== null && variable.scope.type === "global" && variable.defs.length === 0; -} - -/** - * Determines whether the given node is an argument of the specified global method call, at the given `index` position. - * E.g., for given `index === 1`, this function checks for `objectName.methodName(foo, node)`, where objectName is a global variable. - * @param {ASTNode} node The node to check. - * @param {Scope} scope Scope to which the node belongs. - * @param {string} objectName Name of the global object. - * @param {string} methodName Name of the method. - * @param {number} index The given position. - * @returns {boolean} `true` if the node is argument at the given position. - */ -function isArgumentOfGlobalMethodCall(node, scope, objectName, methodName, index) { - const callNode = node.parent; - - return callNode.type === "CallExpression" && - callNode.arguments[index] === node && - astUtils.isSpecificMemberAccess(callNode.callee, objectName, methodName) && - isGlobalReference(astUtils.skipChainExpression(callNode.callee).object, scope); -} - -/** - * Determines whether the given node is used as a property descriptor. - * @param {ASTNode} node The node to check. - * @param {Scope} scope Scope to which the node belongs. - * @returns {boolean} `true` if the node is a property descriptor. - */ -function isPropertyDescriptor(node, scope) { - if ( - isArgumentOfGlobalMethodCall(node, scope, "Object", "defineProperty", 2) || - isArgumentOfGlobalMethodCall(node, scope, "Reflect", "defineProperty", 2) - ) { - return true; - } - - const parent = node.parent; - - if ( - parent.type === "Property" && - parent.value === node - ) { - const grandparent = parent.parent; - - if ( - grandparent.type === "ObjectExpression" && - ( - isArgumentOfGlobalMethodCall(grandparent, scope, "Object", "create", 1) || - isArgumentOfGlobalMethodCall(grandparent, scope, "Object", "defineProperties", 1) - ) - ) { - return true; - } - } - - return false; -} - -/** - * Determines whether the given function node is used as a setter function. - * @param {ASTNode} node The node to check. - * @param {Scope} scope Scope to which the node belongs. - * @returns {boolean} `true` if the node is a setter. - */ -function isSetter(node, scope) { - const parent = node.parent; - - if ( - parent.kind === "set" && - parent.value === node - ) { - - // Setter in an object literal or in a class - return true; - } - - if ( - parent.type === "Property" && - parent.value === node && - astUtils.getStaticPropertyName(parent) === "set" && - parent.parent.type === "ObjectExpression" && - isPropertyDescriptor(parent.parent, scope) - ) { - - // Setter in a property descriptor - return true; - } - - return false; -} - -/** - * Finds function's outer scope. - * @param {Scope} scope Function's own scope. - * @returns {Scope} Function's outer scope. - */ -function getOuterScope(scope) { - const upper = scope.upper; - - if (upper.type === "function-expression-name") { - return upper.upper; - } - - return upper; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noSetterReturn = { - meta: { - type: "problem", - - docs: { - description: "disallow returning values from setters", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-setter-return" - }, - - schema: [], - - messages: { - returnsValue: "Setter cannot return a value." - } - }, - - create(context) { - let funcInfo = null; - - /** - * Creates and pushes to the stack a function info object for the given function node. - * @param {ASTNode} node The function node. - * @returns {void} - */ - function enterFunction(node) { - const outerScope = getOuterScope(context.getScope()); - - funcInfo = { - upper: funcInfo, - isSetter: isSetter(node, outerScope) - }; - } - - /** - * Pops the current function info object from the stack. - * @returns {void} - */ - function exitFunction() { - funcInfo = funcInfo.upper; - } - - /** - * Reports the given node. - * @param {ASTNode} node Node to report. - * @returns {void} - */ - function report(node) { - context.report({ node, messageId: "returnsValue" }); - } - - return { - - /* - * Function declarations cannot be setters, but we still have to track them in the `funcInfo` stack to avoid - * false positives, because a ReturnStatement node can belong to a function declaration inside a setter. - * - * Note: A previously declared function can be referenced and actually used as a setter in a property descriptor, - * but that's out of scope for this rule. - */ - FunctionDeclaration: enterFunction, - FunctionExpression: enterFunction, - ArrowFunctionExpression(node) { - enterFunction(node); - - if (funcInfo.isSetter && node.expression) { - - // { set: foo => bar } property descriptor. Report implicit return 'bar' as the equivalent for a return statement. - report(node.body); - } - }, - - "FunctionDeclaration:exit": exitFunction, - "FunctionExpression:exit": exitFunction, - "ArrowFunctionExpression:exit": exitFunction, - - ReturnStatement(node) { - - // Global returns (e.g., at the top level of a Node module) don't have `funcInfo`. - if (funcInfo && funcInfo.isSetter && node.argument) { - report(node); - } - } - }; - } -}; - -/** - * @fileoverview Rule to flag on declaring variables already declared in the outer scope - * @author Ilya Volodin - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noShadow = { - meta: { - type: "suggestion", - - docs: { - description: "disallow variable declarations from shadowing variables declared in the outer scope", - category: "Variables", - recommended: false, - url: "https://eslint.org/docs/rules/no-shadow" - }, - - schema: [ - { - type: "object", - properties: { - builtinGlobals: { type: "boolean", default: false }, - hoist: { enum: ["all", "functions", "never"], default: "functions" }, - allow: { - type: "array", - items: { - type: "string" - } - } - }, - additionalProperties: false - } - ], - - messages: { - noShadow: "'{{name}}' is already declared in the upper scope on line {{shadowedLine}} column {{shadowedColumn}}.", - noShadowGlobal: "'{{name}}' is already a global variable." - } - }, - - create(context) { - - const options = { - builtinGlobals: context.options[0] && context.options[0].builtinGlobals, - hoist: (context.options[0] && context.options[0].hoist) || "functions", - allow: (context.options[0] && context.options[0].allow) || [] - }; - - /** - * Check if variable name is allowed. - * @param {ASTNode} variable The variable to check. - * @returns {boolean} Whether or not the variable name is allowed. - */ - function isAllowed(variable) { - return options.allow.indexOf(variable.name) !== -1; - } - - /** - * Checks if a variable of the class name in the class scope of ClassDeclaration. - * - * ClassDeclaration creates two variables of its name into its outer scope and its class scope. - * So we should ignore the variable in the class scope. - * @param {Object} variable The variable to check. - * @returns {boolean} Whether or not the variable of the class name in the class scope of ClassDeclaration. - */ - function isDuplicatedClassNameVariable(variable) { - const block = variable.scope.block; - - return block.type === "ClassDeclaration" && block.id === variable.identifiers[0]; - } - - /** - * Checks if a variable is inside the initializer of scopeVar. - * - * To avoid reporting at declarations such as `var a = function a() {};`. - * But it should report `var a = function(a) {};` or `var a = function() { function a() {} };`. - * @param {Object} variable The variable to check. - * @param {Object} scopeVar The scope variable to look for. - * @returns {boolean} Whether or not the variable is inside initializer of scopeVar. - */ - function isOnInitializer(variable, scopeVar) { - const outerScope = scopeVar.scope; - const outerDef = scopeVar.defs[0]; - const outer = outerDef && outerDef.parent && outerDef.parent.range; - const innerScope = variable.scope; - const innerDef = variable.defs[0]; - const inner = innerDef && innerDef.name.range; - - return ( - outer && - inner && - outer[0] < inner[0] && - inner[1] < outer[1] && - ((innerDef.type === "FunctionName" && innerDef.node.type === "FunctionExpression") || innerDef.node.type === "ClassExpression") && - outerScope === innerScope.upper - ); - } - - /** - * Get a range of a variable's identifier node. - * @param {Object} variable The variable to get. - * @returns {Array|undefined} The range of the variable's identifier node. - */ - function getNameRange(variable) { - const def = variable.defs[0]; - - return def && def.name.range; - } - - /** - * Get declared line and column of a variable. - * @param {eslint-scope.Variable} variable The variable to get. - * @returns {Object} The declared line and column of the variable. - */ - function getDeclaredLocation(variable) { - const identifier = variable.identifiers[0]; - let obj; - - if (identifier) { - obj = { - global: false, - line: identifier.loc.start.line, - column: identifier.loc.start.column + 1 - }; - } else { - obj = { - global: true - }; - } - return obj; - } - - /** - * Checks if a variable is in TDZ of scopeVar. - * @param {Object} variable The variable to check. - * @param {Object} scopeVar The variable of TDZ. - * @returns {boolean} Whether or not the variable is in TDZ of scopeVar. - */ - function isInTdz(variable, scopeVar) { - const outerDef = scopeVar.defs[0]; - const inner = getNameRange(variable); - const outer = getNameRange(scopeVar); - - return ( - inner && - outer && - inner[1] < outer[0] && - - // Excepts FunctionDeclaration if is {"hoist":"function"}. - (options.hoist !== "functions" || !outerDef || outerDef.node.type !== "FunctionDeclaration") - ); - } - - /** - * Checks the current context for shadowed variables. - * @param {Scope} scope Fixme - * @returns {void} - */ - function checkForShadows(scope) { - const variables = scope.variables; - - for (let i = 0; i < variables.length; ++i) { - const variable = variables[i]; - - // Skips "arguments" or variables of a class name in the class scope of ClassDeclaration. - if (variable.identifiers.length === 0 || - isDuplicatedClassNameVariable(variable) || - isAllowed(variable) - ) { - continue; - } - - // Gets shadowed variable. - const shadowed = astUtils.getVariableByName(scope.upper, variable.name); - - if (shadowed && - (shadowed.identifiers.length > 0 || (options.builtinGlobals && "writeable" in shadowed)) && - !isOnInitializer(variable, shadowed) && - !(options.hoist !== "all" && isInTdz(variable, shadowed)) - ) { - const location = getDeclaredLocation(shadowed); - const messageId = location.global ? "noShadowGlobal" : "noShadow"; - const data = { name: variable.name }; - - if (!location.global) { - data.shadowedLine = location.line; - data.shadowedColumn = location.column; - } - context.report({ - node: variable.identifiers[0], - messageId, - data - }); - } - } - } - - return { - "Program:exit"() { - const globalScope = context.getScope(); - const stack = globalScope.childScopes.slice(); - - while (stack.length) { - const scope = stack.pop(); - - stack.push(...scope.childScopes); - checkForShadows(scope); - } - } - }; - - } -}; - -/** - * @fileoverview Disallow shadowing of NaN, undefined, and Infinity (ES5 section 15.1.1) - * @author Michael Ficarra - */ - -/** - * Determines if a variable safely shadows undefined. - * This is the case when a variable named `undefined` is never assigned to a value (i.e. it always shares the same value - * as the global). - * @param {eslintScope.Variable} variable The variable to check - * @returns {boolean} true if this variable safely shadows `undefined` - */ -function safelyShadowsUndefined(variable) { - return variable.name === "undefined" && - variable.references.every(ref => !ref.isWrite()) && - variable.defs.every(def => def.node.type === "VariableDeclarator" && def.node.init === null); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noShadowRestrictedNames = { - meta: { - type: "suggestion", - - docs: { - description: "disallow identifiers from shadowing restricted names", - category: "Variables", - recommended: true, - url: "https://eslint.org/docs/rules/no-shadow-restricted-names" - }, - - schema: [], - - messages: { - shadowingRestrictedName: "Shadowing of global property '{{name}}'." - } - }, - - create(context) { - - - const RESTRICTED = new Set(["undefined", "NaN", "Infinity", "arguments", "eval"]); - - return { - "VariableDeclaration, :function, CatchClause"(node) { - for (const variable of context.getDeclaredVariables(node)) { - if (variable.defs.length > 0 && RESTRICTED.has(variable.name) && !safelyShadowsUndefined(variable)) { - context.report({ - node: variable.defs[0].name, - messageId: "shadowingRestrictedName", - data: { - name: variable.name - } - }); - } - } - } - }; - - } -}; - -/** - * @fileoverview Rule to check that spaced function application - * @author Matt DuVall - * @deprecated in ESLint v3.3.0 - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noSpacedFunc = { - meta: { - type: "layout", - - docs: { - description: "disallow spacing between function identifiers and their applications (deprecated)", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/no-spaced-func" - }, - - deprecated: true, - - replacedBy: ["func-call-spacing"], - - fixable: "whitespace", - schema: [], - - messages: { - noSpacedFunction: "Unexpected space between function name and paren." - } - }, - - create(context) { - - const sourceCode = context.getSourceCode(); - - /** - * Check if open space is present in a function name - * @param {ASTNode} node node to evaluate - * @returns {void} - * @private - */ - function detectOpenSpaces(node) { - const lastCalleeToken = sourceCode.getLastToken(node.callee); - let prevToken = lastCalleeToken, - parenToken = sourceCode.getTokenAfter(lastCalleeToken); - - // advances to an open parenthesis. - while ( - parenToken && - parenToken.range[1] < node.range[1] && - parenToken.value !== "(" - ) { - prevToken = parenToken; - parenToken = sourceCode.getTokenAfter(parenToken); - } - - // look for a space between the callee and the open paren - if (parenToken && - parenToken.range[1] < node.range[1] && - sourceCode.isSpaceBetweenTokens(prevToken, parenToken) - ) { - context.report({ - node, - loc: lastCalleeToken.loc.start, - messageId: "noSpacedFunction", - fix(fixer) { - return fixer.removeRange([prevToken.range[1], parenToken.range[0]]); - } - }); - } - } - - return { - CallExpression: detectOpenSpaces, - NewExpression: detectOpenSpaces - }; - - } -}; - -/** - * @fileoverview Disallow sparse arrays - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noSparseArrays = { - meta: { - type: "problem", - - docs: { - description: "disallow sparse arrays", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-sparse-arrays" - }, - - schema: [], - - messages: { - unexpectedSparseArray: "Unexpected comma in middle of array." - } - }, - - create(context) { - - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - - ArrayExpression(node) { - - const emptySpot = node.elements.indexOf(null) > -1; - - if (emptySpot) { - context.report({ node, messageId: "unexpectedSparseArray" }); - } - } - - }; - - } -}; - -/** - * @fileoverview Rule to check for properties whose identifier ends with the string Sync - * @author Matt DuVall - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noSync = { - meta: { - deprecated: true, - - replacedBy: [], - - type: "suggestion", - - docs: { - description: "disallow synchronous methods", - category: "Node.js and CommonJS", - recommended: false, - url: "https://eslint.org/docs/rules/no-sync" - }, - - schema: [ - { - type: "object", - properties: { - allowAtRootLevel: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - messages: { - noSync: "Unexpected sync method: '{{propertyName}}'." - } - }, - - create(context) { - const selector = context.options[0] && context.options[0].allowAtRootLevel - ? ":function MemberExpression[property.name=/.*Sync$/]" - : "MemberExpression[property.name=/.*Sync$/]"; - - return { - [selector](node) { - context.report({ - node, - messageId: "noSync", - data: { - propertyName: node.property.name - } - }); - } - }; - - } -}; - -/** - * @fileoverview Rule to check for tabs inside a file - * @author Gyandeep Singh - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const tabRegex = /\t+/gu; -const anyNonWhitespaceRegex = /\S/u; - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -var noTabs = { - meta: { - type: "layout", - - docs: { - description: "disallow all tabs", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/no-tabs" - }, - schema: [{ - type: "object", - properties: { - allowIndentationTabs: { - type: "boolean", - default: false - } - }, - additionalProperties: false - }], - - messages: { - unexpectedTab: "Unexpected tab character." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const allowIndentationTabs = context.options && context.options[0] && context.options[0].allowIndentationTabs; - - return { - Program(node) { - sourceCode.getLines().forEach((line, index) => { - let match; - - while ((match = tabRegex.exec(line)) !== null) { - if (allowIndentationTabs && !anyNonWhitespaceRegex.test(line.slice(0, match.index))) { - continue; - } - - context.report({ - node, - loc: { - start: { - line: index + 1, - column: match.index - }, - end: { - line: index + 1, - column: match.index + match[0].length - } - }, - messageId: "unexpectedTab" - }); - } - }); - } - }; - } -}; - -/** - * @fileoverview Warn when using template string syntax in regular strings - * @author Jeroen Engels - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noTemplateCurlyInString = { - meta: { - type: "problem", - - docs: { - description: "disallow template literal placeholder syntax in regular strings", - category: "Possible Errors", - recommended: false, - url: "https://eslint.org/docs/rules/no-template-curly-in-string" - }, - - schema: [], - - messages: { - unexpectedTemplateExpression: "Unexpected template string expression." - } - }, - - create(context) { - const regex = /\$\{[^}]+\}/u; - - return { - Literal(node) { - if (typeof node.value === "string" && regex.test(node.value)) { - context.report({ - node, - messageId: "unexpectedTemplateExpression" - }); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag use of ternary operators. - * @author Ian Christian Myers - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noTernary = { - meta: { - type: "suggestion", - - docs: { - description: "disallow ternary operators", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/no-ternary" - }, - - schema: [], - - messages: { - noTernaryOperator: "Ternary operator used." - } - }, - - create(context) { - - return { - - ConditionalExpression(node) { - context.report({ node, messageId: "noTernaryOperator" }); - } - - }; - - } -}; - -/** - * @fileoverview A rule to disallow using `this`/`super` before `super()`. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether or not a given node is a constructor. - * @param {ASTNode} node A node to check. This node type is one of - * `Program`, `FunctionDeclaration`, `FunctionExpression`, and - * `ArrowFunctionExpression`. - * @returns {boolean} `true` if the node is a constructor. - */ -function isConstructorFunction(node) { - return ( - node.type === "FunctionExpression" && - node.parent.type === "MethodDefinition" && - node.parent.kind === "constructor" - ); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noThisBeforeSuper = { - meta: { - type: "problem", - - docs: { - description: "disallow `this`/`super` before calling `super()` in constructors", - category: "ECMAScript 6", - recommended: true, - url: "https://eslint.org/docs/rules/no-this-before-super" - }, - - schema: [], - - messages: { - noBeforeSuper: "'{{kind}}' is not allowed before 'super()'." - } - }, - - create(context) { - - /* - * Information for each constructor. - * - upper: Information of the upper constructor. - * - hasExtends: A flag which shows whether the owner class has a valid - * `extends` part. - * - scope: The scope of the owner class. - * - codePath: The code path of this constructor. - */ - let funcInfo = null; - - /* - * Information for each code path segment. - * Each key is the id of a code path segment. - * Each value is an object: - * - superCalled: The flag which shows `super()` called in all code paths. - * - invalidNodes: The array of invalid ThisExpression and Super nodes. - */ - let segInfoMap = Object.create(null); - - /** - * Gets whether or not `super()` is called in a given code path segment. - * @param {CodePathSegment} segment A code path segment to get. - * @returns {boolean} `true` if `super()` is called. - */ - function isCalled(segment) { - return !segment.reachable || segInfoMap[segment.id].superCalled; - } - - /** - * Checks whether or not this is in a constructor. - * @returns {boolean} `true` if this is in a constructor. - */ - function isInConstructorOfDerivedClass() { - return Boolean(funcInfo && funcInfo.isConstructor && funcInfo.hasExtends); - } - - /** - * Checks whether or not this is before `super()` is called. - * @returns {boolean} `true` if this is before `super()` is called. - */ - function isBeforeCallOfSuper() { - return ( - isInConstructorOfDerivedClass() && - !funcInfo.codePath.currentSegments.every(isCalled) - ); - } - - /** - * Sets a given node as invalid. - * @param {ASTNode} node A node to set as invalid. This is one of - * a ThisExpression and a Super. - * @returns {void} - */ - function setInvalid(node) { - const segments = funcInfo.codePath.currentSegments; - - for (let i = 0; i < segments.length; ++i) { - const segment = segments[i]; - - if (segment.reachable) { - segInfoMap[segment.id].invalidNodes.push(node); - } - } - } - - /** - * Sets the current segment as `super` was called. - * @returns {void} - */ - function setSuperCalled() { - const segments = funcInfo.codePath.currentSegments; - - for (let i = 0; i < segments.length; ++i) { - const segment = segments[i]; - - if (segment.reachable) { - segInfoMap[segment.id].superCalled = true; - } - } - } - - return { - - /** - * Adds information of a constructor into the stack. - * @param {CodePath} codePath A code path which was started. - * @param {ASTNode} node The current node. - * @returns {void} - */ - onCodePathStart(codePath, node) { - if (isConstructorFunction(node)) { - - // Class > ClassBody > MethodDefinition > FunctionExpression - const classNode = node.parent.parent.parent; - - funcInfo = { - upper: funcInfo, - isConstructor: true, - hasExtends: Boolean( - classNode.superClass && - !astUtils.isNullOrUndefined(classNode.superClass) - ), - codePath - }; - } else { - funcInfo = { - upper: funcInfo, - isConstructor: false, - hasExtends: false, - codePath - }; - } - }, - - /** - * Removes the top of stack item. - * - * And this traverses all segments of this code path then reports every - * invalid node. - * @param {CodePath} codePath A code path which was ended. - * @returns {void} - */ - onCodePathEnd(codePath) { - const isDerivedClass = funcInfo.hasExtends; - - funcInfo = funcInfo.upper; - if (!isDerivedClass) { - return; - } - - codePath.traverseSegments((segment, controller) => { - const info = segInfoMap[segment.id]; - - for (let i = 0; i < info.invalidNodes.length; ++i) { - const invalidNode = info.invalidNodes[i]; - - context.report({ - messageId: "noBeforeSuper", - node: invalidNode, - data: { - kind: invalidNode.type === "Super" ? "super" : "this" - } - }); - } - - if (info.superCalled) { - controller.skip(); - } - }); - }, - - /** - * Initialize information of a given code path segment. - * @param {CodePathSegment} segment A code path segment to initialize. - * @returns {void} - */ - onCodePathSegmentStart(segment) { - if (!isInConstructorOfDerivedClass()) { - return; - } - - // Initialize info. - segInfoMap[segment.id] = { - superCalled: ( - segment.prevSegments.length > 0 && - segment.prevSegments.every(isCalled) - ), - invalidNodes: [] - }; - }, - - /** - * Update information of the code path segment when a code path was - * looped. - * @param {CodePathSegment} fromSegment The code path segment of the - * end of a loop. - * @param {CodePathSegment} toSegment A code path segment of the head - * of a loop. - * @returns {void} - */ - onCodePathSegmentLoop(fromSegment, toSegment) { - if (!isInConstructorOfDerivedClass()) { - return; - } - - // Update information inside of the loop. - funcInfo.codePath.traverseSegments( - { first: toSegment, last: fromSegment }, - (segment, controller) => { - const info = segInfoMap[segment.id]; - - if (info.superCalled) { - info.invalidNodes = []; - controller.skip(); - } else if ( - segment.prevSegments.length > 0 && - segment.prevSegments.every(isCalled) - ) { - info.superCalled = true; - info.invalidNodes = []; - } - } - ); - }, - - /** - * Reports if this is before `super()`. - * @param {ASTNode} node A target node. - * @returns {void} - */ - ThisExpression(node) { - if (isBeforeCallOfSuper()) { - setInvalid(node); - } - }, - - /** - * Reports if this is before `super()`. - * @param {ASTNode} node A target node. - * @returns {void} - */ - Super(node) { - if (!astUtils.isCallee(node) && isBeforeCallOfSuper()) { - setInvalid(node); - } - }, - - /** - * Marks `super()` called. - * @param {ASTNode} node A target node. - * @returns {void} - */ - "CallExpression:exit"(node) { - if (node.callee.type === "Super" && isBeforeCallOfSuper()) { - setSuperCalled(); - } - }, - - /** - * Resets state. - * @returns {void} - */ - "Program:exit"() { - segInfoMap = Object.create(null); - } - }; - } -}; - -/** - * @fileoverview Rule to restrict what can be thrown as an exception. - * @author Dieter Oberkofler - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noThrowLiteral = { - meta: { - type: "suggestion", - - docs: { - description: "disallow throwing literals as exceptions", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-throw-literal" - }, - - schema: [], - - messages: { - object: "Expected an error object to be thrown.", - undef: "Do not throw undefined." - } - }, - - create(context) { - - return { - - ThrowStatement(node) { - if (!astUtils.couldBeError(node.argument)) { - context.report({ node, messageId: "object" }); - } else if (node.argument.type === "Identifier") { - if (node.argument.name === "undefined") { - context.report({ node, messageId: "undef" }); - } - } - - } - - }; - - } -}; - -/** - * @fileoverview Disallow trailing spaces at the end of lines. - * @author Nodeca Team - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noTrailingSpaces = { - meta: { - type: "layout", - - docs: { - description: "disallow trailing whitespace at the end of lines", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/no-trailing-spaces" - }, - - fixable: "whitespace", - - schema: [ - { - type: "object", - properties: { - skipBlankLines: { - type: "boolean", - default: false - }, - ignoreComments: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - messages: { - trailingSpace: "Trailing spaces not allowed." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - const BLANK_CLASS = "[ \t\u00a0\u2000-\u200b\u3000]", - SKIP_BLANK = `^${BLANK_CLASS}*$`, - NONBLANK = `${BLANK_CLASS}+$`; - - const options = context.options[0] || {}, - skipBlankLines = options.skipBlankLines || false, - ignoreComments = options.ignoreComments || false; - - /** - * Report the error message - * @param {ASTNode} node node to report - * @param {int[]} location range information - * @param {int[]} fixRange Range based on the whole program - * @returns {void} - */ - function report(node, location, fixRange) { - - /* - * Passing node is a bit dirty, because message data will contain big - * text in `source`. But... who cares :) ? - * One more kludge will not make worse the bloody wizardry of this - * plugin. - */ - context.report({ - node, - loc: location, - messageId: "trailingSpace", - fix(fixer) { - return fixer.removeRange(fixRange); - } - }); - } - - /** - * Given a list of comment nodes, return the line numbers for those comments. - * @param {Array} comments An array of comment nodes. - * @returns {number[]} An array of line numbers containing comments. - */ - function getCommentLineNumbers(comments) { - const lines = new Set(); - - comments.forEach(comment => { - const endLine = comment.type === "Block" - ? comment.loc.end.line - 1 - : comment.loc.end.line; - - for (let i = comment.loc.start.line; i <= endLine; i++) { - lines.add(i); - } - }); - - return lines; - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - - Program: function checkTrailingSpaces(node) { - - /* - * Let's hack. Since Espree does not return whitespace nodes, - * fetch the source code and do matching via regexps. - */ - - const re = new RegExp(NONBLANK, "u"), - skipMatch = new RegExp(SKIP_BLANK, "u"), - lines = sourceCode.lines, - linebreaks = sourceCode.getText().match(astUtils.createGlobalLinebreakMatcher()), - comments = sourceCode.getAllComments(), - commentLineNumbers = getCommentLineNumbers(comments); - - let totalLength = 0, - fixRange = []; - - for (let i = 0, ii = lines.length; i < ii; i++) { - const lineNumber = i + 1; - - /* - * Always add linebreak length to line length to accommodate for line break (\n or \r\n) - * Because during the fix time they also reserve one spot in the array. - * Usually linebreak length is 2 for \r\n (CRLF) and 1 for \n (LF) - */ - const linebreakLength = linebreaks && linebreaks[i] ? linebreaks[i].length : 1; - const lineLength = lines[i].length + linebreakLength; - - const matches = re.exec(lines[i]); - - if (matches) { - const location = { - start: { - line: lineNumber, - column: matches.index - }, - end: { - line: lineNumber, - column: lineLength - linebreakLength - } - }; - - const rangeStart = totalLength + location.start.column; - const rangeEnd = totalLength + location.end.column; - const containingNode = sourceCode.getNodeByRangeIndex(rangeStart); - - if (containingNode && containingNode.type === "TemplateElement" && - rangeStart > containingNode.parent.range[0] && - rangeEnd < containingNode.parent.range[1]) { - totalLength += lineLength; - continue; - } - - /* - * If the line has only whitespace, and skipBlankLines - * is true, don't report it - */ - if (skipBlankLines && skipMatch.test(lines[i])) { - totalLength += lineLength; - continue; - } - - fixRange = [rangeStart, rangeEnd]; - - if (!ignoreComments || !commentLineNumbers.has(lineNumber)) { - report(node, location, fixRange); - } - } - - totalLength += lineLength; - } - } - - }; - } -}; - -/** - * @fileoverview Rule to flag references to undeclared variables. - * @author Mark Macdonald - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks if the given node is the argument of a typeof operator. - * @param {ASTNode} node The AST node being checked. - * @returns {boolean} Whether or not the node is the argument of a typeof operator. - */ -function hasTypeOfOperator(node) { - const parent = node.parent; - - return parent.type === "UnaryExpression" && parent.operator === "typeof"; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUndef = { - meta: { - type: "problem", - - docs: { - description: "disallow the use of undeclared variables unless mentioned in `/*global */` comments", - category: "Variables", - recommended: true, - url: "https://eslint.org/docs/rules/no-undef" - }, - - schema: [ - { - type: "object", - properties: { - typeof: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - messages: { - undef: "'{{name}}' is not defined." - } - }, - - create(context) { - const options = context.options[0]; - const considerTypeOf = options && options.typeof === true || false; - - return { - "Program:exit"(/* node */) { - const globalScope = context.getScope(); - - globalScope.through.forEach(ref => { - const identifier = ref.identifier; - - if (!considerTypeOf && hasTypeOfOperator(identifier)) { - return; - } - - context.report({ - node: identifier, - messageId: "undef", - data: identifier - }); - }); - } - }; - } -}; - -/** - * @fileoverview Rule to flag when initializing to undefined - * @author Ilya Volodin - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUndefInit = { - meta: { - type: "suggestion", - - docs: { - description: "disallow initializing variables to `undefined`", - category: "Variables", - recommended: false, - url: "https://eslint.org/docs/rules/no-undef-init" - }, - - schema: [], - fixable: "code", - - messages: { - unnecessaryUndefinedInit: "It's not necessary to initialize '{{name}}' to undefined." - } - }, - - create(context) { - - const sourceCode = context.getSourceCode(); - - return { - - VariableDeclarator(node) { - const name = sourceCode.getText(node.id), - init = node.init && node.init.name, - scope = context.getScope(), - undefinedVar = astUtils.getVariableByName(scope, "undefined"), - shadowed = undefinedVar && undefinedVar.defs.length > 0, - lastToken = sourceCode.getLastToken(node); - - if (init === "undefined" && node.parent.kind !== "const" && !shadowed) { - context.report({ - node, - messageId: "unnecessaryUndefinedInit", - data: { name }, - fix(fixer) { - if (node.parent.kind === "var") { - return null; - } - - if (node.id.type === "ArrayPattern" || node.id.type === "ObjectPattern") { - - // Don't fix destructuring assignment to `undefined`. - return null; - } - - if (sourceCode.commentsExistBetween(node.id, lastToken)) { - return null; - } - - return fixer.removeRange([node.id.range[1], node.range[1]]); - } - }); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag references to the undefined variable. - * @author Michael Ficarra - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUndefined = { - meta: { - type: "suggestion", - - docs: { - description: "disallow the use of `undefined` as an identifier", - category: "Variables", - recommended: false, - url: "https://eslint.org/docs/rules/no-undefined" - }, - - schema: [], - - messages: { - unexpectedUndefined: "Unexpected use of undefined." - } - }, - - create(context) { - - /** - * Report an invalid "undefined" identifier node. - * @param {ASTNode} node The node to report. - * @returns {void} - */ - function report(node) { - context.report({ - node, - messageId: "unexpectedUndefined" - }); - } - - /** - * Checks the given scope for references to `undefined` and reports - * all references found. - * @param {eslint-scope.Scope} scope The scope to check. - * @returns {void} - */ - function checkScope(scope) { - const undefinedVar = scope.set.get("undefined"); - - if (!undefinedVar) { - return; - } - - const references = undefinedVar.references; - - const defs = undefinedVar.defs; - - // Report non-initializing references (those are covered in defs below) - references - .filter(ref => !ref.init) - .forEach(ref => report(ref.identifier)); - - defs.forEach(def => report(def.name)); - } - - return { - "Program:exit"() { - const globalScope = context.getScope(); - - const stack = [globalScope]; - - while (stack.length) { - const scope = stack.pop(); - - stack.push(...scope.childScopes); - checkScope(scope); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag dangling underscores in variable declarations. - * @author Matt DuVall - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUnderscoreDangle = { - meta: { - type: "suggestion", - - docs: { - description: "disallow dangling underscores in identifiers", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/no-underscore-dangle" - }, - - schema: [ - { - type: "object", - properties: { - allow: { - type: "array", - items: { - type: "string" - } - }, - allowAfterThis: { - type: "boolean", - default: false - }, - allowAfterSuper: { - type: "boolean", - default: false - }, - allowAfterThisConstructor: { - type: "boolean", - default: false - }, - enforceInMethodNames: { - type: "boolean", - default: false - }, - allowFunctionParams: { - type: "boolean", - default: true - } - }, - additionalProperties: false - } - ], - - messages: { - unexpectedUnderscore: "Unexpected dangling '_' in '{{identifier}}'." - } - }, - - create(context) { - - const options = context.options[0] || {}; - const ALLOWED_VARIABLES = options.allow ? options.allow : []; - const allowAfterThis = typeof options.allowAfterThis !== "undefined" ? options.allowAfterThis : false; - const allowAfterSuper = typeof options.allowAfterSuper !== "undefined" ? options.allowAfterSuper : false; - const allowAfterThisConstructor = typeof options.allowAfterThisConstructor !== "undefined" ? options.allowAfterThisConstructor : false; - const enforceInMethodNames = typeof options.enforceInMethodNames !== "undefined" ? options.enforceInMethodNames : false; - const allowFunctionParams = typeof options.allowFunctionParams !== "undefined" ? options.allowFunctionParams : true; - - //------------------------------------------------------------------------- - // Helpers - //------------------------------------------------------------------------- - - /** - * Check if identifier is present inside the allowed option - * @param {string} identifier name of the node - * @returns {boolean} true if its is present - * @private - */ - function isAllowed(identifier) { - return ALLOWED_VARIABLES.some(ident => ident === identifier); - } - - /** - * Check if identifier has a dangling underscore - * @param {string} identifier name of the node - * @returns {boolean} true if its is present - * @private - */ - function hasDanglingUnderscore(identifier) { - const len = identifier.length; - - return identifier !== "_" && (identifier[0] === "_" || identifier[len - 1] === "_"); - } - - /** - * Check if identifier is a special case member expression - * @param {string} identifier name of the node - * @returns {boolean} true if its is a special case - * @private - */ - function isSpecialCaseIdentifierForMemberExpression(identifier) { - return identifier === "__proto__"; - } - - /** - * Check if identifier is a special case variable expression - * @param {string} identifier name of the node - * @returns {boolean} true if its is a special case - * @private - */ - function isSpecialCaseIdentifierInVariableExpression(identifier) { - - // Checks for the underscore library usage here - return identifier === "_"; - } - - /** - * Check if a node is a member reference of this.constructor - * @param {ASTNode} node node to evaluate - * @returns {boolean} true if it is a reference on this.constructor - * @private - */ - function isThisConstructorReference(node) { - return node.object.type === "MemberExpression" && - node.object.property.name === "constructor" && - node.object.object.type === "ThisExpression"; - } - - /** - * Check if function parameter has a dangling underscore. - * @param {ASTNode} node function node to evaluate - * @returns {void} - * @private - */ - function checkForDanglingUnderscoreInFunctionParameters(node) { - if (!allowFunctionParams) { - node.params.forEach(param => { - const { type } = param; - let nodeToCheck; - - if (type === "RestElement") { - nodeToCheck = param.argument; - } else if (type === "AssignmentPattern") { - nodeToCheck = param.left; - } else { - nodeToCheck = param; - } - - if (nodeToCheck.type === "Identifier") { - const identifier = nodeToCheck.name; - - if (hasDanglingUnderscore(identifier) && !isAllowed(identifier)) { - context.report({ - node: param, - messageId: "unexpectedUnderscore", - data: { - identifier - } - }); - } - } - }); - } - } - - /** - * Check if function has a dangling underscore - * @param {ASTNode} node node to evaluate - * @returns {void} - * @private - */ - function checkForDanglingUnderscoreInFunction(node) { - if (node.type === "FunctionDeclaration" && node.id) { - const identifier = node.id.name; - - if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) && !isAllowed(identifier)) { - context.report({ - node, - messageId: "unexpectedUnderscore", - data: { - identifier - } - }); - } - } - checkForDanglingUnderscoreInFunctionParameters(node); - } - - /** - * Check if variable expression has a dangling underscore - * @param {ASTNode} node node to evaluate - * @returns {void} - * @private - */ - function checkForDanglingUnderscoreInVariableExpression(node) { - const identifier = node.id.name; - - if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) && - !isSpecialCaseIdentifierInVariableExpression(identifier) && !isAllowed(identifier)) { - context.report({ - node, - messageId: "unexpectedUnderscore", - data: { - identifier - } - }); - } - } - - /** - * Check if member expression has a dangling underscore - * @param {ASTNode} node node to evaluate - * @returns {void} - * @private - */ - function checkForDanglingUnderscoreInMemberExpression(node) { - const identifier = node.property.name, - isMemberOfThis = node.object.type === "ThisExpression", - isMemberOfSuper = node.object.type === "Super", - isMemberOfThisConstructor = isThisConstructorReference(node); - - if (typeof identifier !== "undefined" && hasDanglingUnderscore(identifier) && - !(isMemberOfThis && allowAfterThis) && - !(isMemberOfSuper && allowAfterSuper) && - !(isMemberOfThisConstructor && allowAfterThisConstructor) && - !isSpecialCaseIdentifierForMemberExpression(identifier) && !isAllowed(identifier)) { - context.report({ - node, - messageId: "unexpectedUnderscore", - data: { - identifier - } - }); - } - } - - /** - * Check if method declaration or method property has a dangling underscore - * @param {ASTNode} node node to evaluate - * @returns {void} - * @private - */ - function checkForDanglingUnderscoreInMethod(node) { - const identifier = node.key.name; - const isMethod = node.type === "MethodDefinition" || node.type === "Property" && node.method; - - if (typeof identifier !== "undefined" && enforceInMethodNames && isMethod && hasDanglingUnderscore(identifier) && !isAllowed(identifier)) { - context.report({ - node, - messageId: "unexpectedUnderscore", - data: { - identifier - } - }); - } - } - - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- - - return { - FunctionDeclaration: checkForDanglingUnderscoreInFunction, - VariableDeclarator: checkForDanglingUnderscoreInVariableExpression, - MemberExpression: checkForDanglingUnderscoreInMemberExpression, - MethodDefinition: checkForDanglingUnderscoreInMethod, - Property: checkForDanglingUnderscoreInMethod, - FunctionExpression: checkForDanglingUnderscoreInFunction, - ArrowFunctionExpression: checkForDanglingUnderscoreInFunction - }; - - } -}; - -/** - * @fileoverview Rule to spot scenarios where a newline looks like it is ending a statement, but is not. - * @author Glen Mailer - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUnexpectedMultiline = { - meta: { - type: "problem", - - docs: { - description: "disallow confusing multiline expressions", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-unexpected-multiline" - }, - - schema: [], - messages: { - function: "Unexpected newline between function and ( of function call.", - property: "Unexpected newline between object and [ of property access.", - taggedTemplate: "Unexpected newline between template tag and template literal.", - division: "Unexpected newline between numerator and division operator." - } - }, - - create(context) { - - const REGEX_FLAG_MATCHER = /^[gimsuy]+$/u; - - const sourceCode = context.getSourceCode(); - - /** - * Check to see if there is a newline between the node and the following open bracket - * line's expression - * @param {ASTNode} node The node to check. - * @param {string} messageId The error messageId to use. - * @returns {void} - * @private - */ - function checkForBreakAfter(node, messageId) { - const openParen = sourceCode.getTokenAfter(node, astUtils.isNotClosingParenToken); - const nodeExpressionEnd = sourceCode.getTokenBefore(openParen); - - if (openParen.loc.start.line !== nodeExpressionEnd.loc.end.line) { - context.report({ - node, - loc: openParen.loc, - messageId - }); - } - } - - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- - - return { - - MemberExpression(node) { - if (!node.computed || node.optional) { - return; - } - checkForBreakAfter(node.object, "property"); - }, - - TaggedTemplateExpression(node) { - const { quasi } = node; - - // handles common tags, parenthesized tags, and typescript's generic type arguments - const tokenBefore = sourceCode.getTokenBefore(quasi); - - if (tokenBefore.loc.end.line !== quasi.loc.start.line) { - context.report({ - node, - loc: { - start: quasi.loc.start, - end: { - line: quasi.loc.start.line, - column: quasi.loc.start.column + 1 - } - }, - messageId: "taggedTemplate" - }); - } - }, - - CallExpression(node) { - if (node.arguments.length === 0 || node.optional) { - return; - } - checkForBreakAfter(node.callee, "function"); - }, - - "BinaryExpression[operator='/'] > BinaryExpression[operator='/'].left"(node) { - const secondSlash = sourceCode.getTokenAfter(node, token => token.value === "/"); - const tokenAfterOperator = sourceCode.getTokenAfter(secondSlash); - - if ( - tokenAfterOperator.type === "Identifier" && - REGEX_FLAG_MATCHER.test(tokenAfterOperator.value) && - secondSlash.range[1] === tokenAfterOperator.range[0] - ) { - checkForBreakAfter(node.left, "division"); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to disallow use of unmodified expressions in loop conditions - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const SENTINEL_PATTERN = /(?:(?:Call|Class|Function|Member|New|Yield)Expression|Statement|Declaration)$/u; -const LOOP_PATTERN = /^(?:DoWhile|For|While)Statement$/u; // for-in/of statements don't have `test` property. -const GROUP_PATTERN = /^(?:BinaryExpression|ConditionalExpression)$/u; -const SKIP_PATTERN = /^(?:ArrowFunction|Class|Function)Expression$/u; -const DYNAMIC_PATTERN = /^(?:Call|Member|New|TaggedTemplate|Yield)Expression$/u; - -/** - * @typedef {Object} LoopConditionInfo - * @property {eslint-scope.Reference} reference - The reference. - * @property {ASTNode} group - BinaryExpression or ConditionalExpression nodes - * that the reference is belonging to. - * @property {Function} isInLoop - The predicate which checks a given reference - * is in this loop. - * @property {boolean} modified - The flag that the reference is modified in - * this loop. - */ - -/** - * Checks whether or not a given reference is a write reference. - * @param {eslint-scope.Reference} reference A reference to check. - * @returns {boolean} `true` if the reference is a write reference. - */ -function isWriteReference(reference) { - if (reference.init) { - const def = reference.resolved && reference.resolved.defs[0]; - - if (!def || def.type !== "Variable" || def.parent.kind !== "var") { - return false; - } - } - return reference.isWrite(); -} - -/** - * Checks whether or not a given loop condition info does not have the modified - * flag. - * @param {LoopConditionInfo} condition A loop condition info to check. - * @returns {boolean} `true` if the loop condition info is "unmodified". - */ -function isUnmodified(condition) { - return !condition.modified; -} - -/** - * Checks whether or not a given loop condition info does not have the modified - * flag and does not have the group this condition belongs to. - * @param {LoopConditionInfo} condition A loop condition info to check. - * @returns {boolean} `true` if the loop condition info is "unmodified". - */ -function isUnmodifiedAndNotBelongToGroup(condition) { - return !(condition.modified || condition.group); -} - -/** - * Checks whether or not a given reference is inside of a given node. - * @param {ASTNode} node A node to check. - * @param {eslint-scope.Reference} reference A reference to check. - * @returns {boolean} `true` if the reference is inside of the node. - */ -function isInRange$1(node, reference) { - const or = node.range; - const ir = reference.identifier.range; - - return or[0] <= ir[0] && ir[1] <= or[1]; -} - -/** - * Checks whether or not a given reference is inside of a loop node's condition. - * @param {ASTNode} node A node to check. - * @param {eslint-scope.Reference} reference A reference to check. - * @returns {boolean} `true` if the reference is inside of the loop node's - * condition. - */ -const isInLoop = { - WhileStatement: isInRange$1, - DoWhileStatement: isInRange$1, - ForStatement(node, reference) { - return ( - isInRange$1(node, reference) && - !(node.init && isInRange$1(node.init, reference)) - ); - } -}; - -/** - * Gets the function which encloses a given reference. - * This supports only FunctionDeclaration. - * @param {eslint-scope.Reference} reference A reference to get. - * @returns {ASTNode|null} The function node or null. - */ -function getEncloseFunctionDeclaration(reference) { - let node = reference.identifier; - - while (node) { - if (node.type === "FunctionDeclaration") { - return node.id ? node : null; - } - - node = node.parent; - } - - return null; -} - -/** - * Updates the "modified" flags of given loop conditions with given modifiers. - * @param {LoopConditionInfo[]} conditions The loop conditions to be updated. - * @param {eslint-scope.Reference[]} modifiers The references to update. - * @returns {void} - */ -function updateModifiedFlag(conditions, modifiers) { - - for (let i = 0; i < conditions.length; ++i) { - const condition = conditions[i]; - - for (let j = 0; !condition.modified && j < modifiers.length; ++j) { - const modifier = modifiers[j]; - let funcNode, funcVar; - - /* - * Besides checking for the condition being in the loop, we want to - * check the function that this modifier is belonging to is called - * in the loop. - * FIXME: This should probably be extracted to a function. - */ - const inLoop = condition.isInLoop(modifier) || Boolean( - (funcNode = getEncloseFunctionDeclaration(modifier)) && - (funcVar = astUtils.getVariableByName(modifier.from.upper, funcNode.id.name)) && - funcVar.references.some(condition.isInLoop) - ); - - condition.modified = inLoop; - } - } -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUnmodifiedLoopCondition = { - meta: { - type: "problem", - - docs: { - description: "disallow unmodified loop conditions", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-unmodified-loop-condition" - }, - - schema: [], - - messages: { - loopConditionNotModified: "'{{name}}' is not modified in this loop." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - let groupMap = null; - - /** - * Reports a given condition info. - * @param {LoopConditionInfo} condition A loop condition info to report. - * @returns {void} - */ - function report(condition) { - const node = condition.reference.identifier; - - context.report({ - node, - messageId: "loopConditionNotModified", - data: node - }); - } - - /** - * Registers given conditions to the group the condition belongs to. - * @param {LoopConditionInfo[]} conditions A loop condition info to - * register. - * @returns {void} - */ - function registerConditionsToGroup(conditions) { - for (let i = 0; i < conditions.length; ++i) { - const condition = conditions[i]; - - if (condition.group) { - let group = groupMap.get(condition.group); - - if (!group) { - group = []; - groupMap.set(condition.group, group); - } - group.push(condition); - } - } - } - - /** - * Reports references which are inside of unmodified groups. - * @param {LoopConditionInfo[]} conditions A loop condition info to report. - * @returns {void} - */ - function checkConditionsInGroup(conditions) { - if (conditions.every(isUnmodified)) { - conditions.forEach(report); - } - } - - /** - * Checks whether or not a given group node has any dynamic elements. - * @param {ASTNode} root A node to check. - * This node is one of BinaryExpression or ConditionalExpression. - * @returns {boolean} `true` if the node is dynamic. - */ - function hasDynamicExpressions(root) { - let retv = false; - - traverser.traverse(root, { - visitorKeys: sourceCode.visitorKeys, - enter(node) { - if (DYNAMIC_PATTERN.test(node.type)) { - retv = true; - this.break(); - } else if (SKIP_PATTERN.test(node.type)) { - this.skip(); - } - } - }); - - return retv; - } - - /** - * Creates the loop condition information from a given reference. - * @param {eslint-scope.Reference} reference A reference to create. - * @returns {LoopConditionInfo|null} Created loop condition info, or null. - */ - function toLoopCondition(reference) { - if (reference.init) { - return null; - } - - let group = null; - let child = reference.identifier; - let node = child.parent; - - while (node) { - if (SENTINEL_PATTERN.test(node.type)) { - if (LOOP_PATTERN.test(node.type) && node.test === child) { - - // This reference is inside of a loop condition. - return { - reference, - group, - isInLoop: isInLoop[node.type].bind(null, node), - modified: false - }; - } - - // This reference is outside of a loop condition. - break; - } - - /* - * If it's inside of a group, OK if either operand is modified. - * So stores the group this reference belongs to. - */ - if (GROUP_PATTERN.test(node.type)) { - - // If this expression is dynamic, no need to check. - if (hasDynamicExpressions(node)) { - break; - } else { - group = node; - } - } - - child = node; - node = node.parent; - } - - return null; - } - - /** - * Finds unmodified references which are inside of a loop condition. - * Then reports the references which are outside of groups. - * @param {eslint-scope.Variable} variable A variable to report. - * @returns {void} - */ - function checkReferences(variable) { - - // Gets references that exist in loop conditions. - const conditions = variable - .references - .map(toLoopCondition) - .filter(Boolean); - - if (conditions.length === 0) { - return; - } - - // Registers the conditions to belonging groups. - registerConditionsToGroup(conditions); - - // Check the conditions are modified. - const modifiers = variable.references.filter(isWriteReference); - - if (modifiers.length > 0) { - updateModifiedFlag(conditions, modifiers); - } - - /* - * Reports the conditions which are not belonging to groups. - * Others will be reported after all variables are done. - */ - conditions - .filter(isUnmodifiedAndNotBelongToGroup) - .forEach(report); - } - - return { - "Program:exit"() { - const queue = [context.getScope()]; - - groupMap = new Map(); - - let scope; - - while ((scope = queue.pop())) { - queue.push(...scope.childScopes); - scope.variables.forEach(checkReferences); - } - - groupMap.forEach(checkConditionsInGroup); - groupMap = null; - } - }; - } -}; - -/** - * @fileoverview Rule to flag no-unneeded-ternary - * @author Gyandeep Singh - */ - - - -// Operators that always result in a boolean value -const BOOLEAN_OPERATORS = new Set(["==", "===", "!=", "!==", ">", ">=", "<", "<=", "in", "instanceof"]); -const OPERATOR_INVERSES = { - "==": "!=", - "!=": "==", - "===": "!==", - "!==": "===" - - // Operators like < and >= are not true inverses, since both will return false with NaN. -}; -const OR_PRECEDENCE = astUtils.getPrecedence({ type: "LogicalExpression", operator: "||" }); - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUnneededTernary = { - meta: { - type: "suggestion", - - docs: { - description: "disallow ternary operators when simpler alternatives exist", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/no-unneeded-ternary" - }, - - schema: [ - { - type: "object", - properties: { - defaultAssignment: { - type: "boolean", - default: true - } - }, - additionalProperties: false - } - ], - - fixable: "code", - - messages: { - unnecessaryConditionalExpression: "Unnecessary use of boolean literals in conditional expression.", - unnecessaryConditionalAssignment: "Unnecessary use of conditional expression for default assignment." - } - }, - - create(context) { - const options = context.options[0] || {}; - const defaultAssignment = options.defaultAssignment !== false; - const sourceCode = context.getSourceCode(); - - /** - * Test if the node is a boolean literal - * @param {ASTNode} node The node to report. - * @returns {boolean} True if the its a boolean literal - * @private - */ - function isBooleanLiteral(node) { - return node.type === "Literal" && typeof node.value === "boolean"; - } - - /** - * Creates an expression that represents the boolean inverse of the expression represented by the original node - * @param {ASTNode} node A node representing an expression - * @returns {string} A string representing an inverted expression - */ - function invertExpression(node) { - if (node.type === "BinaryExpression" && Object.prototype.hasOwnProperty.call(OPERATOR_INVERSES, node.operator)) { - const operatorToken = sourceCode.getFirstTokenBetween( - node.left, - node.right, - token => token.value === node.operator - ); - const text = sourceCode.getText(); - - return text.slice(node.range[0], - operatorToken.range[0]) + OPERATOR_INVERSES[node.operator] + text.slice(operatorToken.range[1], node.range[1]); - } - - if (astUtils.getPrecedence(node) < astUtils.getPrecedence({ type: "UnaryExpression" })) { - return `!(${astUtils.getParenthesisedText(sourceCode, node)})`; - } - return `!${astUtils.getParenthesisedText(sourceCode, node)}`; - } - - /** - * Tests if a given node always evaluates to a boolean value - * @param {ASTNode} node An expression node - * @returns {boolean} True if it is determined that the node will always evaluate to a boolean value - */ - function isBooleanExpression(node) { - return node.type === "BinaryExpression" && BOOLEAN_OPERATORS.has(node.operator) || - node.type === "UnaryExpression" && node.operator === "!"; - } - - /** - * Test if the node matches the pattern id ? id : expression - * @param {ASTNode} node The ConditionalExpression to check. - * @returns {boolean} True if the pattern is matched, and false otherwise - * @private - */ - function matchesDefaultAssignment(node) { - return node.test.type === "Identifier" && - node.consequent.type === "Identifier" && - node.test.name === node.consequent.name; - } - - return { - - ConditionalExpression(node) { - if (isBooleanLiteral(node.alternate) && isBooleanLiteral(node.consequent)) { - context.report({ - node, - messageId: "unnecessaryConditionalExpression", - fix(fixer) { - if (node.consequent.value === node.alternate.value) { - - // Replace `foo ? true : true` with just `true`, but don't replace `foo() ? true : true` - return node.test.type === "Identifier" ? fixer.replaceText(node, node.consequent.value.toString()) : null; - } - if (node.alternate.value) { - - // Replace `foo() ? false : true` with `!(foo())` - return fixer.replaceText(node, invertExpression(node.test)); - } - - // Replace `foo ? true : false` with `foo` if `foo` is guaranteed to be a boolean, or `!!foo` otherwise. - - return fixer.replaceText(node, isBooleanExpression(node.test) ? astUtils.getParenthesisedText(sourceCode, node.test) : `!${invertExpression(node.test)}`); - } - }); - } else if (!defaultAssignment && matchesDefaultAssignment(node)) { - context.report({ - node, - messageId: "unnecessaryConditionalAssignment", - fix: fixer => { - const shouldParenthesizeAlternate = - ( - astUtils.getPrecedence(node.alternate) < OR_PRECEDENCE || - astUtils.isCoalesceExpression(node.alternate) - ) && - !astUtils.isParenthesised(sourceCode, node.alternate); - const alternateText = shouldParenthesizeAlternate - ? `(${sourceCode.getText(node.alternate)})` - : astUtils.getParenthesisedText(sourceCode, node.alternate); - const testText = astUtils.getParenthesisedText(sourceCode, node.test); - - return fixer.replaceText(node, `${testText} || ${alternateText}`); - } - }); - } - } - }; - } -}; - -/** - * @fileoverview Checks for unreachable code due to return, throws, break, and continue. - * @author Joel Feenstra - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether or not a given variable declarator has the initializer. - * @param {ASTNode} node A VariableDeclarator node to check. - * @returns {boolean} `true` if the node has the initializer. - */ -function isInitialized(node) { - return Boolean(node.init); -} - -/** - * Checks whether or not a given code path segment is unreachable. - * @param {CodePathSegment} segment A CodePathSegment to check. - * @returns {boolean} `true` if the segment is unreachable. - */ -function isUnreachable(segment) { - return !segment.reachable; -} - -/** - * The class to distinguish consecutive unreachable statements. - */ -class ConsecutiveRange { - constructor(sourceCode) { - this.sourceCode = sourceCode; - this.startNode = null; - this.endNode = null; - } - - /** - * The location object of this range. - * @type {Object} - */ - get location() { - return { - start: this.startNode.loc.start, - end: this.endNode.loc.end - }; - } - - /** - * `true` if this range is empty. - * @type {boolean} - */ - get isEmpty() { - return !(this.startNode && this.endNode); - } - - /** - * Checks whether the given node is inside of this range. - * @param {ASTNode|Token} node The node to check. - * @returns {boolean} `true` if the node is inside of this range. - */ - contains(node) { - return ( - node.range[0] >= this.startNode.range[0] && - node.range[1] <= this.endNode.range[1] - ); - } - - /** - * Checks whether the given node is consecutive to this range. - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if the node is consecutive to this range. - */ - isConsecutive(node) { - return this.contains(this.sourceCode.getTokenBefore(node)); - } - - /** - * Merges the given node to this range. - * @param {ASTNode} node The node to merge. - * @returns {void} - */ - merge(node) { - this.endNode = node; - } - - /** - * Resets this range by the given node or null. - * @param {ASTNode|null} node The node to reset, or null. - * @returns {void} - */ - reset(node) { - this.startNode = this.endNode = node; - } -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUnreachable = { - meta: { - type: "problem", - - docs: { - description: "disallow unreachable code after `return`, `throw`, `continue`, and `break` statements", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-unreachable" - }, - - schema: [], - - messages: { - unreachableCode: "Unreachable code." - } - }, - - create(context) { - let currentCodePath = null; - - const range = new ConsecutiveRange(context.getSourceCode()); - - /** - * Reports a given node if it's unreachable. - * @param {ASTNode} node A statement node to report. - * @returns {void} - */ - function reportIfUnreachable(node) { - let nextNode = null; - - if (node && currentCodePath.currentSegments.every(isUnreachable)) { - - // Store this statement to distinguish consecutive statements. - if (range.isEmpty) { - range.reset(node); - return; - } - - // Skip if this statement is inside of the current range. - if (range.contains(node)) { - return; - } - - // Merge if this statement is consecutive to the current range. - if (range.isConsecutive(node)) { - range.merge(node); - return; - } - - nextNode = node; - } - - /* - * Report the current range since this statement is reachable or is - * not consecutive to the current range. - */ - if (!range.isEmpty) { - context.report({ - messageId: "unreachableCode", - loc: range.location, - node: range.startNode - }); - } - - // Update the current range. - range.reset(nextNode); - } - - return { - - // Manages the current code path. - onCodePathStart(codePath) { - currentCodePath = codePath; - }, - - onCodePathEnd() { - currentCodePath = currentCodePath.upper; - }, - - // Registers for all statement nodes (excludes FunctionDeclaration). - BlockStatement: reportIfUnreachable, - BreakStatement: reportIfUnreachable, - ClassDeclaration: reportIfUnreachable, - ContinueStatement: reportIfUnreachable, - DebuggerStatement: reportIfUnreachable, - DoWhileStatement: reportIfUnreachable, - ExpressionStatement: reportIfUnreachable, - ForInStatement: reportIfUnreachable, - ForOfStatement: reportIfUnreachable, - ForStatement: reportIfUnreachable, - IfStatement: reportIfUnreachable, - ImportDeclaration: reportIfUnreachable, - LabeledStatement: reportIfUnreachable, - ReturnStatement: reportIfUnreachable, - SwitchStatement: reportIfUnreachable, - ThrowStatement: reportIfUnreachable, - TryStatement: reportIfUnreachable, - - VariableDeclaration(node) { - if (node.kind !== "var" || node.declarations.some(isInitialized)) { - reportIfUnreachable(node); - } - }, - - WhileStatement: reportIfUnreachable, - WithStatement: reportIfUnreachable, - ExportNamedDeclaration: reportIfUnreachable, - ExportDefaultDeclaration: reportIfUnreachable, - ExportAllDeclaration: reportIfUnreachable, - - "Program:exit"() { - reportIfUnreachable(); - } - }; - } -}; - -/** - * @fileoverview Rule to disallow loops with a body that allows only one iteration - * @author Milos Djermanovic - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const allLoopTypes = ["WhileStatement", "DoWhileStatement", "ForStatement", "ForInStatement", "ForOfStatement"]; - -/** - * Determines whether the given node is the first node in the code path to which a loop statement - * 'loops' for the next iteration. - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if the node is a looping target. - */ -function isLoopingTarget(node) { - const parent = node.parent; - - if (parent) { - switch (parent.type) { - case "WhileStatement": - return node === parent.test; - case "DoWhileStatement": - return node === parent.body; - case "ForStatement": - return node === (parent.update || parent.test || parent.body); - case "ForInStatement": - case "ForOfStatement": - return node === parent.left; - - // no default - } - } - - return false; -} - -/** - * Creates an array with elements from the first given array that are not included in the second given array. - * @param {Array} arrA The array to compare from. - * @param {Array} arrB The array to compare against. - * @returns {Array} a new array that represents `arrA \ arrB`. - */ -function getDifference(arrA, arrB) { - return arrA.filter(a => !arrB.includes(a)); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUnreachableLoop = { - meta: { - type: "problem", - - docs: { - description: "disallow loops with a body that allows only one iteration", - category: "Possible Errors", - recommended: false, - url: "https://eslint.org/docs/rules/no-unreachable-loop" - }, - - schema: [{ - type: "object", - properties: { - ignore: { - type: "array", - items: { - enum: allLoopTypes - }, - uniqueItems: true - } - }, - additionalProperties: false - }], - - messages: { - invalid: "Invalid loop. Its body allows only one iteration." - } - }, - - create(context) { - const ignoredLoopTypes = context.options[0] && context.options[0].ignore || [], - loopTypesToCheck = getDifference(allLoopTypes, ignoredLoopTypes), - loopSelector = loopTypesToCheck.join(","), - loopsByTargetSegments = new Map(), - loopsToReport = new Set(); - - let currentCodePath = null; - - return { - onCodePathStart(codePath) { - currentCodePath = codePath; - }, - - onCodePathEnd() { - currentCodePath = currentCodePath.upper; - }, - - [loopSelector](node) { - - /** - * Ignore unreachable loop statements to avoid unnecessary complexity in the implementation, or false positives otherwise. - * For unreachable segments, the code path analysis does not raise events required for this implementation. - */ - if (currentCodePath.currentSegments.some(segment => segment.reachable)) { - loopsToReport.add(node); - } - }, - - onCodePathSegmentStart(segment, node) { - if (isLoopingTarget(node)) { - const loop = node.parent; - - loopsByTargetSegments.set(segment, loop); - } - }, - - onCodePathSegmentLoop(_, toSegment, node) { - const loop = loopsByTargetSegments.get(toSegment); - - /** - * The second iteration is reachable, meaning that the loop is valid by the logic of this rule, - * only if there is at least one loop event with the appropriate target (which has been already - * determined in the `loopsByTargetSegments` map), raised from either: - * - * - the end of the loop's body (in which case `node === loop`) - * - a `continue` statement - * - * This condition skips loop events raised from `ForInStatement > .right` and `ForOfStatement > .right` nodes. - */ - if (node === loop || node.type === "ContinueStatement") { - - // Removes loop if it exists in the set. Otherwise, `Set#delete` has no effect and doesn't throw. - loopsToReport.delete(loop); - } - }, - - "Program:exit"() { - loopsToReport.forEach( - node => context.report({ node, messageId: "invalid" }) - ); - } - }; - } -}; - -/** - * @fileoverview Rule to flag unsafe statements in finally block - * @author Onur Temizkan - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const SENTINEL_NODE_TYPE_RETURN_THROW = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression)$/u; -const SENTINEL_NODE_TYPE_BREAK = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|DoWhileStatement|WhileStatement|ForOfStatement|ForInStatement|ForStatement|SwitchStatement)$/u; -const SENTINEL_NODE_TYPE_CONTINUE = /^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|DoWhileStatement|WhileStatement|ForOfStatement|ForInStatement|ForStatement)$/u; - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUnsafeFinally = { - meta: { - type: "problem", - - docs: { - description: "disallow control flow statements in `finally` blocks", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-unsafe-finally" - }, - - schema: [], - - messages: { - unsafeUsage: "Unsafe usage of {{nodeType}}." - } - }, - create(context) { - - /** - * Checks if the node is the finalizer of a TryStatement - * @param {ASTNode} node node to check. - * @returns {boolean} - true if the node is the finalizer of a TryStatement - */ - function isFinallyBlock(node) { - return node.parent.type === "TryStatement" && node.parent.finalizer === node; - } - - /** - * Climbs up the tree if the node is not a sentinel node - * @param {ASTNode} node node to check. - * @param {string} label label of the break or continue statement - * @returns {boolean} - return whether the node is a finally block or a sentinel node - */ - function isInFinallyBlock(node, label) { - let labelInside = false; - let sentinelNodeType; - - if (node.type === "BreakStatement" && !node.label) { - sentinelNodeType = SENTINEL_NODE_TYPE_BREAK; - } else if (node.type === "ContinueStatement") { - sentinelNodeType = SENTINEL_NODE_TYPE_CONTINUE; - } else { - sentinelNodeType = SENTINEL_NODE_TYPE_RETURN_THROW; - } - - for ( - let currentNode = node; - currentNode && !sentinelNodeType.test(currentNode.type); - currentNode = currentNode.parent - ) { - if (currentNode.parent.label && label && (currentNode.parent.label.name === label.name)) { - labelInside = true; - } - if (isFinallyBlock(currentNode)) { - if (label && labelInside) { - return false; - } - return true; - } - } - return false; - } - - /** - * Checks whether the possibly-unsafe statement is inside a finally block. - * @param {ASTNode} node node to check. - * @returns {void} - */ - function check(node) { - if (isInFinallyBlock(node, node.label)) { - context.report({ - messageId: "unsafeUsage", - data: { - nodeType: node.type - }, - node, - line: node.loc.line, - column: node.loc.column - }); - } - } - - return { - ReturnStatement: check, - ThrowStatement: check, - BreakStatement: check, - ContinueStatement: check - }; - } -}; - -/** - * @fileoverview Rule to disallow negating the left operand of relational operators - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether the given operator is `in` or `instanceof` - * @param {string} op The operator type to check. - * @returns {boolean} `true` if the operator is `in` or `instanceof` - */ -function isInOrInstanceOfOperator(op) { - return op === "in" || op === "instanceof"; -} - -/** - * Checks whether the given operator is an ordering relational operator or not. - * @param {string} op The operator type to check. - * @returns {boolean} `true` if the operator is an ordering relational operator. - */ -function isOrderingRelationalOperator(op) { - return op === "<" || op === ">" || op === ">=" || op === "<="; -} - -/** - * Checks whether the given node is a logical negation expression or not. - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if the node is a logical negation expression. - */ -function isNegation(node) { - return node.type === "UnaryExpression" && node.operator === "!"; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUnsafeNegation = { - meta: { - type: "problem", - - docs: { - description: "disallow negating the left operand of relational operators", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/no-unsafe-negation", - suggestion: true - }, - - schema: [ - { - type: "object", - properties: { - enforceForOrderingRelations: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - fixable: null, - - messages: { - unexpected: "Unexpected negating the left operand of '{{operator}}' operator.", - suggestNegatedExpression: "Negate '{{operator}}' expression instead of its left operand. This changes the current behavior.", - suggestParenthesisedNegation: "Wrap negation in '()' to make the intention explicit. This preserves the current behavior." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const options = context.options[0] || {}; - const enforceForOrderingRelations = options.enforceForOrderingRelations === true; - - return { - BinaryExpression(node) { - const operator = node.operator; - const orderingRelationRuleApplies = enforceForOrderingRelations && isOrderingRelationalOperator(operator); - - if ( - (isInOrInstanceOfOperator(operator) || orderingRelationRuleApplies) && - isNegation(node.left) && - !astUtils.isParenthesised(sourceCode, node.left) - ) { - context.report({ - node, - loc: node.left.loc, - messageId: "unexpected", - data: { operator }, - suggest: [ - { - messageId: "suggestNegatedExpression", - data: { operator }, - fix(fixer) { - const negationToken = sourceCode.getFirstToken(node.left); - const fixRange = [negationToken.range[1], node.range[1]]; - const text = sourceCode.text.slice(fixRange[0], fixRange[1]); - - return fixer.replaceTextRange(fixRange, `(${text})`); - } - }, - { - messageId: "suggestParenthesisedNegation", - fix(fixer) { - return fixer.replaceText(node.left, `(${sourceCode.getText(node.left)})`); - } - } - ] - }); - } - } - }; - } -}; - -/** - * @fileoverview Rule to disallow unsafe optional chaining - * @author Yeon JuAn - */ - -const UNSAFE_ARITHMETIC_OPERATORS = new Set(["+", "-", "/", "*", "%", "**"]); -const UNSAFE_ASSIGNMENT_OPERATORS = new Set(["+=", "-=", "/=", "*=", "%=", "**="]); -const UNSAFE_RELATIONAL_OPERATORS = new Set(["in", "instanceof"]); - -/** - * Checks whether a node is a destructuring pattern or not - * @param {ASTNode} node node to check - * @returns {boolean} `true` if a node is a destructuring pattern, otherwise `false` - */ -function isDestructuringPattern(node) { - return node.type === "ObjectPattern" || node.type === "ArrayPattern"; -} - -var noUnsafeOptionalChaining = { - meta: { - type: "problem", - - docs: { - description: "disallow use of optional chaining in contexts where the `undefined` value is not allowed", - category: "Possible Errors", - recommended: false, - url: "https://eslint.org/docs/rules/no-unsafe-optional-chaining" - }, - schema: [{ - type: "object", - properties: { - disallowArithmeticOperators: { - type: "boolean", - default: false - } - }, - additionalProperties: false - }], - fixable: null, - messages: { - unsafeOptionalChain: "Unsafe usage of optional chaining. If it short-circuits with 'undefined' the evaluation will throw TypeError.", - unsafeArithmetic: "Unsafe arithmetic operation on optional chaining. It can result in NaN." - } - }, - - create(context) { - const options = context.options[0] || {}; - const disallowArithmeticOperators = (options.disallowArithmeticOperators) || false; - - /** - * Reports unsafe usage of optional chaining - * @param {ASTNode} node node to report - * @returns {void} - */ - function reportUnsafeUsage(node) { - context.report({ - messageId: "unsafeOptionalChain", - node - }); - } - - /** - * Reports unsafe arithmetic operation on optional chaining - * @param {ASTNode} node node to report - * @returns {void} - */ - function reportUnsafeArithmetic(node) { - context.report({ - messageId: "unsafeArithmetic", - node - }); - } - - /** - * Checks and reports if a node can short-circuit with `undefined` by optional chaining. - * @param {ASTNode} [node] node to check - * @param {Function} reportFunc report function - * @returns {void} - */ - function checkUndefinedShortCircuit(node, reportFunc) { - if (!node) { - return; - } - switch (node.type) { - case "LogicalExpression": - if (node.operator === "||" || node.operator === "??") { - checkUndefinedShortCircuit(node.right, reportFunc); - } else if (node.operator === "&&") { - checkUndefinedShortCircuit(node.left, reportFunc); - checkUndefinedShortCircuit(node.right, reportFunc); - } - break; - case "SequenceExpression": - checkUndefinedShortCircuit( - node.expressions[node.expressions.length - 1], - reportFunc - ); - break; - case "ConditionalExpression": - checkUndefinedShortCircuit(node.consequent, reportFunc); - checkUndefinedShortCircuit(node.alternate, reportFunc); - break; - case "AwaitExpression": - checkUndefinedShortCircuit(node.argument, reportFunc); - break; - case "ChainExpression": - reportFunc(node); - break; - } - } - - /** - * Checks unsafe usage of optional chaining - * @param {ASTNode} node node to check - * @returns {void} - */ - function checkUnsafeUsage(node) { - checkUndefinedShortCircuit(node, reportUnsafeUsage); - } - - /** - * Checks unsafe arithmetic operations on optional chaining - * @param {ASTNode} node node to check - * @returns {void} - */ - function checkUnsafeArithmetic(node) { - checkUndefinedShortCircuit(node, reportUnsafeArithmetic); - } - - return { - "AssignmentExpression, AssignmentPattern"(node) { - if (isDestructuringPattern(node.left)) { - checkUnsafeUsage(node.right); - } - }, - "ClassDeclaration, ClassExpression"(node) { - checkUnsafeUsage(node.superClass); - }, - CallExpression(node) { - if (!node.optional) { - checkUnsafeUsage(node.callee); - } - }, - NewExpression(node) { - checkUnsafeUsage(node.callee); - }, - VariableDeclarator(node) { - if (isDestructuringPattern(node.id)) { - checkUnsafeUsage(node.init); - } - }, - MemberExpression(node) { - if (!node.optional) { - checkUnsafeUsage(node.object); - } - }, - TaggedTemplateExpression(node) { - checkUnsafeUsage(node.tag); - }, - ForOfStatement(node) { - checkUnsafeUsage(node.right); - }, - SpreadElement(node) { - if (node.parent && node.parent.type !== "ObjectExpression") { - checkUnsafeUsage(node.argument); - } - }, - BinaryExpression(node) { - if (UNSAFE_RELATIONAL_OPERATORS.has(node.operator)) { - checkUnsafeUsage(node.right); - } - if ( - disallowArithmeticOperators && - UNSAFE_ARITHMETIC_OPERATORS.has(node.operator) - ) { - checkUnsafeArithmetic(node.right); - checkUnsafeArithmetic(node.left); - } - }, - WithStatement(node) { - checkUnsafeUsage(node.object); - }, - UnaryExpression(node) { - if ( - disallowArithmeticOperators && - UNSAFE_ARITHMETIC_OPERATORS.has(node.operator) - ) { - checkUnsafeArithmetic(node.argument); - } - }, - AssignmentExpression(node) { - if ( - disallowArithmeticOperators && - UNSAFE_ASSIGNMENT_OPERATORS.has(node.operator) - ) { - checkUnsafeArithmetic(node.right); - } - } - }; - } -}; - -/** - * @fileoverview Flag expressions in statement position that do not side effect - * @author Michael Ficarra - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -/** - * Returns `true`. - * @returns {boolean} `true`. - */ -function alwaysTrue() { - return true; -} - -/** - * Returns `false`. - * @returns {boolean} `false`. - */ -function alwaysFalse() { - return false; -} - -var noUnusedExpressions = { - meta: { - type: "suggestion", - - docs: { - description: "disallow unused expressions", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-unused-expressions" - }, - - schema: [ - { - type: "object", - properties: { - allowShortCircuit: { - type: "boolean", - default: false - }, - allowTernary: { - type: "boolean", - default: false - }, - allowTaggedTemplates: { - type: "boolean", - default: false - }, - enforceForJSX: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - messages: { - unusedExpression: "Expected an assignment or function call and instead saw an expression." - } - }, - - create(context) { - const config = context.options[0] || {}, - allowShortCircuit = config.allowShortCircuit || false, - allowTernary = config.allowTernary || false, - allowTaggedTemplates = config.allowTaggedTemplates || false, - enforceForJSX = config.enforceForJSX || false; - - // eslint-disable-next-line jsdoc/require-description - /** - * @param {ASTNode} node any node - * @returns {boolean} whether the given node structurally represents a directive - */ - function looksLikeDirective(node) { - return node.type === "ExpressionStatement" && - node.expression.type === "Literal" && typeof node.expression.value === "string"; - } - - // eslint-disable-next-line jsdoc/require-description - /** - * @param {Function} predicate ([a] -> Boolean) the function used to make the determination - * @param {a[]} list the input list - * @returns {a[]} the leading sequence of members in the given list that pass the given predicate - */ - function takeWhile(predicate, list) { - for (let i = 0; i < list.length; ++i) { - if (!predicate(list[i])) { - return list.slice(0, i); - } - } - return list.slice(); - } - - // eslint-disable-next-line jsdoc/require-description - /** - * @param {ASTNode} node a Program or BlockStatement node - * @returns {ASTNode[]} the leading sequence of directive nodes in the given node's body - */ - function directives(node) { - return takeWhile(looksLikeDirective, node.body); - } - - // eslint-disable-next-line jsdoc/require-description - /** - * @param {ASTNode} node any node - * @param {ASTNode[]} ancestors the given node's ancestors - * @returns {boolean} whether the given node is considered a directive in its current position - */ - function isDirective(node, ancestors) { - const parent = ancestors[ancestors.length - 1], - grandparent = ancestors[ancestors.length - 2]; - - return (parent.type === "Program" || parent.type === "BlockStatement" && - (/Function/u.test(grandparent.type))) && - directives(parent).indexOf(node) >= 0; - } - - /** - * The member functions return `true` if the type has no side-effects. - * Unknown nodes are handled as `false`, then this rule ignores those. - */ - const Checker = Object.assign(Object.create(null), { - isDisallowed(node) { - return (Checker[node.type] || alwaysFalse)(node); - }, - - ArrayExpression: alwaysTrue, - ArrowFunctionExpression: alwaysTrue, - BinaryExpression: alwaysTrue, - ChainExpression(node) { - return Checker.isDisallowed(node.expression); - }, - ClassExpression: alwaysTrue, - ConditionalExpression(node) { - if (allowTernary) { - return Checker.isDisallowed(node.consequent) || Checker.isDisallowed(node.alternate); - } - return true; - }, - FunctionExpression: alwaysTrue, - Identifier: alwaysTrue, - JSXElement() { - return enforceForJSX; - }, - JSXFragment() { - return enforceForJSX; - }, - Literal: alwaysTrue, - LogicalExpression(node) { - if (allowShortCircuit) { - return Checker.isDisallowed(node.right); - } - return true; - }, - MemberExpression: alwaysTrue, - MetaProperty: alwaysTrue, - ObjectExpression: alwaysTrue, - SequenceExpression: alwaysTrue, - TaggedTemplateExpression() { - return !allowTaggedTemplates; - }, - TemplateLiteral: alwaysTrue, - ThisExpression: alwaysTrue, - UnaryExpression(node) { - return node.operator !== "void" && node.operator !== "delete"; - } - }); - - return { - ExpressionStatement(node) { - if (Checker.isDisallowed(node.expression) && !isDirective(node, context.getAncestors())) { - context.report({ node, messageId: "unusedExpression" }); - } - } - }; - } -}; - -/** - * @fileoverview Rule to disallow unused labels. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUnusedLabels = { - meta: { - type: "suggestion", - - docs: { - description: "disallow unused labels", - category: "Best Practices", - recommended: true, - url: "https://eslint.org/docs/rules/no-unused-labels" - }, - - schema: [], - - fixable: "code", - - messages: { - unused: "'{{name}}:' is defined but never used." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - let scopeInfo = null; - - /** - * Adds a scope info to the stack. - * @param {ASTNode} node A node to add. This is a LabeledStatement. - * @returns {void} - */ - function enterLabeledScope(node) { - scopeInfo = { - label: node.label.name, - used: false, - upper: scopeInfo - }; - } - - /** - * Removes the top of the stack. - * At the same time, this reports the label if it's never used. - * @param {ASTNode} node A node to report. This is a LabeledStatement. - * @returns {void} - */ - function exitLabeledScope(node) { - if (!scopeInfo.used) { - context.report({ - node: node.label, - messageId: "unused", - data: node.label, - fix(fixer) { - - /* - * Only perform a fix if there are no comments between the label and the body. This will be the case - * when there is exactly one token/comment (the ":") between the label and the body. - */ - if (sourceCode.getTokenAfter(node.label, { includeComments: true }) === - sourceCode.getTokenBefore(node.body, { includeComments: true })) { - return fixer.removeRange([node.range[0], node.body.range[0]]); - } - - return null; - } - }); - } - - scopeInfo = scopeInfo.upper; - } - - /** - * Marks the label of a given node as used. - * @param {ASTNode} node A node to mark. This is a BreakStatement or - * ContinueStatement. - * @returns {void} - */ - function markAsUsed(node) { - if (!node.label) { - return; - } - - const label = node.label.name; - let info = scopeInfo; - - while (info) { - if (info.label === label) { - info.used = true; - break; - } - info = info.upper; - } - } - - return { - LabeledStatement: enterLabeledScope, - "LabeledStatement:exit": exitLabeledScope, - BreakStatement: markAsUsed, - ContinueStatement: markAsUsed - }; - } -}; - -/** - * @fileoverview Rule to flag declared but unused variables - * @author Ilya Volodin - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Typedefs -//------------------------------------------------------------------------------ - -/** - * Bag of data used for formatting the `unusedVar` lint message. - * @typedef {Object} UnusedVarMessageData - * @property {string} varName The name of the unused var. - * @property {'defined'|'assigned a value'} action Description of the vars state. - * @property {string} additional Any additional info to be appended at the end. - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUnusedVars = { - meta: { - type: "problem", - - docs: { - description: "disallow unused variables", - category: "Variables", - recommended: true, - url: "https://eslint.org/docs/rules/no-unused-vars" - }, - - schema: [ - { - oneOf: [ - { - enum: ["all", "local"] - }, - { - type: "object", - properties: { - vars: { - enum: ["all", "local"] - }, - varsIgnorePattern: { - type: "string" - }, - args: { - enum: ["all", "after-used", "none"] - }, - ignoreRestSiblings: { - type: "boolean" - }, - argsIgnorePattern: { - type: "string" - }, - caughtErrors: { - enum: ["all", "none"] - }, - caughtErrorsIgnorePattern: { - type: "string" - } - }, - additionalProperties: false - } - ] - } - ], - - messages: { - unusedVar: "'{{varName}}' is {{action}} but never used{{additional}}." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - const REST_PROPERTY_TYPE = /^(?:RestElement|(?:Experimental)?RestProperty)$/u; - - const config = { - vars: "all", - args: "after-used", - ignoreRestSiblings: false, - caughtErrors: "none" - }; - - const firstOption = context.options[0]; - - if (firstOption) { - if (typeof firstOption === "string") { - config.vars = firstOption; - } else { - config.vars = firstOption.vars || config.vars; - config.args = firstOption.args || config.args; - config.ignoreRestSiblings = firstOption.ignoreRestSiblings || config.ignoreRestSiblings; - config.caughtErrors = firstOption.caughtErrors || config.caughtErrors; - - if (firstOption.varsIgnorePattern) { - config.varsIgnorePattern = new RegExp(firstOption.varsIgnorePattern, "u"); - } - - if (firstOption.argsIgnorePattern) { - config.argsIgnorePattern = new RegExp(firstOption.argsIgnorePattern, "u"); - } - - if (firstOption.caughtErrorsIgnorePattern) { - config.caughtErrorsIgnorePattern = new RegExp(firstOption.caughtErrorsIgnorePattern, "u"); - } - } - } - - /** - * Generates the message data about the variable being defined and unused, - * including the ignore pattern if configured. - * @param {Variable} unusedVar eslint-scope variable object. - * @returns {UnusedVarMessageData} The message data to be used with this unused variable. - */ - function getDefinedMessageData(unusedVar) { - const defType = unusedVar.defs && unusedVar.defs[0] && unusedVar.defs[0].type; - let type; - let pattern; - - if (defType === "CatchClause" && config.caughtErrorsIgnorePattern) { - type = "args"; - pattern = config.caughtErrorsIgnorePattern.toString(); - } else if (defType === "Parameter" && config.argsIgnorePattern) { - type = "args"; - pattern = config.argsIgnorePattern.toString(); - } else if (defType !== "Parameter" && config.varsIgnorePattern) { - type = "vars"; - pattern = config.varsIgnorePattern.toString(); - } - - const additional = type ? `. Allowed unused ${type} must match ${pattern}` : ""; - - return { - varName: unusedVar.name, - action: "defined", - additional - }; - } - - /** - * Generate the warning message about the variable being - * assigned and unused, including the ignore pattern if configured. - * @param {Variable} unusedVar eslint-scope variable object. - * @returns {UnusedVarMessageData} The message data to be used with this unused variable. - */ - function getAssignedMessageData(unusedVar) { - const additional = config.varsIgnorePattern ? `. Allowed unused vars must match ${config.varsIgnorePattern.toString()}` : ""; - - return { - varName: unusedVar.name, - action: "assigned a value", - additional - }; - } - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - const STATEMENT_TYPE = /(?:Statement|Declaration)$/u; - - /** - * Determines if a given variable is being exported from a module. - * @param {Variable} variable eslint-scope variable object. - * @returns {boolean} True if the variable is exported, false if not. - * @private - */ - function isExported(variable) { - - const definition = variable.defs[0]; - - if (definition) { - - let node = definition.node; - - if (node.type === "VariableDeclarator") { - node = node.parent; - } else if (definition.type === "Parameter") { - return false; - } - - return node.parent.type.indexOf("Export") === 0; - } - return false; - - } - - /** - * Checks whether a node is a sibling of the rest property or not. - * @param {ASTNode} node a node to check - * @returns {boolean} True if the node is a sibling of the rest property, otherwise false. - */ - function hasRestSibling(node) { - return node.type === "Property" && - node.parent.type === "ObjectPattern" && - REST_PROPERTY_TYPE.test(node.parent.properties[node.parent.properties.length - 1].type); - } - - /** - * Determines if a variable has a sibling rest property - * @param {Variable} variable eslint-scope variable object. - * @returns {boolean} True if the variable is exported, false if not. - * @private - */ - function hasRestSpreadSibling(variable) { - if (config.ignoreRestSiblings) { - const hasRestSiblingDefinition = variable.defs.some(def => hasRestSibling(def.name.parent)); - const hasRestSiblingReference = variable.references.some(ref => hasRestSibling(ref.identifier.parent)); - - return hasRestSiblingDefinition || hasRestSiblingReference; - } - - return false; - } - - /** - * Determines if a reference is a read operation. - * @param {Reference} ref An eslint-scope Reference - * @returns {boolean} whether the given reference represents a read operation - * @private - */ - function isReadRef(ref) { - return ref.isRead(); - } - - /** - * Determine if an identifier is referencing an enclosing function name. - * @param {Reference} ref The reference to check. - * @param {ASTNode[]} nodes The candidate function nodes. - * @returns {boolean} True if it's a self-reference, false if not. - * @private - */ - function isSelfReference(ref, nodes) { - let scope = ref.from; - - while (scope) { - if (nodes.indexOf(scope.block) >= 0) { - return true; - } - - scope = scope.upper; - } - - return false; - } - - /** - * Gets a list of function definitions for a specified variable. - * @param {Variable} variable eslint-scope variable object. - * @returns {ASTNode[]} Function nodes. - * @private - */ - function getFunctionDefinitions(variable) { - const functionDefinitions = []; - - variable.defs.forEach(def => { - const { type, node } = def; - - // FunctionDeclarations - if (type === "FunctionName") { - functionDefinitions.push(node); - } - - // FunctionExpressions - if (type === "Variable" && node.init && - (node.init.type === "FunctionExpression" || node.init.type === "ArrowFunctionExpression")) { - functionDefinitions.push(node.init); - } - }); - return functionDefinitions; - } - - /** - * Checks the position of given nodes. - * @param {ASTNode} inner A node which is expected as inside. - * @param {ASTNode} outer A node which is expected as outside. - * @returns {boolean} `true` if the `inner` node exists in the `outer` node. - * @private - */ - function isInside(inner, outer) { - return ( - inner.range[0] >= outer.range[0] && - inner.range[1] <= outer.range[1] - ); - } - - /** - * If a given reference is left-hand side of an assignment, this gets - * the right-hand side node of the assignment. - * - * In the following cases, this returns null. - * - * - The reference is not the LHS of an assignment expression. - * - The reference is inside of a loop. - * - The reference is inside of a function scope which is different from - * the declaration. - * @param {eslint-scope.Reference} ref A reference to check. - * @param {ASTNode} prevRhsNode The previous RHS node. - * @returns {ASTNode|null} The RHS node or null. - * @private - */ - function getRhsNode(ref, prevRhsNode) { - const id = ref.identifier; - const parent = id.parent; - const grandparent = parent.parent; - const refScope = ref.from.variableScope; - const varScope = ref.resolved.scope.variableScope; - const canBeUsedLater = refScope !== varScope || astUtils.isInLoop(id); - - /* - * Inherits the previous node if this reference is in the node. - * This is for `a = a + a`-like code. - */ - if (prevRhsNode && isInside(id, prevRhsNode)) { - return prevRhsNode; - } - - if (parent.type === "AssignmentExpression" && - grandparent.type === "ExpressionStatement" && - id === parent.left && - !canBeUsedLater - ) { - return parent.right; - } - return null; - } - - /** - * Checks whether a given function node is stored to somewhere or not. - * If the function node is stored, the function can be used later. - * @param {ASTNode} funcNode A function node to check. - * @param {ASTNode} rhsNode The RHS node of the previous assignment. - * @returns {boolean} `true` if under the following conditions: - * - the funcNode is assigned to a variable. - * - the funcNode is bound as an argument of a function call. - * - the function is bound to a property and the object satisfies above conditions. - * @private - */ - function isStorableFunction(funcNode, rhsNode) { - let node = funcNode; - let parent = funcNode.parent; - - while (parent && isInside(parent, rhsNode)) { - switch (parent.type) { - case "SequenceExpression": - if (parent.expressions[parent.expressions.length - 1] !== node) { - return false; - } - break; - - case "CallExpression": - case "NewExpression": - return parent.callee !== node; - - case "AssignmentExpression": - case "TaggedTemplateExpression": - case "YieldExpression": - return true; - - default: - if (STATEMENT_TYPE.test(parent.type)) { - - /* - * If it encountered statements, this is a complex pattern. - * Since analyzing complex patterns is hard, this returns `true` to avoid false positive. - */ - return true; - } - } - - node = parent; - parent = parent.parent; - } - - return false; - } - - /** - * Checks whether a given Identifier node exists inside of a function node which can be used later. - * - * "can be used later" means: - * - the function is assigned to a variable. - * - the function is bound to a property and the object can be used later. - * - the function is bound as an argument of a function call. - * - * If a reference exists in a function which can be used later, the reference is read when the function is called. - * @param {ASTNode} id An Identifier node to check. - * @param {ASTNode} rhsNode The RHS node of the previous assignment. - * @returns {boolean} `true` if the `id` node exists inside of a function node which can be used later. - * @private - */ - function isInsideOfStorableFunction(id, rhsNode) { - const funcNode = astUtils.getUpperFunction(id); - - return ( - funcNode && - isInside(funcNode, rhsNode) && - isStorableFunction(funcNode, rhsNode) - ); - } - - /** - * Checks whether a given reference is a read to update itself or not. - * @param {eslint-scope.Reference} ref A reference to check. - * @param {ASTNode} rhsNode The RHS node of the previous assignment. - * @returns {boolean} The reference is a read to update itself. - * @private - */ - function isReadForItself(ref, rhsNode) { - const id = ref.identifier; - const parent = id.parent; - const grandparent = parent.parent; - - return ref.isRead() && ( - - // self update. e.g. `a += 1`, `a++` - (// in RHS of an assignment for itself. e.g. `a = a + 1` - (( - parent.type === "AssignmentExpression" && - grandparent.type === "ExpressionStatement" && - parent.left === id - ) || - ( - parent.type === "UpdateExpression" && - grandparent.type === "ExpressionStatement" - ) || rhsNode && - isInside(id, rhsNode) && - !isInsideOfStorableFunction(id, rhsNode))) - ); - } - - /** - * Determine if an identifier is used either in for-in loops. - * @param {Reference} ref The reference to check. - * @returns {boolean} whether reference is used in the for-in loops - * @private - */ - function isForInRef(ref) { - let target = ref.identifier.parent; - - - // "for (var ...) { return; }" - if (target.type === "VariableDeclarator") { - target = target.parent.parent; - } - - if (target.type !== "ForInStatement") { - return false; - } - - // "for (...) { return; }" - if (target.body.type === "BlockStatement") { - target = target.body.body[0]; - - // "for (...) return;" - } else { - target = target.body; - } - - // For empty loop body - if (!target) { - return false; - } - - return target.type === "ReturnStatement"; - } - - /** - * Determines if the variable is used. - * @param {Variable} variable The variable to check. - * @returns {boolean} True if the variable is used - * @private - */ - function isUsedVariable(variable) { - const functionNodes = getFunctionDefinitions(variable), - isFunctionDefinition = functionNodes.length > 0; - let rhsNode = null; - - return variable.references.some(ref => { - if (isForInRef(ref)) { - return true; - } - - const forItself = isReadForItself(ref, rhsNode); - - rhsNode = getRhsNode(ref, rhsNode); - - return ( - isReadRef(ref) && - !forItself && - !(isFunctionDefinition && isSelfReference(ref, functionNodes)) - ); - }); - } - - /** - * Checks whether the given variable is after the last used parameter. - * @param {eslint-scope.Variable} variable The variable to check. - * @returns {boolean} `true` if the variable is defined after the last - * used parameter. - */ - function isAfterLastUsedArg(variable) { - const def = variable.defs[0]; - const params = context.getDeclaredVariables(def.node); - const posteriorParams = params.slice(params.indexOf(variable) + 1); - - // If any used parameters occur after this parameter, do not report. - return !posteriorParams.some(v => v.references.length > 0 || v.eslintUsed); - } - - /** - * Gets an array of variables without read references. - * @param {Scope} scope an eslint-scope Scope object. - * @param {Variable[]} unusedVars an array that saving result. - * @returns {Variable[]} unused variables of the scope and descendant scopes. - * @private - */ - function collectUnusedVariables(scope, unusedVars) { - const variables = scope.variables; - const childScopes = scope.childScopes; - let i, l; - - if (scope.type !== "global" || config.vars === "all") { - for (i = 0, l = variables.length; i < l; ++i) { - const variable = variables[i]; - - // skip a variable of class itself name in the class scope - if (scope.type === "class" && scope.block.id === variable.identifiers[0]) { - continue; - } - - // skip function expression names and variables marked with markVariableAsUsed() - if (scope.functionExpressionScope || variable.eslintUsed) { - continue; - } - - // skip implicit "arguments" variable - if (scope.type === "function" && variable.name === "arguments" && variable.identifiers.length === 0) { - continue; - } - - // explicit global variables don't have definitions. - const def = variable.defs[0]; - - if (def) { - const type = def.type; - - // skip catch variables - if (type === "CatchClause") { - if (config.caughtErrors === "none") { - continue; - } - - // skip ignored parameters - if (config.caughtErrorsIgnorePattern && config.caughtErrorsIgnorePattern.test(def.name.name)) { - continue; - } - } - - if (type === "Parameter") { - - // skip any setter argument - if ((def.node.parent.type === "Property" || def.node.parent.type === "MethodDefinition") && def.node.parent.kind === "set") { - continue; - } - - // if "args" option is "none", skip any parameter - if (config.args === "none") { - continue; - } - - // skip ignored parameters - if (config.argsIgnorePattern && config.argsIgnorePattern.test(def.name.name)) { - continue; - } - - // if "args" option is "after-used", skip used variables - if (config.args === "after-used" && astUtils.isFunction(def.name.parent) && !isAfterLastUsedArg(variable)) { - continue; - } - } else { - - // skip ignored variables - if (config.varsIgnorePattern && config.varsIgnorePattern.test(def.name.name)) { - continue; - } - } - } - - if (!isUsedVariable(variable) && !isExported(variable) && !hasRestSpreadSibling(variable)) { - unusedVars.push(variable); - } - } - } - - for (i = 0, l = childScopes.length; i < l; ++i) { - collectUnusedVariables(childScopes[i], unusedVars); - } - - return unusedVars; - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - "Program:exit"(programNode) { - const unusedVars = collectUnusedVariables(context.getScope(), []); - - for (let i = 0, l = unusedVars.length; i < l; ++i) { - const unusedVar = unusedVars[i]; - - // Report the first declaration. - if (unusedVar.defs.length > 0) { - context.report({ - node: unusedVar.references.length ? unusedVar.references[ - unusedVar.references.length - 1 - ].identifier : unusedVar.identifiers[0], - messageId: "unusedVar", - data: unusedVar.references.some(ref => ref.isWrite()) - ? getAssignedMessageData(unusedVar) - : getDefinedMessageData(unusedVar) - }); - - // If there are no regular declaration, report the first `/*globals*/` comment directive. - } else if (unusedVar.eslintExplicitGlobalComments) { - const directiveComment = unusedVar.eslintExplicitGlobalComments[0]; - - context.report({ - node: programNode, - loc: astUtils.getNameLocationInGlobalDirectiveComment(sourceCode, directiveComment, unusedVar.name), - messageId: "unusedVar", - data: getDefinedMessageData(unusedVar) - }); - } - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag use of variables before they are defined - * @author Ilya Volodin - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const SENTINEL_TYPE = /^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/u; -const FOR_IN_OF_TYPE = /^For(?:In|Of)Statement$/u; - -/** - * Parses a given value as options. - * @param {any} options A value to parse. - * @returns {Object} The parsed options. - */ -function parseOptions(options) { - let functions = true; - let classes = true; - let variables = true; - - if (typeof options === "string") { - functions = (options !== "nofunc"); - } else if (typeof options === "object" && options !== null) { - functions = options.functions !== false; - classes = options.classes !== false; - variables = options.variables !== false; - } - - return { functions, classes, variables }; -} - -/** - * Checks whether or not a given variable is a function declaration. - * @param {eslint-scope.Variable} variable A variable to check. - * @returns {boolean} `true` if the variable is a function declaration. - */ -function isFunction(variable) { - return variable.defs[0].type === "FunctionName"; -} - -/** - * Checks whether or not a given variable is a class declaration in an upper function scope. - * @param {eslint-scope.Variable} variable A variable to check. - * @param {eslint-scope.Reference} reference A reference to check. - * @returns {boolean} `true` if the variable is a class declaration. - */ -function isOuterClass(variable, reference) { - return ( - variable.defs[0].type === "ClassName" && - variable.scope.variableScope !== reference.from.variableScope - ); -} - -/** - * Checks whether or not a given variable is a variable declaration in an upper function scope. - * @param {eslint-scope.Variable} variable A variable to check. - * @param {eslint-scope.Reference} reference A reference to check. - * @returns {boolean} `true` if the variable is a variable declaration. - */ -function isOuterVariable(variable, reference) { - return ( - variable.defs[0].type === "Variable" && - variable.scope.variableScope !== reference.from.variableScope - ); -} - -/** - * Checks whether or not a given location is inside of the range of a given node. - * @param {ASTNode} node An node to check. - * @param {number} location A location to check. - * @returns {boolean} `true` if the location is inside of the range of the node. - */ -function isInRange(node, location) { - return node && node.range[0] <= location && location <= node.range[1]; -} - -/** - * Checks whether or not a given reference is inside of the initializers of a given variable. - * - * This returns `true` in the following cases: - * - * var a = a - * var [a = a] = list - * var {a = a} = obj - * for (var a in a) {} - * for (var a of a) {} - * @param {Variable} variable A variable to check. - * @param {Reference} reference A reference to check. - * @returns {boolean} `true` if the reference is inside of the initializers. - */ -function isInInitializer(variable, reference) { - if (variable.scope !== reference.from) { - return false; - } - - let node = variable.identifiers[0].parent; - const location = reference.identifier.range[1]; - - while (node) { - if (node.type === "VariableDeclarator") { - if (isInRange(node.init, location)) { - return true; - } - if (FOR_IN_OF_TYPE.test(node.parent.parent.type) && - isInRange(node.parent.parent.right, location) - ) { - return true; - } - break; - } else if (node.type === "AssignmentPattern") { - if (isInRange(node.right, location)) { - return true; - } - } else if (SENTINEL_TYPE.test(node.type)) { - break; - } - - node = node.parent; - } - - return false; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUseBeforeDefine = { - meta: { - type: "problem", - - docs: { - description: "disallow the use of variables before they are defined", - category: "Variables", - recommended: false, - url: "https://eslint.org/docs/rules/no-use-before-define" - }, - - schema: [ - { - oneOf: [ - { - enum: ["nofunc"] - }, - { - type: "object", - properties: { - functions: { type: "boolean" }, - classes: { type: "boolean" }, - variables: { type: "boolean" } - }, - additionalProperties: false - } - ] - } - ], - - messages: { - usedBeforeDefined: "'{{name}}' was used before it was defined." - } - }, - - create(context) { - const options = parseOptions(context.options[0]); - - /** - * Determines whether a given use-before-define case should be reported according to the options. - * @param {eslint-scope.Variable} variable The variable that gets used before being defined - * @param {eslint-scope.Reference} reference The reference to the variable - * @returns {boolean} `true` if the usage should be reported - */ - function isForbidden(variable, reference) { - if (isFunction(variable)) { - return options.functions; - } - if (isOuterClass(variable, reference)) { - return options.classes; - } - if (isOuterVariable(variable, reference)) { - return options.variables; - } - return true; - } - - /** - * Finds and validates all variables in a given scope. - * @param {Scope} scope The scope object. - * @returns {void} - * @private - */ - function findVariablesInScope(scope) { - scope.references.forEach(reference => { - const variable = reference.resolved; - - /* - * Skips when the reference is: - * - initialization's. - * - referring to an undefined variable. - * - referring to a global environment variable (there're no identifiers). - * - located preceded by the variable (except in initializers). - * - allowed by options. - */ - if (reference.init || - !variable || - variable.identifiers.length === 0 || - (variable.identifiers[0].range[1] < reference.identifier.range[1] && !isInInitializer(variable, reference)) || - !isForbidden(variable, reference) - ) { - return; - } - - // Reports. - context.report({ - node: reference.identifier, - messageId: "usedBeforeDefined", - data: reference.identifier - }); - }); - - scope.childScopes.forEach(findVariablesInScope); - } - - return { - Program() { - findVariablesInScope(context.getScope()); - } - }; - } -}; - -/** - * @fileoverview Rule to disallow useless backreferences in regular expressions - * @author Milos Djermanovic - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -const { CALL: CALL$5, CONSTRUCT: CONSTRUCT$3, ReferenceTracker: ReferenceTracker$5, getStringIfConstant: getStringIfConstant$2 } = require$$0__default$1['default']; -const { RegExpParser, visitRegExpAST } = regexpp__default['default']; - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const parser$1 = new RegExpParser(); - -/** - * Finds the path from the given `regexpp` AST node to the root node. - * @param {regexpp.Node} node Node. - * @returns {regexpp.Node[]} Array that starts with the given node and ends with the root node. - */ -function getPathToRoot(node) { - const path = []; - let current = node; - - do { - path.push(current); - current = current.parent; - } while (current); - - return path; -} - -/** - * Determines whether the given `regexpp` AST node is a lookaround node. - * @param {regexpp.Node} node Node. - * @returns {boolean} `true` if it is a lookaround node. - */ -function isLookaround(node) { - return node.type === "Assertion" && - (node.kind === "lookahead" || node.kind === "lookbehind"); -} - -/** - * Determines whether the given `regexpp` AST node is a negative lookaround node. - * @param {regexpp.Node} node Node. - * @returns {boolean} `true` if it is a negative lookaround node. - */ -function isNegativeLookaround(node) { - return isLookaround(node) && node.negate; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUselessBackreference = { - meta: { - type: "problem", - - docs: { - description: "disallow useless backreferences in regular expressions", - category: "Possible Errors", - recommended: false, - url: "https://eslint.org/docs/rules/no-useless-backreference" - }, - - schema: [], - - messages: { - nested: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' from within that group.", - forward: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which appears later in the pattern.", - backward: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which appears before in the same lookbehind.", - disjunctive: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which is in another alternative.", - intoNegativeLookaround: "Backreference '{{ bref }}' will be ignored. It references group '{{ group }}' which is in a negative lookaround." - } - }, - - create(context) { - - /** - * Checks and reports useless backreferences in the given regular expression. - * @param {ASTNode} node Node that represents regular expression. A regex literal or RegExp constructor call. - * @param {string} pattern Regular expression pattern. - * @param {string} flags Regular expression flags. - * @returns {void} - */ - function checkRegex(node, pattern, flags) { - let regExpAST; - - try { - regExpAST = parser$1.parsePattern(pattern, 0, pattern.length, flags.includes("u")); - } catch { - - // Ignore regular expressions with syntax errors - return; - } - - visitRegExpAST(regExpAST, { - onBackreferenceEnter(bref) { - const group = bref.resolved, - brefPath = getPathToRoot(bref), - groupPath = getPathToRoot(group); - let messageId = null; - - if (brefPath.includes(group)) { - - // group is bref's ancestor => bref is nested ('nested reference') => group hasn't matched yet when bref starts to match. - messageId = "nested"; - } else { - - // Start from the root to find the lowest common ancestor. - let i = brefPath.length - 1, - j = groupPath.length - 1; - - do { - i--; - j--; - } while (brefPath[i] === groupPath[j]); - - const indexOfLowestCommonAncestor = j + 1, - groupCut = groupPath.slice(0, indexOfLowestCommonAncestor), - commonPath = groupPath.slice(indexOfLowestCommonAncestor), - lowestCommonLookaround = commonPath.find(isLookaround), - isMatchingBackward = lowestCommonLookaround && lowestCommonLookaround.kind === "lookbehind"; - - if (!isMatchingBackward && bref.end <= group.start) { - - // bref is left, group is right ('forward reference') => group hasn't matched yet when bref starts to match. - messageId = "forward"; - } else if (isMatchingBackward && group.end <= bref.start) { - - // the opposite of the previous when the regex is matching backward in a lookbehind context. - messageId = "backward"; - } else if (lodash__default['default'].last(groupCut).type === "Alternative") { - - // group's and bref's ancestor nodes below the lowest common ancestor are sibling alternatives => they're disjunctive. - messageId = "disjunctive"; - } else if (groupCut.some(isNegativeLookaround)) { - - // group is in a negative lookaround which isn't bref's ancestor => group has already failed when bref starts to match. - messageId = "intoNegativeLookaround"; - } - } - - if (messageId) { - context.report({ - node, - messageId, - data: { - bref: bref.raw, - group: group.raw - } - }); - } - } - }); - } - - return { - "Literal[regex]"(node) { - const { pattern, flags } = node.regex; - - checkRegex(node, pattern, flags); - }, - Program() { - const scope = context.getScope(), - tracker = new ReferenceTracker$5(scope), - traceMap = { - RegExp: { - [CALL$5]: true, - [CONSTRUCT$3]: true - } - }; - - for (const { node } of tracker.iterateGlobalReferences(traceMap)) { - const [patternNode, flagsNode] = node.arguments, - pattern = getStringIfConstant$2(patternNode, scope), - flags = getStringIfConstant$2(flagsNode, scope); - - if (typeof pattern === "string") { - checkRegex(node, pattern, flags || ""); - } - } - } - }; - } -}; - -/** - * @fileoverview A rule to disallow unnecessary `.call()` and `.apply()`. - * @author Toru Nagashima - */ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether or not a node is a `.call()`/`.apply()`. - * @param {ASTNode} node A CallExpression node to check. - * @returns {boolean} Whether or not the node is a `.call()`/`.apply()`. - */ -function isCallOrNonVariadicApply(node) { - const callee = astUtils.skipChainExpression(node.callee); - - return ( - callee.type === "MemberExpression" && - callee.property.type === "Identifier" && - callee.computed === false && - ( - (callee.property.name === "call" && node.arguments.length >= 1) || - (callee.property.name === "apply" && node.arguments.length === 2 && node.arguments[1].type === "ArrayExpression") - ) - ); -} - - -/** - * Checks whether or not `thisArg` is not changed by `.call()`/`.apply()`. - * @param {ASTNode|null} expectedThis The node that is the owner of the applied function. - * @param {ASTNode} thisArg The node that is given to the first argument of the `.call()`/`.apply()`. - * @param {SourceCode} sourceCode The ESLint source code object. - * @returns {boolean} Whether or not `thisArg` is not changed by `.call()`/`.apply()`. - */ -function isValidThisArg$1(expectedThis, thisArg, sourceCode) { - if (!expectedThis) { - return astUtils.isNullOrUndefined(thisArg); - } - return astUtils.equalTokens(expectedThis, thisArg, sourceCode); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUselessCall = { - meta: { - type: "suggestion", - - docs: { - description: "disallow unnecessary calls to `.call()` and `.apply()`", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-useless-call" - }, - - schema: [], - - messages: { - unnecessaryCall: "Unnecessary '.{{name}}()'." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - return { - CallExpression(node) { - if (!isCallOrNonVariadicApply(node)) { - return; - } - - const callee = astUtils.skipChainExpression(node.callee); - const applied = astUtils.skipChainExpression(callee.object); - const expectedThis = (applied.type === "MemberExpression") ? applied.object : null; - const thisArg = node.arguments[0]; - - if (isValidThisArg$1(expectedThis, thisArg, sourceCode)) { - context.report({ node, messageId: "unnecessaryCall", data: { name: callee.property.name } }); - } - } - }; - } -}; - -/** - * @fileoverview Reports useless `catch` clauses that just rethrow their error. - * @author Teddy Katz - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUselessCatch = { - meta: { - type: "suggestion", - - docs: { - description: "disallow unnecessary `catch` clauses", - category: "Best Practices", - recommended: true, - url: "https://eslint.org/docs/rules/no-useless-catch" - }, - - schema: [], - - messages: { - unnecessaryCatchClause: "Unnecessary catch clause.", - unnecessaryCatch: "Unnecessary try/catch wrapper." - } - }, - - create(context) { - return { - CatchClause(node) { - if ( - node.param && - node.param.type === "Identifier" && - node.body.body.length && - node.body.body[0].type === "ThrowStatement" && - node.body.body[0].argument.type === "Identifier" && - node.body.body[0].argument.name === node.param.name - ) { - if (node.parent.finalizer) { - context.report({ - node, - messageId: "unnecessaryCatchClause" - }); - } else { - context.report({ - node: node.parent, - messageId: "unnecessaryCatch" - }); - } - } - } - }; - } -}; - -/** - * @fileoverview Rule to disallow unnecessary computed property keys in object literals - * @author Burak Yigit Kaya - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUselessComputedKey = { - meta: { - type: "suggestion", - - docs: { - description: "disallow unnecessary computed property keys in objects and classes", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/no-useless-computed-key" - }, - - schema: [{ - type: "object", - properties: { - enforceForClassMembers: { - type: "boolean", - default: false - } - }, - additionalProperties: false - }], - fixable: "code", - - messages: { - unnecessarilyComputedProperty: "Unnecessarily computed property [{{property}}] found." - } - }, - create(context) { - const sourceCode = context.getSourceCode(); - const enforceForClassMembers = context.options[0] && context.options[0].enforceForClassMembers; - - /** - * Reports a given node if it violated this rule. - * @param {ASTNode} node The node to check. - * @returns {void} - */ - function check(node) { - if (!node.computed) { - return; - } - - const key = node.key, - nodeType = typeof key.value; - - let allowedKey; - - if (node.type === "MethodDefinition") { - allowedKey = node.static ? "prototype" : "constructor"; - } else { - allowedKey = "__proto__"; - } - - if (key.type === "Literal" && (nodeType === "string" || nodeType === "number") && key.value !== allowedKey) { - context.report({ - node, - messageId: "unnecessarilyComputedProperty", - data: { property: sourceCode.getText(key) }, - fix(fixer) { - const leftSquareBracket = sourceCode.getTokenBefore(key, astUtils.isOpeningBracketToken); - const rightSquareBracket = sourceCode.getTokenAfter(key, astUtils.isClosingBracketToken); - - // If there are comments between the brackets and the property name, don't do a fix. - if (sourceCode.commentsExistBetween(leftSquareBracket, rightSquareBracket)) { - return null; - } - - const tokenBeforeLeftBracket = sourceCode.getTokenBefore(leftSquareBracket); - - // Insert a space before the key to avoid changing identifiers, e.g. ({ get[2]() {} }) to ({ get2() {} }) - const needsSpaceBeforeKey = tokenBeforeLeftBracket.range[1] === leftSquareBracket.range[0] && - !astUtils.canTokensBeAdjacent(tokenBeforeLeftBracket, sourceCode.getFirstToken(key)); - - const replacementKey = (needsSpaceBeforeKey ? " " : "") + key.raw; - - return fixer.replaceTextRange([leftSquareBracket.range[0], rightSquareBracket.range[1]], replacementKey); - } - }); - } - } - - return { - Property: check, - MethodDefinition: enforceForClassMembers ? check : lodash__default['default'].noop - }; - } -}; - -/** - * @fileoverview disallow unnecessary concatenation of template strings - * @author Henry Zhu - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether or not a given node is a concatenation. - * @param {ASTNode} node A node to check. - * @returns {boolean} `true` if the node is a concatenation. - */ -function isConcatenation$1(node) { - return node.type === "BinaryExpression" && node.operator === "+"; -} - -/** - * Checks if the given token is a `+` token or not. - * @param {Token} token The token to check. - * @returns {boolean} `true` if the token is a `+` token. - */ -function isConcatOperatorToken(token) { - return token.value === "+" && token.type === "Punctuator"; -} - -/** - * Get's the right most node on the left side of a BinaryExpression with + operator. - * @param {ASTNode} node A BinaryExpression node to check. - * @returns {ASTNode} node - */ -function getLeft(node) { - let left = node.left; - - while (isConcatenation$1(left)) { - left = left.right; - } - return left; -} - -/** - * Get's the left most node on the right side of a BinaryExpression with + operator. - * @param {ASTNode} node A BinaryExpression node to check. - * @returns {ASTNode} node - */ -function getRight(node) { - let right = node.right; - - while (isConcatenation$1(right)) { - right = right.left; - } - return right; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUselessConcat = { - meta: { - type: "suggestion", - - docs: { - description: "disallow unnecessary concatenation of literals or template literals", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-useless-concat" - }, - - schema: [], - - messages: { - unexpectedConcat: "Unexpected string concatenation of literals." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - return { - BinaryExpression(node) { - - // check if not concatenation - if (node.operator !== "+") { - return; - } - - // account for the `foo + "a" + "b"` case - const left = getLeft(node); - const right = getRight(node); - - if (astUtils.isStringLiteral(left) && - astUtils.isStringLiteral(right) && - astUtils.isTokenOnSameLine(left, right) - ) { - const operatorToken = sourceCode.getFirstTokenBetween(left, right, isConcatOperatorToken); - - context.report({ - node, - loc: operatorToken.loc, - messageId: "unexpectedConcat" - }); - } - } - }; - } -}; - -/** - * @fileoverview Rule to flag the use of redundant constructors in classes. - * @author Alberto Rodríguez - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether a given array of statements is a single call of `super`. - * @param {ASTNode[]} body An array of statements to check. - * @returns {boolean} `true` if the body is a single call of `super`. - */ -function isSingleSuperCall(body) { - return ( - body.length === 1 && - body[0].type === "ExpressionStatement" && - body[0].expression.type === "CallExpression" && - body[0].expression.callee.type === "Super" - ); -} - -/** - * Checks whether a given node is a pattern which doesn't have any side effects. - * Default parameters and Destructuring parameters can have side effects. - * @param {ASTNode} node A pattern node. - * @returns {boolean} `true` if the node doesn't have any side effects. - */ -function isSimple(node) { - return node.type === "Identifier" || node.type === "RestElement"; -} - -/** - * Checks whether a given array of expressions is `...arguments` or not. - * `super(...arguments)` passes all arguments through. - * @param {ASTNode[]} superArgs An array of expressions to check. - * @returns {boolean} `true` if the superArgs is `...arguments`. - */ -function isSpreadArguments(superArgs) { - return ( - superArgs.length === 1 && - superArgs[0].type === "SpreadElement" && - superArgs[0].argument.type === "Identifier" && - superArgs[0].argument.name === "arguments" - ); -} - -/** - * Checks whether given 2 nodes are identifiers which have the same name or not. - * @param {ASTNode} ctorParam A node to check. - * @param {ASTNode} superArg A node to check. - * @returns {boolean} `true` if the nodes are identifiers which have the same - * name. - */ -function isValidIdentifierPair(ctorParam, superArg) { - return ( - ctorParam.type === "Identifier" && - superArg.type === "Identifier" && - ctorParam.name === superArg.name - ); -} - -/** - * Checks whether given 2 nodes are a rest/spread pair which has the same values. - * @param {ASTNode} ctorParam A node to check. - * @param {ASTNode} superArg A node to check. - * @returns {boolean} `true` if the nodes are a rest/spread pair which has the - * same values. - */ -function isValidRestSpreadPair(ctorParam, superArg) { - return ( - ctorParam.type === "RestElement" && - superArg.type === "SpreadElement" && - isValidIdentifierPair(ctorParam.argument, superArg.argument) - ); -} - -/** - * Checks whether given 2 nodes have the same value or not. - * @param {ASTNode} ctorParam A node to check. - * @param {ASTNode} superArg A node to check. - * @returns {boolean} `true` if the nodes have the same value or not. - */ -function isValidPair(ctorParam, superArg) { - return ( - isValidIdentifierPair(ctorParam, superArg) || - isValidRestSpreadPair(ctorParam, superArg) - ); -} - -/** - * Checks whether the parameters of a constructor and the arguments of `super()` - * have the same values or not. - * @param {ASTNode} ctorParams The parameters of a constructor to check. - * @param {ASTNode} superArgs The arguments of `super()` to check. - * @returns {boolean} `true` if those have the same values. - */ -function isPassingThrough(ctorParams, superArgs) { - if (ctorParams.length !== superArgs.length) { - return false; - } - - for (let i = 0; i < ctorParams.length; ++i) { - if (!isValidPair(ctorParams[i], superArgs[i])) { - return false; - } - } - - return true; -} - -/** - * Checks whether the constructor body is a redundant super call. - * @param {Array} body constructor body content. - * @param {Array} ctorParams The params to check against super call. - * @returns {boolean} true if the constructor body is redundant - */ -function isRedundantSuperCall(body, ctorParams) { - return ( - isSingleSuperCall(body) && - ctorParams.every(isSimple) && - ( - isSpreadArguments(body[0].expression.arguments) || - isPassingThrough(ctorParams, body[0].expression.arguments) - ) - ); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUselessConstructor = { - meta: { - type: "suggestion", - - docs: { - description: "disallow unnecessary constructors", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/no-useless-constructor" - }, - - schema: [], - - messages: { - noUselessConstructor: "Useless constructor." - } - }, - - create(context) { - - /** - * Checks whether a node is a redundant constructor - * @param {ASTNode} node node to check - * @returns {void} - */ - function checkForConstructor(node) { - if (node.kind !== "constructor") { - return; - } - - /* - * Prevent crashing on parsers which do not require class constructor - * to have a body, e.g. typescript and flow - */ - if (!node.value.body) { - return; - } - - const body = node.value.body.body; - const ctorParams = node.value.params; - const superClass = node.parent.parent.superClass; - - if (superClass ? isRedundantSuperCall(body, ctorParams) : (body.length === 0)) { - context.report({ - node, - messageId: "noUselessConstructor" - }); - } - } - - return { - MethodDefinition: checkForConstructor - }; - } -}; - -/** - * @fileoverview Look for useless escapes in strings and regexes - * @author Onur Temizkan - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -/** - * Returns the union of two sets. - * @param {Set} setA The first set - * @param {Set} setB The second set - * @returns {Set} The union of the two sets - */ -function union(setA, setB) { - return new Set(function *() { - yield* setA; - yield* setB; - }()); -} - -const VALID_STRING_ESCAPES = union(new Set("\\nrvtbfux"), astUtils.LINEBREAKS); -const REGEX_GENERAL_ESCAPES = new Set("\\bcdDfnpPrsStvwWxu0123456789]"); -const REGEX_NON_CHARCLASS_ESCAPES = union(REGEX_GENERAL_ESCAPES, new Set("^/.$*+?[{}|()Bk")); - -/** - * Parses a regular expression into a list of characters with character class info. - * @param {string} regExpText The raw text used to create the regular expression - * @returns {Object[]} A list of characters, each with info on escaping and whether they're in a character class. - * @example - * - * parseRegExp('a\\b[cd-]') - * - * returns: - * [ - * {text: 'a', index: 0, escaped: false, inCharClass: false, startsCharClass: false, endsCharClass: false}, - * {text: 'b', index: 2, escaped: true, inCharClass: false, startsCharClass: false, endsCharClass: false}, - * {text: 'c', index: 4, escaped: false, inCharClass: true, startsCharClass: true, endsCharClass: false}, - * {text: 'd', index: 5, escaped: false, inCharClass: true, startsCharClass: false, endsCharClass: false}, - * {text: '-', index: 6, escaped: false, inCharClass: true, startsCharClass: false, endsCharClass: false} - * ] - */ -function parseRegExp(regExpText) { - const charList = []; - - regExpText.split("").reduce((state, char, index) => { - if (!state.escapeNextChar) { - if (char === "\\") { - return Object.assign(state, { escapeNextChar: true }); - } - if (char === "[" && !state.inCharClass) { - return Object.assign(state, { inCharClass: true, startingCharClass: true }); - } - if (char === "]" && state.inCharClass) { - if (charList.length && charList[charList.length - 1].inCharClass) { - charList[charList.length - 1].endsCharClass = true; - } - return Object.assign(state, { inCharClass: false, startingCharClass: false }); - } - } - charList.push({ - text: char, - index, - escaped: state.escapeNextChar, - inCharClass: state.inCharClass, - startsCharClass: state.startingCharClass, - endsCharClass: false - }); - return Object.assign(state, { escapeNextChar: false, startingCharClass: false }); - }, { escapeNextChar: false, inCharClass: false, startingCharClass: false }); - - return charList; -} - -var noUselessEscape = { - meta: { - type: "suggestion", - - docs: { - description: "disallow unnecessary escape characters", - category: "Best Practices", - recommended: true, - url: "https://eslint.org/docs/rules/no-useless-escape", - suggestion: true - }, - - messages: { - unnecessaryEscape: "Unnecessary escape character: \\{{character}}.", - removeEscape: "Remove the `\\`. This maintains the current functionality.", - escapeBackslash: "Replace the `\\` with `\\\\` to include the actual backslash character." - }, - - schema: [] - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - /** - * Reports a node - * @param {ASTNode} node The node to report - * @param {number} startOffset The backslash's offset from the start of the node - * @param {string} character The uselessly escaped character (not including the backslash) - * @returns {void} - */ - function report(node, startOffset, character) { - const rangeStart = node.range[0] + startOffset; - const range = [rangeStart, rangeStart + 1]; - const start = sourceCode.getLocFromIndex(rangeStart); - - context.report({ - node, - loc: { - start, - end: { line: start.line, column: start.column + 1 } - }, - messageId: "unnecessaryEscape", - data: { character }, - suggest: [ - { - messageId: "removeEscape", - fix(fixer) { - return fixer.removeRange(range); - } - }, - { - messageId: "escapeBackslash", - fix(fixer) { - return fixer.insertTextBeforeRange(range, "\\"); - } - } - ] - }); - } - - /** - * Checks if the escape character in given string slice is unnecessary. - * @private - * @param {ASTNode} node node to validate. - * @param {string} match string slice to validate. - * @returns {void} - */ - function validateString(node, match) { - const isTemplateElement = node.type === "TemplateElement"; - const escapedChar = match[0][1]; - let isUnnecessaryEscape = !VALID_STRING_ESCAPES.has(escapedChar); - let isQuoteEscape; - - if (isTemplateElement) { - isQuoteEscape = escapedChar === "`"; - - if (escapedChar === "$") { - - // Warn if `\$` is not followed by `{` - isUnnecessaryEscape = match.input[match.index + 2] !== "{"; - } else if (escapedChar === "{") { - - /* - * Warn if `\{` is not preceded by `$`. If preceded by `$`, escaping - * is necessary and the rule should not warn. If preceded by `/$`, the rule - * will warn for the `/$` instead, as it is the first unnecessarily escaped character. - */ - isUnnecessaryEscape = match.input[match.index - 1] !== "$"; - } - } else { - isQuoteEscape = escapedChar === node.raw[0]; - } - - if (isUnnecessaryEscape && !isQuoteEscape) { - report(node, match.index, match[0].slice(1)); - } - } - - /** - * Checks if a node has an escape. - * @param {ASTNode} node node to check. - * @returns {void} - */ - function check(node) { - const isTemplateElement = node.type === "TemplateElement"; - - if ( - isTemplateElement && - node.parent && - node.parent.parent && - node.parent.parent.type === "TaggedTemplateExpression" && - node.parent === node.parent.parent.quasi - ) { - - // Don't report tagged template literals, because the backslash character is accessible to the tag function. - return; - } - - if (typeof node.value === "string" || isTemplateElement) { - - /* - * JSXAttribute doesn't have any escape sequence: https://facebook.github.io/jsx/. - * In addition, backticks are not supported by JSX yet: https://github.com/facebook/jsx/issues/25. - */ - if (node.parent.type === "JSXAttribute" || node.parent.type === "JSXElement" || node.parent.type === "JSXFragment") { - return; - } - - const value = isTemplateElement ? sourceCode.getText(node) : node.raw; - const pattern = /\\[^\d]/gu; - let match; - - while ((match = pattern.exec(value))) { - validateString(node, match); - } - } else if (node.regex) { - parseRegExp(node.regex.pattern) - - /* - * The '-' character is a special case, because it's only valid to escape it if it's in a character - * class, and is not at either edge of the character class. To account for this, don't consider '-' - * characters to be valid in general, and filter out '-' characters that appear in the middle of a - * character class. - */ - .filter(charInfo => !(charInfo.text === "-" && charInfo.inCharClass && !charInfo.startsCharClass && !charInfo.endsCharClass)) - - /* - * The '^' character is also a special case; it must always be escaped outside of character classes, but - * it only needs to be escaped in character classes if it's at the beginning of the character class. To - * account for this, consider it to be a valid escape character outside of character classes, and filter - * out '^' characters that appear at the start of a character class. - */ - .filter(charInfo => !(charInfo.text === "^" && charInfo.startsCharClass)) - - // Filter out characters that aren't escaped. - .filter(charInfo => charInfo.escaped) - - // Filter out characters that are valid to escape, based on their position in the regular expression. - .filter(charInfo => !(charInfo.inCharClass ? REGEX_GENERAL_ESCAPES : REGEX_NON_CHARCLASS_ESCAPES).has(charInfo.text)) - - // Report all the remaining characters. - .forEach(charInfo => report(node, charInfo.index, charInfo.text)); - } - - } - - return { - Literal: check, - TemplateElement: check - }; - } -}; - -/** - * @fileoverview Disallow renaming import, export, and destructured assignments to the same name. - * @author Kai Cataldo - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUselessRename = { - meta: { - type: "suggestion", - - docs: { - description: "disallow renaming import, export, and destructured assignments to the same name", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/no-useless-rename" - }, - - fixable: "code", - - schema: [ - { - type: "object", - properties: { - ignoreDestructuring: { type: "boolean", default: false }, - ignoreImport: { type: "boolean", default: false }, - ignoreExport: { type: "boolean", default: false } - }, - additionalProperties: false - } - ], - - messages: { - unnecessarilyRenamed: "{{type}} {{name}} unnecessarily renamed." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(), - options = context.options[0] || {}, - ignoreDestructuring = options.ignoreDestructuring === true, - ignoreImport = options.ignoreImport === true, - ignoreExport = options.ignoreExport === true; - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Reports error for unnecessarily renamed assignments - * @param {ASTNode} node node to report - * @param {ASTNode} initial node with initial name value - * @param {string} type the type of the offending node - * @returns {void} - */ - function reportError(node, initial, type) { - const name = initial.type === "Identifier" ? initial.name : initial.value; - - return context.report({ - node, - messageId: "unnecessarilyRenamed", - data: { - name, - type - }, - fix(fixer) { - const replacementNode = node.type === "Property" ? node.value : node.local; - - if (sourceCode.getCommentsInside(node).length > sourceCode.getCommentsInside(replacementNode).length) { - return null; - } - - // Don't autofix code such as `({foo: (foo) = a} = obj);`, parens are not allowed in shorthand properties. - if ( - replacementNode.type === "AssignmentPattern" && - astUtils.isParenthesised(sourceCode, replacementNode.left) - ) { - return null; - } - - return fixer.replaceText(node, sourceCode.getText(replacementNode)); - } - }); - } - - /** - * Checks whether a destructured assignment is unnecessarily renamed - * @param {ASTNode} node node to check - * @returns {void} - */ - function checkDestructured(node) { - if (ignoreDestructuring) { - return; - } - - for (const property of node.properties) { - - /** - * Properties using shorthand syntax and rest elements can not be renamed. - * If the property is computed, we have no idea if a rename is useless or not. - */ - if (property.type !== "Property" || property.shorthand || property.computed) { - continue; - } - - const key = (property.key.type === "Identifier" && property.key.name) || (property.key.type === "Literal" && property.key.value); - const renamedKey = property.value.type === "AssignmentPattern" ? property.value.left.name : property.value.name; - - if (key === renamedKey) { - reportError(property, property.key, "Destructuring assignment"); - } - } - } - - /** - * Checks whether an import is unnecessarily renamed - * @param {ASTNode} node node to check - * @returns {void} - */ - function checkImport(node) { - if (ignoreImport) { - return; - } - - if (node.imported.name === node.local.name && - node.imported.range[0] !== node.local.range[0]) { - reportError(node, node.imported, "Import"); - } - } - - /** - * Checks whether an export is unnecessarily renamed - * @param {ASTNode} node node to check - * @returns {void} - */ - function checkExport(node) { - if (ignoreExport) { - return; - } - - if (node.local.name === node.exported.name && - node.local.range[0] !== node.exported.range[0]) { - reportError(node, node.local, "Export"); - } - - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - ObjectPattern: checkDestructured, - ImportSpecifier: checkImport, - ExportSpecifier: checkExport - }; - } -}; - -/** - * @fileoverview Disallow redundant return statements - * @author Teddy Katz - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Removes the given element from the array. - * @param {Array} array The source array to remove. - * @param {any} element The target item to remove. - * @returns {void} - */ -function remove(array, element) { - const index = array.indexOf(element); - - if (index !== -1) { - array.splice(index, 1); - } -} - -/** - * Checks whether it can remove the given return statement or not. - * @param {ASTNode} node The return statement node to check. - * @returns {boolean} `true` if the node is removable. - */ -function isRemovable(node) { - return astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type); -} - -/** - * Checks whether the given return statement is in a `finally` block or not. - * @param {ASTNode} node The return statement node to check. - * @returns {boolean} `true` if the node is in a `finally` block. - */ -function isInFinally(node) { - for ( - let currentNode = node; - currentNode && currentNode.parent && !astUtils.isFunction(currentNode); - currentNode = currentNode.parent - ) { - if (currentNode.parent.type === "TryStatement" && currentNode.parent.finalizer === currentNode) { - return true; - } - } - - return false; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noUselessReturn = { - meta: { - type: "suggestion", - - docs: { - description: "disallow redundant return statements", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-useless-return" - }, - - fixable: "code", - schema: [], - - messages: { - unnecessaryReturn: "Unnecessary return statement." - } - }, - - create(context) { - const segmentInfoMap = new WeakMap(); - const usedUnreachableSegments = new WeakSet(); - const sourceCode = context.getSourceCode(); - let scopeInfo = null; - - /** - * Checks whether the given segment is terminated by a return statement or not. - * @param {CodePathSegment} segment The segment to check. - * @returns {boolean} `true` if the segment is terminated by a return statement, or if it's still a part of unreachable. - */ - function isReturned(segment) { - const info = segmentInfoMap.get(segment); - - return !info || info.returned; - } - - /** - * Collects useless return statements from the given previous segments. - * - * A previous segment may be an unreachable segment. - * In that case, the information object of the unreachable segment is not - * initialized because `onCodePathSegmentStart` event is not notified for - * unreachable segments. - * This goes to the previous segments of the unreachable segment recursively - * if the unreachable segment was generated by a return statement. Otherwise, - * this ignores the unreachable segment. - * - * This behavior would simulate code paths for the case that the return - * statement does not exist. - * @param {ASTNode[]} uselessReturns The collected return statements. - * @param {CodePathSegment[]} prevSegments The previous segments to traverse. - * @param {WeakSet} [providedTraversedSegments] A set of segments that have already been traversed in this call - * @returns {ASTNode[]} `uselessReturns`. - */ - function getUselessReturns(uselessReturns, prevSegments, providedTraversedSegments) { - const traversedSegments = providedTraversedSegments || new WeakSet(); - - for (const segment of prevSegments) { - if (!segment.reachable) { - if (!traversedSegments.has(segment)) { - traversedSegments.add(segment); - getUselessReturns( - uselessReturns, - segment.allPrevSegments.filter(isReturned), - traversedSegments - ); - } - continue; - } - - uselessReturns.push(...segmentInfoMap.get(segment).uselessReturns); - } - - return uselessReturns; - } - - /** - * Removes the return statements on the given segment from the useless return - * statement list. - * - * This segment may be an unreachable segment. - * In that case, the information object of the unreachable segment is not - * initialized because `onCodePathSegmentStart` event is not notified for - * unreachable segments. - * This goes to the previous segments of the unreachable segment recursively - * if the unreachable segment was generated by a return statement. Otherwise, - * this ignores the unreachable segment. - * - * This behavior would simulate code paths for the case that the return - * statement does not exist. - * @param {CodePathSegment} segment The segment to get return statements. - * @returns {void} - */ - function markReturnStatementsOnSegmentAsUsed(segment) { - if (!segment.reachable) { - usedUnreachableSegments.add(segment); - segment.allPrevSegments - .filter(isReturned) - .filter(prevSegment => !usedUnreachableSegments.has(prevSegment)) - .forEach(markReturnStatementsOnSegmentAsUsed); - return; - } - - const info = segmentInfoMap.get(segment); - - for (const node of info.uselessReturns) { - remove(scopeInfo.uselessReturns, node); - } - info.uselessReturns = []; - } - - /** - * Removes the return statements on the current segments from the useless - * return statement list. - * - * This function will be called at every statement except FunctionDeclaration, - * BlockStatement, and BreakStatement. - * - * - FunctionDeclarations are always executed whether it's returned or not. - * - BlockStatements do nothing. - * - BreakStatements go the next merely. - * @returns {void} - */ - function markReturnStatementsOnCurrentSegmentsAsUsed() { - scopeInfo - .codePath - .currentSegments - .forEach(markReturnStatementsOnSegmentAsUsed); - } - - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - - return { - - // Makes and pushs a new scope information. - onCodePathStart(codePath) { - scopeInfo = { - upper: scopeInfo, - uselessReturns: [], - codePath - }; - }, - - // Reports useless return statements if exist. - onCodePathEnd() { - for (const node of scopeInfo.uselessReturns) { - context.report({ - node, - loc: node.loc, - messageId: "unnecessaryReturn", - fix(fixer) { - if (isRemovable(node) && !sourceCode.getCommentsInside(node).length) { - - /* - * Extend the replacement range to include the - * entire function to avoid conflicting with - * no-else-return. - * https://github.com/eslint/eslint/issues/8026 - */ - return new fixTracker(fixer, sourceCode) - .retainEnclosingFunction(node) - .remove(node); - } - return null; - } - }); - } - - scopeInfo = scopeInfo.upper; - }, - - /* - * Initializes segments. - * NOTE: This event is notified for only reachable segments. - */ - onCodePathSegmentStart(segment) { - const info = { - uselessReturns: getUselessReturns([], segment.allPrevSegments), - returned: false - }; - - // Stores the info. - segmentInfoMap.set(segment, info); - }, - - // Adds ReturnStatement node to check whether it's useless or not. - ReturnStatement(node) { - if (node.argument) { - markReturnStatementsOnCurrentSegmentsAsUsed(); - } - if ( - node.argument || - astUtils.isInLoop(node) || - isInFinally(node) || - - // Ignore `return` statements in unreachable places (https://github.com/eslint/eslint/issues/11647). - !scopeInfo.codePath.currentSegments.some(s => s.reachable) - ) { - return; - } - - for (const segment of scopeInfo.codePath.currentSegments) { - const info = segmentInfoMap.get(segment); - - if (info) { - info.uselessReturns.push(node); - info.returned = true; - } - } - scopeInfo.uselessReturns.push(node); - }, - - /* - * Registers for all statement nodes except FunctionDeclaration, BlockStatement, BreakStatement. - * Removes return statements of the current segments from the useless return statement list. - */ - ClassDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, - ContinueStatement: markReturnStatementsOnCurrentSegmentsAsUsed, - DebuggerStatement: markReturnStatementsOnCurrentSegmentsAsUsed, - DoWhileStatement: markReturnStatementsOnCurrentSegmentsAsUsed, - EmptyStatement: markReturnStatementsOnCurrentSegmentsAsUsed, - ExpressionStatement: markReturnStatementsOnCurrentSegmentsAsUsed, - ForInStatement: markReturnStatementsOnCurrentSegmentsAsUsed, - ForOfStatement: markReturnStatementsOnCurrentSegmentsAsUsed, - ForStatement: markReturnStatementsOnCurrentSegmentsAsUsed, - IfStatement: markReturnStatementsOnCurrentSegmentsAsUsed, - ImportDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, - LabeledStatement: markReturnStatementsOnCurrentSegmentsAsUsed, - SwitchStatement: markReturnStatementsOnCurrentSegmentsAsUsed, - ThrowStatement: markReturnStatementsOnCurrentSegmentsAsUsed, - TryStatement: markReturnStatementsOnCurrentSegmentsAsUsed, - VariableDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, - WhileStatement: markReturnStatementsOnCurrentSegmentsAsUsed, - WithStatement: markReturnStatementsOnCurrentSegmentsAsUsed, - ExportNamedDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, - ExportDefaultDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed, - ExportAllDeclaration: markReturnStatementsOnCurrentSegmentsAsUsed - }; - } -}; - -/** - * @fileoverview Rule to check for the usage of var. - * @author Jamund Ferguson - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Check whether a given variable is a global variable or not. - * @param {eslint-scope.Variable} variable The variable to check. - * @returns {boolean} `true` if the variable is a global variable. - */ -function isGlobal(variable) { - return Boolean(variable.scope) && variable.scope.type === "global"; -} - -/** - * Finds the nearest function scope or global scope walking up the scope - * hierarchy. - * @param {eslint-scope.Scope} scope The scope to traverse. - * @returns {eslint-scope.Scope} a function scope or global scope containing the given - * scope. - */ -function getEnclosingFunctionScope(scope) { - let currentScope = scope; - - while (currentScope.type !== "function" && currentScope.type !== "global") { - currentScope = currentScope.upper; - } - return currentScope; -} - -/** - * Checks whether the given variable has any references from a more specific - * function expression (i.e. a closure). - * @param {eslint-scope.Variable} variable A variable to check. - * @returns {boolean} `true` if the variable is used from a closure. - */ -function isReferencedInClosure(variable) { - const enclosingFunctionScope = getEnclosingFunctionScope(variable.scope); - - return variable.references.some(reference => - getEnclosingFunctionScope(reference.from) !== enclosingFunctionScope); -} - -/** - * Checks whether the given node is the assignee of a loop. - * @param {ASTNode} node A VariableDeclaration node to check. - * @returns {boolean} `true` if the declaration is assigned as part of loop - * iteration. - */ -function isLoopAssignee(node) { - return (node.parent.type === "ForOfStatement" || node.parent.type === "ForInStatement") && - node === node.parent.left; -} - -/** - * Checks whether the given variable declaration is immediately initialized. - * @param {ASTNode} node A VariableDeclaration node to check. - * @returns {boolean} `true` if the declaration has an initializer. - */ -function isDeclarationInitialized(node) { - return node.declarations.every(declarator => declarator.init !== null); -} - -const SCOPE_NODE_TYPE = /^(?:Program|BlockStatement|SwitchStatement|ForStatement|ForInStatement|ForOfStatement)$/u; - -/** - * Gets the scope node which directly contains a given node. - * @param {ASTNode} node A node to get. This is a `VariableDeclaration` or - * an `Identifier`. - * @returns {ASTNode} A scope node. This is one of `Program`, `BlockStatement`, - * `SwitchStatement`, `ForStatement`, `ForInStatement`, and - * `ForOfStatement`. - */ -function getScopeNode(node) { - for (let currentNode = node; currentNode; currentNode = currentNode.parent) { - if (SCOPE_NODE_TYPE.test(currentNode.type)) { - return currentNode; - } - } - - /* istanbul ignore next : unreachable */ - return null; -} - -/** - * Checks whether a given variable is redeclared or not. - * @param {eslint-scope.Variable} variable A variable to check. - * @returns {boolean} `true` if the variable is redeclared. - */ -function isRedeclared(variable) { - return variable.defs.length >= 2; -} - -/** - * Checks whether a given variable is used from outside of the specified scope. - * @param {ASTNode} scopeNode A scope node to check. - * @returns {Function} The predicate function which checks whether a given - * variable is used from outside of the specified scope. - */ -function isUsedFromOutsideOf(scopeNode) { - - /** - * Checks whether a given reference is inside of the specified scope or not. - * @param {eslint-scope.Reference} reference A reference to check. - * @returns {boolean} `true` if the reference is inside of the specified - * scope. - */ - function isOutsideOfScope(reference) { - const scope = scopeNode.range; - const id = reference.identifier.range; - - return id[0] < scope[0] || id[1] > scope[1]; - } - - return function(variable) { - return variable.references.some(isOutsideOfScope); - }; -} - -/** - * Creates the predicate function which checks whether a variable has their references in TDZ. - * - * The predicate function would return `true`: - * - * - if a reference is before the declarator. E.g. (var a = b, b = 1;)(var {a = b, b} = {};) - * - if a reference is in the expression of their default value. E.g. (var {a = a} = {};) - * - if a reference is in the expression of their initializer. E.g. (var a = a;) - * @param {ASTNode} node The initializer node of VariableDeclarator. - * @returns {Function} The predicate function. - * @private - */ -function hasReferenceInTDZ(node) { - const initStart = node.range[0]; - const initEnd = node.range[1]; - - return variable => { - const id = variable.defs[0].name; - const idStart = id.range[0]; - const defaultValue = (id.parent.type === "AssignmentPattern" ? id.parent.right : null); - const defaultStart = defaultValue && defaultValue.range[0]; - const defaultEnd = defaultValue && defaultValue.range[1]; - - return variable.references.some(reference => { - const start = reference.identifier.range[0]; - const end = reference.identifier.range[1]; - - return !reference.init && ( - start < idStart || - (defaultValue !== null && start >= defaultStart && end <= defaultEnd) || - (start >= initStart && end <= initEnd) - ); - }); - }; -} - -/** - * Checks whether a given variable has name that is allowed for 'var' declarations, - * but disallowed for `let` declarations. - * @param {eslint-scope.Variable} variable The variable to check. - * @returns {boolean} `true` if the variable has a disallowed name. - */ -function hasNameDisallowedForLetDeclarations(variable) { - return variable.name === "let"; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noVar = { - meta: { - type: "suggestion", - - docs: { - description: "require `let` or `const` instead of `var`", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/no-var" - }, - - schema: [], - fixable: "code", - - messages: { - unexpectedVar: "Unexpected var, use let or const instead." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - /** - * Checks whether the variables which are defined by the given declarator node have their references in TDZ. - * @param {ASTNode} declarator The VariableDeclarator node to check. - * @returns {boolean} `true` if one of the variables which are defined by the given declarator node have their references in TDZ. - */ - function hasSelfReferenceInTDZ(declarator) { - if (!declarator.init) { - return false; - } - const variables = context.getDeclaredVariables(declarator); - - return variables.some(hasReferenceInTDZ(declarator.init)); - } - - /** - * Checks whether it can fix a given variable declaration or not. - * It cannot fix if the following cases: - * - * - A variable is a global variable. - * - A variable is declared on a SwitchCase node. - * - A variable is redeclared. - * - A variable is used from outside the scope. - * - A variable is used from a closure within a loop. - * - A variable might be used before it is assigned within a loop. - * - A variable might be used in TDZ. - * - A variable is declared in statement position (e.g. a single-line `IfStatement`) - * - A variable has name that is disallowed for `let` declarations. - * - * ## A variable is declared on a SwitchCase node. - * - * If this rule modifies 'var' declarations on a SwitchCase node, it - * would generate the warnings of 'no-case-declarations' rule. And the - * 'eslint:recommended' preset includes 'no-case-declarations' rule, so - * this rule doesn't modify those declarations. - * - * ## A variable is redeclared. - * - * The language spec disallows redeclarations of `let` declarations. - * Those variables would cause syntax errors. - * - * ## A variable is used from outside the scope. - * - * The language spec disallows accesses from outside of the scope for - * `let` declarations. Those variables would cause reference errors. - * - * ## A variable is used from a closure within a loop. - * - * A `var` declaration within a loop shares the same variable instance - * across all loop iterations, while a `let` declaration creates a new - * instance for each iteration. This means if a variable in a loop is - * referenced by any closure, changing it from `var` to `let` would - * change the behavior in a way that is generally unsafe. - * - * ## A variable might be used before it is assigned within a loop. - * - * Within a loop, a `let` declaration without an initializer will be - * initialized to null, while a `var` declaration will retain its value - * from the previous iteration, so it is only safe to change `var` to - * `let` if we can statically determine that the variable is always - * assigned a value before its first access in the loop body. To keep - * the implementation simple, we only convert `var` to `let` within - * loops when the variable is a loop assignee or the declaration has an - * initializer. - * @param {ASTNode} node A variable declaration node to check. - * @returns {boolean} `true` if it can fix the node. - */ - function canFix(node) { - const variables = context.getDeclaredVariables(node); - const scopeNode = getScopeNode(node); - - if (node.parent.type === "SwitchCase" || - node.declarations.some(hasSelfReferenceInTDZ) || - variables.some(isGlobal) || - variables.some(isRedeclared) || - variables.some(isUsedFromOutsideOf(scopeNode)) || - variables.some(hasNameDisallowedForLetDeclarations) - ) { - return false; - } - - if (astUtils.isInLoop(node)) { - if (variables.some(isReferencedInClosure)) { - return false; - } - if (!isLoopAssignee(node) && !isDeclarationInitialized(node)) { - return false; - } - } - - if ( - !isLoopAssignee(node) && - !(node.parent.type === "ForStatement" && node.parent.init === node) && - !astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type) - ) { - - // If the declaration is not in a block, e.g. `if (foo) var bar = 1;`, then it can't be fixed. - return false; - } - - return true; - } - - /** - * Reports a given variable declaration node. - * @param {ASTNode} node A variable declaration node to report. - * @returns {void} - */ - function report(node) { - context.report({ - node, - messageId: "unexpectedVar", - - fix(fixer) { - const varToken = sourceCode.getFirstToken(node, { filter: t => t.value === "var" }); - - return canFix(node) - ? fixer.replaceText(varToken, "let") - : null; - } - }); - } - - return { - "VariableDeclaration:exit"(node) { - if (node.kind === "var") { - report(node); - } - } - }; - } -}; - -/** - * @fileoverview Rule to disallow use of void operator. - * @author Mike Sidorov - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noVoid = { - meta: { - type: "suggestion", - - docs: { - description: "disallow `void` operators", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-void" - }, - - messages: { - noVoid: "Expected 'undefined' and instead saw 'void'." - }, - - schema: [ - { - type: "object", - properties: { - allowAsStatement: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ] - }, - - create(context) { - const allowAsStatement = - context.options[0] && context.options[0].allowAsStatement; - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - 'UnaryExpression[operator="void"]'(node) { - if ( - allowAsStatement && - node.parent && - node.parent.type === "ExpressionStatement" - ) { - return; - } - context.report({ - node, - messageId: "noVoid" - }); - } - }; - } -}; - -/** - * @fileoverview Rule that warns about used warning comments - * @author Alexander Schmidt - */ - -const { escapeRegExp } = lodash__default['default']; - - -const CHAR_LIMIT = 40; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noWarningComments = { - meta: { - type: "suggestion", - - docs: { - description: "disallow specified warning terms in comments", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/no-warning-comments" - }, - - schema: [ - { - type: "object", - properties: { - terms: { - type: "array", - items: { - type: "string" - } - }, - location: { - enum: ["start", "anywhere"] - } - }, - additionalProperties: false - } - ], - - messages: { - unexpectedComment: "Unexpected '{{matchedTerm}}' comment: '{{comment}}'." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(), - configuration = context.options[0] || {}, - warningTerms = configuration.terms || ["todo", "fixme", "xxx"], - location = configuration.location || "start", - selfConfigRegEx = /\bno-warning-comments\b/u; - - /** - * Convert a warning term into a RegExp which will match a comment containing that whole word in the specified - * location ("start" or "anywhere"). If the term starts or ends with non word characters, then the match will not - * require word boundaries on that side. - * @param {string} term A term to convert to a RegExp - * @returns {RegExp} The term converted to a RegExp - */ - function convertToRegExp(term) { - const escaped = escapeRegExp(term); - const wordBoundary = "\\b"; - const eitherOrWordBoundary = `|${wordBoundary}`; - let prefix; - - /* - * If the term ends in a word character (a-z0-9_), ensure a word - * boundary at the end, so that substrings do not get falsely - * matched. eg "todo" in a string such as "mastodon". - * If the term ends in a non-word character, then \b won't match on - * the boundary to the next non-word character, which would likely - * be a space. For example `/\bFIX!\b/.test('FIX! blah') === false`. - * In these cases, use no bounding match. Same applies for the - * prefix, handled below. - */ - const suffix = /\w$/u.test(term) ? "\\b" : ""; - - if (location === "start") { - - /* - * When matching at the start, ignore leading whitespace, and - * there's no need to worry about word boundaries. - */ - prefix = "^\\s*"; - } else if (/^\w/u.test(term)) { - prefix = wordBoundary; - } else { - prefix = ""; - } - - if (location === "start") { - - /* - * For location "start" the regex should be - * ^\s*TERM\b. This checks the word boundary - * at the beginning of the comment. - */ - return new RegExp(prefix + escaped + suffix, "iu"); - } - - /* - * For location "anywhere" the regex should be - * \bTERM\b|\bTERM\b, this checks the entire comment - * for the term. - */ - return new RegExp( - prefix + - escaped + - suffix + - eitherOrWordBoundary + - term + - wordBoundary, - "iu" - ); - } - - const warningRegExps = warningTerms.map(convertToRegExp); - - /** - * Checks the specified comment for matches of the configured warning terms and returns the matches. - * @param {string} comment The comment which is checked. - * @returns {Array} All matched warning terms for this comment. - */ - function commentContainsWarningTerm(comment) { - const matches = []; - - warningRegExps.forEach((regex, index) => { - if (regex.test(comment)) { - matches.push(warningTerms[index]); - } - }); - - return matches; - } - - /** - * Checks the specified node for matching warning comments and reports them. - * @param {ASTNode} node The AST node being checked. - * @returns {void} undefined. - */ - function checkComment(node) { - const comment = node.value; - - if ( - astUtils.isDirectiveComment(node) && - selfConfigRegEx.test(comment) - ) { - return; - } - - const matches = commentContainsWarningTerm(comment); - - matches.forEach(matchedTerm => { - let commentToDisplay = ""; - let truncated = false; - - for (const c of comment.trim().split(/\s+/u)) { - const tmp = commentToDisplay ? `${commentToDisplay} ${c}` : c; - - if (tmp.length <= CHAR_LIMIT) { - commentToDisplay = tmp; - } else { - truncated = true; - break; - } - } - - context.report({ - node, - messageId: "unexpectedComment", - data: { - matchedTerm, - comment: `${commentToDisplay}${ - truncated ? "..." : "" - }` - } - }); - }); - } - - return { - Program() { - const comments = sourceCode.getAllComments(); - - comments - .filter(token => token.type !== "Shebang") - .forEach(checkComment); - } - }; - } -}; - -/** - * @fileoverview Rule to disallow whitespace before properties - * @author Kai Cataldo - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noWhitespaceBeforeProperty = { - meta: { - type: "layout", - - docs: { - description: "disallow whitespace before properties", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/no-whitespace-before-property" - }, - - fixable: "whitespace", - schema: [], - - messages: { - unexpectedWhitespace: "Unexpected whitespace before property {{propName}}." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Reports whitespace before property token - * @param {ASTNode} node the node to report in the event of an error - * @param {Token} leftToken the left token - * @param {Token} rightToken the right token - * @returns {void} - * @private - */ - function reportError(node, leftToken, rightToken) { - context.report({ - node, - messageId: "unexpectedWhitespace", - data: { - propName: sourceCode.getText(node.property) - }, - fix(fixer) { - let replacementText = ""; - - if (!node.computed && !node.optional && astUtils.isDecimalInteger(node.object)) { - - /* - * If the object is a number literal, fixing it to something like 5.toString() would cause a SyntaxError. - * Don't fix this case. - */ - return null; - } - - // Don't fix if comments exist. - if (sourceCode.commentsExistBetween(leftToken, rightToken)) { - return null; - } - - if (node.optional) { - replacementText = "?."; - } else if (!node.computed) { - replacementText = "."; - } - - return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], replacementText); - } - }); - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - MemberExpression(node) { - let rightToken; - let leftToken; - - if (!astUtils.isTokenOnSameLine(node.object, node.property)) { - return; - } - - if (node.computed) { - rightToken = sourceCode.getTokenBefore(node.property, astUtils.isOpeningBracketToken); - leftToken = sourceCode.getTokenBefore(rightToken, node.optional ? 1 : 0); - } else { - rightToken = sourceCode.getFirstToken(node.property); - leftToken = sourceCode.getTokenBefore(rightToken, 1); - } - - if (sourceCode.isSpaceBetweenTokens(leftToken, rightToken)) { - reportError(node, leftToken, rightToken); - } - } - }; - } -}; - -/** - * @fileoverview Rule to flag use of with statement - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var noWith = { - meta: { - type: "suggestion", - - docs: { - description: "disallow `with` statements", - category: "Best Practices", - recommended: true, - url: "https://eslint.org/docs/rules/no-with" - }, - - schema: [], - - messages: { - unexpectedWith: "Unexpected use of 'with' statement." - } - }, - - create(context) { - - return { - WithStatement(node) { - context.report({ node, messageId: "unexpectedWith" }); - } - }; - - } -}; - -/** - * @fileoverview enforce the location of single-line statements - * @author Teddy Katz - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -const POSITION_SCHEMA = { enum: ["beside", "below", "any"] }; - -var nonblockStatementBodyPosition = { - meta: { - type: "layout", - - docs: { - description: "enforce the location of single-line statements", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/nonblock-statement-body-position" - }, - - fixable: "whitespace", - - schema: [ - POSITION_SCHEMA, - { - properties: { - overrides: { - properties: { - if: POSITION_SCHEMA, - else: POSITION_SCHEMA, - while: POSITION_SCHEMA, - do: POSITION_SCHEMA, - for: POSITION_SCHEMA - }, - additionalProperties: false - } - }, - additionalProperties: false - } - ], - - messages: { - expectNoLinebreak: "Expected no linebreak before this statement.", - expectLinebreak: "Expected a linebreak before this statement." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - //---------------------------------------------------------------------- - // Helpers - //---------------------------------------------------------------------- - - /** - * Gets the applicable preference for a particular keyword - * @param {string} keywordName The name of a keyword, e.g. 'if' - * @returns {string} The applicable option for the keyword, e.g. 'beside' - */ - function getOption(keywordName) { - return context.options[1] && context.options[1].overrides && context.options[1].overrides[keywordName] || - context.options[0] || - "beside"; - } - - /** - * Validates the location of a single-line statement - * @param {ASTNode} node The single-line statement - * @param {string} keywordName The applicable keyword name for the single-line statement - * @returns {void} - */ - function validateStatement(node, keywordName) { - const option = getOption(keywordName); - - if (node.type === "BlockStatement" || option === "any") { - return; - } - - const tokenBefore = sourceCode.getTokenBefore(node); - - if (tokenBefore.loc.end.line === node.loc.start.line && option === "below") { - context.report({ - node, - messageId: "expectLinebreak", - fix: fixer => fixer.insertTextBefore(node, "\n") - }); - } else if (tokenBefore.loc.end.line !== node.loc.start.line && option === "beside") { - context.report({ - node, - messageId: "expectNoLinebreak", - fix(fixer) { - if (sourceCode.getText().slice(tokenBefore.range[1], node.range[0]).trim()) { - return null; - } - return fixer.replaceTextRange([tokenBefore.range[1], node.range[0]], " "); - } - }); - } - } - - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - - return { - IfStatement(node) { - validateStatement(node.consequent, "if"); - - // Check the `else` node, but don't check 'else if' statements. - if (node.alternate && node.alternate.type !== "IfStatement") { - validateStatement(node.alternate, "else"); - } - }, - WhileStatement: node => validateStatement(node.body, "while"), - DoWhileStatement: node => validateStatement(node.body, "do"), - ForStatement: node => validateStatement(node.body, "for"), - ForInStatement: node => validateStatement(node.body, "for"), - ForOfStatement: node => validateStatement(node.body, "for") - }; - } -}; - -/** - * @fileoverview Rule to require or disallow line breaks inside braces. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -// Schema objects. -const OPTION_VALUE = { - oneOf: [ - { - enum: ["always", "never"] - }, - { - type: "object", - properties: { - multiline: { - type: "boolean" - }, - minProperties: { - type: "integer", - minimum: 0 - }, - consistent: { - type: "boolean" - } - }, - additionalProperties: false, - minProperties: 1 - } - ] -}; - -/** - * Normalizes a given option value. - * @param {string|Object|undefined} value An option value to parse. - * @returns {{multiline: boolean, minProperties: number, consistent: boolean}} Normalized option object. - */ -function normalizeOptionValue(value) { - let multiline = false; - let minProperties = Number.POSITIVE_INFINITY; - let consistent = false; - - if (value) { - if (value === "always") { - minProperties = 0; - } else if (value === "never") { - minProperties = Number.POSITIVE_INFINITY; - } else { - multiline = Boolean(value.multiline); - minProperties = value.minProperties || Number.POSITIVE_INFINITY; - consistent = Boolean(value.consistent); - } - } else { - consistent = true; - } - - return { multiline, minProperties, consistent }; -} - -/** - * Normalizes a given option value. - * @param {string|Object|undefined} options An option value to parse. - * @returns {{ - * ObjectExpression: {multiline: boolean, minProperties: number, consistent: boolean}, - * ObjectPattern: {multiline: boolean, minProperties: number, consistent: boolean}, - * ImportDeclaration: {multiline: boolean, minProperties: number, consistent: boolean}, - * ExportNamedDeclaration : {multiline: boolean, minProperties: number, consistent: boolean} - * }} Normalized option object. - */ -function normalizeOptions(options) { - const isNodeSpecificOption = lodash__default['default'].overSome([lodash__default['default'].isPlainObject, lodash__default['default'].isString]); - - if (lodash__default['default'].isPlainObject(options) && Object.values(options).some(isNodeSpecificOption)) { - return { - ObjectExpression: normalizeOptionValue(options.ObjectExpression), - ObjectPattern: normalizeOptionValue(options.ObjectPattern), - ImportDeclaration: normalizeOptionValue(options.ImportDeclaration), - ExportNamedDeclaration: normalizeOptionValue(options.ExportDeclaration) - }; - } - - const value = normalizeOptionValue(options); - - return { ObjectExpression: value, ObjectPattern: value, ImportDeclaration: value, ExportNamedDeclaration: value }; -} - -/** - * Determines if ObjectExpression, ObjectPattern, ImportDeclaration or ExportNamedDeclaration - * node needs to be checked for missing line breaks - * @param {ASTNode} node Node under inspection - * @param {Object} options option specific to node type - * @param {Token} first First object property - * @param {Token} last Last object property - * @returns {boolean} `true` if node needs to be checked for missing line breaks - */ -function areLineBreaksRequired(node, options, first, last) { - let objectProperties; - - if (node.type === "ObjectExpression" || node.type === "ObjectPattern") { - objectProperties = node.properties; - } else { - - // is ImportDeclaration or ExportNamedDeclaration - objectProperties = node.specifiers - .filter(s => s.type === "ImportSpecifier" || s.type === "ExportSpecifier"); - } - - return objectProperties.length >= options.minProperties || - ( - options.multiline && - objectProperties.length > 0 && - first.loc.start.line !== last.loc.end.line - ); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var objectCurlyNewline = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent line breaks after opening and before closing braces", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/object-curly-newline" - }, - - fixable: "whitespace", - - schema: [ - { - oneOf: [ - OPTION_VALUE, - { - type: "object", - properties: { - ObjectExpression: OPTION_VALUE, - ObjectPattern: OPTION_VALUE, - ImportDeclaration: OPTION_VALUE, - ExportDeclaration: OPTION_VALUE - }, - additionalProperties: false, - minProperties: 1 - } - ] - } - ], - - messages: { - unexpectedLinebreakBeforeClosingBrace: "Unexpected line break before this closing brace.", - unexpectedLinebreakAfterOpeningBrace: "Unexpected line break after this opening brace.", - expectedLinebreakBeforeClosingBrace: "Expected a line break before this closing brace.", - expectedLinebreakAfterOpeningBrace: "Expected a line break after this opening brace." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const normalizedOptions = normalizeOptions(context.options[0]); - - /** - * Reports a given node if it violated this rule. - * @param {ASTNode} node A node to check. This is an ObjectExpression, ObjectPattern, ImportDeclaration or ExportNamedDeclaration node. - * @returns {void} - */ - function check(node) { - const options = normalizedOptions[node.type]; - - if ( - (node.type === "ImportDeclaration" && - !node.specifiers.some(specifier => specifier.type === "ImportSpecifier")) || - (node.type === "ExportNamedDeclaration" && - !node.specifiers.some(specifier => specifier.type === "ExportSpecifier")) - ) { - return; - } - - const openBrace = sourceCode.getFirstToken(node, token => token.value === "{"); - - let closeBrace; - - if (node.typeAnnotation) { - closeBrace = sourceCode.getTokenBefore(node.typeAnnotation); - } else { - closeBrace = sourceCode.getLastToken(node, token => token.value === "}"); - } - - let first = sourceCode.getTokenAfter(openBrace, { includeComments: true }); - let last = sourceCode.getTokenBefore(closeBrace, { includeComments: true }); - - const needsLineBreaks = areLineBreaksRequired(node, options, first, last); - - const hasCommentsFirstToken = astUtils.isCommentToken(first); - const hasCommentsLastToken = astUtils.isCommentToken(last); - - /* - * Use tokens or comments to check multiline or not. - * But use only tokens to check whether line breaks are needed. - * This allows: - * var obj = { // eslint-disable-line foo - * a: 1 - * } - */ - first = sourceCode.getTokenAfter(openBrace); - last = sourceCode.getTokenBefore(closeBrace); - - if (needsLineBreaks) { - if (astUtils.isTokenOnSameLine(openBrace, first)) { - context.report({ - messageId: "expectedLinebreakAfterOpeningBrace", - node, - loc: openBrace.loc, - fix(fixer) { - if (hasCommentsFirstToken) { - return null; - } - - return fixer.insertTextAfter(openBrace, "\n"); - } - }); - } - if (astUtils.isTokenOnSameLine(last, closeBrace)) { - context.report({ - messageId: "expectedLinebreakBeforeClosingBrace", - node, - loc: closeBrace.loc, - fix(fixer) { - if (hasCommentsLastToken) { - return null; - } - - return fixer.insertTextBefore(closeBrace, "\n"); - } - }); - } - } else { - const consistent = options.consistent; - const hasLineBreakBetweenOpenBraceAndFirst = !astUtils.isTokenOnSameLine(openBrace, first); - const hasLineBreakBetweenCloseBraceAndLast = !astUtils.isTokenOnSameLine(last, closeBrace); - - if ( - (!consistent && hasLineBreakBetweenOpenBraceAndFirst) || - (consistent && hasLineBreakBetweenOpenBraceAndFirst && !hasLineBreakBetweenCloseBraceAndLast) - ) { - context.report({ - messageId: "unexpectedLinebreakAfterOpeningBrace", - node, - loc: openBrace.loc, - fix(fixer) { - if (hasCommentsFirstToken) { - return null; - } - - return fixer.removeRange([ - openBrace.range[1], - first.range[0] - ]); - } - }); - } - if ( - (!consistent && hasLineBreakBetweenCloseBraceAndLast) || - (consistent && !hasLineBreakBetweenOpenBraceAndFirst && hasLineBreakBetweenCloseBraceAndLast) - ) { - context.report({ - messageId: "unexpectedLinebreakBeforeClosingBrace", - node, - loc: closeBrace.loc, - fix(fixer) { - if (hasCommentsLastToken) { - return null; - } - - return fixer.removeRange([ - last.range[1], - closeBrace.range[0] - ]); - } - }); - } - } - } - - return { - ObjectExpression: check, - ObjectPattern: check, - ImportDeclaration: check, - ExportNamedDeclaration: check - }; - } -}; - -/** - * @fileoverview Disallows or enforces spaces inside of object literals. - * @author Jamund Ferguson - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var objectCurlySpacing = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent spacing inside braces", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/object-curly-spacing" - }, - - fixable: "whitespace", - - schema: [ - { - enum: ["always", "never"] - }, - { - type: "object", - properties: { - arraysInObjects: { - type: "boolean" - }, - objectsInObjects: { - type: "boolean" - } - }, - additionalProperties: false - } - ], - - messages: { - requireSpaceBefore: "A space is required before '{{token}}'.", - requireSpaceAfter: "A space is required after '{{token}}'.", - unexpectedSpaceBefore: "There should be no space before '{{token}}'.", - unexpectedSpaceAfter: "There should be no space after '{{token}}'." - } - }, - - create(context) { - const spaced = context.options[0] === "always", - sourceCode = context.getSourceCode(); - - /** - * Determines whether an option is set, relative to the spacing option. - * If spaced is "always", then check whether option is set to false. - * If spaced is "never", then check whether option is set to true. - * @param {Object} option The option to exclude. - * @returns {boolean} Whether or not the property is excluded. - */ - function isOptionSet(option) { - return context.options[1] ? context.options[1][option] === !spaced : false; - } - - const options = { - spaced, - arraysInObjectsException: isOptionSet("arraysInObjects"), - objectsInObjectsException: isOptionSet("objectsInObjects") - }; - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Reports that there shouldn't be a space after the first token - * @param {ASTNode} node The node to report in the event of an error. - * @param {Token} token The token to use for the report. - * @returns {void} - */ - function reportNoBeginningSpace(node, token) { - const nextToken = context.getSourceCode().getTokenAfter(token, { includeComments: true }); - - context.report({ - node, - loc: { start: token.loc.end, end: nextToken.loc.start }, - messageId: "unexpectedSpaceAfter", - data: { - token: token.value - }, - fix(fixer) { - return fixer.removeRange([token.range[1], nextToken.range[0]]); - } - }); - } - - /** - * Reports that there shouldn't be a space before the last token - * @param {ASTNode} node The node to report in the event of an error. - * @param {Token} token The token to use for the report. - * @returns {void} - */ - function reportNoEndingSpace(node, token) { - const previousToken = context.getSourceCode().getTokenBefore(token, { includeComments: true }); - - context.report({ - node, - loc: { start: previousToken.loc.end, end: token.loc.start }, - messageId: "unexpectedSpaceBefore", - data: { - token: token.value - }, - fix(fixer) { - return fixer.removeRange([previousToken.range[1], token.range[0]]); - } - }); - } - - /** - * Reports that there should be a space after the first token - * @param {ASTNode} node The node to report in the event of an error. - * @param {Token} token The token to use for the report. - * @returns {void} - */ - function reportRequiredBeginningSpace(node, token) { - context.report({ - node, - loc: token.loc, - messageId: "requireSpaceAfter", - data: { - token: token.value - }, - fix(fixer) { - return fixer.insertTextAfter(token, " "); - } - }); - } - - /** - * Reports that there should be a space before the last token - * @param {ASTNode} node The node to report in the event of an error. - * @param {Token} token The token to use for the report. - * @returns {void} - */ - function reportRequiredEndingSpace(node, token) { - context.report({ - node, - loc: token.loc, - messageId: "requireSpaceBefore", - data: { - token: token.value - }, - fix(fixer) { - return fixer.insertTextBefore(token, " "); - } - }); - } - - /** - * Determines if spacing in curly braces is valid. - * @param {ASTNode} node The AST node to check. - * @param {Token} first The first token to check (should be the opening brace) - * @param {Token} second The second token to check (should be first after the opening brace) - * @param {Token} penultimate The penultimate token to check (should be last before closing brace) - * @param {Token} last The last token to check (should be closing brace) - * @returns {void} - */ - function validateBraceSpacing(node, first, second, penultimate, last) { - if (astUtils.isTokenOnSameLine(first, second)) { - const firstSpaced = sourceCode.isSpaceBetweenTokens(first, second); - - if (options.spaced && !firstSpaced) { - reportRequiredBeginningSpace(node, first); - } - if (!options.spaced && firstSpaced && second.type !== "Line") { - reportNoBeginningSpace(node, first); - } - } - - if (astUtils.isTokenOnSameLine(penultimate, last)) { - const shouldCheckPenultimate = ( - options.arraysInObjectsException && astUtils.isClosingBracketToken(penultimate) || - options.objectsInObjectsException && astUtils.isClosingBraceToken(penultimate) - ); - const penultimateType = shouldCheckPenultimate && sourceCode.getNodeByRangeIndex(penultimate.range[0]).type; - - const closingCurlyBraceMustBeSpaced = ( - options.arraysInObjectsException && penultimateType === "ArrayExpression" || - options.objectsInObjectsException && (penultimateType === "ObjectExpression" || penultimateType === "ObjectPattern") - ) ? !options.spaced : options.spaced; - - const lastSpaced = sourceCode.isSpaceBetweenTokens(penultimate, last); - - if (closingCurlyBraceMustBeSpaced && !lastSpaced) { - reportRequiredEndingSpace(node, last); - } - if (!closingCurlyBraceMustBeSpaced && lastSpaced) { - reportNoEndingSpace(node, last); - } - } - } - - /** - * Gets '}' token of an object node. - * - * Because the last token of object patterns might be a type annotation, - * this traverses tokens preceded by the last property, then returns the - * first '}' token. - * @param {ASTNode} node The node to get. This node is an - * ObjectExpression or an ObjectPattern. And this node has one or - * more properties. - * @returns {Token} '}' token. - */ - function getClosingBraceOfObject(node) { - const lastProperty = node.properties[node.properties.length - 1]; - - return sourceCode.getTokenAfter(lastProperty, astUtils.isClosingBraceToken); - } - - /** - * Reports a given object node if spacing in curly braces is invalid. - * @param {ASTNode} node An ObjectExpression or ObjectPattern node to check. - * @returns {void} - */ - function checkForObject(node) { - if (node.properties.length === 0) { - return; - } - - const first = sourceCode.getFirstToken(node), - last = getClosingBraceOfObject(node), - second = sourceCode.getTokenAfter(first, { includeComments: true }), - penultimate = sourceCode.getTokenBefore(last, { includeComments: true }); - - validateBraceSpacing(node, first, second, penultimate, last); - } - - /** - * Reports a given import node if spacing in curly braces is invalid. - * @param {ASTNode} node An ImportDeclaration node to check. - * @returns {void} - */ - function checkForImport(node) { - if (node.specifiers.length === 0) { - return; - } - - let firstSpecifier = node.specifiers[0]; - const lastSpecifier = node.specifiers[node.specifiers.length - 1]; - - if (lastSpecifier.type !== "ImportSpecifier") { - return; - } - if (firstSpecifier.type !== "ImportSpecifier") { - firstSpecifier = node.specifiers[1]; - } - - const first = sourceCode.getTokenBefore(firstSpecifier), - last = sourceCode.getTokenAfter(lastSpecifier, astUtils.isNotCommaToken), - second = sourceCode.getTokenAfter(first, { includeComments: true }), - penultimate = sourceCode.getTokenBefore(last, { includeComments: true }); - - validateBraceSpacing(node, first, second, penultimate, last); - } - - /** - * Reports a given export node if spacing in curly braces is invalid. - * @param {ASTNode} node An ExportNamedDeclaration node to check. - * @returns {void} - */ - function checkForExport(node) { - if (node.specifiers.length === 0) { - return; - } - - const firstSpecifier = node.specifiers[0], - lastSpecifier = node.specifiers[node.specifiers.length - 1], - first = sourceCode.getTokenBefore(firstSpecifier), - last = sourceCode.getTokenAfter(lastSpecifier, astUtils.isNotCommaToken), - second = sourceCode.getTokenAfter(first, { includeComments: true }), - penultimate = sourceCode.getTokenBefore(last, { includeComments: true }); - - validateBraceSpacing(node, first, second, penultimate, last); - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - - // var {x} = y; - ObjectPattern: checkForObject, - - // var y = {x: 'y'} - ObjectExpression: checkForObject, - - // import {y} from 'x'; - ImportDeclaration: checkForImport, - - // export {name} from 'yo'; - ExportNamedDeclaration: checkForExport - }; - - } -}; - -/** - * @fileoverview Rule to enforce placing object properties on separate lines. - * @author Vitor Balocco - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var objectPropertyNewline = { - meta: { - type: "layout", - - docs: { - description: "enforce placing object properties on separate lines", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/object-property-newline" - }, - - schema: [ - { - type: "object", - properties: { - allowAllPropertiesOnSameLine: { - type: "boolean", - default: false - }, - allowMultiplePropertiesPerLine: { // Deprecated - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - fixable: "whitespace", - - messages: { - propertiesOnNewlineAll: "Object properties must go on a new line if they aren't all on the same line.", - propertiesOnNewline: "Object properties must go on a new line." - } - }, - - create(context) { - const allowSameLine = context.options[0] && ( - (context.options[0].allowAllPropertiesOnSameLine || context.options[0].allowMultiplePropertiesPerLine /* Deprecated */) - ); - const messageId = allowSameLine - ? "propertiesOnNewlineAll" - : "propertiesOnNewline"; - - const sourceCode = context.getSourceCode(); - - return { - ObjectExpression(node) { - if (allowSameLine) { - if (node.properties.length > 1) { - const firstTokenOfFirstProperty = sourceCode.getFirstToken(node.properties[0]); - const lastTokenOfLastProperty = sourceCode.getLastToken(node.properties[node.properties.length - 1]); - - if (firstTokenOfFirstProperty.loc.end.line === lastTokenOfLastProperty.loc.start.line) { - - // All keys and values are on the same line - return; - } - } - } - - for (let i = 1; i < node.properties.length; i++) { - const lastTokenOfPreviousProperty = sourceCode.getLastToken(node.properties[i - 1]); - const firstTokenOfCurrentProperty = sourceCode.getFirstToken(node.properties[i]); - - if (lastTokenOfPreviousProperty.loc.end.line === firstTokenOfCurrentProperty.loc.start.line) { - context.report({ - node, - loc: firstTokenOfCurrentProperty.loc, - messageId, - fix(fixer) { - const comma = sourceCode.getTokenBefore(firstTokenOfCurrentProperty); - const rangeAfterComma = [comma.range[1], firstTokenOfCurrentProperty.range[0]]; - - // Don't perform a fix if there are any comments between the comma and the next property. - if (sourceCode.text.slice(rangeAfterComma[0], rangeAfterComma[1]).trim()) { - return null; - } - - return fixer.replaceTextRange(rangeAfterComma, "\n"); - } - }); - } - } - } - }; - } -}; - -/** - * @fileoverview Rule to enforce concise object methods and properties. - * @author Jamund Ferguson - */ - -const OPTIONS = { - always: "always", - never: "never", - methods: "methods", - properties: "properties", - consistent: "consistent", - consistentAsNeeded: "consistent-as-needed" -}; - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ -var objectShorthand = { - meta: { - type: "suggestion", - - docs: { - description: "require or disallow method and property shorthand syntax for object literals", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/object-shorthand" - }, - - fixable: "code", - - schema: { - anyOf: [ - { - type: "array", - items: [ - { - enum: ["always", "methods", "properties", "never", "consistent", "consistent-as-needed"] - } - ], - minItems: 0, - maxItems: 1 - }, - { - type: "array", - items: [ - { - enum: ["always", "methods", "properties"] - }, - { - type: "object", - properties: { - avoidQuotes: { - type: "boolean" - } - }, - additionalProperties: false - } - ], - minItems: 0, - maxItems: 2 - }, - { - type: "array", - items: [ - { - enum: ["always", "methods"] - }, - { - type: "object", - properties: { - ignoreConstructors: { - type: "boolean" - }, - avoidQuotes: { - type: "boolean" - }, - avoidExplicitReturnArrows: { - type: "boolean" - } - }, - additionalProperties: false - } - ], - minItems: 0, - maxItems: 2 - } - ] - }, - - messages: { - expectedAllPropertiesShorthanded: "Expected shorthand for all properties.", - expectedLiteralMethodLongform: "Expected longform method syntax for string literal keys.", - expectedPropertyShorthand: "Expected property shorthand.", - expectedPropertyLongform: "Expected longform property syntax.", - expectedMethodShorthand: "Expected method shorthand.", - expectedMethodLongform: "Expected longform method syntax.", - unexpectedMix: "Unexpected mix of shorthand and non-shorthand properties." - } - }, - - create(context) { - const APPLY = context.options[0] || OPTIONS.always; - const APPLY_TO_METHODS = APPLY === OPTIONS.methods || APPLY === OPTIONS.always; - const APPLY_TO_PROPS = APPLY === OPTIONS.properties || APPLY === OPTIONS.always; - const APPLY_NEVER = APPLY === OPTIONS.never; - const APPLY_CONSISTENT = APPLY === OPTIONS.consistent; - const APPLY_CONSISTENT_AS_NEEDED = APPLY === OPTIONS.consistentAsNeeded; - - const PARAMS = context.options[1] || {}; - const IGNORE_CONSTRUCTORS = PARAMS.ignoreConstructors; - const AVOID_QUOTES = PARAMS.avoidQuotes; - const AVOID_EXPLICIT_RETURN_ARROWS = !!PARAMS.avoidExplicitReturnArrows; - const sourceCode = context.getSourceCode(); - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - const CTOR_PREFIX_REGEX = /[^_$0-9]/u; - - /** - * Determines if the first character of the name is a capital letter. - * @param {string} name The name of the node to evaluate. - * @returns {boolean} True if the first character of the property name is a capital letter, false if not. - * @private - */ - function isConstructor(name) { - const match = CTOR_PREFIX_REGEX.exec(name); - - // Not a constructor if name has no characters apart from '_', '$' and digits e.g. '_', '$$', '_8' - if (!match) { - return false; - } - - const firstChar = name.charAt(match.index); - - return firstChar === firstChar.toUpperCase(); - } - - /** - * Determines if the property can have a shorthand form. - * @param {ASTNode} property Property AST node - * @returns {boolean} True if the property can have a shorthand form - * @private - * - */ - function canHaveShorthand(property) { - return (property.kind !== "set" && property.kind !== "get" && property.type !== "SpreadElement" && property.type !== "SpreadProperty" && property.type !== "ExperimentalSpreadProperty"); - } - - /** - * Checks whether a node is a string literal. - * @param {ASTNode} node Any AST node. - * @returns {boolean} `true` if it is a string literal. - */ - function isStringLiteral(node) { - return node.type === "Literal" && typeof node.value === "string"; - } - - /** - * Determines if the property is a shorthand or not. - * @param {ASTNode} property Property AST node - * @returns {boolean} True if the property is considered shorthand, false if not. - * @private - * - */ - function isShorthand(property) { - - // property.method is true when `{a(){}}`. - return (property.shorthand || property.method); - } - - /** - * Determines if the property's key and method or value are named equally. - * @param {ASTNode} property Property AST node - * @returns {boolean} True if the key and value are named equally, false if not. - * @private - * - */ - function isRedundant(property) { - const value = property.value; - - if (value.type === "FunctionExpression") { - return !value.id; // Only anonymous should be shorthand method. - } - if (value.type === "Identifier") { - return astUtils.getStaticPropertyName(property) === value.name; - } - - return false; - } - - /** - * Ensures that an object's properties are consistently shorthand, or not shorthand at all. - * @param {ASTNode} node Property AST node - * @param {boolean} checkRedundancy Whether to check longform redundancy - * @returns {void} - * - */ - function checkConsistency(node, checkRedundancy) { - - // We are excluding getters/setters and spread properties as they are considered neither longform nor shorthand. - const properties = node.properties.filter(canHaveShorthand); - - // Do we still have properties left after filtering the getters and setters? - if (properties.length > 0) { - const shorthandProperties = properties.filter(isShorthand); - - /* - * If we do not have an equal number of longform properties as - * shorthand properties, we are using the annotations inconsistently - */ - if (shorthandProperties.length !== properties.length) { - - // We have at least 1 shorthand property - if (shorthandProperties.length > 0) { - context.report({ node, messageId: "unexpectedMix" }); - } else if (checkRedundancy) { - - /* - * If all properties of the object contain a method or value with a name matching it's key, - * all the keys are redundant. - */ - const canAlwaysUseShorthand = properties.every(isRedundant); - - if (canAlwaysUseShorthand) { - context.report({ node, messageId: "expectedAllPropertiesShorthanded" }); - } - } - } - } - } - - /** - * Fixes a FunctionExpression node by making it into a shorthand property. - * @param {SourceCodeFixer} fixer The fixer object - * @param {ASTNode} node A `Property` node that has a `FunctionExpression` or `ArrowFunctionExpression` as its value - * @returns {Object} A fix for this node - */ - function makeFunctionShorthand(fixer, node) { - const firstKeyToken = node.computed - ? sourceCode.getFirstToken(node, astUtils.isOpeningBracketToken) - : sourceCode.getFirstToken(node.key); - const lastKeyToken = node.computed - ? sourceCode.getFirstTokenBetween(node.key, node.value, astUtils.isClosingBracketToken) - : sourceCode.getLastToken(node.key); - const keyText = sourceCode.text.slice(firstKeyToken.range[0], lastKeyToken.range[1]); - let keyPrefix = ""; - - // key: /* */ () => {} - if (sourceCode.commentsExistBetween(lastKeyToken, node.value)) { - return null; - } - - if (node.value.async) { - keyPrefix += "async "; - } - if (node.value.generator) { - keyPrefix += "*"; - } - - const fixRange = [firstKeyToken.range[0], node.range[1]]; - const methodPrefix = keyPrefix + keyText; - - if (node.value.type === "FunctionExpression") { - const functionToken = sourceCode.getTokens(node.value).find(token => token.type === "Keyword" && token.value === "function"); - const tokenBeforeParams = node.value.generator ? sourceCode.getTokenAfter(functionToken) : functionToken; - - return fixer.replaceTextRange( - fixRange, - methodPrefix + sourceCode.text.slice(tokenBeforeParams.range[1], node.value.range[1]) - ); - } - - const arrowToken = sourceCode.getTokenBefore(node.value.body, astUtils.isArrowToken); - const fnBody = sourceCode.text.slice(arrowToken.range[1], node.value.range[1]); - - let shouldAddParensAroundParameters = false; - let tokenBeforeParams; - - if (node.value.params.length === 0) { - tokenBeforeParams = sourceCode.getFirstToken(node.value, astUtils.isOpeningParenToken); - } else { - tokenBeforeParams = sourceCode.getTokenBefore(node.value.params[0]); - } - - if (node.value.params.length === 1) { - const hasParen = astUtils.isOpeningParenToken(tokenBeforeParams); - const isTokenOutsideNode = tokenBeforeParams.range[0] < node.range[0]; - - shouldAddParensAroundParameters = !hasParen || isTokenOutsideNode; - } - - const sliceStart = shouldAddParensAroundParameters - ? node.value.params[0].range[0] - : tokenBeforeParams.range[0]; - const sliceEnd = sourceCode.getTokenBefore(arrowToken).range[1]; - - const oldParamText = sourceCode.text.slice(sliceStart, sliceEnd); - const newParamText = shouldAddParensAroundParameters ? `(${oldParamText})` : oldParamText; - - return fixer.replaceTextRange( - fixRange, - methodPrefix + newParamText + fnBody - ); - - } - - /** - * Fixes a FunctionExpression node by making it into a longform property. - * @param {SourceCodeFixer} fixer The fixer object - * @param {ASTNode} node A `Property` node that has a `FunctionExpression` as its value - * @returns {Object} A fix for this node - */ - function makeFunctionLongform(fixer, node) { - const firstKeyToken = node.computed ? sourceCode.getTokens(node).find(token => token.value === "[") : sourceCode.getFirstToken(node.key); - const lastKeyToken = node.computed ? sourceCode.getTokensBetween(node.key, node.value).find(token => token.value === "]") : sourceCode.getLastToken(node.key); - const keyText = sourceCode.text.slice(firstKeyToken.range[0], lastKeyToken.range[1]); - let functionHeader = "function"; - - if (node.value.async) { - functionHeader = `async ${functionHeader}`; - } - if (node.value.generator) { - functionHeader = `${functionHeader}*`; - } - - return fixer.replaceTextRange([node.range[0], lastKeyToken.range[1]], `${keyText}: ${functionHeader}`); - } - - /* - * To determine whether a given arrow function has a lexical identifier (`this`, `arguments`, `super`, or `new.target`), - * create a stack of functions that define these identifiers (i.e. all functions except arrow functions) as the AST is - * traversed. Whenever a new function is encountered, create a new entry on the stack (corresponding to a different lexical - * scope of `this`), and whenever a function is exited, pop that entry off the stack. When an arrow function is entered, - * keep a reference to it on the current stack entry, and remove that reference when the arrow function is exited. - * When a lexical identifier is encountered, mark all the arrow functions on the current stack entry by adding them - * to an `arrowsWithLexicalIdentifiers` set. Any arrow function in that set will not be reported by this rule, - * because converting it into a method would change the value of one of the lexical identifiers. - */ - const lexicalScopeStack = []; - const arrowsWithLexicalIdentifiers = new WeakSet(); - const argumentsIdentifiers = new WeakSet(); - - /** - * Enters a function. This creates a new lexical identifier scope, so a new Set of arrow functions is pushed onto the stack. - * Also, this marks all `arguments` identifiers so that they can be detected later. - * @returns {void} - */ - function enterFunction() { - lexicalScopeStack.unshift(new Set()); - context.getScope().variables.filter(variable => variable.name === "arguments").forEach(variable => { - variable.references.map(ref => ref.identifier).forEach(identifier => argumentsIdentifiers.add(identifier)); - }); - } - - /** - * Exits a function. This pops the current set of arrow functions off the lexical scope stack. - * @returns {void} - */ - function exitFunction() { - lexicalScopeStack.shift(); - } - - /** - * Marks the current function as having a lexical keyword. This implies that all arrow functions - * in the current lexical scope contain a reference to this lexical keyword. - * @returns {void} - */ - function reportLexicalIdentifier() { - lexicalScopeStack[0].forEach(arrowFunction => arrowsWithLexicalIdentifiers.add(arrowFunction)); - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - Program: enterFunction, - FunctionDeclaration: enterFunction, - FunctionExpression: enterFunction, - "Program:exit": exitFunction, - "FunctionDeclaration:exit": exitFunction, - "FunctionExpression:exit": exitFunction, - - ArrowFunctionExpression(node) { - lexicalScopeStack[0].add(node); - }, - "ArrowFunctionExpression:exit"(node) { - lexicalScopeStack[0].delete(node); - }, - - ThisExpression: reportLexicalIdentifier, - Super: reportLexicalIdentifier, - MetaProperty(node) { - if (node.meta.name === "new" && node.property.name === "target") { - reportLexicalIdentifier(); - } - }, - Identifier(node) { - if (argumentsIdentifiers.has(node)) { - reportLexicalIdentifier(); - } - }, - - ObjectExpression(node) { - if (APPLY_CONSISTENT) { - checkConsistency(node, false); - } else if (APPLY_CONSISTENT_AS_NEEDED) { - checkConsistency(node, true); - } - }, - - "Property:exit"(node) { - const isConciseProperty = node.method || node.shorthand; - - // Ignore destructuring assignment - if (node.parent.type === "ObjectPattern") { - return; - } - - // getters and setters are ignored - if (node.kind === "get" || node.kind === "set") { - return; - } - - // only computed methods can fail the following checks - if (node.computed && node.value.type !== "FunctionExpression" && node.value.type !== "ArrowFunctionExpression") { - return; - } - - //-------------------------------------------------------------- - // Checks for property/method shorthand. - if (isConciseProperty) { - if (node.method && (APPLY_NEVER || AVOID_QUOTES && isStringLiteral(node.key))) { - const messageId = APPLY_NEVER ? "expectedMethodLongform" : "expectedLiteralMethodLongform"; - - // { x() {} } should be written as { x: function() {} } - context.report({ - node, - messageId, - fix: fixer => makeFunctionLongform(fixer, node) - }); - } else if (APPLY_NEVER) { - - // { x } should be written as { x: x } - context.report({ - node, - messageId: "expectedPropertyLongform", - fix: fixer => fixer.insertTextAfter(node.key, `: ${node.key.name}`) - }); - } - } else if (APPLY_TO_METHODS && !node.value.id && (node.value.type === "FunctionExpression" || node.value.type === "ArrowFunctionExpression")) { - if (IGNORE_CONSTRUCTORS && node.key.type === "Identifier" && isConstructor(node.key.name)) { - return; - } - if (AVOID_QUOTES && isStringLiteral(node.key)) { - return; - } - - // {[x]: function(){}} should be written as {[x]() {}} - if (node.value.type === "FunctionExpression" || - node.value.type === "ArrowFunctionExpression" && - node.value.body.type === "BlockStatement" && - AVOID_EXPLICIT_RETURN_ARROWS && - !arrowsWithLexicalIdentifiers.has(node.value) - ) { - context.report({ - node, - messageId: "expectedMethodShorthand", - fix: fixer => makeFunctionShorthand(fixer, node) - }); - } - } else if (node.value.type === "Identifier" && node.key.name === node.value.name && APPLY_TO_PROPS) { - - // {x: x} should be written as {x} - context.report({ - node, - messageId: "expectedPropertyShorthand", - fix(fixer) { - return fixer.replaceText(node, node.value.name); - } - }); - } else if (node.value.type === "Identifier" && node.key.type === "Literal" && node.key.value === node.value.name && APPLY_TO_PROPS) { - if (AVOID_QUOTES) { - return; - } - - // {"x": x} should be written as {x} - context.report({ - node, - messageId: "expectedPropertyShorthand", - fix(fixer) { - return fixer.replaceText(node, node.value.name); - } - }); - } - } - }; - } -}; - -/** - * @fileoverview A rule to control the use of single variable declarations. - * @author Ian Christian Myers - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Determines whether the given node is in a statement list. - * @param {ASTNode} node node to check - * @returns {boolean} `true` if the given node is in a statement list - */ -function isInStatementList(node) { - return astUtils.STATEMENT_LIST_PARENTS.has(node.parent.type); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var oneVar = { - meta: { - type: "suggestion", - - docs: { - description: "enforce variables to be declared either together or separately in functions", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/one-var" - }, - - fixable: "code", - - schema: [ - { - oneOf: [ - { - enum: ["always", "never", "consecutive"] - }, - { - type: "object", - properties: { - separateRequires: { - type: "boolean" - }, - var: { - enum: ["always", "never", "consecutive"] - }, - let: { - enum: ["always", "never", "consecutive"] - }, - const: { - enum: ["always", "never", "consecutive"] - } - }, - additionalProperties: false - }, - { - type: "object", - properties: { - initialized: { - enum: ["always", "never", "consecutive"] - }, - uninitialized: { - enum: ["always", "never", "consecutive"] - } - }, - additionalProperties: false - } - ] - } - ], - - messages: { - combineUninitialized: "Combine this with the previous '{{type}}' statement with uninitialized variables.", - combineInitialized: "Combine this with the previous '{{type}}' statement with initialized variables.", - splitUninitialized: "Split uninitialized '{{type}}' declarations into multiple statements.", - splitInitialized: "Split initialized '{{type}}' declarations into multiple statements.", - splitRequires: "Split requires to be separated into a single block.", - combine: "Combine this with the previous '{{type}}' statement.", - split: "Split '{{type}}' declarations into multiple statements." - } - }, - - create(context) { - const MODE_ALWAYS = "always"; - const MODE_NEVER = "never"; - const MODE_CONSECUTIVE = "consecutive"; - const mode = context.options[0] || MODE_ALWAYS; - - const options = {}; - - if (typeof mode === "string") { // simple options configuration with just a string - options.var = { uninitialized: mode, initialized: mode }; - options.let = { uninitialized: mode, initialized: mode }; - options.const = { uninitialized: mode, initialized: mode }; - } else if (typeof mode === "object") { // options configuration is an object - options.separateRequires = !!mode.separateRequires; - options.var = { uninitialized: mode.var, initialized: mode.var }; - options.let = { uninitialized: mode.let, initialized: mode.let }; - options.const = { uninitialized: mode.const, initialized: mode.const }; - if (Object.prototype.hasOwnProperty.call(mode, "uninitialized")) { - options.var.uninitialized = mode.uninitialized; - options.let.uninitialized = mode.uninitialized; - options.const.uninitialized = mode.uninitialized; - } - if (Object.prototype.hasOwnProperty.call(mode, "initialized")) { - options.var.initialized = mode.initialized; - options.let.initialized = mode.initialized; - options.const.initialized = mode.initialized; - } - } - - const sourceCode = context.getSourceCode(); - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - const functionStack = []; - const blockStack = []; - - /** - * Increments the blockStack counter. - * @returns {void} - * @private - */ - function startBlock() { - blockStack.push({ - let: { initialized: false, uninitialized: false }, - const: { initialized: false, uninitialized: false } - }); - } - - /** - * Increments the functionStack counter. - * @returns {void} - * @private - */ - function startFunction() { - functionStack.push({ initialized: false, uninitialized: false }); - startBlock(); - } - - /** - * Decrements the blockStack counter. - * @returns {void} - * @private - */ - function endBlock() { - blockStack.pop(); - } - - /** - * Decrements the functionStack counter. - * @returns {void} - * @private - */ - function endFunction() { - functionStack.pop(); - endBlock(); - } - - /** - * Check if a variable declaration is a require. - * @param {ASTNode} decl variable declaration Node - * @returns {bool} if decl is a require, return true; else return false. - * @private - */ - function isRequire(decl) { - return decl.init && decl.init.type === "CallExpression" && decl.init.callee.name === "require"; - } - - /** - * Records whether initialized/uninitialized/required variables are defined in current scope. - * @param {string} statementType node.kind, one of: "var", "let", or "const" - * @param {ASTNode[]} declarations List of declarations - * @param {Object} currentScope The scope being investigated - * @returns {void} - * @private - */ - function recordTypes(statementType, declarations, currentScope) { - for (let i = 0; i < declarations.length; i++) { - if (declarations[i].init === null) { - if (options[statementType] && options[statementType].uninitialized === MODE_ALWAYS) { - currentScope.uninitialized = true; - } - } else { - if (options[statementType] && options[statementType].initialized === MODE_ALWAYS) { - if (options.separateRequires && isRequire(declarations[i])) { - currentScope.required = true; - } else { - currentScope.initialized = true; - } - } - } - } - } - - /** - * Determines the current scope (function or block) - * @param {string} statementType node.kind, one of: "var", "let", or "const" - * @returns {Object} The scope associated with statementType - */ - function getCurrentScope(statementType) { - let currentScope; - - if (statementType === "var") { - currentScope = functionStack[functionStack.length - 1]; - } else if (statementType === "let") { - currentScope = blockStack[blockStack.length - 1].let; - } else if (statementType === "const") { - currentScope = blockStack[blockStack.length - 1].const; - } - return currentScope; - } - - /** - * Counts the number of initialized and uninitialized declarations in a list of declarations - * @param {ASTNode[]} declarations List of declarations - * @returns {Object} Counts of 'uninitialized' and 'initialized' declarations - * @private - */ - function countDeclarations(declarations) { - const counts = { uninitialized: 0, initialized: 0 }; - - for (let i = 0; i < declarations.length; i++) { - if (declarations[i].init === null) { - counts.uninitialized++; - } else { - counts.initialized++; - } - } - return counts; - } - - /** - * Determines if there is more than one var statement in the current scope. - * @param {string} statementType node.kind, one of: "var", "let", or "const" - * @param {ASTNode[]} declarations List of declarations - * @returns {boolean} Returns true if it is the first var declaration, false if not. - * @private - */ - function hasOnlyOneStatement(statementType, declarations) { - - const declarationCounts = countDeclarations(declarations); - const currentOptions = options[statementType] || {}; - const currentScope = getCurrentScope(statementType); - const hasRequires = declarations.some(isRequire); - - if (currentOptions.uninitialized === MODE_ALWAYS && currentOptions.initialized === MODE_ALWAYS) { - if (currentScope.uninitialized || currentScope.initialized) { - if (!hasRequires) { - return false; - } - } - } - - if (declarationCounts.uninitialized > 0) { - if (currentOptions.uninitialized === MODE_ALWAYS && currentScope.uninitialized) { - return false; - } - } - if (declarationCounts.initialized > 0) { - if (currentOptions.initialized === MODE_ALWAYS && currentScope.initialized) { - if (!hasRequires) { - return false; - } - } - } - if (currentScope.required && hasRequires) { - return false; - } - recordTypes(statementType, declarations, currentScope); - return true; - } - - /** - * Fixer to join VariableDeclaration's into a single declaration - * @param {VariableDeclarator[]} declarations The `VariableDeclaration` to join - * @returns {Function} The fixer function - */ - function joinDeclarations(declarations) { - const declaration = declarations[0]; - const body = Array.isArray(declaration.parent.parent.body) ? declaration.parent.parent.body : []; - const currentIndex = body.findIndex(node => node.range[0] === declaration.parent.range[0]); - const previousNode = body[currentIndex - 1]; - - return fixer => { - const type = sourceCode.getTokenBefore(declaration); - const prevSemi = sourceCode.getTokenBefore(type); - const res = []; - - if (previousNode && previousNode.kind === sourceCode.getText(type)) { - if (prevSemi.value === ";") { - res.push(fixer.replaceText(prevSemi, ",")); - } else { - res.push(fixer.insertTextAfter(prevSemi, ",")); - } - res.push(fixer.replaceText(type, "")); - } - - return res; - }; - } - - /** - * Fixer to split a VariableDeclaration into individual declarations - * @param {VariableDeclaration} declaration The `VariableDeclaration` to split - * @returns {Function|null} The fixer function - */ - function splitDeclarations(declaration) { - const { parent } = declaration; - - // don't autofix code such as: if (foo) var x, y; - if (!isInStatementList(parent.type === "ExportNamedDeclaration" ? parent : declaration)) { - return null; - } - - return fixer => declaration.declarations.map(declarator => { - const tokenAfterDeclarator = sourceCode.getTokenAfter(declarator); - - if (tokenAfterDeclarator === null) { - return null; - } - - const afterComma = sourceCode.getTokenAfter(tokenAfterDeclarator, { includeComments: true }); - - if (tokenAfterDeclarator.value !== ",") { - return null; - } - - const exportPlacement = declaration.parent.type === "ExportNamedDeclaration" ? "export " : ""; - - /* - * `var x,y` - * tokenAfterDeclarator ^^ afterComma - */ - if (afterComma.range[0] === tokenAfterDeclarator.range[1]) { - return fixer.replaceText(tokenAfterDeclarator, `; ${exportPlacement}${declaration.kind} `); - } - - /* - * `var x, - * tokenAfterDeclarator ^ - * y` - * ^ afterComma - */ - if ( - afterComma.loc.start.line > tokenAfterDeclarator.loc.end.line || - afterComma.type === "Line" || - afterComma.type === "Block" - ) { - let lastComment = afterComma; - - while (lastComment.type === "Line" || lastComment.type === "Block") { - lastComment = sourceCode.getTokenAfter(lastComment, { includeComments: true }); - } - - return fixer.replaceTextRange( - [tokenAfterDeclarator.range[0], lastComment.range[0]], - `;${sourceCode.text.slice(tokenAfterDeclarator.range[1], lastComment.range[0])}${exportPlacement}${declaration.kind} ` - ); - } - - return fixer.replaceText(tokenAfterDeclarator, `; ${exportPlacement}${declaration.kind}`); - }).filter(x => x); - } - - /** - * Checks a given VariableDeclaration node for errors. - * @param {ASTNode} node The VariableDeclaration node to check - * @returns {void} - * @private - */ - function checkVariableDeclaration(node) { - const parent = node.parent; - const type = node.kind; - - if (!options[type]) { - return; - } - - const declarations = node.declarations; - const declarationCounts = countDeclarations(declarations); - const mixedRequires = declarations.some(isRequire) && !declarations.every(isRequire); - - if (options[type].initialized === MODE_ALWAYS) { - if (options.separateRequires && mixedRequires) { - context.report({ - node, - messageId: "splitRequires" - }); - } - } - - // consecutive - const nodeIndex = (parent.body && parent.body.length > 0 && parent.body.indexOf(node)) || 0; - - if (nodeIndex > 0) { - const previousNode = parent.body[nodeIndex - 1]; - const isPreviousNodeDeclaration = previousNode.type === "VariableDeclaration"; - const declarationsWithPrevious = declarations.concat(previousNode.declarations || []); - - if ( - isPreviousNodeDeclaration && - previousNode.kind === type && - !(declarationsWithPrevious.some(isRequire) && !declarationsWithPrevious.every(isRequire)) - ) { - const previousDeclCounts = countDeclarations(previousNode.declarations); - - if (options[type].initialized === MODE_CONSECUTIVE && options[type].uninitialized === MODE_CONSECUTIVE) { - context.report({ - node, - messageId: "combine", - data: { - type - }, - fix: joinDeclarations(declarations) - }); - } else if (options[type].initialized === MODE_CONSECUTIVE && declarationCounts.initialized > 0 && previousDeclCounts.initialized > 0) { - context.report({ - node, - messageId: "combineInitialized", - data: { - type - }, - fix: joinDeclarations(declarations) - }); - } else if (options[type].uninitialized === MODE_CONSECUTIVE && - declarationCounts.uninitialized > 0 && - previousDeclCounts.uninitialized > 0) { - context.report({ - node, - messageId: "combineUninitialized", - data: { - type - }, - fix: joinDeclarations(declarations) - }); - } - } - } - - // always - if (!hasOnlyOneStatement(type, declarations)) { - if (options[type].initialized === MODE_ALWAYS && options[type].uninitialized === MODE_ALWAYS) { - context.report({ - node, - messageId: "combine", - data: { - type - }, - fix: joinDeclarations(declarations) - }); - } else { - if (options[type].initialized === MODE_ALWAYS && declarationCounts.initialized > 0) { - context.report({ - node, - messageId: "combineInitialized", - data: { - type - }, - fix: joinDeclarations(declarations) - }); - } - if (options[type].uninitialized === MODE_ALWAYS && declarationCounts.uninitialized > 0) { - if (node.parent.left === node && (node.parent.type === "ForInStatement" || node.parent.type === "ForOfStatement")) { - return; - } - context.report({ - node, - messageId: "combineUninitialized", - data: { - type - }, - fix: joinDeclarations(declarations) - }); - } - } - } - - // never - if (parent.type !== "ForStatement" || parent.init !== node) { - const totalDeclarations = declarationCounts.uninitialized + declarationCounts.initialized; - - if (totalDeclarations > 1) { - if (options[type].initialized === MODE_NEVER && options[type].uninitialized === MODE_NEVER) { - - // both initialized and uninitialized - context.report({ - node, - messageId: "split", - data: { - type - }, - fix: splitDeclarations(node) - }); - } else if (options[type].initialized === MODE_NEVER && declarationCounts.initialized > 0) { - - // initialized - context.report({ - node, - messageId: "splitInitialized", - data: { - type - }, - fix: splitDeclarations(node) - }); - } else if (options[type].uninitialized === MODE_NEVER && declarationCounts.uninitialized > 0) { - - // uninitialized - context.report({ - node, - messageId: "splitUninitialized", - data: { - type - }, - fix: splitDeclarations(node) - }); - } - } - } - } - - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- - - return { - Program: startFunction, - FunctionDeclaration: startFunction, - FunctionExpression: startFunction, - ArrowFunctionExpression: startFunction, - BlockStatement: startBlock, - ForStatement: startBlock, - ForInStatement: startBlock, - ForOfStatement: startBlock, - SwitchStatement: startBlock, - VariableDeclaration: checkVariableDeclaration, - "ForStatement:exit": endBlock, - "ForOfStatement:exit": endBlock, - "ForInStatement:exit": endBlock, - "SwitchStatement:exit": endBlock, - "BlockStatement:exit": endBlock, - "Program:exit": endFunction, - "FunctionDeclaration:exit": endFunction, - "FunctionExpression:exit": endFunction, - "ArrowFunctionExpression:exit": endFunction - }; - - } -}; - -/** - * @fileoverview Rule to check multiple var declarations per line - * @author Alberto Rodríguez - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var oneVarDeclarationPerLine = { - meta: { - type: "suggestion", - - docs: { - description: "require or disallow newlines around variable declarations", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/one-var-declaration-per-line" - }, - - schema: [ - { - enum: ["always", "initializations"] - } - ], - - fixable: "whitespace", - - messages: { - expectVarOnNewline: "Expected variable declaration to be on a new line." - } - }, - - create(context) { - - const always = context.options[0] === "always"; - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - - /** - * Determine if provided keyword is a variant of for specifiers - * @private - * @param {string} keyword keyword to test - * @returns {boolean} True if `keyword` is a variant of for specifier - */ - function isForTypeSpecifier(keyword) { - return keyword === "ForStatement" || keyword === "ForInStatement" || keyword === "ForOfStatement"; - } - - /** - * Checks newlines around variable declarations. - * @private - * @param {ASTNode} node `VariableDeclaration` node to test - * @returns {void} - */ - function checkForNewLine(node) { - if (isForTypeSpecifier(node.parent.type)) { - return; - } - - const declarations = node.declarations; - let prev; - - declarations.forEach(current => { - if (prev && prev.loc.end.line === current.loc.start.line) { - if (always || prev.init || current.init) { - context.report({ - node, - messageId: "expectVarOnNewline", - loc: current.loc, - fix: fixer => fixer.insertTextBefore(current, "\n") - }); - } - } - prev = current; - }); - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - VariableDeclaration: checkForNewLine - }; - - } -}; - -/** - * @fileoverview Rule to replace assignment expressions with operator assignment - * @author Brandon Mills - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether an operator is commutative and has an operator assignment - * shorthand form. - * @param {string} operator Operator to check. - * @returns {boolean} True if the operator is commutative and has a - * shorthand form. - */ -function isCommutativeOperatorWithShorthand(operator) { - return ["*", "&", "^", "|"].indexOf(operator) >= 0; -} - -/** - * Checks whether an operator is not commutative and has an operator assignment - * shorthand form. - * @param {string} operator Operator to check. - * @returns {boolean} True if the operator is not commutative and has - * a shorthand form. - */ -function isNonCommutativeOperatorWithShorthand(operator) { - return ["+", "-", "/", "%", "<<", ">>", ">>>", "**"].indexOf(operator) >= 0; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -/** - * Determines if the left side of a node can be safely fixed (i.e. if it activates the same getters/setters and) - * toString calls regardless of whether assignment shorthand is used) - * @param {ASTNode} node The node on the left side of the expression - * @returns {boolean} `true` if the node can be fixed - */ -function canBeFixed(node) { - return ( - node.type === "Identifier" || - ( - node.type === "MemberExpression" && - (node.object.type === "Identifier" || node.object.type === "ThisExpression") && - (!node.computed || node.property.type === "Literal") - ) - ); -} - -var operatorAssignment = { - meta: { - type: "suggestion", - - docs: { - description: "require or disallow assignment operator shorthand where possible", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/operator-assignment" - }, - - schema: [ - { - enum: ["always", "never"] - } - ], - - fixable: "code", - messages: { - replaced: "Assignment can be replaced with operator assignment.", - unexpected: "Unexpected operator assignment shorthand." - } - }, - - create(context) { - - const sourceCode = context.getSourceCode(); - - /** - * Returns the operator token of an AssignmentExpression or BinaryExpression - * @param {ASTNode} node An AssignmentExpression or BinaryExpression node - * @returns {Token} The operator token in the node - */ - function getOperatorToken(node) { - return sourceCode.getFirstTokenBetween(node.left, node.right, token => token.value === node.operator); - } - - /** - * Ensures that an assignment uses the shorthand form where possible. - * @param {ASTNode} node An AssignmentExpression node. - * @returns {void} - */ - function verify(node) { - if (node.operator !== "=" || node.right.type !== "BinaryExpression") { - return; - } - - const left = node.left; - const expr = node.right; - const operator = expr.operator; - - if (isCommutativeOperatorWithShorthand(operator) || isNonCommutativeOperatorWithShorthand(operator)) { - if (astUtils.isSameReference(left, expr.left, true)) { - context.report({ - node, - messageId: "replaced", - fix(fixer) { - if (canBeFixed(left) && canBeFixed(expr.left)) { - const equalsToken = getOperatorToken(node); - const operatorToken = getOperatorToken(expr); - const leftText = sourceCode.getText().slice(node.range[0], equalsToken.range[0]); - const rightText = sourceCode.getText().slice(operatorToken.range[1], node.right.range[1]); - - // Check for comments that would be removed. - if (sourceCode.commentsExistBetween(equalsToken, operatorToken)) { - return null; - } - - return fixer.replaceText(node, `${leftText}${expr.operator}=${rightText}`); - } - return null; - } - }); - } else if (astUtils.isSameReference(left, expr.right, true) && isCommutativeOperatorWithShorthand(operator)) { - - /* - * This case can't be fixed safely. - * If `a` and `b` both have custom valueOf() behavior, then fixing `a = b * a` to `a *= b` would - * change the execution order of the valueOf() functions. - */ - context.report({ - node, - messageId: "replaced" - }); - } - } - } - - /** - * Warns if an assignment expression uses operator assignment shorthand. - * @param {ASTNode} node An AssignmentExpression node. - * @returns {void} - */ - function prohibit(node) { - if (node.operator !== "=" && !astUtils.isLogicalAssignmentOperator(node.operator)) { - context.report({ - node, - messageId: "unexpected", - fix(fixer) { - if (canBeFixed(node.left)) { - const firstToken = sourceCode.getFirstToken(node); - const operatorToken = getOperatorToken(node); - const leftText = sourceCode.getText().slice(node.range[0], operatorToken.range[0]); - const newOperator = node.operator.slice(0, -1); - let rightText; - - // Check for comments that would be duplicated. - if (sourceCode.commentsExistBetween(firstToken, operatorToken)) { - return null; - } - - // If this change would modify precedence (e.g. `foo *= bar + 1` => `foo = foo * (bar + 1)`), parenthesize the right side. - if ( - astUtils.getPrecedence(node.right) <= astUtils.getPrecedence({ type: "BinaryExpression", operator: newOperator }) && - !astUtils.isParenthesised(sourceCode, node.right) - ) { - rightText = `${sourceCode.text.slice(operatorToken.range[1], node.right.range[0])}(${sourceCode.getText(node.right)})`; - } else { - const tokenAfterOperator = sourceCode.getTokenAfter(operatorToken, { includeComments: true }); - let rightTextPrefix = ""; - - if ( - operatorToken.range[1] === tokenAfterOperator.range[0] && - !astUtils.canTokensBeAdjacent({ type: "Punctuator", value: newOperator }, tokenAfterOperator) - ) { - rightTextPrefix = " "; // foo+=+bar -> foo= foo+ +bar - } - - rightText = `${rightTextPrefix}${sourceCode.text.slice(operatorToken.range[1], node.range[1])}`; - } - - return fixer.replaceText(node, `${leftText}= ${leftText}${newOperator}${rightText}`); - } - return null; - } - }); - } - } - - return { - AssignmentExpression: context.options[0] !== "never" ? verify : prohibit - }; - - } -}; - -/** - * @fileoverview Operator linebreak - enforces operator linebreak style of two types: after and before - * @author Benoît Zugmeyer - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var operatorLinebreak = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent linebreak style for operators", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/operator-linebreak" - }, - - schema: [ - { - enum: ["after", "before", "none", null] - }, - { - type: "object", - properties: { - overrides: { - type: "object", - additionalProperties: { - enum: ["after", "before", "none", "ignore"] - } - } - }, - additionalProperties: false - } - ], - - fixable: "code", - - messages: { - operatorAtBeginning: "'{{operator}}' should be placed at the beginning of the line.", - operatorAtEnd: "'{{operator}}' should be placed at the end of the line.", - badLinebreak: "Bad line breaking before and after '{{operator}}'.", - noLinebreak: "There should be no line break before or after '{{operator}}'." - } - }, - - create(context) { - - const usedDefaultGlobal = !context.options[0]; - const globalStyle = context.options[0] || "after"; - const options = context.options[1] || {}; - const styleOverrides = options.overrides ? Object.assign({}, options.overrides) : {}; - - if (usedDefaultGlobal && !styleOverrides["?"]) { - styleOverrides["?"] = "before"; - } - - if (usedDefaultGlobal && !styleOverrides[":"]) { - styleOverrides[":"] = "before"; - } - - const sourceCode = context.getSourceCode(); - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Gets a fixer function to fix rule issues - * @param {Token} operatorToken The operator token of an expression - * @param {string} desiredStyle The style for the rule. One of 'before', 'after', 'none' - * @returns {Function} A fixer function - */ - function getFixer(operatorToken, desiredStyle) { - return fixer => { - const tokenBefore = sourceCode.getTokenBefore(operatorToken); - const tokenAfter = sourceCode.getTokenAfter(operatorToken); - const textBefore = sourceCode.text.slice(tokenBefore.range[1], operatorToken.range[0]); - const textAfter = sourceCode.text.slice(operatorToken.range[1], tokenAfter.range[0]); - const hasLinebreakBefore = !astUtils.isTokenOnSameLine(tokenBefore, operatorToken); - const hasLinebreakAfter = !astUtils.isTokenOnSameLine(operatorToken, tokenAfter); - let newTextBefore, newTextAfter; - - if (hasLinebreakBefore !== hasLinebreakAfter && desiredStyle !== "none") { - - // If there is a comment before and after the operator, don't do a fix. - if (sourceCode.getTokenBefore(operatorToken, { includeComments: true }) !== tokenBefore && - sourceCode.getTokenAfter(operatorToken, { includeComments: true }) !== tokenAfter) { - - return null; - } - - /* - * If there is only one linebreak and it's on the wrong side of the operator, swap the text before and after the operator. - * foo && - * bar - * would get fixed to - * foo - * && bar - */ - newTextBefore = textAfter; - newTextAfter = textBefore; - } else { - const LINEBREAK_REGEX = astUtils.createGlobalLinebreakMatcher(); - - // Otherwise, if no linebreak is desired and no comments interfere, replace the linebreaks with empty strings. - newTextBefore = desiredStyle === "before" || textBefore.trim() ? textBefore : textBefore.replace(LINEBREAK_REGEX, ""); - newTextAfter = desiredStyle === "after" || textAfter.trim() ? textAfter : textAfter.replace(LINEBREAK_REGEX, ""); - - // If there was no change (due to interfering comments), don't output a fix. - if (newTextBefore === textBefore && newTextAfter === textAfter) { - return null; - } - } - - if (newTextAfter === "" && tokenAfter.type === "Punctuator" && "+-".includes(operatorToken.value) && tokenAfter.value === operatorToken.value) { - - // To avoid accidentally creating a ++ or -- operator, insert a space if the operator is a +/- and the following token is a unary +/-. - newTextAfter += " "; - } - - return fixer.replaceTextRange([tokenBefore.range[1], tokenAfter.range[0]], newTextBefore + operatorToken.value + newTextAfter); - }; - } - - /** - * Checks the operator placement - * @param {ASTNode} node The node to check - * @param {ASTNode} leftSide The node that comes before the operator in `node` - * @private - * @returns {void} - */ - function validateNode(node, leftSide) { - - /* - * When the left part of a binary expression is a single expression wrapped in - * parentheses (ex: `(a) + b`), leftToken will be the last token of the expression - * and operatorToken will be the closing parenthesis. - * The leftToken should be the last closing parenthesis, and the operatorToken - * should be the token right after that. - */ - const operatorToken = sourceCode.getTokenAfter(leftSide, astUtils.isNotClosingParenToken); - const leftToken = sourceCode.getTokenBefore(operatorToken); - const rightToken = sourceCode.getTokenAfter(operatorToken); - const operator = operatorToken.value; - const operatorStyleOverride = styleOverrides[operator]; - const style = operatorStyleOverride || globalStyle; - const fix = getFixer(operatorToken, style); - - // if single line - if (astUtils.isTokenOnSameLine(leftToken, operatorToken) && - astUtils.isTokenOnSameLine(operatorToken, rightToken)) ; else if (operatorStyleOverride !== "ignore" && !astUtils.isTokenOnSameLine(leftToken, operatorToken) && - !astUtils.isTokenOnSameLine(operatorToken, rightToken)) { - - // lone operator - context.report({ - node, - loc: operatorToken.loc, - messageId: "badLinebreak", - data: { - operator - }, - fix - }); - - } else if (style === "before" && astUtils.isTokenOnSameLine(leftToken, operatorToken)) { - - context.report({ - node, - loc: operatorToken.loc, - messageId: "operatorAtBeginning", - data: { - operator - }, - fix - }); - - } else if (style === "after" && astUtils.isTokenOnSameLine(operatorToken, rightToken)) { - - context.report({ - node, - loc: operatorToken.loc, - messageId: "operatorAtEnd", - data: { - operator - }, - fix - }); - - } else if (style === "none") { - - context.report({ - node, - loc: operatorToken.loc, - messageId: "noLinebreak", - data: { - operator - }, - fix - }); - - } - } - - /** - * Validates a binary expression using `validateNode` - * @param {BinaryExpression|LogicalExpression|AssignmentExpression} node node to be validated - * @returns {void} - */ - function validateBinaryExpression(node) { - validateNode(node, node.left); - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - BinaryExpression: validateBinaryExpression, - LogicalExpression: validateBinaryExpression, - AssignmentExpression: validateBinaryExpression, - VariableDeclarator(node) { - if (node.init) { - validateNode(node, node.id); - } - }, - ConditionalExpression(node) { - validateNode(node, node.test); - validateNode(node, node.consequent); - } - }; - } -}; - -/** - * @fileoverview A rule to ensure blank lines within blocks. - * @author Mathias Schreck - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var paddedBlocks = { - meta: { - type: "layout", - - docs: { - description: "require or disallow padding within blocks", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/padded-blocks" - }, - - fixable: "whitespace", - - schema: [ - { - oneOf: [ - { - enum: ["always", "never"] - }, - { - type: "object", - properties: { - blocks: { - enum: ["always", "never"] - }, - switches: { - enum: ["always", "never"] - }, - classes: { - enum: ["always", "never"] - } - }, - additionalProperties: false, - minProperties: 1 - } - ] - }, - { - type: "object", - properties: { - allowSingleLineBlocks: { - type: "boolean" - } - }, - additionalProperties: false - } - ], - - messages: { - alwaysPadBlock: "Block must be padded by blank lines.", - neverPadBlock: "Block must not be padded by blank lines." - } - }, - - create(context) { - const options = {}; - const typeOptions = context.options[0] || "always"; - const exceptOptions = context.options[1] || {}; - - if (typeof typeOptions === "string") { - const shouldHavePadding = typeOptions === "always"; - - options.blocks = shouldHavePadding; - options.switches = shouldHavePadding; - options.classes = shouldHavePadding; - } else { - if (Object.prototype.hasOwnProperty.call(typeOptions, "blocks")) { - options.blocks = typeOptions.blocks === "always"; - } - if (Object.prototype.hasOwnProperty.call(typeOptions, "switches")) { - options.switches = typeOptions.switches === "always"; - } - if (Object.prototype.hasOwnProperty.call(typeOptions, "classes")) { - options.classes = typeOptions.classes === "always"; - } - } - - if (Object.prototype.hasOwnProperty.call(exceptOptions, "allowSingleLineBlocks")) { - options.allowSingleLineBlocks = exceptOptions.allowSingleLineBlocks === true; - } - - const sourceCode = context.getSourceCode(); - - /** - * Gets the open brace token from a given node. - * @param {ASTNode} node A BlockStatement or SwitchStatement node from which to get the open brace. - * @returns {Token} The token of the open brace. - */ - function getOpenBrace(node) { - if (node.type === "SwitchStatement") { - return sourceCode.getTokenBefore(node.cases[0]); - } - return sourceCode.getFirstToken(node); - } - - /** - * Checks if the given parameter is a comment node - * @param {ASTNode|Token} node An AST node or token - * @returns {boolean} True if node is a comment - */ - function isComment(node) { - return node.type === "Line" || node.type === "Block"; - } - - /** - * Checks if there is padding between two tokens - * @param {Token} first The first token - * @param {Token} second The second token - * @returns {boolean} True if there is at least a line between the tokens - */ - function isPaddingBetweenTokens(first, second) { - return second.loc.start.line - first.loc.end.line >= 2; - } - - - /** - * Checks if the given token has a blank line after it. - * @param {Token} token The token to check. - * @returns {boolean} Whether or not the token is followed by a blank line. - */ - function getFirstBlockToken(token) { - let prev, - first = token; - - do { - prev = first; - first = sourceCode.getTokenAfter(first, { includeComments: true }); - } while (isComment(first) && first.loc.start.line === prev.loc.end.line); - - return first; - } - - /** - * Checks if the given token is preceded by a blank line. - * @param {Token} token The token to check - * @returns {boolean} Whether or not the token is preceded by a blank line - */ - function getLastBlockToken(token) { - let last = token, - next; - - do { - next = last; - last = sourceCode.getTokenBefore(last, { includeComments: true }); - } while (isComment(last) && last.loc.end.line === next.loc.start.line); - - return last; - } - - /** - * Checks if a node should be padded, according to the rule config. - * @param {ASTNode} node The AST node to check. - * @returns {boolean} True if the node should be padded, false otherwise. - */ - function requirePaddingFor(node) { - switch (node.type) { - case "BlockStatement": - return options.blocks; - case "SwitchStatement": - return options.switches; - case "ClassBody": - return options.classes; - - /* istanbul ignore next */ - default: - throw new Error("unreachable"); - } - } - - /** - * Checks the given BlockStatement node to be padded if the block is not empty. - * @param {ASTNode} node The AST node of a BlockStatement. - * @returns {void} undefined. - */ - function checkPadding(node) { - const openBrace = getOpenBrace(node), - firstBlockToken = getFirstBlockToken(openBrace), - tokenBeforeFirst = sourceCode.getTokenBefore(firstBlockToken, { includeComments: true }), - closeBrace = sourceCode.getLastToken(node), - lastBlockToken = getLastBlockToken(closeBrace), - tokenAfterLast = sourceCode.getTokenAfter(lastBlockToken, { includeComments: true }), - blockHasTopPadding = isPaddingBetweenTokens(tokenBeforeFirst, firstBlockToken), - blockHasBottomPadding = isPaddingBetweenTokens(lastBlockToken, tokenAfterLast); - - if (options.allowSingleLineBlocks && astUtils.isTokenOnSameLine(tokenBeforeFirst, tokenAfterLast)) { - return; - } - - if (requirePaddingFor(node)) { - - if (!blockHasTopPadding) { - context.report({ - node, - loc: { - start: tokenBeforeFirst.loc.start, - end: firstBlockToken.loc.start - }, - fix(fixer) { - return fixer.insertTextAfter(tokenBeforeFirst, "\n"); - }, - messageId: "alwaysPadBlock" - }); - } - if (!blockHasBottomPadding) { - context.report({ - node, - loc: { - end: tokenAfterLast.loc.start, - start: lastBlockToken.loc.end - }, - fix(fixer) { - return fixer.insertTextBefore(tokenAfterLast, "\n"); - }, - messageId: "alwaysPadBlock" - }); - } - } else { - if (blockHasTopPadding) { - - context.report({ - node, - loc: { - start: tokenBeforeFirst.loc.start, - end: firstBlockToken.loc.start - }, - fix(fixer) { - return fixer.replaceTextRange([tokenBeforeFirst.range[1], firstBlockToken.range[0] - firstBlockToken.loc.start.column], "\n"); - }, - messageId: "neverPadBlock" - }); - } - - if (blockHasBottomPadding) { - - context.report({ - node, - loc: { - end: tokenAfterLast.loc.start, - start: lastBlockToken.loc.end - }, - messageId: "neverPadBlock", - fix(fixer) { - return fixer.replaceTextRange([lastBlockToken.range[1], tokenAfterLast.range[0] - tokenAfterLast.loc.start.column], "\n"); - } - }); - } - } - } - - const rule = {}; - - if (Object.prototype.hasOwnProperty.call(options, "switches")) { - rule.SwitchStatement = function(node) { - if (node.cases.length === 0) { - return; - } - checkPadding(node); - }; - } - - if (Object.prototype.hasOwnProperty.call(options, "blocks")) { - rule.BlockStatement = function(node) { - if (node.body.length === 0) { - return; - } - checkPadding(node); - }; - } - - if (Object.prototype.hasOwnProperty.call(options, "classes")) { - rule.ClassBody = function(node) { - if (node.body.length === 0) { - return; - } - checkPadding(node); - }; - } - - return rule; - } -}; - -/** - * @fileoverview Rule to require or disallow newlines between statements - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const LT = `[${Array.from(astUtils.LINEBREAKS).join("")}]`; -const PADDING_LINE_SEQUENCE = new RegExp( - String.raw`^(\s*?${LT})\s*${LT}(\s*;?)$`, - "u" -); -const CJS_EXPORT = /^(?:module\s*\.\s*)?exports(?:\s*\.|\s*\[|$)/u; -const CJS_IMPORT = /^require\(/u; - -/** - * Creates tester which check if a node starts with specific keyword. - * @param {string} keyword The keyword to test. - * @returns {Object} the created tester. - * @private - */ -function newKeywordTester(keyword) { - return { - test: (node, sourceCode) => - sourceCode.getFirstToken(node).value === keyword - }; -} - -/** - * Creates tester which check if a node starts with specific keyword and spans a single line. - * @param {string} keyword The keyword to test. - * @returns {Object} the created tester. - * @private - */ -function newSinglelineKeywordTester(keyword) { - return { - test: (node, sourceCode) => - node.loc.start.line === node.loc.end.line && - sourceCode.getFirstToken(node).value === keyword - }; -} - -/** - * Creates tester which check if a node starts with specific keyword and spans multiple lines. - * @param {string} keyword The keyword to test. - * @returns {Object} the created tester. - * @private - */ -function newMultilineKeywordTester(keyword) { - return { - test: (node, sourceCode) => - node.loc.start.line !== node.loc.end.line && - sourceCode.getFirstToken(node).value === keyword - }; -} - -/** - * Creates tester which check if a node is specific type. - * @param {string} type The node type to test. - * @returns {Object} the created tester. - * @private - */ -function newNodeTypeTester(type) { - return { - test: node => - node.type === type - }; -} - -/** - * Checks the given node is an expression statement of IIFE. - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if the node is an expression statement of IIFE. - * @private - */ -function isIIFEStatement(node) { - if (node.type === "ExpressionStatement") { - let call = astUtils.skipChainExpression(node.expression); - - if (call.type === "UnaryExpression") { - call = astUtils.skipChainExpression(call.argument); - } - return call.type === "CallExpression" && astUtils.isFunction(call.callee); - } - return false; -} - -/** - * Checks whether the given node is a block-like statement. - * This checks the last token of the node is the closing brace of a block. - * @param {SourceCode} sourceCode The source code to get tokens. - * @param {ASTNode} node The node to check. - * @returns {boolean} `true` if the node is a block-like statement. - * @private - */ -function isBlockLikeStatement(sourceCode, node) { - - // do-while with a block is a block-like statement. - if (node.type === "DoWhileStatement" && node.body.type === "BlockStatement") { - return true; - } - - /* - * IIFE is a block-like statement specially from - * JSCS#disallowPaddingNewLinesAfterBlocks. - */ - if (isIIFEStatement(node)) { - return true; - } - - // Checks the last token is a closing brace of blocks. - const lastToken = sourceCode.getLastToken(node, astUtils.isNotSemicolonToken); - const belongingNode = lastToken && astUtils.isClosingBraceToken(lastToken) - ? sourceCode.getNodeByRangeIndex(lastToken.range[0]) - : null; - - return Boolean(belongingNode) && ( - belongingNode.type === "BlockStatement" || - belongingNode.type === "SwitchStatement" - ); -} - -/** - * Check whether the given node is a directive or not. - * @param {ASTNode} node The node to check. - * @param {SourceCode} sourceCode The source code object to get tokens. - * @returns {boolean} `true` if the node is a directive. - */ -function isDirective(node, sourceCode) { - return ( - node.type === "ExpressionStatement" && - ( - node.parent.type === "Program" || - ( - node.parent.type === "BlockStatement" && - astUtils.isFunction(node.parent.parent) - ) - ) && - node.expression.type === "Literal" && - typeof node.expression.value === "string" && - !astUtils.isParenthesised(sourceCode, node.expression) - ); -} - -/** - * Check whether the given node is a part of directive prologue or not. - * @param {ASTNode} node The node to check. - * @param {SourceCode} sourceCode The source code object to get tokens. - * @returns {boolean} `true` if the node is a part of directive prologue. - */ -function isDirectivePrologue(node, sourceCode) { - if (isDirective(node, sourceCode)) { - for (const sibling of node.parent.body) { - if (sibling === node) { - break; - } - if (!isDirective(sibling, sourceCode)) { - return false; - } - } - return true; - } - return false; -} - -/** - * Gets the actual last token. - * - * If a semicolon is semicolon-less style's semicolon, this ignores it. - * For example: - * - * foo() - * ;[1, 2, 3].forEach(bar) - * @param {SourceCode} sourceCode The source code to get tokens. - * @param {ASTNode} node The node to get. - * @returns {Token} The actual last token. - * @private - */ -function getActualLastToken(sourceCode, node) { - const semiToken = sourceCode.getLastToken(node); - const prevToken = sourceCode.getTokenBefore(semiToken); - const nextToken = sourceCode.getTokenAfter(semiToken); - const isSemicolonLessStyle = Boolean( - prevToken && - nextToken && - prevToken.range[0] >= node.range[0] && - astUtils.isSemicolonToken(semiToken) && - semiToken.loc.start.line !== prevToken.loc.end.line && - semiToken.loc.end.line === nextToken.loc.start.line - ); - - return isSemicolonLessStyle ? prevToken : semiToken; -} - -/** - * This returns the concatenation of the first 2 captured strings. - * @param {string} _ Unused. Whole matched string. - * @param {string} trailingSpaces The trailing spaces of the first line. - * @param {string} indentSpaces The indentation spaces of the last line. - * @returns {string} The concatenation of trailingSpaces and indentSpaces. - * @private - */ -function replacerToRemovePaddingLines(_, trailingSpaces, indentSpaces) { - return trailingSpaces + indentSpaces; -} - -/** - * Check and report statements for `any` configuration. - * It does nothing. - * @returns {void} - * @private - */ -function verifyForAny() { -} - -/** - * Check and report statements for `never` configuration. - * This autofix removes blank lines between the given 2 statements. - * However, if comments exist between 2 blank lines, it does not remove those - * blank lines automatically. - * @param {RuleContext} context The rule context to report. - * @param {ASTNode} _ Unused. The previous node to check. - * @param {ASTNode} nextNode The next node to check. - * @param {Array} paddingLines The array of token pairs that blank - * lines exist between the pair. - * @returns {void} - * @private - */ -function verifyForNever(context, _, nextNode, paddingLines) { - if (paddingLines.length === 0) { - return; - } - - context.report({ - node: nextNode, - messageId: "unexpectedBlankLine", - fix(fixer) { - if (paddingLines.length >= 2) { - return null; - } - - const prevToken = paddingLines[0][0]; - const nextToken = paddingLines[0][1]; - const start = prevToken.range[1]; - const end = nextToken.range[0]; - const text = context.getSourceCode().text - .slice(start, end) - .replace(PADDING_LINE_SEQUENCE, replacerToRemovePaddingLines); - - return fixer.replaceTextRange([start, end], text); - } - }); -} - -/** - * Check and report statements for `always` configuration. - * This autofix inserts a blank line between the given 2 statements. - * If the `prevNode` has trailing comments, it inserts a blank line after the - * trailing comments. - * @param {RuleContext} context The rule context to report. - * @param {ASTNode} prevNode The previous node to check. - * @param {ASTNode} nextNode The next node to check. - * @param {Array} paddingLines The array of token pairs that blank - * lines exist between the pair. - * @returns {void} - * @private - */ -function verifyForAlways(context, prevNode, nextNode, paddingLines) { - if (paddingLines.length > 0) { - return; - } - - context.report({ - node: nextNode, - messageId: "expectedBlankLine", - fix(fixer) { - const sourceCode = context.getSourceCode(); - let prevToken = getActualLastToken(sourceCode, prevNode); - const nextToken = sourceCode.getFirstTokenBetween( - prevToken, - nextNode, - { - includeComments: true, - - /** - * Skip the trailing comments of the previous node. - * This inserts a blank line after the last trailing comment. - * - * For example: - * - * foo(); // trailing comment. - * // comment. - * bar(); - * - * Get fixed to: - * - * foo(); // trailing comment. - * - * // comment. - * bar(); - * @param {Token} token The token to check. - * @returns {boolean} `true` if the token is not a trailing comment. - * @private - */ - filter(token) { - if (astUtils.isTokenOnSameLine(prevToken, token)) { - prevToken = token; - return false; - } - return true; - } - } - ) || nextNode; - const insertText = astUtils.isTokenOnSameLine(prevToken, nextToken) - ? "\n\n" - : "\n"; - - return fixer.insertTextAfter(prevToken, insertText); - } - }); -} - -/** - * Types of blank lines. - * `any`, `never`, and `always` are defined. - * Those have `verify` method to check and report statements. - * @private - */ -const PaddingTypes = { - any: { verify: verifyForAny }, - never: { verify: verifyForNever }, - always: { verify: verifyForAlways } -}; - -/** - * Types of statements. - * Those have `test` method to check it matches to the given statement. - * @private - */ -const StatementTypes = { - "*": { test: () => true }, - "block-like": { - test: (node, sourceCode) => isBlockLikeStatement(sourceCode, node) - }, - "cjs-export": { - test: (node, sourceCode) => - node.type === "ExpressionStatement" && - node.expression.type === "AssignmentExpression" && - CJS_EXPORT.test(sourceCode.getText(node.expression.left)) - }, - "cjs-import": { - test: (node, sourceCode) => - node.type === "VariableDeclaration" && - node.declarations.length > 0 && - Boolean(node.declarations[0].init) && - CJS_IMPORT.test(sourceCode.getText(node.declarations[0].init)) - }, - directive: { - test: isDirectivePrologue - }, - expression: { - test: (node, sourceCode) => - node.type === "ExpressionStatement" && - !isDirectivePrologue(node, sourceCode) - }, - iife: { - test: isIIFEStatement - }, - "multiline-block-like": { - test: (node, sourceCode) => - node.loc.start.line !== node.loc.end.line && - isBlockLikeStatement(sourceCode, node) - }, - "multiline-expression": { - test: (node, sourceCode) => - node.loc.start.line !== node.loc.end.line && - node.type === "ExpressionStatement" && - !isDirectivePrologue(node, sourceCode) - }, - - "multiline-const": newMultilineKeywordTester("const"), - "multiline-let": newMultilineKeywordTester("let"), - "multiline-var": newMultilineKeywordTester("var"), - "singleline-const": newSinglelineKeywordTester("const"), - "singleline-let": newSinglelineKeywordTester("let"), - "singleline-var": newSinglelineKeywordTester("var"), - - block: newNodeTypeTester("BlockStatement"), - empty: newNodeTypeTester("EmptyStatement"), - function: newNodeTypeTester("FunctionDeclaration"), - - break: newKeywordTester("break"), - case: newKeywordTester("case"), - class: newKeywordTester("class"), - const: newKeywordTester("const"), - continue: newKeywordTester("continue"), - debugger: newKeywordTester("debugger"), - default: newKeywordTester("default"), - do: newKeywordTester("do"), - export: newKeywordTester("export"), - for: newKeywordTester("for"), - if: newKeywordTester("if"), - import: newKeywordTester("import"), - let: newKeywordTester("let"), - return: newKeywordTester("return"), - switch: newKeywordTester("switch"), - throw: newKeywordTester("throw"), - try: newKeywordTester("try"), - var: newKeywordTester("var"), - while: newKeywordTester("while"), - with: newKeywordTester("with") -}; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var paddingLineBetweenStatements = { - meta: { - type: "layout", - - docs: { - description: "require or disallow padding lines between statements", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/padding-line-between-statements" - }, - - fixable: "whitespace", - - schema: { - definitions: { - paddingType: { - enum: Object.keys(PaddingTypes) - }, - statementType: { - anyOf: [ - { enum: Object.keys(StatementTypes) }, - { - type: "array", - items: { enum: Object.keys(StatementTypes) }, - minItems: 1, - uniqueItems: true, - additionalItems: false - } - ] - } - }, - type: "array", - items: { - type: "object", - properties: { - blankLine: { $ref: "#/definitions/paddingType" }, - prev: { $ref: "#/definitions/statementType" }, - next: { $ref: "#/definitions/statementType" } - }, - additionalProperties: false, - required: ["blankLine", "prev", "next"] - }, - additionalItems: false - }, - - messages: { - unexpectedBlankLine: "Unexpected blank line before this statement.", - expectedBlankLine: "Expected blank line before this statement." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const configureList = context.options || []; - let scopeInfo = null; - - /** - * Processes to enter to new scope. - * This manages the current previous statement. - * @returns {void} - * @private - */ - function enterScope() { - scopeInfo = { - upper: scopeInfo, - prevNode: null - }; - } - - /** - * Processes to exit from the current scope. - * @returns {void} - * @private - */ - function exitScope() { - scopeInfo = scopeInfo.upper; - } - - /** - * Checks whether the given node matches the given type. - * @param {ASTNode} node The statement node to check. - * @param {string|string[]} type The statement type to check. - * @returns {boolean} `true` if the statement node matched the type. - * @private - */ - function match(node, type) { - let innerStatementNode = node; - - while (innerStatementNode.type === "LabeledStatement") { - innerStatementNode = innerStatementNode.body; - } - if (Array.isArray(type)) { - return type.some(match.bind(null, innerStatementNode)); - } - return StatementTypes[type].test(innerStatementNode, sourceCode); - } - - /** - * Finds the last matched configure from configureList. - * @param {ASTNode} prevNode The previous statement to match. - * @param {ASTNode} nextNode The current statement to match. - * @returns {Object} The tester of the last matched configure. - * @private - */ - function getPaddingType(prevNode, nextNode) { - for (let i = configureList.length - 1; i >= 0; --i) { - const configure = configureList[i]; - const matched = - match(prevNode, configure.prev) && - match(nextNode, configure.next); - - if (matched) { - return PaddingTypes[configure.blankLine]; - } - } - return PaddingTypes.any; - } - - /** - * Gets padding line sequences between the given 2 statements. - * Comments are separators of the padding line sequences. - * @param {ASTNode} prevNode The previous statement to count. - * @param {ASTNode} nextNode The current statement to count. - * @returns {Array} The array of token pairs. - * @private - */ - function getPaddingLineSequences(prevNode, nextNode) { - const pairs = []; - let prevToken = getActualLastToken(sourceCode, prevNode); - - if (nextNode.loc.start.line - prevToken.loc.end.line >= 2) { - do { - const token = sourceCode.getTokenAfter( - prevToken, - { includeComments: true } - ); - - if (token.loc.start.line - prevToken.loc.end.line >= 2) { - pairs.push([prevToken, token]); - } - prevToken = token; - - } while (prevToken.range[0] < nextNode.range[0]); - } - - return pairs; - } - - /** - * Verify padding lines between the given node and the previous node. - * @param {ASTNode} node The node to verify. - * @returns {void} - * @private - */ - function verify(node) { - const parentType = node.parent.type; - const validParent = - astUtils.STATEMENT_LIST_PARENTS.has(parentType) || - parentType === "SwitchStatement"; - - if (!validParent) { - return; - } - - // Save this node as the current previous statement. - const prevNode = scopeInfo.prevNode; - - // Verify. - if (prevNode) { - const type = getPaddingType(prevNode, node); - const paddingLines = getPaddingLineSequences(prevNode, node); - - type.verify(context, prevNode, node, paddingLines); - } - - scopeInfo.prevNode = node; - } - - /** - * Verify padding lines between the given node and the previous node. - * Then process to enter to new scope. - * @param {ASTNode} node The node to verify. - * @returns {void} - * @private - */ - function verifyThenEnterScope(node) { - verify(node); - enterScope(); - } - - return { - Program: enterScope, - BlockStatement: enterScope, - SwitchStatement: enterScope, - "Program:exit": exitScope, - "BlockStatement:exit": exitScope, - "SwitchStatement:exit": exitScope, - - ":statement": verify, - - SwitchCase: verifyThenEnterScope, - "SwitchCase:exit": exitScope - }; - } -}; - -/** - * @fileoverview A rule to suggest using arrow functions as callbacks. - * @author Toru Nagashima - */ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether or not a given variable is a function name. - * @param {eslint-scope.Variable} variable A variable to check. - * @returns {boolean} `true` if the variable is a function name. - */ -function isFunctionName(variable) { - return variable && variable.defs[0].type === "FunctionName"; -} - -/** - * Checks whether or not a given MetaProperty node equals to a given value. - * @param {ASTNode} node A MetaProperty node to check. - * @param {string} metaName The name of `MetaProperty.meta`. - * @param {string} propertyName The name of `MetaProperty.property`. - * @returns {boolean} `true` if the node is the specific value. - */ -function checkMetaProperty(node, metaName, propertyName) { - return node.meta.name === metaName && node.property.name === propertyName; -} - -/** - * Gets the variable object of `arguments` which is defined implicitly. - * @param {eslint-scope.Scope} scope A scope to get. - * @returns {eslint-scope.Variable} The found variable object. - */ -function getVariableOfArguments$1(scope) { - const variables = scope.variables; - - for (let i = 0; i < variables.length; ++i) { - const variable = variables[i]; - - if (variable.name === "arguments") { - - /* - * If there was a parameter which is named "arguments", the - * implicit "arguments" is not defined. - * So does fast return with null. - */ - return (variable.identifiers.length === 0) ? variable : null; - } - } - - /* istanbul ignore next */ - return null; -} - -/** - * Checks whether or not a given node is a callback. - * @param {ASTNode} node A node to check. - * @returns {Object} - * {boolean} retv.isCallback - `true` if the node is a callback. - * {boolean} retv.isLexicalThis - `true` if the node is with `.bind(this)`. - */ -function getCallbackInfo(node) { - const retv = { isCallback: false, isLexicalThis: false }; - let currentNode = node; - let parent = node.parent; - let bound = false; - - while (currentNode) { - switch (parent.type) { - - // Checks parents recursively. - - case "LogicalExpression": - case "ChainExpression": - case "ConditionalExpression": - break; - - // Checks whether the parent node is `.bind(this)` call. - case "MemberExpression": - if ( - parent.object === currentNode && - !parent.property.computed && - parent.property.type === "Identifier" && - parent.property.name === "bind" - ) { - const maybeCallee = parent.parent.type === "ChainExpression" - ? parent.parent - : parent; - - if (astUtils.isCallee(maybeCallee)) { - if (!bound) { - bound = true; // Use only the first `.bind()` to make `isLexicalThis` value. - retv.isLexicalThis = ( - maybeCallee.parent.arguments.length === 1 && - maybeCallee.parent.arguments[0].type === "ThisExpression" - ); - } - parent = maybeCallee.parent; - } else { - return retv; - } - } else { - return retv; - } - break; - - // Checks whether the node is a callback. - case "CallExpression": - case "NewExpression": - if (parent.callee !== currentNode) { - retv.isCallback = true; - } - return retv; - - default: - return retv; - } - - currentNode = parent; - parent = parent.parent; - } - - /* istanbul ignore next */ - throw new Error("unreachable"); -} - -/** - * Checks whether a simple list of parameters contains any duplicates. This does not handle complex - * parameter lists (e.g. with destructuring), since complex parameter lists are a SyntaxError with duplicate - * parameter names anyway. Instead, it always returns `false` for complex parameter lists. - * @param {ASTNode[]} paramsList The list of parameters for a function - * @returns {boolean} `true` if the list of parameters contains any duplicates - */ -function hasDuplicateParams(paramsList) { - return paramsList.every(param => param.type === "Identifier") && paramsList.length !== new Set(paramsList.map(param => param.name)).size; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var preferArrowCallback = { - meta: { - type: "suggestion", - - docs: { - description: "require using arrow functions for callbacks", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/prefer-arrow-callback" - }, - - schema: [ - { - type: "object", - properties: { - allowNamedFunctions: { - type: "boolean", - default: false - }, - allowUnboundThis: { - type: "boolean", - default: true - } - }, - additionalProperties: false - } - ], - - fixable: "code", - - messages: { - preferArrowCallback: "Unexpected function expression." - } - }, - - create(context) { - const options = context.options[0] || {}; - - const allowUnboundThis = options.allowUnboundThis !== false; // default to true - const allowNamedFunctions = options.allowNamedFunctions; - const sourceCode = context.getSourceCode(); - - /* - * {Array<{this: boolean, super: boolean, meta: boolean}>} - * - this - A flag which shows there are one or more ThisExpression. - * - super - A flag which shows there are one or more Super. - * - meta - A flag which shows there are one or more MethProperty. - */ - let stack = []; - - /** - * Pushes new function scope with all `false` flags. - * @returns {void} - */ - function enterScope() { - stack.push({ this: false, super: false, meta: false }); - } - - /** - * Pops a function scope from the stack. - * @returns {{this: boolean, super: boolean, meta: boolean}} The information of the last scope. - */ - function exitScope() { - return stack.pop(); - } - - return { - - // Reset internal state. - Program() { - stack = []; - }, - - // If there are below, it cannot replace with arrow functions merely. - ThisExpression() { - const info = stack[stack.length - 1]; - - if (info) { - info.this = true; - } - }, - - Super() { - const info = stack[stack.length - 1]; - - if (info) { - info.super = true; - } - }, - - MetaProperty(node) { - const info = stack[stack.length - 1]; - - if (info && checkMetaProperty(node, "new", "target")) { - info.meta = true; - } - }, - - // To skip nested scopes. - FunctionDeclaration: enterScope, - "FunctionDeclaration:exit": exitScope, - - // Main. - FunctionExpression: enterScope, - "FunctionExpression:exit"(node) { - const scopeInfo = exitScope(); - - // Skip named function expressions - if (allowNamedFunctions && node.id && node.id.name) { - return; - } - - // Skip generators. - if (node.generator) { - return; - } - - // Skip recursive functions. - const nameVar = context.getDeclaredVariables(node)[0]; - - if (isFunctionName(nameVar) && nameVar.references.length > 0) { - return; - } - - // Skip if it's using arguments. - const variable = getVariableOfArguments$1(context.getScope()); - - if (variable && variable.references.length > 0) { - return; - } - - // Reports if it's a callback which can replace with arrows. - const callbackInfo = getCallbackInfo(node); - - if (callbackInfo.isCallback && - (!allowUnboundThis || !scopeInfo.this || callbackInfo.isLexicalThis) && - !scopeInfo.super && - !scopeInfo.meta - ) { - context.report({ - node, - messageId: "preferArrowCallback", - *fix(fixer) { - if ((!callbackInfo.isLexicalThis && scopeInfo.this) || hasDuplicateParams(node.params)) { - - /* - * If the callback function does not have .bind(this) and contains a reference to `this`, there - * is no way to determine what `this` should be, so don't perform any fixes. - * If the callback function has duplicates in its list of parameters (possible in sloppy mode), - * don't replace it with an arrow function, because this is a SyntaxError with arrow functions. - */ - return; // eslint-disable-line eslint-plugin/fixer-return -- false positive - } - - // Remove `.bind(this)` if exists. - if (callbackInfo.isLexicalThis) { - const memberNode = node.parent; - - /* - * If `.bind(this)` exists but the parent is not `.bind(this)`, don't remove it automatically. - * E.g. `(foo || function(){}).bind(this)` - */ - if (memberNode.type !== "MemberExpression") { - return; // eslint-disable-line eslint-plugin/fixer-return -- false positive - } - - const callNode = memberNode.parent; - const firstTokenToRemove = sourceCode.getTokenAfter(memberNode.object, astUtils.isNotClosingParenToken); - const lastTokenToRemove = sourceCode.getLastToken(callNode); - - /* - * If the member expression is parenthesized, don't remove the right paren. - * E.g. `(function(){}.bind)(this)` - * ^^^^^^^^^^^^ - */ - if (astUtils.isParenthesised(sourceCode, memberNode)) { - return; // eslint-disable-line eslint-plugin/fixer-return -- false positive - } - - // If comments exist in the `.bind(this)`, don't remove those. - if (sourceCode.commentsExistBetween(firstTokenToRemove, lastTokenToRemove)) { - return; // eslint-disable-line eslint-plugin/fixer-return -- false positive - } - - yield fixer.removeRange([firstTokenToRemove.range[0], lastTokenToRemove.range[1]]); - } - - // Convert the function expression to an arrow function. - const functionToken = sourceCode.getFirstToken(node, node.async ? 1 : 0); - const leftParenToken = sourceCode.getTokenAfter(functionToken, astUtils.isOpeningParenToken); - - if (sourceCode.commentsExistBetween(functionToken, leftParenToken)) { - - // Remove only extra tokens to keep comments. - yield fixer.remove(functionToken); - if (node.id) { - yield fixer.remove(node.id); - } - } else { - - // Remove extra tokens and spaces. - yield fixer.removeRange([functionToken.range[0], leftParenToken.range[0]]); - } - yield fixer.insertTextBefore(node.body, "=> "); - - // Get the node that will become the new arrow function. - let replacedNode = callbackInfo.isLexicalThis ? node.parent.parent : node; - - if (replacedNode.type === "ChainExpression") { - replacedNode = replacedNode.parent; - } - - /* - * If the replaced node is part of a BinaryExpression, LogicalExpression, or MemberExpression, then - * the arrow function needs to be parenthesized, because `foo || () => {}` is invalid syntax even - * though `foo || function() {}` is valid. - */ - if ( - replacedNode.parent.type !== "CallExpression" && - replacedNode.parent.type !== "ConditionalExpression" && - !astUtils.isParenthesised(sourceCode, replacedNode) && - !astUtils.isParenthesised(sourceCode, node) - ) { - yield fixer.insertTextBefore(replacedNode, "("); - yield fixer.insertTextAfter(replacedNode, ")"); - } - } - }); - } - } - }; - } -}; - -/** - * @fileoverview A rule to suggest using of const declaration for variables that are never reassigned after declared. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const PATTERN_TYPE = /^(?:.+?Pattern|RestElement|SpreadProperty|ExperimentalRestProperty|Property)$/u; -const DECLARATION_HOST_TYPE = /^(?:Program|BlockStatement|SwitchCase)$/u; -const DESTRUCTURING_HOST_TYPE = /^(?:VariableDeclarator|AssignmentExpression)$/u; - -/** - * Checks whether a given node is located at `ForStatement.init` or not. - * @param {ASTNode} node A node to check. - * @returns {boolean} `true` if the node is located at `ForStatement.init`. - */ -function isInitOfForStatement(node) { - return node.parent.type === "ForStatement" && node.parent.init === node; -} - -/** - * Checks whether a given Identifier node becomes a VariableDeclaration or not. - * @param {ASTNode} identifier An Identifier node to check. - * @returns {boolean} `true` if the node can become a VariableDeclaration. - */ -function canBecomeVariableDeclaration(identifier) { - let node = identifier.parent; - - while (PATTERN_TYPE.test(node.type)) { - node = node.parent; - } - - return ( - node.type === "VariableDeclarator" || - ( - node.type === "AssignmentExpression" && - node.parent.type === "ExpressionStatement" && - DECLARATION_HOST_TYPE.test(node.parent.parent.type) - ) - ); -} - -/** - * Checks if an property or element is from outer scope or function parameters - * in destructing pattern. - * @param {string} name A variable name to be checked. - * @param {eslint-scope.Scope} initScope A scope to start find. - * @returns {boolean} Indicates if the variable is from outer scope or function parameters. - */ -function isOuterVariableInDestructing(name, initScope) { - - if (initScope.through.find(ref => ref.resolved && ref.resolved.name === name)) { - return true; - } - - const variable = astUtils.getVariableByName(initScope, name); - - if (variable !== null) { - return variable.defs.some(def => def.type === "Parameter"); - } - - return false; -} - -/** - * Gets the VariableDeclarator/AssignmentExpression node that a given reference - * belongs to. - * This is used to detect a mix of reassigned and never reassigned in a - * destructuring. - * @param {eslint-scope.Reference} reference A reference to get. - * @returns {ASTNode|null} A VariableDeclarator/AssignmentExpression node or - * null. - */ -function getDestructuringHost(reference) { - if (!reference.isWrite()) { - return null; - } - let node = reference.identifier.parent; - - while (PATTERN_TYPE.test(node.type)) { - node = node.parent; - } - - if (!DESTRUCTURING_HOST_TYPE.test(node.type)) { - return null; - } - return node; -} - -/** - * Determines if a destructuring assignment node contains - * any MemberExpression nodes. This is used to determine if a - * variable that is only written once using destructuring can be - * safely converted into a const declaration. - * @param {ASTNode} node The ObjectPattern or ArrayPattern node to check. - * @returns {boolean} True if the destructuring pattern contains - * a MemberExpression, false if not. - */ -function hasMemberExpressionAssignment(node) { - switch (node.type) { - case "ObjectPattern": - return node.properties.some(prop => { - if (prop) { - - /* - * Spread elements have an argument property while - * others have a value property. Because different - * parsers use different node types for spread elements, - * we just check if there is an argument property. - */ - return hasMemberExpressionAssignment(prop.argument || prop.value); - } - - return false; - }); - - case "ArrayPattern": - return node.elements.some(element => { - if (element) { - return hasMemberExpressionAssignment(element); - } - - return false; - }); - - case "AssignmentPattern": - return hasMemberExpressionAssignment(node.left); - - case "MemberExpression": - return true; - - // no default - } - - return false; -} - -/** - * Gets an identifier node of a given variable. - * - * If the initialization exists or one or more reading references exist before - * the first assignment, the identifier node is the node of the declaration. - * Otherwise, the identifier node is the node of the first assignment. - * - * If the variable should not change to const, this function returns null. - * - If the variable is reassigned. - * - If the variable is never initialized nor assigned. - * - If the variable is initialized in a different scope from the declaration. - * - If the unique assignment of the variable cannot change to a declaration. - * e.g. `if (a) b = 1` / `return (b = 1)` - * - If the variable is declared in the global scope and `eslintUsed` is `true`. - * `/*exported foo` directive comment makes such variables. This rule does not - * warn such variables because this rule cannot distinguish whether the - * exported variables are reassigned or not. - * @param {eslint-scope.Variable} variable A variable to get. - * @param {boolean} ignoreReadBeforeAssign - * The value of `ignoreReadBeforeAssign` option. - * @returns {ASTNode|null} - * An Identifier node if the variable should change to const. - * Otherwise, null. - */ -function getIdentifierIfShouldBeConst(variable, ignoreReadBeforeAssign) { - if (variable.eslintUsed && variable.scope.type === "global") { - return null; - } - - // Finds the unique WriteReference. - let writer = null; - let isReadBeforeInit = false; - const references = variable.references; - - for (let i = 0; i < references.length; ++i) { - const reference = references[i]; - - if (reference.isWrite()) { - const isReassigned = ( - writer !== null && - writer.identifier !== reference.identifier - ); - - if (isReassigned) { - return null; - } - - const destructuringHost = getDestructuringHost(reference); - - if (destructuringHost !== null && destructuringHost.left !== void 0) { - const leftNode = destructuringHost.left; - let hasOuterVariables = false, - hasNonIdentifiers = false; - - if (leftNode.type === "ObjectPattern") { - const properties = leftNode.properties; - - hasOuterVariables = properties - .filter(prop => prop.value) - .map(prop => prop.value.name) - .some(name => isOuterVariableInDestructing(name, variable.scope)); - - hasNonIdentifiers = hasMemberExpressionAssignment(leftNode); - - } else if (leftNode.type === "ArrayPattern") { - const elements = leftNode.elements; - - hasOuterVariables = elements - .map(element => element && element.name) - .some(name => isOuterVariableInDestructing(name, variable.scope)); - - hasNonIdentifiers = hasMemberExpressionAssignment(leftNode); - } - - if (hasOuterVariables || hasNonIdentifiers) { - return null; - } - - } - - writer = reference; - - } else if (reference.isRead() && writer === null) { - if (ignoreReadBeforeAssign) { - return null; - } - isReadBeforeInit = true; - } - } - - /* - * If the assignment is from a different scope, ignore it. - * If the assignment cannot change to a declaration, ignore it. - */ - const shouldBeConst = ( - writer !== null && - writer.from === variable.scope && - canBecomeVariableDeclaration(writer.identifier) - ); - - if (!shouldBeConst) { - return null; - } - - if (isReadBeforeInit) { - return variable.defs[0].name; - } - - return writer.identifier; -} - -/** - * Groups by the VariableDeclarator/AssignmentExpression node that each - * reference of given variables belongs to. - * This is used to detect a mix of reassigned and never reassigned in a - * destructuring. - * @param {eslint-scope.Variable[]} variables Variables to group by destructuring. - * @param {boolean} ignoreReadBeforeAssign - * The value of `ignoreReadBeforeAssign` option. - * @returns {Map} Grouped identifier nodes. - */ -function groupByDestructuring(variables, ignoreReadBeforeAssign) { - const identifierMap = new Map(); - - for (let i = 0; i < variables.length; ++i) { - const variable = variables[i]; - const references = variable.references; - const identifier = getIdentifierIfShouldBeConst(variable, ignoreReadBeforeAssign); - let prevId = null; - - for (let j = 0; j < references.length; ++j) { - const reference = references[j]; - const id = reference.identifier; - - /* - * Avoid counting a reference twice or more for default values of - * destructuring. - */ - if (id === prevId) { - continue; - } - prevId = id; - - // Add the identifier node into the destructuring group. - const group = getDestructuringHost(reference); - - if (group) { - if (identifierMap.has(group)) { - identifierMap.get(group).push(identifier); - } else { - identifierMap.set(group, [identifier]); - } - } - } - } - - return identifierMap; -} - -/** - * Finds the nearest parent of node with a given type. - * @param {ASTNode} node The node to search from. - * @param {string} type The type field of the parent node. - * @param {Function} shouldStop A predicate that returns true if the traversal should stop, and false otherwise. - * @returns {ASTNode} The closest ancestor with the specified type; null if no such ancestor exists. - */ -function findUp(node, type, shouldStop) { - if (!node || shouldStop(node)) { - return null; - } - if (node.type === type) { - return node; - } - return findUp(node.parent, type, shouldStop); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var preferConst = { - meta: { - type: "suggestion", - - docs: { - description: "require `const` declarations for variables that are never reassigned after declared", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/prefer-const" - }, - - fixable: "code", - - schema: [ - { - type: "object", - properties: { - destructuring: { enum: ["any", "all"], default: "any" }, - ignoreReadBeforeAssign: { type: "boolean", default: false } - }, - additionalProperties: false - } - ], - messages: { - useConst: "'{{name}}' is never reassigned. Use 'const' instead." - } - }, - - create(context) { - const options = context.options[0] || {}; - const sourceCode = context.getSourceCode(); - const shouldMatchAnyDestructuredVariable = options.destructuring !== "all"; - const ignoreReadBeforeAssign = options.ignoreReadBeforeAssign === true; - const variables = []; - let reportCount = 0; - let checkedId = null; - let checkedName = ""; - - - /** - * Reports given identifier nodes if all of the nodes should be declared - * as const. - * - * The argument 'nodes' is an array of Identifier nodes. - * This node is the result of 'getIdentifierIfShouldBeConst()', so it's - * nullable. In simple declaration or assignment cases, the length of - * the array is 1. In destructuring cases, the length of the array can - * be 2 or more. - * @param {(eslint-scope.Reference|null)[]} nodes - * References which are grouped by destructuring to report. - * @returns {void} - */ - function checkGroup(nodes) { - const nodesToReport = nodes.filter(Boolean); - - if (nodes.length && (shouldMatchAnyDestructuredVariable || nodesToReport.length === nodes.length)) { - const varDeclParent = findUp(nodes[0], "VariableDeclaration", parentNode => parentNode.type.endsWith("Statement")); - const isVarDecParentNull = varDeclParent === null; - - if (!isVarDecParentNull && varDeclParent.declarations.length > 0) { - const firstDeclaration = varDeclParent.declarations[0]; - - if (firstDeclaration.init) { - const firstDecParent = firstDeclaration.init.parent; - - /* - * First we check the declaration type and then depending on - * if the type is a "VariableDeclarator" or its an "ObjectPattern" - * we compare the name and id from the first identifier, if the names are different - * we assign the new name, id and reset the count of reportCount and nodeCount in - * order to check each block for the number of reported errors and base our fix - * based on comparing nodes.length and nodesToReport.length. - */ - - if (firstDecParent.type === "VariableDeclarator") { - - if (firstDecParent.id.name !== checkedName) { - checkedName = firstDecParent.id.name; - reportCount = 0; - } - - if (firstDecParent.id.type === "ObjectPattern") { - if (firstDecParent.init.name !== checkedName) { - checkedName = firstDecParent.init.name; - reportCount = 0; - } - } - - if (firstDecParent.id !== checkedId) { - checkedId = firstDecParent.id; - reportCount = 0; - } - } - } - } - - let shouldFix = varDeclParent && - - // Don't do a fix unless all variables in the declarations are initialized (or it's in a for-in or for-of loop) - (varDeclParent.parent.type === "ForInStatement" || varDeclParent.parent.type === "ForOfStatement" || - varDeclParent.declarations.every(declaration => declaration.init)) && - - /* - * If options.destructuring is "all", then this warning will not occur unless - * every assignment in the destructuring should be const. In that case, it's safe - * to apply the fix. - */ - nodesToReport.length === nodes.length; - - if (!isVarDecParentNull && varDeclParent.declarations && varDeclParent.declarations.length !== 1) { - - if (varDeclParent && varDeclParent.declarations && varDeclParent.declarations.length >= 1) { - - /* - * Add nodesToReport.length to a count, then comparing the count to the length - * of the declarations in the current block. - */ - - reportCount += nodesToReport.length; - - shouldFix = shouldFix && (reportCount === varDeclParent.declarations.length); - } - } - - nodesToReport.forEach(node => { - context.report({ - node, - messageId: "useConst", - data: node, - fix: shouldFix - ? fixer => { - const letKeywordToken = sourceCode.getFirstToken(varDeclParent, t => t.value === varDeclParent.kind); - - /** - * Extend the replacement range to the whole declaration, - * in order to prevent other fixes in the same pass - * https://github.com/eslint/eslint/issues/13899 - */ - return new fixTracker(fixer, sourceCode) - .retainRange(varDeclParent.range) - .replaceTextRange(letKeywordToken.range, "const"); - } - : null - }); - }); - } - } - - return { - "Program:exit"() { - groupByDestructuring(variables, ignoreReadBeforeAssign).forEach(checkGroup); - }, - - VariableDeclaration(node) { - if (node.kind === "let" && !isInitOfForStatement(node)) { - variables.push(...context.getDeclaredVariables(node)); - } - } - }; - } -}; - -/** - * @fileoverview Prefer destructuring from arrays and objects - * @author Alex LaFroscia - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const PRECEDENCE_OF_ASSIGNMENT_EXPR = astUtils.getPrecedence({ type: "AssignmentExpression" }); - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var preferDestructuring = { - meta: { - type: "suggestion", - - docs: { - description: "require destructuring from arrays and/or objects", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/prefer-destructuring" - }, - - fixable: "code", - - schema: [ - { - - /* - * old support {array: Boolean, object: Boolean} - * new support {VariableDeclarator: {}, AssignmentExpression: {}} - */ - oneOf: [ - { - type: "object", - properties: { - VariableDeclarator: { - type: "object", - properties: { - array: { - type: "boolean" - }, - object: { - type: "boolean" - } - }, - additionalProperties: false - }, - AssignmentExpression: { - type: "object", - properties: { - array: { - type: "boolean" - }, - object: { - type: "boolean" - } - }, - additionalProperties: false - } - }, - additionalProperties: false - }, - { - type: "object", - properties: { - array: { - type: "boolean" - }, - object: { - type: "boolean" - } - }, - additionalProperties: false - } - ] - }, - { - type: "object", - properties: { - enforceForRenamedProperties: { - type: "boolean" - } - }, - additionalProperties: false - } - ], - - messages: { - preferDestructuring: "Use {{type}} destructuring." - } - }, - create(context) { - - const enabledTypes = context.options[0]; - const enforceForRenamedProperties = context.options[1] && context.options[1].enforceForRenamedProperties; - let normalizedOptions = { - VariableDeclarator: { array: true, object: true }, - AssignmentExpression: { array: true, object: true } - }; - - if (enabledTypes) { - normalizedOptions = typeof enabledTypes.array !== "undefined" || typeof enabledTypes.object !== "undefined" - ? { VariableDeclarator: enabledTypes, AssignmentExpression: enabledTypes } - : enabledTypes; - } - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - // eslint-disable-next-line jsdoc/require-description - /** - * @param {string} nodeType "AssignmentExpression" or "VariableDeclarator" - * @param {string} destructuringType "array" or "object" - * @returns {boolean} `true` if the destructuring type should be checked for the given node - */ - function shouldCheck(nodeType, destructuringType) { - return normalizedOptions && - normalizedOptions[nodeType] && - normalizedOptions[nodeType][destructuringType]; - } - - /** - * Determines if the given node is accessing an array index - * - * This is used to differentiate array index access from object property - * access. - * @param {ASTNode} node the node to evaluate - * @returns {boolean} whether or not the node is an integer - */ - function isArrayIndexAccess(node) { - return Number.isInteger(node.property.value); - } - - /** - * Report that the given node should use destructuring - * @param {ASTNode} reportNode the node to report - * @param {string} type the type of destructuring that should have been done - * @param {Function|null} fix the fix function or null to pass to context.report - * @returns {void} - */ - function report(reportNode, type, fix) { - context.report({ - node: reportNode, - messageId: "preferDestructuring", - data: { type }, - fix - }); - } - - /** - * Determines if a node should be fixed into object destructuring - * - * The fixer only fixes the simplest case of object destructuring, - * like: `let x = a.x`; - * - * Assignment expression is not fixed. - * Array destructuring is not fixed. - * Renamed property is not fixed. - * @param {ASTNode} node the node to evaluate - * @returns {boolean} whether or not the node should be fixed - */ - function shouldFix(node) { - return node.type === "VariableDeclarator" && - node.id.type === "Identifier" && - node.init.type === "MemberExpression" && - !node.init.computed && - node.init.property.type === "Identifier" && - node.id.name === node.init.property.name; - } - - /** - * Fix a node into object destructuring. - * This function only handles the simplest case of object destructuring, - * see {@link shouldFix}. - * @param {SourceCodeFixer} fixer the fixer object - * @param {ASTNode} node the node to be fixed. - * @returns {Object} a fix for the node - */ - function fixIntoObjectDestructuring(fixer, node) { - const rightNode = node.init; - const sourceCode = context.getSourceCode(); - - // Don't fix if that would remove any comments. Only comments inside `rightNode.object` can be preserved. - if (sourceCode.getCommentsInside(node).length > sourceCode.getCommentsInside(rightNode.object).length) { - return null; - } - - let objectText = sourceCode.getText(rightNode.object); - - if (astUtils.getPrecedence(rightNode.object) < PRECEDENCE_OF_ASSIGNMENT_EXPR) { - objectText = `(${objectText})`; - } - - return fixer.replaceText( - node, - `{${rightNode.property.name}} = ${objectText}` - ); - } - - /** - * Check that the `prefer-destructuring` rules are followed based on the - * given left- and right-hand side of the assignment. - * - * Pulled out into a separate method so that VariableDeclarators and - * AssignmentExpressions can share the same verification logic. - * @param {ASTNode} leftNode the left-hand side of the assignment - * @param {ASTNode} rightNode the right-hand side of the assignment - * @param {ASTNode} reportNode the node to report the error on - * @returns {void} - */ - function performCheck(leftNode, rightNode, reportNode) { - if (rightNode.type !== "MemberExpression" || rightNode.object.type === "Super") { - return; - } - - if (isArrayIndexAccess(rightNode)) { - if (shouldCheck(reportNode.type, "array")) { - report(reportNode, "array", null); - } - return; - } - - const fix = shouldFix(reportNode) - ? fixer => fixIntoObjectDestructuring(fixer, reportNode) - : null; - - if (shouldCheck(reportNode.type, "object") && enforceForRenamedProperties) { - report(reportNode, "object", fix); - return; - } - - if (shouldCheck(reportNode.type, "object")) { - const property = rightNode.property; - - if ( - (property.type === "Literal" && leftNode.name === property.value) || - (property.type === "Identifier" && leftNode.name === property.name && !rightNode.computed) - ) { - report(reportNode, "object", fix); - } - } - } - - /** - * Check if a given variable declarator is coming from an property access - * that should be using destructuring instead - * @param {ASTNode} node the variable declarator to check - * @returns {void} - */ - function checkVariableDeclarator(node) { - - // Skip if variable is declared without assignment - if (!node.init) { - return; - } - - // We only care about member expressions past this point - if (node.init.type !== "MemberExpression") { - return; - } - - performCheck(node.id, node.init, node); - } - - /** - * Run the `prefer-destructuring` check on an AssignmentExpression - * @param {ASTNode} node the AssignmentExpression node - * @returns {void} - */ - function checkAssignmentExpression(node) { - if (node.operator === "=") { - performCheck(node.left, node.right, node); - } - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - VariableDeclarator: checkVariableDeclarator, - AssignmentExpression: checkAssignmentExpression - }; - } -}; - -/** - * @fileoverview Rule to disallow Math.pow in favor of the ** operator - * @author Milos Djermanovic - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - -const { CALL: CALL$4, ReferenceTracker: ReferenceTracker$4 } = require$$0__default$1['default']; - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const PRECEDENCE_OF_EXPONENTIATION_EXPR = astUtils.getPrecedence({ type: "BinaryExpression", operator: "**" }); - -/** - * Determines whether the given node needs parens if used as the base in an exponentiation binary expression. - * @param {ASTNode} base The node to check. - * @returns {boolean} `true` if the node needs to be parenthesised. - */ -function doesBaseNeedParens(base) { - return ( - - // '**' is right-associative, parens are needed when Math.pow(a ** b, c) is converted to (a ** b) ** c - astUtils.getPrecedence(base) <= PRECEDENCE_OF_EXPONENTIATION_EXPR || - - // An unary operator cannot be used immediately before an exponentiation expression - base.type === "AwaitExpression" || - base.type === "UnaryExpression" - ); -} - -/** - * Determines whether the given node needs parens if used as the exponent in an exponentiation binary expression. - * @param {ASTNode} exponent The node to check. - * @returns {boolean} `true` if the node needs to be parenthesised. - */ -function doesExponentNeedParens(exponent) { - - // '**' is right-associative, there is no need for parens when Math.pow(a, b ** c) is converted to a ** b ** c - return astUtils.getPrecedence(exponent) < PRECEDENCE_OF_EXPONENTIATION_EXPR; -} - -/** - * Determines whether an exponentiation binary expression at the place of the given node would need parens. - * @param {ASTNode} node A node that would be replaced by an exponentiation binary expression. - * @param {SourceCode} sourceCode A SourceCode object. - * @returns {boolean} `true` if the expression needs to be parenthesised. - */ -function doesExponentiationExpressionNeedParens(node, sourceCode) { - const parent = node.parent.type === "ChainExpression" ? node.parent.parent : node.parent; - - const needsParens = ( - parent.type === "ClassDeclaration" || - ( - parent.type.endsWith("Expression") && - astUtils.getPrecedence(parent) >= PRECEDENCE_OF_EXPONENTIATION_EXPR && - !(parent.type === "BinaryExpression" && parent.operator === "**" && parent.right === node) && - !((parent.type === "CallExpression" || parent.type === "NewExpression") && parent.arguments.includes(node)) && - !(parent.type === "MemberExpression" && parent.computed && parent.property === node) && - !(parent.type === "ArrayExpression") - ) - ); - - return needsParens && !astUtils.isParenthesised(sourceCode, node); -} - -/** - * Optionally parenthesizes given text. - * @param {string} text The text to parenthesize. - * @param {boolean} shouldParenthesize If `true`, the text will be parenthesised. - * @returns {string} parenthesised or unchanged text. - */ -function parenthesizeIfShould(text, shouldParenthesize) { - return shouldParenthesize ? `(${text})` : text; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var preferExponentiationOperator = { - meta: { - type: "suggestion", - - docs: { - description: "disallow the use of `Math.pow` in favor of the `**` operator", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/prefer-exponentiation-operator" - }, - - schema: [], - fixable: "code", - - messages: { - useExponentiation: "Use the '**' operator instead of 'Math.pow'." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - /** - * Reports the given node. - * @param {ASTNode} node 'Math.pow()' node to report. - * @returns {void} - */ - function report(node) { - context.report({ - node, - messageId: "useExponentiation", - fix(fixer) { - if ( - node.arguments.length !== 2 || - node.arguments.some(arg => arg.type === "SpreadElement") || - sourceCode.getCommentsInside(node).length > 0 - ) { - return null; - } - - const base = node.arguments[0], - exponent = node.arguments[1], - baseText = sourceCode.getText(base), - exponentText = sourceCode.getText(exponent), - shouldParenthesizeBase = doesBaseNeedParens(base), - shouldParenthesizeExponent = doesExponentNeedParens(exponent), - shouldParenthesizeAll = doesExponentiationExpressionNeedParens(node, sourceCode); - - let prefix = "", - suffix = ""; - - if (!shouldParenthesizeAll) { - if (!shouldParenthesizeBase) { - const firstReplacementToken = sourceCode.getFirstToken(base), - tokenBefore = sourceCode.getTokenBefore(node); - - if ( - tokenBefore && - tokenBefore.range[1] === node.range[0] && - !astUtils.canTokensBeAdjacent(tokenBefore, firstReplacementToken) - ) { - prefix = " "; // a+Math.pow(++b, c) -> a+ ++b**c - } - } - if (!shouldParenthesizeExponent) { - const lastReplacementToken = sourceCode.getLastToken(exponent), - tokenAfter = sourceCode.getTokenAfter(node); - - if ( - tokenAfter && - node.range[1] === tokenAfter.range[0] && - !astUtils.canTokensBeAdjacent(lastReplacementToken, tokenAfter) - ) { - suffix = " "; // Math.pow(a, b)in c -> a**b in c - } - } - } - - const baseReplacement = parenthesizeIfShould(baseText, shouldParenthesizeBase), - exponentReplacement = parenthesizeIfShould(exponentText, shouldParenthesizeExponent), - replacement = parenthesizeIfShould(`${baseReplacement}**${exponentReplacement}`, shouldParenthesizeAll); - - return fixer.replaceText(node, `${prefix}${replacement}${suffix}`); - } - }); - } - - return { - Program() { - const scope = context.getScope(); - const tracker = new ReferenceTracker$4(scope); - const trackMap = { - Math: { - pow: { [CALL$4]: true } - } - }; - - for (const { node } of tracker.iterateGlobalReferences(trackMap)) { - report(node); - } - } - }; - } -}; - -/** - * @fileoverview Rule to enforce requiring named capture groups in regular expression. - * @author Pig Fang - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -const { - CALL: CALL$3, - CONSTRUCT: CONSTRUCT$2, - ReferenceTracker: ReferenceTracker$3, - getStringIfConstant: getStringIfConstant$1 -} = require$$0__default$1['default']; - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const parser = new regexpp__default['default'].RegExpParser(); - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var preferNamedCaptureGroup = { - meta: { - type: "suggestion", - - docs: { - description: "enforce using named capture group in regular expression", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/prefer-named-capture-group" - }, - - schema: [], - - messages: { - required: "Capture group '{{group}}' should be converted to a named or non-capturing group." - } - }, - - create(context) { - - /** - * Function to check regular expression. - * @param {string} pattern The regular expression pattern to be check. - * @param {ASTNode} node AST node which contains regular expression. - * @param {boolean} uFlag Flag indicates whether unicode mode is enabled or not. - * @returns {void} - */ - function checkRegex(pattern, node, uFlag) { - let ast; - - try { - ast = parser.parsePattern(pattern, 0, pattern.length, uFlag); - } catch { - - // ignore regex syntax errors - return; - } - - regexpp__default['default'].visitRegExpAST(ast, { - onCapturingGroupEnter(group) { - if (!group.name) { - context.report({ - node, - messageId: "required", - data: { - group: group.raw - } - }); - } - } - }); - } - - return { - Literal(node) { - if (node.regex) { - checkRegex(node.regex.pattern, node, node.regex.flags.includes("u")); - } - }, - Program() { - const scope = context.getScope(); - const tracker = new ReferenceTracker$3(scope); - const traceMap = { - RegExp: { - [CALL$3]: true, - [CONSTRUCT$2]: true - } - }; - - for (const { node } of tracker.iterateGlobalReferences(traceMap)) { - const regex = getStringIfConstant$1(node.arguments[0]); - const flags = getStringIfConstant$1(node.arguments[1]); - - if (regex) { - checkRegex(regex, node, flags && flags.includes("u")); - } - } - } - }; - } -}; - -/** - * @fileoverview Rule to disallow `parseInt()` in favor of binary, octal, and hexadecimal literals - * @author Annie Zhang, Henry Zhu - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const radixMap = new Map([ - [2, { system: "binary", literalPrefix: "0b" }], - [8, { system: "octal", literalPrefix: "0o" }], - [16, { system: "hexadecimal", literalPrefix: "0x" }] -]); - -/** - * Checks to see if a CallExpression's callee node is `parseInt` or - * `Number.parseInt`. - * @param {ASTNode} calleeNode The callee node to evaluate. - * @returns {boolean} True if the callee is `parseInt` or `Number.parseInt`, - * false otherwise. - */ -function isParseInt(calleeNode) { - return ( - astUtils.isSpecificId(calleeNode, "parseInt") || - astUtils.isSpecificMemberAccess(calleeNode, "Number", "parseInt") - ); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var preferNumericLiterals = { - meta: { - type: "suggestion", - - docs: { - description: "disallow `parseInt()` and `Number.parseInt()` in favor of binary, octal, and hexadecimal literals", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/prefer-numeric-literals" - }, - - schema: [], - - messages: { - useLiteral: "Use {{system}} literals instead of {{functionName}}()." - }, - - fixable: "code" - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - - return { - - "CallExpression[arguments.length=2]"(node) { - const [strNode, radixNode] = node.arguments, - str = astUtils.getStaticStringValue(strNode), - radix = radixNode.value; - - if ( - str !== null && - astUtils.isStringLiteral(strNode) && - radixNode.type === "Literal" && - typeof radix === "number" && - radixMap.has(radix) && - isParseInt(node.callee) - ) { - - const { system, literalPrefix } = radixMap.get(radix); - - context.report({ - node, - messageId: "useLiteral", - data: { - system, - functionName: sourceCode.getText(node.callee) - }, - fix(fixer) { - if (sourceCode.getCommentsInside(node).length) { - return null; - } - - const replacement = `${literalPrefix}${str}`; - - if (+replacement !== parseInt(str, radix)) { - - /* - * If the newly-produced literal would be invalid, (e.g. 0b1234), - * or it would yield an incorrect parseInt result for some other reason, don't make a fix. - * - * If `str` had numeric separators, `+replacement` will evaluate to `NaN` because unary `+` - * per the specification doesn't support numeric separators. Thus, the above condition will be `true` - * (`NaN !== anything` is always `true`) regardless of the `parseInt(str, radix)` value. - * Consequently, no autofixes will be made. This is correct behavior because `parseInt` also - * doesn't support numeric separators, but it does parse part of the string before the first `_`, - * so the autofix would be invalid: - * - * parseInt("1_1", 2) // === 1 - * 0b1_1 // === 3 - */ - return null; - } - - const tokenBefore = sourceCode.getTokenBefore(node), - tokenAfter = sourceCode.getTokenAfter(node); - let prefix = "", - suffix = ""; - - if ( - tokenBefore && - tokenBefore.range[1] === node.range[0] && - !astUtils.canTokensBeAdjacent(tokenBefore, replacement) - ) { - prefix = " "; - } - - if ( - tokenAfter && - node.range[1] === tokenAfter.range[0] && - !astUtils.canTokensBeAdjacent(replacement, tokenAfter) - ) { - suffix = " "; - } - - return fixer.replaceText(node, `${prefix}${replacement}${suffix}`); - } - }); - } - } - }; - } -}; - -/** - * @fileoverview Prefers object spread property over Object.assign - * @author Sharmila Jesupaul - * See LICENSE file in root directory for full license. - */ - -const { CALL: CALL$2, ReferenceTracker: ReferenceTracker$2 } = require$$0__default$1['default']; -const { - isCommaToken, - isOpeningParenToken, - isClosingParenToken, - isParenthesised -} = astUtils; - -const ANY_SPACE = /\s/u; - -/** - * Helper that checks if the Object.assign call has array spread - * @param {ASTNode} node The node that the rule warns on - * @returns {boolean} - Returns true if the Object.assign call has array spread - */ -function hasArraySpread(node) { - return node.arguments.some(arg => arg.type === "SpreadElement"); -} - -/** - * Determines whether the given node is an accessor property (getter/setter). - * @param {ASTNode} node Node to check. - * @returns {boolean} `true` if the node is a getter or a setter. - */ -function isAccessorProperty(node) { - return node.type === "Property" && - (node.kind === "get" || node.kind === "set"); -} - -/** - * Determines whether the given object expression node has accessor properties (getters/setters). - * @param {ASTNode} node `ObjectExpression` node to check. - * @returns {boolean} `true` if the node has at least one getter/setter. - */ -function hasAccessors(node) { - return node.properties.some(isAccessorProperty); -} - -/** - * Determines whether the given call expression node has object expression arguments with accessor properties (getters/setters). - * @param {ASTNode} node `CallExpression` node to check. - * @returns {boolean} `true` if the node has at least one argument that is an object expression with at least one getter/setter. - */ -function hasArgumentsWithAccessors(node) { - return node.arguments - .filter(arg => arg.type === "ObjectExpression") - .some(hasAccessors); -} - -/** - * Helper that checks if the node needs parentheses to be valid JS. - * The default is to wrap the node in parentheses to avoid parsing errors. - * @param {ASTNode} node The node that the rule warns on - * @param {Object} sourceCode in context sourcecode object - * @returns {boolean} - Returns true if the node needs parentheses - */ -function needsParens(node, sourceCode) { - const parent = node.parent; - - switch (parent.type) { - case "VariableDeclarator": - case "ArrayExpression": - case "ReturnStatement": - case "CallExpression": - case "Property": - return false; - case "AssignmentExpression": - return parent.left === node && !isParenthesised(sourceCode, node); - default: - return !isParenthesised(sourceCode, node); - } -} - -/** - * Determines if an argument needs parentheses. The default is to not add parens. - * @param {ASTNode} node The node to be checked. - * @param {Object} sourceCode in context sourcecode object - * @returns {boolean} True if the node needs parentheses - */ -function argNeedsParens(node, sourceCode) { - switch (node.type) { - case "AssignmentExpression": - case "ArrowFunctionExpression": - case "ConditionalExpression": - return !isParenthesised(sourceCode, node); - default: - return false; - } -} - -/** - * Get the parenthesis tokens of a given ObjectExpression node. - * This includes the braces of the object literal and enclosing parentheses. - * @param {ASTNode} node The node to get. - * @param {Token} leftArgumentListParen The opening paren token of the argument list. - * @param {SourceCode} sourceCode The source code object to get tokens. - * @returns {Token[]} The parenthesis tokens of the node. This is sorted by the location. - */ -function getParenTokens(node, leftArgumentListParen, sourceCode) { - const parens = [sourceCode.getFirstToken(node), sourceCode.getLastToken(node)]; - let leftNext = sourceCode.getTokenBefore(node); - let rightNext = sourceCode.getTokenAfter(node); - - // Note: don't include the parens of the argument list. - while ( - leftNext && - rightNext && - leftNext.range[0] > leftArgumentListParen.range[0] && - isOpeningParenToken(leftNext) && - isClosingParenToken(rightNext) - ) { - parens.push(leftNext, rightNext); - leftNext = sourceCode.getTokenBefore(leftNext); - rightNext = sourceCode.getTokenAfter(rightNext); - } - - return parens.sort((a, b) => a.range[0] - b.range[0]); -} - -/** - * Get the range of a given token and around whitespaces. - * @param {Token} token The token to get range. - * @param {SourceCode} sourceCode The source code object to get tokens. - * @returns {number} The end of the range of the token and around whitespaces. - */ -function getStartWithSpaces(token, sourceCode) { - const text = sourceCode.text; - let start = token.range[0]; - - // If the previous token is a line comment then skip this step to avoid commenting this token out. - { - const prevToken = sourceCode.getTokenBefore(token, { includeComments: true }); - - if (prevToken && prevToken.type === "Line") { - return start; - } - } - - // Detect spaces before the token. - while (ANY_SPACE.test(text[start - 1] || "")) { - start -= 1; - } - - return start; -} - -/** - * Get the range of a given token and around whitespaces. - * @param {Token} token The token to get range. - * @param {SourceCode} sourceCode The source code object to get tokens. - * @returns {number} The start of the range of the token and around whitespaces. - */ -function getEndWithSpaces(token, sourceCode) { - const text = sourceCode.text; - let end = token.range[1]; - - // Detect spaces after the token. - while (ANY_SPACE.test(text[end] || "")) { - end += 1; - } - - return end; -} - -/** - * Autofixes the Object.assign call to use an object spread instead. - * @param {ASTNode|null} node The node that the rule warns on, i.e. the Object.assign call - * @param {string} sourceCode sourceCode of the Object.assign call - * @returns {Function} autofixer - replaces the Object.assign with a spread object. - */ -function defineFixer(node, sourceCode) { - return function *(fixer) { - const leftParen = sourceCode.getTokenAfter(node.callee, isOpeningParenToken); - const rightParen = sourceCode.getLastToken(node); - - // Remove everything before the opening paren: callee `Object.assign`, type arguments, and whitespace between the callee and the paren. - yield fixer.removeRange([node.range[0], leftParen.range[0]]); - - // Replace the parens of argument list to braces. - if (needsParens(node, sourceCode)) { - yield fixer.replaceText(leftParen, "({"); - yield fixer.replaceText(rightParen, "})"); - } else { - yield fixer.replaceText(leftParen, "{"); - yield fixer.replaceText(rightParen, "}"); - } - - // Process arguments. - for (const argNode of node.arguments) { - const innerParens = getParenTokens(argNode, leftParen, sourceCode); - const left = innerParens.shift(); - const right = innerParens.pop(); - - if (argNode.type === "ObjectExpression") { - const maybeTrailingComma = sourceCode.getLastToken(argNode, 1); - const maybeArgumentComma = sourceCode.getTokenAfter(right); - - /* - * Make bare this object literal. - * And remove spaces inside of the braces for better formatting. - */ - for (const innerParen of innerParens) { - yield fixer.remove(innerParen); - } - const leftRange = [left.range[0], getEndWithSpaces(left, sourceCode)]; - const rightRange = [ - Math.max(getStartWithSpaces(right, sourceCode), leftRange[1]), // Ensure ranges don't overlap - right.range[1] - ]; - - yield fixer.removeRange(leftRange); - yield fixer.removeRange(rightRange); - - // Remove the comma of this argument if it's duplication. - if ( - (argNode.properties.length === 0 || isCommaToken(maybeTrailingComma)) && - isCommaToken(maybeArgumentComma) - ) { - yield fixer.remove(maybeArgumentComma); - } - } else { - - // Make spread. - if (argNeedsParens(argNode, sourceCode)) { - yield fixer.insertTextBefore(left, "...("); - yield fixer.insertTextAfter(right, ")"); - } else { - yield fixer.insertTextBefore(left, "..."); - } - } - } - }; -} - -var preferObjectSpread = { - meta: { - type: "suggestion", - - docs: { - description: - "disallow using Object.assign with an object literal as the first argument and prefer the use of object spread instead.", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/prefer-object-spread" - }, - - schema: [], - fixable: "code", - - messages: { - useSpreadMessage: "Use an object spread instead of `Object.assign` eg: `{ ...foo }`.", - useLiteralMessage: "Use an object literal instead of `Object.assign`. eg: `{ foo: bar }`." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - return { - Program() { - const scope = context.getScope(); - const tracker = new ReferenceTracker$2(scope); - const trackMap = { - Object: { - assign: { [CALL$2]: true } - } - }; - - // Iterate all calls of `Object.assign` (only of the global variable `Object`). - for (const { node } of tracker.iterateGlobalReferences(trackMap)) { - if ( - node.arguments.length >= 1 && - node.arguments[0].type === "ObjectExpression" && - !hasArraySpread(node) && - !( - node.arguments.length > 1 && - hasArgumentsWithAccessors(node) - ) - ) { - const messageId = node.arguments.length === 1 - ? "useLiteralMessage" - : "useSpreadMessage"; - const fix = defineFixer(node, sourceCode); - - context.report({ node, messageId, fix }); - } - } - } - }; - } -}; - -/** - * @fileoverview restrict values that can be used as Promise rejection reasons - * @author Teddy Katz - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var preferPromiseRejectErrors = { - meta: { - type: "suggestion", - - docs: { - description: "require using Error objects as Promise rejection reasons", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/prefer-promise-reject-errors" - }, - - fixable: null, - - schema: [ - { - type: "object", - properties: { - allowEmptyReject: { type: "boolean", default: false } - }, - additionalProperties: false - } - ], - - messages: { - rejectAnError: "Expected the Promise rejection reason to be an Error." - } - }, - - create(context) { - - const ALLOW_EMPTY_REJECT = context.options.length && context.options[0].allowEmptyReject; - - //---------------------------------------------------------------------- - // Helpers - //---------------------------------------------------------------------- - - /** - * Checks the argument of a reject() or Promise.reject() CallExpression, and reports it if it can't be an Error - * @param {ASTNode} callExpression A CallExpression node which is used to reject a Promise - * @returns {void} - */ - function checkRejectCall(callExpression) { - if (!callExpression.arguments.length && ALLOW_EMPTY_REJECT) { - return; - } - if ( - !callExpression.arguments.length || - !astUtils.couldBeError(callExpression.arguments[0]) || - callExpression.arguments[0].type === "Identifier" && callExpression.arguments[0].name === "undefined" - ) { - context.report({ - node: callExpression, - messageId: "rejectAnError" - }); - } - } - - /** - * Determines whether a function call is a Promise.reject() call - * @param {ASTNode} node A CallExpression node - * @returns {boolean} `true` if the call is a Promise.reject() call - */ - function isPromiseRejectCall(node) { - return astUtils.isSpecificMemberAccess(node.callee, "Promise", "reject"); - } - - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - - return { - - // Check `Promise.reject(value)` calls. - CallExpression(node) { - if (isPromiseRejectCall(node)) { - checkRejectCall(node); - } - }, - - /* - * Check for `new Promise((resolve, reject) => {})`, and check for reject() calls. - * This function is run on "NewExpression:exit" instead of "NewExpression" to ensure that - * the nodes in the expression already have the `parent` property. - */ - "NewExpression:exit"(node) { - if ( - node.callee.type === "Identifier" && node.callee.name === "Promise" && - node.arguments.length && astUtils.isFunction(node.arguments[0]) && - node.arguments[0].params.length > 1 && node.arguments[0].params[1].type === "Identifier" - ) { - context.getDeclaredVariables(node.arguments[0]) - - /* - * Find the first variable that matches the second parameter's name. - * If the first parameter has the same name as the second parameter, then the variable will actually - * be "declared" when the first parameter is evaluated, but then it will be immediately overwritten - * by the second parameter. It's not possible for an expression with the variable to be evaluated before - * the variable is overwritten, because functions with duplicate parameters cannot have destructuring or - * default assignments in their parameter lists. Therefore, it's not necessary to explicitly account for - * this case. - */ - .find(variable => variable.name === node.arguments[0].params[1].name) - - // Get the references to that variable. - .references - - // Only check the references that read the parameter's value. - .filter(ref => ref.isRead()) - - // Only check the references that are used as the callee in a function call, e.g. `reject(foo)`. - .filter(ref => ref.identifier.parent.type === "CallExpression" && ref.identifier === ref.identifier.parent.callee) - - // Check the argument of the function call to determine whether it's an Error. - .forEach(ref => checkRejectCall(ref.identifier.parent)); - } - } - }; - } -}; - -/** - * @fileoverview Rule to suggest using "Reflect" api over Function/Object methods - * @author Keith Cirkel - * @deprecated in ESLint v3.9.0 - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var preferReflect = { - meta: { - type: "suggestion", - - docs: { - description: "require `Reflect` methods where applicable", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/prefer-reflect" - }, - - deprecated: true, - - replacedBy: [], - - schema: [ - { - type: "object", - properties: { - exceptions: { - type: "array", - items: { - enum: [ - "apply", - "call", - "delete", - "defineProperty", - "getOwnPropertyDescriptor", - "getPrototypeOf", - "setPrototypeOf", - "isExtensible", - "getOwnPropertyNames", - "preventExtensions" - ] - }, - uniqueItems: true - } - }, - additionalProperties: false - } - ], - - messages: { - preferReflect: "Avoid using {{existing}}, instead use {{substitute}}." - } - }, - - create(context) { - const existingNames = { - apply: "Function.prototype.apply", - call: "Function.prototype.call", - defineProperty: "Object.defineProperty", - getOwnPropertyDescriptor: "Object.getOwnPropertyDescriptor", - getPrototypeOf: "Object.getPrototypeOf", - setPrototypeOf: "Object.setPrototypeOf", - isExtensible: "Object.isExtensible", - getOwnPropertyNames: "Object.getOwnPropertyNames", - preventExtensions: "Object.preventExtensions" - }; - - const reflectSubstitutes = { - apply: "Reflect.apply", - call: "Reflect.apply", - defineProperty: "Reflect.defineProperty", - getOwnPropertyDescriptor: "Reflect.getOwnPropertyDescriptor", - getPrototypeOf: "Reflect.getPrototypeOf", - setPrototypeOf: "Reflect.setPrototypeOf", - isExtensible: "Reflect.isExtensible", - getOwnPropertyNames: "Reflect.getOwnPropertyNames", - preventExtensions: "Reflect.preventExtensions" - }; - - const exceptions = (context.options[0] || {}).exceptions || []; - - /** - * Reports the Reflect violation based on the `existing` and `substitute` - * @param {Object} node The node that violates the rule. - * @param {string} existing The existing method name that has been used. - * @param {string} substitute The Reflect substitute that should be used. - * @returns {void} - */ - function report(node, existing, substitute) { - context.report({ - node, - messageId: "preferReflect", - data: { - existing, - substitute - } - }); - } - - return { - CallExpression(node) { - const methodName = (node.callee.property || {}).name; - const isReflectCall = (node.callee.object || {}).name === "Reflect"; - const hasReflectSubstitute = Object.prototype.hasOwnProperty.call(reflectSubstitutes, methodName); - const userConfiguredException = exceptions.indexOf(methodName) !== -1; - - if (hasReflectSubstitute && !isReflectCall && !userConfiguredException) { - report(node, existingNames[methodName], reflectSubstitutes[methodName]); - } - }, - UnaryExpression(node) { - const isDeleteOperator = node.operator === "delete"; - const targetsIdentifier = node.argument.type === "Identifier"; - const userConfiguredException = exceptions.indexOf("delete") !== -1; - - if (isDeleteOperator && !targetsIdentifier && !userConfiguredException) { - report(node, "the delete keyword", "Reflect.deleteProperty"); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to disallow use of the `RegExp` constructor in favor of regular expression literals - * @author Milos Djermanovic - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - -const { CALL: CALL$1, CONSTRUCT: CONSTRUCT$1, ReferenceTracker: ReferenceTracker$1, findVariable } = require$$0__default$1['default']; - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Determines whether the given node is a string literal. - * @param {ASTNode} node Node to check. - * @returns {boolean} True if the node is a string literal. - */ -function isStringLiteral(node) { - return node.type === "Literal" && typeof node.value === "string"; -} - -/** - * Determines whether the given node is a regex literal. - * @param {ASTNode} node Node to check. - * @returns {boolean} True if the node is a regex literal. - */ -function isRegexLiteral(node) { - return node.type === "Literal" && Object.prototype.hasOwnProperty.call(node, "regex"); -} - -/** - * Determines whether the given node is a template literal without expressions. - * @param {ASTNode} node Node to check. - * @returns {boolean} True if the node is a template literal without expressions. - */ -function isStaticTemplateLiteral$1(node) { - return node.type === "TemplateLiteral" && node.expressions.length === 0; -} - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var preferRegexLiterals = { - meta: { - type: "suggestion", - - docs: { - description: "disallow use of the `RegExp` constructor in favor of regular expression literals", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/prefer-regex-literals" - }, - - schema: [ - { - type: "object", - properties: { - disallowRedundantWrapping: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - messages: { - unexpectedRegExp: "Use a regular expression literal instead of the 'RegExp' constructor.", - unexpectedRedundantRegExp: "Regular expression literal is unnecessarily wrapped within a 'RegExp' constructor.", - unexpectedRedundantRegExpWithFlags: "Use regular expression literal with flags instead of the 'RegExp' constructor." - } - }, - - create(context) { - const [{ disallowRedundantWrapping = false } = {}] = context.options; - - /** - * Determines whether the given identifier node is a reference to a global variable. - * @param {ASTNode} node `Identifier` node to check. - * @returns {boolean} True if the identifier is a reference to a global variable. - */ - function isGlobalReference(node) { - const scope = context.getScope(); - const variable = findVariable(scope, node); - - return variable !== null && variable.scope.type === "global" && variable.defs.length === 0; - } - - /** - * Determines whether the given node is a String.raw`` tagged template expression - * with a static template literal. - * @param {ASTNode} node Node to check. - * @returns {boolean} True if the node is String.raw`` with a static template. - */ - function isStringRawTaggedStaticTemplateLiteral(node) { - return node.type === "TaggedTemplateExpression" && - astUtils.isSpecificMemberAccess(node.tag, "String", "raw") && - isGlobalReference(astUtils.skipChainExpression(node.tag).object) && - isStaticTemplateLiteral$1(node.quasi); - } - - /** - * Determines whether the given node is considered to be a static string by the logic of this rule. - * @param {ASTNode} node Node to check. - * @returns {boolean} True if the node is a static string. - */ - function isStaticString(node) { - return isStringLiteral(node) || - isStaticTemplateLiteral$1(node) || - isStringRawTaggedStaticTemplateLiteral(node); - } - - /** - * Determines whether the relevant arguments of the given are all static string literals. - * @param {ASTNode} node Node to check. - * @returns {boolean} True if all arguments are static strings. - */ - function hasOnlyStaticStringArguments(node) { - const args = node.arguments; - - if ((args.length === 1 || args.length === 2) && args.every(isStaticString)) { - return true; - } - - return false; - } - - /** - * Determines whether the arguments of the given node indicate that a regex literal is unnecessarily wrapped. - * @param {ASTNode} node Node to check. - * @returns {boolean} True if the node already contains a regex literal argument. - */ - function isUnnecessarilyWrappedRegexLiteral(node) { - const args = node.arguments; - - if (args.length === 1 && isRegexLiteral(args[0])) { - return true; - } - - if (args.length === 2 && isRegexLiteral(args[0]) && isStaticString(args[1])) { - return true; - } - - return false; - } - - return { - Program() { - const scope = context.getScope(); - const tracker = new ReferenceTracker$1(scope); - const traceMap = { - RegExp: { - [CALL$1]: true, - [CONSTRUCT$1]: true - } - }; - - for (const { node } of tracker.iterateGlobalReferences(traceMap)) { - if (disallowRedundantWrapping && isUnnecessarilyWrappedRegexLiteral(node)) { - if (node.arguments.length === 2) { - context.report({ node, messageId: "unexpectedRedundantRegExpWithFlags" }); - } else { - context.report({ node, messageId: "unexpectedRedundantRegExp" }); - } - } else if (hasOnlyStaticStringArguments(node)) { - context.report({ node, messageId: "unexpectedRegExp" }); - } - } - } - }; - } -}; - -/** - * @fileoverview Rule to - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Gets the variable object of `arguments` which is defined implicitly. - * @param {eslint-scope.Scope} scope A scope to get. - * @returns {eslint-scope.Variable} The found variable object. - */ -function getVariableOfArguments(scope) { - const variables = scope.variables; - - for (let i = 0; i < variables.length; ++i) { - const variable = variables[i]; - - if (variable.name === "arguments") { - - /* - * If there was a parameter which is named "arguments", the implicit "arguments" is not defined. - * So does fast return with null. - */ - return (variable.identifiers.length === 0) ? variable : null; - } - } - - /* istanbul ignore next : unreachable */ - return null; -} - -/** - * Checks if the given reference is not normal member access. - * - * - arguments .... true // not member access - * - arguments[i] .... true // computed member access - * - arguments[0] .... true // computed member access - * - arguments.length .... false // normal member access - * @param {eslint-scope.Reference} reference The reference to check. - * @returns {boolean} `true` if the reference is not normal member access. - */ -function isNotNormalMemberAccess(reference) { - const id = reference.identifier; - const parent = id.parent; - - return !( - parent.type === "MemberExpression" && - parent.object === id && - !parent.computed - ); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var preferRestParams = { - meta: { - type: "suggestion", - - docs: { - description: "require rest parameters instead of `arguments`", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/prefer-rest-params" - }, - - schema: [], - - messages: { - preferRestParams: "Use the rest parameters instead of 'arguments'." - } - }, - - create(context) { - - /** - * Reports a given reference. - * @param {eslint-scope.Reference} reference A reference to report. - * @returns {void} - */ - function report(reference) { - context.report({ - node: reference.identifier, - loc: reference.identifier.loc, - messageId: "preferRestParams" - }); - } - - /** - * Reports references of the implicit `arguments` variable if exist. - * @returns {void} - */ - function checkForArguments() { - const argumentsVar = getVariableOfArguments(context.getScope()); - - if (argumentsVar) { - argumentsVar - .references - .filter(isNotNormalMemberAccess) - .forEach(report); - } - } - - return { - "FunctionDeclaration:exit": checkForArguments, - "FunctionExpression:exit": checkForArguments - }; - } -}; - -/** - * @fileoverview A rule to suggest using of the spread operator instead of `.apply()`. - * @author Toru Nagashima - */ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether or not a node is a `.apply()` for variadic. - * @param {ASTNode} node A CallExpression node to check. - * @returns {boolean} Whether or not the node is a `.apply()` for variadic. - */ -function isVariadicApplyCalling(node) { - return ( - astUtils.isSpecificMemberAccess(node.callee, null, "apply") && - node.arguments.length === 2 && - node.arguments[1].type !== "ArrayExpression" && - node.arguments[1].type !== "SpreadElement" - ); -} - -/** - * Checks whether or not `thisArg` is not changed by `.apply()`. - * @param {ASTNode|null} expectedThis The node that is the owner of the applied function. - * @param {ASTNode} thisArg The node that is given to the first argument of the `.apply()`. - * @param {RuleContext} context The ESLint rule context object. - * @returns {boolean} Whether or not `thisArg` is not changed by `.apply()`. - */ -function isValidThisArg(expectedThis, thisArg, context) { - if (!expectedThis) { - return astUtils.isNullOrUndefined(thisArg); - } - return astUtils.equalTokens(expectedThis, thisArg, context); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var preferSpread = { - meta: { - type: "suggestion", - - docs: { - description: "require spread operators instead of `.apply()`", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/prefer-spread" - }, - - schema: [], - fixable: null, - - messages: { - preferSpread: "Use the spread operator instead of '.apply()'." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - return { - CallExpression(node) { - if (!isVariadicApplyCalling(node)) { - return; - } - - const applied = astUtils.skipChainExpression(astUtils.skipChainExpression(node.callee).object); - const expectedThis = (applied.type === "MemberExpression") ? applied.object : null; - const thisArg = node.arguments[0]; - - if (isValidThisArg(expectedThis, thisArg, sourceCode)) { - context.report({ - node, - messageId: "preferSpread" - }); - } - } - }; - } -}; - -/** - * @fileoverview A rule to suggest using template literals instead of string concatenation. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether or not a given node is a concatenation. - * @param {ASTNode} node A node to check. - * @returns {boolean} `true` if the node is a concatenation. - */ -function isConcatenation(node) { - return node.type === "BinaryExpression" && node.operator === "+"; -} - -/** - * Gets the top binary expression node for concatenation in parents of a given node. - * @param {ASTNode} node A node to get. - * @returns {ASTNode} the top binary expression node in parents of a given node. - */ -function getTopConcatBinaryExpression(node) { - let currentNode = node; - - while (isConcatenation(currentNode.parent)) { - currentNode = currentNode.parent; - } - return currentNode; -} - -/** - * Checks whether or not a node contains a string literal with an octal or non-octal decimal escape sequence - * @param {ASTNode} node A node to check - * @returns {boolean} `true` if at least one string literal within the node contains - * an octal or non-octal decimal escape sequence - */ -function hasOctalOrNonOctalDecimalEscapeSequence(node) { - if (isConcatenation(node)) { - return ( - hasOctalOrNonOctalDecimalEscapeSequence(node.left) || - hasOctalOrNonOctalDecimalEscapeSequence(node.right) - ); - } - - // No need to check TemplateLiterals – would throw parsing error - if (node.type === "Literal" && typeof node.value === "string") { - return astUtils.hasOctalOrNonOctalDecimalEscapeSequence(node.raw); - } - - return false; -} - -/** - * Checks whether or not a given binary expression has string literals. - * @param {ASTNode} node A node to check. - * @returns {boolean} `true` if the node has string literals. - */ -function hasStringLiteral(node) { - if (isConcatenation(node)) { - - // `left` is deeper than `right` normally. - return hasStringLiteral(node.right) || hasStringLiteral(node.left); - } - return astUtils.isStringLiteral(node); -} - -/** - * Checks whether or not a given binary expression has non string literals. - * @param {ASTNode} node A node to check. - * @returns {boolean} `true` if the node has non string literals. - */ -function hasNonStringLiteral(node) { - if (isConcatenation(node)) { - - // `left` is deeper than `right` normally. - return hasNonStringLiteral(node.right) || hasNonStringLiteral(node.left); - } - return !astUtils.isStringLiteral(node); -} - -/** - * Determines whether a given node will start with a template curly expression (`${}`) when being converted to a template literal. - * @param {ASTNode} node The node that will be fixed to a template literal - * @returns {boolean} `true` if the node will start with a template curly. - */ -function startsWithTemplateCurly(node) { - if (node.type === "BinaryExpression") { - return startsWithTemplateCurly(node.left); - } - if (node.type === "TemplateLiteral") { - return node.expressions.length && node.quasis.length && node.quasis[0].range[0] === node.quasis[0].range[1]; - } - return node.type !== "Literal" || typeof node.value !== "string"; -} - -/** - * Determines whether a given node end with a template curly expression (`${}`) when being converted to a template literal. - * @param {ASTNode} node The node that will be fixed to a template literal - * @returns {boolean} `true` if the node will end with a template curly. - */ -function endsWithTemplateCurly(node) { - if (node.type === "BinaryExpression") { - return startsWithTemplateCurly(node.right); - } - if (node.type === "TemplateLiteral") { - return node.expressions.length && node.quasis.length && node.quasis[node.quasis.length - 1].range[0] === node.quasis[node.quasis.length - 1].range[1]; - } - return node.type !== "Literal" || typeof node.value !== "string"; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var preferTemplate = { - meta: { - type: "suggestion", - - docs: { - description: "require template literals instead of string concatenation", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/prefer-template" - }, - - schema: [], - fixable: "code", - - messages: { - unexpectedStringConcatenation: "Unexpected string concatenation." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - let done = Object.create(null); - - /** - * Gets the non-token text between two nodes, ignoring any other tokens that appear between the two tokens. - * @param {ASTNode} node1 The first node - * @param {ASTNode} node2 The second node - * @returns {string} The text between the nodes, excluding other tokens - */ - function getTextBetween(node1, node2) { - const allTokens = [node1].concat(sourceCode.getTokensBetween(node1, node2)).concat(node2); - const sourceText = sourceCode.getText(); - - return allTokens.slice(0, -1).reduce((accumulator, token, index) => accumulator + sourceText.slice(token.range[1], allTokens[index + 1].range[0]), ""); - } - - /** - * Returns a template literal form of the given node. - * @param {ASTNode} currentNode A node that should be converted to a template literal - * @param {string} textBeforeNode Text that should appear before the node - * @param {string} textAfterNode Text that should appear after the node - * @returns {string} A string form of this node, represented as a template literal - */ - function getTemplateLiteral(currentNode, textBeforeNode, textAfterNode) { - if (currentNode.type === "Literal" && typeof currentNode.value === "string") { - - /* - * If the current node is a string literal, escape any instances of ${ or ` to prevent them from being interpreted - * as a template placeholder. However, if the code already contains a backslash before the ${ or ` - * for some reason, don't add another backslash, because that would change the meaning of the code (it would cause - * an actual backslash character to appear before the dollar sign). - */ - return `\`${currentNode.raw.slice(1, -1).replace(/\\*(\$\{|`)/gu, matched => { - if (matched.lastIndexOf("\\") % 2) { - return `\\${matched}`; - } - return matched; - - // Unescape any quotes that appear in the original Literal that no longer need to be escaped. - }).replace(new RegExp(`\\\\${currentNode.raw[0]}`, "gu"), currentNode.raw[0])}\``; - } - - if (currentNode.type === "TemplateLiteral") { - return sourceCode.getText(currentNode); - } - - if (isConcatenation(currentNode) && hasStringLiteral(currentNode) && hasNonStringLiteral(currentNode)) { - const plusSign = sourceCode.getFirstTokenBetween(currentNode.left, currentNode.right, token => token.value === "+"); - const textBeforePlus = getTextBetween(currentNode.left, plusSign); - const textAfterPlus = getTextBetween(plusSign, currentNode.right); - const leftEndsWithCurly = endsWithTemplateCurly(currentNode.left); - const rightStartsWithCurly = startsWithTemplateCurly(currentNode.right); - - if (leftEndsWithCurly) { - - // If the left side of the expression ends with a template curly, add the extra text to the end of the curly bracket. - // `foo${bar}` /* comment */ + 'baz' --> `foo${bar /* comment */ }${baz}` - return getTemplateLiteral(currentNode.left, textBeforeNode, textBeforePlus + textAfterPlus).slice(0, -1) + - getTemplateLiteral(currentNode.right, null, textAfterNode).slice(1); - } - if (rightStartsWithCurly) { - - // Otherwise, if the right side of the expression starts with a template curly, add the text there. - // 'foo' /* comment */ + `${bar}baz` --> `foo${ /* comment */ bar}baz` - return getTemplateLiteral(currentNode.left, textBeforeNode, null).slice(0, -1) + - getTemplateLiteral(currentNode.right, textBeforePlus + textAfterPlus, textAfterNode).slice(1); - } - - /* - * Otherwise, these nodes should not be combined into a template curly, since there is nowhere to put - * the text between them. - */ - return `${getTemplateLiteral(currentNode.left, textBeforeNode, null)}${textBeforePlus}+${textAfterPlus}${getTemplateLiteral(currentNode.right, textAfterNode, null)}`; - } - - return `\`\${${textBeforeNode || ""}${sourceCode.getText(currentNode)}${textAfterNode || ""}}\``; - } - - /** - * Returns a fixer object that converts a non-string binary expression to a template literal - * @param {SourceCodeFixer} fixer The fixer object - * @param {ASTNode} node A node that should be converted to a template literal - * @returns {Object} A fix for this binary expression - */ - function fixNonStringBinaryExpression(fixer, node) { - const topBinaryExpr = getTopConcatBinaryExpression(node.parent); - - if (hasOctalOrNonOctalDecimalEscapeSequence(topBinaryExpr)) { - return null; - } - - return fixer.replaceText(topBinaryExpr, getTemplateLiteral(topBinaryExpr, null, null)); - } - - /** - * Reports if a given node is string concatenation with non string literals. - * @param {ASTNode} node A node to check. - * @returns {void} - */ - function checkForStringConcat(node) { - if (!astUtils.isStringLiteral(node) || !isConcatenation(node.parent)) { - return; - } - - const topBinaryExpr = getTopConcatBinaryExpression(node.parent); - - // Checks whether or not this node had been checked already. - if (done[topBinaryExpr.range[0]]) { - return; - } - done[topBinaryExpr.range[0]] = true; - - if (hasNonStringLiteral(topBinaryExpr)) { - context.report({ - node: topBinaryExpr, - messageId: "unexpectedStringConcatenation", - fix: fixer => fixNonStringBinaryExpression(fixer, node) - }); - } - } - - return { - Program() { - done = Object.create(null); - }, - - Literal: checkForStringConcat, - TemplateLiteral: checkForStringConcat - }; - } -}; - -/** - * @fileoverview Rule to flag non-quoted property names in object literals. - * @author Mathias Bynens - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var quoteProps = { - meta: { - type: "suggestion", - - docs: { - description: "require quotes around object literal property names", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/quote-props" - }, - - schema: { - anyOf: [ - { - type: "array", - items: [ - { - enum: ["always", "as-needed", "consistent", "consistent-as-needed"] - } - ], - minItems: 0, - maxItems: 1 - }, - { - type: "array", - items: [ - { - enum: ["always", "as-needed", "consistent", "consistent-as-needed"] - }, - { - type: "object", - properties: { - keywords: { - type: "boolean" - }, - unnecessary: { - type: "boolean" - }, - numbers: { - type: "boolean" - } - }, - additionalProperties: false - } - ], - minItems: 0, - maxItems: 2 - } - ] - }, - - fixable: "code", - messages: { - requireQuotesDueToReservedWord: "Properties should be quoted as '{{property}}' is a reserved word.", - inconsistentlyQuotedProperty: "Inconsistently quoted property '{{key}}' found.", - unnecessarilyQuotedProperty: "Unnecessarily quoted property '{{property}}' found.", - unquotedReservedProperty: "Unquoted reserved word '{{property}}' used as key.", - unquotedNumericProperty: "Unquoted number literal '{{property}}' used as key.", - unquotedPropertyFound: "Unquoted property '{{property}}' found.", - redundantQuoting: "Properties shouldn't be quoted as all quotes are redundant." - } - }, - - create(context) { - - const MODE = context.options[0], - KEYWORDS = context.options[1] && context.options[1].keywords, - CHECK_UNNECESSARY = !context.options[1] || context.options[1].unnecessary !== false, - NUMBERS = context.options[1] && context.options[1].numbers, - - sourceCode = context.getSourceCode(); - - - /** - * Checks whether a certain string constitutes an ES3 token - * @param {string} tokenStr The string to be checked. - * @returns {boolean} `true` if it is an ES3 token. - */ - function isKeyword(tokenStr) { - return keywords.indexOf(tokenStr) >= 0; - } - - /** - * Checks if an espree-tokenized key has redundant quotes (i.e. whether quotes are unnecessary) - * @param {string} rawKey The raw key value from the source - * @param {espreeTokens} tokens The espree-tokenized node key - * @param {boolean} [skipNumberLiterals=false] Indicates whether number literals should be checked - * @returns {boolean} Whether or not a key has redundant quotes. - * @private - */ - function areQuotesRedundant(rawKey, tokens, skipNumberLiterals) { - return tokens.length === 1 && tokens[0].start === 0 && tokens[0].end === rawKey.length && - (["Identifier", "Keyword", "Null", "Boolean"].indexOf(tokens[0].type) >= 0 || - (tokens[0].type === "Numeric" && !skipNumberLiterals && String(+tokens[0].value) === tokens[0].value)); - } - - /** - * Returns a string representation of a property node with quotes removed - * @param {ASTNode} key Key AST Node, which may or may not be quoted - * @returns {string} A replacement string for this property - */ - function getUnquotedKey(key) { - return key.type === "Identifier" ? key.name : key.value; - } - - /** - * Returns a string representation of a property node with quotes added - * @param {ASTNode} key Key AST Node, which may or may not be quoted - * @returns {string} A replacement string for this property - */ - function getQuotedKey(key) { - if (key.type === "Literal" && typeof key.value === "string") { - - // If the key is already a string literal, don't replace the quotes with double quotes. - return sourceCode.getText(key); - } - - // Otherwise, the key is either an identifier or a number literal. - return `"${key.type === "Identifier" ? key.name : key.value}"`; - } - - /** - * Ensures that a property's key is quoted only when necessary - * @param {ASTNode} node Property AST node - * @returns {void} - */ - function checkUnnecessaryQuotes(node) { - const key = node.key; - - if (node.method || node.computed || node.shorthand) { - return; - } - - if (key.type === "Literal" && typeof key.value === "string") { - let tokens; - - try { - tokens = espree__default['default'].tokenize(key.value); - } catch { - return; - } - - if (tokens.length !== 1) { - return; - } - - const isKeywordToken = isKeyword(tokens[0].value); - - if (isKeywordToken && KEYWORDS) { - return; - } - - if (CHECK_UNNECESSARY && areQuotesRedundant(key.value, tokens, NUMBERS)) { - context.report({ - node, - messageId: "unnecessarilyQuotedProperty", - data: { property: key.value }, - fix: fixer => fixer.replaceText(key, getUnquotedKey(key)) - }); - } - } else if (KEYWORDS && key.type === "Identifier" && isKeyword(key.name)) { - context.report({ - node, - messageId: "unquotedReservedProperty", - data: { property: key.name }, - fix: fixer => fixer.replaceText(key, getQuotedKey(key)) - }); - } else if (NUMBERS && key.type === "Literal" && astUtils.isNumericLiteral(key)) { - context.report({ - node, - messageId: "unquotedNumericProperty", - data: { property: key.value }, - fix: fixer => fixer.replaceText(key, getQuotedKey(key)) - }); - } - } - - /** - * Ensures that a property's key is quoted - * @param {ASTNode} node Property AST node - * @returns {void} - */ - function checkOmittedQuotes(node) { - const key = node.key; - - if (!node.method && !node.computed && !node.shorthand && !(key.type === "Literal" && typeof key.value === "string")) { - context.report({ - node, - messageId: "unquotedPropertyFound", - data: { property: key.name || key.value }, - fix: fixer => fixer.replaceText(key, getQuotedKey(key)) - }); - } - } - - /** - * Ensures that an object's keys are consistently quoted, optionally checks for redundancy of quotes - * @param {ASTNode} node Property AST node - * @param {boolean} checkQuotesRedundancy Whether to check quotes' redundancy - * @returns {void} - */ - function checkConsistency(node, checkQuotesRedundancy) { - const quotedProps = [], - unquotedProps = []; - let keywordKeyName = null, - necessaryQuotes = false; - - node.properties.forEach(property => { - const key = property.key; - - if (!key || property.method || property.computed || property.shorthand) { - return; - } - - if (key.type === "Literal" && typeof key.value === "string") { - - quotedProps.push(property); - - if (checkQuotesRedundancy) { - let tokens; - - try { - tokens = espree__default['default'].tokenize(key.value); - } catch { - necessaryQuotes = true; - return; - } - - necessaryQuotes = necessaryQuotes || !areQuotesRedundant(key.value, tokens) || KEYWORDS && isKeyword(tokens[0].value); - } - } else if (KEYWORDS && checkQuotesRedundancy && key.type === "Identifier" && isKeyword(key.name)) { - unquotedProps.push(property); - necessaryQuotes = true; - keywordKeyName = key.name; - } else { - unquotedProps.push(property); - } - }); - - if (checkQuotesRedundancy && quotedProps.length && !necessaryQuotes) { - quotedProps.forEach(property => { - context.report({ - node: property, - messageId: "redundantQuoting", - fix: fixer => fixer.replaceText(property.key, getUnquotedKey(property.key)) - }); - }); - } else if (unquotedProps.length && keywordKeyName) { - unquotedProps.forEach(property => { - context.report({ - node: property, - messageId: "requireQuotesDueToReservedWord", - data: { property: keywordKeyName }, - fix: fixer => fixer.replaceText(property.key, getQuotedKey(property.key)) - }); - }); - } else if (quotedProps.length && unquotedProps.length) { - unquotedProps.forEach(property => { - context.report({ - node: property, - messageId: "inconsistentlyQuotedProperty", - data: { key: property.key.name || property.key.value }, - fix: fixer => fixer.replaceText(property.key, getQuotedKey(property.key)) - }); - }); - } - } - - return { - Property(node) { - if (MODE === "always" || !MODE) { - checkOmittedQuotes(node); - } - if (MODE === "as-needed") { - checkUnnecessaryQuotes(node); - } - }, - ObjectExpression(node) { - if (MODE === "consistent") { - checkConsistency(node, false); - } - if (MODE === "consistent-as-needed") { - checkConsistency(node, true); - } - } - }; - - } -}; - -/** - * @fileoverview A rule to choose between single and double quote marks - * @author Matt DuVall , Brandon Payton - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Constants -//------------------------------------------------------------------------------ - -const QUOTE_SETTINGS = { - double: { - quote: "\"", - alternateQuote: "'", - description: "doublequote" - }, - single: { - quote: "'", - alternateQuote: "\"", - description: "singlequote" - }, - backtick: { - quote: "`", - alternateQuote: "\"", - description: "backtick" - } -}; - -// An unescaped newline is a newline preceded by an even number of backslashes. -const UNESCAPED_LINEBREAK_PATTERN = new RegExp(String.raw`(^|[^\\])(\\\\)*[${Array.from(astUtils.LINEBREAKS).join("")}]`, "u"); - -/** - * Switches quoting of javascript string between ' " and ` - * escaping and unescaping as necessary. - * Only escaping of the minimal set of characters is changed. - * Note: escaping of newlines when switching from backtick to other quotes is not handled. - * @param {string} str A string to convert. - * @returns {string} The string with changed quotes. - * @private - */ -QUOTE_SETTINGS.double.convert = -QUOTE_SETTINGS.single.convert = -QUOTE_SETTINGS.backtick.convert = function(str) { - const newQuote = this.quote; - const oldQuote = str[0]; - - if (newQuote === oldQuote) { - return str; - } - return newQuote + str.slice(1, -1).replace(/\\(\$\{|\r\n?|\n|.)|["'`]|\$\{|(\r\n?|\n)/gu, (match, escaped, newline) => { - if (escaped === oldQuote || oldQuote === "`" && escaped === "${") { - return escaped; // unescape - } - if (match === newQuote || newQuote === "`" && match === "${") { - return `\\${match}`; // escape - } - if (newline && oldQuote === "`") { - return "\\n"; // escape newlines - } - return match; - }) + newQuote; -}; - -const AVOID_ESCAPE = "avoid-escape"; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var quotes = { - meta: { - type: "layout", - - docs: { - description: "enforce the consistent use of either backticks, double, or single quotes", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/quotes" - }, - - fixable: "code", - - schema: [ - { - enum: ["single", "double", "backtick"] - }, - { - anyOf: [ - { - enum: ["avoid-escape"] - }, - { - type: "object", - properties: { - avoidEscape: { - type: "boolean" - }, - allowTemplateLiterals: { - type: "boolean" - } - }, - additionalProperties: false - } - ] - } - ], - - messages: { - wrongQuotes: "Strings must use {{description}}." - } - }, - - create(context) { - - const quoteOption = context.options[0], - settings = QUOTE_SETTINGS[quoteOption || "double"], - options = context.options[1], - allowTemplateLiterals = options && options.allowTemplateLiterals === true, - sourceCode = context.getSourceCode(); - let avoidEscape = options && options.avoidEscape === true; - - // deprecated - if (options === AVOID_ESCAPE) { - avoidEscape = true; - } - - /** - * Determines if a given node is part of JSX syntax. - * - * This function returns `true` in the following cases: - * - * - `
` ... If the literal is an attribute value, the parent of the literal is `JSXAttribute`. - * - `
foo
` ... If the literal is a text content, the parent of the literal is `JSXElement`. - * - `<>foo` ... If the literal is a text content, the parent of the literal is `JSXFragment`. - * - * In particular, this function returns `false` in the following cases: - * - * - `
` - * - `
{"foo"}
` - * - * In both cases, inside of the braces is handled as normal JavaScript. - * The braces are `JSXExpressionContainer` nodes. - * @param {ASTNode} node The Literal node to check. - * @returns {boolean} True if the node is a part of JSX, false if not. - * @private - */ - function isJSXLiteral(node) { - return node.parent.type === "JSXAttribute" || node.parent.type === "JSXElement" || node.parent.type === "JSXFragment"; - } - - /** - * Checks whether or not a given node is a directive. - * The directive is a `ExpressionStatement` which has only a string literal. - * @param {ASTNode} node A node to check. - * @returns {boolean} Whether or not the node is a directive. - * @private - */ - function isDirective(node) { - return ( - node.type === "ExpressionStatement" && - node.expression.type === "Literal" && - typeof node.expression.value === "string" - ); - } - - /** - * Checks whether or not a given node is a part of directive prologues. - * See also: http://www.ecma-international.org/ecma-262/6.0/#sec-directive-prologues-and-the-use-strict-directive - * @param {ASTNode} node A node to check. - * @returns {boolean} Whether or not the node is a part of directive prologues. - * @private - */ - function isPartOfDirectivePrologue(node) { - const block = node.parent.parent; - - if (block.type !== "Program" && (block.type !== "BlockStatement" || !astUtils.isFunction(block.parent))) { - return false; - } - - // Check the node is at a prologue. - for (let i = 0; i < block.body.length; ++i) { - const statement = block.body[i]; - - if (statement === node.parent) { - return true; - } - if (!isDirective(statement)) { - break; - } - } - - return false; - } - - /** - * Checks whether or not a given node is allowed as non backtick. - * @param {ASTNode} node A node to check. - * @returns {boolean} Whether or not the node is allowed as non backtick. - * @private - */ - function isAllowedAsNonBacktick(node) { - const parent = node.parent; - - switch (parent.type) { - - // Directive Prologues. - case "ExpressionStatement": - return isPartOfDirectivePrologue(node); - - // LiteralPropertyName. - case "Property": - case "MethodDefinition": - return parent.key === node && !parent.computed; - - // ModuleSpecifier. - case "ImportDeclaration": - case "ExportNamedDeclaration": - case "ExportAllDeclaration": - return parent.source === node; - - // Others don't allow. - default: - return false; - } - } - - /** - * Checks whether or not a given TemplateLiteral node is actually using any of the special features provided by template literal strings. - * @param {ASTNode} node A TemplateLiteral node to check. - * @returns {boolean} Whether or not the TemplateLiteral node is using any of the special features provided by template literal strings. - * @private - */ - function isUsingFeatureOfTemplateLiteral(node) { - const hasTag = node.parent.type === "TaggedTemplateExpression" && node === node.parent.quasi; - - if (hasTag) { - return true; - } - - const hasStringInterpolation = node.expressions.length > 0; - - if (hasStringInterpolation) { - return true; - } - - const isMultilineString = node.quasis.length >= 1 && UNESCAPED_LINEBREAK_PATTERN.test(node.quasis[0].value.raw); - - if (isMultilineString) { - return true; - } - - return false; - } - - return { - - Literal(node) { - const val = node.value, - rawVal = node.raw; - - if (settings && typeof val === "string") { - let isValid = (quoteOption === "backtick" && isAllowedAsNonBacktick(node)) || - isJSXLiteral(node) || - astUtils.isSurroundedBy(rawVal, settings.quote); - - if (!isValid && avoidEscape) { - isValid = astUtils.isSurroundedBy(rawVal, settings.alternateQuote) && rawVal.indexOf(settings.quote) >= 0; - } - - if (!isValid) { - context.report({ - node, - messageId: "wrongQuotes", - data: { - description: settings.description - }, - fix(fixer) { - if (quoteOption === "backtick" && astUtils.hasOctalOrNonOctalDecimalEscapeSequence(rawVal)) { - - /* - * An octal or non-octal decimal escape sequence in a template literal would - * produce syntax error, even in non-strict mode. - */ - return null; - } - - return fixer.replaceText(node, settings.convert(node.raw)); - } - }); - } - } - }, - - TemplateLiteral(node) { - - // Don't throw an error if backticks are expected or a template literal feature is in use. - if ( - allowTemplateLiterals || - quoteOption === "backtick" || - isUsingFeatureOfTemplateLiteral(node) - ) { - return; - } - - context.report({ - node, - messageId: "wrongQuotes", - data: { - description: settings.description - }, - fix(fixer) { - if (isPartOfDirectivePrologue(node)) { - - /* - * TemplateLiterals in a directive prologue aren't actually directives, but if they're - * in the directive prologue, then fixing them might turn them into directives and change - * the behavior of the code. - */ - return null; - } - return fixer.replaceText(node, settings.convert(sourceCode.getText(node))); - } - }); - } - }; - - } -}; - -/** - * @fileoverview Rule to flag use of parseInt without a radix argument - * @author James Allardice - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const MODE_ALWAYS = "always", - MODE_AS_NEEDED = "as-needed"; - -const validRadixValues = new Set(Array.from({ length: 37 - 2 }, (_, index) => index + 2)); - -/** - * Checks whether a given variable is shadowed or not. - * @param {eslint-scope.Variable} variable A variable to check. - * @returns {boolean} `true` if the variable is shadowed. - */ -function isShadowed(variable) { - return variable.defs.length >= 1; -} - -/** - * Checks whether a given node is a MemberExpression of `parseInt` method or not. - * @param {ASTNode} node A node to check. - * @returns {boolean} `true` if the node is a MemberExpression of `parseInt` - * method. - */ -function isParseIntMethod(node) { - return ( - node.type === "MemberExpression" && - !node.computed && - node.property.type === "Identifier" && - node.property.name === "parseInt" - ); -} - -/** - * Checks whether a given node is a valid value of radix or not. - * - * The following values are invalid. - * - * - A literal except integers between 2 and 36. - * - undefined. - * @param {ASTNode} radix A node of radix to check. - * @returns {boolean} `true` if the node is valid. - */ -function isValidRadix(radix) { - return !( - (radix.type === "Literal" && !validRadixValues.has(radix.value)) || - (radix.type === "Identifier" && radix.name === "undefined") - ); -} - -/** - * Checks whether a given node is a default value of radix or not. - * @param {ASTNode} radix A node of radix to check. - * @returns {boolean} `true` if the node is the literal node of `10`. - */ -function isDefaultRadix(radix) { - return radix.type === "Literal" && radix.value === 10; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var radix = { - meta: { - type: "suggestion", - - docs: { - description: "enforce the consistent use of the radix argument when using `parseInt()`", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/radix" - }, - - schema: [ - { - enum: ["always", "as-needed"] - } - ], - - messages: { - missingParameters: "Missing parameters.", - redundantRadix: "Redundant radix parameter.", - missingRadix: "Missing radix parameter.", - invalidRadix: "Invalid radix parameter, must be an integer between 2 and 36." - } - }, - - create(context) { - const mode = context.options[0] || MODE_ALWAYS; - - /** - * Checks the arguments of a given CallExpression node and reports it if it - * offends this rule. - * @param {ASTNode} node A CallExpression node to check. - * @returns {void} - */ - function checkArguments(node) { - const args = node.arguments; - - switch (args.length) { - case 0: - context.report({ - node, - messageId: "missingParameters" - }); - break; - - case 1: - if (mode === MODE_ALWAYS) { - context.report({ - node, - messageId: "missingRadix" - }); - } - break; - - default: - if (mode === MODE_AS_NEEDED && isDefaultRadix(args[1])) { - context.report({ - node, - messageId: "redundantRadix" - }); - } else if (!isValidRadix(args[1])) { - context.report({ - node, - messageId: "invalidRadix" - }); - } - break; - } - } - - return { - "Program:exit"() { - const scope = context.getScope(); - let variable; - - // Check `parseInt()` - variable = astUtils.getVariableByName(scope, "parseInt"); - if (variable && !isShadowed(variable)) { - variable.references.forEach(reference => { - const node = reference.identifier; - - if (astUtils.isCallee(node)) { - checkArguments(node.parent); - } - }); - } - - // Check `Number.parseInt()` - variable = astUtils.getVariableByName(scope, "Number"); - if (variable && !isShadowed(variable)) { - variable.references.forEach(reference => { - const node = reference.identifier.parent; - const maybeCallee = node.parent.type === "ChainExpression" - ? node.parent - : node; - - if (isParseIntMethod(node) && astUtils.isCallee(maybeCallee)) { - checkArguments(maybeCallee.parent); - } - }); - } - } - }; - } -}; - -/** - * @fileoverview disallow assignments that can lead to race conditions due to usage of `await` or `yield` - * @author Teddy Katz - * @author Toru Nagashima - */ - -/** - * Make the map from identifiers to each reference. - * @param {escope.Scope} scope The scope to get references. - * @param {Map} [outReferenceMap] The map from identifier nodes to each reference object. - * @returns {Map} `referenceMap`. - */ -function createReferenceMap(scope, outReferenceMap = new Map()) { - for (const reference of scope.references) { - outReferenceMap.set(reference.identifier, reference); - } - for (const childScope of scope.childScopes) { - if (childScope.type !== "function") { - createReferenceMap(childScope, outReferenceMap); - } - } - - return outReferenceMap; -} - -/** - * Get `reference.writeExpr` of a given reference. - * If it's the read reference of MemberExpression in LHS, returns RHS in order to address `a.b = await a` - * @param {escope.Reference} reference The reference to get. - * @returns {Expression|null} The `reference.writeExpr`. - */ -function getWriteExpr(reference) { - if (reference.writeExpr) { - return reference.writeExpr; - } - let node = reference.identifier; - - while (node) { - const t = node.parent.type; - - if (t === "AssignmentExpression" && node.parent.left === node) { - return node.parent.right; - } - if (t === "MemberExpression" && node.parent.object === node) { - node = node.parent; - continue; - } - - break; - } - - return null; -} - -/** - * Checks if an expression is a variable that can only be observed within the given function. - * @param {Variable|null} variable The variable to check - * @param {boolean} isMemberAccess If `true` then this is a member access. - * @returns {boolean} `true` if the variable is local to the given function, and is never referenced in a closure. - */ -function isLocalVariableWithoutEscape(variable, isMemberAccess) { - if (!variable) { - return false; // A global variable which was not defined. - } - - // If the reference is a property access and the variable is a parameter, it handles the variable is not local. - if (isMemberAccess && variable.defs.some(d => d.type === "Parameter")) { - return false; - } - - const functionScope = variable.scope.variableScope; - - return variable.references.every(reference => - reference.from.variableScope === functionScope); -} - -class SegmentInfo { - constructor() { - this.info = new WeakMap(); - } - - /** - * Initialize the segment information. - * @param {PathSegment} segment The segment to initialize. - * @returns {void} - */ - initialize(segment) { - const outdatedReadVariableNames = new Set(); - const freshReadVariableNames = new Set(); - - for (const prevSegment of segment.prevSegments) { - const info = this.info.get(prevSegment); - - if (info) { - info.outdatedReadVariableNames.forEach(Set.prototype.add, outdatedReadVariableNames); - info.freshReadVariableNames.forEach(Set.prototype.add, freshReadVariableNames); - } - } - - this.info.set(segment, { outdatedReadVariableNames, freshReadVariableNames }); - } - - /** - * Mark a given variable as read on given segments. - * @param {PathSegment[]} segments The segments that it read the variable on. - * @param {string} variableName The variable name to be read. - * @returns {void} - */ - markAsRead(segments, variableName) { - for (const segment of segments) { - const info = this.info.get(segment); - - if (info) { - info.freshReadVariableNames.add(variableName); - - // If a variable is freshly read again, then it's no more out-dated. - info.outdatedReadVariableNames.delete(variableName); - } - } - } - - /** - * Move `freshReadVariableNames` to `outdatedReadVariableNames`. - * @param {PathSegment[]} segments The segments to process. - * @returns {void} - */ - makeOutdated(segments) { - for (const segment of segments) { - const info = this.info.get(segment); - - if (info) { - info.freshReadVariableNames.forEach(Set.prototype.add, info.outdatedReadVariableNames); - info.freshReadVariableNames.clear(); - } - } - } - - /** - * Check if a given variable is outdated on the current segments. - * @param {PathSegment[]} segments The current segments. - * @param {string} variableName The variable name to check. - * @returns {boolean} `true` if the variable is outdated on the segments. - */ - isOutdated(segments, variableName) { - for (const segment of segments) { - const info = this.info.get(segment); - - if (info && info.outdatedReadVariableNames.has(variableName)) { - return true; - } - } - return false; - } -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var requireAtomicUpdates = { - meta: { - type: "problem", - - docs: { - description: "disallow assignments that can lead to race conditions due to usage of `await` or `yield`", - category: "Possible Errors", - recommended: false, - url: "https://eslint.org/docs/rules/require-atomic-updates" - }, - - fixable: null, - schema: [], - - messages: { - nonAtomicUpdate: "Possible race condition: `{{value}}` might be reassigned based on an outdated value of `{{value}}`." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const assignmentReferences = new Map(); - const segmentInfo = new SegmentInfo(); - let stack = null; - - return { - onCodePathStart(codePath) { - const scope = context.getScope(); - const shouldVerify = - scope.type === "function" && - (scope.block.async || scope.block.generator); - - stack = { - upper: stack, - codePath, - referenceMap: shouldVerify ? createReferenceMap(scope) : null - }; - }, - onCodePathEnd() { - stack = stack.upper; - }, - - // Initialize the segment information. - onCodePathSegmentStart(segment) { - segmentInfo.initialize(segment); - }, - - // Handle references to prepare verification. - Identifier(node) { - const { codePath, referenceMap } = stack; - const reference = referenceMap && referenceMap.get(node); - - // Ignore if this is not a valid variable reference. - if (!reference) { - return; - } - const name = reference.identifier.name; - const variable = reference.resolved; - const writeExpr = getWriteExpr(reference); - const isMemberAccess = reference.identifier.parent.type === "MemberExpression"; - - // Add a fresh read variable. - if (reference.isRead() && !(writeExpr && writeExpr.parent.operator === "=")) { - segmentInfo.markAsRead(codePath.currentSegments, name); - } - - /* - * Register the variable to verify after ESLint traversed the `writeExpr` node - * if this reference is an assignment to a variable which is referred from other closure. - */ - if (writeExpr && - writeExpr.parent.right === writeExpr && // ← exclude variable declarations. - !isLocalVariableWithoutEscape(variable, isMemberAccess) - ) { - let refs = assignmentReferences.get(writeExpr); - - if (!refs) { - refs = []; - assignmentReferences.set(writeExpr, refs); - } - - refs.push(reference); - } - }, - - /* - * Verify assignments. - * If the reference exists in `outdatedReadVariableNames` list, report it. - */ - ":expression:exit"(node) { - const { codePath, referenceMap } = stack; - - // referenceMap exists if this is in a resumable function scope. - if (!referenceMap) { - return; - } - - // Mark the read variables on this code path as outdated. - if (node.type === "AwaitExpression" || node.type === "YieldExpression") { - segmentInfo.makeOutdated(codePath.currentSegments); - } - - // Verify. - const references = assignmentReferences.get(node); - - if (references) { - assignmentReferences.delete(node); - - for (const reference of references) { - const name = reference.identifier.name; - - if (segmentInfo.isOutdated(codePath.currentSegments, name)) { - context.report({ - node: node.parent, - messageId: "nonAtomicUpdate", - data: { - value: sourceCode.getText(node.parent.left) - } - }); - } - } - } - } - }; - } -}; - -/** - * @fileoverview Rule to disallow async functions which have no `await` expression. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Capitalize the 1st letter of the given text. - * @param {string} text The text to capitalize. - * @returns {string} The text that the 1st letter was capitalized. - */ -function capitalizeFirstLetter(text) { - return text[0].toUpperCase() + text.slice(1); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var requireAwait = { - meta: { - type: "suggestion", - - docs: { - description: "disallow async functions which have no `await` expression", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/require-await" - }, - - schema: [], - - messages: { - missingAwait: "{{name}} has no 'await' expression." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - let scopeInfo = null; - - /** - * Push the scope info object to the stack. - * @returns {void} - */ - function enterFunction() { - scopeInfo = { - upper: scopeInfo, - hasAwait: false - }; - } - - /** - * Pop the top scope info object from the stack. - * Also, it reports the function if needed. - * @param {ASTNode} node The node to report. - * @returns {void} - */ - function exitFunction(node) { - if (!node.generator && node.async && !scopeInfo.hasAwait && !astUtils.isEmptyFunction(node)) { - context.report({ - node, - loc: astUtils.getFunctionHeadLoc(node, sourceCode), - messageId: "missingAwait", - data: { - name: capitalizeFirstLetter( - astUtils.getFunctionNameWithKind(node) - ) - } - }); - } - - scopeInfo = scopeInfo.upper; - } - - return { - FunctionDeclaration: enterFunction, - FunctionExpression: enterFunction, - ArrowFunctionExpression: enterFunction, - "FunctionDeclaration:exit": exitFunction, - "FunctionExpression:exit": exitFunction, - "ArrowFunctionExpression:exit": exitFunction, - - AwaitExpression() { - if (!scopeInfo) { - return; - } - - scopeInfo.hasAwait = true; - }, - ForOfStatement(node) { - if (!scopeInfo) { - return; - } - - if (node.await) { - scopeInfo.hasAwait = true; - } - } - }; - } -}; - -/** - * @fileoverview Rule to check for jsdoc presence. - * @author Gyandeep Singh - */ - -var requireJsdoc$1 = { - meta: { - type: "suggestion", - - docs: { - description: "require JSDoc comments", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/require-jsdoc" - }, - - schema: [ - { - type: "object", - properties: { - require: { - type: "object", - properties: { - ClassDeclaration: { - type: "boolean", - default: false - }, - MethodDefinition: { - type: "boolean", - default: false - }, - FunctionDeclaration: { - type: "boolean", - default: true - }, - ArrowFunctionExpression: { - type: "boolean", - default: false - }, - FunctionExpression: { - type: "boolean", - default: false - } - }, - additionalProperties: false, - default: {} - } - }, - additionalProperties: false - } - ], - - deprecated: true, - replacedBy: [], - - messages: { - missingJSDocComment: "Missing JSDoc comment." - } - }, - - create(context) { - const source = context.getSourceCode(); - const DEFAULT_OPTIONS = { - FunctionDeclaration: true, - MethodDefinition: false, - ClassDeclaration: false, - ArrowFunctionExpression: false, - FunctionExpression: false - }; - const options = Object.assign(DEFAULT_OPTIONS, context.options[0] && context.options[0].require); - - /** - * Report the error message - * @param {ASTNode} node node to report - * @returns {void} - */ - function report(node) { - context.report({ node, messageId: "missingJSDocComment" }); - } - - /** - * Check if the jsdoc comment is present or not. - * @param {ASTNode} node node to examine - * @returns {void} - */ - function checkJsDoc(node) { - const jsdocComment = source.getJSDocComment(node); - - if (!jsdocComment) { - report(node); - } - } - - return { - FunctionDeclaration(node) { - if (options.FunctionDeclaration) { - checkJsDoc(node); - } - }, - FunctionExpression(node) { - if ( - (options.MethodDefinition && node.parent.type === "MethodDefinition") || - (options.FunctionExpression && (node.parent.type === "VariableDeclarator" || (node.parent.type === "Property" && node === node.parent.value))) - ) { - checkJsDoc(node); - } - }, - ClassDeclaration(node) { - if (options.ClassDeclaration) { - checkJsDoc(node); - } - }, - ArrowFunctionExpression(node) { - if (options.ArrowFunctionExpression && node.parent.type === "VariableDeclarator") { - checkJsDoc(node); - } - } - }; - } -}; - -/** - * @fileoverview Rule to enforce the use of `u` flag on RegExp. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -const { - CALL, - CONSTRUCT, - ReferenceTracker, - getStringIfConstant -} = require$$0__default$1['default']; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var requireUnicodeRegexp = { - meta: { - type: "suggestion", - - docs: { - description: "enforce the use of `u` flag on RegExp", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/require-unicode-regexp" - }, - - messages: { - requireUFlag: "Use the 'u' flag." - }, - - schema: [] - }, - - create(context) { - return { - "Literal[regex]"(node) { - const flags = node.regex.flags || ""; - - if (!flags.includes("u")) { - context.report({ node, messageId: "requireUFlag" }); - } - }, - - Program() { - const scope = context.getScope(); - const tracker = new ReferenceTracker(scope); - const trackMap = { - RegExp: { [CALL]: true, [CONSTRUCT]: true } - }; - - for (const { node } of tracker.iterateGlobalReferences(trackMap)) { - const flagsNode = node.arguments[1]; - const flags = getStringIfConstant(flagsNode, scope); - - if (!flagsNode || (typeof flags === "string" && !flags.includes("u"))) { - context.report({ node, messageId: "requireUFlag" }); - } - } - } - }; - } -}; - -/** - * @fileoverview Rule to flag the generator functions that does not have yield. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var requireYield = { - meta: { - type: "suggestion", - - docs: { - description: "require generator functions to contain `yield`", - category: "ECMAScript 6", - recommended: true, - url: "https://eslint.org/docs/rules/require-yield" - }, - - schema: [], - - messages: { - missingYield: "This generator function does not have 'yield'." - } - }, - - create(context) { - const stack = []; - - /** - * If the node is a generator function, start counting `yield` keywords. - * @param {Node} node A function node to check. - * @returns {void} - */ - function beginChecking(node) { - if (node.generator) { - stack.push(0); - } - } - - /** - * If the node is a generator function, end counting `yield` keywords, then - * reports result. - * @param {Node} node A function node to check. - * @returns {void} - */ - function endChecking(node) { - if (!node.generator) { - return; - } - - const countYield = stack.pop(); - - if (countYield === 0 && node.body.body.length > 0) { - context.report({ node, messageId: "missingYield" }); - } - } - - return { - FunctionDeclaration: beginChecking, - "FunctionDeclaration:exit": endChecking, - FunctionExpression: beginChecking, - "FunctionExpression:exit": endChecking, - - // Increases the count of `yield` keyword. - YieldExpression() { - - /* istanbul ignore else */ - if (stack.length > 0) { - stack[stack.length - 1] += 1; - } - } - }; - } -}; - -/** - * @fileoverview Enforce spacing between rest and spread operators and their expressions. - * @author Kai Cataldo - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var restSpreadSpacing = { - meta: { - type: "layout", - - docs: { - description: "enforce spacing between rest and spread operators and their expressions", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/rest-spread-spacing" - }, - - fixable: "whitespace", - - schema: [ - { - enum: ["always", "never"] - } - ], - - messages: { - unexpectedWhitespace: "Unexpected whitespace after {{type}} operator.", - expectedWhitespace: "Expected whitespace after {{type}} operator." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(), - alwaysSpace = context.options[0] === "always"; - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Checks whitespace between rest/spread operators and their expressions - * @param {ASTNode} node The node to check - * @returns {void} - */ - function checkWhiteSpace(node) { - const operator = sourceCode.getFirstToken(node), - nextToken = sourceCode.getTokenAfter(operator), - hasWhitespace = sourceCode.isSpaceBetweenTokens(operator, nextToken); - let type; - - switch (node.type) { - case "SpreadElement": - type = "spread"; - if (node.parent.type === "ObjectExpression") { - type += " property"; - } - break; - case "RestElement": - type = "rest"; - if (node.parent.type === "ObjectPattern") { - type += " property"; - } - break; - case "ExperimentalSpreadProperty": - type = "spread property"; - break; - case "ExperimentalRestProperty": - type = "rest property"; - break; - default: - return; - } - - if (alwaysSpace && !hasWhitespace) { - context.report({ - node, - loc: operator.loc, - messageId: "expectedWhitespace", - data: { - type - }, - fix(fixer) { - return fixer.replaceTextRange([operator.range[1], nextToken.range[0]], " "); - } - }); - } else if (!alwaysSpace && hasWhitespace) { - context.report({ - node, - loc: { - start: operator.loc.end, - end: nextToken.loc.start - }, - messageId: "unexpectedWhitespace", - data: { - type - }, - fix(fixer) { - return fixer.removeRange([operator.range[1], nextToken.range[0]]); - } - }); - } - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - SpreadElement: checkWhiteSpace, - RestElement: checkWhiteSpace, - ExperimentalSpreadProperty: checkWhiteSpace, - ExperimentalRestProperty: checkWhiteSpace - }; - } -}; - -/** - * @fileoverview Rule to flag missing semicolons. - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var semi = { - meta: { - type: "layout", - - docs: { - description: "require or disallow semicolons instead of ASI", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/semi" - }, - - fixable: "code", - - schema: { - anyOf: [ - { - type: "array", - items: [ - { - enum: ["never"] - }, - { - type: "object", - properties: { - beforeStatementContinuationChars: { - enum: ["always", "any", "never"] - } - }, - additionalProperties: false - } - ], - minItems: 0, - maxItems: 2 - }, - { - type: "array", - items: [ - { - enum: ["always"] - }, - { - type: "object", - properties: { - omitLastInOneLineBlock: { type: "boolean" } - }, - additionalProperties: false - } - ], - minItems: 0, - maxItems: 2 - } - ] - }, - - messages: { - missingSemi: "Missing semicolon.", - extraSemi: "Extra semicolon." - } - }, - - create(context) { - - const OPT_OUT_PATTERN = /^[-[(/+`]/u; // One of [(/+-` - const options = context.options[1]; - const never = context.options[0] === "never"; - const exceptOneLine = Boolean(options && options.omitLastInOneLineBlock); - const beforeStatementContinuationChars = options && options.beforeStatementContinuationChars || "any"; - const sourceCode = context.getSourceCode(); - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Reports a semicolon error with appropriate location and message. - * @param {ASTNode} node The node with an extra or missing semicolon. - * @param {boolean} missing True if the semicolon is missing. - * @returns {void} - */ - function report(node, missing) { - const lastToken = sourceCode.getLastToken(node); - let messageId, - fix, - loc; - - if (!missing) { - messageId = "missingSemi"; - loc = { - start: lastToken.loc.end, - end: astUtils.getNextLocation(sourceCode, lastToken.loc.end) - }; - fix = function(fixer) { - return fixer.insertTextAfter(lastToken, ";"); - }; - } else { - messageId = "extraSemi"; - loc = lastToken.loc; - fix = function(fixer) { - - /* - * Expand the replacement range to include the surrounding - * tokens to avoid conflicting with no-extra-semi. - * https://github.com/eslint/eslint/issues/7928 - */ - return new fixTracker(fixer, sourceCode) - .retainSurroundingTokens(lastToken) - .remove(lastToken); - }; - } - - context.report({ - node, - loc, - messageId, - fix - }); - - } - - /** - * Check whether a given semicolon token is redundant. - * @param {Token} semiToken A semicolon token to check. - * @returns {boolean} `true` if the next token is `;` or `}`. - */ - function isRedundantSemi(semiToken) { - const nextToken = sourceCode.getTokenAfter(semiToken); - - return ( - !nextToken || - astUtils.isClosingBraceToken(nextToken) || - astUtils.isSemicolonToken(nextToken) - ); - } - - /** - * Check whether a given token is the closing brace of an arrow function. - * @param {Token} lastToken A token to check. - * @returns {boolean} `true` if the token is the closing brace of an arrow function. - */ - function isEndOfArrowBlock(lastToken) { - if (!astUtils.isClosingBraceToken(lastToken)) { - return false; - } - const node = sourceCode.getNodeByRangeIndex(lastToken.range[0]); - - return ( - node.type === "BlockStatement" && - node.parent.type === "ArrowFunctionExpression" - ); - } - - /** - * Check whether a given node is on the same line with the next token. - * @param {Node} node A statement node to check. - * @returns {boolean} `true` if the node is on the same line with the next token. - */ - function isOnSameLineWithNextToken(node) { - const prevToken = sourceCode.getLastToken(node, 1); - const nextToken = sourceCode.getTokenAfter(node); - - return !!nextToken && astUtils.isTokenOnSameLine(prevToken, nextToken); - } - - /** - * Check whether a given node can connect the next line if the next line is unreliable. - * @param {Node} node A statement node to check. - * @returns {boolean} `true` if the node can connect the next line. - */ - function maybeAsiHazardAfter(node) { - const t = node.type; - - if (t === "DoWhileStatement" || - t === "BreakStatement" || - t === "ContinueStatement" || - t === "DebuggerStatement" || - t === "ImportDeclaration" || - t === "ExportAllDeclaration" - ) { - return false; - } - if (t === "ReturnStatement") { - return Boolean(node.argument); - } - if (t === "ExportNamedDeclaration") { - return Boolean(node.declaration); - } - if (isEndOfArrowBlock(sourceCode.getLastToken(node, 1))) { - return false; - } - - return true; - } - - /** - * Check whether a given token can connect the previous statement. - * @param {Token} token A token to check. - * @returns {boolean} `true` if the token is one of `[`, `(`, `/`, `+`, `-`, ```, `++`, and `--`. - */ - function maybeAsiHazardBefore(token) { - return ( - Boolean(token) && - OPT_OUT_PATTERN.test(token.value) && - token.value !== "++" && - token.value !== "--" - ); - } - - /** - * Check if the semicolon of a given node is unnecessary, only true if: - * - next token is a valid statement divider (`;` or `}`). - * - next token is on a new line and the node is not connectable to the new line. - * @param {Node} node A statement node to check. - * @returns {boolean} whether the semicolon is unnecessary. - */ - function canRemoveSemicolon(node) { - if (isRedundantSemi(sourceCode.getLastToken(node))) { - return true; // `;;` or `;}` - } - if (isOnSameLineWithNextToken(node)) { - return false; // One liner. - } - if (beforeStatementContinuationChars === "never" && !maybeAsiHazardAfter(node)) { - return true; // ASI works. This statement doesn't connect to the next. - } - if (!maybeAsiHazardBefore(sourceCode.getTokenAfter(node))) { - return true; // ASI works. The next token doesn't connect to this statement. - } - - return false; - } - - /** - * Checks a node to see if it's in a one-liner block statement. - * @param {ASTNode} node The node to check. - * @returns {boolean} whether the node is in a one-liner block statement. - */ - function isOneLinerBlock(node) { - const parent = node.parent; - const nextToken = sourceCode.getTokenAfter(node); - - if (!nextToken || nextToken.value !== "}") { - return false; - } - return ( - !!parent && - parent.type === "BlockStatement" && - parent.loc.start.line === parent.loc.end.line - ); - } - - /** - * Checks a node to see if it's followed by a semicolon. - * @param {ASTNode} node The node to check. - * @returns {void} - */ - function checkForSemicolon(node) { - const isSemi = astUtils.isSemicolonToken(sourceCode.getLastToken(node)); - - if (never) { - if (isSemi && canRemoveSemicolon(node)) { - report(node, true); - } else if (!isSemi && beforeStatementContinuationChars === "always" && maybeAsiHazardBefore(sourceCode.getTokenAfter(node))) { - report(node); - } - } else { - const oneLinerBlock = (exceptOneLine && isOneLinerBlock(node)); - - if (isSemi && oneLinerBlock) { - report(node, true); - } else if (!isSemi && !oneLinerBlock) { - report(node); - } - } - } - - /** - * Checks to see if there's a semicolon after a variable declaration. - * @param {ASTNode} node The node to check. - * @returns {void} - */ - function checkForSemicolonForVariableDeclaration(node) { - const parent = node.parent; - - if ((parent.type !== "ForStatement" || parent.init !== node) && - (!/^For(?:In|Of)Statement/u.test(parent.type) || parent.left !== node) - ) { - checkForSemicolon(node); - } - } - - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- - - return { - VariableDeclaration: checkForSemicolonForVariableDeclaration, - ExpressionStatement: checkForSemicolon, - ReturnStatement: checkForSemicolon, - ThrowStatement: checkForSemicolon, - DoWhileStatement: checkForSemicolon, - DebuggerStatement: checkForSemicolon, - BreakStatement: checkForSemicolon, - ContinueStatement: checkForSemicolon, - ImportDeclaration: checkForSemicolon, - ExportAllDeclaration: checkForSemicolon, - ExportNamedDeclaration(node) { - if (!node.declaration) { - checkForSemicolon(node); - } - }, - ExportDefaultDeclaration(node) { - if (!/(?:Class|Function)Declaration/u.test(node.declaration.type)) { - checkForSemicolon(node); - } - } - }; - - } -}; - -/** - * @fileoverview Validates spacing before and after semicolon - * @author Mathias Schreck - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var semiSpacing = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent spacing before and after semicolons", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/semi-spacing" - }, - - fixable: "whitespace", - - schema: [ - { - type: "object", - properties: { - before: { - type: "boolean", - default: false - }, - after: { - type: "boolean", - default: true - } - }, - additionalProperties: false - } - ], - - messages: { - unexpectedWhitespaceBefore: "Unexpected whitespace before semicolon.", - unexpectedWhitespaceAfter: "Unexpected whitespace after semicolon.", - missingWhitespaceBefore: "Missing whitespace before semicolon.", - missingWhitespaceAfter: "Missing whitespace after semicolon." - } - }, - - create(context) { - - const config = context.options[0], - sourceCode = context.getSourceCode(); - let requireSpaceBefore = false, - requireSpaceAfter = true; - - if (typeof config === "object") { - requireSpaceBefore = config.before; - requireSpaceAfter = config.after; - } - - /** - * Checks if a given token has leading whitespace. - * @param {Object} token The token to check. - * @returns {boolean} True if the given token has leading space, false if not. - */ - function hasLeadingSpace(token) { - const tokenBefore = sourceCode.getTokenBefore(token); - - return tokenBefore && astUtils.isTokenOnSameLine(tokenBefore, token) && sourceCode.isSpaceBetweenTokens(tokenBefore, token); - } - - /** - * Checks if a given token has trailing whitespace. - * @param {Object} token The token to check. - * @returns {boolean} True if the given token has trailing space, false if not. - */ - function hasTrailingSpace(token) { - const tokenAfter = sourceCode.getTokenAfter(token); - - return tokenAfter && astUtils.isTokenOnSameLine(token, tokenAfter) && sourceCode.isSpaceBetweenTokens(token, tokenAfter); - } - - /** - * Checks if the given token is the last token in its line. - * @param {Token} token The token to check. - * @returns {boolean} Whether or not the token is the last in its line. - */ - function isLastTokenInCurrentLine(token) { - const tokenAfter = sourceCode.getTokenAfter(token); - - return !(tokenAfter && astUtils.isTokenOnSameLine(token, tokenAfter)); - } - - /** - * Checks if the given token is the first token in its line - * @param {Token} token The token to check. - * @returns {boolean} Whether or not the token is the first in its line. - */ - function isFirstTokenInCurrentLine(token) { - const tokenBefore = sourceCode.getTokenBefore(token); - - return !(tokenBefore && astUtils.isTokenOnSameLine(token, tokenBefore)); - } - - /** - * Checks if the next token of a given token is a closing parenthesis. - * @param {Token} token The token to check. - * @returns {boolean} Whether or not the next token of a given token is a closing parenthesis. - */ - function isBeforeClosingParen(token) { - const nextToken = sourceCode.getTokenAfter(token); - - return (nextToken && astUtils.isClosingBraceToken(nextToken) || astUtils.isClosingParenToken(nextToken)); - } - - /** - * Report location example : - * - * for unexpected space `before` - * - * var a = 'b' ; - * ^^^ - * - * for unexpected space `after` - * - * var a = 'b'; c = 10; - * ^^ - * - * Reports if the given token has invalid spacing. - * @param {Token} token The semicolon token to check. - * @param {ASTNode} node The corresponding node of the token. - * @returns {void} - */ - function checkSemicolonSpacing(token, node) { - if (astUtils.isSemicolonToken(token)) { - if (hasLeadingSpace(token)) { - if (!requireSpaceBefore) { - const tokenBefore = sourceCode.getTokenBefore(token); - const loc = { - start: tokenBefore.loc.end, - end: token.loc.start - }; - - context.report({ - node, - loc, - messageId: "unexpectedWhitespaceBefore", - fix(fixer) { - - return fixer.removeRange([tokenBefore.range[1], token.range[0]]); - } - }); - } - } else { - if (requireSpaceBefore) { - const loc = token.loc; - - context.report({ - node, - loc, - messageId: "missingWhitespaceBefore", - fix(fixer) { - return fixer.insertTextBefore(token, " "); - } - }); - } - } - - if (!isFirstTokenInCurrentLine(token) && !isLastTokenInCurrentLine(token) && !isBeforeClosingParen(token)) { - if (hasTrailingSpace(token)) { - if (!requireSpaceAfter) { - const tokenAfter = sourceCode.getTokenAfter(token); - const loc = { - start: token.loc.end, - end: tokenAfter.loc.start - }; - - context.report({ - node, - loc, - messageId: "unexpectedWhitespaceAfter", - fix(fixer) { - - return fixer.removeRange([token.range[1], tokenAfter.range[0]]); - } - }); - } - } else { - if (requireSpaceAfter) { - const loc = token.loc; - - context.report({ - node, - loc, - messageId: "missingWhitespaceAfter", - fix(fixer) { - return fixer.insertTextAfter(token, " "); - } - }); - } - } - } - } - } - - /** - * Checks the spacing of the semicolon with the assumption that the last token is the semicolon. - * @param {ASTNode} node The node to check. - * @returns {void} - */ - function checkNode(node) { - const token = sourceCode.getLastToken(node); - - checkSemicolonSpacing(token, node); - } - - return { - VariableDeclaration: checkNode, - ExpressionStatement: checkNode, - BreakStatement: checkNode, - ContinueStatement: checkNode, - DebuggerStatement: checkNode, - DoWhileStatement: checkNode, - ReturnStatement: checkNode, - ThrowStatement: checkNode, - ImportDeclaration: checkNode, - ExportNamedDeclaration: checkNode, - ExportAllDeclaration: checkNode, - ExportDefaultDeclaration: checkNode, - ForStatement(node) { - if (node.init) { - checkSemicolonSpacing(sourceCode.getTokenAfter(node.init), node); - } - - if (node.test) { - checkSemicolonSpacing(sourceCode.getTokenAfter(node.test), node); - } - } - }; - } -}; - -/** - * @fileoverview Rule to enforce location of semicolons. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -const SELECTOR = `:matches(${ - [ - "BreakStatement", "ContinueStatement", "DebuggerStatement", - "DoWhileStatement", "ExportAllDeclaration", - "ExportDefaultDeclaration", "ExportNamedDeclaration", - "ExpressionStatement", "ImportDeclaration", "ReturnStatement", - "ThrowStatement", "VariableDeclaration" - ].join(",") -})`; - -/** - * Get the child node list of a given node. - * This returns `Program#body`, `BlockStatement#body`, or `SwitchCase#consequent`. - * This is used to check whether a node is the first/last child. - * @param {Node} node A node to get child node list. - * @returns {Node[]|null} The child node list. - */ -function getChildren(node) { - const t = node.type; - - if (t === "BlockStatement" || t === "Program") { - return node.body; - } - if (t === "SwitchCase") { - return node.consequent; - } - return null; -} - -/** - * Check whether a given node is the last statement in the parent block. - * @param {Node} node A node to check. - * @returns {boolean} `true` if the node is the last statement in the parent block. - */ -function isLastChild(node) { - const t = node.parent.type; - - if (t === "IfStatement" && node.parent.consequent === node && node.parent.alternate) { // before `else` keyword. - return true; - } - if (t === "DoWhileStatement") { // before `while` keyword. - return true; - } - const nodeList = getChildren(node.parent); - - return nodeList !== null && nodeList[nodeList.length - 1] === node; // before `}` or etc. -} - -var semiStyle = { - meta: { - type: "layout", - - docs: { - description: "enforce location of semicolons", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/semi-style" - }, - - schema: [{ enum: ["last", "first"] }], - fixable: "whitespace", - - messages: { - expectedSemiColon: "Expected this semicolon to be at {{pos}}." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const option = context.options[0] || "last"; - - /** - * Check the given semicolon token. - * @param {Token} semiToken The semicolon token to check. - * @param {"first"|"last"} expected The expected location to check. - * @returns {void} - */ - function check(semiToken, expected) { - const prevToken = sourceCode.getTokenBefore(semiToken); - const nextToken = sourceCode.getTokenAfter(semiToken); - const prevIsSameLine = !prevToken || astUtils.isTokenOnSameLine(prevToken, semiToken); - const nextIsSameLine = !nextToken || astUtils.isTokenOnSameLine(semiToken, nextToken); - - if ((expected === "last" && !prevIsSameLine) || (expected === "first" && !nextIsSameLine)) { - context.report({ - loc: semiToken.loc, - messageId: "expectedSemiColon", - data: { - pos: (expected === "last") - ? "the end of the previous line" - : "the beginning of the next line" - }, - fix(fixer) { - if (prevToken && nextToken && sourceCode.commentsExistBetween(prevToken, nextToken)) { - return null; - } - - const start = prevToken ? prevToken.range[1] : semiToken.range[0]; - const end = nextToken ? nextToken.range[0] : semiToken.range[1]; - const text = (expected === "last") ? ";\n" : "\n;"; - - return fixer.replaceTextRange([start, end], text); - } - }); - } - } - - return { - [SELECTOR](node) { - if (option === "first" && isLastChild(node)) { - return; - } - - const lastToken = sourceCode.getLastToken(node); - - if (astUtils.isSemicolonToken(lastToken)) { - check(lastToken, option); - } - }, - - ForStatement(node) { - const firstSemi = node.init && sourceCode.getTokenAfter(node.init, astUtils.isSemicolonToken); - const secondSemi = node.test && sourceCode.getTokenAfter(node.test, astUtils.isSemicolonToken); - - if (firstSemi) { - check(firstSemi, "last"); - } - if (secondSemi) { - check(secondSemi, "last"); - } - } - }; - } -}; - -/** - * @fileoverview Rule to require sorting of import declarations - * @author Christian Schuller - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var sortImports = { - meta: { - type: "suggestion", - - docs: { - description: "enforce sorted import declarations within modules", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/sort-imports" - }, - - schema: [ - { - type: "object", - properties: { - ignoreCase: { - type: "boolean", - default: false - }, - memberSyntaxSortOrder: { - type: "array", - items: { - enum: ["none", "all", "multiple", "single"] - }, - uniqueItems: true, - minItems: 4, - maxItems: 4 - }, - ignoreDeclarationSort: { - type: "boolean", - default: false - }, - ignoreMemberSort: { - type: "boolean", - default: false - }, - allowSeparatedGroups: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - fixable: "code", - - messages: { - sortImportsAlphabetically: "Imports should be sorted alphabetically.", - sortMembersAlphabetically: "Member '{{memberName}}' of the import declaration should be sorted alphabetically.", - unexpectedSyntaxOrder: "Expected '{{syntaxA}}' syntax before '{{syntaxB}}' syntax." - } - }, - - create(context) { - - const configuration = context.options[0] || {}, - ignoreCase = configuration.ignoreCase || false, - ignoreDeclarationSort = configuration.ignoreDeclarationSort || false, - ignoreMemberSort = configuration.ignoreMemberSort || false, - memberSyntaxSortOrder = configuration.memberSyntaxSortOrder || ["none", "all", "multiple", "single"], - allowSeparatedGroups = configuration.allowSeparatedGroups || false, - sourceCode = context.getSourceCode(); - let previousDeclaration = null; - - /** - * Gets the used member syntax style. - * - * import "my-module.js" --> none - * import * as myModule from "my-module.js" --> all - * import {myMember} from "my-module.js" --> single - * import {foo, bar} from "my-module.js" --> multiple - * @param {ASTNode} node the ImportDeclaration node. - * @returns {string} used member parameter style, ["all", "multiple", "single"] - */ - function usedMemberSyntax(node) { - if (node.specifiers.length === 0) { - return "none"; - } - if (node.specifiers[0].type === "ImportNamespaceSpecifier") { - return "all"; - } - if (node.specifiers.length === 1) { - return "single"; - } - return "multiple"; - - } - - /** - * Gets the group by member parameter index for given declaration. - * @param {ASTNode} node the ImportDeclaration node. - * @returns {number} the declaration group by member index. - */ - function getMemberParameterGroupIndex(node) { - return memberSyntaxSortOrder.indexOf(usedMemberSyntax(node)); - } - - /** - * Gets the local name of the first imported module. - * @param {ASTNode} node the ImportDeclaration node. - * @returns {?string} the local name of the first imported module. - */ - function getFirstLocalMemberName(node) { - if (node.specifiers[0]) { - return node.specifiers[0].local.name; - } - return null; - - } - - /** - * Calculates number of lines between two nodes. It is assumed that the given `left` node appears before - * the given `right` node in the source code. Lines are counted from the end of the `left` node till the - * start of the `right` node. If the given nodes are on the same line, it returns `0`, same as if they were - * on two consecutive lines. - * @param {ASTNode} left node that appears before the given `right` node. - * @param {ASTNode} right node that appears after the given `left` node. - * @returns {number} number of lines between nodes. - */ - function getNumberOfLinesBetween(left, right) { - return Math.max(right.loc.start.line - left.loc.end.line - 1, 0); - } - - return { - ImportDeclaration(node) { - if (!ignoreDeclarationSort) { - if ( - previousDeclaration && - allowSeparatedGroups && - getNumberOfLinesBetween(previousDeclaration, node) > 0 - ) { - - // reset declaration sort - previousDeclaration = null; - } - - if (previousDeclaration) { - const currentMemberSyntaxGroupIndex = getMemberParameterGroupIndex(node), - previousMemberSyntaxGroupIndex = getMemberParameterGroupIndex(previousDeclaration); - let currentLocalMemberName = getFirstLocalMemberName(node), - previousLocalMemberName = getFirstLocalMemberName(previousDeclaration); - - if (ignoreCase) { - previousLocalMemberName = previousLocalMemberName && previousLocalMemberName.toLowerCase(); - currentLocalMemberName = currentLocalMemberName && currentLocalMemberName.toLowerCase(); - } - - /* - * When the current declaration uses a different member syntax, - * then check if the ordering is correct. - * Otherwise, make a default string compare (like rule sort-vars to be consistent) of the first used local member name. - */ - if (currentMemberSyntaxGroupIndex !== previousMemberSyntaxGroupIndex) { - if (currentMemberSyntaxGroupIndex < previousMemberSyntaxGroupIndex) { - context.report({ - node, - messageId: "unexpectedSyntaxOrder", - data: { - syntaxA: memberSyntaxSortOrder[currentMemberSyntaxGroupIndex], - syntaxB: memberSyntaxSortOrder[previousMemberSyntaxGroupIndex] - } - }); - } - } else { - if (previousLocalMemberName && - currentLocalMemberName && - currentLocalMemberName < previousLocalMemberName - ) { - context.report({ - node, - messageId: "sortImportsAlphabetically" - }); - } - } - } - - previousDeclaration = node; - } - - if (!ignoreMemberSort) { - const importSpecifiers = node.specifiers.filter(specifier => specifier.type === "ImportSpecifier"); - const getSortableName = ignoreCase ? specifier => specifier.local.name.toLowerCase() : specifier => specifier.local.name; - const firstUnsortedIndex = importSpecifiers.map(getSortableName).findIndex((name, index, array) => array[index - 1] > name); - - if (firstUnsortedIndex !== -1) { - context.report({ - node: importSpecifiers[firstUnsortedIndex], - messageId: "sortMembersAlphabetically", - data: { memberName: importSpecifiers[firstUnsortedIndex].local.name }, - fix(fixer) { - if (importSpecifiers.some(specifier => - sourceCode.getCommentsBefore(specifier).length || sourceCode.getCommentsAfter(specifier).length)) { - - // If there are comments in the ImportSpecifier list, don't rearrange the specifiers. - return null; - } - - return fixer.replaceTextRange( - [importSpecifiers[0].range[0], importSpecifiers[importSpecifiers.length - 1].range[1]], - importSpecifiers - - // Clone the importSpecifiers array to avoid mutating it - .slice() - - // Sort the array into the desired order - .sort((specifierA, specifierB) => { - const aName = getSortableName(specifierA); - const bName = getSortableName(specifierB); - - return aName > bName ? 1 : -1; - }) - - // Build a string out of the sorted list of import specifiers and the text between the originals - .reduce((sourceText, specifier, index) => { - const textAfterSpecifier = index === importSpecifiers.length - 1 - ? "" - : sourceCode.getText().slice(importSpecifiers[index].range[1], importSpecifiers[index + 1].range[0]); - - return sourceText + sourceCode.getText(specifier) + textAfterSpecifier; - }, "") - ); - } - }); - } - } - } - }; - } -}; - -/** - * @fileoverview Rule to require object keys to be sorted - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Gets the property name of the given `Property` node. - * - * - If the property's key is an `Identifier` node, this returns the key's name - * whether it's a computed property or not. - * - If the property has a static name, this returns the static name. - * - Otherwise, this returns null. - * @param {ASTNode} node The `Property` node to get. - * @returns {string|null} The property name or null. - * @private - */ -function getPropertyName(node) { - const staticName = astUtils.getStaticPropertyName(node); - - if (staticName !== null) { - return staticName; - } - - return node.key.name || null; -} - -/** - * Functions which check that the given 2 names are in specific order. - * - * Postfix `I` is meant insensitive. - * Postfix `N` is meant natural. - * @private - */ -const isValidOrders = { - asc(a, b) { - return a <= b; - }, - ascI(a, b) { - return a.toLowerCase() <= b.toLowerCase(); - }, - ascN(a, b) { - return naturalCompare__default['default'](a, b) <= 0; - }, - ascIN(a, b) { - return naturalCompare__default['default'](a.toLowerCase(), b.toLowerCase()) <= 0; - }, - desc(a, b) { - return isValidOrders.asc(b, a); - }, - descI(a, b) { - return isValidOrders.ascI(b, a); - }, - descN(a, b) { - return isValidOrders.ascN(b, a); - }, - descIN(a, b) { - return isValidOrders.ascIN(b, a); - } -}; - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var sortKeys = { - meta: { - type: "suggestion", - - docs: { - description: "require object keys to be sorted", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/sort-keys" - }, - - schema: [ - { - enum: ["asc", "desc"] - }, - { - type: "object", - properties: { - caseSensitive: { - type: "boolean", - default: true - }, - natural: { - type: "boolean", - default: false - }, - minKeys: { - type: "integer", - minimum: 2, - default: 2 - } - }, - additionalProperties: false - } - ], - - messages: { - sortKeys: "Expected object keys to be in {{natural}}{{insensitive}}{{order}}ending order. '{{thisName}}' should be before '{{prevName}}'." - } - }, - - create(context) { - - // Parse options. - const order = context.options[0] || "asc"; - const options = context.options[1]; - const insensitive = options && options.caseSensitive === false; - const natural = options && options.natural; - const minKeys = options && options.minKeys; - const isValidOrder = isValidOrders[ - order + (insensitive ? "I" : "") + (natural ? "N" : "") - ]; - - // The stack to save the previous property's name for each object literals. - let stack = null; - - return { - ObjectExpression(node) { - stack = { - upper: stack, - prevName: null, - numKeys: node.properties.length - }; - }, - - "ObjectExpression:exit"() { - stack = stack.upper; - }, - - SpreadElement(node) { - if (node.parent.type === "ObjectExpression") { - stack.prevName = null; - } - }, - - Property(node) { - if (node.parent.type === "ObjectPattern") { - return; - } - - const prevName = stack.prevName; - const numKeys = stack.numKeys; - const thisName = getPropertyName(node); - - if (thisName !== null) { - stack.prevName = thisName; - } - - if (prevName === null || thisName === null || numKeys < minKeys) { - return; - } - - if (!isValidOrder(prevName, thisName)) { - context.report({ - node, - loc: node.key.loc, - messageId: "sortKeys", - data: { - thisName, - prevName, - order, - insensitive: insensitive ? "insensitive " : "", - natural: natural ? "natural " : "" - } - }); - } - } - }; - } -}; - -/** - * @fileoverview Rule to require sorting of variables within a single Variable Declaration block - * @author Ilya Volodin - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var sortVars = { - meta: { - type: "suggestion", - - docs: { - description: "require variables within the same declaration block to be sorted", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/sort-vars" - }, - - schema: [ - { - type: "object", - properties: { - ignoreCase: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - fixable: "code", - - messages: { - sortVars: "Variables within the same declaration block should be sorted alphabetically." - } - }, - - create(context) { - - const configuration = context.options[0] || {}, - ignoreCase = configuration.ignoreCase || false, - sourceCode = context.getSourceCode(); - - return { - VariableDeclaration(node) { - const idDeclarations = node.declarations.filter(decl => decl.id.type === "Identifier"); - const getSortableName = ignoreCase ? decl => decl.id.name.toLowerCase() : decl => decl.id.name; - const unfixable = idDeclarations.some(decl => decl.init !== null && decl.init.type !== "Literal"); - let fixed = false; - - idDeclarations.slice(1).reduce((memo, decl) => { - const lastVariableName = getSortableName(memo), - currentVariableName = getSortableName(decl); - - if (currentVariableName < lastVariableName) { - context.report({ - node: decl, - messageId: "sortVars", - fix(fixer) { - if (unfixable || fixed) { - return null; - } - return fixer.replaceTextRange( - [idDeclarations[0].range[0], idDeclarations[idDeclarations.length - 1].range[1]], - idDeclarations - - // Clone the idDeclarations array to avoid mutating it - .slice() - - // Sort the array into the desired order - .sort((declA, declB) => { - const aName = getSortableName(declA); - const bName = getSortableName(declB); - - return aName > bName ? 1 : -1; - }) - - // Build a string out of the sorted list of identifier declarations and the text between the originals - .reduce((sourceText, identifier, index) => { - const textAfterIdentifier = index === idDeclarations.length - 1 - ? "" - : sourceCode.getText().slice(idDeclarations[index].range[1], idDeclarations[index + 1].range[0]); - - return sourceText + sourceCode.getText(identifier) + textAfterIdentifier; - }, "") - - ); - } - }); - fixed = true; - return memo; - } - return decl; - - }, idDeclarations[0]); - } - }; - } -}; - -/** - * @fileoverview A rule to ensure whitespace before blocks. - * @author Mathias Schreck - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Checks whether the given node represents the body of a function. - * @param {ASTNode} node the node to check. - * @returns {boolean} `true` if the node is function body. - */ -function isFunctionBody(node) { - const parent = node.parent; - - return ( - node.type === "BlockStatement" && - astUtils.isFunction(parent) && - parent.body === node - ); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var spaceBeforeBlocks = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent spacing before blocks", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/space-before-blocks" - }, - - fixable: "whitespace", - - schema: [ - { - oneOf: [ - { - enum: ["always", "never"] - }, - { - type: "object", - properties: { - keywords: { - enum: ["always", "never", "off"] - }, - functions: { - enum: ["always", "never", "off"] - }, - classes: { - enum: ["always", "never", "off"] - } - }, - additionalProperties: false - } - ] - } - ], - - messages: { - unexpectedSpace: "Unexpected space before opening brace.", - missingSpace: "Missing space before opening brace." - } - }, - - create(context) { - const config = context.options[0], - sourceCode = context.getSourceCode(); - let alwaysFunctions = true, - alwaysKeywords = true, - alwaysClasses = true, - neverFunctions = false, - neverKeywords = false, - neverClasses = false; - - if (typeof config === "object") { - alwaysFunctions = config.functions === "always"; - alwaysKeywords = config.keywords === "always"; - alwaysClasses = config.classes === "always"; - neverFunctions = config.functions === "never"; - neverKeywords = config.keywords === "never"; - neverClasses = config.classes === "never"; - } else if (config === "never") { - alwaysFunctions = false; - alwaysKeywords = false; - alwaysClasses = false; - neverFunctions = true; - neverKeywords = true; - neverClasses = true; - } - - /** - * Checks whether the spacing before the given block is already controlled by another rule: - * - `arrow-spacing` checks spaces after `=>`. - * - `keyword-spacing` checks spaces after keywords in certain contexts. - * @param {Token} precedingToken first token before the block. - * @param {ASTNode|Token} node `BlockStatement` node or `{` token of a `SwitchStatement` node. - * @returns {boolean} `true` if requiring or disallowing spaces before the given block could produce conflicts with other rules. - */ - function isConflicted(precedingToken, node) { - return astUtils.isArrowToken(precedingToken) || - astUtils.isKeywordToken(precedingToken) && !isFunctionBody(node); - } - - /** - * Checks the given BlockStatement node has a preceding space if it doesn’t start on a new line. - * @param {ASTNode|Token} node The AST node of a BlockStatement. - * @returns {void} undefined. - */ - function checkPrecedingSpace(node) { - const precedingToken = sourceCode.getTokenBefore(node); - - if (precedingToken && !isConflicted(precedingToken, node) && astUtils.isTokenOnSameLine(precedingToken, node)) { - const hasSpace = sourceCode.isSpaceBetweenTokens(precedingToken, node); - let requireSpace; - let requireNoSpace; - - if (isFunctionBody(node)) { - requireSpace = alwaysFunctions; - requireNoSpace = neverFunctions; - } else if (node.type === "ClassBody") { - requireSpace = alwaysClasses; - requireNoSpace = neverClasses; - } else { - requireSpace = alwaysKeywords; - requireNoSpace = neverKeywords; - } - - if (requireSpace && !hasSpace) { - context.report({ - node, - messageId: "missingSpace", - fix(fixer) { - return fixer.insertTextBefore(node, " "); - } - }); - } else if (requireNoSpace && hasSpace) { - context.report({ - node, - messageId: "unexpectedSpace", - fix(fixer) { - return fixer.removeRange([precedingToken.range[1], node.range[0]]); - } - }); - } - } - } - - /** - * Checks if the CaseBlock of an given SwitchStatement node has a preceding space. - * @param {ASTNode} node The node of a SwitchStatement. - * @returns {void} undefined. - */ - function checkSpaceBeforeCaseBlock(node) { - const cases = node.cases; - let openingBrace; - - if (cases.length > 0) { - openingBrace = sourceCode.getTokenBefore(cases[0]); - } else { - openingBrace = sourceCode.getLastToken(node, 1); - } - - checkPrecedingSpace(openingBrace); - } - - return { - BlockStatement: checkPrecedingSpace, - ClassBody: checkPrecedingSpace, - SwitchStatement: checkSpaceBeforeCaseBlock - }; - - } -}; - -/** - * @fileoverview Rule to validate spacing before function paren. - * @author Mathias Schreck - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var spaceBeforeFunctionParen = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent spacing before `function` definition opening parenthesis", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/space-before-function-paren" - }, - - fixable: "whitespace", - - schema: [ - { - oneOf: [ - { - enum: ["always", "never"] - }, - { - type: "object", - properties: { - anonymous: { - enum: ["always", "never", "ignore"] - }, - named: { - enum: ["always", "never", "ignore"] - }, - asyncArrow: { - enum: ["always", "never", "ignore"] - } - }, - additionalProperties: false - } - ] - } - ], - - messages: { - unexpectedSpace: "Unexpected space before function parentheses.", - missingSpace: "Missing space before function parentheses." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const baseConfig = typeof context.options[0] === "string" ? context.options[0] : "always"; - const overrideConfig = typeof context.options[0] === "object" ? context.options[0] : {}; - - /** - * Determines whether a function has a name. - * @param {ASTNode} node The function node. - * @returns {boolean} Whether the function has a name. - */ - function isNamedFunction(node) { - if (node.id) { - return true; - } - - const parent = node.parent; - - return parent.type === "MethodDefinition" || - (parent.type === "Property" && - ( - parent.kind === "get" || - parent.kind === "set" || - parent.method - ) - ); - } - - /** - * Gets the config for a given function - * @param {ASTNode} node The function node - * @returns {string} "always", "never", or "ignore" - */ - function getConfigForFunction(node) { - if (node.type === "ArrowFunctionExpression") { - - // Always ignore non-async functions and arrow functions without parens, e.g. async foo => bar - if (node.async && astUtils.isOpeningParenToken(sourceCode.getFirstToken(node, { skip: 1 }))) { - return overrideConfig.asyncArrow || baseConfig; - } - } else if (isNamedFunction(node)) { - return overrideConfig.named || baseConfig; - - // `generator-star-spacing` should warn anonymous generators. E.g. `function* () {}` - } else if (!node.generator) { - return overrideConfig.anonymous || baseConfig; - } - - return "ignore"; - } - - /** - * Checks the parens of a function node - * @param {ASTNode} node A function node - * @returns {void} - */ - function checkFunction(node) { - const functionConfig = getConfigForFunction(node); - - if (functionConfig === "ignore") { - return; - } - - const rightToken = sourceCode.getFirstToken(node, astUtils.isOpeningParenToken); - const leftToken = sourceCode.getTokenBefore(rightToken); - const hasSpacing = sourceCode.isSpaceBetweenTokens(leftToken, rightToken); - - if (hasSpacing && functionConfig === "never") { - context.report({ - node, - loc: { - start: leftToken.loc.end, - end: rightToken.loc.start - }, - messageId: "unexpectedSpace", - fix(fixer) { - const comments = sourceCode.getCommentsBefore(rightToken); - - // Don't fix anything if there's a single line comment between the left and the right token - if (comments.some(comment => comment.type === "Line")) { - return null; - } - return fixer.replaceTextRange( - [leftToken.range[1], rightToken.range[0]], - comments.reduce((text, comment) => text + sourceCode.getText(comment), "") - ); - } - }); - } else if (!hasSpacing && functionConfig === "always") { - context.report({ - node, - loc: rightToken.loc, - messageId: "missingSpace", - fix: fixer => fixer.insertTextAfter(leftToken, " ") - }); - } - } - - return { - ArrowFunctionExpression: checkFunction, - FunctionDeclaration: checkFunction, - FunctionExpression: checkFunction - }; - } -}; - -/** - * @fileoverview Disallows or enforces spaces inside of parentheses. - * @author Jonathan Rajavuori - */ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var spaceInParens = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent spacing inside parentheses", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/space-in-parens" - }, - - fixable: "whitespace", - - schema: [ - { - enum: ["always", "never"] - }, - { - type: "object", - properties: { - exceptions: { - type: "array", - items: { - enum: ["{}", "[]", "()", "empty"] - }, - uniqueItems: true - } - }, - additionalProperties: false - } - ], - - messages: { - missingOpeningSpace: "There must be a space after this paren.", - missingClosingSpace: "There must be a space before this paren.", - rejectedOpeningSpace: "There should be no space after this paren.", - rejectedClosingSpace: "There should be no space before this paren." - } - }, - - create(context) { - const ALWAYS = context.options[0] === "always", - exceptionsArrayOptions = (context.options[1] && context.options[1].exceptions) || [], - options = {}; - - let exceptions; - - if (exceptionsArrayOptions.length) { - options.braceException = exceptionsArrayOptions.includes("{}"); - options.bracketException = exceptionsArrayOptions.includes("[]"); - options.parenException = exceptionsArrayOptions.includes("()"); - options.empty = exceptionsArrayOptions.includes("empty"); - } - - /** - * Produces an object with the opener and closer exception values - * @returns {Object} `openers` and `closers` exception values - * @private - */ - function getExceptions() { - const openers = [], - closers = []; - - if (options.braceException) { - openers.push("{"); - closers.push("}"); - } - - if (options.bracketException) { - openers.push("["); - closers.push("]"); - } - - if (options.parenException) { - openers.push("("); - closers.push(")"); - } - - if (options.empty) { - openers.push(")"); - closers.push("("); - } - - return { - openers, - closers - }; - } - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - const sourceCode = context.getSourceCode(); - - /** - * Determines if a token is one of the exceptions for the opener paren - * @param {Object} token The token to check - * @returns {boolean} True if the token is one of the exceptions for the opener paren - */ - function isOpenerException(token) { - return exceptions.openers.includes(token.value); - } - - /** - * Determines if a token is one of the exceptions for the closer paren - * @param {Object} token The token to check - * @returns {boolean} True if the token is one of the exceptions for the closer paren - */ - function isCloserException(token) { - return exceptions.closers.includes(token.value); - } - - /** - * Determines if an opening paren is immediately followed by a required space - * @param {Object} openingParenToken The paren token - * @param {Object} tokenAfterOpeningParen The token after it - * @returns {boolean} True if the opening paren is missing a required space - */ - function openerMissingSpace(openingParenToken, tokenAfterOpeningParen) { - if (sourceCode.isSpaceBetweenTokens(openingParenToken, tokenAfterOpeningParen)) { - return false; - } - - if (!options.empty && astUtils.isClosingParenToken(tokenAfterOpeningParen)) { - return false; - } - - if (ALWAYS) { - return !isOpenerException(tokenAfterOpeningParen); - } - return isOpenerException(tokenAfterOpeningParen); - } - - /** - * Determines if an opening paren is immediately followed by a disallowed space - * @param {Object} openingParenToken The paren token - * @param {Object} tokenAfterOpeningParen The token after it - * @returns {boolean} True if the opening paren has a disallowed space - */ - function openerRejectsSpace(openingParenToken, tokenAfterOpeningParen) { - if (!astUtils.isTokenOnSameLine(openingParenToken, tokenAfterOpeningParen)) { - return false; - } - - if (tokenAfterOpeningParen.type === "Line") { - return false; - } - - if (!sourceCode.isSpaceBetweenTokens(openingParenToken, tokenAfterOpeningParen)) { - return false; - } - - if (ALWAYS) { - return isOpenerException(tokenAfterOpeningParen); - } - return !isOpenerException(tokenAfterOpeningParen); - } - - /** - * Determines if a closing paren is immediately preceded by a required space - * @param {Object} tokenBeforeClosingParen The token before the paren - * @param {Object} closingParenToken The paren token - * @returns {boolean} True if the closing paren is missing a required space - */ - function closerMissingSpace(tokenBeforeClosingParen, closingParenToken) { - if (sourceCode.isSpaceBetweenTokens(tokenBeforeClosingParen, closingParenToken)) { - return false; - } - - if (!options.empty && astUtils.isOpeningParenToken(tokenBeforeClosingParen)) { - return false; - } - - if (ALWAYS) { - return !isCloserException(tokenBeforeClosingParen); - } - return isCloserException(tokenBeforeClosingParen); - } - - /** - * Determines if a closer paren is immediately preceded by a disallowed space - * @param {Object} tokenBeforeClosingParen The token before the paren - * @param {Object} closingParenToken The paren token - * @returns {boolean} True if the closing paren has a disallowed space - */ - function closerRejectsSpace(tokenBeforeClosingParen, closingParenToken) { - if (!astUtils.isTokenOnSameLine(tokenBeforeClosingParen, closingParenToken)) { - return false; - } - - if (!sourceCode.isSpaceBetweenTokens(tokenBeforeClosingParen, closingParenToken)) { - return false; - } - - if (ALWAYS) { - return isCloserException(tokenBeforeClosingParen); - } - return !isCloserException(tokenBeforeClosingParen); - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - Program: function checkParenSpaces(node) { - exceptions = getExceptions(); - const tokens = sourceCode.tokensAndComments; - - tokens.forEach((token, i) => { - const prevToken = tokens[i - 1]; - const nextToken = tokens[i + 1]; - - // if token is not an opening or closing paren token, do nothing - if (!astUtils.isOpeningParenToken(token) && !astUtils.isClosingParenToken(token)) { - return; - } - - // if token is an opening paren and is not followed by a required space - if (token.value === "(" && openerMissingSpace(token, nextToken)) { - context.report({ - node, - loc: token.loc, - messageId: "missingOpeningSpace", - fix(fixer) { - return fixer.insertTextAfter(token, " "); - } - }); - } - - // if token is an opening paren and is followed by a disallowed space - if (token.value === "(" && openerRejectsSpace(token, nextToken)) { - context.report({ - node, - loc: { start: token.loc.end, end: nextToken.loc.start }, - messageId: "rejectedOpeningSpace", - fix(fixer) { - return fixer.removeRange([token.range[1], nextToken.range[0]]); - } - }); - } - - // if token is a closing paren and is not preceded by a required space - if (token.value === ")" && closerMissingSpace(prevToken, token)) { - context.report({ - node, - loc: token.loc, - messageId: "missingClosingSpace", - fix(fixer) { - return fixer.insertTextBefore(token, " "); - } - }); - } - - // if token is a closing paren and is preceded by a disallowed space - if (token.value === ")" && closerRejectsSpace(prevToken, token)) { - context.report({ - node, - loc: { start: prevToken.loc.end, end: token.loc.start }, - messageId: "rejectedClosingSpace", - fix(fixer) { - return fixer.removeRange([prevToken.range[1], token.range[0]]); - } - }); - } - }); - } - }; - } -}; - -/** - * @fileoverview Require spaces around infix operators - * @author Michael Ficarra - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var spaceInfixOps = { - meta: { - type: "layout", - - docs: { - description: "require spacing around infix operators", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/space-infix-ops" - }, - - fixable: "whitespace", - - schema: [ - { - type: "object", - properties: { - int32Hint: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - messages: { - missingSpace: "Operator '{{operator}}' must be spaced." - } - }, - - create(context) { - const int32Hint = context.options[0] ? context.options[0].int32Hint === true : false; - const sourceCode = context.getSourceCode(); - - /** - * Returns the first token which violates the rule - * @param {ASTNode} left The left node of the main node - * @param {ASTNode} right The right node of the main node - * @param {string} op The operator of the main node - * @returns {Object} The violator token or null - * @private - */ - function getFirstNonSpacedToken(left, right, op) { - const operator = sourceCode.getFirstTokenBetween(left, right, token => token.value === op); - const prev = sourceCode.getTokenBefore(operator); - const next = sourceCode.getTokenAfter(operator); - - if (!sourceCode.isSpaceBetweenTokens(prev, operator) || !sourceCode.isSpaceBetweenTokens(operator, next)) { - return operator; - } - - return null; - } - - /** - * Reports an AST node as a rule violation - * @param {ASTNode} mainNode The node to report - * @param {Object} culpritToken The token which has a problem - * @returns {void} - * @private - */ - function report(mainNode, culpritToken) { - context.report({ - node: mainNode, - loc: culpritToken.loc, - messageId: "missingSpace", - data: { - operator: culpritToken.value - }, - fix(fixer) { - const previousToken = sourceCode.getTokenBefore(culpritToken); - const afterToken = sourceCode.getTokenAfter(culpritToken); - let fixString = ""; - - if (culpritToken.range[0] - previousToken.range[1] === 0) { - fixString = " "; - } - - fixString += culpritToken.value; - - if (afterToken.range[0] - culpritToken.range[1] === 0) { - fixString += " "; - } - - return fixer.replaceText(culpritToken, fixString); - } - }); - } - - /** - * Check if the node is binary then report - * @param {ASTNode} node node to evaluate - * @returns {void} - * @private - */ - function checkBinary(node) { - const leftNode = (node.left.typeAnnotation) ? node.left.typeAnnotation : node.left; - const rightNode = node.right; - - // search for = in AssignmentPattern nodes - const operator = node.operator || "="; - - const nonSpacedNode = getFirstNonSpacedToken(leftNode, rightNode, operator); - - if (nonSpacedNode) { - if (!(int32Hint && sourceCode.getText(node).endsWith("|0"))) { - report(node, nonSpacedNode); - } - } - } - - /** - * Check if the node is conditional - * @param {ASTNode} node node to evaluate - * @returns {void} - * @private - */ - function checkConditional(node) { - const nonSpacedConsequentNode = getFirstNonSpacedToken(node.test, node.consequent, "?"); - const nonSpacedAlternateNode = getFirstNonSpacedToken(node.consequent, node.alternate, ":"); - - if (nonSpacedConsequentNode) { - report(node, nonSpacedConsequentNode); - } - - if (nonSpacedAlternateNode) { - report(node, nonSpacedAlternateNode); - } - } - - /** - * Check if the node is a variable - * @param {ASTNode} node node to evaluate - * @returns {void} - * @private - */ - function checkVar(node) { - const leftNode = (node.id.typeAnnotation) ? node.id.typeAnnotation : node.id; - const rightNode = node.init; - - if (rightNode) { - const nonSpacedNode = getFirstNonSpacedToken(leftNode, rightNode, "="); - - if (nonSpacedNode) { - report(node, nonSpacedNode); - } - } - } - - return { - AssignmentExpression: checkBinary, - AssignmentPattern: checkBinary, - BinaryExpression: checkBinary, - LogicalExpression: checkBinary, - ConditionalExpression: checkConditional, - VariableDeclarator: checkVar - }; - - } -}; - -/** - * @fileoverview This rule should require or disallow spaces before or after unary operations. - * @author Marcin Kumorek - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var spaceUnaryOps = { - meta: { - type: "layout", - - docs: { - description: "enforce consistent spacing before or after unary operators", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/space-unary-ops" - }, - - fixable: "whitespace", - - schema: [ - { - type: "object", - properties: { - words: { - type: "boolean", - default: true - }, - nonwords: { - type: "boolean", - default: false - }, - overrides: { - type: "object", - additionalProperties: { - type: "boolean" - } - } - }, - additionalProperties: false - } - ], - messages: { - unexpectedBefore: "Unexpected space before unary operator '{{operator}}'.", - unexpectedAfter: "Unexpected space after unary operator '{{operator}}'.", - unexpectedAfterWord: "Unexpected space after unary word operator '{{word}}'.", - wordOperator: "Unary word operator '{{word}}' must be followed by whitespace.", - operator: "Unary operator '{{operator}}' must be followed by whitespace.", - beforeUnaryExpressions: "Space is required before unary expressions '{{token}}'." - } - }, - - create(context) { - const options = context.options[0] || { words: true, nonwords: false }; - - const sourceCode = context.getSourceCode(); - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - /** - * Check if the node is the first "!" in a "!!" convert to Boolean expression - * @param {ASTnode} node AST node - * @returns {boolean} Whether or not the node is first "!" in "!!" - */ - function isFirstBangInBangBangExpression(node) { - return node && node.type === "UnaryExpression" && node.argument.operator === "!" && - node.argument && node.argument.type === "UnaryExpression" && node.argument.operator === "!"; - } - - /** - * Checks if an override exists for a given operator. - * @param {string} operator Operator - * @returns {boolean} Whether or not an override has been provided for the operator - */ - function overrideExistsForOperator(operator) { - return options.overrides && Object.prototype.hasOwnProperty.call(options.overrides, operator); - } - - /** - * Gets the value that the override was set to for this operator - * @param {string} operator Operator - * @returns {boolean} Whether or not an override enforces a space with this operator - */ - function overrideEnforcesSpaces(operator) { - return options.overrides[operator]; - } - - /** - * Verify Unary Word Operator has spaces after the word operator - * @param {ASTnode} node AST node - * @param {Object} firstToken first token from the AST node - * @param {Object} secondToken second token from the AST node - * @param {string} word The word to be used for reporting - * @returns {void} - */ - function verifyWordHasSpaces(node, firstToken, secondToken, word) { - if (secondToken.range[0] === firstToken.range[1]) { - context.report({ - node, - messageId: "wordOperator", - data: { - word - }, - fix(fixer) { - return fixer.insertTextAfter(firstToken, " "); - } - }); - } - } - - /** - * Verify Unary Word Operator doesn't have spaces after the word operator - * @param {ASTnode} node AST node - * @param {Object} firstToken first token from the AST node - * @param {Object} secondToken second token from the AST node - * @param {string} word The word to be used for reporting - * @returns {void} - */ - function verifyWordDoesntHaveSpaces(node, firstToken, secondToken, word) { - if (astUtils.canTokensBeAdjacent(firstToken, secondToken)) { - if (secondToken.range[0] > firstToken.range[1]) { - context.report({ - node, - messageId: "unexpectedAfterWord", - data: { - word - }, - fix(fixer) { - return fixer.removeRange([firstToken.range[1], secondToken.range[0]]); - } - }); - } - } - } - - /** - * Check Unary Word Operators for spaces after the word operator - * @param {ASTnode} node AST node - * @param {Object} firstToken first token from the AST node - * @param {Object} secondToken second token from the AST node - * @param {string} word The word to be used for reporting - * @returns {void} - */ - function checkUnaryWordOperatorForSpaces(node, firstToken, secondToken, word) { - if (overrideExistsForOperator(word)) { - if (overrideEnforcesSpaces(word)) { - verifyWordHasSpaces(node, firstToken, secondToken, word); - } else { - verifyWordDoesntHaveSpaces(node, firstToken, secondToken, word); - } - } else if (options.words) { - verifyWordHasSpaces(node, firstToken, secondToken, word); - } else { - verifyWordDoesntHaveSpaces(node, firstToken, secondToken, word); - } - } - - /** - * Verifies YieldExpressions satisfy spacing requirements - * @param {ASTnode} node AST node - * @returns {void} - */ - function checkForSpacesAfterYield(node) { - const tokens = sourceCode.getFirstTokens(node, 3), - word = "yield"; - - if (!node.argument || node.delegate) { - return; - } - - checkUnaryWordOperatorForSpaces(node, tokens[0], tokens[1], word); - } - - /** - * Verifies AwaitExpressions satisfy spacing requirements - * @param {ASTNode} node AwaitExpression AST node - * @returns {void} - */ - function checkForSpacesAfterAwait(node) { - const tokens = sourceCode.getFirstTokens(node, 3); - - checkUnaryWordOperatorForSpaces(node, tokens[0], tokens[1], "await"); - } - - /** - * Verifies UnaryExpression, UpdateExpression and NewExpression have spaces before or after the operator - * @param {ASTnode} node AST node - * @param {Object} firstToken First token in the expression - * @param {Object} secondToken Second token in the expression - * @returns {void} - */ - function verifyNonWordsHaveSpaces(node, firstToken, secondToken) { - if (node.prefix) { - if (isFirstBangInBangBangExpression(node)) { - return; - } - if (firstToken.range[1] === secondToken.range[0]) { - context.report({ - node, - messageId: "operator", - data: { - operator: firstToken.value - }, - fix(fixer) { - return fixer.insertTextAfter(firstToken, " "); - } - }); - } - } else { - if (firstToken.range[1] === secondToken.range[0]) { - context.report({ - node, - messageId: "beforeUnaryExpressions", - data: { - token: secondToken.value - }, - fix(fixer) { - return fixer.insertTextBefore(secondToken, " "); - } - }); - } - } - } - - /** - * Verifies UnaryExpression, UpdateExpression and NewExpression don't have spaces before or after the operator - * @param {ASTnode} node AST node - * @param {Object} firstToken First token in the expression - * @param {Object} secondToken Second token in the expression - * @returns {void} - */ - function verifyNonWordsDontHaveSpaces(node, firstToken, secondToken) { - if (node.prefix) { - if (secondToken.range[0] > firstToken.range[1]) { - context.report({ - node, - messageId: "unexpectedAfter", - data: { - operator: firstToken.value - }, - fix(fixer) { - if (astUtils.canTokensBeAdjacent(firstToken, secondToken)) { - return fixer.removeRange([firstToken.range[1], secondToken.range[0]]); - } - return null; - } - }); - } - } else { - if (secondToken.range[0] > firstToken.range[1]) { - context.report({ - node, - messageId: "unexpectedBefore", - data: { - operator: secondToken.value - }, - fix(fixer) { - return fixer.removeRange([firstToken.range[1], secondToken.range[0]]); - } - }); - } - } - } - - /** - * Verifies UnaryExpression, UpdateExpression and NewExpression satisfy spacing requirements - * @param {ASTnode} node AST node - * @returns {void} - */ - function checkForSpaces(node) { - const tokens = node.type === "UpdateExpression" && !node.prefix - ? sourceCode.getLastTokens(node, 2) - : sourceCode.getFirstTokens(node, 2); - const firstToken = tokens[0]; - const secondToken = tokens[1]; - - if ((node.type === "NewExpression" || node.prefix) && firstToken.type === "Keyword") { - checkUnaryWordOperatorForSpaces(node, firstToken, secondToken, firstToken.value); - return; - } - - const operator = node.prefix ? tokens[0].value : tokens[1].value; - - if (overrideExistsForOperator(operator)) { - if (overrideEnforcesSpaces(operator)) { - verifyNonWordsHaveSpaces(node, firstToken, secondToken); - } else { - verifyNonWordsDontHaveSpaces(node, firstToken, secondToken); - } - } else if (options.nonwords) { - verifyNonWordsHaveSpaces(node, firstToken, secondToken); - } else { - verifyNonWordsDontHaveSpaces(node, firstToken, secondToken); - } - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - UnaryExpression: checkForSpaces, - UpdateExpression: checkForSpaces, - NewExpression: checkForSpaces, - YieldExpression: checkForSpacesAfterYield, - AwaitExpression: checkForSpacesAfterAwait - }; - - } -}; - -/** - * @fileoverview Source code for spaced-comments rule - * @author Gyandeep Singh - */ - - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Escapes the control characters of a given string. - * @param {string} s A string to escape. - * @returns {string} An escaped string. - */ -function escape(s) { - return `(?:${lodash__default['default'].escapeRegExp(s)})`; -} - -/** - * Escapes the control characters of a given string. - * And adds a repeat flag. - * @param {string} s A string to escape. - * @returns {string} An escaped string. - */ -function escapeAndRepeat(s) { - return `${escape(s)}+`; -} - -/** - * Parses `markers` option. - * If markers don't include `"*"`, this adds `"*"` to allow JSDoc comments. - * @param {string[]} [markers] A marker list. - * @returns {string[]} A marker list. - */ -function parseMarkersOption(markers) { - - // `*` is a marker for JSDoc comments. - if (markers.indexOf("*") === -1) { - return markers.concat("*"); - } - - return markers; -} - -/** - * Creates string pattern for exceptions. - * Generated pattern: - * - * 1. A space or an exception pattern sequence. - * @param {string[]} exceptions An exception pattern list. - * @returns {string} A regular expression string for exceptions. - */ -function createExceptionsPattern(exceptions) { - let pattern = ""; - - /* - * A space or an exception pattern sequence. - * [] ==> "\s" - * ["-"] ==> "(?:\s|\-+$)" - * ["-", "="] ==> "(?:\s|(?:\-+|=+)$)" - * ["-", "=", "--=="] ==> "(?:\s|(?:\-+|=+|(?:\-\-==)+)$)" ==> https://jex.im/regulex/#!embed=false&flags=&re=(%3F%3A%5Cs%7C(%3F%3A%5C-%2B%7C%3D%2B%7C(%3F%3A%5C-%5C-%3D%3D)%2B)%24) - */ - if (exceptions.length === 0) { - - // a space. - pattern += "\\s"; - } else { - - // a space or... - pattern += "(?:\\s|"; - - if (exceptions.length === 1) { - - // a sequence of the exception pattern. - pattern += escapeAndRepeat(exceptions[0]); - } else { - - // a sequence of one of the exception patterns. - pattern += "(?:"; - pattern += exceptions.map(escapeAndRepeat).join("|"); - pattern += ")"; - } - pattern += `(?:$|[${Array.from(astUtils.LINEBREAKS).join("")}]))`; - } - - return pattern; -} - -/** - * Creates RegExp object for `always` mode. - * Generated pattern for beginning of comment: - * - * 1. First, a marker or nothing. - * 2. Next, a space or an exception pattern sequence. - * @param {string[]} markers A marker list. - * @param {string[]} exceptions An exception pattern list. - * @returns {RegExp} A RegExp object for the beginning of a comment in `always` mode. - */ -function createAlwaysStylePattern(markers, exceptions) { - let pattern = "^"; - - /* - * A marker or nothing. - * ["*"] ==> "\*?" - * ["*", "!"] ==> "(?:\*|!)?" - * ["*", "/", "!<"] ==> "(?:\*|\/|(?:!<))?" ==> https://jex.im/regulex/#!embed=false&flags=&re=(%3F%3A%5C*%7C%5C%2F%7C(%3F%3A!%3C))%3F - */ - if (markers.length === 1) { - - // the marker. - pattern += escape(markers[0]); - } else { - - // one of markers. - pattern += "(?:"; - pattern += markers.map(escape).join("|"); - pattern += ")"; - } - - pattern += "?"; // or nothing. - pattern += createExceptionsPattern(exceptions); - - return new RegExp(pattern, "u"); -} - -/** - * Creates RegExp object for `never` mode. - * Generated pattern for beginning of comment: - * - * 1. First, a marker or nothing (captured). - * 2. Next, a space or a tab. - * @param {string[]} markers A marker list. - * @returns {RegExp} A RegExp object for `never` mode. - */ -function createNeverStylePattern(markers) { - const pattern = `^(${markers.map(escape).join("|")})?[ \t]+`; - - return new RegExp(pattern, "u"); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var spacedComment = { - meta: { - type: "suggestion", - - docs: { - description: "enforce consistent spacing after the `//` or `/*` in a comment", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/spaced-comment" - }, - - fixable: "whitespace", - - schema: [ - { - enum: ["always", "never"] - }, - { - type: "object", - properties: { - exceptions: { - type: "array", - items: { - type: "string" - } - }, - markers: { - type: "array", - items: { - type: "string" - } - }, - line: { - type: "object", - properties: { - exceptions: { - type: "array", - items: { - type: "string" - } - }, - markers: { - type: "array", - items: { - type: "string" - } - } - }, - additionalProperties: false - }, - block: { - type: "object", - properties: { - exceptions: { - type: "array", - items: { - type: "string" - } - }, - markers: { - type: "array", - items: { - type: "string" - } - }, - balanced: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - }, - additionalProperties: false - } - ], - - messages: { - unexpectedSpaceAfterMarker: "Unexpected space or tab after marker ({{refChar}}) in comment.", - expectedExceptionAfter: "Expected exception block, space or tab after '{{refChar}}' in comment.", - unexpectedSpaceBefore: "Unexpected space or tab before '*/' in comment.", - unexpectedSpaceAfter: "Unexpected space or tab after '{{refChar}}' in comment.", - expectedSpaceBefore: "Expected space or tab before '*/' in comment.", - expectedSpaceAfter: "Expected space or tab after '{{refChar}}' in comment." - } - }, - - create(context) { - - const sourceCode = context.getSourceCode(); - - // Unless the first option is never, require a space - const requireSpace = context.options[0] !== "never"; - - /* - * Parse the second options. - * If markers don't include `"*"`, it's added automatically for JSDoc - * comments. - */ - const config = context.options[1] || {}; - const balanced = config.block && config.block.balanced; - - const styleRules = ["block", "line"].reduce((rule, type) => { - const markers = parseMarkersOption(config[type] && config[type].markers || config.markers || []); - const exceptions = config[type] && config[type].exceptions || config.exceptions || []; - const endNeverPattern = "[ \t]+$"; - - // Create RegExp object for valid patterns. - rule[type] = { - beginRegex: requireSpace ? createAlwaysStylePattern(markers, exceptions) : createNeverStylePattern(markers), - endRegex: balanced && requireSpace ? new RegExp(`${createExceptionsPattern(exceptions)}$`, "u") : new RegExp(endNeverPattern, "u"), - hasExceptions: exceptions.length > 0, - captureMarker: new RegExp(`^(${markers.map(escape).join("|")})`, "u"), - markers: new Set(markers) - }; - - return rule; - }, {}); - - /** - * Reports a beginning spacing error with an appropriate message. - * @param {ASTNode} node A comment node to check. - * @param {string} messageId An error message to report. - * @param {Array} match An array of match results for markers. - * @param {string} refChar Character used for reference in the error message. - * @returns {void} - */ - function reportBegin(node, messageId, match, refChar) { - const type = node.type.toLowerCase(), - commentIdentifier = type === "block" ? "/*" : "//"; - - context.report({ - node, - fix(fixer) { - const start = node.range[0]; - let end = start + 2; - - if (requireSpace) { - if (match) { - end += match[0].length; - } - return fixer.insertTextAfterRange([start, end], " "); - } - end += match[0].length; - return fixer.replaceTextRange([start, end], commentIdentifier + (match[1] ? match[1] : "")); - - }, - messageId, - data: { refChar } - }); - } - - /** - * Reports an ending spacing error with an appropriate message. - * @param {ASTNode} node A comment node to check. - * @param {string} messageId An error message to report. - * @param {string} match An array of the matched whitespace characters. - * @returns {void} - */ - function reportEnd(node, messageId, match) { - context.report({ - node, - fix(fixer) { - if (requireSpace) { - return fixer.insertTextAfterRange([node.range[0], node.range[1] - 2], " "); - } - const end = node.range[1] - 2, - start = end - match[0].length; - - return fixer.replaceTextRange([start, end], ""); - - }, - messageId - }); - } - - /** - * Reports a given comment if it's invalid. - * @param {ASTNode} node a comment node to check. - * @returns {void} - */ - function checkCommentForSpace(node) { - const type = node.type.toLowerCase(), - rule = styleRules[type], - commentIdentifier = type === "block" ? "/*" : "//"; - - // Ignores empty comments and comments that consist only of a marker. - if (node.value.length === 0 || rule.markers.has(node.value)) { - return; - } - - const beginMatch = rule.beginRegex.exec(node.value); - const endMatch = rule.endRegex.exec(node.value); - - // Checks. - if (requireSpace) { - if (!beginMatch) { - const hasMarker = rule.captureMarker.exec(node.value); - const marker = hasMarker ? commentIdentifier + hasMarker[0] : commentIdentifier; - - if (rule.hasExceptions) { - reportBegin(node, "expectedExceptionAfter", hasMarker, marker); - } else { - reportBegin(node, "expectedSpaceAfter", hasMarker, marker); - } - } - - if (balanced && type === "block" && !endMatch) { - reportEnd(node, "expectedSpaceBefore"); - } - } else { - if (beginMatch) { - if (!beginMatch[1]) { - reportBegin(node, "unexpectedSpaceAfter", beginMatch, commentIdentifier); - } else { - reportBegin(node, "unexpectedSpaceAfterMarker", beginMatch, beginMatch[1]); - } - } - - if (balanced && type === "block" && endMatch) { - reportEnd(node, "unexpectedSpaceBefore", endMatch); - } - } - } - - return { - Program() { - const comments = sourceCode.getAllComments(); - - comments.filter(token => token.type !== "Shebang").forEach(checkCommentForSpace); - } - }; - } -}; - -/** - * @fileoverview Rule to control usage of strict mode directives. - * @author Brandon Mills - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Gets all of the Use Strict Directives in the Directive Prologue of a group of - * statements. - * @param {ASTNode[]} statements Statements in the program or function body. - * @returns {ASTNode[]} All of the Use Strict Directives. - */ -function getUseStrictDirectives(statements) { - const directives = []; - - for (let i = 0; i < statements.length; i++) { - const statement = statements[i]; - - if ( - statement.type === "ExpressionStatement" && - statement.expression.type === "Literal" && - statement.expression.value === "use strict" - ) { - directives[i] = statement; - } else { - break; - } - } - - return directives; -} - -/** - * Checks whether a given parameter is a simple parameter. - * @param {ASTNode} node A pattern node to check. - * @returns {boolean} `true` if the node is an Identifier node. - */ -function isSimpleParameter(node) { - return node.type === "Identifier"; -} - -/** - * Checks whether a given parameter list is a simple parameter list. - * @param {ASTNode[]} params A parameter list to check. - * @returns {boolean} `true` if the every parameter is an Identifier node. - */ -function isSimpleParameterList(params) { - return params.every(isSimpleParameter); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var strict = { - meta: { - type: "suggestion", - - docs: { - description: "require or disallow strict mode directives", - category: "Strict Mode", - recommended: false, - url: "https://eslint.org/docs/rules/strict" - }, - - schema: [ - { - enum: ["never", "global", "function", "safe"] - } - ], - - fixable: "code", - messages: { - function: "Use the function form of 'use strict'.", - global: "Use the global form of 'use strict'.", - multiple: "Multiple 'use strict' directives.", - never: "Strict mode is not permitted.", - unnecessary: "Unnecessary 'use strict' directive.", - module: "'use strict' is unnecessary inside of modules.", - implied: "'use strict' is unnecessary when implied strict mode is enabled.", - unnecessaryInClasses: "'use strict' is unnecessary inside of classes.", - nonSimpleParameterList: "'use strict' directive inside a function with non-simple parameter list throws a syntax error since ES2016.", - wrap: "Wrap {{name}} in a function with 'use strict' directive." - } - }, - - create(context) { - - const ecmaFeatures = context.parserOptions.ecmaFeatures || {}, - scopes = [], - classScopes = []; - let mode = context.options[0] || "safe"; - - if (ecmaFeatures.impliedStrict) { - mode = "implied"; - } else if (mode === "safe") { - mode = ecmaFeatures.globalReturn ? "global" : "function"; - } - - /** - * Determines whether a reported error should be fixed, depending on the error type. - * @param {string} errorType The type of error - * @returns {boolean} `true` if the reported error should be fixed - */ - function shouldFix(errorType) { - return errorType === "multiple" || errorType === "unnecessary" || errorType === "module" || errorType === "implied" || errorType === "unnecessaryInClasses"; - } - - /** - * Gets a fixer function to remove a given 'use strict' directive. - * @param {ASTNode} node The directive that should be removed - * @returns {Function} A fixer function - */ - function getFixFunction(node) { - return fixer => fixer.remove(node); - } - - /** - * Report a slice of an array of nodes with a given message. - * @param {ASTNode[]} nodes Nodes. - * @param {string} start Index to start from. - * @param {string} end Index to end before. - * @param {string} messageId Message to display. - * @param {boolean} fix `true` if the directive should be fixed (i.e. removed) - * @returns {void} - */ - function reportSlice(nodes, start, end, messageId, fix) { - nodes.slice(start, end).forEach(node => { - context.report({ node, messageId, fix: fix ? getFixFunction(node) : null }); - }); - } - - /** - * Report all nodes in an array with a given message. - * @param {ASTNode[]} nodes Nodes. - * @param {string} messageId Message id to display. - * @param {boolean} fix `true` if the directive should be fixed (i.e. removed) - * @returns {void} - */ - function reportAll(nodes, messageId, fix) { - reportSlice(nodes, 0, nodes.length, messageId, fix); - } - - /** - * Report all nodes in an array, except the first, with a given message. - * @param {ASTNode[]} nodes Nodes. - * @param {string} messageId Message id to display. - * @param {boolean} fix `true` if the directive should be fixed (i.e. removed) - * @returns {void} - */ - function reportAllExceptFirst(nodes, messageId, fix) { - reportSlice(nodes, 1, nodes.length, messageId, fix); - } - - /** - * Entering a function in 'function' mode pushes a new nested scope onto the - * stack. The new scope is true if the nested function is strict mode code. - * @param {ASTNode} node The function declaration or expression. - * @param {ASTNode[]} useStrictDirectives The Use Strict Directives of the node. - * @returns {void} - */ - function enterFunctionInFunctionMode(node, useStrictDirectives) { - const isInClass = classScopes.length > 0, - isParentGlobal = scopes.length === 0 && classScopes.length === 0, - isParentStrict = scopes.length > 0 && scopes[scopes.length - 1], - isStrict = useStrictDirectives.length > 0; - - if (isStrict) { - if (!isSimpleParameterList(node.params)) { - context.report({ node: useStrictDirectives[0], messageId: "nonSimpleParameterList" }); - } else if (isParentStrict) { - context.report({ node: useStrictDirectives[0], messageId: "unnecessary", fix: getFixFunction(useStrictDirectives[0]) }); - } else if (isInClass) { - context.report({ node: useStrictDirectives[0], messageId: "unnecessaryInClasses", fix: getFixFunction(useStrictDirectives[0]) }); - } - - reportAllExceptFirst(useStrictDirectives, "multiple", true); - } else if (isParentGlobal) { - if (isSimpleParameterList(node.params)) { - context.report({ node, messageId: "function" }); - } else { - context.report({ - node, - messageId: "wrap", - data: { name: astUtils.getFunctionNameWithKind(node) } - }); - } - } - - scopes.push(isParentStrict || isStrict); - } - - /** - * Exiting a function in 'function' mode pops its scope off the stack. - * @returns {void} - */ - function exitFunctionInFunctionMode() { - scopes.pop(); - } - - /** - * Enter a function and either: - * - Push a new nested scope onto the stack (in 'function' mode). - * - Report all the Use Strict Directives (in the other modes). - * @param {ASTNode} node The function declaration or expression. - * @returns {void} - */ - function enterFunction(node) { - const isBlock = node.body.type === "BlockStatement", - useStrictDirectives = isBlock - ? getUseStrictDirectives(node.body.body) : []; - - if (mode === "function") { - enterFunctionInFunctionMode(node, useStrictDirectives); - } else if (useStrictDirectives.length > 0) { - if (isSimpleParameterList(node.params)) { - reportAll(useStrictDirectives, mode, shouldFix(mode)); - } else { - context.report({ node: useStrictDirectives[0], messageId: "nonSimpleParameterList" }); - reportAllExceptFirst(useStrictDirectives, "multiple", true); - } - } - } - - const rule = { - Program(node) { - const useStrictDirectives = getUseStrictDirectives(node.body); - - if (node.sourceType === "module") { - mode = "module"; - } - - if (mode === "global") { - if (node.body.length > 0 && useStrictDirectives.length === 0) { - context.report({ node, messageId: "global" }); - } - reportAllExceptFirst(useStrictDirectives, "multiple", true); - } else { - reportAll(useStrictDirectives, mode, shouldFix(mode)); - } - }, - FunctionDeclaration: enterFunction, - FunctionExpression: enterFunction, - ArrowFunctionExpression: enterFunction - }; - - if (mode === "function") { - Object.assign(rule, { - - // Inside of class bodies are always strict mode. - ClassBody() { - classScopes.push(true); - }, - "ClassBody:exit"() { - classScopes.pop(); - }, - - "FunctionDeclaration:exit": exitFunctionInFunctionMode, - "FunctionExpression:exit": exitFunctionInFunctionMode, - "ArrowFunctionExpression:exit": exitFunctionInFunctionMode - }); - } - - return rule; - } -}; - -/** - * @fileoverview Rule to enforce spacing around colons of switch statements. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var switchColonSpacing = { - meta: { - type: "layout", - - docs: { - description: "enforce spacing around colons of switch statements", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/switch-colon-spacing" - }, - - schema: [ - { - type: "object", - properties: { - before: { type: "boolean", default: false }, - after: { type: "boolean", default: true } - }, - additionalProperties: false - } - ], - fixable: "whitespace", - messages: { - expectedBefore: "Expected space(s) before this colon.", - expectedAfter: "Expected space(s) after this colon.", - unexpectedBefore: "Unexpected space(s) before this colon.", - unexpectedAfter: "Unexpected space(s) after this colon." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const options = context.options[0] || {}; - const beforeSpacing = options.before === true; // false by default - const afterSpacing = options.after !== false; // true by default - - /** - * Get the colon token of the given SwitchCase node. - * @param {ASTNode} node The SwitchCase node to get. - * @returns {Token} The colon token of the node. - */ - function getColonToken(node) { - if (node.test) { - return sourceCode.getTokenAfter(node.test, astUtils.isColonToken); - } - return sourceCode.getFirstToken(node, 1); - } - - /** - * Check whether the spacing between the given 2 tokens is valid or not. - * @param {Token} left The left token to check. - * @param {Token} right The right token to check. - * @param {boolean} expected The expected spacing to check. `true` if there should be a space. - * @returns {boolean} `true` if the spacing between the tokens is valid. - */ - function isValidSpacing(left, right, expected) { - return ( - astUtils.isClosingBraceToken(right) || - !astUtils.isTokenOnSameLine(left, right) || - sourceCode.isSpaceBetweenTokens(left, right) === expected - ); - } - - /** - * Check whether comments exist between the given 2 tokens. - * @param {Token} left The left token to check. - * @param {Token} right The right token to check. - * @returns {boolean} `true` if comments exist between the given 2 tokens. - */ - function commentsExistBetween(left, right) { - return sourceCode.getFirstTokenBetween( - left, - right, - { - includeComments: true, - filter: astUtils.isCommentToken - } - ) !== null; - } - - /** - * Fix the spacing between the given 2 tokens. - * @param {RuleFixer} fixer The fixer to fix. - * @param {Token} left The left token of fix range. - * @param {Token} right The right token of fix range. - * @param {boolean} spacing The spacing style. `true` if there should be a space. - * @returns {Fix|null} The fix object. - */ - function fix(fixer, left, right, spacing) { - if (commentsExistBetween(left, right)) { - return null; - } - if (spacing) { - return fixer.insertTextAfter(left, " "); - } - return fixer.removeRange([left.range[1], right.range[0]]); - } - - return { - SwitchCase(node) { - const colonToken = getColonToken(node); - const beforeToken = sourceCode.getTokenBefore(colonToken); - const afterToken = sourceCode.getTokenAfter(colonToken); - - if (!isValidSpacing(beforeToken, colonToken, beforeSpacing)) { - context.report({ - node, - loc: colonToken.loc, - messageId: beforeSpacing ? "expectedBefore" : "unexpectedBefore", - fix: fixer => fix(fixer, beforeToken, colonToken, beforeSpacing) - }); - } - if (!isValidSpacing(colonToken, afterToken, afterSpacing)) { - context.report({ - node, - loc: colonToken.loc, - messageId: afterSpacing ? "expectedAfter" : "unexpectedAfter", - fix: fixer => fix(fixer, colonToken, afterToken, afterSpacing) - }); - } - } - }; - } -}; - -/** - * @fileoverview Rule to enforce description with the `Symbol` object - * @author Jarek Rencz - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - - -var symbolDescription = { - meta: { - type: "suggestion", - - docs: { - description: "require symbol descriptions", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/symbol-description" - }, - fixable: null, - schema: [], - messages: { - expected: "Expected Symbol to have a description." - } - }, - - create(context) { - - /** - * Reports if node does not conform the rule in case rule is set to - * report missing description - * @param {ASTNode} node A CallExpression node to check. - * @returns {void} - */ - function checkArgument(node) { - if (node.arguments.length === 0) { - context.report({ - node, - messageId: "expected" - }); - } - } - - return { - "Program:exit"() { - const scope = context.getScope(); - const variable = astUtils.getVariableByName(scope, "Symbol"); - - if (variable && variable.defs.length === 0) { - variable.references.forEach(reference => { - const node = reference.identifier; - - if (astUtils.isCallee(node)) { - checkArgument(node.parent); - } - }); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to enforce spacing around embedded expressions of template strings - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var templateCurlySpacing = { - meta: { - type: "layout", - - docs: { - description: "require or disallow spacing around embedded expressions of template strings", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/template-curly-spacing" - }, - - fixable: "whitespace", - - schema: [ - { enum: ["always", "never"] } - ], - messages: { - expectedBefore: "Expected space(s) before '}'.", - expectedAfter: "Expected space(s) after '${'.", - unexpectedBefore: "Unexpected space(s) before '}'.", - unexpectedAfter: "Unexpected space(s) after '${'." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - const always = context.options[0] === "always"; - - /** - * Checks spacing before `}` of a given token. - * @param {Token} token A token to check. This is a Template token. - * @returns {void} - */ - function checkSpacingBefore(token) { - if (!token.value.startsWith("}")) { - return; // starts with a backtick, this is the first template element in the template literal - } - - const prevToken = sourceCode.getTokenBefore(token, { includeComments: true }), - hasSpace = sourceCode.isSpaceBetween(prevToken, token); - - if (!astUtils.isTokenOnSameLine(prevToken, token)) { - return; - } - - if (always && !hasSpace) { - context.report({ - loc: { - start: token.loc.start, - end: { - line: token.loc.start.line, - column: token.loc.start.column + 1 - } - }, - messageId: "expectedBefore", - fix: fixer => fixer.insertTextBefore(token, " ") - }); - } - - if (!always && hasSpace) { - context.report({ - loc: { - start: prevToken.loc.end, - end: token.loc.start - }, - messageId: "unexpectedBefore", - fix: fixer => fixer.removeRange([prevToken.range[1], token.range[0]]) - }); - } - } - - /** - * Checks spacing after `${` of a given token. - * @param {Token} token A token to check. This is a Template token. - * @returns {void} - */ - function checkSpacingAfter(token) { - if (!token.value.endsWith("${")) { - return; // ends with a backtick, this is the last template element in the template literal - } - - const nextToken = sourceCode.getTokenAfter(token, { includeComments: true }), - hasSpace = sourceCode.isSpaceBetween(token, nextToken); - - if (!astUtils.isTokenOnSameLine(token, nextToken)) { - return; - } - - if (always && !hasSpace) { - context.report({ - loc: { - start: { - line: token.loc.end.line, - column: token.loc.end.column - 2 - }, - end: token.loc.end - }, - messageId: "expectedAfter", - fix: fixer => fixer.insertTextAfter(token, " ") - }); - } - - if (!always && hasSpace) { - context.report({ - loc: { - start: token.loc.end, - end: nextToken.loc.start - }, - messageId: "unexpectedAfter", - fix: fixer => fixer.removeRange([token.range[1], nextToken.range[0]]) - }); - } - } - - return { - TemplateElement(node) { - const token = sourceCode.getFirstToken(node); - - checkSpacingBefore(token); - checkSpacingAfter(token); - } - }; - } -}; - -/** - * @fileoverview Rule to check spacing between template tags and their literals - * @author Jonathan Wilsson - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var templateTagSpacing = { - meta: { - type: "layout", - - docs: { - description: "require or disallow spacing between template tags and their literals", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/template-tag-spacing" - }, - - fixable: "whitespace", - - schema: [ - { enum: ["always", "never"] } - ], - messages: { - unexpected: "Unexpected space between template tag and template literal.", - missing: "Missing space between template tag and template literal." - } - }, - - create(context) { - const never = context.options[0] !== "always"; - const sourceCode = context.getSourceCode(); - - /** - * Check if a space is present between a template tag and its literal - * @param {ASTNode} node node to evaluate - * @returns {void} - * @private - */ - function checkSpacing(node) { - const tagToken = sourceCode.getTokenBefore(node.quasi); - const literalToken = sourceCode.getFirstToken(node.quasi); - const hasWhitespace = sourceCode.isSpaceBetweenTokens(tagToken, literalToken); - - if (never && hasWhitespace) { - context.report({ - node, - loc: { - start: tagToken.loc.end, - end: literalToken.loc.start - }, - messageId: "unexpected", - fix(fixer) { - const comments = sourceCode.getCommentsBefore(node.quasi); - - // Don't fix anything if there's a single line comment after the template tag - if (comments.some(comment => comment.type === "Line")) { - return null; - } - - return fixer.replaceTextRange( - [tagToken.range[1], literalToken.range[0]], - comments.reduce((text, comment) => text + sourceCode.getText(comment), "") - ); - } - }); - } else if (!never && !hasWhitespace) { - context.report({ - node, - loc: { - start: node.loc.start, - end: literalToken.loc.start - }, - messageId: "missing", - fix(fixer) { - return fixer.insertTextAfter(tagToken, " "); - } - }); - } - } - - return { - TaggedTemplateExpression: checkSpacing - }; - } -}; - -/** - * @fileoverview Require or disallow Unicode BOM - * @author Andrew Johnston - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var unicodeBom = { - meta: { - type: "layout", - - docs: { - description: "require or disallow Unicode byte order mark (BOM)", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/unicode-bom" - }, - - fixable: "whitespace", - - schema: [ - { - enum: ["always", "never"] - } - ], - messages: { - expected: "Expected Unicode BOM (Byte Order Mark).", - unexpected: "Unexpected Unicode BOM (Byte Order Mark)." - } - }, - - create(context) { - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - - Program: function checkUnicodeBOM(node) { - - const sourceCode = context.getSourceCode(), - location = { column: 0, line: 1 }, - requireBOM = context.options[0] || "never"; - - if (!sourceCode.hasBOM && (requireBOM === "always")) { - context.report({ - node, - loc: location, - messageId: "expected", - fix(fixer) { - return fixer.insertTextBeforeRange([0, 1], "\uFEFF"); - } - }); - } else if (sourceCode.hasBOM && (requireBOM === "never")) { - context.report({ - node, - loc: location, - messageId: "unexpected", - fix(fixer) { - return fixer.removeRange([-1, 0]); - } - }); - } - } - - }; - - } -}; - -/** - * @fileoverview Rule to flag comparisons to the value NaN - * @author James Allardice - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Determines if the given node is a NaN `Identifier` node. - * @param {ASTNode|null} node The node to check. - * @returns {boolean} `true` if the node is 'NaN' identifier. - */ -function isNaNIdentifier(node) { - return Boolean(node) && node.type === "Identifier" && node.name === "NaN"; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var useIsnan = { - meta: { - type: "problem", - - docs: { - description: "require calls to `isNaN()` when checking for `NaN`", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/use-isnan" - }, - - schema: [ - { - type: "object", - properties: { - enforceForSwitchCase: { - type: "boolean", - default: true - }, - enforceForIndexOf: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - messages: { - comparisonWithNaN: "Use the isNaN function to compare with NaN.", - switchNaN: "'switch(NaN)' can never match a case clause. Use Number.isNaN instead of the switch.", - caseNaN: "'case NaN' can never match. Use Number.isNaN before the switch.", - indexOfNaN: "Array prototype method '{{ methodName }}' cannot find NaN." - } - }, - - create(context) { - - const enforceForSwitchCase = !context.options[0] || context.options[0].enforceForSwitchCase; - const enforceForIndexOf = context.options[0] && context.options[0].enforceForIndexOf; - - /** - * Checks the given `BinaryExpression` node for `foo === NaN` and other comparisons. - * @param {ASTNode} node The node to check. - * @returns {void} - */ - function checkBinaryExpression(node) { - if ( - /^(?:[<>]|[!=]=)=?$/u.test(node.operator) && - (isNaNIdentifier(node.left) || isNaNIdentifier(node.right)) - ) { - context.report({ node, messageId: "comparisonWithNaN" }); - } - } - - /** - * Checks the discriminant and all case clauses of the given `SwitchStatement` node for `switch(NaN)` and `case NaN:` - * @param {ASTNode} node The node to check. - * @returns {void} - */ - function checkSwitchStatement(node) { - if (isNaNIdentifier(node.discriminant)) { - context.report({ node, messageId: "switchNaN" }); - } - - for (const switchCase of node.cases) { - if (isNaNIdentifier(switchCase.test)) { - context.report({ node: switchCase, messageId: "caseNaN" }); - } - } - } - - /** - * Checks the given `CallExpression` node for `.indexOf(NaN)` and `.lastIndexOf(NaN)`. - * @param {ASTNode} node The node to check. - * @returns {void} - */ - function checkCallExpression(node) { - const callee = astUtils.skipChainExpression(node.callee); - - if (callee.type === "MemberExpression") { - const methodName = astUtils.getStaticPropertyName(callee); - - if ( - (methodName === "indexOf" || methodName === "lastIndexOf") && - node.arguments.length === 1 && - isNaNIdentifier(node.arguments[0]) - ) { - context.report({ node, messageId: "indexOfNaN", data: { methodName } }); - } - } - } - - const listeners = { - BinaryExpression: checkBinaryExpression - }; - - if (enforceForSwitchCase) { - listeners.SwitchStatement = checkSwitchStatement; - } - - if (enforceForIndexOf) { - listeners.CallExpression = checkCallExpression; - } - - return listeners; - } -}; - -/** - * @fileoverview Validates JSDoc comments are syntactically correct - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var validJsdoc = { - meta: { - type: "suggestion", - - docs: { - description: "enforce valid JSDoc comments", - category: "Possible Errors", - recommended: false, - url: "https://eslint.org/docs/rules/valid-jsdoc" - }, - - schema: [ - { - type: "object", - properties: { - prefer: { - type: "object", - additionalProperties: { - type: "string" - } - }, - preferType: { - type: "object", - additionalProperties: { - type: "string" - } - }, - requireReturn: { - type: "boolean", - default: true - }, - requireParamDescription: { - type: "boolean", - default: true - }, - requireReturnDescription: { - type: "boolean", - default: true - }, - matchDescription: { - type: "string" - }, - requireReturnType: { - type: "boolean", - default: true - }, - requireParamType: { - type: "boolean", - default: true - } - }, - additionalProperties: false - } - ], - - fixable: "code", - messages: { - unexpectedTag: "Unexpected @{{title}} tag; function has no return statement.", - expected: "Expected JSDoc for '{{name}}' but found '{{jsdocName}}'.", - use: "Use @{{name}} instead.", - useType: "Use '{{expectedTypeName}}' instead of '{{currentTypeName}}'.", - syntaxError: "JSDoc syntax error.", - missingBrace: "JSDoc type missing brace.", - missingParamDesc: "Missing JSDoc parameter description for '{{name}}'.", - missingParamType: "Missing JSDoc parameter type for '{{name}}'.", - missingReturnType: "Missing JSDoc return type.", - missingReturnDesc: "Missing JSDoc return description.", - missingReturn: "Missing JSDoc @{{returns}} for function.", - missingParam: "Missing JSDoc for parameter '{{name}}'.", - duplicateParam: "Duplicate JSDoc parameter '{{name}}'.", - unsatisfiedDesc: "JSDoc description does not satisfy the regex pattern." - }, - - deprecated: true, - replacedBy: [] - }, - - create(context) { - - const options = context.options[0] || {}, - prefer = options.prefer || {}, - sourceCode = context.getSourceCode(), - - // these both default to true, so you have to explicitly make them false - requireReturn = options.requireReturn !== false, - requireParamDescription = options.requireParamDescription !== false, - requireReturnDescription = options.requireReturnDescription !== false, - requireReturnType = options.requireReturnType !== false, - requireParamType = options.requireParamType !== false, - preferType = options.preferType || {}, - checkPreferType = Object.keys(preferType).length !== 0; - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - // Using a stack to store if a function returns or not (handling nested functions) - const fns = []; - - /** - * Check if node type is a Class - * @param {ASTNode} node node to check. - * @returns {boolean} True is its a class - * @private - */ - function isTypeClass(node) { - return node.type === "ClassExpression" || node.type === "ClassDeclaration"; - } - - /** - * When parsing a new function, store it in our function stack. - * @param {ASTNode} node A function node to check. - * @returns {void} - * @private - */ - function startFunction(node) { - fns.push({ - returnPresent: (node.type === "ArrowFunctionExpression" && node.body.type !== "BlockStatement") || - isTypeClass(node) || node.async - }); - } - - /** - * Indicate that return has been found in the current function. - * @param {ASTNode} node The return node. - * @returns {void} - * @private - */ - function addReturn(node) { - const functionState = fns[fns.length - 1]; - - if (functionState && node.argument !== null) { - functionState.returnPresent = true; - } - } - - /** - * Check if return tag type is void or undefined - * @param {Object} tag JSDoc tag - * @returns {boolean} True if its of type void or undefined - * @private - */ - function isValidReturnType(tag) { - return tag.type === null || tag.type.name === "void" || tag.type.type === "UndefinedLiteral"; - } - - /** - * Check if type should be validated based on some exceptions - * @param {Object} type JSDoc tag - * @returns {boolean} True if it can be validated - * @private - */ - function canTypeBeValidated(type) { - return type !== "UndefinedLiteral" && // {undefined} as there is no name property available. - type !== "NullLiteral" && // {null} - type !== "NullableLiteral" && // {?} - type !== "FunctionType" && // {function(a)} - type !== "AllLiteral"; // {*} - } - - /** - * Extract the current and expected type based on the input type object - * @param {Object} type JSDoc tag - * @returns {{currentType: Doctrine.Type, expectedTypeName: string}} The current type annotation and - * the expected name of the annotation - * @private - */ - function getCurrentExpectedTypes(type) { - let currentType; - - if (type.name) { - currentType = type; - } else if (type.expression) { - currentType = type.expression; - } - - return { - currentType, - expectedTypeName: currentType && preferType[currentType.name] - }; - } - - /** - * Gets the location of a JSDoc node in a file - * @param {Token} jsdocComment The comment that this node is parsed from - * @param {{range: number[]}} parsedJsdocNode A tag or other node which was parsed from this comment - * @returns {{start: SourceLocation, end: SourceLocation}} The 0-based source location for the tag - */ - function getAbsoluteRange(jsdocComment, parsedJsdocNode) { - return { - start: sourceCode.getLocFromIndex(jsdocComment.range[0] + 2 + parsedJsdocNode.range[0]), - end: sourceCode.getLocFromIndex(jsdocComment.range[0] + 2 + parsedJsdocNode.range[1]) - }; - } - - /** - * Validate type for a given JSDoc node - * @param {Object} jsdocNode JSDoc node - * @param {Object} type JSDoc tag - * @returns {void} - * @private - */ - function validateType(jsdocNode, type) { - if (!type || !canTypeBeValidated(type.type)) { - return; - } - - const typesToCheck = []; - let elements = []; - - switch (type.type) { - case "TypeApplication": // {Array.} - elements = type.applications[0].type === "UnionType" ? type.applications[0].elements : type.applications; - typesToCheck.push(getCurrentExpectedTypes(type)); - break; - case "RecordType": // {{20:String}} - elements = type.fields; - break; - case "UnionType": // {String|number|Test} - case "ArrayType": // {[String, number, Test]} - elements = type.elements; - break; - case "FieldType": // Array.<{count: number, votes: number}> - if (type.value) { - typesToCheck.push(getCurrentExpectedTypes(type.value)); - } - break; - default: - typesToCheck.push(getCurrentExpectedTypes(type)); - } - - elements.forEach(validateType.bind(null, jsdocNode)); - - typesToCheck.forEach(typeToCheck => { - if (typeToCheck.expectedTypeName && - typeToCheck.expectedTypeName !== typeToCheck.currentType.name) { - context.report({ - node: jsdocNode, - messageId: "useType", - loc: getAbsoluteRange(jsdocNode, typeToCheck.currentType), - data: { - currentTypeName: typeToCheck.currentType.name, - expectedTypeName: typeToCheck.expectedTypeName - }, - fix(fixer) { - return fixer.replaceTextRange( - typeToCheck.currentType.range.map(indexInComment => jsdocNode.range[0] + 2 + indexInComment), - typeToCheck.expectedTypeName - ); - } - }); - } - }); - } - - /** - * Validate the JSDoc node and output warnings if anything is wrong. - * @param {ASTNode} node The AST node to check. - * @returns {void} - * @private - */ - function checkJSDoc(node) { - const jsdocNode = sourceCode.getJSDocComment(node), - functionData = fns.pop(), - paramTagsByName = Object.create(null), - paramTags = []; - let hasReturns = false, - returnsTag, - hasConstructor = false, - isInterface = false, - isOverride = false, - isAbstract = false; - - // make sure only to validate JSDoc comments - if (jsdocNode) { - let jsdoc; - - try { - jsdoc = doctrine__default['default'].parse(jsdocNode.value, { - strict: true, - unwrap: true, - sloppy: true, - range: true - }); - } catch (ex) { - - if (/braces/iu.test(ex.message)) { - context.report({ node: jsdocNode, messageId: "missingBrace" }); - } else { - context.report({ node: jsdocNode, messageId: "syntaxError" }); - } - - return; - } - - jsdoc.tags.forEach(tag => { - - switch (tag.title.toLowerCase()) { - - case "param": - case "arg": - case "argument": - paramTags.push(tag); - break; - - case "return": - case "returns": - hasReturns = true; - returnsTag = tag; - break; - - case "constructor": - case "class": - hasConstructor = true; - break; - - case "override": - case "inheritdoc": - isOverride = true; - break; - - case "abstract": - case "virtual": - isAbstract = true; - break; - - case "interface": - isInterface = true; - break; - - // no default - } - - // check tag preferences - if (Object.prototype.hasOwnProperty.call(prefer, tag.title) && tag.title !== prefer[tag.title]) { - const entireTagRange = getAbsoluteRange(jsdocNode, tag); - - context.report({ - node: jsdocNode, - messageId: "use", - loc: { - start: entireTagRange.start, - end: { - line: entireTagRange.start.line, - column: entireTagRange.start.column + `@${tag.title}`.length - } - }, - data: { name: prefer[tag.title] }, - fix(fixer) { - return fixer.replaceTextRange( - [ - jsdocNode.range[0] + tag.range[0] + 3, - jsdocNode.range[0] + tag.range[0] + tag.title.length + 3 - ], - prefer[tag.title] - ); - } - }); - } - - // validate the types - if (checkPreferType && tag.type) { - validateType(jsdocNode, tag.type); - } - }); - - paramTags.forEach(param => { - if (requireParamType && !param.type) { - context.report({ - node: jsdocNode, - messageId: "missingParamType", - loc: getAbsoluteRange(jsdocNode, param), - data: { name: param.name } - }); - } - if (!param.description && requireParamDescription) { - context.report({ - node: jsdocNode, - messageId: "missingParamDesc", - loc: getAbsoluteRange(jsdocNode, param), - data: { name: param.name } - }); - } - if (paramTagsByName[param.name]) { - context.report({ - node: jsdocNode, - messageId: "duplicateParam", - loc: getAbsoluteRange(jsdocNode, param), - data: { name: param.name } - }); - } else if (param.name.indexOf(".") === -1) { - paramTagsByName[param.name] = param; - } - }); - - if (hasReturns) { - if (!requireReturn && !functionData.returnPresent && (returnsTag.type === null || !isValidReturnType(returnsTag)) && !isAbstract) { - context.report({ - node: jsdocNode, - messageId: "unexpectedTag", - loc: getAbsoluteRange(jsdocNode, returnsTag), - data: { - title: returnsTag.title - } - }); - } else { - if (requireReturnType && !returnsTag.type) { - context.report({ node: jsdocNode, messageId: "missingReturnType" }); - } - - if (!isValidReturnType(returnsTag) && !returnsTag.description && requireReturnDescription) { - context.report({ node: jsdocNode, messageId: "missingReturnDesc" }); - } - } - } - - // check for functions missing @returns - if (!isOverride && !hasReturns && !hasConstructor && !isInterface && - node.parent.kind !== "get" && node.parent.kind !== "constructor" && - node.parent.kind !== "set" && !isTypeClass(node)) { - if (requireReturn || (functionData.returnPresent && !node.async)) { - context.report({ - node: jsdocNode, - messageId: "missingReturn", - data: { - returns: prefer.returns || "returns" - } - }); - } - } - - // check the parameters - const jsdocParamNames = Object.keys(paramTagsByName); - - if (node.params) { - node.params.forEach((param, paramsIndex) => { - const bindingParam = param.type === "AssignmentPattern" - ? param.left - : param; - - // TODO(nzakas): Figure out logical things to do with destructured, default, rest params - if (bindingParam.type === "Identifier") { - const name = bindingParam.name; - - if (jsdocParamNames[paramsIndex] && (name !== jsdocParamNames[paramsIndex])) { - context.report({ - node: jsdocNode, - messageId: "expected", - loc: getAbsoluteRange(jsdocNode, paramTagsByName[jsdocParamNames[paramsIndex]]), - data: { - name, - jsdocName: jsdocParamNames[paramsIndex] - } - }); - } else if (!paramTagsByName[name] && !isOverride) { - context.report({ - node: jsdocNode, - messageId: "missingParam", - data: { - name - } - }); - } - } - }); - } - - if (options.matchDescription) { - const regex = new RegExp(options.matchDescription, "u"); - - if (!regex.test(jsdoc.description)) { - context.report({ node: jsdocNode, messageId: "unsatisfiedDesc" }); - } - } - - } - - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - ArrowFunctionExpression: startFunction, - FunctionExpression: startFunction, - FunctionDeclaration: startFunction, - ClassExpression: startFunction, - ClassDeclaration: startFunction, - "ArrowFunctionExpression:exit": checkJSDoc, - "FunctionExpression:exit": checkJSDoc, - "FunctionDeclaration:exit": checkJSDoc, - "ClassExpression:exit": checkJSDoc, - "ClassDeclaration:exit": checkJSDoc, - ReturnStatement: addReturn - }; - - } -}; - -/** - * @fileoverview Ensures that the results of typeof are compared against a valid string - * @author Ian Christian Myers - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var validTypeof = { - meta: { - type: "problem", - - docs: { - description: "enforce comparing `typeof` expressions against valid strings", - category: "Possible Errors", - recommended: true, - url: "https://eslint.org/docs/rules/valid-typeof" - }, - - schema: [ - { - type: "object", - properties: { - requireStringLiterals: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - messages: { - invalidValue: "Invalid typeof comparison value.", - notString: "Typeof comparisons should be to string literals." - } - }, - - create(context) { - - const VALID_TYPES = ["symbol", "undefined", "object", "boolean", "number", "string", "function", "bigint"], - OPERATORS = ["==", "===", "!=", "!=="]; - - const requireStringLiterals = context.options[0] && context.options[0].requireStringLiterals; - - /** - * Determines whether a node is a typeof expression. - * @param {ASTNode} node The node - * @returns {boolean} `true` if the node is a typeof expression - */ - function isTypeofExpression(node) { - return node.type === "UnaryExpression" && node.operator === "typeof"; - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - - UnaryExpression(node) { - if (isTypeofExpression(node)) { - const parent = context.getAncestors().pop(); - - if (parent.type === "BinaryExpression" && OPERATORS.indexOf(parent.operator) !== -1) { - const sibling = parent.left === node ? parent.right : parent.left; - - if (sibling.type === "Literal" || sibling.type === "TemplateLiteral" && !sibling.expressions.length) { - const value = sibling.type === "Literal" ? sibling.value : sibling.quasis[0].value.cooked; - - if (VALID_TYPES.indexOf(value) === -1) { - context.report({ node: sibling, messageId: "invalidValue" }); - } - } else if (requireStringLiterals && !isTypeofExpression(sibling)) { - context.report({ node: sibling, messageId: "notString" }); - } - } - } - } - - }; - - } -}; - -/** - * @fileoverview Rule to enforce var declarations are only at the top of a function. - * @author Danny Fritz - * @author Gyandeep Singh - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var varsOnTop = { - meta: { - type: "suggestion", - - docs: { - description: "require `var` declarations be placed at the top of their containing scope", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/vars-on-top" - }, - - schema: [], - messages: { - top: "All 'var' declarations must be at the top of the function scope." - } - }, - - create(context) { - - //-------------------------------------------------------------------------- - // Helpers - //-------------------------------------------------------------------------- - - // eslint-disable-next-line jsdoc/require-description - /** - * @param {ASTNode} node any node - * @returns {boolean} whether the given node structurally represents a directive - */ - function looksLikeDirective(node) { - return node.type === "ExpressionStatement" && - node.expression.type === "Literal" && typeof node.expression.value === "string"; - } - - /** - * Check to see if its a ES6 import declaration - * @param {ASTNode} node any node - * @returns {boolean} whether the given node represents a import declaration - */ - function looksLikeImport(node) { - return node.type === "ImportDeclaration" || node.type === "ImportSpecifier" || - node.type === "ImportDefaultSpecifier" || node.type === "ImportNamespaceSpecifier"; - } - - /** - * Checks whether a given node is a variable declaration or not. - * @param {ASTNode} node any node - * @returns {boolean} `true` if the node is a variable declaration. - */ - function isVariableDeclaration(node) { - return ( - node.type === "VariableDeclaration" || - ( - node.type === "ExportNamedDeclaration" && - node.declaration && - node.declaration.type === "VariableDeclaration" - ) - ); - } - - /** - * Checks whether this variable is on top of the block body - * @param {ASTNode} node The node to check - * @param {ASTNode[]} statements collection of ASTNodes for the parent node block - * @returns {boolean} True if var is on top otherwise false - */ - function isVarOnTop(node, statements) { - const l = statements.length; - let i = 0; - - // skip over directives - for (; i < l; ++i) { - if (!looksLikeDirective(statements[i]) && !looksLikeImport(statements[i])) { - break; - } - } - - for (; i < l; ++i) { - if (!isVariableDeclaration(statements[i])) { - return false; - } - if (statements[i] === node) { - return true; - } - } - - return false; - } - - /** - * Checks whether variable is on top at the global level - * @param {ASTNode} node The node to check - * @param {ASTNode} parent Parent of the node - * @returns {void} - */ - function globalVarCheck(node, parent) { - if (!isVarOnTop(node, parent.body)) { - context.report({ node, messageId: "top" }); - } - } - - /** - * Checks whether variable is on top at functional block scope level - * @param {ASTNode} node The node to check - * @param {ASTNode} parent Parent of the node - * @param {ASTNode} grandParent Parent of the node's parent - * @returns {void} - */ - function blockScopeVarCheck(node, parent, grandParent) { - if (!(/Function/u.test(grandParent.type) && - parent.type === "BlockStatement" && - isVarOnTop(node, parent.body))) { - context.report({ node, messageId: "top" }); - } - } - - //-------------------------------------------------------------------------- - // Public API - //-------------------------------------------------------------------------- - - return { - "VariableDeclaration[kind='var']"(node) { - if (node.parent.type === "ExportNamedDeclaration") { - globalVarCheck(node.parent, node.parent.parent); - } else if (node.parent.type === "Program") { - globalVarCheck(node, node.parent); - } else { - blockScopeVarCheck(node, node.parent, node.parent.parent); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag when IIFE is not wrapped in parens - * @author Ilya Volodin - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//---------------------------------------------------------------------- -// Helpers -//---------------------------------------------------------------------- - -/** - * Check if the given node is callee of a `NewExpression` node - * @param {ASTNode} node node to check - * @returns {boolean} True if the node is callee of a `NewExpression` node - * @private - */ -function isCalleeOfNewExpression(node) { - const maybeCallee = node.parent.type === "ChainExpression" - ? node.parent - : node; - - return ( - maybeCallee.parent.type === "NewExpression" && - maybeCallee.parent.callee === maybeCallee - ); -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var wrapIife = { - meta: { - type: "layout", - - docs: { - description: "require parentheses around immediate `function` invocations", - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/wrap-iife" - }, - - schema: [ - { - enum: ["outside", "inside", "any"] - }, - { - type: "object", - properties: { - functionPrototypeMethods: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - fixable: "code", - messages: { - wrapInvocation: "Wrap an immediate function invocation in parentheses.", - wrapExpression: "Wrap only the function expression in parens.", - moveInvocation: "Move the invocation into the parens that contain the function." - } - }, - - create(context) { - - const style = context.options[0] || "outside"; - const includeFunctionPrototypeMethods = context.options[1] && context.options[1].functionPrototypeMethods; - - const sourceCode = context.getSourceCode(); - - /** - * Check if the node is wrapped in any (). All parens count: grouping parens and parens for constructs such as if() - * @param {ASTNode} node node to evaluate - * @returns {boolean} True if it is wrapped in any parens - * @private - */ - function isWrappedInAnyParens(node) { - return astUtils.isParenthesised(sourceCode, node); - } - - /** - * Check if the node is wrapped in grouping (). Parens for constructs such as if() don't count - * @param {ASTNode} node node to evaluate - * @returns {boolean} True if it is wrapped in grouping parens - * @private - */ - function isWrappedInGroupingParens(node) { - return require$$0__default$1['default'].isParenthesized(1, node, sourceCode); - } - - /** - * Get the function node from an IIFE - * @param {ASTNode} node node to evaluate - * @returns {ASTNode} node that is the function expression of the given IIFE, or null if none exist - */ - function getFunctionNodeFromIIFE(node) { - const callee = astUtils.skipChainExpression(node.callee); - - if (callee.type === "FunctionExpression") { - return callee; - } - - if (includeFunctionPrototypeMethods && - callee.type === "MemberExpression" && - callee.object.type === "FunctionExpression" && - (astUtils.getStaticPropertyName(callee) === "call" || astUtils.getStaticPropertyName(callee) === "apply") - ) { - return callee.object; - } - - return null; - } - - - return { - CallExpression(node) { - const innerNode = getFunctionNodeFromIIFE(node); - - if (!innerNode) { - return; - } - - const isCallExpressionWrapped = isWrappedInAnyParens(node), - isFunctionExpressionWrapped = isWrappedInAnyParens(innerNode); - - if (!isCallExpressionWrapped && !isFunctionExpressionWrapped) { - context.report({ - node, - messageId: "wrapInvocation", - fix(fixer) { - const nodeToSurround = style === "inside" ? innerNode : node; - - return fixer.replaceText(nodeToSurround, `(${sourceCode.getText(nodeToSurround)})`); - } - }); - } else if (style === "inside" && !isFunctionExpressionWrapped) { - context.report({ - node, - messageId: "wrapExpression", - fix(fixer) { - - // The outer call expression will always be wrapped at this point. - - if (isWrappedInGroupingParens(node) && !isCalleeOfNewExpression(node)) { - - /* - * Parenthesize the function expression and remove unnecessary grouping parens around the call expression. - * Replace the range between the end of the function expression and the end of the call expression. - * for example, in `(function(foo) {}(bar))`, the range `(bar))` should get replaced with `)(bar)`. - */ - - const parenAfter = sourceCode.getTokenAfter(node); - - return fixer.replaceTextRange( - [innerNode.range[1], parenAfter.range[1]], - `)${sourceCode.getText().slice(innerNode.range[1], parenAfter.range[0])}` - ); - } - - /* - * Call expression is wrapped in mandatory parens such as if(), or in necessary grouping parens. - * These parens cannot be removed, so just parenthesize the function expression. - */ - - return fixer.replaceText(innerNode, `(${sourceCode.getText(innerNode)})`); - } - }); - } else if (style === "outside" && !isCallExpressionWrapped) { - context.report({ - node, - messageId: "moveInvocation", - fix(fixer) { - - /* - * The inner function expression will always be wrapped at this point. - * It's only necessary to replace the range between the end of the function expression - * and the call expression. For example, in `(function(foo) {})(bar)`, the range `)(bar)` - * should get replaced with `(bar))`. - */ - const parenAfter = sourceCode.getTokenAfter(innerNode); - - return fixer.replaceTextRange( - [parenAfter.range[0], node.range[1]], - `${sourceCode.getText().slice(parenAfter.range[1], node.range[1])})` - ); - } - }); - } - } - }; - - } -}; - -/** - * @fileoverview Rule to flag when regex literals are not wrapped in parens - * @author Matt DuVall - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var wrapRegex = { - meta: { - type: "layout", - - docs: { - description: "require parenthesis around regex literals", - category: "Stylistic Issues", - recommended: false, - url: "https://eslint.org/docs/rules/wrap-regex" - }, - - schema: [], - fixable: "code", - - messages: { - requireParens: "Wrap the regexp literal in parens to disambiguate the slash." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - return { - - Literal(node) { - const token = sourceCode.getFirstToken(node), - nodeType = token.type; - - if (nodeType === "RegularExpression") { - const beforeToken = sourceCode.getTokenBefore(node); - const afterToken = sourceCode.getTokenAfter(node); - const ancestors = context.getAncestors(); - const grandparent = ancestors[ancestors.length - 1]; - - if (grandparent.type === "MemberExpression" && grandparent.object === node && - !(beforeToken && beforeToken.value === "(" && afterToken && afterToken.value === ")")) { - context.report({ - node, - messageId: "requireParens", - fix: fixer => fixer.replaceText(node, `(${sourceCode.getText(node)})`) - }); - } - } - } - }; - - } -}; - -/** - * @fileoverview Rule to check the spacing around the * in yield* expressions. - * @author Bryan Smith - */ - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var yieldStarSpacing = { - meta: { - type: "layout", - - docs: { - description: "require or disallow spacing around the `*` in `yield*` expressions", - category: "ECMAScript 6", - recommended: false, - url: "https://eslint.org/docs/rules/yield-star-spacing" - }, - - fixable: "whitespace", - - schema: [ - { - oneOf: [ - { - enum: ["before", "after", "both", "neither"] - }, - { - type: "object", - properties: { - before: { type: "boolean" }, - after: { type: "boolean" } - }, - additionalProperties: false - } - ] - } - ], - messages: { - missingBefore: "Missing space before *.", - missingAfter: "Missing space after *.", - unexpectedBefore: "Unexpected space before *.", - unexpectedAfter: "Unexpected space after *." - } - }, - - create(context) { - const sourceCode = context.getSourceCode(); - - const mode = (function(option) { - if (!option || typeof option === "string") { - return { - before: { before: true, after: false }, - after: { before: false, after: true }, - both: { before: true, after: true }, - neither: { before: false, after: false } - }[option || "after"]; - } - return option; - }(context.options[0])); - - /** - * Checks the spacing between two tokens before or after the star token. - * @param {string} side Either "before" or "after". - * @param {Token} leftToken `function` keyword token if side is "before", or - * star token if side is "after". - * @param {Token} rightToken Star token if side is "before", or identifier - * token if side is "after". - * @returns {void} - */ - function checkSpacing(side, leftToken, rightToken) { - if (sourceCode.isSpaceBetweenTokens(leftToken, rightToken) !== mode[side]) { - const after = leftToken.value === "*"; - const spaceRequired = mode[side]; - const node = after ? leftToken : rightToken; - let messageId = ""; - - if (spaceRequired) { - messageId = side === "before" ? "missingBefore" : "missingAfter"; - } else { - messageId = side === "before" ? "unexpectedBefore" : "unexpectedAfter"; - } - - context.report({ - node, - messageId, - fix(fixer) { - if (spaceRequired) { - if (after) { - return fixer.insertTextAfter(node, " "); - } - return fixer.insertTextBefore(node, " "); - } - return fixer.removeRange([leftToken.range[1], rightToken.range[0]]); - } - }); - } - } - - /** - * Enforces the spacing around the star if node is a yield* expression. - * @param {ASTNode} node A yield expression node. - * @returns {void} - */ - function checkExpression(node) { - if (!node.delegate) { - return; - } - - const tokens = sourceCode.getFirstTokens(node, 3); - const yieldToken = tokens[0]; - const starToken = tokens[1]; - const nextToken = tokens[2]; - - checkSpacing("before", yieldToken, starToken); - checkSpacing("after", starToken, nextToken); - } - - return { - YieldExpression: checkExpression - }; - - } -}; - -/** - * @fileoverview Rule to require or disallow yoda comparisons - * @author Nicholas C. Zakas - */ - -//-------------------------------------------------------------------------- -// Requirements -//-------------------------------------------------------------------------- - - - -//-------------------------------------------------------------------------- -// Helpers -//-------------------------------------------------------------------------- - -/** - * Determines whether an operator is a comparison operator. - * @param {string} operator The operator to check. - * @returns {boolean} Whether or not it is a comparison operator. - */ -function isComparisonOperator(operator) { - return /^(==|===|!=|!==|<|>|<=|>=)$/u.test(operator); -} - -/** - * Determines whether an operator is an equality operator. - * @param {string} operator The operator to check. - * @returns {boolean} Whether or not it is an equality operator. - */ -function isEqualityOperator(operator) { - return /^(==|===)$/u.test(operator); -} - -/** - * Determines whether an operator is one used in a range test. - * Allowed operators are `<` and `<=`. - * @param {string} operator The operator to check. - * @returns {boolean} Whether the operator is used in range tests. - */ -function isRangeTestOperator(operator) { - return ["<", "<="].indexOf(operator) >= 0; -} - -/** - * Determines whether a non-Literal node is a negative number that should be - * treated as if it were a single Literal node. - * @param {ASTNode} node Node to test. - * @returns {boolean} True if the node is a negative number that looks like a - * real literal and should be treated as such. - */ -function isNegativeNumericLiteral(node) { - return ( - node.type === "UnaryExpression" && - node.operator === "-" && - node.prefix && - astUtils.isNumericLiteral(node.argument) - ); -} - -/** - * Determines whether a node is a Template Literal which can be determined statically. - * @param {ASTNode} node Node to test - * @returns {boolean} True if the node is a Template Literal without expression. - */ -function isStaticTemplateLiteral(node) { - return node.type === "TemplateLiteral" && node.expressions.length === 0; -} - -/** - * Determines whether a non-Literal node should be treated as a single Literal node. - * @param {ASTNode} node Node to test - * @returns {boolean} True if the node should be treated as a single Literal node. - */ -function looksLikeLiteral(node) { - return isNegativeNumericLiteral(node) || isStaticTemplateLiteral(node); -} - -/** - * Attempts to derive a Literal node from nodes that are treated like literals. - * @param {ASTNode} node Node to normalize. - * @returns {ASTNode} One of the following options. - * 1. The original node if the node is already a Literal - * 2. A normalized Literal node with the negative number as the value if the - * node represents a negative number literal. - * 3. A normalized Literal node with the string as the value if the node is - * a Template Literal without expression. - * 4. Otherwise `null`. - */ -function getNormalizedLiteral(node) { - if (node.type === "Literal") { - return node; - } - - if (isNegativeNumericLiteral(node)) { - return { - type: "Literal", - value: -node.argument.value, - raw: `-${node.argument.value}` - }; - } - - if (isStaticTemplateLiteral(node)) { - return { - type: "Literal", - value: node.quasis[0].value.cooked, - raw: node.quasis[0].value.raw - }; - } - - return null; -} - -//------------------------------------------------------------------------------ -// Rule Definition -//------------------------------------------------------------------------------ - -var yoda = { - meta: { - type: "suggestion", - - docs: { - description: 'require or disallow "Yoda" conditions', - category: "Best Practices", - recommended: false, - url: "https://eslint.org/docs/rules/yoda" - }, - - schema: [ - { - enum: ["always", "never"] - }, - { - type: "object", - properties: { - exceptRange: { - type: "boolean", - default: false - }, - onlyEquality: { - type: "boolean", - default: false - } - }, - additionalProperties: false - } - ], - - fixable: "code", - messages: { - expected: - "Expected literal to be on the {{expectedSide}} side of {{operator}}." - } - }, - - create(context) { - - // Default to "never" (!always) if no option - const always = context.options[0] === "always"; - const exceptRange = - context.options[1] && context.options[1].exceptRange; - const onlyEquality = - context.options[1] && context.options[1].onlyEquality; - - const sourceCode = context.getSourceCode(); - - /** - * Determines whether node represents a range test. - * A range test is a "between" test like `(0 <= x && x < 1)` or an "outside" - * test like `(x < 0 || 1 <= x)`. It must be wrapped in parentheses, and - * both operators must be `<` or `<=`. Finally, the literal on the left side - * must be less than or equal to the literal on the right side so that the - * test makes any sense. - * @param {ASTNode} node LogicalExpression node to test. - * @returns {boolean} Whether node is a range test. - */ - function isRangeTest(node) { - const left = node.left, - right = node.right; - - /** - * Determines whether node is of the form `0 <= x && x < 1`. - * @returns {boolean} Whether node is a "between" range test. - */ - function isBetweenTest() { - if (node.operator === "&&" && astUtils.isSameReference(left.right, right.left)) { - const leftLiteral = getNormalizedLiteral(left.left); - const rightLiteral = getNormalizedLiteral(right.right); - - if (leftLiteral === null && rightLiteral === null) { - return false; - } - - if (rightLiteral === null || leftLiteral === null) { - return true; - } - - if (leftLiteral.value <= rightLiteral.value) { - return true; - } - } - return false; - } - - /** - * Determines whether node is of the form `x < 0 || 1 <= x`. - * @returns {boolean} Whether node is an "outside" range test. - */ - function isOutsideTest() { - if (node.operator === "||" && astUtils.isSameReference(left.left, right.right)) { - const leftLiteral = getNormalizedLiteral(left.right); - const rightLiteral = getNormalizedLiteral(right.left); - - if (leftLiteral === null && rightLiteral === null) { - return false; - } - - if (rightLiteral === null || leftLiteral === null) { - return true; - } - - if (leftLiteral.value <= rightLiteral.value) { - return true; - } - } - - return false; - } - - /** - * Determines whether node is wrapped in parentheses. - * @returns {boolean} Whether node is preceded immediately by an open - * paren token and followed immediately by a close - * paren token. - */ - function isParenWrapped() { - return astUtils.isParenthesised(sourceCode, node); - } - - return ( - node.type === "LogicalExpression" && - left.type === "BinaryExpression" && - right.type === "BinaryExpression" && - isRangeTestOperator(left.operator) && - isRangeTestOperator(right.operator) && - (isBetweenTest() || isOutsideTest()) && - isParenWrapped() - ); - } - - const OPERATOR_FLIP_MAP = { - "===": "===", - "!==": "!==", - "==": "==", - "!=": "!=", - "<": ">", - ">": "<", - "<=": ">=", - ">=": "<=" - }; - - /** - * Returns a string representation of a BinaryExpression node with its sides/operator flipped around. - * @param {ASTNode} node The BinaryExpression node - * @returns {string} A string representation of the node with the sides and operator flipped - */ - function getFlippedString(node) { - const operatorToken = sourceCode.getFirstTokenBetween( - node.left, - node.right, - token => token.value === node.operator - ); - const lastLeftToken = sourceCode.getTokenBefore(operatorToken); - const firstRightToken = sourceCode.getTokenAfter(operatorToken); - - const source = sourceCode.getText(); - - const leftText = source.slice( - node.range[0], - lastLeftToken.range[1] - ); - const textBeforeOperator = source.slice( - lastLeftToken.range[1], - operatorToken.range[0] - ); - const textAfterOperator = source.slice( - operatorToken.range[1], - firstRightToken.range[0] - ); - const rightText = source.slice( - firstRightToken.range[0], - node.range[1] - ); - - const tokenBefore = sourceCode.getTokenBefore(node); - const tokenAfter = sourceCode.getTokenAfter(node); - let prefix = ""; - let suffix = ""; - - if ( - tokenBefore && - tokenBefore.range[1] === node.range[0] && - !astUtils.canTokensBeAdjacent(tokenBefore, firstRightToken) - ) { - prefix = " "; - } - - if ( - tokenAfter && - node.range[1] === tokenAfter.range[0] && - !astUtils.canTokensBeAdjacent(lastLeftToken, tokenAfter) - ) { - suffix = " "; - } - - return ( - prefix + - rightText + - textBeforeOperator + - OPERATOR_FLIP_MAP[operatorToken.value] + - textAfterOperator + - leftText + - suffix - ); - } - - //-------------------------------------------------------------------------- - // Public - //-------------------------------------------------------------------------- - - return { - BinaryExpression(node) { - const expectedLiteral = always ? node.left : node.right; - const expectedNonLiteral = always ? node.right : node.left; - - // If `expectedLiteral` is not a literal, and `expectedNonLiteral` is a literal, raise an error. - if ( - (expectedNonLiteral.type === "Literal" || - looksLikeLiteral(expectedNonLiteral)) && - !( - expectedLiteral.type === "Literal" || - looksLikeLiteral(expectedLiteral) - ) && - !(!isEqualityOperator(node.operator) && onlyEquality) && - isComparisonOperator(node.operator) && - !(exceptRange && isRangeTest(context.getAncestors().pop())) - ) { - context.report({ - node, - messageId: "expected", - data: { - operator: node.operator, - expectedSide: always ? "left" : "right" - }, - fix: fixer => - fixer.replaceText(node, getFlippedString(node)) - }); - } - } - }; - } -}; - -/** - * @fileoverview Collects the built-in rules into a map structure so that they can be imported all at once and without - * using the file-system directly. - * @author Peter (Somogyvari) Metz - */ - -/* eslint sort-keys: ["error", "asc"] */ - -const { LazyLoadingRuleMap } = lazyLoadingRuleMap; - -/** @type {Map} */ -var rules$2 = new LazyLoadingRuleMap(Object.entries({ - "accessor-pairs": () => accessorPairs, - "array-bracket-newline": () => arrayBracketNewline, - "array-bracket-spacing": () => arrayBracketSpacing, - "array-callback-return": () => arrayCallbackReturn, - "array-element-newline": () => arrayElementNewline, - "arrow-body-style": () => arrowBodyStyle, - "arrow-parens": () => arrowParens, - "arrow-spacing": () => arrowSpacing, - "block-scoped-var": () => blockScopedVar, - "block-spacing": () => blockSpacing, - "brace-style": () => braceStyle, - "callback-return": () => callbackReturn, - camelcase: () => camelcase, - "capitalized-comments": () => capitalizedComments, - "class-methods-use-this": () => classMethodsUseThis, - "comma-dangle": () => commaDangle, - "comma-spacing": () => commaSpacing, - "comma-style": () => commaStyle, - complexity: () => complexity, - "computed-property-spacing": () => computedPropertySpacing, - "consistent-return": () => consistentReturn, - "consistent-this": () => consistentThis, - "constructor-super": () => constructorSuper, - curly: () => curly, - "default-case": () => defaultCase, - "default-case-last": () => defaultCaseLast, - "default-param-last": () => defaultParamLast, - "dot-location": () => dotLocation, - "dot-notation": () => dotNotation, - "eol-last": () => eolLast, - eqeqeq: () => eqeqeq, - "for-direction": () => forDirection, - "func-call-spacing": () => funcCallSpacing, - "func-name-matching": () => funcNameMatching, - "func-names": () => funcNames, - "func-style": () => funcStyle, - "function-call-argument-newline": () => functionCallArgumentNewline, - "function-paren-newline": () => functionParenNewline, - "generator-star-spacing": () => generatorStarSpacing, - "getter-return": () => getterReturn, - "global-require": () => globalRequire, - "grouped-accessor-pairs": () => groupedAccessorPairs, - "guard-for-in": () => guardForIn, - "handle-callback-err": () => handleCallbackErr, - "id-blacklist": () => idBlacklist, - "id-denylist": () => idDenylist, - "id-length": () => idLength, - "id-match": () => idMatch, - "implicit-arrow-linebreak": () => implicitArrowLinebreak, - indent: () => indent, - "indent-legacy": () => indentLegacy, - "init-declarations": () => initDeclarations, - "jsx-quotes": () => jsxQuotes, - "key-spacing": () => keySpacing, - "keyword-spacing": () => keywordSpacing, - "line-comment-position": () => lineCommentPosition, - "linebreak-style": () => linebreakStyle, - "lines-around-comment": () => linesAroundComment, - "lines-around-directive": () => linesAroundDirective, - "lines-between-class-members": () => linesBetweenClassMembers, - "max-classes-per-file": () => maxClassesPerFile, - "max-depth": () => maxDepth, - "max-len": () => maxLen, - "max-lines": () => maxLines, - "max-lines-per-function": () => maxLinesPerFunction, - "max-nested-callbacks": () => maxNestedCallbacks, - "max-params": () => maxParams, - "max-statements": () => maxStatements, - "max-statements-per-line": () => maxStatementsPerLine, - "multiline-comment-style": () => multilineCommentStyle, - "multiline-ternary": () => multilineTernary, - "new-cap": () => newCap, - "new-parens": () => newParens, - "newline-after-var": () => newlineAfterVar, - "newline-before-return": () => newlineBeforeReturn, - "newline-per-chained-call": () => newlinePerChainedCall, - "no-alert": () => noAlert, - "no-array-constructor": () => noArrayConstructor, - "no-async-promise-executor": () => noAsyncPromiseExecutor, - "no-await-in-loop": () => noAwaitInLoop, - "no-bitwise": () => noBitwise, - "no-buffer-constructor": () => noBufferConstructor, - "no-caller": () => noCaller, - "no-case-declarations": () => noCaseDeclarations, - "no-catch-shadow": () => noCatchShadow, - "no-class-assign": () => noClassAssign, - "no-compare-neg-zero": () => noCompareNegZero, - "no-cond-assign": () => noCondAssign, - "no-confusing-arrow": () => noConfusingArrow, - "no-console": () => noConsole, - "no-const-assign": () => noConstAssign, - "no-constant-condition": () => noConstantCondition, - "no-constructor-return": () => noConstructorReturn, - "no-continue": () => noContinue, - "no-control-regex": () => noControlRegex, - "no-debugger": () => noDebugger, - "no-delete-var": () => noDeleteVar, - "no-div-regex": () => noDivRegex, - "no-dupe-args": () => noDupeArgs, - "no-dupe-class-members": () => noDupeClassMembers, - "no-dupe-else-if": () => noDupeElseIf, - "no-dupe-keys": () => noDupeKeys, - "no-duplicate-case": () => noDuplicateCase, - "no-duplicate-imports": () => noDuplicateImports, - "no-else-return": () => noElseReturn, - "no-empty": () => noEmpty, - "no-empty-character-class": () => noEmptyCharacterClass, - "no-empty-function": () => noEmptyFunction, - "no-empty-pattern": () => noEmptyPattern, - "no-eq-null": () => noEqNull, - "no-eval": () => noEval, - "no-ex-assign": () => noExAssign, - "no-extend-native": () => noExtendNative, - "no-extra-bind": () => noExtraBind, - "no-extra-boolean-cast": () => noExtraBooleanCast, - "no-extra-label": () => noExtraLabel, - "no-extra-parens": () => noExtraParens, - "no-extra-semi": () => noExtraSemi, - "no-fallthrough": () => noFallthrough, - "no-floating-decimal": () => noFloatingDecimal, - "no-func-assign": () => noFuncAssign, - "no-global-assign": () => noGlobalAssign, - "no-implicit-coercion": () => noImplicitCoercion, - "no-implicit-globals": () => noImplicitGlobals, - "no-implied-eval": () => noImpliedEval, - "no-import-assign": () => noImportAssign, - "no-inline-comments": () => noInlineComments, - "no-inner-declarations": () => noInnerDeclarations, - "no-invalid-regexp": () => noInvalidRegexp, - "no-invalid-this": () => noInvalidThis, - "no-irregular-whitespace": () => noIrregularWhitespace, - "no-iterator": () => noIterator, - "no-label-var": () => noLabelVar, - "no-labels": () => noLabels, - "no-lone-blocks": () => noLoneBlocks, - "no-lonely-if": () => noLonelyIf, - "no-loop-func": () => noLoopFunc, - "no-loss-of-precision": () => noLossOfPrecision, - "no-magic-numbers": () => noMagicNumbers, - "no-misleading-character-class": () => noMisleadingCharacterClass, - "no-mixed-operators": () => noMixedOperators, - "no-mixed-requires": () => noMixedRequires, - "no-mixed-spaces-and-tabs": () => noMixedSpacesAndTabs, - "no-multi-assign": () => noMultiAssign, - "no-multi-spaces": () => noMultiSpaces, - "no-multi-str": () => noMultiStr, - "no-multiple-empty-lines": () => noMultipleEmptyLines, - "no-native-reassign": () => noNativeReassign, - "no-negated-condition": () => noNegatedCondition, - "no-negated-in-lhs": () => noNegatedInLhs, - "no-nested-ternary": () => noNestedTernary, - "no-new": () => noNew, - "no-new-func": () => noNewFunc, - "no-new-object": () => noNewObject, - "no-new-require": () => noNewRequire, - "no-new-symbol": () => noNewSymbol, - "no-new-wrappers": () => noNewWrappers, - "no-nonoctal-decimal-escape": () => noNonoctalDecimalEscape, - "no-obj-calls": () => noObjCalls, - "no-octal": () => noOctal, - "no-octal-escape": () => noOctalEscape, - "no-param-reassign": () => noParamReassign, - "no-path-concat": () => noPathConcat, - "no-plusplus": () => noPlusplus, - "no-process-env": () => noProcessEnv, - "no-process-exit": () => noProcessExit, - "no-promise-executor-return": () => noPromiseExecutorReturn, - "no-proto": () => noProto, - "no-prototype-builtins": () => noPrototypeBuiltins, - "no-redeclare": () => noRedeclare, - "no-regex-spaces": () => noRegexSpaces, - "no-restricted-exports": () => noRestrictedExports, - "no-restricted-globals": () => noRestrictedGlobals, - "no-restricted-imports": () => noRestrictedImports, - "no-restricted-modules": () => noRestrictedModules, - "no-restricted-properties": () => noRestrictedProperties, - "no-restricted-syntax": () => noRestrictedSyntax, - "no-return-assign": () => noReturnAssign, - "no-return-await": () => noReturnAwait, - "no-script-url": () => noScriptUrl, - "no-self-assign": () => noSelfAssign, - "no-self-compare": () => noSelfCompare, - "no-sequences": () => noSequences, - "no-setter-return": () => noSetterReturn, - "no-shadow": () => noShadow, - "no-shadow-restricted-names": () => noShadowRestrictedNames, - "no-spaced-func": () => noSpacedFunc, - "no-sparse-arrays": () => noSparseArrays, - "no-sync": () => noSync, - "no-tabs": () => noTabs, - "no-template-curly-in-string": () => noTemplateCurlyInString, - "no-ternary": () => noTernary, - "no-this-before-super": () => noThisBeforeSuper, - "no-throw-literal": () => noThrowLiteral, - "no-trailing-spaces": () => noTrailingSpaces, - "no-undef": () => noUndef, - "no-undef-init": () => noUndefInit, - "no-undefined": () => noUndefined, - "no-underscore-dangle": () => noUnderscoreDangle, - "no-unexpected-multiline": () => noUnexpectedMultiline, - "no-unmodified-loop-condition": () => noUnmodifiedLoopCondition, - "no-unneeded-ternary": () => noUnneededTernary, - "no-unreachable": () => noUnreachable, - "no-unreachable-loop": () => noUnreachableLoop, - "no-unsafe-finally": () => noUnsafeFinally, - "no-unsafe-negation": () => noUnsafeNegation, - "no-unsafe-optional-chaining": () => noUnsafeOptionalChaining, - "no-unused-expressions": () => noUnusedExpressions, - "no-unused-labels": () => noUnusedLabels, - "no-unused-vars": () => noUnusedVars, - "no-use-before-define": () => noUseBeforeDefine, - "no-useless-backreference": () => noUselessBackreference, - "no-useless-call": () => noUselessCall, - "no-useless-catch": () => noUselessCatch, - "no-useless-computed-key": () => noUselessComputedKey, - "no-useless-concat": () => noUselessConcat, - "no-useless-constructor": () => noUselessConstructor, - "no-useless-escape": () => noUselessEscape, - "no-useless-rename": () => noUselessRename, - "no-useless-return": () => noUselessReturn, - "no-var": () => noVar, - "no-void": () => noVoid, - "no-warning-comments": () => noWarningComments, - "no-whitespace-before-property": () => noWhitespaceBeforeProperty, - "no-with": () => noWith, - "nonblock-statement-body-position": () => nonblockStatementBodyPosition, - "object-curly-newline": () => objectCurlyNewline, - "object-curly-spacing": () => objectCurlySpacing, - "object-property-newline": () => objectPropertyNewline, - "object-shorthand": () => objectShorthand, - "one-var": () => oneVar, - "one-var-declaration-per-line": () => oneVarDeclarationPerLine, - "operator-assignment": () => operatorAssignment, - "operator-linebreak": () => operatorLinebreak, - "padded-blocks": () => paddedBlocks, - "padding-line-between-statements": () => paddingLineBetweenStatements, - "prefer-arrow-callback": () => preferArrowCallback, - "prefer-const": () => preferConst, - "prefer-destructuring": () => preferDestructuring, - "prefer-exponentiation-operator": () => preferExponentiationOperator, - "prefer-named-capture-group": () => preferNamedCaptureGroup, - "prefer-numeric-literals": () => preferNumericLiterals, - "prefer-object-spread": () => preferObjectSpread, - "prefer-promise-reject-errors": () => preferPromiseRejectErrors, - "prefer-reflect": () => preferReflect, - "prefer-regex-literals": () => preferRegexLiterals, - "prefer-rest-params": () => preferRestParams, - "prefer-spread": () => preferSpread, - "prefer-template": () => preferTemplate, - "quote-props": () => quoteProps, - quotes: () => quotes, - radix: () => radix, - "require-atomic-updates": () => requireAtomicUpdates, - "require-await": () => requireAwait, - "require-jsdoc": () => requireJsdoc$1, - "require-unicode-regexp": () => requireUnicodeRegexp, - "require-yield": () => requireYield, - "rest-spread-spacing": () => restSpreadSpacing, - semi: () => semi, - "semi-spacing": () => semiSpacing, - "semi-style": () => semiStyle, - "sort-imports": () => sortImports, - "sort-keys": () => sortKeys, - "sort-vars": () => sortVars, - "space-before-blocks": () => spaceBeforeBlocks, - "space-before-function-paren": () => spaceBeforeFunctionParen, - "space-in-parens": () => spaceInParens, - "space-infix-ops": () => spaceInfixOps, - "space-unary-ops": () => spaceUnaryOps, - "spaced-comment": () => spacedComment, - strict: () => strict, - "switch-colon-spacing": () => switchColonSpacing, - "symbol-description": () => symbolDescription, - "template-curly-spacing": () => templateCurlySpacing, - "template-tag-spacing": () => templateTagSpacing, - "unicode-bom": () => unicodeBom, - "use-isnan": () => useIsnan, - "valid-jsdoc": () => validJsdoc, - "valid-typeof": () => validTypeof, - "vars-on-top": () => varsOnTop, - "wrap-iife": () => wrapIife, - "wrap-regex": () => wrapRegex, - "yield-star-spacing": () => yieldStarSpacing, - yoda: () => yoda -})); - -/** - * @fileoverview Defines a storage for rules. - * @author Nicholas C. Zakas - * @author aladdin-add - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Normalizes a rule module to the new-style API - * @param {(Function|{create: Function})} rule A rule object, which can either be a function - * ("old-style") or an object with a `create` method ("new-style") - * @returns {{create: Function}} A new-style rule. - */ -function normalizeRule(rule) { - return typeof rule === "function" ? Object.assign({ create: rule }, rule) : rule; -} - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -class Rules { - constructor() { - this._rules = Object.create(null); - } - - /** - * Registers a rule module for rule id in storage. - * @param {string} ruleId Rule id (file name). - * @param {Function} ruleModule Rule handler. - * @returns {void} - */ - define(ruleId, ruleModule) { - this._rules[ruleId] = normalizeRule(ruleModule); - } - - /** - * Access rule handler by id (file name). - * @param {string} ruleId Rule id (file name). - * @returns {{create: Function, schema: JsonSchema[]}} - * A rule. This is normalized to always have the new-style shape with a `create` method. - */ - get(ruleId) { - if (typeof this._rules[ruleId] === "string") { - this.define(ruleId, commonjsRequire(this._rules[ruleId])); - } - if (this._rules[ruleId]) { - return this._rules[ruleId]; - } - if (rules$2.has(ruleId)) { - return rules$2.get(ruleId); - } - - return null; - } - - *[Symbol.iterator]() { - yield* rules$2; - - for (const ruleId of Object.keys(this._rules)) { - yield [ruleId, this.get(ruleId)]; - } - } -} - -var rules$1 = Rules; - -/** - * @fileoverview A variant of EventEmitter which does not give listeners information about each other - * @author Teddy Katz - */ - -//------------------------------------------------------------------------------ -// Typedefs -//------------------------------------------------------------------------------ - -/** - * An event emitter - * @typedef {Object} SafeEmitter - * @property {function(eventName: string, listenerFunc: Function): void} on Adds a listener for a given event name - * @property {function(eventName: string, arg1?: any, arg2?: any, arg3?: any)} emit Emits an event with a given name. - * This calls all the listeners that were listening for that name, with `arg1`, `arg2`, and `arg3` as arguments. - * @property {function(): string[]} eventNames Gets the list of event names that have registered listeners. - */ - -/** - * Creates an object which can listen for and emit events. - * This is similar to the EventEmitter API in Node's standard library, but it has a few differences. - * The goal is to allow multiple modules to attach arbitrary listeners to the same emitter, without - * letting the modules know about each other at all. - * 1. It has no special keys like `error` and `newListener`, which would allow modules to detect when - * another module throws an error or registers a listener. - * 2. It calls listener functions without any `this` value. (`EventEmitter` calls listeners with a - * `this` value of the emitter instance, which would give listeners access to other listeners.) - * @returns {SafeEmitter} An emitter - */ -var safeEmitter = () => { - const listeners = Object.create(null); - - return Object.freeze({ - on(eventName, listener) { - if (eventName in listeners) { - listeners[eventName].push(listener); - } else { - listeners[eventName] = [listener]; - } - }, - emit(eventName, ...args) { - if (eventName in listeners) { - listeners[eventName].forEach(listener => listener(...args)); - } - }, - eventNames() { - return Object.keys(listeners); - } - }); -}; - -/** - * @fileoverview An object that caches and applies source code fixes. - * @author Nicholas C. Zakas - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -const debug$3 = require$$0__default['default']("eslint:source-code-fixer"); - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const BOM = "\uFEFF"; - -/** - * Compares items in a messages array by range. - * @param {Message} a The first message. - * @param {Message} b The second message. - * @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal. - * @private - */ -function compareMessagesByFixRange(a, b) { - return a.fix.range[0] - b.fix.range[0] || a.fix.range[1] - b.fix.range[1]; -} - -/** - * Compares items in a messages array by line and column. - * @param {Message} a The first message. - * @param {Message} b The second message. - * @returns {int} -1 if a comes before b, 1 if a comes after b, 0 if equal. - * @private - */ -function compareMessagesByLocation(a, b) { - return a.line - b.line || a.column - b.column; -} - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -/** - * Utility for apply fixes to source code. - * @constructor - */ -function SourceCodeFixer$1() { - Object.freeze(this); -} - -/** - * Applies the fixes specified by the messages to the given text. Tries to be - * smart about the fixes and won't apply fixes over the same area in the text. - * @param {string} sourceText The text to apply the changes to. - * @param {Message[]} messages The array of messages reported by ESLint. - * @param {boolean|Function} [shouldFix=true] Determines whether each message should be fixed - * @returns {Object} An object containing the fixed text and any unfixed messages. - */ -SourceCodeFixer$1.applyFixes = function(sourceText, messages, shouldFix) { - debug$3("Applying fixes"); - - if (shouldFix === false) { - debug$3("shouldFix parameter was false, not attempting fixes"); - return { - fixed: false, - messages, - output: sourceText - }; - } - - // clone the array - const remainingMessages = [], - fixes = [], - bom = sourceText.startsWith(BOM) ? BOM : "", - text = bom ? sourceText.slice(1) : sourceText; - let lastPos = Number.NEGATIVE_INFINITY, - output = bom; - - /** - * Try to use the 'fix' from a problem. - * @param {Message} problem The message object to apply fixes from - * @returns {boolean} Whether fix was successfully applied - */ - function attemptFix(problem) { - const fix = problem.fix; - const start = fix.range[0]; - const end = fix.range[1]; - - // Remain it as a problem if it's overlapped or it's a negative range - if (lastPos >= start || start > end) { - remainingMessages.push(problem); - return false; - } - - // Remove BOM. - if ((start < 0 && end >= 0) || (start === 0 && fix.text.startsWith(BOM))) { - output = ""; - } - - // Make output to this fix. - output += text.slice(Math.max(0, lastPos), Math.max(0, start)); - output += fix.text; - lastPos = end; - return true; - } - - messages.forEach(problem => { - if (Object.prototype.hasOwnProperty.call(problem, "fix")) { - fixes.push(problem); - } else { - remainingMessages.push(problem); - } - }); - - if (fixes.length) { - debug$3("Found fixes to apply"); - let fixesWereApplied = false; - - for (const problem of fixes.sort(compareMessagesByFixRange)) { - if (typeof shouldFix !== "function" || shouldFix(problem)) { - attemptFix(problem); - - /* - * The only time attemptFix will fail is if a previous fix was - * applied which conflicts with it. So we can mark this as true. - */ - fixesWereApplied = true; - } else { - remainingMessages.push(problem); - } - } - output += text.slice(Math.max(0, lastPos)); - - return { - fixed: fixesWereApplied, - messages: remainingMessages.sort(compareMessagesByLocation), - output - }; - } - - debug$3("No fixes to apply"); - return { - fixed: false, - messages, - output: bom + text - }; - -}; - -var sourceCodeFixer = SourceCodeFixer$1; - -/** - * @fileoverview Tracks performance of individual rules. - * @author Brandon Mills - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/* istanbul ignore next */ -/** - * Align the string to left - * @param {string} str string to evaluate - * @param {int} len length of the string - * @param {string} ch delimiter character - * @returns {string} modified string - * @private - */ -function alignLeft(str, len, ch) { - return str + new Array(len - str.length + 1).join(ch || " "); -} - -/* istanbul ignore next */ -/** - * Align the string to right - * @param {string} str string to evaluate - * @param {int} len length of the string - * @param {string} ch delimiter character - * @returns {string} modified string - * @private - */ -function alignRight(str, len, ch) { - return new Array(len - str.length + 1).join(ch || " ") + str; -} - -//------------------------------------------------------------------------------ -// Module definition -//------------------------------------------------------------------------------ - -const enabled = !!process.env.TIMING; - -const HEADERS = ["Rule", "Time (ms)", "Relative"]; -const ALIGN = [alignLeft, alignRight, alignRight]; - -/** - * Decide how many rules to show in the output list. - * @returns {number} the number of rules to show - */ -function getListSize() { - const MINIMUM_SIZE = 10; - - if (typeof process.env.TIMING !== "string") { - return MINIMUM_SIZE; - } - - if (process.env.TIMING.toLowerCase() === "all") { - return Number.POSITIVE_INFINITY; - } - - const TIMING_ENV_VAR_AS_INTEGER = Number.parseInt(process.env.TIMING, 10); - - return TIMING_ENV_VAR_AS_INTEGER > 10 ? TIMING_ENV_VAR_AS_INTEGER : MINIMUM_SIZE; -} - -/* istanbul ignore next */ -/** - * display the data - * @param {Object} data Data object to be displayed - * @returns {void} prints modified string with console.log - * @private - */ -function display(data) { - let total = 0; - const rows = Object.keys(data) - .map(key => { - const time = data[key]; - - total += time; - return [key, time]; - }) - .sort((a, b) => b[1] - a[1]) - .slice(0, getListSize()); - - rows.forEach(row => { - row.push(`${(row[1] * 100 / total).toFixed(1)}%`); - row[1] = row[1].toFixed(3); - }); - - rows.unshift(HEADERS); - - const widths = []; - - rows.forEach(row => { - const len = row.length; - - for (let i = 0; i < len; i++) { - const n = row[i].length; - - if (!widths[i] || n > widths[i]) { - widths[i] = n; - } - } - }); - - const table = rows.map(row => ( - row - .map((cell, index) => ALIGN[index](cell, widths[index])) - .join(" | ") - )); - - table.splice(1, 0, widths.map((width, index) => { - const extraAlignment = index !== 0 && index !== widths.length - 1 ? 2 : 1; - - return ALIGN[index](":", width + extraAlignment, "-"); - }).join("|")); - - console.log(table.join("\n")); // eslint-disable-line no-console -} - -/* istanbul ignore next */ -var timing = (function() { - - const data = Object.create(null); - - /** - * Time the run - * @param {*} key key from the data object - * @param {Function} fn function to be called - * @returns {Function} function to be executed - * @private - */ - function time(key, fn) { - if (typeof data[key] === "undefined") { - data[key] = 0; - } - - return function(...args) { - let t = process.hrtime(); - - fn(...args); - t = process.hrtime(t); - data[key] += t[0] * 1e3 + t[1] / 1e6; - }; - } - - if (enabled) { - process.on("exit", () => { - display(data); - }); - } - - return { - time, - enabled, - getListSize - }; - -}()); - -var rules = { - "generator-star": [ - "generator-star-spacing" - ], - "global-strict": [ - "strict" - ], - "no-arrow-condition": [ - "no-confusing-arrow", - "no-constant-condition" - ], - "no-comma-dangle": [ - "comma-dangle" - ], - "no-empty-class": [ - "no-empty-character-class" - ], - "no-empty-label": [ - "no-labels" - ], - "no-extra-strict": [ - "strict" - ], - "no-reserved-keys": [ - "quote-props" - ], - "no-space-before-semi": [ - "semi-spacing" - ], - "no-wrap-func": [ - "no-extra-parens" - ], - "space-after-function-name": [ - "space-before-function-paren" - ], - "space-after-keywords": [ - "keyword-spacing" - ], - "space-before-function-parentheses": [ - "space-before-function-paren" - ], - "space-before-keywords": [ - "keyword-spacing" - ], - "space-in-brackets": [ - "object-curly-spacing", - "array-bracket-spacing", - "computed-property-spacing" - ], - "space-return-throw-case": [ - "keyword-spacing" - ], - "space-unary-word-ops": [ - "space-unary-ops" - ], - "spaced-line-comment": [ - "spaced-comment" - ] -}; -var ruleReplacements = { - rules: rules -}; - -/** - * @fileoverview Main Linter Class - * @author Gyandeep Singh - * @author aladdin-add - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -const - { SourceCode } = sourceCode; - -const debug$2 = require$$0__default['default']("eslint:linter"); -const MAX_AUTOFIX_PASSES = 10; -const DEFAULT_PARSER_NAME = "espree"; -const commentParser = new configCommentParser(); -const DEFAULT_ERROR_LOC = { start: { line: 1, column: 0 }, end: { line: 1, column: 1 } }; - -//------------------------------------------------------------------------------ -// Typedefs -//------------------------------------------------------------------------------ - -/** @typedef {InstanceType} ConfigArray */ -/** @typedef {InstanceType} ExtractedConfig */ -/** @typedef {import("../shared/types").ConfigData} ConfigData */ -/** @typedef {import("../shared/types").Environment} Environment */ -/** @typedef {import("../shared/types").GlobalConf} GlobalConf */ -/** @typedef {import("../shared/types").LintMessage} LintMessage */ -/** @typedef {import("../shared/types").ParserOptions} ParserOptions */ -/** @typedef {import("../shared/types").Processor} Processor */ -/** @typedef {import("../shared/types").Rule} Rule */ - -/** - * @template T - * @typedef {{ [P in keyof T]-?: T[P] }} Required - */ - -/** - * @typedef {Object} DisableDirective - * @property {("disable"|"enable"|"disable-line"|"disable-next-line")} type - * @property {number} line - * @property {number} column - * @property {(string|null)} ruleId - */ - -/** - * The private data for `Linter` instance. - * @typedef {Object} LinterInternalSlots - * @property {ConfigArray|null} lastConfigArray The `ConfigArray` instance that the last `verify()` call used. - * @property {SourceCode|null} lastSourceCode The `SourceCode` instance that the last `verify()` call used. - * @property {Map} parserMap The loaded parsers. - * @property {Rules} ruleMap The loaded rules. - */ - -/** - * @typedef {Object} VerifyOptions - * @property {boolean} [allowInlineConfig] Allow/disallow inline comments' ability - * to change config once it is set. Defaults to true if not supplied. - * Useful if you want to validate JS without comments overriding rules. - * @property {boolean} [disableFixes] if `true` then the linter doesn't make `fix` - * properties into the lint result. - * @property {string} [filename] the filename of the source code. - * @property {boolean | "off" | "warn" | "error"} [reportUnusedDisableDirectives] Adds reported errors for - * unused `eslint-disable` directives. - */ - -/** - * @typedef {Object} ProcessorOptions - * @property {(filename:string, text:string) => boolean} [filterCodeBlock] the - * predicate function that selects adopt code blocks. - * @property {Processor["postprocess"]} [postprocess] postprocessor for report - * messages. If provided, this should accept an array of the message lists - * for each code block returned from the preprocessor, apply a mapping to - * the messages as appropriate, and return a one-dimensional array of - * messages. - * @property {Processor["preprocess"]} [preprocess] preprocessor for source text. - * If provided, this should accept a string of source text, and return an - * array of code blocks to lint. - */ - -/** - * @typedef {Object} FixOptions - * @property {boolean | ((message: LintMessage) => boolean)} [fix] Determines - * whether fixes should be applied. - */ - -/** - * @typedef {Object} InternalOptions - * @property {string | null} warnInlineConfig The config name what `noInlineConfig` setting came from. If `noInlineConfig` setting didn't exist, this is null. If this is a config name, then the linter warns directive comments. - * @property {"off" | "warn" | "error"} reportUnusedDisableDirectives (boolean values were normalized) - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** - * Ensures that variables representing built-in properties of the Global Object, - * and any globals declared by special block comments, are present in the global - * scope. - * @param {Scope} globalScope The global scope. - * @param {Object} configGlobals The globals declared in configuration - * @param {{exportedVariables: Object, enabledGlobals: Object}} commentDirectives Directives from comment configuration - * @returns {void} - */ -function addDeclaredGlobals(globalScope, configGlobals, { exportedVariables, enabledGlobals }) { - - // Define configured global variables. - for (const id of new Set([...Object.keys(configGlobals), ...Object.keys(enabledGlobals)])) { - - /* - * `ConfigOps.normalizeConfigGlobal` will throw an error if a configured global value is invalid. However, these errors would - * typically be caught when validating a config anyway (validity for inline global comments is checked separately). - */ - const configValue = configGlobals[id] === void 0 ? void 0 : configOps.normalizeConfigGlobal(configGlobals[id]); - const commentValue = enabledGlobals[id] && enabledGlobals[id].value; - const value = commentValue || configValue; - const sourceComments = enabledGlobals[id] && enabledGlobals[id].comments; - - if (value === "off") { - continue; - } - - let variable = globalScope.set.get(id); - - if (!variable) { - variable = new eslintScope__default['default'].Variable(id, globalScope); - - globalScope.variables.push(variable); - globalScope.set.set(id, variable); - } - - variable.eslintImplicitGlobalSetting = configValue; - variable.eslintExplicitGlobal = sourceComments !== void 0; - variable.eslintExplicitGlobalComments = sourceComments; - variable.writeable = (value === "writable"); - } - - // mark all exported variables as such - Object.keys(exportedVariables).forEach(name => { - const variable = globalScope.set.get(name); - - if (variable) { - variable.eslintUsed = true; - } - }); - - /* - * "through" contains all references which definitions cannot be found. - * Since we augment the global scope using configuration, we need to update - * references and remove the ones that were added by configuration. - */ - globalScope.through = globalScope.through.filter(reference => { - const name = reference.identifier.name; - const variable = globalScope.set.get(name); - - if (variable) { - - /* - * Links the variable and the reference. - * And this reference is removed from `Scope#through`. - */ - reference.resolved = variable; - variable.references.push(reference); - - return false; - } - - return true; - }); -} - -/** - * creates a missing-rule message. - * @param {string} ruleId the ruleId to create - * @returns {string} created error message - * @private - */ -function createMissingRuleMessage(ruleId) { - return Object.prototype.hasOwnProperty.call(ruleReplacements.rules, ruleId) - ? `Rule '${ruleId}' was removed and replaced by: ${ruleReplacements.rules[ruleId].join(", ")}` - : `Definition for rule '${ruleId}' was not found.`; -} - -/** - * creates a linting problem - * @param {Object} options to create linting error - * @param {string} [options.ruleId] the ruleId to report - * @param {Object} [options.loc] the loc to report - * @param {string} [options.message] the error message to report - * @param {string} [options.severity] the error message to report - * @returns {LintMessage} created problem, returns a missing-rule problem if only provided ruleId. - * @private - */ -function createLintingProblem(options) { - const { - ruleId = null, - loc = DEFAULT_ERROR_LOC, - message = createMissingRuleMessage(options.ruleId), - severity = 2 - } = options; - - return { - ruleId, - message, - line: loc.start.line, - column: loc.start.column + 1, - endLine: loc.end.line, - endColumn: loc.end.column + 1, - severity, - nodeType: null - }; -} - -/** - * Creates a collection of disable directives from a comment - * @param {Object} options to create disable directives - * @param {("disable"|"enable"|"disable-line"|"disable-next-line")} options.type The type of directive comment - * @param {{line: number, column: number}} options.loc The 0-based location of the comment token - * @param {string} options.value The value after the directive in the comment - * comment specified no specific rules, so it applies to all rules (e.g. `eslint-disable`) - * @param {function(string): {create: Function}} options.ruleMapper A map from rule IDs to defined rules - * @returns {Object} Directives and problems from the comment - */ -function createDisableDirectives(options) { - const { type, loc, value, ruleMapper } = options; - const ruleIds = Object.keys(commentParser.parseListConfig(value)); - const directiveRules = ruleIds.length ? ruleIds : [null]; - const result = { - directives: [], // valid disable directives - directiveProblems: [] // problems in directives - }; - - for (const ruleId of directiveRules) { - - // push to directives, if the rule is defined(including null, e.g. /*eslint enable*/) - if (ruleId === null || ruleMapper(ruleId) !== null) { - result.directives.push({ type, line: loc.start.line, column: loc.start.column + 1, ruleId }); - } else { - result.directiveProblems.push(createLintingProblem({ ruleId, loc })); - } - } - return result; -} - -/** - * Remove the ignored part from a given directive comment and trim it. - * @param {string} value The comment text to strip. - * @returns {string} The stripped text. - */ -function stripDirectiveComment(value) { - return value.split(/\s-{2,}\s/u)[0].trim(); -} - -/** - * Parses comments in file to extract file-specific config of rules, globals - * and environments and merges them with global config; also code blocks - * where reporting is disabled or enabled and merges them with reporting config. - * @param {string} filename The file being checked. - * @param {ASTNode} ast The top node of the AST. - * @param {function(string): {create: Function}} ruleMapper A map from rule IDs to defined rules - * @param {string|null} warnInlineConfig If a string then it should warn directive comments as disabled. The string value is the config name what the setting came from. - * @returns {{configuredRules: Object, enabledGlobals: {value:string,comment:Token}[], exportedVariables: Object, problems: Problem[], disableDirectives: DisableDirective[]}} - * A collection of the directive comments that were found, along with any problems that occurred when parsing - */ -function getDirectiveComments(filename, ast, ruleMapper, warnInlineConfig) { - const configuredRules = {}; - const enabledGlobals = Object.create(null); - const exportedVariables = {}; - const problems = []; - const disableDirectives = []; - const validator = new configValidator$1({ - builtInRules: rules$1 - }); - - ast.comments.filter(token => token.type !== "Shebang").forEach(comment => { - const trimmedCommentText = stripDirectiveComment(comment.value); - const match = /^(eslint(?:-env|-enable|-disable(?:(?:-next)?-line)?)?|exported|globals?)(?:\s|$)/u.exec(trimmedCommentText); - - if (!match) { - return; - } - const directiveText = match[1]; - const lineCommentSupported = /^eslint-disable-(next-)?line$/u.test(directiveText); - - if (comment.type === "Line" && !lineCommentSupported) { - return; - } - - if (warnInlineConfig) { - const kind = comment.type === "Block" ? `/*${directiveText}*/` : `//${directiveText}`; - - problems.push(createLintingProblem({ - ruleId: null, - message: `'${kind}' has no effect because you have 'noInlineConfig' setting in ${warnInlineConfig}.`, - loc: comment.loc, - severity: 1 - })); - return; - } - - if (lineCommentSupported && comment.loc.start.line !== comment.loc.end.line) { - const message = `${directiveText} comment should not span multiple lines.`; - - problems.push(createLintingProblem({ - ruleId: null, - message, - loc: comment.loc - })); - return; - } - - const directiveValue = trimmedCommentText.slice(match.index + directiveText.length); - - switch (directiveText) { - case "eslint-disable": - case "eslint-enable": - case "eslint-disable-next-line": - case "eslint-disable-line": { - const directiveType = directiveText.slice("eslint-".length); - const options = { type: directiveType, loc: comment.loc, value: directiveValue, ruleMapper }; - const { directives, directiveProblems } = createDisableDirectives(options); - - disableDirectives.push(...directives); - problems.push(...directiveProblems); - break; - } - - case "exported": - Object.assign(exportedVariables, commentParser.parseStringConfig(directiveValue, comment)); - break; - - case "globals": - case "global": - for (const [id, { value }] of Object.entries(commentParser.parseStringConfig(directiveValue, comment))) { - let normalizedValue; - - try { - normalizedValue = configOps.normalizeConfigGlobal(value); - } catch (err) { - problems.push(createLintingProblem({ - ruleId: null, - loc: comment.loc, - message: err.message - })); - continue; - } - - if (enabledGlobals[id]) { - enabledGlobals[id].comments.push(comment); - enabledGlobals[id].value = normalizedValue; - } else { - enabledGlobals[id] = { - comments: [comment], - value: normalizedValue - }; - } - } - break; - - case "eslint": { - const parseResult = commentParser.parseJsonConfig(directiveValue, comment.loc); - - if (parseResult.success) { - Object.keys(parseResult.config).forEach(name => { - const rule = ruleMapper(name); - const ruleValue = parseResult.config[name]; - - if (rule === null) { - problems.push(createLintingProblem({ ruleId: name, loc: comment.loc })); - return; - } - - try { - validator.validateRuleOptions(rule, name, ruleValue); - } catch (err) { - problems.push(createLintingProblem({ - ruleId: name, - message: err.message, - loc: comment.loc - })); - - // do not apply the config, if found invalid options. - return; - } - - configuredRules[name] = ruleValue; - }); - } else { - problems.push(parseResult.error); - } - - break; - } - - // no default - } - }); - - return { - configuredRules, - enabledGlobals, - exportedVariables, - problems, - disableDirectives - }; -} - -/** - * Normalize ECMAScript version from the initial config - * @param {number} ecmaVersion ECMAScript version from the initial config - * @returns {number} normalized ECMAScript version - */ -function normalizeEcmaVersion(ecmaVersion) { - - /* - * Calculate ECMAScript edition number from official year version starting with - * ES2015, which corresponds with ES6 (or a difference of 2009). - */ - return ecmaVersion >= 2015 ? ecmaVersion - 2009 : ecmaVersion; -} - -const eslintEnvPattern = /\/\*\s*eslint-env\s(.+?)\*\//gu; - -/** - * Checks whether or not there is a comment which has "eslint-env *" in a given text. - * @param {string} text A source code text to check. - * @returns {Object|null} A result of parseListConfig() with "eslint-env *" comment. - */ -function findEslintEnv(text) { - let match, retv; - - eslintEnvPattern.lastIndex = 0; - - while ((match = eslintEnvPattern.exec(text)) !== null) { - retv = Object.assign( - retv || {}, - commentParser.parseListConfig(stripDirectiveComment(match[1])) - ); - } - - return retv; -} - -/** - * Convert "/path/to/" to "". - * `CLIEngine#executeOnText()` method gives "/path/to/" if the filename - * was omitted because `configArray.extractConfig()` requires an absolute path. - * But the linter should pass `` to `RuleContext#getFilename()` in that - * case. - * Also, code blocks can have their virtual filename. If the parent filename was - * ``, the virtual filename is `/0_foo.js` or something like (i.e., - * it's not an absolute path). - * @param {string} filename The filename to normalize. - * @returns {string} The normalized filename. - */ -function normalizeFilename(filename) { - const parts = filename.split(path__default['default'].sep); - const index = parts.lastIndexOf(""); - - return index === -1 ? filename : parts.slice(index).join(path__default['default'].sep); -} - -/** - * Normalizes the possible options for `linter.verify` and `linter.verifyAndFix` to a - * consistent shape. - * @param {VerifyOptions} providedOptions Options - * @param {ConfigData} config Config. - * @returns {Required & InternalOptions} Normalized options - */ -function normalizeVerifyOptions(providedOptions, config) { - const disableInlineConfig = config.noInlineConfig === true; - const ignoreInlineConfig = providedOptions.allowInlineConfig === false; - const configNameOfNoInlineConfig = config.configNameOfNoInlineConfig - ? ` (${config.configNameOfNoInlineConfig})` - : ""; - - let reportUnusedDisableDirectives = providedOptions.reportUnusedDisableDirectives; - - if (typeof reportUnusedDisableDirectives === "boolean") { - reportUnusedDisableDirectives = reportUnusedDisableDirectives ? "error" : "off"; - } - if (typeof reportUnusedDisableDirectives !== "string") { - reportUnusedDisableDirectives = config.reportUnusedDisableDirectives ? "warn" : "off"; - } - - return { - filename: normalizeFilename(providedOptions.filename || ""), - allowInlineConfig: !ignoreInlineConfig, - warnInlineConfig: disableInlineConfig && !ignoreInlineConfig - ? `your config${configNameOfNoInlineConfig}` - : null, - reportUnusedDisableDirectives, - disableFixes: Boolean(providedOptions.disableFixes) - }; -} - -/** - * Combines the provided parserOptions with the options from environments - * @param {string} parserName The parser name which uses this options. - * @param {ParserOptions} providedOptions The provided 'parserOptions' key in a config - * @param {Environment[]} enabledEnvironments The environments enabled in configuration and with inline comments - * @returns {ParserOptions} Resulting parser options after merge - */ -function resolveParserOptions(parserName, providedOptions, enabledEnvironments) { - const parserOptionsFromEnv = enabledEnvironments - .filter(env => env.parserOptions) - .reduce((parserOptions, env) => lodash__default['default'].merge(parserOptions, env.parserOptions), {}); - const mergedParserOptions = lodash__default['default'].merge(parserOptionsFromEnv, providedOptions || {}); - const isModule = mergedParserOptions.sourceType === "module"; - - if (isModule) { - - /* - * can't have global return inside of modules - * TODO: espree validate parserOptions.globalReturn when sourceType is setting to module.(@aladdin-add) - */ - mergedParserOptions.ecmaFeatures = Object.assign({}, mergedParserOptions.ecmaFeatures, { globalReturn: false }); - } - - /* - * TODO: @aladdin-add - * 1. for a 3rd-party parser, do not normalize parserOptions - * 2. for espree, no need to do this (espree will do it) - */ - mergedParserOptions.ecmaVersion = normalizeEcmaVersion(mergedParserOptions.ecmaVersion); - - return mergedParserOptions; -} - -/** - * Combines the provided globals object with the globals from environments - * @param {Record} providedGlobals The 'globals' key in a config - * @param {Environment[]} enabledEnvironments The environments enabled in configuration and with inline comments - * @returns {Record} The resolved globals object - */ -function resolveGlobals(providedGlobals, enabledEnvironments) { - return Object.assign( - {}, - ...enabledEnvironments.filter(env => env.globals).map(env => env.globals), - providedGlobals - ); -} - -/** - * Strips Unicode BOM from a given text. - * @param {string} text A text to strip. - * @returns {string} The stripped text. - */ -function stripUnicodeBOM(text) { - - /* - * Check Unicode BOM. - * In JavaScript, string data is stored as UTF-16, so BOM is 0xFEFF. - * http://www.ecma-international.org/ecma-262/6.0/#sec-unicode-format-control-characters - */ - if (text.charCodeAt(0) === 0xFEFF) { - return text.slice(1); - } - return text; -} - -/** - * Get the options for a rule (not including severity), if any - * @param {Array|number} ruleConfig rule configuration - * @returns {Array} of rule options, empty Array if none - */ -function getRuleOptions(ruleConfig) { - if (Array.isArray(ruleConfig)) { - return ruleConfig.slice(1); - } - return []; - -} - -/** - * Analyze scope of the given AST. - * @param {ASTNode} ast The `Program` node to analyze. - * @param {ParserOptions} parserOptions The parser options. - * @param {Record} visitorKeys The visitor keys. - * @returns {ScopeManager} The analysis result. - */ -function analyzeScope(ast, parserOptions, visitorKeys) { - const ecmaFeatures = parserOptions.ecmaFeatures || {}; - const ecmaVersion = parserOptions.ecmaVersion || 5; - - return eslintScope__default['default'].analyze(ast, { - ignoreEval: true, - nodejsScope: ecmaFeatures.globalReturn, - impliedStrict: ecmaFeatures.impliedStrict, - ecmaVersion, - sourceType: parserOptions.sourceType || "script", - childVisitorKeys: visitorKeys || vk__default['default'].KEYS, - fallback: traverser.getKeys - }); -} - -/** - * Parses text into an AST. Moved out here because the try-catch prevents - * optimization of functions, so it's best to keep the try-catch as isolated - * as possible - * @param {string} text The text to parse. - * @param {Parser} parser The parser to parse. - * @param {ParserOptions} providedParserOptions Options to pass to the parser - * @param {string} filePath The path to the file being parsed. - * @returns {{success: false, error: Problem}|{success: true, sourceCode: SourceCode}} - * An object containing the AST and parser services if parsing was successful, or the error if parsing failed - * @private - */ -function parse$3(text, parser, providedParserOptions, filePath) { - const textToParse = stripUnicodeBOM(text).replace(astUtils$1.shebangPattern, (match, captured) => `//${captured}`); - const parserOptions = Object.assign({}, providedParserOptions, { - loc: true, - range: true, - raw: true, - tokens: true, - comment: true, - eslintVisitorKeys: true, - eslintScopeManager: true, - filePath - }); - - /* - * Check for parsing errors first. If there's a parsing error, nothing - * else can happen. However, a parsing error does not throw an error - * from this method - it's just considered a fatal error message, a - * problem that ESLint identified just like any other. - */ - try { - const parseResult = (typeof parser.parseForESLint === "function") - ? parser.parseForESLint(textToParse, parserOptions) - : { ast: parser.parse(textToParse, parserOptions) }; - const ast = parseResult.ast; - const parserServices = parseResult.services || {}; - const visitorKeys = parseResult.visitorKeys || vk__default['default'].KEYS; - const scopeManager = parseResult.scopeManager || analyzeScope(ast, parserOptions, visitorKeys); - - return { - success: true, - - /* - * Save all values that `parseForESLint()` returned. - * If a `SourceCode` object is given as the first parameter instead of source code text, - * linter skips the parsing process and reuses the source code object. - * In that case, linter needs all the values that `parseForESLint()` returned. - */ - sourceCode: new SourceCode({ - text, - ast, - parserServices, - scopeManager, - visitorKeys - }) - }; - } catch (ex) { - - // If the message includes a leading line number, strip it: - const message = `Parsing error: ${ex.message.replace(/^line \d+:/iu, "").trim()}`; - - debug$2("%s\n%s", message, ex.stack); - - return { - success: false, - error: { - ruleId: null, - fatal: true, - severity: 2, - message, - line: ex.lineNumber, - column: ex.column - } - }; - } -} - -/** - * Gets the scope for the current node - * @param {ScopeManager} scopeManager The scope manager for this AST - * @param {ASTNode} currentNode The node to get the scope of - * @returns {eslint-scope.Scope} The scope information for this node - */ -function getScope(scopeManager, currentNode) { - - // On Program node, get the outermost scope to avoid return Node.js special function scope or ES modules scope. - const inner = currentNode.type !== "Program"; - - for (let node = currentNode; node; node = node.parent) { - const scope = scopeManager.acquire(node, inner); - - if (scope) { - if (scope.type === "function-expression-name") { - return scope.childScopes[0]; - } - return scope; - } - } - - return scopeManager.scopes[0]; -} - -/** - * Marks a variable as used in the current scope - * @param {ScopeManager} scopeManager The scope manager for this AST. The scope may be mutated by this function. - * @param {ASTNode} currentNode The node currently being traversed - * @param {Object} parserOptions The options used to parse this text - * @param {string} name The name of the variable that should be marked as used. - * @returns {boolean} True if the variable was found and marked as used, false if not. - */ -function markVariableAsUsed(scopeManager, currentNode, parserOptions, name) { - const hasGlobalReturn = parserOptions.ecmaFeatures && parserOptions.ecmaFeatures.globalReturn; - const specialScope = hasGlobalReturn || parserOptions.sourceType === "module"; - const currentScope = getScope(scopeManager, currentNode); - - // Special Node.js scope means we need to start one level deeper - const initialScope = currentScope.type === "global" && specialScope ? currentScope.childScopes[0] : currentScope; - - for (let scope = initialScope; scope; scope = scope.upper) { - const variable = scope.variables.find(scopeVar => scopeVar.name === name); - - if (variable) { - variable.eslintUsed = true; - return true; - } - } - - return false; -} - -/** - * Runs a rule, and gets its listeners - * @param {Rule} rule A normalized rule with a `create` method - * @param {Context} ruleContext The context that should be passed to the rule - * @returns {Object} A map of selector listeners provided by the rule - */ -function createRuleListeners(rule, ruleContext) { - try { - return rule.create(ruleContext); - } catch (ex) { - ex.message = `Error while loading rule '${ruleContext.id}': ${ex.message}`; - throw ex; - } -} - -/** - * Gets all the ancestors of a given node - * @param {ASTNode} node The node - * @returns {ASTNode[]} All the ancestor nodes in the AST, not including the provided node, starting - * from the root node and going inwards to the parent node. - */ -function getAncestors(node) { - const ancestorsStartingAtParent = []; - - for (let ancestor = node.parent; ancestor; ancestor = ancestor.parent) { - ancestorsStartingAtParent.push(ancestor); - } - - return ancestorsStartingAtParent.reverse(); -} - -// methods that exist on SourceCode object -const DEPRECATED_SOURCECODE_PASSTHROUGHS = { - getSource: "getText", - getSourceLines: "getLines", - getAllComments: "getAllComments", - getNodeByRangeIndex: "getNodeByRangeIndex", - getComments: "getComments", - getCommentsBefore: "getCommentsBefore", - getCommentsAfter: "getCommentsAfter", - getCommentsInside: "getCommentsInside", - getJSDocComment: "getJSDocComment", - getFirstToken: "getFirstToken", - getFirstTokens: "getFirstTokens", - getLastToken: "getLastToken", - getLastTokens: "getLastTokens", - getTokenAfter: "getTokenAfter", - getTokenBefore: "getTokenBefore", - getTokenByRangeStart: "getTokenByRangeStart", - getTokens: "getTokens", - getTokensAfter: "getTokensAfter", - getTokensBefore: "getTokensBefore", - getTokensBetween: "getTokensBetween" -}; - -const BASE_TRAVERSAL_CONTEXT = Object.freeze( - Object.keys(DEPRECATED_SOURCECODE_PASSTHROUGHS).reduce( - (contextInfo, methodName) => - Object.assign(contextInfo, { - [methodName](...args) { - return this.getSourceCode()[DEPRECATED_SOURCECODE_PASSTHROUGHS[methodName]](...args); - } - }), - {} - ) -); - -/** - * Runs the given rules on the given SourceCode object - * @param {SourceCode} sourceCode A SourceCode object for the given text - * @param {Object} configuredRules The rules configuration - * @param {function(string): Rule} ruleMapper A mapper function from rule names to rules - * @param {Object} parserOptions The options that were passed to the parser - * @param {string} parserName The name of the parser in the config - * @param {Object} settings The settings that were enabled in the config - * @param {string} filename The reported filename of the code - * @param {boolean} disableFixes If true, it doesn't make `fix` properties. - * @param {string | undefined} cwd cwd of the cli - * @returns {Problem[]} An array of reported problems - */ -function runRules(sourceCode, configuredRules, ruleMapper, parserOptions, parserName, settings, filename, disableFixes, cwd) { - const emitter = safeEmitter(); - const nodeQueue = []; - let currentNode = sourceCode.ast; - - traverser.traverse(sourceCode.ast, { - enter(node, parent) { - node.parent = parent; - nodeQueue.push({ isEntering: true, node }); - }, - leave(node) { - nodeQueue.push({ isEntering: false, node }); - }, - visitorKeys: sourceCode.visitorKeys - }); - - /* - * Create a frozen object with the ruleContext properties and methods that are shared by all rules. - * All rule contexts will inherit from this object. This avoids the performance penalty of copying all the - * properties once for each rule. - */ - const sharedTraversalContext = Object.freeze( - Object.assign( - Object.create(BASE_TRAVERSAL_CONTEXT), - { - getAncestors: () => getAncestors(currentNode), - getDeclaredVariables: sourceCode.scopeManager.getDeclaredVariables.bind(sourceCode.scopeManager), - getCwd: () => cwd, - getFilename: () => filename, - getScope: () => getScope(sourceCode.scopeManager, currentNode), - getSourceCode: () => sourceCode, - markVariableAsUsed: name => markVariableAsUsed(sourceCode.scopeManager, currentNode, parserOptions, name), - parserOptions, - parserPath: parserName, - parserServices: sourceCode.parserServices, - settings - } - ) - ); - - - const lintingProblems = []; - - Object.keys(configuredRules).forEach(ruleId => { - const severity = configOps.getRuleSeverity(configuredRules[ruleId]); - - // not load disabled rules - if (severity === 0) { - return; - } - - const rule = ruleMapper(ruleId); - - if (rule === null) { - lintingProblems.push(createLintingProblem({ ruleId })); - return; - } - - const messageIds = rule.meta && rule.meta.messages; - let reportTranslator$1 = null; - const ruleContext = Object.freeze( - Object.assign( - Object.create(sharedTraversalContext), - { - id: ruleId, - options: getRuleOptions(configuredRules[ruleId]), - report(...args) { - - /* - * Create a report translator lazily. - * In a vast majority of cases, any given rule reports zero errors on a given - * piece of code. Creating a translator lazily avoids the performance cost of - * creating a new translator function for each rule that usually doesn't get - * called. - * - * Using lazy report translators improves end-to-end performance by about 3% - * with Node 8.4.0. - */ - if (reportTranslator$1 === null) { - reportTranslator$1 = reportTranslator({ - ruleId, - severity, - sourceCode, - messageIds, - disableFixes - }); - } - const problem = reportTranslator$1(...args); - - if (problem.fix && rule.meta && !rule.meta.fixable) { - throw new Error("Fixable rules should export a `meta.fixable` property."); - } - lintingProblems.push(problem); - } - } - ) - ); - - const ruleListeners = createRuleListeners(rule, ruleContext); - - // add all the selectors from the rule as listeners - Object.keys(ruleListeners).forEach(selector => { - emitter.on( - selector, - timing.enabled - ? timing.time(ruleId, ruleListeners[selector]) - : ruleListeners[selector] - ); - }); - }); - - // only run code path analyzer if the top level node is "Program", skip otherwise - const eventGenerator = nodeQueue[0].node.type === "Program" - ? new codePathAnalyzer(new nodeEventGenerator(emitter, { visitorKeys: sourceCode.visitorKeys, fallback: traverser.getKeys })) - : new nodeEventGenerator(emitter, { visitorKeys: sourceCode.visitorKeys, fallback: traverser.getKeys }); - - nodeQueue.forEach(traversalInfo => { - currentNode = traversalInfo.node; - - try { - if (traversalInfo.isEntering) { - eventGenerator.enterNode(currentNode); - } else { - eventGenerator.leaveNode(currentNode); - } - } catch (err) { - err.currentNode = currentNode; - throw err; - } - }); - - return lintingProblems; -} - -/** - * Ensure the source code to be a string. - * @param {string|SourceCode} textOrSourceCode The text or source code object. - * @returns {string} The source code text. - */ -function ensureText(textOrSourceCode) { - if (typeof textOrSourceCode === "object") { - const { hasBOM, text } = textOrSourceCode; - const bom = hasBOM ? "\uFEFF" : ""; - - return bom + text; - } - - return String(textOrSourceCode); -} - -/** - * Get an environment. - * @param {LinterInternalSlots} slots The internal slots of Linter. - * @param {string} envId The environment ID to get. - * @returns {Environment|null} The environment. - */ -function getEnv(slots, envId) { - return ( - (slots.lastConfigArray && slots.lastConfigArray.pluginEnvironments.get(envId)) || - environments.get(envId) || - null - ); -} - -/** - * Get a rule. - * @param {LinterInternalSlots} slots The internal slots of Linter. - * @param {string} ruleId The rule ID to get. - * @returns {Rule|null} The rule. - */ -function getRule$1(slots, ruleId) { - return ( - (slots.lastConfigArray && slots.lastConfigArray.pluginRules.get(ruleId)) || - slots.ruleMap.get(ruleId) - ); -} - -/** - * Normalize the value of the cwd - * @param {string | undefined} cwd raw value of the cwd, path to a directory that should be considered as the current working directory, can be undefined. - * @returns {string | undefined} normalized cwd - */ -function normalizeCwd(cwd) { - if (cwd) { - return cwd; - } - if (typeof process === "object") { - return process.cwd(); - } - - // It's more explicit to assign the undefined - // eslint-disable-next-line no-undefined - return undefined; -} - -/** - * The map to store private data. - * @type {WeakMap} - */ -const internalSlotsMap$1 = new WeakMap(); - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -/** - * Object that is responsible for verifying JavaScript text - * @name eslint - */ -class Linter$3 { - - /** - * Initialize the Linter. - * @param {Object} [config] the config object - * @param {string} [config.cwd] path to a directory that should be considered as the current working directory, can be undefined. - */ - constructor({ cwd } = {}) { - internalSlotsMap$1.set(this, { - cwd: normalizeCwd(cwd), - lastConfigArray: null, - lastSourceCode: null, - parserMap: new Map([["espree", espree__default['default']]]), - ruleMap: new rules$1() - }); - - this.version = require$$3.version; - } - - /** - * Getter for package version. - * @static - * @returns {string} The version from package.json. - */ - static get version() { - return require$$3.version; - } - - /** - * Same as linter.verify, except without support for processors. - * @param {string|SourceCode} textOrSourceCode The text to parse or a SourceCode object. - * @param {ConfigData} providedConfig An ESLintConfig instance to configure everything. - * @param {VerifyOptions} [providedOptions] The optional filename of the file being checked. - * @returns {LintMessage[]} The results as an array of messages or an empty array if no messages. - */ - _verifyWithoutProcessors(textOrSourceCode, providedConfig, providedOptions) { - const slots = internalSlotsMap$1.get(this); - const config = providedConfig || {}; - const options = normalizeVerifyOptions(providedOptions, config); - let text; - - // evaluate arguments - if (typeof textOrSourceCode === "string") { - slots.lastSourceCode = null; - text = textOrSourceCode; - } else { - slots.lastSourceCode = textOrSourceCode; - text = textOrSourceCode.text; - } - - // Resolve parser. - let parserName = DEFAULT_PARSER_NAME; - let parser = espree__default['default']; - - if (typeof config.parser === "object" && config.parser !== null) { - parserName = config.parser.filePath; - parser = config.parser.definition; - } else if (typeof config.parser === "string") { - if (!slots.parserMap.has(config.parser)) { - return [{ - ruleId: null, - fatal: true, - severity: 2, - message: `Configured parser '${config.parser}' was not found.`, - line: 0, - column: 0 - }]; - } - parserName = config.parser; - parser = slots.parserMap.get(config.parser); - } - - // search and apply "eslint-env *". - const envInFile = options.allowInlineConfig && !options.warnInlineConfig - ? findEslintEnv(text) - : {}; - const resolvedEnvConfig = Object.assign({ builtin: true }, config.env, envInFile); - const enabledEnvs = Object.keys(resolvedEnvConfig) - .filter(envName => resolvedEnvConfig[envName]) - .map(envName => getEnv(slots, envName)) - .filter(env => env); - - const parserOptions = resolveParserOptions(parserName, config.parserOptions || {}, enabledEnvs); - const configuredGlobals = resolveGlobals(config.globals || {}, enabledEnvs); - const settings = config.settings || {}; - - if (!slots.lastSourceCode) { - const parseResult = parse$3( - text, - parser, - parserOptions, - options.filename - ); - - if (!parseResult.success) { - return [parseResult.error]; - } - - slots.lastSourceCode = parseResult.sourceCode; - } else { - - /* - * If the given source code object as the first argument does not have scopeManager, analyze the scope. - * This is for backward compatibility (SourceCode is frozen so it cannot rebind). - */ - if (!slots.lastSourceCode.scopeManager) { - slots.lastSourceCode = new SourceCode({ - text: slots.lastSourceCode.text, - ast: slots.lastSourceCode.ast, - parserServices: slots.lastSourceCode.parserServices, - visitorKeys: slots.lastSourceCode.visitorKeys, - scopeManager: analyzeScope(slots.lastSourceCode.ast, parserOptions) - }); - } - } - - const sourceCode = slots.lastSourceCode; - const commentDirectives = options.allowInlineConfig - ? getDirectiveComments(options.filename, sourceCode.ast, ruleId => getRule$1(slots, ruleId), options.warnInlineConfig) - : { configuredRules: {}, enabledGlobals: {}, exportedVariables: {}, problems: [], disableDirectives: [] }; - - // augment global scope with declared global variables - addDeclaredGlobals( - sourceCode.scopeManager.scopes[0], - configuredGlobals, - { exportedVariables: commentDirectives.exportedVariables, enabledGlobals: commentDirectives.enabledGlobals } - ); - - const configuredRules = Object.assign({}, config.rules, commentDirectives.configuredRules); - - let lintingProblems; - - try { - lintingProblems = runRules( - sourceCode, - configuredRules, - ruleId => getRule$1(slots, ruleId), - parserOptions, - parserName, - settings, - options.filename, - options.disableFixes, - slots.cwd - ); - } catch (err) { - err.message += `\nOccurred while linting ${options.filename}`; - debug$2("An error occurred while traversing"); - debug$2("Filename:", options.filename); - if (err.currentNode) { - const { line } = err.currentNode.loc.start; - - debug$2("Line:", line); - err.message += `:${line}`; - } - debug$2("Parser Options:", parserOptions); - debug$2("Parser Path:", parserName); - debug$2("Settings:", settings); - throw err; - } - - return applyDisableDirectives({ - directives: commentDirectives.disableDirectives, - problems: lintingProblems - .concat(commentDirectives.problems) - .sort((problemA, problemB) => problemA.line - problemB.line || problemA.column - problemB.column), - reportUnusedDisableDirectives: options.reportUnusedDisableDirectives - }); - } - - /** - * Verifies the text against the rules specified by the second argument. - * @param {string|SourceCode} textOrSourceCode The text to parse or a SourceCode object. - * @param {ConfigData|ConfigArray} config An ESLintConfig instance to configure everything. - * @param {(string|(VerifyOptions&ProcessorOptions))} [filenameOrOptions] The optional filename of the file being checked. - * If this is not set, the filename will default to '' in the rule context. If - * an object, then it has "filename", "allowInlineConfig", and some properties. - * @returns {LintMessage[]} The results as an array of messages or an empty array if no messages. - */ - verify(textOrSourceCode, config, filenameOrOptions) { - debug$2("Verify"); - const options = typeof filenameOrOptions === "string" - ? { filename: filenameOrOptions } - : filenameOrOptions || {}; - - // CLIEngine passes a `ConfigArray` object. - if (config && typeof config.extractConfig === "function") { - return this._verifyWithConfigArray(textOrSourceCode, config, options); - } - - /* - * `Linter` doesn't support `overrides` property in configuration. - * So we cannot apply multiple processors. - */ - if (options.preprocess || options.postprocess) { - return this._verifyWithProcessor(textOrSourceCode, config, options); - } - return this._verifyWithoutProcessors(textOrSourceCode, config, options); - } - - /** - * Verify a given code with `ConfigArray`. - * @param {string|SourceCode} textOrSourceCode The source code. - * @param {ConfigArray} configArray The config array. - * @param {VerifyOptions&ProcessorOptions} options The options. - * @returns {LintMessage[]} The found problems. - */ - _verifyWithConfigArray(textOrSourceCode, configArray, options) { - debug$2("With ConfigArray: %s", options.filename); - - // Store the config array in order to get plugin envs and rules later. - internalSlotsMap$1.get(this).lastConfigArray = configArray; - - // Extract the final config for this file. - const config = configArray.extractConfig(options.filename); - const processor = - config.processor && - configArray.pluginProcessors.get(config.processor); - - // Verify. - if (processor) { - debug$2("Apply the processor: %o", config.processor); - const { preprocess, postprocess, supportsAutofix } = processor; - const disableFixes = options.disableFixes || !supportsAutofix; - - return this._verifyWithProcessor( - textOrSourceCode, - config, - { ...options, disableFixes, postprocess, preprocess }, - configArray - ); - } - return this._verifyWithoutProcessors(textOrSourceCode, config, options); - } - - /** - * Verify with a processor. - * @param {string|SourceCode} textOrSourceCode The source code. - * @param {ConfigData|ExtractedConfig} config The config array. - * @param {VerifyOptions&ProcessorOptions} options The options. - * @param {ConfigArray} [configForRecursive] The `ConfigArray` object to apply multiple processors recursively. - * @returns {LintMessage[]} The found problems. - */ - _verifyWithProcessor(textOrSourceCode, config, options, configForRecursive) { - const filename = options.filename || ""; - const filenameToExpose = normalizeFilename(filename); - const text = ensureText(textOrSourceCode); - const preprocess = options.preprocess || (rawText => [rawText]); - const postprocess = options.postprocess || lodash__default['default'].flatten; - const filterCodeBlock = - options.filterCodeBlock || - (blockFilename => blockFilename.endsWith(".js")); - const originalExtname = path__default['default'].extname(filename); - const messageLists = preprocess(text, filenameToExpose).map((block, i) => { - debug$2("A code block was found: %o", block.filename || "(unnamed)"); - - // Keep the legacy behavior. - if (typeof block === "string") { - return this._verifyWithoutProcessors(block, config, options); - } - - const blockText = block.text; - const blockName = path__default['default'].join(filename, `${i}_${block.filename}`); - - // Skip this block if filtered. - if (!filterCodeBlock(blockName, blockText)) { - debug$2("This code block was skipped."); - return []; - } - - // Resolve configuration again if the file extension was changed. - if (configForRecursive && path__default['default'].extname(blockName) !== originalExtname) { - debug$2("Resolving configuration again because the file extension was changed."); - return this._verifyWithConfigArray( - blockText, - configForRecursive, - { ...options, filename: blockName } - ); - } - - // Does lint. - return this._verifyWithoutProcessors( - blockText, - config, - { ...options, filename: blockName } - ); - }); - - return postprocess(messageLists, filenameToExpose); - } - - /** - * Gets the SourceCode object representing the parsed source. - * @returns {SourceCode} The SourceCode object. - */ - getSourceCode() { - return internalSlotsMap$1.get(this).lastSourceCode; - } - - /** - * Defines a new linting rule. - * @param {string} ruleId A unique rule identifier - * @param {Function | Rule} ruleModule Function from context to object mapping AST node types to event handlers - * @returns {void} - */ - defineRule(ruleId, ruleModule) { - internalSlotsMap$1.get(this).ruleMap.define(ruleId, ruleModule); - } - - /** - * Defines many new linting rules. - * @param {Record} rulesToDefine map from unique rule identifier to rule - * @returns {void} - */ - defineRules(rulesToDefine) { - Object.getOwnPropertyNames(rulesToDefine).forEach(ruleId => { - this.defineRule(ruleId, rulesToDefine[ruleId]); - }); - } - - /** - * Gets an object with all loaded rules. - * @returns {Map} All loaded rules - */ - getRules() { - const { lastConfigArray, ruleMap } = internalSlotsMap$1.get(this); - - return new Map(function *() { - yield* ruleMap; - - if (lastConfigArray) { - yield* lastConfigArray.pluginRules; - } - }()); - } - - /** - * Define a new parser module - * @param {string} parserId Name of the parser - * @param {Parser} parserModule The parser object - * @returns {void} - */ - defineParser(parserId, parserModule) { - internalSlotsMap$1.get(this).parserMap.set(parserId, parserModule); - } - - /** - * Performs multiple autofix passes over the text until as many fixes as possible - * have been applied. - * @param {string} text The source text to apply fixes to. - * @param {ConfigData|ConfigArray} config The ESLint config object to use. - * @param {VerifyOptions&ProcessorOptions&FixOptions} options The ESLint options object to use. - * @returns {{fixed:boolean,messages:LintMessage[],output:string}} The result of the fix operation as returned from the - * SourceCodeFixer. - */ - verifyAndFix(text, config, options) { - let messages = [], - fixedResult, - fixed = false, - passNumber = 0, - currentText = text; - const debugTextDescription = options && options.filename || `${text.slice(0, 10)}...`; - const shouldFix = options && typeof options.fix !== "undefined" ? options.fix : true; - - /** - * This loop continues until one of the following is true: - * - * 1. No more fixes have been applied. - * 2. Ten passes have been made. - * - * That means anytime a fix is successfully applied, there will be another pass. - * Essentially, guaranteeing a minimum of two passes. - */ - do { - passNumber++; - - debug$2(`Linting code for ${debugTextDescription} (pass ${passNumber})`); - messages = this.verify(currentText, config, options); - - debug$2(`Generating fixed text for ${debugTextDescription} (pass ${passNumber})`); - fixedResult = sourceCodeFixer.applyFixes(currentText, messages, shouldFix); - - /* - * stop if there are any syntax errors. - * 'fixedResult.output' is a empty string. - */ - if (messages.length === 1 && messages[0].fatal) { - break; - } - - // keep track if any fixes were ever applied - important for return value - fixed = fixed || fixedResult.fixed; - - // update to use the fixed output instead of the original text - currentText = fixedResult.output; - - } while ( - fixedResult.fixed && - passNumber < MAX_AUTOFIX_PASSES - ); - - /* - * If the last result had fixes, we need to lint again to be sure we have - * the most up-to-date information. - */ - if (fixedResult.fixed) { - fixedResult.messages = this.verify(currentText, config, options); - } - - // ensure the last result properly reflects if fixes were done - fixedResult.fixed = fixed; - fixedResult.output = currentText; - - return fixedResult; - } -} - -var linter$1 = { - Linter: Linter$3, - - /** - * Get the internal slots of a given Linter instance for tests. - * @param {Linter} instance The Linter instance to get. - * @returns {LinterInternalSlots} The internal slots. - */ - getLinterInternalSlots(instance) { - return internalSlotsMap$1.get(instance); - } -}; - -const { Linter: Linter$2 } = linter$1; - - - -var linter = { - Linter: Linter$2, - - // For testers. - SourceCodeFixer: sourceCodeFixer, - interpolate: interpolate$1 -}; - -/** - * @fileoverview Module for loading rules from files and directories. - * @author Michael Ficarra - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -const rulesDirCache = {}; - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -/** - * Load all rule modules from specified directory. - * @param {string} relativeRulesDir Path to rules directory, may be relative. - * @param {string} cwd Current working directory - * @returns {Object} Loaded rule modules. - */ -var loadRules = function(relativeRulesDir, cwd) { - const rulesDir = path__default['default'].resolve(cwd, relativeRulesDir); - - // cache will help performance as IO operation are expensive - if (rulesDirCache[rulesDir]) { - return rulesDirCache[rulesDir]; - } - - const rules = Object.create(null); - - fs__default['default'].readdirSync(rulesDir).forEach(file => { - if (path__default['default'].extname(file) !== ".js") { - return; - } - rules[file.slice(0, -3)] = commonjsRequire(path__default['default'].join(rulesDir, file)); - }); - rulesDirCache[rulesDir] = rules; - - return rules; -}; - -/** - * @fileoverview Defining the hashing function in one place. - * @author Michael Ficarra - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -//------------------------------------------------------------------------------ -// Private -//------------------------------------------------------------------------------ - -/** - * hash the given string - * @param {string} str the string to hash - * @returns {string} the hash - */ -function hash(str) { - return murmur__default['default'](str).result().toString(36); -} - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -var hash_1 = hash; - -/** - * @fileoverview Utility for caching lint results. - * @author Kevin Partington - */ - -//----------------------------------------------------------------------------- -// Requirements -//----------------------------------------------------------------------------- - - - - - - - - -const debug$1 = require$$0__default['default']("eslint:lint-result-cache"); - -//----------------------------------------------------------------------------- -// Helpers -//----------------------------------------------------------------------------- - -const configHashCache = new WeakMap(); -const nodeVersion = process && process.version; - -const validCacheStrategies = ["metadata", "content"]; -const invalidCacheStrategyErrorMessage = `Cache strategy must be one of: ${validCacheStrategies - .map(strategy => `"${strategy}"`) - .join(", ")}`; - -/** - * Tests whether a provided cacheStrategy is valid - * @param {string} cacheStrategy The cache strategy to use - * @returns {boolean} true if `cacheStrategy` is one of `validCacheStrategies`; false otherwise - */ -function isValidCacheStrategy(cacheStrategy) { - return ( - validCacheStrategies.indexOf(cacheStrategy) !== -1 - ); -} - -/** - * Calculates the hash of the config - * @param {ConfigArray} config The config. - * @returns {string} The hash of the config - */ -function hashOfConfigFor(config) { - if (!configHashCache.has(config)) { - configHashCache.set(config, hash_1(`${require$$3.version}_${nodeVersion}_${stringify__default['default'](config)}`)); - } - - return configHashCache.get(config); -} - -//----------------------------------------------------------------------------- -// Public Interface -//----------------------------------------------------------------------------- - -/** - * Lint result cache. This wraps around the file-entry-cache module, - * transparently removing properties that are difficult or expensive to - * serialize and adding them back in on retrieval. - */ -class LintResultCache { - - /** - * Creates a new LintResultCache instance. - * @param {string} cacheFileLocation The cache file location. - * @param {"metadata" | "content"} cacheStrategy The cache strategy to use. - */ - constructor(cacheFileLocation, cacheStrategy) { - assert__default['default'](cacheFileLocation, "Cache file location is required"); - assert__default['default'](cacheStrategy, "Cache strategy is required"); - assert__default['default']( - isValidCacheStrategy(cacheStrategy), - invalidCacheStrategyErrorMessage - ); - - debug$1(`Caching results to ${cacheFileLocation}`); - - const useChecksum = cacheStrategy === "content"; - - debug$1( - `Using "${cacheStrategy}" strategy to detect changes` - ); - - this.fileEntryCache = fileEntryCache__default['default'].create( - cacheFileLocation, - void 0, - useChecksum - ); - this.cacheFileLocation = cacheFileLocation; - } - - /** - * Retrieve cached lint results for a given file path, if present in the - * cache. If the file is present and has not been changed, rebuild any - * missing result information. - * @param {string} filePath The file for which to retrieve lint results. - * @param {ConfigArray} config The config of the file. - * @returns {Object|null} The rebuilt lint results, or null if the file is - * changed or not in the filesystem. - */ - getCachedLintResults(filePath, config) { - - /* - * Cached lint results are valid if and only if: - * 1. The file is present in the filesystem - * 2. The file has not changed since the time it was previously linted - * 3. The ESLint configuration has not changed since the time the file - * was previously linted - * If any of these are not true, we will not reuse the lint results. - */ - const fileDescriptor = this.fileEntryCache.getFileDescriptor(filePath); - const hashOfConfig = hashOfConfigFor(config); - const changed = - fileDescriptor.changed || - fileDescriptor.meta.hashOfConfig !== hashOfConfig; - - if (fileDescriptor.notFound) { - debug$1(`File not found on the file system: ${filePath}`); - return null; - } - - if (changed) { - debug$1(`Cache entry not found or no longer valid: ${filePath}`); - return null; - } - - // If source is present but null, need to reread the file from the filesystem. - if ( - fileDescriptor.meta.results && - fileDescriptor.meta.results.source === null - ) { - debug$1(`Rereading cached result source from filesystem: ${filePath}`); - fileDescriptor.meta.results.source = fs__default['default'].readFileSync(filePath, "utf-8"); - } - - return fileDescriptor.meta.results; - } - - /** - * Set the cached lint results for a given file path, after removing any - * information that will be both unnecessary and difficult to serialize. - * Avoids caching results with an "output" property (meaning fixes were - * applied), to prevent potentially incorrect results if fixes are not - * written to disk. - * @param {string} filePath The file for which to set lint results. - * @param {ConfigArray} config The config of the file. - * @param {Object} result The lint result to be set for the file. - * @returns {void} - */ - setCachedLintResults(filePath, config, result) { - if (result && Object.prototype.hasOwnProperty.call(result, "output")) { - return; - } - - const fileDescriptor = this.fileEntryCache.getFileDescriptor(filePath); - - if (fileDescriptor && !fileDescriptor.notFound) { - debug$1(`Updating cached result: ${filePath}`); - - // Serialize the result, except that we want to remove the file source if present. - const resultToSerialize = Object.assign({}, result); - - /* - * Set result.source to null. - * In `getCachedLintResults`, if source is explicitly null, we will - * read the file from the filesystem to set the value again. - */ - if (Object.prototype.hasOwnProperty.call(resultToSerialize, "source")) { - resultToSerialize.source = null; - } - - fileDescriptor.meta.results = resultToSerialize; - fileDescriptor.meta.hashOfConfig = hashOfConfigFor(config); - } - } - - /** - * Persists the in-memory cache to disk. - * @returns {void} - */ - reconcile() { - debug$1(`Persisting cached results: ${this.cacheFileLocation}`); - this.fileEntryCache.reconcile(); - } -} - -var lintResultCache = LintResultCache; - -/** - * @fileoverview Main CLI object. - * @author Nicholas C. Zakas - */ - -/* - * The CLI object should *not* call process.exit() directly. It should only return - * exit codes. This allows other programs to use the CLI object and still control - * when the program exits. - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - - - - -const { - Legacy: { - ConfigOps, - naming, - CascadingConfigArrayFactory, - IgnorePattern, - getUsedExtractedConfigs - } -} = require$$2__default['default']; - -/* - * For some reason, ModuleResolver must be included via filepath instead of by - * API exports in order to work properly. That's why this is separated out onto - * its own require() statement. - */ - -const { FileEnumerator } = fileEnumerator; - -const { Linter: Linter$1 } = linter; - - - - - -const debug = require$$0__default['default']("eslint:cli-engine"); -const validFixTypes = new Set(["problem", "suggestion", "layout"]); - -//------------------------------------------------------------------------------ -// Typedefs -//------------------------------------------------------------------------------ - -// For VSCode IntelliSense -/** @typedef {import("../shared/types").ConfigData} ConfigData */ -/** @typedef {import("../shared/types").DeprecatedRuleInfo} DeprecatedRuleInfo */ -/** @typedef {import("../shared/types").LintMessage} LintMessage */ -/** @typedef {import("../shared/types").ParserOptions} ParserOptions */ -/** @typedef {import("../shared/types").Plugin} Plugin */ -/** @typedef {import("../shared/types").RuleConf} RuleConf */ -/** @typedef {import("../shared/types").Rule} Rule */ -/** @typedef {ReturnType} ConfigArray */ -/** @typedef {ReturnType} ExtractedConfig */ - -/** - * The options to configure a CLI engine with. - * @typedef {Object} CLIEngineOptions - * @property {boolean} [allowInlineConfig] Enable or disable inline configuration comments. - * @property {ConfigData} [baseConfig] Base config object, extended by all configs used with this CLIEngine instance - * @property {boolean} [cache] Enable result caching. - * @property {string} [cacheLocation] The cache file to use instead of .eslintcache. - * @property {string} [configFile] The configuration file to use. - * @property {string} [cwd] The value to use for the current working directory. - * @property {string[]} [envs] An array of environments to load. - * @property {string[]|null} [extensions] An array of file extensions to check. - * @property {boolean|Function} [fix] Execute in autofix mode. If a function, should return a boolean. - * @property {string[]} [fixTypes] Array of rule types to apply fixes for. - * @property {string[]} [globals] An array of global variables to declare. - * @property {boolean} [ignore] False disables use of .eslintignore. - * @property {string} [ignorePath] The ignore file to use instead of .eslintignore. - * @property {string|string[]} [ignorePattern] One or more glob patterns to ignore. - * @property {boolean} [useEslintrc] False disables looking for .eslintrc - * @property {string} [parser] The name of the parser to use. - * @property {ParserOptions} [parserOptions] An object of parserOption settings to use. - * @property {string[]} [plugins] An array of plugins to load. - * @property {Record} [rules] An object of rules to use. - * @property {string[]} [rulePaths] An array of directories to load custom rules from. - * @property {boolean} [reportUnusedDisableDirectives] `true` adds reports for unused eslint-disable directives - * @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file. - * @property {string} [resolvePluginsRelativeTo] The folder where plugins should be resolved from, defaulting to the CWD - */ - -/** - * A linting result. - * @typedef {Object} LintResult - * @property {string} filePath The path to the file that was linted. - * @property {LintMessage[]} messages All of the messages for the result. - * @property {number} errorCount Number of errors for the result. - * @property {number} warningCount Number of warnings for the result. - * @property {number} fixableErrorCount Number of fixable errors for the result. - * @property {number} fixableWarningCount Number of fixable warnings for the result. - * @property {string} [source] The source code of the file that was linted. - * @property {string} [output] The source code of the file that was linted, with as many fixes applied as possible. - */ - -/** - * Linting results. - * @typedef {Object} LintReport - * @property {LintResult[]} results All of the result. - * @property {number} errorCount Number of errors for the result. - * @property {number} warningCount Number of warnings for the result. - * @property {number} fixableErrorCount Number of fixable errors for the result. - * @property {number} fixableWarningCount Number of fixable warnings for the result. - * @property {DeprecatedRuleInfo[]} usedDeprecatedRules The list of used deprecated rules. - */ - -/** - * Private data for CLIEngine. - * @typedef {Object} CLIEngineInternalSlots - * @property {Map} additionalPluginPool The map for additional plugins. - * @property {string} cacheFilePath The path to the cache of lint results. - * @property {CascadingConfigArrayFactory} configArrayFactory The factory of configs. - * @property {(filePath: string) => boolean} defaultIgnores The default predicate function to check if a file ignored or not. - * @property {FileEnumerator} fileEnumerator The file enumerator. - * @property {ConfigArray[]} lastConfigArrays The list of config arrays that the last `executeOnFiles` or `executeOnText` used. - * @property {LintResultCache|null} lintResultCache The cache of lint results. - * @property {Linter} linter The linter instance which has loaded rules. - * @property {CLIEngineOptions} options The normalized options of this instance. - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -/** @type {WeakMap} */ -const internalSlotsMap = new WeakMap(); - -/** - * Determines if each fix type in an array is supported by ESLint and throws - * an error if not. - * @param {string[]} fixTypes An array of fix types to check. - * @returns {void} - * @throws {Error} If an invalid fix type is found. - */ -function validateFixTypes(fixTypes) { - for (const fixType of fixTypes) { - if (!validFixTypes.has(fixType)) { - throw new Error(`Invalid fix type "${fixType}" found.`); - } - } -} - -/** - * It will calculate the error and warning count for collection of messages per file - * @param {LintMessage[]} messages Collection of messages - * @returns {Object} Contains the stats - * @private - */ -function calculateStatsPerFile(messages) { - return messages.reduce((stat, message) => { - if (message.fatal || message.severity === 2) { - stat.errorCount++; - if (message.fix) { - stat.fixableErrorCount++; - } - } else { - stat.warningCount++; - if (message.fix) { - stat.fixableWarningCount++; - } - } - return stat; - }, { - errorCount: 0, - warningCount: 0, - fixableErrorCount: 0, - fixableWarningCount: 0 - }); -} - -/** - * It will calculate the error and warning count for collection of results from all files - * @param {LintResult[]} results Collection of messages from all the files - * @returns {Object} Contains the stats - * @private - */ -function calculateStatsPerRun(results) { - return results.reduce((stat, result) => { - stat.errorCount += result.errorCount; - stat.warningCount += result.warningCount; - stat.fixableErrorCount += result.fixableErrorCount; - stat.fixableWarningCount += result.fixableWarningCount; - return stat; - }, { - errorCount: 0, - warningCount: 0, - fixableErrorCount: 0, - fixableWarningCount: 0 - }); -} - -/** - * Processes an source code using ESLint. - * @param {Object} config The config object. - * @param {string} config.text The source code to verify. - * @param {string} config.cwd The path to the current working directory. - * @param {string|undefined} config.filePath The path to the file of `text`. If this is undefined, it uses ``. - * @param {ConfigArray} config.config The config. - * @param {boolean} config.fix If `true` then it does fix. - * @param {boolean} config.allowInlineConfig If `true` then it uses directive comments. - * @param {boolean} config.reportUnusedDisableDirectives If `true` then it reports unused `eslint-disable` comments. - * @param {FileEnumerator} config.fileEnumerator The file enumerator to check if a path is a target or not. - * @param {Linter} config.linter The linter instance to verify. - * @returns {LintResult} The result of linting. - * @private - */ -function verifyText({ - text, - cwd, - filePath: providedFilePath, - config, - fix, - allowInlineConfig, - reportUnusedDisableDirectives, - fileEnumerator, - linter -}) { - const filePath = providedFilePath || ""; - - debug(`Lint ${filePath}`); - - /* - * Verify. - * `config.extractConfig(filePath)` requires an absolute path, but `linter` - * doesn't know CWD, so it gives `linter` an absolute path always. - */ - const filePathToVerify = filePath === "" ? path__default['default'].join(cwd, filePath) : filePath; - const { fixed, messages, output } = linter.verifyAndFix( - text, - config, - { - allowInlineConfig, - filename: filePathToVerify, - fix, - reportUnusedDisableDirectives, - - /** - * Check if the linter should adopt a given code block or not. - * @param {string} blockFilename The virtual filename of a code block. - * @returns {boolean} `true` if the linter should adopt the code block. - */ - filterCodeBlock(blockFilename) { - return fileEnumerator.isTargetPath(blockFilename); - } - } - ); - - // Tweak and return. - const result = { - filePath, - messages, - ...calculateStatsPerFile(messages) - }; - - if (fixed) { - result.output = output; - } - if ( - result.errorCount + result.warningCount > 0 && - typeof result.output === "undefined" - ) { - result.source = text; - } - - return result; -} - -/** - * Returns result with warning by ignore settings - * @param {string} filePath File path of checked code - * @param {string} baseDir Absolute path of base directory - * @returns {LintResult} Result with single warning - * @private - */ -function createIgnoreResult(filePath, baseDir) { - let message; - const isHidden = filePath.split(path__default['default'].sep) - .find(segment => /^\./u.test(segment)); - const isInNodeModules = baseDir && path__default['default'].relative(baseDir, filePath).startsWith("node_modules"); - - if (isHidden) { - message = "File ignored by default. Use a negated ignore pattern (like \"--ignore-pattern '!'\") to override."; - } else if (isInNodeModules) { - message = "File ignored by default. Use \"--ignore-pattern '!node_modules/*'\" to override."; - } else { - message = "File ignored because of a matching ignore pattern. Use \"--no-ignore\" to override."; - } - - return { - filePath: path__default['default'].resolve(filePath), - messages: [ - { - fatal: false, - severity: 1, - message - } - ], - errorCount: 0, - warningCount: 1, - fixableErrorCount: 0, - fixableWarningCount: 0 - }; -} - -/** - * Get a rule. - * @param {string} ruleId The rule ID to get. - * @param {ConfigArray[]} configArrays The config arrays that have plugin rules. - * @returns {Rule|null} The rule or null. - */ -function getRule(ruleId, configArrays) { - for (const configArray of configArrays) { - const rule = configArray.pluginRules.get(ruleId); - - if (rule) { - return rule; - } - } - return rules$2.get(ruleId) || null; -} - -/** - * Collect used deprecated rules. - * @param {ConfigArray[]} usedConfigArrays The config arrays which were used. - * @returns {IterableIterator} Used deprecated rules. - */ -function *iterateRuleDeprecationWarnings(usedConfigArrays) { - const processedRuleIds = new Set(); - - // Flatten used configs. - /** @type {ExtractedConfig[]} */ - const configs = [].concat( - ...usedConfigArrays.map(getUsedExtractedConfigs) - ); - - // Traverse rule configs. - for (const config of configs) { - for (const [ruleId, ruleConfig] of Object.entries(config.rules)) { - - // Skip if it was processed. - if (processedRuleIds.has(ruleId)) { - continue; - } - processedRuleIds.add(ruleId); - - // Skip if it's not used. - if (!ConfigOps.getRuleSeverity(ruleConfig)) { - continue; - } - const rule = getRule(ruleId, usedConfigArrays); - - // Skip if it's not deprecated. - if (!(rule && rule.meta && rule.meta.deprecated)) { - continue; - } - - // This rule was used and deprecated. - yield { - ruleId, - replacedBy: rule.meta.replacedBy || [] - }; - } - } -} - -/** - * Checks if the given message is an error message. - * @param {LintMessage} message The message to check. - * @returns {boolean} Whether or not the message is an error message. - * @private - */ -function isErrorMessage(message) { - return message.severity === 2; -} - - -/** - * return the cacheFile to be used by eslint, based on whether the provided parameter is - * a directory or looks like a directory (ends in `path.sep`), in which case the file - * name will be the `cacheFile/.cache_hashOfCWD` - * - * if cacheFile points to a file or looks like a file then in will just use that file - * @param {string} cacheFile The name of file to be used to store the cache - * @param {string} cwd Current working directory - * @returns {string} the resolved path to the cache file - */ -function getCacheFile(cacheFile, cwd) { - - /* - * make sure the path separators are normalized for the environment/os - * keeping the trailing path separator if present - */ - const normalizedCacheFile = path__default['default'].normalize(cacheFile); - - const resolvedCacheFile = path__default['default'].resolve(cwd, normalizedCacheFile); - const looksLikeADirectory = normalizedCacheFile.slice(-1) === path__default['default'].sep; - - /** - * return the name for the cache file in case the provided parameter is a directory - * @returns {string} the resolved path to the cacheFile - */ - function getCacheFileForDirectory() { - return path__default['default'].join(resolvedCacheFile, `.cache_${hash_1(cwd)}`); - } - - let fileStats; - - try { - fileStats = fs__default['default'].lstatSync(resolvedCacheFile); - } catch { - fileStats = null; - } - - - /* - * in case the file exists we need to verify if the provided path - * is a directory or a file. If it is a directory we want to create a file - * inside that directory - */ - if (fileStats) { - - /* - * is a directory or is a file, but the original file the user provided - * looks like a directory but `path.resolve` removed the `last path.sep` - * so we need to still treat this like a directory - */ - if (fileStats.isDirectory() || looksLikeADirectory) { - return getCacheFileForDirectory(); - } - - // is file so just use that file - return resolvedCacheFile; - } - - /* - * here we known the file or directory doesn't exist, - * so we will try to infer if its a directory if it looks like a directory - * for the current operating system. - */ - - // if the last character passed is a path separator we assume is a directory - if (looksLikeADirectory) { - return getCacheFileForDirectory(); - } - - return resolvedCacheFile; -} - -/** - * Convert a string array to a boolean map. - * @param {string[]|null} keys The keys to assign true. - * @param {boolean} defaultValue The default value for each property. - * @param {string} displayName The property name which is used in error message. - * @returns {Record} The boolean map. - */ -function toBooleanMap(keys, defaultValue, displayName) { - if (keys && !Array.isArray(keys)) { - throw new Error(`${displayName} must be an array.`); - } - if (keys && keys.length > 0) { - return keys.reduce((map, def) => { - const [key, value] = def.split(":"); - - if (key !== "__proto__") { - map[key] = value === void 0 - ? defaultValue - : value === "true"; - } - - return map; - }, {}); - } - return void 0; -} - -/** - * Create a config data from CLI options. - * @param {CLIEngineOptions} options The options - * @returns {ConfigData|null} The created config data. - */ -function createConfigDataFromOptions(options) { - const { - ignorePattern, - parser, - parserOptions, - plugins, - rules - } = options; - const env = toBooleanMap(options.envs, true, "envs"); - const globals = toBooleanMap(options.globals, false, "globals"); - - if ( - env === void 0 && - globals === void 0 && - (ignorePattern === void 0 || ignorePattern.length === 0) && - parser === void 0 && - parserOptions === void 0 && - plugins === void 0 && - rules === void 0 - ) { - return null; - } - return { - env, - globals, - ignorePatterns: ignorePattern, - parser, - parserOptions, - plugins, - rules - }; -} - -/** - * Checks whether a directory exists at the given location - * @param {string} resolvedPath A path from the CWD - * @returns {boolean} `true` if a directory exists - */ -function directoryExists(resolvedPath) { - try { - return fs__default['default'].statSync(resolvedPath).isDirectory(); - } catch (error) { - if (error && (error.code === "ENOENT" || error.code === "ENOTDIR")) { - return false; - } - throw error; - } -} - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -class CLIEngine$2 { - - /** - * Creates a new instance of the core CLI engine. - * @param {CLIEngineOptions} providedOptions The options for this instance. - */ - constructor(providedOptions) { - const options = Object.assign( - Object.create(null), - defaultCliOptions, - { cwd: process.cwd() }, - providedOptions - ); - - if (options.fix === void 0) { - options.fix = false; - } - - const additionalPluginPool = new Map(); - const cacheFilePath = getCacheFile( - options.cacheLocation || options.cacheFile, - options.cwd - ); - const configArrayFactory = new CascadingConfigArrayFactory({ - additionalPluginPool, - baseConfig: options.baseConfig || null, - cliConfig: createConfigDataFromOptions(options), - cwd: options.cwd, - ignorePath: options.ignorePath, - resolvePluginsRelativeTo: options.resolvePluginsRelativeTo, - rulePaths: options.rulePaths, - specificConfigPath: options.configFile, - useEslintrc: options.useEslintrc, - builtInRules: rules$2, - loadRules, - eslintRecommendedPath: path__default['default'].resolve(__dirname, "../../conf/eslint-recommended.js"), - eslintAllPath: path__default['default'].resolve(__dirname, "../../conf/eslint-all.js") - }); - const fileEnumerator = new FileEnumerator({ - configArrayFactory, - cwd: options.cwd, - extensions: options.extensions, - globInputPaths: options.globInputPaths, - errorOnUnmatchedPattern: options.errorOnUnmatchedPattern, - ignore: options.ignore - }); - const lintResultCache$1 = - options.cache ? new lintResultCache(cacheFilePath, options.cacheStrategy) : null; - const linter = new Linter$1({ cwd: options.cwd }); - - /** @type {ConfigArray[]} */ - const lastConfigArrays = [configArrayFactory.getConfigArrayForFile()]; - - // Store private data. - internalSlotsMap.set(this, { - additionalPluginPool, - cacheFilePath, - configArrayFactory, - defaultIgnores: IgnorePattern.createDefaultIgnore(options.cwd), - fileEnumerator, - lastConfigArrays, - lintResultCache: lintResultCache$1, - linter, - options - }); - - // setup special filter for fixes - if (options.fix && options.fixTypes && options.fixTypes.length > 0) { - debug(`Using fix types ${options.fixTypes}`); - - // throw an error if any invalid fix types are found - validateFixTypes(options.fixTypes); - - // convert to Set for faster lookup - const fixTypes = new Set(options.fixTypes); - - // save original value of options.fix in case it's a function - const originalFix = (typeof options.fix === "function") - ? options.fix : () => true; - - options.fix = message => { - const rule = message.ruleId && getRule(message.ruleId, lastConfigArrays); - const matches = rule && rule.meta && fixTypes.has(rule.meta.type); - - return matches && originalFix(message); - }; - } - } - - getRules() { - const { lastConfigArrays } = internalSlotsMap.get(this); - - return new Map(function *() { - yield* rules$2; - - for (const configArray of lastConfigArrays) { - yield* configArray.pluginRules; - } - }()); - } - - /** - * Returns results that only contains errors. - * @param {LintResult[]} results The results to filter. - * @returns {LintResult[]} The filtered results. - */ - static getErrorResults(results) { - const filtered = []; - - results.forEach(result => { - const filteredMessages = result.messages.filter(isErrorMessage); - - if (filteredMessages.length > 0) { - filtered.push({ - ...result, - messages: filteredMessages, - errorCount: filteredMessages.length, - warningCount: 0, - fixableErrorCount: result.fixableErrorCount, - fixableWarningCount: 0 - }); - } - }); - - return filtered; - } - - /** - * Outputs fixes from the given results to files. - * @param {LintReport} report The report object created by CLIEngine. - * @returns {void} - */ - static outputFixes(report) { - report.results.filter(result => Object.prototype.hasOwnProperty.call(result, "output")).forEach(result => { - fs__default['default'].writeFileSync(result.filePath, result.output); - }); - } - - - /** - * Add a plugin by passing its configuration - * @param {string} name Name of the plugin. - * @param {Plugin} pluginObject Plugin configuration object. - * @returns {void} - */ - addPlugin(name, pluginObject) { - const { - additionalPluginPool, - configArrayFactory, - lastConfigArrays - } = internalSlotsMap.get(this); - - additionalPluginPool.set(name, pluginObject); - configArrayFactory.clearCache(); - lastConfigArrays.length = 1; - lastConfigArrays[0] = configArrayFactory.getConfigArrayForFile(); - } - - /** - * Resolves the patterns passed into executeOnFiles() into glob-based patterns - * for easier handling. - * @param {string[]} patterns The file patterns passed on the command line. - * @returns {string[]} The equivalent glob patterns. - */ - resolveFileGlobPatterns(patterns) { - const { options } = internalSlotsMap.get(this); - - if (options.globInputPaths === false) { - return patterns.filter(Boolean); - } - - const extensions = (options.extensions || [".js"]).map(ext => ext.replace(/^\./u, "")); - const dirSuffix = `/**/*.{${extensions.join(",")}}`; - - return patterns.filter(Boolean).map(pathname => { - const resolvedPath = path__default['default'].resolve(options.cwd, pathname); - const newPath = directoryExists(resolvedPath) - ? pathname.replace(/[/\\]$/u, "") + dirSuffix - : pathname; - - return path__default['default'].normalize(newPath).replace(/\\/gu, "/"); - }); - } - - /** - * Executes the current configuration on an array of file and directory names. - * @param {string[]} patterns An array of file and directory names. - * @returns {LintReport} The results for all files that were linted. - */ - executeOnFiles(patterns) { - const { - cacheFilePath, - fileEnumerator, - lastConfigArrays, - lintResultCache, - linter, - options: { - allowInlineConfig, - cache, - cwd, - fix, - reportUnusedDisableDirectives - } - } = internalSlotsMap.get(this); - const results = []; - const startTime = Date.now(); - - // Clear the last used config arrays. - lastConfigArrays.length = 0; - - // Delete cache file; should this do here? - if (!cache) { - try { - fs__default['default'].unlinkSync(cacheFilePath); - } catch (error) { - const errorCode = error && error.code; - - // Ignore errors when no such file exists or file system is read only (and cache file does not exist) - if (errorCode !== "ENOENT" && !(errorCode === "EROFS" && !fs__default['default'].existsSync(cacheFilePath))) { - throw error; - } - } - } - - // Iterate source code files. - for (const { config, filePath, ignored } of fileEnumerator.iterateFiles(patterns)) { - if (ignored) { - results.push(createIgnoreResult(filePath, cwd)); - continue; - } - - /* - * Store used configs for: - * - this method uses to collect used deprecated rules. - * - `getRules()` method uses to collect all loaded rules. - * - `--fix-type` option uses to get the loaded rule's meta data. - */ - if (!lastConfigArrays.includes(config)) { - lastConfigArrays.push(config); - } - - // Skip if there is cached result. - if (lintResultCache) { - const cachedResult = - lintResultCache.getCachedLintResults(filePath, config); - - if (cachedResult) { - const hadMessages = - cachedResult.messages && - cachedResult.messages.length > 0; - - if (hadMessages && fix) { - debug(`Reprocessing cached file to allow autofix: ${filePath}`); - } else { - debug(`Skipping file since it hasn't changed: ${filePath}`); - results.push(cachedResult); - continue; - } - } - } - - // Do lint. - const result = verifyText({ - text: fs__default['default'].readFileSync(filePath, "utf8"), - filePath, - config, - cwd, - fix, - allowInlineConfig, - reportUnusedDisableDirectives, - fileEnumerator, - linter - }); - - results.push(result); - - /* - * Store the lint result in the LintResultCache. - * NOTE: The LintResultCache will remove the file source and any - * other properties that are difficult to serialize, and will - * hydrate those properties back in on future lint runs. - */ - if (lintResultCache) { - lintResultCache.setCachedLintResults(filePath, config, result); - } - } - - // Persist the cache to disk. - if (lintResultCache) { - lintResultCache.reconcile(); - } - - debug(`Linting complete in: ${Date.now() - startTime}ms`); - let usedDeprecatedRules; - - return { - results, - ...calculateStatsPerRun(results), - - // Initialize it lazily because CLI and `ESLint` API don't use it. - get usedDeprecatedRules() { - if (!usedDeprecatedRules) { - usedDeprecatedRules = Array.from( - iterateRuleDeprecationWarnings(lastConfigArrays) - ); - } - return usedDeprecatedRules; - } - }; - } - - /** - * Executes the current configuration on text. - * @param {string} text A string of JavaScript code to lint. - * @param {string} [filename] An optional string representing the texts filename. - * @param {boolean} [warnIgnored] Always warn when a file is ignored - * @returns {LintReport} The results for the linting. - */ - executeOnText(text, filename, warnIgnored) { - const { - configArrayFactory, - fileEnumerator, - lastConfigArrays, - linter, - options: { - allowInlineConfig, - cwd, - fix, - reportUnusedDisableDirectives - } - } = internalSlotsMap.get(this); - const results = []; - const startTime = Date.now(); - const resolvedFilename = filename && path__default['default'].resolve(cwd, filename); - - - // Clear the last used config arrays. - lastConfigArrays.length = 0; - if (resolvedFilename && this.isPathIgnored(resolvedFilename)) { - if (warnIgnored) { - results.push(createIgnoreResult(resolvedFilename, cwd)); - } - } else { - const config = configArrayFactory.getConfigArrayForFile( - resolvedFilename || "__placeholder__.js" - ); - - /* - * Store used configs for: - * - this method uses to collect used deprecated rules. - * - `getRules()` method uses to collect all loaded rules. - * - `--fix-type` option uses to get the loaded rule's meta data. - */ - lastConfigArrays.push(config); - - // Do lint. - results.push(verifyText({ - text, - filePath: resolvedFilename, - config, - cwd, - fix, - allowInlineConfig, - reportUnusedDisableDirectives, - fileEnumerator, - linter - })); - } - - debug(`Linting complete in: ${Date.now() - startTime}ms`); - let usedDeprecatedRules; - - return { - results, - ...calculateStatsPerRun(results), - - // Initialize it lazily because CLI and `ESLint` API don't use it. - get usedDeprecatedRules() { - if (!usedDeprecatedRules) { - usedDeprecatedRules = Array.from( - iterateRuleDeprecationWarnings(lastConfigArrays) - ); - } - return usedDeprecatedRules; - } - }; - } - - /** - * Returns a configuration object for the given file based on the CLI options. - * This is the same logic used by the ESLint CLI executable to determine - * configuration for each file it processes. - * @param {string} filePath The path of the file to retrieve a config object for. - * @returns {ConfigData} A configuration object for the file. - */ - getConfigForFile(filePath) { - const { configArrayFactory, options } = internalSlotsMap.get(this); - const absolutePath = path__default['default'].resolve(options.cwd, filePath); - - if (directoryExists(absolutePath)) { - throw Object.assign( - new Error("'filePath' should not be a directory path."), - { messageTemplate: "print-config-with-directory-path" } - ); - } - - return configArrayFactory - .getConfigArrayForFile(absolutePath) - .extractConfig(absolutePath) - .toCompatibleObjectAsConfigFileContent(); - } - - /** - * Checks if a given path is ignored by ESLint. - * @param {string} filePath The path of the file to check. - * @returns {boolean} Whether or not the given path is ignored. - */ - isPathIgnored(filePath) { - const { - configArrayFactory, - defaultIgnores, - options: { cwd, ignore } - } = internalSlotsMap.get(this); - const absolutePath = path__default['default'].resolve(cwd, filePath); - - if (ignore) { - const config = configArrayFactory - .getConfigArrayForFile(absolutePath) - .extractConfig(absolutePath); - const ignores = config.ignores || defaultIgnores; - - return ignores(absolutePath); - } - - return defaultIgnores(absolutePath); - } - - /** - * Returns the formatter representing the given format or null if the `format` is not a string. - * @param {string} [format] The name of the format to load or the path to a - * custom formatter. - * @returns {(Function|null)} The formatter function or null if the `format` is not a string. - */ - getFormatter(format) { - - // default is stylish - const resolvedFormatName = format || "stylish"; - - // only strings are valid formatters - if (typeof resolvedFormatName === "string") { - - // replace \ with / for Windows compatibility - const normalizedFormatName = resolvedFormatName.replace(/\\/gu, "/"); - - const slots = internalSlotsMap.get(this); - const cwd = slots ? slots.options.cwd : process.cwd(); - const namespace = naming.getNamespaceFromTerm(normalizedFormatName); - - let formatterPath; - - // if there's a slash, then it's a file (TODO: this check seems dubious for scoped npm packages) - if (!namespace && normalizedFormatName.indexOf("/") > -1) { - formatterPath = path__default['default'].resolve(cwd, normalizedFormatName); - } else { - try { - const npmFormat = naming.normalizePackageName(normalizedFormatName, "eslint-formatter"); - - formatterPath = relativeModuleResolver.resolve(npmFormat, path__default['default'].join(cwd, "__placeholder__.js")); - } catch { - formatterPath = path__default['default'].resolve(__dirname, "formatters", normalizedFormatName); - } - } - - try { - return commonjsRequire(formatterPath); - } catch (ex) { - ex.message = `There was a problem loading formatter: ${formatterPath}\nError: ${ex.message}`; - throw ex; - } - - } else { - return null; - } - } -} - -CLIEngine$2.version = require$$3.version; -CLIEngine$2.getFormatter = CLIEngine$2.prototype.getFormatter; - -var cliEngine$1 = { - CLIEngine: CLIEngine$2, - - /** - * Get the internal slots of a given CLIEngine instance for tests. - * @param {CLIEngine} instance The CLIEngine instance to get. - * @returns {CLIEngineInternalSlots} The internal slots. - */ - getCLIEngineInternalSlots(instance) { - return internalSlotsMap.get(instance); - } -}; - -const { CLIEngine: CLIEngine$1 } = cliEngine$1; - -var cliEngine = { - CLIEngine: CLIEngine$1 -}; - -/** - * @fileoverview Main API Class - * @author Kai Cataldo - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -const { promisify } = util__default['default']; -const { CLIEngine, getCLIEngineInternalSlots } = cliEngine$1; - -const { - Legacy: { - ConfigOps: { - getRuleSeverity - } - } -} = require$$2__default['default']; -const { version } = require$$3; - -//------------------------------------------------------------------------------ -// Typedefs -//------------------------------------------------------------------------------ - -/** @typedef {import("../cli-engine/cli-engine").LintReport} CLIEngineLintReport */ -/** @typedef {import("../shared/types").DeprecatedRuleInfo} DeprecatedRuleInfo */ -/** @typedef {import("../shared/types").ConfigData} ConfigData */ -/** @typedef {import("../shared/types").LintMessage} LintMessage */ -/** @typedef {import("../shared/types").Plugin} Plugin */ -/** @typedef {import("../shared/types").Rule} Rule */ -/** @typedef {import("./load-formatter").Formatter} Formatter */ - -/** - * The options with which to configure the ESLint instance. - * @typedef {Object} ESLintOptions - * @property {boolean} [allowInlineConfig] Enable or disable inline configuration comments. - * @property {ConfigData} [baseConfig] Base config object, extended by all configs used with this instance - * @property {boolean} [cache] Enable result caching. - * @property {string} [cacheLocation] The cache file to use instead of .eslintcache. - * @property {"metadata" | "content"} [cacheStrategy] The strategy used to detect changed files. - * @property {string} [cwd] The value to use for the current working directory. - * @property {boolean} [errorOnUnmatchedPattern] If `false` then `ESLint#lintFiles()` doesn't throw even if no target files found. Defaults to `true`. - * @property {string[]} [extensions] An array of file extensions to check. - * @property {boolean|Function} [fix] Execute in autofix mode. If a function, should return a boolean. - * @property {string[]} [fixTypes] Array of rule types to apply fixes for. - * @property {boolean} [globInputPaths] Set to false to skip glob resolution of input file paths to lint (default: true). If false, each input file paths is assumed to be a non-glob path to an existing file. - * @property {boolean} [ignore] False disables use of .eslintignore. - * @property {string} [ignorePath] The ignore file to use instead of .eslintignore. - * @property {ConfigData} [overrideConfig] Override config object, overrides all configs used with this instance - * @property {string} [overrideConfigFile] The configuration file to use. - * @property {Record} [plugins] An array of plugin implementations. - * @property {"error" | "warn" | "off"} [reportUnusedDisableDirectives] the severity to report unused eslint-disable directives. - * @property {string} [resolvePluginsRelativeTo] The folder where plugins should be resolved from, defaulting to the CWD. - * @property {string[]} [rulePaths] An array of directories to load custom rules from. - * @property {boolean} [useEslintrc] False disables looking for .eslintrc.* files. - */ - -/** - * A rules metadata object. - * @typedef {Object} RulesMeta - * @property {string} id The plugin ID. - * @property {Object} definition The plugin definition. - */ - -/** - * A linting result. - * @typedef {Object} LintResult - * @property {string} filePath The path to the file that was linted. - * @property {LintMessage[]} messages All of the messages for the result. - * @property {number} errorCount Number of errors for the result. - * @property {number} warningCount Number of warnings for the result. - * @property {number} fixableErrorCount Number of fixable errors for the result. - * @property {number} fixableWarningCount Number of fixable warnings for the result. - * @property {string} [source] The source code of the file that was linted. - * @property {string} [output] The source code of the file that was linted, with as many fixes applied as possible. - * @property {DeprecatedRuleInfo[]} usedDeprecatedRules The list of used deprecated rules. - */ - -/** - * Private members for the `ESLint` instance. - * @typedef {Object} ESLintPrivateMembers - * @property {CLIEngine} cliEngine The wrapped CLIEngine instance. - * @property {ESLintOptions} options The options used to instantiate the ESLint instance. - */ - -//------------------------------------------------------------------------------ -// Helpers -//------------------------------------------------------------------------------ - -const writeFile = promisify(fs__default['default'].writeFile); - -/** - * The map with which to store private class members. - * @type {WeakMap} - */ -const privateMembersMap = new WeakMap(); - -/** - * Check if a given value is a non-empty string or not. - * @param {any} x The value to check. - * @returns {boolean} `true` if `x` is a non-empty string. - */ -function isNonEmptyString(x) { - return typeof x === "string" && x.trim() !== ""; -} - -/** - * Check if a given value is an array of non-empty stringss or not. - * @param {any} x The value to check. - * @returns {boolean} `true` if `x` is an array of non-empty stringss. - */ -function isArrayOfNonEmptyString(x) { - return Array.isArray(x) && x.every(isNonEmptyString); -} - -/** - * Check if a given value is a valid fix type or not. - * @param {any} x The value to check. - * @returns {boolean} `true` if `x` is valid fix type. - */ -function isFixType(x) { - return x === "problem" || x === "suggestion" || x === "layout"; -} - -/** - * Check if a given value is an array of fix types or not. - * @param {any} x The value to check. - * @returns {boolean} `true` if `x` is an array of fix types. - */ -function isFixTypeArray(x) { - return Array.isArray(x) && x.every(isFixType); -} - -/** - * The error for invalid options. - */ -class ESLintInvalidOptionsError extends Error { - constructor(messages) { - super(`Invalid Options:\n- ${messages.join("\n- ")}`); - this.code = "ESLINT_INVALID_OPTIONS"; - Error.captureStackTrace(this, ESLintInvalidOptionsError); - } -} - -/** - * Validates and normalizes options for the wrapped CLIEngine instance. - * @param {ESLintOptions} options The options to process. - * @returns {ESLintOptions} The normalized options. - */ -function processOptions({ - allowInlineConfig = true, // ← we cannot use `overrideConfig.noInlineConfig` instead because `allowInlineConfig` has side-effect that suppress warnings that show inline configs are ignored. - baseConfig = null, - cache = false, - cacheLocation = ".eslintcache", - cacheStrategy = "metadata", - cwd = process.cwd(), - errorOnUnmatchedPattern = true, - extensions = null, // ← should be null by default because if it's an array then it suppresses RFC20 feature. - fix = false, - fixTypes = null, // ← should be null by default because if it's an array then it suppresses rules that don't have the `meta.type` property. - globInputPaths = true, - ignore = true, - ignorePath = null, // ← should be null by default because if it's a string then it may throw ENOENT. - overrideConfig = null, - overrideConfigFile = null, - plugins = {}, - reportUnusedDisableDirectives = null, // ← should be null by default because if it's a string then it overrides the 'reportUnusedDisableDirectives' setting in config files. And we cannot use `overrideConfig.reportUnusedDisableDirectives` instead because we cannot configure the `error` severity with that. - resolvePluginsRelativeTo = null, // ← should be null by default because if it's a string then it suppresses RFC47 feature. - rulePaths = [], - useEslintrc = true, - ...unknownOptions -}) { - const errors = []; - const unknownOptionKeys = Object.keys(unknownOptions); - - if (unknownOptionKeys.length >= 1) { - errors.push(`Unknown options: ${unknownOptionKeys.join(", ")}`); - if (unknownOptionKeys.includes("cacheFile")) { - errors.push("'cacheFile' has been removed. Please use the 'cacheLocation' option instead."); - } - if (unknownOptionKeys.includes("configFile")) { - errors.push("'configFile' has been removed. Please use the 'overrideConfigFile' option instead."); - } - if (unknownOptionKeys.includes("envs")) { - errors.push("'envs' has been removed. Please use the 'overrideConfig.env' option instead."); - } - if (unknownOptionKeys.includes("globals")) { - errors.push("'globals' has been removed. Please use the 'overrideConfig.globals' option instead."); - } - if (unknownOptionKeys.includes("ignorePattern")) { - errors.push("'ignorePattern' has been removed. Please use the 'overrideConfig.ignorePatterns' option instead."); - } - if (unknownOptionKeys.includes("parser")) { - errors.push("'parser' has been removed. Please use the 'overrideConfig.parser' option instead."); - } - if (unknownOptionKeys.includes("parserOptions")) { - errors.push("'parserOptions' has been removed. Please use the 'overrideConfig.parserOptions' option instead."); - } - if (unknownOptionKeys.includes("rules")) { - errors.push("'rules' has been removed. Please use the 'overrideConfig.rules' option instead."); - } - } - if (typeof allowInlineConfig !== "boolean") { - errors.push("'allowInlineConfig' must be a boolean."); - } - if (typeof baseConfig !== "object") { - errors.push("'baseConfig' must be an object or null."); - } - if (typeof cache !== "boolean") { - errors.push("'cache' must be a boolean."); - } - if (!isNonEmptyString(cacheLocation)) { - errors.push("'cacheLocation' must be a non-empty string."); - } - if ( - cacheStrategy !== "metadata" && - cacheStrategy !== "content" - ) { - errors.push("'cacheStrategy' must be any of \"metadata\", \"content\"."); - } - if (!isNonEmptyString(cwd) || !path__default['default'].isAbsolute(cwd)) { - errors.push("'cwd' must be an absolute path."); - } - if (typeof errorOnUnmatchedPattern !== "boolean") { - errors.push("'errorOnUnmatchedPattern' must be a boolean."); - } - if (!isArrayOfNonEmptyString(extensions) && extensions !== null) { - errors.push("'extensions' must be an array of non-empty strings or null."); - } - if (typeof fix !== "boolean" && typeof fix !== "function") { - errors.push("'fix' must be a boolean or a function."); - } - if (fixTypes !== null && !isFixTypeArray(fixTypes)) { - errors.push("'fixTypes' must be an array of any of \"problem\", \"suggestion\", and \"layout\"."); - } - if (typeof globInputPaths !== "boolean") { - errors.push("'globInputPaths' must be a boolean."); - } - if (typeof ignore !== "boolean") { - errors.push("'ignore' must be a boolean."); - } - if (!isNonEmptyString(ignorePath) && ignorePath !== null) { - errors.push("'ignorePath' must be a non-empty string or null."); - } - if (typeof overrideConfig !== "object") { - errors.push("'overrideConfig' must be an object or null."); - } - if (!isNonEmptyString(overrideConfigFile) && overrideConfigFile !== null) { - errors.push("'overrideConfigFile' must be a non-empty string or null."); - } - if (typeof plugins !== "object") { - errors.push("'plugins' must be an object or null."); - } else if (plugins !== null && Object.keys(plugins).includes("")) { - errors.push("'plugins' must not include an empty string."); - } - if (Array.isArray(plugins)) { - errors.push("'plugins' doesn't add plugins to configuration to load. Please use the 'overrideConfig.plugins' option instead."); - } - if ( - reportUnusedDisableDirectives !== "error" && - reportUnusedDisableDirectives !== "warn" && - reportUnusedDisableDirectives !== "off" && - reportUnusedDisableDirectives !== null - ) { - errors.push("'reportUnusedDisableDirectives' must be any of \"error\", \"warn\", \"off\", and null."); - } - if ( - !isNonEmptyString(resolvePluginsRelativeTo) && - resolvePluginsRelativeTo !== null - ) { - errors.push("'resolvePluginsRelativeTo' must be a non-empty string or null."); - } - if (!isArrayOfNonEmptyString(rulePaths)) { - errors.push("'rulePaths' must be an array of non-empty strings."); - } - if (typeof useEslintrc !== "boolean") { - errors.push("'useEslintrc' must be a boolean."); - } - - if (errors.length > 0) { - throw new ESLintInvalidOptionsError(errors); - } - - return { - allowInlineConfig, - baseConfig, - cache, - cacheLocation, - cacheStrategy, - configFile: overrideConfigFile, - cwd, - errorOnUnmatchedPattern, - extensions, - fix, - fixTypes, - globInputPaths, - ignore, - ignorePath, - reportUnusedDisableDirectives, - resolvePluginsRelativeTo, - rulePaths, - useEslintrc - }; -} - -/** - * Check if a value has one or more properties and that value is not undefined. - * @param {any} obj The value to check. - * @returns {boolean} `true` if `obj` has one or more properties that that value is not undefined. - */ -function hasDefinedProperty(obj) { - if (typeof obj === "object" && obj !== null) { - for (const key in obj) { - if (typeof obj[key] !== "undefined") { - return true; - } - } - } - return false; -} - -/** - * Create rulesMeta object. - * @param {Map} rules a map of rules from which to generate the object. - * @returns {Object} metadata for all enabled rules. - */ -function createRulesMeta(rules) { - return Array.from(rules).reduce((retVal, [id, rule]) => { - retVal[id] = rule.meta; - return retVal; - }, {}); -} - -/** @type {WeakMap} */ -const usedDeprecatedRulesCache = new WeakMap(); - -/** - * Create used deprecated rule list. - * @param {CLIEngine} cliEngine The CLIEngine instance. - * @param {string} maybeFilePath The absolute path to a lint target file or `""`. - * @returns {DeprecatedRuleInfo[]} The used deprecated rule list. - */ -function getOrFindUsedDeprecatedRules(cliEngine, maybeFilePath) { - const { - configArrayFactory, - options: { cwd } - } = getCLIEngineInternalSlots(cliEngine); - const filePath = path__default['default'].isAbsolute(maybeFilePath) - ? maybeFilePath - : path__default['default'].join(cwd, "__placeholder__.js"); - const configArray = configArrayFactory.getConfigArrayForFile(filePath); - const config = configArray.extractConfig(filePath); - - // Most files use the same config, so cache it. - if (!usedDeprecatedRulesCache.has(config)) { - const pluginRules = configArray.pluginRules; - const retv = []; - - for (const [ruleId, ruleConf] of Object.entries(config.rules)) { - if (getRuleSeverity(ruleConf) === 0) { - continue; - } - const rule = pluginRules.get(ruleId) || rules$2.get(ruleId); - const meta = rule && rule.meta; - - if (meta && meta.deprecated) { - retv.push({ ruleId, replacedBy: meta.replacedBy || [] }); - } - } - - usedDeprecatedRulesCache.set(config, Object.freeze(retv)); - } - - return usedDeprecatedRulesCache.get(config); -} - -/** - * Processes the linting results generated by a CLIEngine linting report to - * match the ESLint class's API. - * @param {CLIEngine} cliEngine The CLIEngine instance. - * @param {CLIEngineLintReport} report The CLIEngine linting report to process. - * @returns {LintResult[]} The processed linting results. - */ -function processCLIEngineLintReport(cliEngine, { results }) { - const descriptor = { - configurable: true, - enumerable: true, - get() { - return getOrFindUsedDeprecatedRules(cliEngine, this.filePath); - } - }; - - for (const result of results) { - Object.defineProperty(result, "usedDeprecatedRules", descriptor); - } - - return results; -} - -/** - * An Array.prototype.sort() compatible compare function to order results by their file path. - * @param {LintResult} a The first lint result. - * @param {LintResult} b The second lint result. - * @returns {number} An integer representing the order in which the two results should occur. - */ -function compareResultsByFilePath(a, b) { - if (a.filePath < b.filePath) { - return -1; - } - - if (a.filePath > b.filePath) { - return 1; - } - - return 0; -} - -class ESLint$1 { - - /** - * Creates a new instance of the main ESLint API. - * @param {ESLintOptions} options The options for this instance. - */ - constructor(options = {}) { - const processedOptions = processOptions(options); - const cliEngine = new CLIEngine(processedOptions); - const { - additionalPluginPool, - configArrayFactory, - lastConfigArrays - } = getCLIEngineInternalSlots(cliEngine); - let updated = false; - - /* - * Address `plugins` to add plugin implementations. - * Operate the `additionalPluginPool` internal slot directly to avoid - * using `addPlugin(id, plugin)` method that resets cache everytime. - */ - if (options.plugins) { - for (const [id, plugin] of Object.entries(options.plugins)) { - additionalPluginPool.set(id, plugin); - updated = true; - } - } - - /* - * Address `overrideConfig` to set override config. - * Operate the `configArrayFactory` internal slot directly because this - * functionality doesn't exist as the public API of CLIEngine. - */ - if (hasDefinedProperty(options.overrideConfig)) { - configArrayFactory.setOverrideConfig(options.overrideConfig); - updated = true; - } - - // Update caches. - if (updated) { - configArrayFactory.clearCache(); - lastConfigArrays[0] = configArrayFactory.getConfigArrayForFile(); - } - - // Initialize private properties. - privateMembersMap.set(this, { - cliEngine, - options: processedOptions - }); - } - - /** - * The version text. - * @type {string} - */ - static get version() { - return version; - } - - /** - * Outputs fixes from the given results to files. - * @param {LintResult[]} results The lint results. - * @returns {Promise} Returns a promise that is used to track side effects. - */ - static async outputFixes(results) { - if (!Array.isArray(results)) { - throw new Error("'results' must be an array"); - } - - await Promise.all( - results - .filter(result => { - if (typeof result !== "object" || result === null) { - throw new Error("'results' must include only objects"); - } - return ( - typeof result.output === "string" && - path__default['default'].isAbsolute(result.filePath) - ); - }) - .map(r => writeFile(r.filePath, r.output)) - ); - } - - /** - * Returns results that only contains errors. - * @param {LintResult[]} results The results to filter. - * @returns {LintResult[]} The filtered results. - */ - static getErrorResults(results) { - return CLIEngine.getErrorResults(results); - } - - /** - * Executes the current configuration on an array of file and directory names. - * @param {string[]} patterns An array of file and directory names. - * @returns {Promise} The results of linting the file patterns given. - */ - async lintFiles(patterns) { - if (!isNonEmptyString(patterns) && !isArrayOfNonEmptyString(patterns)) { - throw new Error("'patterns' must be a non-empty string or an array of non-empty strings"); - } - const { cliEngine } = privateMembersMap.get(this); - - return processCLIEngineLintReport( - cliEngine, - cliEngine.executeOnFiles(patterns) - ); - } - - /** - * Executes the current configuration on text. - * @param {string} code A string of JavaScript code to lint. - * @param {Object} [options] The options. - * @param {string} [options.filePath] The path to the file of the source code. - * @param {boolean} [options.warnIgnored] When set to true, warn if given filePath is an ignored path. - * @returns {Promise} The results of linting the string of code given. - */ - async lintText(code, options = {}) { - if (typeof code !== "string") { - throw new Error("'code' must be a string"); - } - if (typeof options !== "object") { - throw new Error("'options' must be an object, null, or undefined"); - } - const { - filePath, - warnIgnored = false, - ...unknownOptions - } = options || {}; - - for (const key of Object.keys(unknownOptions)) { - throw new Error(`'options' must not include the unknown option '${key}'`); - } - if (filePath !== void 0 && !isNonEmptyString(filePath)) { - throw new Error("'options.filePath' must be a non-empty string or undefined"); - } - if (typeof warnIgnored !== "boolean") { - throw new Error("'options.warnIgnored' must be a boolean or undefined"); - } - - const { cliEngine } = privateMembersMap.get(this); - - return processCLIEngineLintReport( - cliEngine, - cliEngine.executeOnText(code, filePath, warnIgnored) - ); - } - - /** - * Returns the formatter representing the given formatter name. - * @param {string} [name] The name of the formatter to load. - * The following values are allowed: - * - `undefined` ... Load `stylish` builtin formatter. - * - A builtin formatter name ... Load the builtin formatter. - * - A thirdparty formatter name: - * - `foo` → `eslint-formatter-foo` - * - `@foo` → `@foo/eslint-formatter` - * - `@foo/bar` → `@foo/eslint-formatter-bar` - * - A file path ... Load the file. - * @returns {Promise} A promise resolving to the formatter object. - * This promise will be rejected if the given formatter was not found or not - * a function. - */ - async loadFormatter(name = "stylish") { - if (typeof name !== "string") { - throw new Error("'name' must be a string"); - } - - const { cliEngine } = privateMembersMap.get(this); - const formatter = cliEngine.getFormatter(name); - - if (typeof formatter !== "function") { - throw new Error(`Formatter must be a function, but got a ${typeof formatter}.`); - } - - return { - - /** - * The main formatter method. - * @param {LintResults[]} results The lint results to format. - * @returns {string} The formatted lint results. - */ - format(results) { - let rulesMeta = null; - - results.sort(compareResultsByFilePath); - - return formatter(results, { - get rulesMeta() { - if (!rulesMeta) { - rulesMeta = createRulesMeta(cliEngine.getRules()); - } - - return rulesMeta; - } - }); - } - }; - } - - /** - * Returns a configuration object for the given file based on the CLI options. - * This is the same logic used by the ESLint CLI executable to determine - * configuration for each file it processes. - * @param {string} filePath The path of the file to retrieve a config object for. - * @returns {Promise} A configuration object for the file. - */ - async calculateConfigForFile(filePath) { - if (!isNonEmptyString(filePath)) { - throw new Error("'filePath' must be a non-empty string"); - } - const { cliEngine } = privateMembersMap.get(this); - - return cliEngine.getConfigForFile(filePath); - } - - /** - * Checks if a given path is ignored by ESLint. - * @param {string} filePath The path of the file to check. - * @returns {Promise} Whether or not the given path is ignored. - */ - async isPathIgnored(filePath) { - if (!isNonEmptyString(filePath)) { - throw new Error("'filePath' must be a non-empty string"); - } - const { cliEngine } = privateMembersMap.get(this); - - return cliEngine.isPathIgnored(filePath); - } -} - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -var eslint$1 = { - ESLint: ESLint$1, - - /** - * Get the private class members of a given ESLint instance for tests. - * @param {ESLint} instance The ESLint instance to get. - * @returns {ESLintPrivateMembers} The instance's private class members. - */ - getESLintPrivateMembers(instance) { - return privateMembersMap.get(instance); - } -}; - -const { ESLint } = eslint$1; - -var eslint = { - ESLint -}; - -/* - * STOP!!! DO NOT MODIFY. - * - * This file is part of the ongoing work to move the eslintrc-style config - * system into the @eslint/eslintrc package. This file needs to remain - * unchanged in order for this work to proceed. - * - * If you think you need to change this file, please contact @nzakas first. - * - * Thanks in advance for your cooperation. - */ - -const baseConfigProperties = { - $schema: { type: "string" }, - env: { type: "object" }, - extends: { $ref: "#/definitions/stringOrStrings" }, - globals: { type: "object" }, - overrides: { - type: "array", - items: { $ref: "#/definitions/overrideConfig" }, - additionalItems: false - }, - parser: { type: ["string", "null"] }, - parserOptions: { type: "object" }, - plugins: { type: "array" }, - processor: { type: "string" }, - rules: { type: "object" }, - settings: { type: "object" }, - noInlineConfig: { type: "boolean" }, - reportUnusedDisableDirectives: { type: "boolean" }, - - ecmaFeatures: { type: "object" } // deprecated; logs a warning when used -}; - -const configSchema = { - definitions: { - stringOrStrings: { - oneOf: [ - { type: "string" }, - { - type: "array", - items: { type: "string" }, - additionalItems: false - } - ] - }, - stringOrStringsRequired: { - oneOf: [ - { type: "string" }, - { - type: "array", - items: { type: "string" }, - additionalItems: false, - minItems: 1 - } - ] - }, - - // Config at top-level. - objectConfig: { - type: "object", - properties: { - root: { type: "boolean" }, - ignorePatterns: { $ref: "#/definitions/stringOrStrings" }, - ...baseConfigProperties - }, - additionalProperties: false - }, - - // Config in `overrides`. - overrideConfig: { - type: "object", - properties: { - excludedFiles: { $ref: "#/definitions/stringOrStrings" }, - files: { $ref: "#/definitions/stringOrStringsRequired" }, - ...baseConfigProperties - }, - required: ["files"], - additionalProperties: false - } - }, - - $ref: "#/definitions/objectConfig" -}; - -var configSchema_1 = configSchema; - -/** - * @fileoverview Provide the function that emits deprecation warnings. - * @author Toru Nagashima - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - - -//------------------------------------------------------------------------------ -// Private -//------------------------------------------------------------------------------ - -// Definitions for deprecation warnings. -const deprecationWarningMessages = { - ESLINT_LEGACY_ECMAFEATURES: - "The 'ecmaFeatures' config file property is deprecated and has no effect.", - ESLINT_PERSONAL_CONFIG_LOAD: - "'~/.eslintrc.*' config files have been deprecated. " + - "Please use a config file per project or the '--config' option.", - ESLINT_PERSONAL_CONFIG_SUPPRESS: - "'~/.eslintrc.*' config files have been deprecated. " + - "Please remove it or add 'root:true' to the config files in your " + - "projects in order to avoid loading '~/.eslintrc.*' accidentally." -}; - -/** - * Emits a deprecation warning containing a given filepath. A new deprecation warning is emitted - * for each unique file path, but repeated invocations with the same file path have no effect. - * No warnings are emitted if the `--no-deprecation` or `--no-warnings` Node runtime flags are active. - * @param {string} source The name of the configuration source to report the warning for. - * @param {string} errorCode The warning message to show. - * @returns {void} - */ -const emitDeprecationWarning$1 = lodash__default['default'].memoize((source, errorCode) => { - const rel = path__default['default'].relative(process.cwd(), source); - const message = deprecationWarningMessages[errorCode]; - - process.emitWarning( - `${message} (found in "${rel}")`, - "DeprecationWarning", - errorCode - ); -}, (...args) => JSON.stringify(args)); - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -var deprecationWarnings = { - emitDeprecationWarning: emitDeprecationWarning$1 -}; - -/** - * @fileoverview The instance of Ajv validator. - * @author Evgeny Poberezkin - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - - - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -var ajv$2 = (additionalOptions = {}) => { - const ajv = new Ajv__default['default']({ - meta: false, - useDefaults: true, - validateSchema: false, - missingRefs: "ignore", - verbose: true, - schemaId: "auto", - ...additionalOptions - }); - - ajv.addMetaSchema(metaSchema); - // eslint-disable-next-line no-underscore-dangle - ajv._opts.defaultMeta = metaSchema.id; - - return ajv; -}; - -/* - * STOP!!! DO NOT MODIFY. - * - * This file is part of the ongoing work to move the eslintrc-style config - * system into the @eslint/eslintrc package. This file needs to remain - * unchanged in order for this work to proceed. - * - * If you think you need to change this file, please contact @nzakas first. - * - * Thanks in advance for your cooperation. - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -const - { emitDeprecationWarning } = deprecationWarnings; - -const ajv$1 = ajv$2(); -const ruleValidators = new WeakMap(); -const noop = Function.prototype; - -//------------------------------------------------------------------------------ -// Private -//------------------------------------------------------------------------------ -let validateSchema; -const severityMap = { - error: 2, - warn: 1, - off: 0 -}; - -/** - * Gets a complete options schema for a rule. - * @param {{create: Function, schema: (Array|null)}} rule A new-style rule object - * @returns {Object} JSON Schema for the rule's options. - */ -function getRuleOptionsSchema$1(rule) { - if (!rule) { - return null; - } - - const schema = rule.schema || rule.meta && rule.meta.schema; - - // Given a tuple of schemas, insert warning level at the beginning - if (Array.isArray(schema)) { - if (schema.length) { - return { - type: "array", - items: schema, - minItems: 0, - maxItems: schema.length - }; - } - return { - type: "array", - minItems: 0, - maxItems: 0 - }; - - } - - // Given a full schema, leave it alone - return schema || null; -} - -/** - * Validates a rule's severity and returns the severity value. Throws an error if the severity is invalid. - * @param {options} options The given options for the rule. - * @returns {number|string} The rule's severity value - */ -function validateRuleSeverity(options) { - const severity = Array.isArray(options) ? options[0] : options; - const normSeverity = typeof severity === "string" ? severityMap[severity.toLowerCase()] : severity; - - if (normSeverity === 0 || normSeverity === 1 || normSeverity === 2) { - return normSeverity; - } - - throw new Error(`\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '${util__default['default'].inspect(severity).replace(/'/gu, "\"").replace(/\n/gu, "")}').\n`); - -} - -/** - * Validates the non-severity options passed to a rule, based on its schema. - * @param {{create: Function}} rule The rule to validate - * @param {Array} localOptions The options for the rule, excluding severity - * @returns {void} - */ -function validateRuleSchema(rule, localOptions) { - if (!ruleValidators.has(rule)) { - const schema = getRuleOptionsSchema$1(rule); - - if (schema) { - ruleValidators.set(rule, ajv$1.compile(schema)); - } - } - - const validateRule = ruleValidators.get(rule); - - if (validateRule) { - validateRule(localOptions); - if (validateRule.errors) { - throw new Error(validateRule.errors.map( - error => `\tValue ${JSON.stringify(error.data)} ${error.message}.\n` - ).join("")); - } - } -} - -/** - * Validates a rule's options against its schema. - * @param {{create: Function}|null} rule The rule that the config is being validated for - * @param {string} ruleId The rule's unique name. - * @param {Array|number} options The given options for the rule. - * @param {string|null} source The name of the configuration source to report in any errors. If null or undefined, - * no source is prepended to the message. - * @returns {void} - */ -function validateRuleOptions(rule, ruleId, options, source = null) { - try { - const severity = validateRuleSeverity(options); - - if (severity !== 0) { - validateRuleSchema(rule, Array.isArray(options) ? options.slice(1) : []); - } - } catch (err) { - const enhancedMessage = `Configuration for rule "${ruleId}" is invalid:\n${err.message}`; - - if (typeof source === "string") { - throw new Error(`${source}:\n\t${enhancedMessage}`); - } else { - throw new Error(enhancedMessage); - } - } -} - -/** - * Validates an environment object - * @param {Object} environment The environment config object to validate. - * @param {string} source The name of the configuration source to report in any errors. - * @param {function(envId:string): Object} [getAdditionalEnv] A map from strings to loaded environments. - * @returns {void} - */ -function validateEnvironment( - environment, - source, - getAdditionalEnv = noop -) { - - // not having an environment is ok - if (!environment) { - return; - } - - Object.keys(environment).forEach(id => { - const env = getAdditionalEnv(id) || environments.get(id) || null; - - if (!env) { - const message = `${source}:\n\tEnvironment key "${id}" is unknown\n`; - - throw new Error(message); - } - }); -} - -/** - * Validates a rules config object - * @param {Object} rulesConfig The rules config object to validate. - * @param {string} source The name of the configuration source to report in any errors. - * @param {function(ruleId:string): Object} getAdditionalRule A map from strings to loaded rules - * @returns {void} - */ -function validateRules( - rulesConfig, - source, - getAdditionalRule = noop -) { - if (!rulesConfig) { - return; - } - - Object.keys(rulesConfig).forEach(id => { - const rule = getAdditionalRule(id) || rules$2.get(id) || null; - - validateRuleOptions(rule, id, rulesConfig[id], source); - }); -} - -/** - * Validates a `globals` section of a config file - * @param {Object} globalsConfig The `globals` section - * @param {string|null} source The name of the configuration source to report in the event of an error. - * @returns {void} - */ -function validateGlobals(globalsConfig, source = null) { - if (!globalsConfig) { - return; - } - - Object.entries(globalsConfig) - .forEach(([configuredGlobal, configuredValue]) => { - try { - configOps.normalizeConfigGlobal(configuredValue); - } catch (err) { - throw new Error(`ESLint configuration of global '${configuredGlobal}' in ${source} is invalid:\n${err.message}`); - } - }); -} - -/** - * Validate `processor` configuration. - * @param {string|undefined} processorName The processor name. - * @param {string} source The name of config file. - * @param {function(id:string): Processor} getProcessor The getter of defined processors. - * @returns {void} - */ -function validateProcessor(processorName, source, getProcessor) { - if (processorName && !getProcessor(processorName)) { - throw new Error(`ESLint configuration of processor in '${source}' is invalid: '${processorName}' was not found.`); - } -} - -/** - * Formats an array of schema validation errors. - * @param {Array} errors An array of error messages to format. - * @returns {string} Formatted error message - */ -function formatErrors(errors) { - return errors.map(error => { - if (error.keyword === "additionalProperties") { - const formattedPropertyPath = error.dataPath.length ? `${error.dataPath.slice(1)}.${error.params.additionalProperty}` : error.params.additionalProperty; - - return `Unexpected top-level property "${formattedPropertyPath}"`; - } - if (error.keyword === "type") { - const formattedField = error.dataPath.slice(1); - const formattedExpectedType = Array.isArray(error.schema) ? error.schema.join("/") : error.schema; - const formattedValue = JSON.stringify(error.data); - - return `Property "${formattedField}" is the wrong type (expected ${formattedExpectedType} but got \`${formattedValue}\`)`; - } - - const field = error.dataPath[0] === "." ? error.dataPath.slice(1) : error.dataPath; - - return `"${field}" ${error.message}. Value: ${JSON.stringify(error.data)}`; - }).map(message => `\t- ${message}.\n`).join(""); -} - -/** - * Validates the top level properties of the config object. - * @param {Object} config The config object to validate. - * @param {string} source The name of the configuration source to report in any errors. - * @returns {void} - */ -function validateConfigSchema(config, source = null) { - validateSchema = validateSchema || ajv$1.compile(configSchema_1); - - if (!validateSchema(config)) { - throw new Error(`ESLint configuration in ${source} is invalid:\n${formatErrors(validateSchema.errors)}`); - } - - if (Object.hasOwnProperty.call(config, "ecmaFeatures")) { - emitDeprecationWarning(source, "ESLINT_LEGACY_ECMAFEATURES"); - } -} - -/** - * Validates an entire config object. - * @param {Object} config The config object to validate. - * @param {string} source The name of the configuration source to report in any errors. - * @param {function(ruleId:string): Object} [getAdditionalRule] A map from strings to loaded rules. - * @param {function(envId:string): Object} [getAdditionalEnv] A map from strings to loaded envs. - * @returns {void} - */ -function validate$1(config, source, getAdditionalRule, getAdditionalEnv) { - validateConfigSchema(config, source); - validateRules(config.rules, source, getAdditionalRule); - validateEnvironment(config.env, source, getAdditionalEnv); - validateGlobals(config.globals, source); - - for (const override of config.overrides || []) { - validateRules(override.rules, source, getAdditionalRule); - validateEnvironment(override.env, source, getAdditionalEnv); - validateGlobals(config.globals, source); - } -} - -const validated = new WeakSet(); - -/** - * Validate config array object. - * @param {ConfigArray} configArray The config array to validate. - * @returns {void} - */ -function validateConfigArray(configArray) { - const getPluginEnv = Map.prototype.get.bind(configArray.pluginEnvironments); - const getPluginProcessor = Map.prototype.get.bind(configArray.pluginProcessors); - const getPluginRule = Map.prototype.get.bind(configArray.pluginRules); - - // Validate. - for (const element of configArray) { - if (validated.has(element)) { - continue; - } - validated.add(element); - - validateEnvironment(element.env, element.name, getPluginEnv); - validateGlobals(element.globals, element.name); - validateProcessor(element.processor, element.name, getPluginProcessor); - validateRules(element.rules, element.name, getPluginRule); - } -} - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -var configValidator = { - getRuleOptionsSchema: getRuleOptionsSchema$1, - validate: validate$1, - validateConfigArray, - validateConfigSchema, - validateRuleOptions -}; - -/** - * @fileoverview Mocha test wrapper - * @author Ilya Volodin - */ - -/* global describe, it */ - -/* - * This is a wrapper around mocha to allow for DRY unittests for eslint - * Format: - * RuleTester.run("{ruleName}", { - * valid: [ - * "{code}", - * { code: "{code}", options: {options}, globals: {globals}, parser: "{parser}", settings: {settings} } - * ], - * invalid: [ - * { code: "{code}", errors: {numErrors} }, - * { code: "{code}", errors: ["{errorMessage}"] }, - * { code: "{code}", options: {options}, globals: {globals}, parser: "{parser}", settings: {settings}, errors: [{ message: "{errorMessage}", type: "{errorNodeType}"}] } - * ] - * }); - * - * Variables: - * {code} - String that represents the code to be tested - * {options} - Arguments that are passed to the configurable rules. - * {globals} - An object representing a list of variables that are - * registered as globals - * {parser} - String representing the parser to use - * {settings} - An object representing global settings for all rules - * {numErrors} - If failing case doesn't need to check error message, - * this integer will specify how many errors should be - * received - * {errorMessage} - Message that is returned by the rule on failure - * {errorNodeType} - AST node type that is returned by they rule as - * a cause of the failure. - */ - -//------------------------------------------------------------------------------ -// Requirements -//------------------------------------------------------------------------------ - -const - { getRuleOptionsSchema, validate } = configValidator, - { Linter, SourceCodeFixer, interpolate } = linter; - -const ajv = ajv$2({ strictDefaults: true }); - -const espreePath = require.resolve("espree"); - -//------------------------------------------------------------------------------ -// Typedefs -//------------------------------------------------------------------------------ - -/** @typedef {import("../shared/types").Parser} Parser */ - -/** - * A test case that is expected to pass lint. - * @typedef {Object} ValidTestCase - * @property {string} code Code for the test case. - * @property {any[]} [options] Options for the test case. - * @property {{ [name: string]: any }} [settings] Settings for the test case. - * @property {string} [filename] The fake filename for the test case. Useful for rules that make assertion about filenames. - * @property {string} [parser] The absolute path for the parser. - * @property {{ [name: string]: any }} [parserOptions] Options for the parser. - * @property {{ [name: string]: "readonly" | "writable" | "off" }} [globals] The additional global variables. - * @property {{ [name: string]: boolean }} [env] Environments for the test case. - */ - -/** - * A test case that is expected to fail lint. - * @typedef {Object} InvalidTestCase - * @property {string} code Code for the test case. - * @property {number | Array} errors Expected errors. - * @property {string | null} [output] The expected code after autofixes are applied. If set to `null`, the test runner will assert that no autofix is suggested. - * @property {any[]} [options] Options for the test case. - * @property {{ [name: string]: any }} [settings] Settings for the test case. - * @property {string} [filename] The fake filename for the test case. Useful for rules that make assertion about filenames. - * @property {string} [parser] The absolute path for the parser. - * @property {{ [name: string]: any }} [parserOptions] Options for the parser. - * @property {{ [name: string]: "readonly" | "writable" | "off" }} [globals] The additional global variables. - * @property {{ [name: string]: boolean }} [env] Environments for the test case. - */ - -/** - * A description of a reported error used in a rule tester test. - * @typedef {Object} TestCaseError - * @property {string | RegExp} [message] Message. - * @property {string} [messageId] Message ID. - * @property {string} [type] The type of the reported AST node. - * @property {{ [name: string]: string }} [data] The data used to fill the message template. - * @property {number} [line] The 1-based line number of the reported start location. - * @property {number} [column] The 1-based column number of the reported start location. - * @property {number} [endLine] The 1-based line number of the reported end location. - * @property {number} [endColumn] The 1-based column number of the reported end location. - */ - -//------------------------------------------------------------------------------ -// Private Members -//------------------------------------------------------------------------------ - -/* - * testerDefaultConfig must not be modified as it allows to reset the tester to - * the initial default configuration - */ -const testerDefaultConfig = { rules: {} }; -let defaultConfig = { rules: {} }; - -/* - * List every parameters possible on a test case that are not related to eslint - * configuration - */ -const RuleTesterParameters = [ - "code", - "filename", - "options", - "errors", - "output" -]; - -/* - * All allowed property names in error objects. - */ -const errorObjectParameters = new Set([ - "message", - "messageId", - "data", - "type", - "line", - "column", - "endLine", - "endColumn", - "suggestions" -]); -const friendlyErrorObjectParameterList = `[${[...errorObjectParameters].map(key => `'${key}'`).join(", ")}]`; - -/* - * All allowed property names in suggestion objects. - */ -const suggestionObjectParameters = new Set([ - "desc", - "messageId", - "data", - "output" -]); -const friendlySuggestionObjectParameterList = `[${[...suggestionObjectParameters].map(key => `'${key}'`).join(", ")}]`; - -const hasOwnProperty = Function.call.bind(Object.hasOwnProperty); - -/** - * Clones a given value deeply. - * Note: This ignores `parent` property. - * @param {any} x A value to clone. - * @returns {any} A cloned value. - */ -function cloneDeeplyExcludesParent(x) { - if (typeof x === "object" && x !== null) { - if (Array.isArray(x)) { - return x.map(cloneDeeplyExcludesParent); - } - - const retv = {}; - - for (const key in x) { - if (key !== "parent" && hasOwnProperty(x, key)) { - retv[key] = cloneDeeplyExcludesParent(x[key]); - } - } - - return retv; - } - - return x; -} - -/** - * Freezes a given value deeply. - * @param {any} x A value to freeze. - * @returns {void} - */ -function freezeDeeply(x) { - if (typeof x === "object" && x !== null) { - if (Array.isArray(x)) { - x.forEach(freezeDeeply); - } else { - for (const key in x) { - if (key !== "parent" && hasOwnProperty(x, key)) { - freezeDeeply(x[key]); - } - } - } - Object.freeze(x); - } -} - -/** - * Replace control characters by `\u00xx` form. - * @param {string} text The text to sanitize. - * @returns {string} The sanitized text. - */ -function sanitize(text) { - return text.replace( - /[\u0000-\u0009\u000b-\u001a]/gu, // eslint-disable-line no-control-regex - c => `\\u${c.codePointAt(0).toString(16).padStart(4, "0")}` - ); -} - -/** - * Define `start`/`end` properties as throwing error. - * @param {string} objName Object name used for error messages. - * @param {ASTNode} node The node to define. - * @returns {void} - */ -function defineStartEndAsError(objName, node) { - Object.defineProperties(node, { - start: { - get() { - throw new Error(`Use ${objName}.range[0] instead of ${objName}.start`); - }, - configurable: true, - enumerable: false - }, - end: { - get() { - throw new Error(`Use ${objName}.range[1] instead of ${objName}.end`); - }, - configurable: true, - enumerable: false - } - }); -} - -/** - * Define `start`/`end` properties of all nodes of the given AST as throwing error. - * @param {ASTNode} ast The root node to errorize `start`/`end` properties. - * @param {Object} [visitorKeys] Visitor keys to be used for traversing the given ast. - * @returns {void} - */ -function defineStartEndAsErrorInTree(ast, visitorKeys) { - traverser.traverse(ast, { visitorKeys, enter: defineStartEndAsError.bind(null, "node") }); - ast.tokens.forEach(defineStartEndAsError.bind(null, "token")); - ast.comments.forEach(defineStartEndAsError.bind(null, "token")); -} - -/** - * Wraps the given parser in order to intercept and modify return values from the `parse` and `parseForESLint` methods, for test purposes. - * In particular, to modify ast nodes, tokens and comments to throw on access to their `start` and `end` properties. - * @param {Parser} parser Parser object. - * @returns {Parser} Wrapped parser object. - */ -function wrapParser(parser) { - if (typeof parser.parseForESLint === "function") { - return { - parseForESLint(...args) { - const ret = parser.parseForESLint(...args); - - defineStartEndAsErrorInTree(ret.ast, ret.visitorKeys); - return ret; - } - }; - } - return { - parse(...args) { - const ast = parser.parse(...args); - - defineStartEndAsErrorInTree(ast); - return ast; - } - }; -} - -//------------------------------------------------------------------------------ -// Public Interface -//------------------------------------------------------------------------------ - -// default separators for testing -const DESCRIBE = Symbol("describe"); -const IT = Symbol("it"); - -/** - * This is `it` default handler if `it` don't exist. - * @this {Mocha} - * @param {string} text The description of the test case. - * @param {Function} method The logic of the test case. - * @returns {any} Returned value of `method`. - */ -function itDefaultHandler(text, method) { - try { - return method.call(this); - } catch (err) { - if (err instanceof assert__default['default'].AssertionError) { - err.message += ` (${util__default['default'].inspect(err.actual)} ${err.operator} ${util__default['default'].inspect(err.expected)})`; - } - throw err; - } -} - -/** - * This is `describe` default handler if `describe` don't exist. - * @this {Mocha} - * @param {string} text The description of the test case. - * @param {Function} method The logic of the test case. - * @returns {any} Returned value of `method`. - */ -function describeDefaultHandler(text, method) { - return method.call(this); -} - -class RuleTester { - - /** - * Creates a new instance of RuleTester. - * @param {Object} [testerConfig] Optional, extra configuration for the tester - */ - constructor(testerConfig) { - - /** - * The configuration to use for this tester. Combination of the tester - * configuration and the default configuration. - * @type {Object} - */ - this.testerConfig = lodash__default['default'].merge( - - // we have to clone because merge uses the first argument for recipient - lodash__default['default'].cloneDeep(defaultConfig), - testerConfig, - { rules: { "rule-tester/validate-ast": "error" } } - ); - - /** - * Rule definitions to define before tests. - * @type {Object} - */ - this.rules = {}; - this.linter = new Linter(); - } - - /** - * Set the configuration to use for all future tests - * @param {Object} config the configuration to use. - * @returns {void} - */ - static setDefaultConfig(config) { - if (typeof config !== "object") { - throw new TypeError("RuleTester.setDefaultConfig: config must be an object"); - } - defaultConfig = config; - - // Make sure the rules object exists since it is assumed to exist later - defaultConfig.rules = defaultConfig.rules || {}; - } - - /** - * Get the current configuration used for all tests - * @returns {Object} the current configuration - */ - static getDefaultConfig() { - return defaultConfig; - } - - /** - * Reset the configuration to the initial configuration of the tester removing - * any changes made until now. - * @returns {void} - */ - static resetDefaultConfig() { - defaultConfig = lodash__default['default'].cloneDeep(testerDefaultConfig); - } - - - /* - * If people use `mocha test.js --watch` command, `describe` and `it` function - * instances are different for each execution. So `describe` and `it` should get fresh instance - * always. - */ - static get describe() { - return ( - this[DESCRIBE] || - (typeof describe === "function" ? describe : describeDefaultHandler) - ); - } - - static set describe(value) { - this[DESCRIBE] = value; - } - - static get it() { - return ( - this[IT] || - (typeof it === "function" ? it : itDefaultHandler) - ); - } - - static set it(value) { - this[IT] = value; - } - - /** - * Define a rule for one particular run of tests. - * @param {string} name The name of the rule to define. - * @param {Function} rule The rule definition. - * @returns {void} - */ - defineRule(name, rule) { - this.rules[name] = rule; - } - - /** - * Adds a new rule test to execute. - * @param {string} ruleName The name of the rule to run. - * @param {Function} rule The rule to test. - * @param {{ - * valid: (ValidTestCase | string)[], - * invalid: InvalidTestCase[] - * }} test The collection of tests to run. - * @returns {void} - */ - run(ruleName, rule, test) { - - const testerConfig = this.testerConfig, - requiredScenarios = ["valid", "invalid"], - scenarioErrors = [], - linter = this.linter; - - if (!test || typeof test !== "object") { - throw new TypeError(`Test Scenarios for rule ${ruleName} : Could not find test scenario object`); - } - - requiredScenarios.forEach(scenarioType => { - if (!test[scenarioType]) { - scenarioErrors.push(`Could not find any ${scenarioType} test scenarios`); - } - }); - - if (scenarioErrors.length > 0) { - throw new Error([ - `Test Scenarios for rule ${ruleName} is invalid:` - ].concat(scenarioErrors).join("\n")); - } - - - linter.defineRule(ruleName, Object.assign({}, rule, { - - // Create a wrapper rule that freezes the `context` properties. - create(context) { - freezeDeeply(context.options); - freezeDeeply(context.settings); - freezeDeeply(context.parserOptions); - - return (typeof rule === "function" ? rule : rule.create)(context); - } - })); - - linter.defineRules(this.rules); - - /** - * Run the rule for the given item - * @param {string|Object} item Item to run the rule against - * @returns {Object} Eslint run result - * @private - */ - function runRuleForItem(item) { - let config = lodash__default['default'].cloneDeep(testerConfig), - code, filename, output, beforeAST, afterAST; - - if (typeof item === "string") { - code = item; - } else { - code = item.code; - - /* - * Assumes everything on the item is a config except for the - * parameters used by this tester - */ - const itemConfig = lodash__default['default'].omit(item, RuleTesterParameters); - - /* - * Create the config object from the tester config and this item - * specific configurations. - */ - config = lodash__default['default'].merge( - config, - itemConfig - ); - } - - if (item.filename) { - filename = item.filename; - } - - if (hasOwnProperty(item, "options")) { - assert__default['default'](Array.isArray(item.options), "options must be an array"); - config.rules[ruleName] = [1].concat(item.options); - } else { - config.rules[ruleName] = 1; - } - - const schema = getRuleOptionsSchema(rule); - - /* - * Setup AST getters. - * The goal is to check whether or not AST was modified when - * running the rule under test. - */ - linter.defineRule("rule-tester/validate-ast", () => ({ - Program(node) { - beforeAST = cloneDeeplyExcludesParent(node); - }, - "Program:exit"(node) { - afterAST = node; - } - })); - - if (typeof config.parser === "string") { - assert__default['default'](path__default['default'].isAbsolute(config.parser), "Parsers provided as strings to RuleTester must be absolute paths"); - } else { - config.parser = espreePath; - } - - linter.defineParser(config.parser, wrapParser(commonjsRequire(config.parser))); - - if (schema) { - ajv.validateSchema(schema); - - if (ajv.errors) { - const errors = ajv.errors.map(error => { - const field = error.dataPath[0] === "." ? error.dataPath.slice(1) : error.dataPath; - - return `\t${field}: ${error.message}`; - }).join("\n"); - - throw new Error([`Schema for rule ${ruleName} is invalid:`, errors]); - } - - /* - * `ajv.validateSchema` checks for errors in the structure of the schema (by comparing the schema against a "meta-schema"), - * and it reports those errors individually. However, there are other types of schema errors that only occur when compiling - * the schema (e.g. using invalid defaults in a schema), and only one of these errors can be reported at a time. As a result, - * the schema is compiled here separately from checking for `validateSchema` errors. - */ - try { - ajv.compile(schema); - } catch (err) { - throw new Error(`Schema for rule ${ruleName} is invalid: ${err.message}`); - } - } - - validate(config, "rule-tester", id => (id === ruleName ? rule : null)); - - // Verify the code. - const messages = linter.verify(code, config, filename); - const fatalErrorMessage = messages.find(m => m.fatal); - - assert__default['default'](!fatalErrorMessage, `A fatal parsing error occurred: ${fatalErrorMessage && fatalErrorMessage.message}`); - - // Verify if autofix makes a syntax error or not. - if (messages.some(m => m.fix)) { - output = SourceCodeFixer.applyFixes(code, messages).output; - const errorMessageInFix = linter.verify(output, config, filename).find(m => m.fatal); - - assert__default['default'](!errorMessageInFix, [ - "A fatal parsing error occurred in autofix.", - `Error: ${errorMessageInFix && errorMessageInFix.message}`, - "Autofix output:", - output - ].join("\n")); - } else { - output = code; - } - - return { - messages, - output, - beforeAST, - afterAST: cloneDeeplyExcludesParent(afterAST) - }; - } - - /** - * Check if the AST was changed - * @param {ASTNode} beforeAST AST node before running - * @param {ASTNode} afterAST AST node after running - * @returns {void} - * @private - */ - function assertASTDidntChange(beforeAST, afterAST) { - if (!lodash__default['default'].isEqual(beforeAST, afterAST)) { - assert__default['default'].fail("Rule should not modify AST."); - } - } - - /** - * Check if the template is valid or not - * all valid cases go through this - * @param {string|Object} item Item to run the rule against - * @returns {void} - * @private - */ - function testValidTemplate(item) { - const result = runRuleForItem(item); - const messages = result.messages; - - assert__default['default'].strictEqual(messages.length, 0, util__default['default'].format("Should have no errors but had %d: %s", - messages.length, util__default['default'].inspect(messages))); - - assertASTDidntChange(result.beforeAST, result.afterAST); - } - - /** - * Asserts that the message matches its expected value. If the expected - * value is a regular expression, it is checked against the actual - * value. - * @param {string} actual Actual value - * @param {string|RegExp} expected Expected value - * @returns {void} - * @private - */ - function assertMessageMatches(actual, expected) { - if (expected instanceof RegExp) { - - // assert.js doesn't have a built-in RegExp match function - assert__default['default'].ok( - expected.test(actual), - `Expected '${actual}' to match ${expected}` - ); - } else { - assert__default['default'].strictEqual(actual, expected); - } - } - - /** - * Check if the template is invalid or not - * all invalid cases go through this. - * @param {string|Object} item Item to run the rule against - * @returns {void} - * @private - */ - function testInvalidTemplate(item) { - assert__default['default'].ok(item.errors || item.errors === 0, - `Did not specify errors for an invalid test of ${ruleName}`); - - if (Array.isArray(item.errors) && item.errors.length === 0) { - assert__default['default'].fail("Invalid cases must have at least one error"); - } - - const ruleHasMetaMessages = hasOwnProperty(rule, "meta") && hasOwnProperty(rule.meta, "messages"); - const friendlyIDList = ruleHasMetaMessages ? `[${Object.keys(rule.meta.messages).map(key => `'${key}'`).join(", ")}]` : null; - - const result = runRuleForItem(item); - const messages = result.messages; - - if (typeof item.errors === "number") { - - if (item.errors === 0) { - assert__default['default'].fail("Invalid cases must have 'error' value greater than 0"); - } - - assert__default['default'].strictEqual(messages.length, item.errors, util__default['default'].format("Should have %d error%s but had %d: %s", - item.errors, item.errors === 1 ? "" : "s", messages.length, util__default['default'].inspect(messages))); - } else { - assert__default['default'].strictEqual( - messages.length, item.errors.length, - util__default['default'].format( - "Should have %d error%s but had %d: %s", - item.errors.length, item.errors.length === 1 ? "" : "s", messages.length, util__default['default'].inspect(messages) - ) - ); - - const hasMessageOfThisRule = messages.some(m => m.ruleId === ruleName); - - for (let i = 0, l = item.errors.length; i < l; i++) { - const error = item.errors[i]; - const message = messages[i]; - - assert__default['default'](hasMessageOfThisRule, "Error rule name should be the same as the name of the rule being tested"); - - if (typeof error === "string" || error instanceof RegExp) { - - // Just an error message. - assertMessageMatches(message.message, error); - } else if (typeof error === "object" && error !== null) { - - /* - * Error object. - * This may have a message, messageId, data, node type, line, and/or - * column. - */ - - Object.keys(error).forEach(propertyName => { - assert__default['default'].ok( - errorObjectParameters.has(propertyName), - `Invalid error property name '${propertyName}'. Expected one of ${friendlyErrorObjectParameterList}.` - ); - }); - - if (hasOwnProperty(error, "message")) { - assert__default['default'].ok(!hasOwnProperty(error, "messageId"), "Error should not specify both 'message' and a 'messageId'."); - assert__default['default'].ok(!hasOwnProperty(error, "data"), "Error should not specify both 'data' and 'message'."); - assertMessageMatches(message.message, error.message); - } else if (hasOwnProperty(error, "messageId")) { - assert__default['default'].ok( - ruleHasMetaMessages, - "Error can not use 'messageId' if rule under test doesn't define 'meta.messages'." - ); - if (!hasOwnProperty(rule.meta.messages, error.messageId)) { - assert__default['default'](false, `Invalid messageId '${error.messageId}'. Expected one of ${friendlyIDList}.`); - } - assert__default['default'].strictEqual( - message.messageId, - error.messageId, - `messageId '${message.messageId}' does not match expected messageId '${error.messageId}'.` - ); - if (hasOwnProperty(error, "data")) { - - /* - * if data was provided, then directly compare the returned message to a synthetic - * interpolated message using the same message ID and data provided in the test. - * See https://github.com/eslint/eslint/issues/9890 for context. - */ - const unformattedOriginalMessage = rule.meta.messages[error.messageId]; - const rehydratedMessage = interpolate(unformattedOriginalMessage, error.data); - - assert__default['default'].strictEqual( - message.message, - rehydratedMessage, - `Hydrated message "${rehydratedMessage}" does not match "${message.message}"` - ); - } - } - - assert__default['default'].ok( - hasOwnProperty(error, "data") ? hasOwnProperty(error, "messageId") : true, - "Error must specify 'messageId' if 'data' is used." - ); - - if (error.type) { - assert__default['default'].strictEqual(message.nodeType, error.type, `Error type should be ${error.type}, found ${message.nodeType}`); - } - - if (hasOwnProperty(error, "line")) { - assert__default['default'].strictEqual(message.line, error.line, `Error line should be ${error.line}`); - } - - if (hasOwnProperty(error, "column")) { - assert__default['default'].strictEqual(message.column, error.column, `Error column should be ${error.column}`); - } - - if (hasOwnProperty(error, "endLine")) { - assert__default['default'].strictEqual(message.endLine, error.endLine, `Error endLine should be ${error.endLine}`); - } - - if (hasOwnProperty(error, "endColumn")) { - assert__default['default'].strictEqual(message.endColumn, error.endColumn, `Error endColumn should be ${error.endColumn}`); - } - - if (hasOwnProperty(error, "suggestions")) { - - // Support asserting there are no suggestions - if (!error.suggestions || (Array.isArray(error.suggestions) && error.suggestions.length === 0)) { - if (Array.isArray(message.suggestions) && message.suggestions.length > 0) { - assert__default['default'].fail(`Error should have no suggestions on error with message: "${message.message}"`); - } - } else { - assert__default['default'].strictEqual(Array.isArray(message.suggestions), true, `Error should have an array of suggestions. Instead received "${message.suggestions}" on error with message: "${message.message}"`); - assert__default['default'].strictEqual(message.suggestions.length, error.suggestions.length, `Error should have ${error.suggestions.length} suggestions. Instead found ${message.suggestions.length} suggestions`); - - error.suggestions.forEach((expectedSuggestion, index) => { - assert__default['default'].ok( - typeof expectedSuggestion === "object" && expectedSuggestion !== null, - "Test suggestion in 'suggestions' array must be an object." - ); - Object.keys(expectedSuggestion).forEach(propertyName => { - assert__default['default'].ok( - suggestionObjectParameters.has(propertyName), - `Invalid suggestion property name '${propertyName}'. Expected one of ${friendlySuggestionObjectParameterList}.` - ); - }); - - const actualSuggestion = message.suggestions[index]; - const suggestionPrefix = `Error Suggestion at index ${index} :`; - - if (hasOwnProperty(expectedSuggestion, "desc")) { - assert__default['default'].ok( - !hasOwnProperty(expectedSuggestion, "data"), - `${suggestionPrefix} Test should not specify both 'desc' and 'data'.` - ); - assert__default['default'].strictEqual( - actualSuggestion.desc, - expectedSuggestion.desc, - `${suggestionPrefix} desc should be "${expectedSuggestion.desc}" but got "${actualSuggestion.desc}" instead.` - ); - } - - if (hasOwnProperty(expectedSuggestion, "messageId")) { - assert__default['default'].ok( - ruleHasMetaMessages, - `${suggestionPrefix} Test can not use 'messageId' if rule under test doesn't define 'meta.messages'.` - ); - assert__default['default'].ok( - hasOwnProperty(rule.meta.messages, expectedSuggestion.messageId), - `${suggestionPrefix} Test has invalid messageId '${expectedSuggestion.messageId}', the rule under test allows only one of ${friendlyIDList}.` - ); - assert__default['default'].strictEqual( - actualSuggestion.messageId, - expectedSuggestion.messageId, - `${suggestionPrefix} messageId should be '${expectedSuggestion.messageId}' but got '${actualSuggestion.messageId}' instead.` - ); - if (hasOwnProperty(expectedSuggestion, "data")) { - const unformattedMetaMessage = rule.meta.messages[expectedSuggestion.messageId]; - const rehydratedDesc = interpolate(unformattedMetaMessage, expectedSuggestion.data); - - assert__default['default'].strictEqual( - actualSuggestion.desc, - rehydratedDesc, - `${suggestionPrefix} Hydrated test desc "${rehydratedDesc}" does not match received desc "${actualSuggestion.desc}".` - ); - } - } else { - assert__default['default'].ok( - !hasOwnProperty(expectedSuggestion, "data"), - `${suggestionPrefix} Test must specify 'messageId' if 'data' is used.` - ); - } - - if (hasOwnProperty(expectedSuggestion, "output")) { - const codeWithAppliedSuggestion = SourceCodeFixer.applyFixes(item.code, [actualSuggestion]).output; - - assert__default['default'].strictEqual(codeWithAppliedSuggestion, expectedSuggestion.output, `Expected the applied suggestion fix to match the test suggestion output for suggestion at index: ${index} on error with message: "${message.message}"`); - } - }); - } - } - } else { - - // Message was an unexpected type - assert__default['default'].fail(`Error should be a string, object, or RegExp, but found (${util__default['default'].inspect(message)})`); - } - } - } - - if (hasOwnProperty(item, "output")) { - if (item.output === null) { - assert__default['default'].strictEqual( - result.output, - item.code, - "Expected no autofixes to be suggested" - ); - } else { - assert__default['default'].strictEqual(result.output, item.output, "Output is incorrect."); - } - } else { - assert__default['default'].strictEqual( - result.output, - item.code, - "The rule fixed the code. Please add 'output' property." - ); - } - - // Rules that produce fixes must have `meta.fixable` property. - if (result.output !== item.code) { - assert__default['default'].ok( - hasOwnProperty(rule, "meta"), - "Fixable rules should export a `meta.fixable` property." - ); - - // Linter throws if a rule that produced a fix has `meta` but doesn't have `meta.fixable`. - } - - assertASTDidntChange(result.beforeAST, result.afterAST); - } - - /* - * This creates a mocha test suite and pipes all supplied info through - * one of the templates above. - */ - RuleTester.describe(ruleName, () => { - RuleTester.describe("valid", () => { - test.valid.forEach(valid => { - RuleTester.it(sanitize(typeof valid === "object" ? valid.code : valid), () => { - testValidTemplate(valid); - }); - }); - }); - - RuleTester.describe("invalid", () => { - test.invalid.forEach(invalid => { - RuleTester.it(sanitize(invalid.code), () => { - testInvalidTemplate(invalid); - }); - }); - }); - }); - } -} - -RuleTester[DESCRIBE] = RuleTester[IT] = null; - -var ruleTester$1 = RuleTester; - -var ruleTester = { - RuleTester: ruleTester$1 -}; - -/** - * @fileoverview Expose out ESLint and CLI to require. - * @author Ian Christian Myers - */ - -var api = createCommonjsModule(function (module) { - -const { CLIEngine } = cliEngine; -const { ESLint } = eslint; -const { Linter } = linter; -const { RuleTester } = ruleTester; -const { SourceCode } = sourceCode; - -module.exports = { - Linter, - CLIEngine, - ESLint, - RuleTester, - SourceCode -}; - -// DOTO: remove deprecated API. -let deprecatedLinterInstance = null; - -Object.defineProperty(module.exports, "linter", { - enumerable: false, - get() { - if (!deprecatedLinterInstance) { - deprecatedLinterInstance = new Linter(); - } - - return deprecatedLinterInstance; - } -}); -}); - -var checkExamples = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - - - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// Todo: When peerDeps bump to ESLint 7, see about replacing `CLIEngine` -// with non-deprecated `ESLint` class: -// https://github.com/eslint/eslint/blob/master/docs/user-guide/migrating-to-7.0.0.md#-the-cliengine-class-has-been-deprecated -const zeroBasedLineIndexAdjust = -1; -const likelyNestedJSDocIndentSpace = 1; -const preTagSpaceLength = 1; // If a space is present, we should ignore it - -const firstLinePrefixLength = preTagSpaceLength; -const hasCaptionRegex = /^\s*([\s\S]*?)<\/caption>/u; - -const escapeStringRegexp = str => { - return str.replace(/[.*+?^${}()|[\]\\]/gu, '\\$&'); -}; - -const countChars = (str, ch) => { - return (str.match(new RegExp(escapeStringRegexp(ch), 'gu')) || []).length; -}; - -const defaultMdRules = { - // "always" newline rule at end unlikely in sample code - 'eol-last': 0, - // Wouldn't generally expect example paths to resolve relative to JS file - 'import/no-unresolved': 0, - // Snippets likely too short to always include import/export info - 'import/unambiguous': 0, - 'jsdoc/require-file-overview': 0, - // The end of a multiline comment would end the comment the example is in. - 'jsdoc/require-jsdoc': 0, - // Unlikely to have inadvertent debugging within examples - 'no-console': 0, - // Often wish to start `@example` code after newline; also may use - // empty lines for spacing - 'no-multiple-empty-lines': 0, - // Many variables in examples will be `undefined` - 'no-undef': 0, - // Common to define variables for clarity without always using them - 'no-unused-vars': 0, - // See import/no-unresolved - 'node/no-missing-import': 0, - 'node/no-missing-require': 0, - // Can generally look nicer to pad a little even if code imposes more stringency - 'padded-blocks': 0 -}; -const defaultExpressionRules = { ...defaultMdRules, - 'no-new': 'off', - 'no-unused-expressions': 'off', - quotes: ['error', 'double'], - semi: ['error', 'never'], - strict: 'off' -}; - -const getLinesCols = text => { - const matchLines = countChars(text, '\n'); - const colDelta = matchLines ? text.slice(text.lastIndexOf('\n') + 1).length : text.length; - return [matchLines, colDelta]; -}; - -var _default = (0, _iterateJsdoc.default)(({ - report, - utils, - context, - globalState -}) => { - if (!globalState.has('checkExamples-matchingFileName')) { - globalState.set('checkExamples-matchingFileName', new Map()); - } - - const matchingFileNameMap = globalState.get('checkExamples-matchingFileName'); - const options = context.options[0] || {}; - let { - exampleCodeRegex = null, - rejectExampleCodeRegex = null - } = options; - const { - checkDefaults = false, - checkParams = false, - checkProperties = false, - noDefaultExampleRules = false, - checkEslintrc = true, - matchingFileName = null, - matchingFileNameDefaults = null, - matchingFileNameParams = null, - matchingFileNameProperties = null, - paddedIndent = 0, - baseConfig = {}, - configFile, - allowInlineConfig = true, - reportUnusedDisableDirectives = true, - captionRequired = false - } = options; // Make this configurable? - - const rulePaths = []; - const mdRules = noDefaultExampleRules ? undefined : defaultMdRules; - const expressionRules = noDefaultExampleRules ? undefined : defaultExpressionRules; - - if (exampleCodeRegex) { - exampleCodeRegex = utils.getRegexFromString(exampleCodeRegex); - } - - if (rejectExampleCodeRegex) { - rejectExampleCodeRegex = utils.getRegexFromString(rejectExampleCodeRegex); - } - - const checkSource = ({ - filename, - defaultFileName, - rules = expressionRules, - lines = 0, - cols = 0, - skipInit, - source, - targetTagName, - sources = [], - tag = { - line: 0 - } - }) => { - if (!skipInit) { - sources.push({ - nonJSPrefacingCols: cols, - nonJSPrefacingLines: lines, - string: source - }); - } // Todo: Make fixable - // Todo: Fix whitespace indent - - - const checkRules = function ({ - nonJSPrefacingCols, - nonJSPrefacingLines, - string - }) { - const cliConfig = { - allowInlineConfig, - baseConfig, - configFile, - reportUnusedDisableDirectives, - rulePaths, - rules, - useEslintrc: checkEslintrc - }; - const cliConfigStr = JSON.stringify(cliConfig); - const src = paddedIndent ? string.replace(new RegExp(`(^|\n) {${paddedIndent}}(?!$)`, 'gu'), '\n') : string; // Programmatic ESLint API: https://eslint.org/docs/developer-guide/nodejs-api - - const fileNameMapKey = filename ? 'a' + cliConfigStr + filename : 'b' + cliConfigStr + defaultFileName; - const file = filename || defaultFileName; - let cliFile; - - if (matchingFileNameMap.has(fileNameMapKey)) { - cliFile = matchingFileNameMap.get(fileNameMapKey); - } else { - const cli = new api.CLIEngine(cliConfig); - let config; - - if (filename || checkEslintrc) { - config = cli.getConfigForFile(file); - } // We need a new instance to ensure that the rules that may only - // be available to `file` (if it has its own `.eslintrc`), - // will be defined. - - - cliFile = new api.CLIEngine({ - allowInlineConfig, - baseConfig: { ...baseConfig, - ...config - }, - configFile, - reportUnusedDisableDirectives, - rulePaths, - rules, - useEslintrc: false - }); - matchingFileNameMap.set(fileNameMapKey, cliFile); - } - - const { - results: [{ - messages - }] - } = cliFile.executeOnText(src); - - if (!('line' in tag)) { - tag.line = tag.source[0].number; - } // NOTE: `tag.line` can be 0 if of form `/** @tag ... */` - - - const codeStartLine = tag.line + nonJSPrefacingLines; - const codeStartCol = likelyNestedJSDocIndentSpace; - messages.forEach(({ - message, - line, - column, - severity, - ruleId - }) => { - const startLine = codeStartLine + line + zeroBasedLineIndexAdjust; - const startCol = codeStartCol + ( // This might not work for line 0, but line 0 is unlikely for examples - line <= 1 ? nonJSPrefacingCols + firstLinePrefixLength : preTagSpaceLength) + column; - report('@' + targetTagName + ' ' + (severity === 2 ? 'error' : 'warning') + (ruleId ? ' (' + ruleId + ')' : '') + ': ' + message, null, { - column: startCol, - line: startLine - }); - }); - }; - - sources.forEach(checkRules); - }; - /** - * - * @param {string} filename - * @param {string} [ext="md/*.js"] Since `eslint-plugin-markdown` v2, and - * ESLint 7, this is the default which other JS-fenced rules will used. - * Formerly "md" was the default. - * @returns {{defaultFileName: string, fileName: string}} - */ - - - const getFilenameInfo = (filename, ext = 'md/*.js') => { - let defaultFileName; - - if (!filename) { - const jsFileName = context.getFilename(); - - if (typeof jsFileName === 'string' && jsFileName.includes('.')) { - defaultFileName = jsFileName.replace(/\..*?$/, `.${ext}`); - } else { - defaultFileName = `dummy.${ext}`; - } - } - - return { - defaultFileName, - filename - }; - }; - - if (checkDefaults) { - const filenameInfo = getFilenameInfo(matchingFileNameDefaults, 'jsdoc-defaults'); - utils.forEachPreferredTag('default', (tag, targetTagName) => { - if (!tag.description.trim()) { - return; - } - - checkSource({ - source: `(${tag.description})`, - targetTagName, - ...filenameInfo - }); - }); - } - - if (checkParams) { - const filenameInfo = getFilenameInfo(matchingFileNameParams, 'jsdoc-params'); - utils.forEachPreferredTag('param', (tag, targetTagName) => { - if (!tag.default || !tag.default.trim()) { - return; - } - - checkSource({ - source: `(${tag.default})`, - targetTagName, - ...filenameInfo - }); - }); - } - - if (checkProperties) { - const filenameInfo = getFilenameInfo(matchingFileNameProperties, 'jsdoc-properties'); - utils.forEachPreferredTag('property', (tag, targetTagName) => { - if (!tag.default || !tag.default.trim()) { - return; - } - - checkSource({ - source: `(${tag.default})`, - targetTagName, - ...filenameInfo - }); - }); - } - - const tagName = utils.getPreferredTagName({ - tagName: 'example' - }); - - if (!utils.hasTag(tagName)) { - return; - } - - const matchingFilenameInfo = getFilenameInfo(matchingFileName); - utils.forEachPreferredTag('example', (tag, targetTagName) => { - let source = tag.source[0].tokens.postTag.slice(1) + tag.description; - const match = source.match(hasCaptionRegex); - - if (captionRequired && (!match || !match[1].trim())) { - report('Caption is expected for examples.', null, tag); - } - - source = source.replace(hasCaptionRegex, ''); - const [lines, cols] = match ? getLinesCols(match[0]) : [0, 0]; - - if (exampleCodeRegex && !exampleCodeRegex.test(source) || rejectExampleCodeRegex && rejectExampleCodeRegex.test(source)) { - return; - } - - const sources = []; - let skipInit = false; - - if (exampleCodeRegex) { - let nonJSPrefacingCols = 0; - let nonJSPrefacingLines = 0; - let startingIndex = 0; - let lastStringCount = 0; - let exampleCode; - exampleCodeRegex.lastIndex = 0; - - while ((exampleCode = exampleCodeRegex.exec(source)) !== null) { - const { - index, - 0: n0, - 1: n1 - } = exampleCode; // Count anything preceding user regex match (can affect line numbering) - - const preMatch = source.slice(startingIndex, index); - const [preMatchLines, colDelta] = getLinesCols(preMatch); - let nonJSPreface; - let nonJSPrefaceLineCount; - - if (n1) { - const idx = n0.indexOf(n1); - nonJSPreface = n0.slice(0, idx); - nonJSPrefaceLineCount = countChars(nonJSPreface, '\n'); - } else { - nonJSPreface = ''; - nonJSPrefaceLineCount = 0; - } - - nonJSPrefacingLines += lastStringCount + preMatchLines + nonJSPrefaceLineCount; // Ignore `preMatch` delta if newlines here - - if (nonJSPrefaceLineCount) { - const charsInLastLine = nonJSPreface.slice(nonJSPreface.lastIndexOf('\n') + 1).length; - nonJSPrefacingCols += charsInLastLine; - } else { - nonJSPrefacingCols += colDelta + nonJSPreface.length; - } - - const string = n1 || n0; - sources.push({ - nonJSPrefacingCols, - nonJSPrefacingLines, - string - }); - startingIndex = exampleCodeRegex.lastIndex; - lastStringCount = countChars(string, '\n'); - - if (!exampleCodeRegex.global) { - break; - } - } - - skipInit = true; - } - - checkSource({ - cols, - lines, - rules: mdRules, - skipInit, - source, - sources, - tag, - targetTagName, - ...matchingFilenameInfo - }); - }); -}, { - iterateAllJsdocs: true, - meta: { - docs: { - description: 'Ensures that (JavaScript) examples within JSDoc adhere to ESLint rules.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-examples' - }, - schema: [{ - additionalProperties: false, - properties: { - allowInlineConfig: { - default: true, - type: 'boolean' - }, - baseConfig: { - type: 'object' - }, - captionRequired: { - default: false, - type: 'boolean' - }, - checkDefaults: { - default: false, - type: 'boolean' - }, - checkEslintrc: { - default: true, - type: 'boolean' - }, - checkParams: { - default: false, - type: 'boolean' - }, - checkProperties: { - default: false, - type: 'boolean' - }, - configFile: { - type: 'string' - }, - exampleCodeRegex: { - type: 'string' - }, - matchingFileName: { - type: 'string' - }, - matchingFileNameDefaults: { - type: 'string' - }, - matchingFileNameParams: { - type: 'string' - }, - matchingFileNameProperties: { - type: 'string' - }, - noDefaultExampleRules: { - default: false, - type: 'boolean' - }, - paddedIndent: { - default: 0, - type: 'integer' - }, - rejectExampleCodeRegex: { - type: 'string' - }, - reportUnusedDisableDirectives: { - default: true, - type: 'boolean' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=checkExamples.js.map -}); - -var checkIndentation = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const maskExcludedContent = (str, excludeTags) => { - const regContent = new RegExp(`([ \\t]+\\*)[ \\t]@(?:${excludeTags.join('|')})(?=[ \\n])([\\w|\\W]*?\\n)(?=[ \\t]*\\*(?:[ \\t]*@|\\/))`, 'gu'); - return str.replace(regContent, (_match, margin, code) => { - return new Array(code.match(/\n/gu).length + 1).join(margin + '\n'); - }); -}; - -const maskCodeBlocks = str => { - const regContent = /([ \t]+\*)[ \t]```[^\n]*?([\w|\W]*?\n)(?=[ \t]*\*(?:[ \t]*(?:```|@)|\/))/gu; - return str.replace(regContent, (_match, margin, code) => { - return new Array(code.match(/\n/gu).length + 1).join(margin + '\n'); - }); -}; - -var _default = (0, _iterateJsdoc.default)(({ - sourceCode, - jsdocNode, - report, - context -}) => { - const options = context.options[0] || {}; - const { - excludeTags = ['example'] - } = options; - const reg = new RegExp(/^(?:\/?\**|[ \t]*)\*[ \t]{2}/gmu); - const textWithoutCodeBlocks = maskCodeBlocks(sourceCode.getText(jsdocNode)); - const text = excludeTags.length ? maskExcludedContent(textWithoutCodeBlocks, excludeTags) : textWithoutCodeBlocks; - - if (reg.test(text)) { - const lineBreaks = text.slice(0, reg.lastIndex).match(/\n/gu) || []; - report('There must be no indentation.', null, { - line: lineBreaks.length - }); - } -}, { - iterateAllJsdocs: true, - meta: { - docs: { - description: 'Reports invalid padding inside JSDoc blocks.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-indentation' - }, - schema: [{ - additionalProperties: false, - properties: { - excludeTags: { - items: { - pattern: '^\\S+$', - type: 'string' - }, - type: 'array' - } - }, - type: 'object' - }], - type: 'layout' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=checkIndentation.js.map -}); - -var checkLineAlignment = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - - - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const { - flow: commentFlow, - align: commentAlign, - indent: commentIndent -} = lib.transforms; - -const checkNotAlignedPerTag = (utils, tag) => { - /* - start + - delimiter + - postDelimiter + - tag + - postTag + - type + - postType + - name + - postName + - description + - end - */ - let spacerProps; - let contentProps; - const mightHaveNamepath = utils.tagMightHaveNamepath(tag.tag); - - if (mightHaveNamepath) { - spacerProps = ['postDelimiter', 'postTag', 'postType', 'postName']; - contentProps = ['tag', 'type', 'name', 'description']; - } else { - spacerProps = ['postDelimiter', 'postTag', 'postType']; - contentProps = ['tag', 'type', 'description']; - } - - const { - tokens - } = tag.source[0]; - - const followedBySpace = (idx, callbck) => { - const nextIndex = idx + 1; - return spacerProps.slice(nextIndex).some((spacerProp, innerIdx) => { - const contentProp = contentProps[nextIndex + innerIdx]; - const spacePropVal = tokens[spacerProp]; - const ret = spacePropVal; - - if (callbck) { - callbck(!ret, contentProp); - } - - return ret; - }); - }; // If checking alignment on multiple lines, need to check other `source` - // items - // Go through `post*` spacing properties and exit to indicate problem if - // extra spacing detected - - - const ok = !spacerProps.some((spacerProp, idx) => { - const contentProp = contentProps[idx]; - const contentPropVal = tokens[contentProp]; - const spacerPropVal = tokens[spacerProp]; // There will be extra alignment if... - // 1. There is extra whitespace within a single spacer segment OR - - return spacerPropVal.length > 1 || // 2. There is a (single) space, no immediate content, and yet another - // space is found subsequently (not separated by intervening content) - spacerPropVal && !contentPropVal && followedBySpace(idx); - }); - - if (ok) { - return; - } - - const fix = () => { - spacerProps.forEach((spacerProp, idx) => { - const contentProp = contentProps[idx]; - const contentPropVal = tokens[contentProp]; - - if (contentPropVal) { - tokens[spacerProp] = ' '; - followedBySpace(idx, (hasSpace, contentPrp) => { - if (hasSpace) { - tokens[contentPrp] = ''; - } - }); - } else { - tokens[spacerProp] = ''; - } - }); - utils.setTag(tag, tokens); - }; - - utils.reportJSDoc('Expected JSDoc block lines to not be aligned.', tag, fix, true); -}; - -const checkAlignment = ({ - indent, - jsdoc, - jsdocNode, - report, - utils -}) => { - const transform = commentFlow(commentAlign(), commentIndent(indent.length)); - const transformedJsdoc = transform(jsdoc); - const comment = '/*' + jsdocNode.value + '*/'; - const formatted = utils.stringify(transformedJsdoc).trimStart(); - - if (comment !== formatted) { - report('Expected JSDoc block lines to be aligned.', fixer => { - return fixer.replaceText(jsdocNode, formatted); - }); - } -}; - -var _default = (0, _iterateJsdoc.default)(({ - indent, - jsdoc, - jsdocNode, - report, - context, - utils -}) => { - const { - tags: applicableTags = ['param', 'arg', 'argument', 'property', 'prop', 'returns', 'return'] - } = context.options[1] || {}; - - if (context.options[0] === 'always') { - // Skip if it contains only a single line. - if (!jsdocNode.value.includes('\n')) { - return; - } - - checkAlignment({ - indent, - jsdoc, - jsdocNode, - report, - utils - }); - return; - } - - const foundTags = utils.getPresentTags(applicableTags); - foundTags.forEach(tag => { - checkNotAlignedPerTag(utils, tag); - }); -}, { - iterateAllJsdocs: true, - meta: { - docs: { - description: 'Reports invalid alignment of JSDoc block lines.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-line-alignment' - }, - fixable: 'whitespace', - schema: [{ - enum: ['always', 'never'], - type: 'string' - }, { - additionalProperties: false, - properties: { - tags: { - items: { - type: 'string' - }, - type: 'array' - } - }, - type: 'object' - }], - type: 'layout' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=checkLineAlignment.js.map -}); - -var checkParamNames = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const validateParameterNames = (targetTagName, allowExtraTrailingParamDocs, checkDestructured, checkRestProperty, checkTypesRegex, disableExtraPropertyReporting, enableFixer, functionParameterNames, jsdoc, _jsdocNode, utils, report) => { - const paramTags = Object.entries(jsdoc.tags).filter(([, tag]) => { - return tag.tag === targetTagName; - }); - const paramTagsNonNested = paramTags.filter(([, tag]) => { - return !tag.name.includes('.'); - }); - let dotted = 0; - return paramTags.some(([, tag], index) => { - let tagsIndex; - const dupeTagInfo = paramTags.find(([tgsIndex, tg], idx) => { - tagsIndex = tgsIndex; - return tg.name === tag.name && idx !== index; - }); - - if (dupeTagInfo) { - utils.reportJSDoc(`Duplicate @${targetTagName} "${tag.name}"`, dupeTagInfo[1], enableFixer ? () => { - utils.removeTag(tagsIndex); - } : null); - return true; - } - - if (tag.name.includes('.')) { - dotted++; - return false; - } - - const functionParameterName = functionParameterNames[index - dotted]; - - if (!functionParameterName) { - if (allowExtraTrailingParamDocs) { - return false; - } - - report(`@${targetTagName} "${tag.name}" does not match an existing function parameter.`, null, tag); - return true; - } - - if (Array.isArray(functionParameterName)) { - if (!checkDestructured) { - return false; - } - - if (tag.type && tag.type.search(checkTypesRegex) === -1) { - return false; - } - - const [parameterName, { - names: properties, - hasPropertyRest, - rests, - annotationParamName - }] = functionParameterName; - - if (annotationParamName !== undefined) { - const name = tag.name.trim(); - - if (name !== annotationParamName) { - report(`@${targetTagName} "${name}" does not match parameter name "${annotationParamName}"`, null, tag); - } - } - - const tagName = parameterName === undefined ? tag.name.trim() : parameterName; - const expectedNames = properties.map(name => { - return `${tagName}.${name}`; - }); - const actualNames = paramTags.map(([, paramTag]) => { - return paramTag.name.trim(); - }); - const actualTypes = paramTags.map(([, paramTag]) => { - return paramTag.type; - }); - const missingProperties = []; - const notCheckingNames = []; - expectedNames.forEach((name, idx) => { - if (notCheckingNames.some(notCheckingName => { - return name.startsWith(notCheckingName); - })) { - return; - } - - const actualNameIdx = actualNames.findIndex(actualName => { - return utils.comparePaths(name)(actualName); - }); - - if (actualNameIdx === -1) { - if (!checkRestProperty && rests[idx]) { - return; - } - - missingProperties.push(name); - } else if (actualTypes[actualNameIdx].search(checkTypesRegex) === -1 && actualTypes[actualNameIdx] !== '') { - notCheckingNames.push(name); - } - }); - const hasMissing = missingProperties.length; - - if (hasMissing) { - missingProperties.forEach(missingProperty => { - report(`Missing @${targetTagName} "${missingProperty}"`, null, tag); - }); - } - - if (!hasPropertyRest || checkRestProperty) { - const extraProperties = []; - actualNames.forEach((name, idx) => { - const match = name.startsWith(tag.name.trim() + '.'); - - if (match && !expectedNames.some(utils.comparePaths(name)) && !utils.comparePaths(name)(tag.name) && (!disableExtraPropertyReporting || properties.some(prop => { - return prop.split('.').length >= name.split('.').length - 1; - }))) { - extraProperties.push([name, paramTags[idx][1]]); - } - }); - - if (extraProperties.length) { - extraProperties.forEach(([extraProperty, tg]) => { - report(`@${targetTagName} "${extraProperty}" does not exist on ${tag.name}`, null, tg); - }); - return true; - } - } - - return hasMissing; - } - - let funcParamName; - - if (typeof functionParameterName === 'object') { - const { - name - } = functionParameterName; - funcParamName = name; - } else { - funcParamName = functionParameterName; - } - - if (funcParamName !== tag.name.trim()) { - // Todo: Improve for array or object child items - const actualNames = paramTagsNonNested.map(([, { - name - }]) => { - return name.trim(); - }); - const expectedNames = functionParameterNames.map((item, idx) => { - var _item$; - - if (item !== null && item !== void 0 && (_item$ = item[1]) !== null && _item$ !== void 0 && _item$.names) { - return actualNames[idx]; - } - - return item; - }).join(', '); - report(`Expected @${targetTagName} names to be "${expectedNames}". Got "${actualNames.join(', ')}".`, null, tag); - return true; - } - - return false; - }); -}; - -const validateParameterNamesDeep = (targetTagName, _allowExtraTrailingParamDocs, jsdocParameterNames, jsdoc, report) => { - let lastRealParameter; - return jsdocParameterNames.some(({ - name: jsdocParameterName, - idx - }) => { - const isPropertyPath = jsdocParameterName.includes('.'); - - if (isPropertyPath) { - if (!lastRealParameter) { - report(`@${targetTagName} path declaration ("${jsdocParameterName}") appears before any real parameter.`, null, jsdoc.tags[idx]); - return true; - } - - let pathRootNodeName = jsdocParameterName.slice(0, jsdocParameterName.indexOf('.')); - - if (pathRootNodeName.endsWith('[]')) { - pathRootNodeName = pathRootNodeName.slice(0, -2); - } - - if (pathRootNodeName !== lastRealParameter) { - report(`@${targetTagName} path declaration ("${jsdocParameterName}") root node name ("${pathRootNodeName}") ` + `does not match previous real parameter name ("${lastRealParameter}").`, null, jsdoc.tags[idx]); - return true; - } - } else { - lastRealParameter = jsdocParameterName; - } - - return false; - }); -}; - -var _default = (0, _iterateJsdoc.default)(({ - context, - jsdoc, - jsdocNode, - report, - utils -}) => { - const { - allowExtraTrailingParamDocs, - checkDestructured = true, - checkRestProperty = false, - checkTypesPattern = '/^(?:[oO]bject|[aA]rray|PlainObject|Generic(?:Object|Array))$/', - enableFixer = false, - useDefaultObjectProperties = false, - disableExtraPropertyReporting = false - } = context.options[0] || {}; - const checkTypesRegex = utils.getRegexFromString(checkTypesPattern); - const jsdocParameterNamesDeep = utils.getJsdocTagsDeep('param'); - - if (!jsdocParameterNamesDeep.length) { - return; - } - - const functionParameterNames = utils.getFunctionParameterNames(useDefaultObjectProperties); - const targetTagName = utils.getPreferredTagName({ - tagName: 'param' - }); - const isError = validateParameterNames(targetTagName, allowExtraTrailingParamDocs, checkDestructured, checkRestProperty, checkTypesRegex, disableExtraPropertyReporting, enableFixer, functionParameterNames, jsdoc, jsdocNode, utils, report); - - if (isError || !checkDestructured) { - return; - } - - validateParameterNamesDeep(targetTagName, allowExtraTrailingParamDocs, jsdocParameterNamesDeep, jsdoc, report); -}, { - meta: { - docs: { - description: 'Ensures that parameter names in JSDoc match those in the function declaration.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-param-names' - }, - fixable: 'code', - schema: [{ - additionalProperties: false, - properties: { - allowExtraTrailingParamDocs: { - type: 'boolean' - }, - checkDestructured: { - type: 'boolean' - }, - checkRestProperty: { - type: 'boolean' - }, - checkTypesPattern: { - type: 'string' - }, - disableExtraPropertyReporting: { - type: 'boolean' - }, - enableFixer: { - type: 'boolean' - }, - useDefaultObjectProperties: { - type: 'boolean' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=checkParamNames.js.map -}); - -var checkPropertyNames = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const validatePropertyNames = (targetTagName, enableFixer, jsdoc, jsdocNode, utils) => { - const propertyTags = Object.entries(jsdoc.tags).filter(([, tag]) => { - return tag.tag === targetTagName; - }); - return propertyTags.some(([, tag], index) => { - let tagsIndex; - const dupeTagInfo = propertyTags.find(([tgsIndex, tg], idx) => { - tagsIndex = tgsIndex; - return tg.name === tag.name && idx !== index; - }); - - if (dupeTagInfo) { - utils.reportJSDoc(`Duplicate @${targetTagName} "${tag.name}"`, dupeTagInfo[1], enableFixer ? () => { - utils.removeTag(tagsIndex); - } : null); - return true; - } - - return false; - }); -}; - -const validatePropertyNamesDeep = (targetTagName, jsdocPropertyNames, jsdoc, report) => { - let lastRealProperty; - return jsdocPropertyNames.some(({ - name: jsdocPropertyName, - idx - }) => { - const isPropertyPath = jsdocPropertyName.includes('.'); - - if (isPropertyPath) { - if (!lastRealProperty) { - report(`@${targetTagName} path declaration ("${jsdocPropertyName}") appears before any real property.`, null, jsdoc.tags[idx]); - return true; - } - - let pathRootNodeName = jsdocPropertyName.slice(0, jsdocPropertyName.indexOf('.')); - - if (pathRootNodeName.endsWith('[]')) { - pathRootNodeName = pathRootNodeName.slice(0, -2); - } - - if (pathRootNodeName !== lastRealProperty) { - report(`@${targetTagName} path declaration ("${jsdocPropertyName}") root node name ("${pathRootNodeName}") ` + `does not match previous real property name ("${lastRealProperty}").`, null, jsdoc.tags[idx]); - return true; - } - } else { - lastRealProperty = jsdocPropertyName; - } - - return false; - }); -}; - -var _default = (0, _iterateJsdoc.default)(({ - context, - jsdoc, - jsdocNode, - report, - utils -}) => { - const { - enableFixer = false - } = context.options[0] || {}; - const jsdocPropertyNamesDeep = utils.getJsdocTagsDeep('property'); - - if (!jsdocPropertyNamesDeep.length) { - return; - } - - const targetTagName = utils.getPreferredTagName({ - tagName: 'property' - }); - const isError = validatePropertyNames(targetTagName, enableFixer, jsdoc, jsdocNode, utils); - - if (isError) { - return; - } - - validatePropertyNamesDeep(targetTagName, jsdocPropertyNamesDeep, jsdoc, report); -}, { - iterateAllJsdocs: true, - meta: { - docs: { - description: 'Ensures that property names in JSDoc are not duplicated on the same block and that nested properties have defined roots.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-property-names' - }, - fixable: 'code', - schema: [{ - additionalProperties: false, - properties: { - enableFixer: { - type: 'boolean' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=checkPropertyNames.js.map -}); - -var checkSyntax = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var _default = (0, _iterateJsdoc.default)(({ - jsdoc, - report, - settings -}) => { - const { - mode - } = settings; // Don't check for "permissive" and "closure" - - if (mode === 'jsdoc' || mode === 'typescript') { - for (const tag of jsdoc.tags) { - if (tag.type.slice(-1) === '=') { - report('Syntax should not be Google Closure Compiler style.', null, tag); - break; - } - } - } -}, { - iterateAllJsdocs: true, - meta: { - docs: { - description: 'Reports against syntax not valid for the mode (e.g., Google Closure Compiler in non-Closure mode).', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-syntax' - }, - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=checkSyntax.js.map -}); - -var checkTagNames = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _lodash = _interopRequireDefault(lodash__default['default']); - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// https://babeljs.io/docs/en/babel-plugin-transform-react-jsx/ -const jsxTagNames = new Set(['jsx', 'jsxFrag', 'jsxImportSource', 'jsxRuntime']); - -var _default = (0, _iterateJsdoc.default)(({ - sourceCode, - jsdoc, - report, - utils, - context, - settings, - jsdocNode -}) => { - const { - definedTags = [], - jsxTags - } = context.options[0] || {}; - let definedPreferredTags = []; - const { - tagNamePreference, - structuredTags - } = settings; - const definedStructuredTags = Object.keys(structuredTags); - const definedNonPreferredTags = Object.keys(tagNamePreference); - - if (definedNonPreferredTags.length) { - definedPreferredTags = Object.values(tagNamePreference).map(preferredTag => { - if (typeof preferredTag === 'string') { - // May become an empty string but will be filtered out below - return preferredTag; - } - - if (!preferredTag) { - return undefined; - } - - if (typeof preferredTag !== 'object') { - utils.reportSettings('Invalid `settings.jsdoc.tagNamePreference`. Values must be falsy, a string, or an object.'); - } - - return preferredTag.replacement; - }).filter(preferredType => { - return preferredType; - }); - } - - jsdoc.tags.forEach(jsdocTag => { - const tagName = jsdocTag.tag; - - if (jsxTags && jsxTagNames.has(tagName)) { - return; - } - - if (utils.isValidTag(tagName, [...definedTags, ...definedPreferredTags, ...definedNonPreferredTags, ...definedStructuredTags])) { - let preferredTagName = utils.getPreferredTagName({ - allowObjectReturn: true, - defaultMessage: `Blacklisted tag found (\`@${tagName}\`)`, - tagName - }); - - if (!preferredTagName) { - return; - } - - let message; - - if (typeof preferredTagName === 'object') { - ({ - message, - replacement: preferredTagName - } = preferredTagName); - } - - if (!message) { - message = `Invalid JSDoc tag (preference). Replace "${tagName}" JSDoc tag with "${preferredTagName}".`; - } - - if (preferredTagName !== tagName) { - report(message, fixer => { - const replacement = sourceCode.getText(jsdocNode).replace(new RegExp(`@${_lodash.default.escapeRegExp(tagName)}\\b`, 'u'), `@${preferredTagName}`); - return fixer.replaceText(jsdocNode, replacement); - }, jsdocTag); - } - } else { - report(`Invalid JSDoc tag name "${tagName}".`, null, jsdocTag); - } - }); -}, { - iterateAllJsdocs: true, - meta: { - docs: { - description: 'Reports invalid block tag names.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-tag-names' - }, - fixable: 'code', - schema: [{ - additionalProperties: false, - properties: { - definedTags: { - items: { - type: 'string' - }, - type: 'array' - }, - jsxTags: { - type: 'boolean' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=checkTagNames.js.map -}); - -/** - * Syntax types for generic types. - * @enum {string} - */ -const GenericTypeSyntax = { - /** - * From TypeScript and Closure Library. - * Example: {@code Array} - */ - ANGLE_BRACKET: 'ANGLE_BRACKET', - - /** - * From JSDoc and Legacy Closure Library. - * Example: {@code Array.} - */ - ANGLE_BRACKET_WITH_DOT: 'ANGLE_BRACKET_WITH_DOT', - - /** - * From JSDoc. - * Example: {@code String[]} - */ - SQUARE_BRACKET: 'SQUARE_BRACKET', -}; - -const VariadicTypeSyntax$1 = { - /** - * From Closure Library. - * Example: {@code ...Type} - */ - PREFIX_DOTS: 'PREFIX_DOTS', - - /** - * From JSDuck. - * Example: {@code Type...} - */ - SUFFIX_DOTS: 'SUFFIX_DOTS', - - /** - * From Closure Library. - * Example: {@code ...} - */ - ONLY_DOTS: 'ONLY_DOTS', -}; - -const OptionalTypeSyntax$1 = { - PREFIX_EQUALS_SIGN: 'PREFIX_EQUALS_SIGN', - SUFFIX_EQUALS_SIGN: 'SUFFIX_EQUALS_SIGN', - SUFFIX_KEY_QUESTION_MARK: 'SUFFIX_KEY_QUESTION_MARK', -}; - -const NullableTypeSyntax = { - PREFIX_QUESTION_MARK: 'PREFIX_QUESTION_MARK', - SUFFIX_QUESTION_MARK: 'SUFFIX_QUESTION_MARK', -}; - -const NotNullableTypeSyntax = { - PREFIX_BANG: 'PREFIX_BANG', - SUFFIX_BANG: 'SUFFIX_BANG', -}; - -var SyntaxType = { - GenericTypeSyntax, - VariadicTypeSyntax: VariadicTypeSyntax$1, - OptionalTypeSyntax: OptionalTypeSyntax$1, - NullableTypeSyntax, - NotNullableTypeSyntax, -}; - -const NodeType = { - NAME: 'NAME', - MEMBER: 'MEMBER', - UNION: 'UNION', - INTERSECTION: 'INTERSECTION', - VARIADIC: 'VARIADIC', - RECORD: 'RECORD', - RECORD_ENTRY: 'RECORD_ENTRY', - TUPLE: 'TUPLE', - GENERIC: 'GENERIC', - MODULE: 'MODULE', - OPTIONAL: 'OPTIONAL', - NULLABLE: 'NULLABLE', - NOT_NULLABLE: 'NOT_NULLABLE', - FUNCTION: 'FUNCTION', - ARROW: 'ARROW', - NAMED_PARAMETER: 'NAMED_PARAMETER', - ANY: 'ANY', - UNKNOWN: 'UNKNOWN', - INNER_MEMBER: 'INNER_MEMBER', - INSTANCE_MEMBER: 'INSTANCE_MEMBER', - STRING_VALUE: 'STRING_VALUE', - NUMBER_VALUE: 'NUMBER_VALUE', - EXTERNAL: 'EXTERNAL', - FILE_PATH: 'FILE_PATH', - PARENTHESIS: 'PARENTHESIS', - TYPE_QUERY: 'TYPE_QUERY', - KEY_QUERY: 'KEY_QUERY', - IMPORT: 'IMPORT', -}; - -/** @typedef {keyof typeof NodeType} Type */ - -var NodeType_1 = /** @type {{readonly [T in Type]: T}} */ (NodeType); - -/* - * Generated by PEG.js 0.10.0. - * - * http://pegjs.org/ - */ - -function peg$subclass$3(child, parent) { - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor(); -} - -function peg$SyntaxError$3(message, expected, found, location) { - this.message = message; - this.expected = expected; - this.found = found; - this.location = location; - this.name = "SyntaxError"; - - if (typeof Error.captureStackTrace === "function") { - Error.captureStackTrace(this, peg$SyntaxError$3); - } -} - -peg$subclass$3(peg$SyntaxError$3, Error); - -peg$SyntaxError$3.buildMessage = function(expected, found) { - var DESCRIBE_EXPECTATION_FNS = { - literal: function(expectation) { - return "\"" + literalEscape(expectation.text) + "\""; - }, - - "class": function(expectation) { - var escapedParts = "", - i; - - for (i = 0; i < expectation.parts.length; i++) { - escapedParts += expectation.parts[i] instanceof Array - ? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1]) - : classEscape(expectation.parts[i]); - } - - return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]"; - }, - - any: function(expectation) { - return "any character"; - }, - - end: function(expectation) { - return "end of input"; - }, - - other: function(expectation) { - return expectation.description; - } - }; - - function hex(ch) { - return ch.charCodeAt(0).toString(16).toUpperCase(); - } - - function literalEscape(s) { - return s - .replace(/\\/g, '\\\\') - .replace(/"/g, '\\"') - .replace(/\0/g, '\\0') - .replace(/\t/g, '\\t') - .replace(/\n/g, '\\n') - .replace(/\r/g, '\\r') - .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) - .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); }); - } - - function classEscape(s) { - return s - .replace(/\\/g, '\\\\') - .replace(/\]/g, '\\]') - .replace(/\^/g, '\\^') - .replace(/-/g, '\\-') - .replace(/\0/g, '\\0') - .replace(/\t/g, '\\t') - .replace(/\n/g, '\\n') - .replace(/\r/g, '\\r') - .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) - .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); }); - } - - function describeExpectation(expectation) { - return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); - } - - function describeExpected(expected) { - var descriptions = new Array(expected.length), - i, j; - - for (i = 0; i < expected.length; i++) { - descriptions[i] = describeExpectation(expected[i]); - } - - descriptions.sort(); - - if (descriptions.length > 0) { - for (i = 1, j = 1; i < descriptions.length; i++) { - if (descriptions[i - 1] !== descriptions[i]) { - descriptions[j] = descriptions[i]; - j++; - } - } - descriptions.length = j; - } - - switch (descriptions.length) { - case 1: - return descriptions[0]; - - case 2: - return descriptions[0] + " or " + descriptions[1]; - - default: - return descriptions.slice(0, -1).join(", ") - + ", or " - + descriptions[descriptions.length - 1]; - } - } - - function describeFound(found) { - return found ? "\"" + literalEscape(found) + "\"" : "end of input"; - } - - return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; -}; - -function peg$parse$3(input, options) { - options = options !== void 0 ? options : {}; - - var peg$FAILED = {}, - - peg$startRuleFunctions = { TopTypeExpr: peg$parseTopTypeExpr, NamepathExpr: peg$parseNamepathExpr, BroadNamepathExpr: peg$parseBroadNamepathExpr, ExternalNameExpr: peg$parseExternalNameExpr, ModuleNameExpr: peg$parseModuleNameExpr }, - peg$startRuleFunction = peg$parseTopTypeExpr, - - peg$c0 = function(expr) { - return expr; - }, - peg$c1 = /^[ \t]/, - peg$c2 = peg$classExpectation([" ", "\t"], false, false), - peg$c3 = /^[\r]/, - peg$c4 = peg$classExpectation(["\r"], false, false), - peg$c5 = /^[\n]/, - peg$c6 = peg$classExpectation(["\n"], false, false), - peg$c7 = /^[a-zA-Z_$]/, - peg$c8 = peg$classExpectation([["a", "z"], ["A", "Z"], "_", "$"], false, false), - peg$c9 = /^[a-zA-Z0-9_$]/, - peg$c10 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$"], false, false), - peg$c11 = "event:", - peg$c12 = peg$literalExpectation("event:", false), - peg$c13 = function(rootOwner, memberPartWithOperators) { - return memberPartWithOperators.reduce(function(owner, tokens) { - const operatorType = tokens[1]; - const eventNamespace = tokens[3]; - const MemberName = tokens[5]; - const {quoteStyle, name: memberName} = MemberName; - - switch (operatorType) { - case NamepathOperatorType.MEMBER: - return { - type: NodeType.MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - case NamepathOperatorType.INSTANCE_MEMBER: - return { - type: NodeType.INSTANCE_MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - case NamepathOperatorType.INNER_MEMBER: - return { - type: NodeType.INNER_MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - /* istanbul ignore next */ - default: - throw new Error('Unexpected operator type: "' + operatorType + '"'); - } - }, rootOwner); - }, - peg$c14 = /^[a-zA-Z0-9_$\-]/, - peg$c15 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$", "-"], false, false), - peg$c16 = function(name) { - return { - type: NodeType.NAME, - name - }; - }, - peg$c17 = "'", - peg$c18 = peg$literalExpectation("'", false), - peg$c19 = /^[^\\']/, - peg$c20 = peg$classExpectation(["\\", "'"], true, false), - peg$c21 = "\\", - peg$c22 = peg$literalExpectation("\\", false), - peg$c23 = peg$anyExpectation(), - peg$c24 = function(name) { - return { - quoteStyle: 'single', - name: name.replace(/\\'/g, "'") - .replace(/\\\\/gu, '\\') - }; - }, - peg$c25 = "\"", - peg$c26 = peg$literalExpectation("\"", false), - peg$c27 = /^[^\\"]/, - peg$c28 = peg$classExpectation(["\\", "\""], true, false), - peg$c29 = function(name) { - return { - quoteStyle: 'double', - name: name.replace(/\\"/gu, '"') - .replace(/\\\\/gu, '\\') - }; - }, - peg$c30 = function(name) { - return { - quoteStyle: 'none', - name - }; - }, - peg$c31 = ".", - peg$c32 = peg$literalExpectation(".", false), - peg$c33 = function(rootOwner, memberPart) { - return memberPart.reduce(function(owner, tokens) { - return { - type: NodeType.MEMBER, - owner, - name: tokens[3] - } - }, rootOwner); - }, - peg$c34 = function() { - return NamepathOperatorType.MEMBER; - }, - peg$c35 = "~", - peg$c36 = peg$literalExpectation("~", false), - peg$c37 = function() { - return NamepathOperatorType.INNER_MEMBER; - }, - peg$c38 = "#", - peg$c39 = peg$literalExpectation("#", false), - peg$c40 = function() { - return NamepathOperatorType.INSTANCE_MEMBER; - }, - peg$c41 = "external", - peg$c42 = peg$literalExpectation("external", false), - peg$c43 = ":", - peg$c44 = peg$literalExpectation(":", false), - peg$c45 = function(external, memberPartWithOperators) { - return memberPartWithOperators.reduce(function(owner, tokens) { - const operatorType = tokens[1]; - const eventNamespace = tokens[3]; - const MemberName = tokens[5]; - const {quoteStyle, name: memberName} = MemberName; - - switch (operatorType) { - case NamepathOperatorType.MEMBER: - return { - type: NodeType.MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - case NamepathOperatorType.INSTANCE_MEMBER: - return { - type: NodeType.INSTANCE_MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - case NamepathOperatorType.INNER_MEMBER: - return { - type: NodeType.INNER_MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - /* istanbul ignore next */ - default: - throw new Error('Unexpected operator type: "' + operatorType + '"'); - } - }, Object.assign({ - type: NodeType.EXTERNAL - }, external)); - }, - peg$c46 = "module", - peg$c47 = peg$literalExpectation("module", false), - peg$c48 = function(value) { - return { - type: NodeType.MODULE, - value, - }; - }, - peg$c49 = function(rootOwner, memberPartWithOperators) { - return memberPartWithOperators.reduce(function(owner, tokens) { - const operatorType = tokens[1]; - const eventNamespace = tokens[3]; - const MemberName = tokens[5]; - const {quoteStyle, name: memberName} = MemberName; - - switch (operatorType) { - case NamepathOperatorType.MEMBER: - return { - type: NodeType.MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - case NamepathOperatorType.INSTANCE_MEMBER: - return { - type: NodeType.INSTANCE_MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - case NamepathOperatorType.INNER_MEMBER: - return { - type: NodeType.INNER_MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - /* istanbul ignore next */ - default: - throw new Error('Unexpected operator type: "' + operatorType + '"'); - } - }, rootOwner); - }, - peg$c50 = function(path) { - return { - quoteStyle: 'single', - type: NodeType.FILE_PATH, - path: path.replace(/\\'/g, "'") - .replace(/\\\\/gu, '\\') - }; - }, - peg$c51 = function(path) { - return { - quoteStyle: 'double', - type: NodeType.FILE_PATH, - path: path.replace(/\\"/gu, '"') - .replace(/\\\\/gu, '\\') - }; - }, - peg$c52 = /^[a-zA-Z0-9_$\/\-]/, - peg$c53 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$", "/", "-"], false, false), - peg$c54 = function(path) { - return { - quoteStyle: 'none', - type: NodeType.FILE_PATH, - path, - }; - }, - peg$c55 = "*", - peg$c56 = peg$literalExpectation("*", false), - peg$c57 = function() { - return { type: NodeType.ANY }; - }, - peg$c58 = "?", - peg$c59 = peg$literalExpectation("?", false), - peg$c60 = function() { - return { type: NodeType.UNKNOWN }; - }, - peg$c61 = function(value) { - return { - type: NodeType.STRING_VALUE, - quoteStyle: 'double', - string: value.replace(/\\"/gu, '"') - .replace(/\\\\/gu, '\\') - }; - }, - peg$c62 = function(value) { - return { - type: NodeType.STRING_VALUE, - quoteStyle: 'single', - string: value.replace(/\\'/g, "'") - .replace(/\\\\/gu, '\\') - }; - }, - peg$c63 = function(value) { - return { - type: NodeType.NUMBER_VALUE, - number: value - }; - }, - peg$c64 = "+", - peg$c65 = peg$literalExpectation("+", false), - peg$c66 = "-", - peg$c67 = peg$literalExpectation("-", false), - peg$c68 = /^[0-9]/, - peg$c69 = peg$classExpectation([["0", "9"]], false, false), - peg$c70 = "e", - peg$c71 = peg$literalExpectation("e", false), - peg$c72 = "0b", - peg$c73 = peg$literalExpectation("0b", false), - peg$c74 = /^[01]/, - peg$c75 = peg$classExpectation(["0", "1"], false, false), - peg$c76 = "0o", - peg$c77 = peg$literalExpectation("0o", false), - peg$c78 = /^[0-7]/, - peg$c79 = peg$classExpectation([["0", "7"]], false, false), - peg$c80 = "0x", - peg$c81 = peg$literalExpectation("0x", false), - peg$c82 = /^[0-9a-fA-F]/, - peg$c83 = peg$classExpectation([["0", "9"], ["a", "f"], ["A", "F"]], false, false), - peg$c84 = "&", - peg$c85 = peg$literalExpectation("&", false), - peg$c86 = function(left, right) { - return { - type: NodeType.INTERSECTION, - left, - right, - }; - }, - peg$c87 = "|", - peg$c88 = peg$literalExpectation("|", false), - peg$c89 = function(left, right) { - return { - type: NodeType.UNION, - left, - right, - }; - }, - peg$c90 = "typeof", - peg$c91 = peg$literalExpectation("typeof", false), - peg$c92 = function(operator, name) { - return { - type: NodeType.TYPE_QUERY, - name, - }; - }, - peg$c93 = "keyof", - peg$c94 = peg$literalExpectation("keyof", false), - peg$c95 = function(operator, operand) { - return { - type: NodeType.KEY_QUERY, - value: operand, - } - }, - peg$c96 = "import", - peg$c97 = peg$literalExpectation("import", false), - peg$c98 = "(", - peg$c99 = peg$literalExpectation("(", false), - peg$c100 = ")", - peg$c101 = peg$literalExpectation(")", false), - peg$c102 = function(operator, path) { - return { type: NodeType.IMPORT, path }; - }, - peg$c103 = function(operator, operand) { - return { - type: NodeType.NULLABLE, - value: operand, - meta: { syntax: NullableTypeSyntax.PREFIX_QUESTION_MARK }, - }; - }, - peg$c104 = "!", - peg$c105 = peg$literalExpectation("!", false), - peg$c106 = function(operator, operand) { - return { - type: NodeType.NOT_NULLABLE, - value: operand, - meta: { syntax: NotNullableTypeSyntax.PREFIX_BANG }, - }; - }, - peg$c107 = "=", - peg$c108 = peg$literalExpectation("=", false), - peg$c109 = function(operator, operand) { - return { - type: NodeType.OPTIONAL, - value: operand, - meta: { syntax: OptionalTypeSyntax.PREFIX_EQUALS_SIGN }, - }; - }, - peg$c110 = function(operand, operator) { - return { - type: NodeType.NULLABLE, - value: operand, - meta: { syntax: NullableTypeSyntax.SUFFIX_QUESTION_MARK }, - }; - }, - peg$c111 = function(operand, operator) { - return { - type: NodeType.NOT_NULLABLE, - value: operand, - meta: { syntax: NotNullableTypeSyntax.SUFFIX_BANG }, - }; - }, - peg$c112 = function(operand, operator) { - return { - type: NodeType.OPTIONAL, - value: operand, - meta: { syntax: OptionalTypeSyntax.SUFFIX_EQUALS_SIGN }, - }; - }, - peg$c113 = function(operand, syntax, params) { - return { - type: NodeType.GENERIC, - subject: operand, - objects: params, - meta: { syntax }, - }; - }, - peg$c114 = ",", - peg$c115 = peg$literalExpectation(",", false), - peg$c116 = function(first, restsWithComma) { - return restsWithComma.reduce(function(params, tokens) { - return params.concat([tokens[3]]); - }, [first]); - }, - peg$c117 = ".<", - peg$c118 = peg$literalExpectation(".<", false), - peg$c119 = function() { - return GenericTypeSyntax.ANGLE_BRACKET_WITH_DOT; - }, - peg$c120 = "<", - peg$c121 = peg$literalExpectation("<", false), - peg$c122 = function() { - return GenericTypeSyntax.ANGLE_BRACKET; - }, - peg$c123 = ">", - peg$c124 = peg$literalExpectation(">", false), - peg$c125 = "[", - peg$c126 = peg$literalExpectation("[", false), - peg$c127 = "]", - peg$c128 = peg$literalExpectation("]", false), - peg$c129 = function(operand, brackets) { - return brackets.reduce(function(operand) { - return { - type: NodeType.GENERIC, - subject: { - type: NodeType.NAME, - name: 'Array' - }, - objects: [ operand ], - meta: { syntax: GenericTypeSyntax.SQUARE_BRACKET }, - }; - }, operand); - }, - peg$c130 = "new", - peg$c131 = peg$literalExpectation("new", false), - peg$c132 = "=>", - peg$c133 = peg$literalExpectation("=>", false), - peg$c134 = function(newModifier, paramsPart, returnedTypeNode) { - return { - type: NodeType.ARROW, - params: paramsPart, - returns: returnedTypeNode, - new: newModifier - }; - }, - peg$c135 = function() { - return []; - }, - peg$c136 = function(params) { - return params; - }, - peg$c137 = function(paramsWithComma, lastParam) { - return paramsWithComma.reduceRight(function(params, tokens) { - const param = { type: NodeType.NAMED_PARAMETER, name: tokens[0], typeName: tokens[4] }; - return [param].concat(params); - }, lastParam ? [lastParam] : []); - }, - peg$c138 = "...", - peg$c139 = peg$literalExpectation("...", false), - peg$c140 = function(spread, id, type) { - const operand = { type: NodeType.NAMED_PARAMETER, name: id, typeName: type }; - if (spread) { - return { - type: NodeType.VARIADIC, - value: operand, - meta: { syntax: VariadicTypeSyntax.PREFIX_DOTS }, - }; - } - else { - return operand; - } - }, - peg$c141 = "function", - peg$c142 = peg$literalExpectation("function", false), - peg$c143 = function(paramsPart, returnedTypePart) { - const returnedTypeNode = returnedTypePart ? returnedTypePart[2] : null; - - return { - type: NodeType.FUNCTION, - params: paramsPart.params, - returns: returnedTypeNode, - this: paramsPart.modifier.nodeThis, - new: paramsPart.modifier.nodeNew, - }; - }, - peg$c144 = function(modifier, params) { - return { params, modifier }; - }, - peg$c145 = function(modifier) { - return { params: [], modifier }; - }, - peg$c146 = function() { - return { params: [], modifier: { nodeThis: null, nodeNew: null } }; - }, - peg$c147 = function(params) { - return { params, modifier: { nodeThis: null, nodeNew: null } }; - }, - peg$c148 = "this", - peg$c149 = peg$literalExpectation("this", false), - peg$c150 = function(modifierThis) { - return { nodeThis: modifierThis[4], nodeNew: null }; - }, - peg$c151 = function(modifierNew) { - return { nodeThis: null, nodeNew: modifierNew[4] }; - }, - peg$c152 = function(paramsWithComma, lastParam) { - return paramsWithComma.reduceRight(function(params, tokens) { - const [param] = tokens; - return [param].concat(params); - }, lastParam ? [lastParam] : []); - }, - peg$c153 = "{", - peg$c154 = peg$literalExpectation("{", false), - peg$c155 = "}", - peg$c156 = peg$literalExpectation("}", false), - peg$c157 = function(entries) { - return { - type: NodeType.RECORD, - entries: entries || [], - }; - }, - peg$c158 = ";", - peg$c159 = peg$literalExpectation(";", false), - peg$c160 = function(first, restWithComma) { - return restWithComma.reduce(function(entries, tokens) { - const entry = tokens[2]; - return entries.concat([entry]); - }, [first]); - }, - peg$c161 = "readonly", - peg$c162 = peg$literalExpectation("readonly", false), - peg$c163 = function(readonly, keyInfo, optional, value) { - const {quoteStyle, key} = keyInfo; - return { - type: NodeType.RECORD_ENTRY, - key, - quoteStyle, - value: - optional === '?' ? { - type: NodeType.OPTIONAL, - value, - meta: { syntax: OptionalTypeSyntax.SUFFIX_KEY_QUESTION_MARK }, - } : - value, - readonly: Boolean(readonly) - }; - }, - peg$c164 = function(readonly, keyInfo) { - const {quoteStyle, key} = keyInfo; - return { - type: NodeType.RECORD_ENTRY, - key, - quoteStyle, - value: null, - readonly: Boolean(readonly) - }; - }, - peg$c165 = function(key) { - return { - quoteStyle: 'double', - key: key.replace(/\\"/gu, '"') - .replace(/\\\\/gu, '\\') - }; - }, - peg$c166 = function(key) { - return { - quoteStyle: 'single', - key: key.replace(/\\'/g, "'") - .replace(/\\\\/gu, '\\') - }; - }, - peg$c167 = function(key) { - return { - quoteStyle: 'none', - key - }; - }, - peg$c168 = function(entries) { - return { - type: NodeType.TUPLE, - entries, - } - }, - peg$c169 = function(restWithComma, last) { - return restWithComma.reduceRight((entries, tokens) => { - let [entry] = tokens; - return [entry].concat(entries); - }, last ? [last] : []); - }, - peg$c170 = function(wrapped) { - return { - type: NodeType.PARENTHESIS, - value: wrapped, - }; - }, - peg$c171 = function(operand) { - return { - type: NodeType.VARIADIC, - value: operand, - meta: { syntax: VariadicTypeSyntax.PREFIX_DOTS }, - }; - }, - peg$c172 = function(operand) { - return { - type: NodeType.VARIADIC, - value: operand, - meta: { syntax: VariadicTypeSyntax.SUFFIX_DOTS }, - }; - }, - peg$c173 = function() { - return { - type: NodeType.VARIADIC, - value: { type: NodeType.ANY }, - meta: { syntax: VariadicTypeSyntax.ONLY_DOTS }, - }; - }, - - peg$currPos = 0, - peg$posDetailsCache = [{ line: 1, column: 1 }], - peg$maxFailPos = 0, - peg$maxFailExpected = [], - peg$resultsCache = {}, - - peg$result; - - if ("startRule" in options) { - if (!(options.startRule in peg$startRuleFunctions)) { - throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); - } - - peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; - } - - function peg$literalExpectation(text, ignoreCase) { - return { type: "literal", text: text, ignoreCase: ignoreCase }; - } - - function peg$classExpectation(parts, inverted, ignoreCase) { - return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase }; - } - - function peg$anyExpectation() { - return { type: "any" }; - } - - function peg$endExpectation() { - return { type: "end" }; - } - - function peg$computePosDetails(pos) { - var details = peg$posDetailsCache[pos], p; - - if (details) { - return details; - } else { - p = pos - 1; - while (!peg$posDetailsCache[p]) { - p--; - } - - details = peg$posDetailsCache[p]; - details = { - line: details.line, - column: details.column - }; - - while (p < pos) { - if (input.charCodeAt(p) === 10) { - details.line++; - details.column = 1; - } else { - details.column++; - } - - p++; - } - - peg$posDetailsCache[pos] = details; - return details; - } - } - - function peg$computeLocation(startPos, endPos) { - var startPosDetails = peg$computePosDetails(startPos), - endPosDetails = peg$computePosDetails(endPos); - - return { - start: { - offset: startPos, - line: startPosDetails.line, - column: startPosDetails.column - }, - end: { - offset: endPos, - line: endPosDetails.line, - column: endPosDetails.column - } - }; - } - - function peg$fail(expected) { - if (peg$currPos < peg$maxFailPos) { return; } - - if (peg$currPos > peg$maxFailPos) { - peg$maxFailPos = peg$currPos; - peg$maxFailExpected = []; - } - - peg$maxFailExpected.push(expected); - } - - function peg$buildStructuredError(expected, found, location) { - return new peg$SyntaxError$3( - peg$SyntaxError$3.buildMessage(expected, found), - expected, - found, - location - ); - } - - function peg$parseTopTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 82 + 0, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parse_(); - if (s1 !== peg$FAILED) { - s2 = peg$parseVariadicTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseUnionTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseIntersectionTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseUnaryUnionTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseArrayTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseGenericTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseRecordTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseTupleTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseArrowTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseFunctionTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseTypeQueryExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseKeyQueryExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseBroadNamepathExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseParenthesizedExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseValueExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseAnyTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - if (s3 !== peg$FAILED) { - s1 = peg$c0(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseWS() { - var s0, s1, s2; - - var key = peg$currPos * 82 + 1, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - if (peg$c1.test(input.charAt(peg$currPos))) { - s0 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s0 = peg$FAILED; - { peg$fail(peg$c2); } - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (peg$c3.test(input.charAt(peg$currPos))) { - s1 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c4); } - } - if (s1 === peg$FAILED) { - s1 = null; - } - if (s1 !== peg$FAILED) { - if (peg$c5.test(input.charAt(peg$currPos))) { - s2 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c6); } - } - if (s2 !== peg$FAILED) { - s1 = [s1, s2]; - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parse_() { - var s0, s1; - - var key = peg$currPos * 82 + 2, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = []; - s1 = peg$parseWS(); - while (s1 !== peg$FAILED) { - s0.push(s1); - s1 = peg$parseWS(); - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parse__() { - var s0, s1; - - var key = peg$currPos * 82 + 3, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = []; - s1 = peg$parseWS(); - if (s1 !== peg$FAILED) { - while (s1 !== peg$FAILED) { - s0.push(s1); - s1 = peg$parseWS(); - } - } else { - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseJsIdentifier() { - var s0, s1, s2, s3, s4; - - var key = peg$currPos * 82 + 4, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (peg$c7.test(input.charAt(peg$currPos))) { - s2 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c8); } - } - if (s2 !== peg$FAILED) { - s3 = []; - if (peg$c9.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c10); } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c9.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c10); } - } - } - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseNamepathExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - - var key = peg$currPos * 82 + 5, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseParenthesizedExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseImportTypeExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseTypeNameExprJsDocFlavored(); - } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseInfixNamepathOperator(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c11) { - s7 = peg$c11; - peg$currPos += 6; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c12); } - } - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - s9 = peg$parseMemberName(); - if (s9 !== peg$FAILED) { - s4 = [s4, s5, s6, s7, s8, s9]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseInfixNamepathOperator(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c11) { - s7 = peg$c11; - peg$currPos += 6; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c12); } - } - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - s9 = peg$parseMemberName(); - if (s9 !== peg$FAILED) { - s4 = [s4, s5, s6, s7, s8, s9]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s1 = peg$c13(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseTypeNameExprJsDocFlavored() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 82 + 6, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - s2 = peg$currPos; - if (peg$c7.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c8); } - } - if (s3 !== peg$FAILED) { - s4 = []; - if (peg$c14.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c15); } - } - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c14.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c15); } - } - } - if (s4 !== peg$FAILED) { - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - s1 = input.substring(s1, peg$currPos); - } else { - s1 = s2; - } - if (s1 !== peg$FAILED) { - s1 = peg$c16(s1); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseMemberName() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 82 + 7, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c17; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c17; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c24(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c25; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c25; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c29(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$parseJsIdentifier(); - if (s1 !== peg$FAILED) { - s1 = peg$c30(s1); - } - s0 = s1; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseInfixNamepathOperator() { - var s0; - - var key = peg$currPos * 82 + 8, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseMemberTypeOperator(); - if (s0 === peg$FAILED) { - s0 = peg$parseInstanceMemberTypeOperator(); - if (s0 === peg$FAILED) { - s0 = peg$parseInnerMemberTypeOperator(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseQualifiedMemberName() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 82 + 9, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseTypeNameExprJsDocFlavored(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 46) { - s5 = peg$c31; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c32); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseTypeNameExprJsDocFlavored(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 46) { - s5 = peg$c31; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c32); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseTypeNameExprJsDocFlavored(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s1 = peg$c33(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseMemberTypeOperator() { - var s0, s1; - - var key = peg$currPos * 82 + 10, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 46) { - s1 = peg$c31; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c32); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c34(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseInnerMemberTypeOperator() { - var s0, s1; - - var key = peg$currPos * 82 + 11, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 126) { - s1 = peg$c35; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c36); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c37(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseInstanceMemberTypeOperator() { - var s0, s1; - - var key = peg$currPos * 82 + 12, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 35) { - s1 = peg$c38; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c39); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c40(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseBroadNamepathExpr() { - var s0; - - var key = peg$currPos * 82 + 13, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseExternalNameExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseModuleNameExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNamepathExpr(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseExternalNameExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13; - - var key = peg$currPos * 82 + 14, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c41) { - s1 = peg$c41; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c42); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s3 = peg$c43; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseMemberName(); - if (s5 !== peg$FAILED) { - s6 = []; - s7 = peg$currPos; - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - s9 = peg$parseInfixNamepathOperator(); - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - if (s10 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c11) { - s11 = peg$c11; - peg$currPos += 6; - } else { - s11 = peg$FAILED; - { peg$fail(peg$c12); } - } - if (s11 === peg$FAILED) { - s11 = null; - } - if (s11 !== peg$FAILED) { - s12 = peg$parse_(); - if (s12 !== peg$FAILED) { - s13 = peg$parseMemberName(); - if (s13 !== peg$FAILED) { - s8 = [s8, s9, s10, s11, s12, s13]; - s7 = s8; - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - while (s7 !== peg$FAILED) { - s6.push(s7); - s7 = peg$currPos; - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - s9 = peg$parseInfixNamepathOperator(); - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - if (s10 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c11) { - s11 = peg$c11; - peg$currPos += 6; - } else { - s11 = peg$FAILED; - { peg$fail(peg$c12); } - } - if (s11 === peg$FAILED) { - s11 = null; - } - if (s11 !== peg$FAILED) { - s12 = peg$parse_(); - if (s12 !== peg$FAILED) { - s13 = peg$parseMemberName(); - if (s13 !== peg$FAILED) { - s8 = [s8, s9, s10, s11, s12, s13]; - s7 = s8; - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } - if (s6 !== peg$FAILED) { - s1 = peg$c45(s5, s6); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseModuleNameExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 82 + 15, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c46) { - s1 = peg$c46; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c47); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s3 = peg$c43; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseModulePathExpr(); - if (s5 !== peg$FAILED) { - s1 = peg$c48(s5); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseModulePathExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - - var key = peg$currPos * 82 + 16, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseFilePathExpr(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseInfixNamepathOperator(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c11) { - s7 = peg$c11; - peg$currPos += 6; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c12); } - } - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - s9 = peg$parseMemberName(); - if (s9 !== peg$FAILED) { - s4 = [s4, s5, s6, s7, s8, s9]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseInfixNamepathOperator(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c11) { - s7 = peg$c11; - peg$currPos += 6; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c12); } - } - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - s9 = peg$parseMemberName(); - if (s9 !== peg$FAILED) { - s4 = [s4, s5, s6, s7, s8, s9]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s1 = peg$c49(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFilePathExpr() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 82 + 17, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c17; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c17; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c50(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c25; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c25; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c51(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$currPos; - s2 = []; - if (peg$c52.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c53); } - } - if (s3 !== peg$FAILED) { - while (s3 !== peg$FAILED) { - s2.push(s3); - if (peg$c52.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c53); } - } - } - } else { - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - s1 = input.substring(s1, peg$currPos); - } else { - s1 = s2; - } - if (s1 !== peg$FAILED) { - s1 = peg$c54(s1); - } - s0 = s1; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseAnyTypeExpr() { - var s0, s1; - - var key = peg$currPos * 82 + 18, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 42) { - s1 = peg$c55; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c56); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c57(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseUnknownTypeExpr() { - var s0, s1; - - var key = peg$currPos * 82 + 19, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 63) { - s1 = peg$c58; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c59); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c60(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseValueExpr() { - var s0; - - var key = peg$currPos * 82 + 20, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseStringLiteralExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNumberLiteralExpr(); - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseStringLiteralExpr() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 82 + 21, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c25; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c25; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c61(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c17; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c17; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c62(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseNumberLiteralExpr() { - var s0, s1; - - var key = peg$currPos * 82 + 22, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseBinNumberLiteralExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseOctNumberLiteralExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseHexNumberLiteralExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseDecimalNumberLiteralExpr(); - } - } - } - if (s1 !== peg$FAILED) { - s1 = peg$c63(s1); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseDecimalNumberLiteralExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 82 + 23, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 43) { - s2 = peg$c64; - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c65); } - } - if (s2 === peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 45) { - s2 = peg$c66; - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c67); } - } - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - s3 = peg$parseUnsignedDecimalNumberLiteralExpr(); - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseUnsignedDecimalNumberLiteralExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 82 + 24, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - s2 = peg$currPos; - s3 = []; - if (peg$c68.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c69); } - } - if (s4 !== peg$FAILED) { - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c68.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c69); } - } - } - } else { - s3 = peg$FAILED; - } - if (s3 !== peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 46) { - s5 = peg$c31; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c32); } - } - if (s5 !== peg$FAILED) { - s6 = []; - if (peg$c68.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c69); } - } - if (s7 !== peg$FAILED) { - while (s7 !== peg$FAILED) { - s6.push(s7); - if (peg$c68.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c69); } - } - } - } else { - s6 = peg$FAILED; - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = null; - } - if (s4 !== peg$FAILED) { - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - if (s2 === peg$FAILED) { - s2 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 46) { - s3 = peg$c31; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c32); } - } - if (s3 !== peg$FAILED) { - s4 = []; - if (peg$c68.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c69); } - } - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c68.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c69); } - } - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s3 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 101) { - s4 = peg$c70; - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c71); } - } - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 43) { - s5 = peg$c64; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c65); } - } - if (s5 === peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 45) { - s5 = peg$c66; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c67); } - } - } - if (s5 === peg$FAILED) { - s5 = null; - } - if (s5 !== peg$FAILED) { - s6 = []; - if (peg$c68.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c69); } - } - if (s7 !== peg$FAILED) { - while (s7 !== peg$FAILED) { - s6.push(s7); - if (peg$c68.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c69); } - } - } - } else { - s6 = peg$FAILED; - } - if (s6 !== peg$FAILED) { - s4 = [s4, s5, s6]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = null; - } - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseBinNumberLiteralExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 82 + 25, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 45) { - s2 = peg$c66; - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c67); } - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c72) { - s3 = peg$c72; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c73); } - } - if (s3 !== peg$FAILED) { - s4 = []; - if (peg$c74.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c75); } - } - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c74.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c75); } - } - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s2 = [s2, s3, s4]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseOctNumberLiteralExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 82 + 26, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 45) { - s2 = peg$c66; - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c67); } - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c76) { - s3 = peg$c76; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c77); } - } - if (s3 !== peg$FAILED) { - s4 = []; - if (peg$c78.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c79); } - } - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c78.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c79); } - } - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s2 = [s2, s3, s4]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseHexNumberLiteralExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 82 + 27, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 45) { - s2 = peg$c66; - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c67); } - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c80) { - s3 = peg$c80; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c81); } - } - if (s3 !== peg$FAILED) { - s4 = []; - if (peg$c82.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c83); } - } - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c82.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c83); } - } - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s2 = [s2, s3, s4]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseIntersectionTypeExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 82 + 28, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseIntersectionTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 38) { - s3 = peg$c84; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c85); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseIntersectionTypeExpr(); - if (s5 === peg$FAILED) { - s5 = peg$parseIntersectionTypeExprOperand(); - } - if (s5 !== peg$FAILED) { - s1 = peg$c86(s1, s5); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseIntersectionTypeExprOperand() { - var s0; - - var key = peg$currPos * 82 + 29, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseKeyQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseUnionTypeExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 82 + 30, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseUnionTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 124) { - s3 = peg$c87; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c88); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseUnionTypeExpr(); - if (s5 === peg$FAILED) { - s5 = peg$parseUnionTypeExprOperand(); - } - if (s5 !== peg$FAILED) { - s1 = peg$c89(s1, s5); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseUnionTypeExprOperand() { - var s0; - - var key = peg$currPos * 82 + 31, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseKeyQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseUnaryUnionTypeExpr() { - var s0; - - var key = peg$currPos * 82 + 32, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseSuffixUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parsePrefixUnaryUnionTypeExpr(); - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixUnaryUnionTypeExpr() { - var s0; - - var key = peg$currPos * 82 + 33, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parsePrefixOptionalTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parsePrefixNotNullableTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parsePrefixNullableTypeExpr(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixUnaryUnionTypeExprOperand() { - var s0; - - var key = peg$currPos * 82 + 34, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseTypeQueryExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 82 + 35, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c90) { - s1 = peg$c90; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c91); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseQualifiedMemberName(); - if (s3 !== peg$FAILED) { - s1 = peg$c92(s1, s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseKeyQueryExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 82 + 36, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 5) === peg$c93) { - s1 = peg$c93; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c94); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseKeyQueryExprOperand(); - if (s3 !== peg$FAILED) { - s1 = peg$c95(s1, s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.substr(peg$currPos, 5) === peg$c93) { - s1 = peg$c93; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c94); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseParenthesizedExpr(); - if (s2 !== peg$FAILED) { - s1 = peg$c95(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseKeyQueryExprOperand() { - var s0; - - var key = peg$currPos * 82 + 37, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseIntersectionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseKeyQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseImportTypeExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 82 + 38, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c96) { - s1 = peg$c96; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c97); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 40) { - s3 = peg$c98; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c99); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseStringLiteralExpr(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s7 = peg$c100; - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c101); } - } - if (s7 !== peg$FAILED) { - s1 = peg$c102(s1, s5); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixNullableTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 82 + 39, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 63) { - s1 = peg$c58; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c59); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); - if (s3 !== peg$FAILED) { - s1 = peg$c103(s1, s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixNotNullableTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 82 + 40, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 33) { - s1 = peg$c104; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c105); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); - if (s3 !== peg$FAILED) { - s1 = peg$c106(s1, s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixOptionalTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 82 + 41, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 61) { - s1 = peg$c107; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c108); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); - if (s3 !== peg$FAILED) { - s1 = peg$c109(s1, s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixUnaryUnionTypeExpr() { - var s0; - - var key = peg$currPos * 82 + 42, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseSuffixOptionalTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseSuffixNullableTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseSuffixNotNullableTypeExpr(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixUnaryUnionTypeExprOperand() { - var s0; - - var key = peg$currPos * 82 + 43, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parsePrefixUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixNullableTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 82 + 44, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 63) { - s3 = peg$c58; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c59); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c110(s1); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixNotNullableTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 82 + 45, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 33) { - s3 = peg$c104; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c105); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c111(s1); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixOptionalTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 82 + 46, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseSuffixNullableTypeExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseSuffixNotNullableTypeExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 61) { - s3 = peg$c107; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c108); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c112(s1); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 82 + 47, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseGenericTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseGenericTypeStartToken(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseGenericTypeExprTypeParamList(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseGenericTypeEndToken(); - if (s7 !== peg$FAILED) { - s1 = peg$c113(s1, s3, s5); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeExprOperand() { - var s0; - - var key = peg$currPos * 82 + 48, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeExprTypeParamOperand() { - var s0; - - var key = peg$currPos * 82 + 49, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseIntersectionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseKeyQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeExprTypeParamList() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 82 + 50, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseGenericTypeExprTypeParamOperand(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c114; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c115); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseGenericTypeExprTypeParamOperand(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c114; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c115); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseGenericTypeExprTypeParamOperand(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s1 = peg$c116(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeStartToken() { - var s0; - - var key = peg$currPos * 82 + 51, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseGenericTypeEcmaScriptFlavoredStartToken(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeTypeScriptFlavoredStartToken(); - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeEcmaScriptFlavoredStartToken() { - var s0, s1; - - var key = peg$currPos * 82 + 52, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c117) { - s1 = peg$c117; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c118); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c119(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeTypeScriptFlavoredStartToken() { - var s0, s1; - - var key = peg$currPos * 82 + 53, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 60) { - s1 = peg$c120; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c121); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c122(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeEndToken() { - var s0; - - var key = peg$currPos * 82 + 54, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - if (input.charCodeAt(peg$currPos) === 62) { - s0 = peg$c123; - peg$currPos++; - } else { - s0 = peg$FAILED; - { peg$fail(peg$c124); } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseArrayTypeExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 82 + 55, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseArrayTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 91) { - s5 = peg$c125; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c126); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 93) { - s7 = peg$c127; - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c128); } - } - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 !== peg$FAILED) { - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 91) { - s5 = peg$c125; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c126); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 93) { - s7 = peg$c127; - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c128); } - } - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - } else { - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - s1 = peg$c129(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseArrayTypeExprOperand() { - var s0; - - var key = peg$currPos * 82 + 56, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseKeyQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseArrowTypeExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 82 + 57, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c130) { - s1 = peg$c130; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c131); } - } - if (s1 === peg$FAILED) { - s1 = null; - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseArrowTypeExprParamsList(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c132) { - s5 = peg$c132; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c133); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseFunctionTypeExprReturnableOperand(); - if (s7 !== peg$FAILED) { - s1 = peg$c134(s1, s3, s7); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseArrowTypeExprParamsList() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 82 + 58, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c98; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c99); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s3 = peg$c100; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c101); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c135(); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c98; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c99); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseArrowTypeExprParams(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s5 = peg$c100; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c101); } - } - if (s5 !== peg$FAILED) { - s1 = peg$c136(s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseArrowTypeExprParams() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10; - - var key = peg$currPos * 82 + 59, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = []; - s2 = peg$currPos; - s3 = peg$parseJsIdentifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s5 = peg$c43; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseFunctionTypeExprParamOperand(); - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s9 = peg$c114; - peg$currPos++; - } else { - s9 = peg$FAILED; - { peg$fail(peg$c115); } - } - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - if (s10 !== peg$FAILED) { - s3 = [s3, s4, s5, s6, s7, s8, s9, s10]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = peg$currPos; - s3 = peg$parseJsIdentifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s5 = peg$c43; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseFunctionTypeExprParamOperand(); - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s9 = peg$c114; - peg$currPos++; - } else { - s9 = peg$FAILED; - { peg$fail(peg$c115); } - } - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - if (s10 !== peg$FAILED) { - s3 = [s3, s4, s5, s6, s7, s8, s9, s10]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseVariadicNameExpr(); - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - s1 = peg$c137(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseVariadicNameExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 82 + 60, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c138) { - s1 = peg$c138; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c139); } - } - if (s1 === peg$FAILED) { - s1 = null; - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseJsIdentifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s5 = peg$c43; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseFunctionTypeExprParamOperand(); - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s1 = peg$c140(s1, s3, s7); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8; - - var key = peg$currPos * 82 + 61, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c141) { - s1 = peg$c141; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c142); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseFunctionTypeExprParamsList(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 58) { - s6 = peg$c43; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s6 !== peg$FAILED) { - s7 = peg$parse_(); - if (s7 !== peg$FAILED) { - s8 = peg$parseFunctionTypeExprReturnableOperand(); - if (s8 !== peg$FAILED) { - s6 = [s6, s7, s8]; - s5 = s6; - } else { - peg$currPos = s5; - s5 = peg$FAILED; - } - } else { - peg$currPos = s5; - s5 = peg$FAILED; - } - } else { - peg$currPos = s5; - s5 = peg$FAILED; - } - if (s5 === peg$FAILED) { - s5 = null; - } - if (s5 !== peg$FAILED) { - s1 = peg$c143(s3, s5); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExprParamsList() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - - var key = peg$currPos * 82 + 62, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c98; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c99); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseFunctionTypeExprModifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c114; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c115); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseFunctionTypeExprParams(); - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s9 = peg$c100; - peg$currPos++; - } else { - s9 = peg$FAILED; - { peg$fail(peg$c101); } - } - if (s9 !== peg$FAILED) { - s1 = peg$c144(s3, s7); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c98; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c99); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseFunctionTypeExprModifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s5 = peg$c100; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c101); } - } - if (s5 !== peg$FAILED) { - s1 = peg$c145(s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c98; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c99); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s3 = peg$c100; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c101); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c146(); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c98; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c99); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseFunctionTypeExprParams(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s5 = peg$c100; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c101); } - } - if (s5 !== peg$FAILED) { - s1 = peg$c147(s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExprModifier() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 82 + 63, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c148) { - s2 = peg$c148; - peg$currPos += 4; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c149); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - if (s3 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s4 = peg$c43; - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - s6 = peg$parseFunctionTypeExprParamOperand(); - if (s6 !== peg$FAILED) { - s2 = [s2, s3, s4, s5, s6]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s1 = peg$c150(s1); - } - s0 = s1; - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c130) { - s2 = peg$c130; - peg$currPos += 3; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c131); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - if (s3 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s4 = peg$c43; - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - s6 = peg$parseFunctionTypeExprParamOperand(); - if (s6 !== peg$FAILED) { - s2 = [s2, s3, s4, s5, s6]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s1 = peg$c151(s1); - } - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExprParams() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 82 + 64, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = []; - s2 = peg$currPos; - s3 = peg$parseFunctionTypeExprParamOperand(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c114; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c115); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s3 = [s3, s4, s5, s6]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = peg$currPos; - s3 = peg$parseFunctionTypeExprParamOperand(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c114; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c115); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s3 = [s3, s4, s5, s6]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseVariadicTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseVariadicTypeExprOperand(); - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - s1 = peg$c152(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExprParamOperand() { - var s0; - - var key = peg$currPos * 82 + 65, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseIntersectionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseKeyQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExprReturnableOperand() { - var s0; - - var key = peg$currPos * 82 + 66, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parsePrefixUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseKeyQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseRecordTypeExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 82 + 67, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 123) { - s1 = peg$c153; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c154); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseRecordTypeExprEntries(); - if (s3 === peg$FAILED) { - s3 = null; - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 125) { - s5 = peg$c155; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c156); } - } - if (s5 !== peg$FAILED) { - s1 = peg$c157(s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseRecordTypeExprEntries() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 82 + 68, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseRecordTypeExprEntry(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$currPos; - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s6 = peg$c114; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c115); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 59) { - s6 = peg$c158; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c159); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - s5 = []; - if (peg$c1.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c2); } - } - while (s6 !== peg$FAILED) { - s5.push(s6); - if (peg$c1.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c2); } - } - } - if (s5 !== peg$FAILED) { - if (peg$c3.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c4); } - } - if (s6 === peg$FAILED) { - s6 = null; - } - if (s6 !== peg$FAILED) { - if (peg$c5.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c6); } - } - if (s7 !== peg$FAILED) { - s5 = [s5, s6, s7]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - s6 = peg$parseRecordTypeExprEntry(); - if (s6 !== peg$FAILED) { - s4 = [s4, s5, s6]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$currPos; - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s6 = peg$c114; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c115); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 59) { - s6 = peg$c158; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c159); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - s5 = []; - if (peg$c1.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c2); } - } - while (s6 !== peg$FAILED) { - s5.push(s6); - if (peg$c1.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c2); } - } - } - if (s5 !== peg$FAILED) { - if (peg$c3.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c4); } - } - if (s6 === peg$FAILED) { - s6 = null; - } - if (s6 !== peg$FAILED) { - if (peg$c5.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c6); } - } - if (s7 !== peg$FAILED) { - s5 = [s5, s6, s7]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - s6 = peg$parseRecordTypeExprEntry(); - if (s6 !== peg$FAILED) { - s4 = [s4, s5, s6]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c114; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c115); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 59) { - s5 = peg$c158; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c159); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = peg$currPos; - s4 = []; - if (peg$c1.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c2); } - } - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c1.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c2); } - } - } - if (s4 !== peg$FAILED) { - if (peg$c3.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c4); } - } - if (s5 === peg$FAILED) { - s5 = null; - } - if (s5 !== peg$FAILED) { - if (peg$c5.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c6); } - } - if (s6 !== peg$FAILED) { - s4 = [s4, s5, s6]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - } - if (s3 === peg$FAILED) { - s3 = null; - } - if (s3 !== peg$FAILED) { - s1 = peg$c160(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseRecordTypeExprEntry() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8; - - var key = peg$currPos * 82 + 69, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c161) { - s2 = peg$c161; - peg$currPos += 8; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c162); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse__(); - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 === peg$FAILED) { - s1 = null; - } - if (s1 !== peg$FAILED) { - s2 = peg$parseRecordTypeExprEntryKey(); - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - if (s3 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 63) { - s4 = peg$c58; - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c59); } - } - if (s4 === peg$FAILED) { - s4 = null; - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s6 = peg$c43; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s6 !== peg$FAILED) { - s7 = peg$parse_(); - if (s7 !== peg$FAILED) { - s8 = peg$parseRecordTypeExprEntryOperand(); - if (s8 !== peg$FAILED) { - s1 = peg$c163(s1, s2, s4, s8); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c161) { - s2 = peg$c161; - peg$currPos += 8; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c162); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse__(); - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 === peg$FAILED) { - s1 = null; - } - if (s1 !== peg$FAILED) { - s2 = peg$parseRecordTypeExprEntryKey(); - if (s2 !== peg$FAILED) { - s1 = peg$c164(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseRecordTypeExprEntryKey() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 82 + 70, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c25; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c25; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c165(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c17; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c17; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c166(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$currPos; - s2 = peg$parseJsIdentifier(); - if (s2 === peg$FAILED) { - s2 = peg$parseUnsignedDecimalNumberLiteralExpr(); - } - if (s2 !== peg$FAILED) { - s1 = input.substring(s1, peg$currPos); - } else { - s1 = s2; - } - if (s1 !== peg$FAILED) { - s1 = peg$c167(s1); - } - s0 = s1; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseRecordTypeExprEntryOperand() { - var s0; - - var key = peg$currPos * 82 + 71, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseIntersectionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseTupleTypeExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 82 + 72, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 91) { - s1 = peg$c125; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c126); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseTupleTypeExprEntries(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 93) { - s5 = peg$c127; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c128); } - } - if (s5 !== peg$FAILED) { - s1 = peg$c168(s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseTupleTypeExprEntries() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 82 + 73, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = []; - s2 = peg$currPos; - s3 = peg$parseTupleTypeExprOperand(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c114; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c115); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s3 = [s3, s4, s5, s6]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = peg$currPos; - s3 = peg$parseTupleTypeExprOperand(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c114; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c115); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s3 = [s3, s4, s5, s6]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseVariadicTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseVariadicTypeExprOperand(); - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - s1 = peg$c169(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseTupleTypeExprOperand() { - var s0; - - var key = peg$currPos * 82 + 74, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseIntersectionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseKeyQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseParenthesizedExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 82 + 75, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c98; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c99); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseParenthesizedExprOperand(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s5 = peg$c100; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c101); } - } - if (s5 !== peg$FAILED) { - s1 = peg$c170(s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseParenthesizedExprOperand() { - var s0; - - var key = peg$currPos * 82 + 76, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseIntersectionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseKeyQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseVariadicTypeExpr() { - var s0; - - var key = peg$currPos * 82 + 77, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parsePrefixVariadicTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseSuffixVariadicTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyVariadicTypeExpr(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixVariadicTypeExpr() { - var s0, s1, s2; - - var key = peg$currPos * 82 + 78, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c138) { - s1 = peg$c138; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c139); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseVariadicTypeExprOperand(); - if (s2 !== peg$FAILED) { - s1 = peg$c171(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixVariadicTypeExpr() { - var s0, s1, s2; - - var key = peg$currPos * 82 + 79, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseVariadicTypeExprOperand(); - if (s1 !== peg$FAILED) { - if (input.substr(peg$currPos, 3) === peg$c138) { - s2 = peg$c138; - peg$currPos += 3; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c139); } - } - if (s2 !== peg$FAILED) { - s1 = peg$c172(s1); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseAnyVariadicTypeExpr() { - var s0, s1; - - var key = peg$currPos * 82 + 80, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c138) { - s1 = peg$c138; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c139); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c173(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseVariadicTypeExprOperand() { - var s0; - - var key = peg$currPos * 82 + 81, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseIntersectionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseKeyQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - - const meta = SyntaxType; - const { - GenericTypeSyntax, - VariadicTypeSyntax, OptionalTypeSyntax, - NullableTypeSyntax, NotNullableTypeSyntax, - } = meta; - const NodeType = NodeType_1; - - const NamepathOperatorType = { - MEMBER: 'MEMBER', - INNER_MEMBER: 'INNER_MEMBER', - INSTANCE_MEMBER: 'INSTANCE_MEMBER', - }; - - - peg$result = peg$startRuleFunction(); - - if (peg$result !== peg$FAILED && peg$currPos === input.length) { - return peg$result; - } else { - if (peg$result !== peg$FAILED && peg$currPos < input.length) { - peg$fail(peg$endExpectation()); - } - - throw peg$buildStructuredError( - peg$maxFailExpected, - peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, - peg$maxFailPos < input.length - ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) - : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) - ); - } -} - -var jsdoctypePermissive = { - SyntaxError: peg$SyntaxError$3, - parse: peg$parse$3 -}; - -/* - * Generated by PEG.js 0.10.0. - * - * http://pegjs.org/ - */ - -function peg$subclass$2(child, parent) { - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor(); -} - -function peg$SyntaxError$2(message, expected, found, location) { - this.message = message; - this.expected = expected; - this.found = found; - this.location = location; - this.name = "SyntaxError"; - - if (typeof Error.captureStackTrace === "function") { - Error.captureStackTrace(this, peg$SyntaxError$2); - } -} - -peg$subclass$2(peg$SyntaxError$2, Error); - -peg$SyntaxError$2.buildMessage = function(expected, found) { - var DESCRIBE_EXPECTATION_FNS = { - literal: function(expectation) { - return "\"" + literalEscape(expectation.text) + "\""; - }, - - "class": function(expectation) { - var escapedParts = "", - i; - - for (i = 0; i < expectation.parts.length; i++) { - escapedParts += expectation.parts[i] instanceof Array - ? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1]) - : classEscape(expectation.parts[i]); - } - - return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]"; - }, - - any: function(expectation) { - return "any character"; - }, - - end: function(expectation) { - return "end of input"; - }, - - other: function(expectation) { - return expectation.description; - } - }; - - function hex(ch) { - return ch.charCodeAt(0).toString(16).toUpperCase(); - } - - function literalEscape(s) { - return s - .replace(/\\/g, '\\\\') - .replace(/"/g, '\\"') - .replace(/\0/g, '\\0') - .replace(/\t/g, '\\t') - .replace(/\n/g, '\\n') - .replace(/\r/g, '\\r') - .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) - .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); }); - } - - function classEscape(s) { - return s - .replace(/\\/g, '\\\\') - .replace(/\]/g, '\\]') - .replace(/\^/g, '\\^') - .replace(/-/g, '\\-') - .replace(/\0/g, '\\0') - .replace(/\t/g, '\\t') - .replace(/\n/g, '\\n') - .replace(/\r/g, '\\r') - .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) - .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); }); - } - - function describeExpectation(expectation) { - return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); - } - - function describeExpected(expected) { - var descriptions = new Array(expected.length), - i, j; - - for (i = 0; i < expected.length; i++) { - descriptions[i] = describeExpectation(expected[i]); - } - - descriptions.sort(); - - if (descriptions.length > 0) { - for (i = 1, j = 1; i < descriptions.length; i++) { - if (descriptions[i - 1] !== descriptions[i]) { - descriptions[j] = descriptions[i]; - j++; - } - } - descriptions.length = j; - } - - switch (descriptions.length) { - case 1: - return descriptions[0]; - - case 2: - return descriptions[0] + " or " + descriptions[1]; - - default: - return descriptions.slice(0, -1).join(", ") - + ", or " - + descriptions[descriptions.length - 1]; - } - } - - function describeFound(found) { - return found ? "\"" + literalEscape(found) + "\"" : "end of input"; - } - - return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; -}; - -function peg$parse$2(input, options) { - options = options !== void 0 ? options : {}; - - var peg$FAILED = {}, - - peg$startRuleFunctions = { TopTypeExpr: peg$parseTopTypeExpr, NamepathExpr: peg$parseNamepathExpr, BroadNamepathExpr: peg$parseBroadNamepathExpr, ExternalNameExpr: peg$parseExternalNameExpr, ModuleNameExpr: peg$parseModuleNameExpr }, - peg$startRuleFunction = peg$parseTopTypeExpr, - - peg$c0 = function(expr) { - return expr; - }, - peg$c1 = /^[ \t]/, - peg$c2 = peg$classExpectation([" ", "\t"], false, false), - peg$c3 = /^[\r]/, - peg$c4 = peg$classExpectation(["\r"], false, false), - peg$c5 = /^[\n]/, - peg$c6 = peg$classExpectation(["\n"], false, false), - peg$c7 = /^[a-zA-Z_$]/, - peg$c8 = peg$classExpectation([["a", "z"], ["A", "Z"], "_", "$"], false, false), - peg$c9 = /^[a-zA-Z0-9_$]/, - peg$c10 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$"], false, false), - peg$c11 = "event:", - peg$c12 = peg$literalExpectation("event:", false), - peg$c13 = function(rootOwner, memberPartWithOperators) { - return memberPartWithOperators.reduce(function(owner, tokens) { - const operatorType = tokens[1]; - const eventNamespace = tokens[3]; - const MemberName = tokens[5]; - const {quoteStyle, name: memberName} = MemberName; - - switch (operatorType) { - case NamepathOperatorType.MEMBER: - return { - type: NodeType.MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - case NamepathOperatorType.INSTANCE_MEMBER: - return { - type: NodeType.INSTANCE_MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - case NamepathOperatorType.INNER_MEMBER: - return { - type: NodeType.INNER_MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - /* istanbul ignore next */ - default: - throw new Error('Unexpected operator type: "' + operatorType + '"'); - } - }, rootOwner); - }, - peg$c14 = /^[a-zA-Z0-9_$\-]/, - peg$c15 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$", "-"], false, false), - peg$c16 = function(name) { - return { - type: NodeType.NAME, - name - }; - }, - peg$c17 = "'", - peg$c18 = peg$literalExpectation("'", false), - peg$c19 = /^[^\\']/, - peg$c20 = peg$classExpectation(["\\", "'"], true, false), - peg$c21 = "\\", - peg$c22 = peg$literalExpectation("\\", false), - peg$c23 = peg$anyExpectation(), - peg$c24 = function(name) { - return { - quoteStyle: 'single', - name: name.replace(/\\'/g, "'") - .replace(/\\\\/gu, '\\') - }; - }, - peg$c25 = "\"", - peg$c26 = peg$literalExpectation("\"", false), - peg$c27 = /^[^\\"]/, - peg$c28 = peg$classExpectation(["\\", "\""], true, false), - peg$c29 = function(name) { - return { - quoteStyle: 'double', - name: name.replace(/\\"/gu, '"') - .replace(/\\\\/gu, '\\') - }; - }, - peg$c30 = function(name) { - return { - quoteStyle: 'none', - name - }; - }, - peg$c31 = ".", - peg$c32 = peg$literalExpectation(".", false), - peg$c34 = function() { - return NamepathOperatorType.MEMBER; - }, - peg$c35 = "~", - peg$c36 = peg$literalExpectation("~", false), - peg$c37 = function() { - return NamepathOperatorType.INNER_MEMBER; - }, - peg$c38 = "#", - peg$c39 = peg$literalExpectation("#", false), - peg$c40 = function() { - return NamepathOperatorType.INSTANCE_MEMBER; - }, - peg$c41 = "external", - peg$c42 = peg$literalExpectation("external", false), - peg$c43 = ":", - peg$c44 = peg$literalExpectation(":", false), - peg$c45 = function(external, memberPartWithOperators) { - return memberPartWithOperators.reduce(function(owner, tokens) { - const operatorType = tokens[1]; - const eventNamespace = tokens[3]; - const MemberName = tokens[5]; - const {quoteStyle, name: memberName} = MemberName; - - switch (operatorType) { - case NamepathOperatorType.MEMBER: - return { - type: NodeType.MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - case NamepathOperatorType.INSTANCE_MEMBER: - return { - type: NodeType.INSTANCE_MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - case NamepathOperatorType.INNER_MEMBER: - return { - type: NodeType.INNER_MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - /* istanbul ignore next */ - default: - throw new Error('Unexpected operator type: "' + operatorType + '"'); - } - }, Object.assign({ - type: NodeType.EXTERNAL - }, external)); - }, - peg$c46 = "module", - peg$c47 = peg$literalExpectation("module", false), - peg$c48 = function(value) { - return { - type: NodeType.MODULE, - value, - }; - }, - peg$c49 = function(rootOwner, memberPartWithOperators) { - return memberPartWithOperators.reduce(function(owner, tokens) { - const operatorType = tokens[1]; - const eventNamespace = tokens[3]; - const MemberName = tokens[5]; - const {quoteStyle, name: memberName} = MemberName; - - switch (operatorType) { - case NamepathOperatorType.MEMBER: - return { - type: NodeType.MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - case NamepathOperatorType.INSTANCE_MEMBER: - return { - type: NodeType.INSTANCE_MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - case NamepathOperatorType.INNER_MEMBER: - return { - type: NodeType.INNER_MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - /* istanbul ignore next */ - default: - throw new Error('Unexpected operator type: "' + operatorType + '"'); - } - }, rootOwner); - }, - peg$c50 = function(path) { - return { - quoteStyle: 'single', - type: NodeType.FILE_PATH, - path: path.replace(/\\'/g, "'") - .replace(/\\\\/gu, '\\') - }; - }, - peg$c51 = function(path) { - return { - quoteStyle: 'double', - type: NodeType.FILE_PATH, - path: path.replace(/\\"/gu, '"') - .replace(/\\\\/gu, '\\') - }; - }, - peg$c52 = /^[a-zA-Z0-9_$\/\-]/, - peg$c53 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$", "/", "-"], false, false), - peg$c54 = function(path) { - return { - quoteStyle: 'none', - type: NodeType.FILE_PATH, - path, - }; - }, - peg$c55 = "*", - peg$c56 = peg$literalExpectation("*", false), - peg$c57 = function() { - return { type: NodeType.ANY }; - }, - peg$c58 = "?", - peg$c59 = peg$literalExpectation("?", false), - peg$c60 = function() { - return { type: NodeType.UNKNOWN }; - }, - peg$c61 = function(value) { - return { - type: NodeType.STRING_VALUE, - quoteStyle: 'double', - string: value.replace(/\\"/gu, '"') - .replace(/\\\\/gu, '\\') - }; - }, - peg$c62 = function(value) { - return { - type: NodeType.STRING_VALUE, - quoteStyle: 'single', - string: value.replace(/\\'/g, "'") - .replace(/\\\\/gu, '\\') - }; - }, - peg$c63 = function(value) { - return { - type: NodeType.NUMBER_VALUE, - number: value - }; - }, - peg$c64 = "+", - peg$c65 = peg$literalExpectation("+", false), - peg$c66 = "-", - peg$c67 = peg$literalExpectation("-", false), - peg$c68 = /^[0-9]/, - peg$c69 = peg$classExpectation([["0", "9"]], false, false), - peg$c70 = "e", - peg$c71 = peg$literalExpectation("e", false), - peg$c72 = "0b", - peg$c73 = peg$literalExpectation("0b", false), - peg$c74 = /^[01]/, - peg$c75 = peg$classExpectation(["0", "1"], false, false), - peg$c76 = "0o", - peg$c77 = peg$literalExpectation("0o", false), - peg$c78 = /^[0-7]/, - peg$c79 = peg$classExpectation([["0", "7"]], false, false), - peg$c80 = "0x", - peg$c81 = peg$literalExpectation("0x", false), - peg$c82 = /^[0-9a-fA-F]/, - peg$c83 = peg$classExpectation([["0", "9"], ["a", "f"], ["A", "F"]], false, false), - peg$c84 = "|", - peg$c85 = peg$literalExpectation("|", false), - peg$c86 = function(left, right) { - return { - type: NodeType.UNION, - left, - right, - }; - }, - peg$c87 = function(operator, operand) { - return { - type: NodeType.NULLABLE, - value: operand, - meta: { syntax: NullableTypeSyntax.PREFIX_QUESTION_MARK }, - }; - }, - peg$c88 = "!", - peg$c89 = peg$literalExpectation("!", false), - peg$c90 = function(operator, operand) { - return { - type: NodeType.NOT_NULLABLE, - value: operand, - meta: { syntax: NotNullableTypeSyntax.PREFIX_BANG }, - }; - }, - peg$c91 = "=", - peg$c92 = peg$literalExpectation("=", false), - peg$c93 = function(operator, operand) { - return { - type: NodeType.OPTIONAL, - value: operand, - meta: { syntax: OptionalTypeSyntax.PREFIX_EQUALS_SIGN }, - }; - }, - peg$c94 = function(operand, operator) { - return { - type: NodeType.NULLABLE, - value: operand, - meta: { syntax: NullableTypeSyntax.SUFFIX_QUESTION_MARK }, - }; - }, - peg$c95 = function(operand, operator) { - return { - type: NodeType.NOT_NULLABLE, - value: operand, - meta: { syntax: NotNullableTypeSyntax.SUFFIX_BANG }, - }; - }, - peg$c96 = function(operand, operator) { - return { - type: NodeType.OPTIONAL, - value: operand, - meta: { syntax: OptionalTypeSyntax.SUFFIX_EQUALS_SIGN }, - }; - }, - peg$c97 = function(operand, syntax, params) { - return { - type: NodeType.GENERIC, - subject: operand, - objects: params, - meta: { syntax }, - }; - }, - peg$c98 = ",", - peg$c99 = peg$literalExpectation(",", false), - peg$c100 = function(first, restsWithComma) { - return restsWithComma.reduce(function(params, tokens) { - return params.concat([tokens[3]]); - }, [first]); - }, - peg$c101 = ".<", - peg$c102 = peg$literalExpectation(".<", false), - peg$c103 = function() { - return GenericTypeSyntax.ANGLE_BRACKET_WITH_DOT; - }, - peg$c104 = "<", - peg$c105 = peg$literalExpectation("<", false), - peg$c106 = function() { - return GenericTypeSyntax.ANGLE_BRACKET; - }, - peg$c107 = ">", - peg$c108 = peg$literalExpectation(">", false), - peg$c109 = "[", - peg$c110 = peg$literalExpectation("[", false), - peg$c111 = "]", - peg$c112 = peg$literalExpectation("]", false), - peg$c113 = function(operand, brackets) { - return brackets.reduce(function(operand) { - return { - type: NodeType.GENERIC, - subject: { - type: NodeType.NAME, - name: 'Array' - }, - objects: [ operand ], - meta: { syntax: GenericTypeSyntax.SQUARE_BRACKET }, - }; - }, operand); - }, - peg$c114 = "function", - peg$c115 = peg$literalExpectation("function", false), - peg$c116 = function(paramsPart, returnedTypePart) { - const returnedTypeNode = returnedTypePart ? returnedTypePart[2] : null; - - return { - type: NodeType.FUNCTION, - params: paramsPart.params, - returns: returnedTypeNode, - this: paramsPart.modifier.nodeThis, - new: paramsPart.modifier.nodeNew, - }; - }, - peg$c117 = "(", - peg$c118 = peg$literalExpectation("(", false), - peg$c119 = ")", - peg$c120 = peg$literalExpectation(")", false), - peg$c121 = function(modifier, params) { - return { params, modifier }; - }, - peg$c122 = function(modifier) { - return { params: [], modifier }; - }, - peg$c123 = function() { - return { params: [], modifier: { nodeThis: null, nodeNew: null } }; - }, - peg$c124 = function(params) { - return { params, modifier: { nodeThis: null, nodeNew: null } }; - }, - peg$c125 = "this", - peg$c126 = peg$literalExpectation("this", false), - peg$c127 = function(modifierThis) { - return { nodeThis: modifierThis[4], nodeNew: null }; - }, - peg$c128 = "new", - peg$c129 = peg$literalExpectation("new", false), - peg$c130 = function(modifierNew) { - return { nodeThis: null, nodeNew: modifierNew[4] }; - }, - peg$c131 = function(paramsWithComma, lastParam) { - return paramsWithComma.reduceRight(function(params, tokens) { - const [param] = tokens; - return [param].concat(params); - }, lastParam ? [lastParam] : []); - }, - peg$c132 = "{", - peg$c133 = peg$literalExpectation("{", false), - peg$c134 = "}", - peg$c135 = peg$literalExpectation("}", false), - peg$c136 = function(entries) { - return { - type: NodeType.RECORD, - entries: entries || [], - }; - }, - peg$c137 = ";", - peg$c138 = peg$literalExpectation(";", false), - peg$c139 = function(first, restWithComma) { - return restWithComma.reduce(function(entries, tokens) { - const entry = tokens[2]; - return entries.concat([entry]); - }, [first]); - }, - peg$c140 = "readonly", - peg$c141 = peg$literalExpectation("readonly", false), - peg$c142 = function(readonly, keyInfo, optional, value) { - const {quoteStyle, key} = keyInfo; - return { - type: NodeType.RECORD_ENTRY, - key, - quoteStyle, - value: - optional === '?' ? { - type: NodeType.OPTIONAL, - value, - meta: { syntax: OptionalTypeSyntax.SUFFIX_KEY_QUESTION_MARK }, - } : - value, - readonly: Boolean(readonly) - }; - }, - peg$c143 = function(readonly, keyInfo) { - const {quoteStyle, key} = keyInfo; - return { - type: NodeType.RECORD_ENTRY, - key, - quoteStyle, - value: null, - readonly: Boolean(readonly) - }; - }, - peg$c144 = function(key) { - return { - quoteStyle: 'double', - key: key.replace(/\\"/gu, '"') - .replace(/\\\\/gu, '\\') - }; - }, - peg$c145 = function(key) { - return { - quoteStyle: 'single', - key: key.replace(/\\'/g, "'") - .replace(/\\\\/gu, '\\') - }; - }, - peg$c146 = function(key) { - return { - quoteStyle: 'none', - key - }; - }, - peg$c147 = function(wrapped) { - return { - type: NodeType.PARENTHESIS, - value: wrapped, - }; - }, - peg$c148 = "...", - peg$c149 = peg$literalExpectation("...", false), - peg$c150 = function(operand) { - return { - type: NodeType.VARIADIC, - value: operand, - meta: { syntax: VariadicTypeSyntax.PREFIX_DOTS }, - }; - }, - peg$c151 = function(operand) { - return { - type: NodeType.VARIADIC, - value: operand, - meta: { syntax: VariadicTypeSyntax.SUFFIX_DOTS }, - }; - }, - peg$c152 = function() { - return { - type: NodeType.VARIADIC, - value: { type: NodeType.ANY }, - meta: { syntax: VariadicTypeSyntax.ONLY_DOTS }, - }; - }, - - peg$currPos = 0, - peg$posDetailsCache = [{ line: 1, column: 1 }], - peg$maxFailPos = 0, - peg$maxFailExpected = [], - peg$resultsCache = {}, - - peg$result; - - if ("startRule" in options) { - if (!(options.startRule in peg$startRuleFunctions)) { - throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); - } - - peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; - } - - function peg$literalExpectation(text, ignoreCase) { - return { type: "literal", text: text, ignoreCase: ignoreCase }; - } - - function peg$classExpectation(parts, inverted, ignoreCase) { - return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase }; - } - - function peg$anyExpectation() { - return { type: "any" }; - } - - function peg$endExpectation() { - return { type: "end" }; - } - - function peg$computePosDetails(pos) { - var details = peg$posDetailsCache[pos], p; - - if (details) { - return details; - } else { - p = pos - 1; - while (!peg$posDetailsCache[p]) { - p--; - } - - details = peg$posDetailsCache[p]; - details = { - line: details.line, - column: details.column - }; - - while (p < pos) { - if (input.charCodeAt(p) === 10) { - details.line++; - details.column = 1; - } else { - details.column++; - } - - p++; - } - - peg$posDetailsCache[pos] = details; - return details; - } - } - - function peg$computeLocation(startPos, endPos) { - var startPosDetails = peg$computePosDetails(startPos), - endPosDetails = peg$computePosDetails(endPos); - - return { - start: { - offset: startPos, - line: startPosDetails.line, - column: startPosDetails.column - }, - end: { - offset: endPos, - line: endPosDetails.line, - column: endPosDetails.column - } - }; - } - - function peg$fail(expected) { - if (peg$currPos < peg$maxFailPos) { return; } - - if (peg$currPos > peg$maxFailPos) { - peg$maxFailPos = peg$currPos; - peg$maxFailExpected = []; - } - - peg$maxFailExpected.push(expected); - } - - function peg$buildStructuredError(expected, found, location) { - return new peg$SyntaxError$2( - peg$SyntaxError$2.buildMessage(expected, found), - expected, - found, - location - ); - } - - function peg$parseTopTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 69 + 0, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parse_(); - if (s1 !== peg$FAILED) { - s2 = peg$parseVariadicTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseUnionTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseUnaryUnionTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseArrayTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseGenericTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseRecordTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseFunctionTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseBroadNamepathExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseParenthesizedExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseValueExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseAnyTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - if (s3 !== peg$FAILED) { - s1 = peg$c0(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseWS() { - var s0, s1, s2; - - var key = peg$currPos * 69 + 1, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - if (peg$c1.test(input.charAt(peg$currPos))) { - s0 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s0 = peg$FAILED; - { peg$fail(peg$c2); } - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (peg$c3.test(input.charAt(peg$currPos))) { - s1 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c4); } - } - if (s1 === peg$FAILED) { - s1 = null; - } - if (s1 !== peg$FAILED) { - if (peg$c5.test(input.charAt(peg$currPos))) { - s2 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c6); } - } - if (s2 !== peg$FAILED) { - s1 = [s1, s2]; - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parse_() { - var s0, s1; - - var key = peg$currPos * 69 + 2, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = []; - s1 = peg$parseWS(); - while (s1 !== peg$FAILED) { - s0.push(s1); - s1 = peg$parseWS(); - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parse__() { - var s0, s1; - - var key = peg$currPos * 69 + 3, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = []; - s1 = peg$parseWS(); - if (s1 !== peg$FAILED) { - while (s1 !== peg$FAILED) { - s0.push(s1); - s1 = peg$parseWS(); - } - } else { - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseJsIdentifier() { - var s0, s1, s2, s3, s4; - - var key = peg$currPos * 69 + 4, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (peg$c7.test(input.charAt(peg$currPos))) { - s2 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c8); } - } - if (s2 !== peg$FAILED) { - s3 = []; - if (peg$c9.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c10); } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c9.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c10); } - } - } - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseNamepathExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - - var key = peg$currPos * 69 + 5, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseParenthesizedExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseTypeNameExprJsDocFlavored(); - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseInfixNamepathOperator(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c11) { - s7 = peg$c11; - peg$currPos += 6; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c12); } - } - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - s9 = peg$parseMemberName(); - if (s9 !== peg$FAILED) { - s4 = [s4, s5, s6, s7, s8, s9]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseInfixNamepathOperator(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c11) { - s7 = peg$c11; - peg$currPos += 6; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c12); } - } - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - s9 = peg$parseMemberName(); - if (s9 !== peg$FAILED) { - s4 = [s4, s5, s6, s7, s8, s9]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s1 = peg$c13(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseTypeNameExprJsDocFlavored() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 69 + 6, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - s2 = peg$currPos; - if (peg$c7.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c8); } - } - if (s3 !== peg$FAILED) { - s4 = []; - if (peg$c14.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c15); } - } - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c14.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c15); } - } - } - if (s4 !== peg$FAILED) { - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - s1 = input.substring(s1, peg$currPos); - } else { - s1 = s2; - } - if (s1 !== peg$FAILED) { - s1 = peg$c16(s1); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseMemberName() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 69 + 7, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c17; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c17; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c24(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c25; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c25; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c29(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$parseJsIdentifier(); - if (s1 !== peg$FAILED) { - s1 = peg$c30(s1); - } - s0 = s1; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseInfixNamepathOperator() { - var s0; - - var key = peg$currPos * 69 + 8, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseMemberTypeOperator(); - if (s0 === peg$FAILED) { - s0 = peg$parseInstanceMemberTypeOperator(); - if (s0 === peg$FAILED) { - s0 = peg$parseInnerMemberTypeOperator(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseMemberTypeOperator() { - var s0, s1; - - var key = peg$currPos * 69 + 10, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 46) { - s1 = peg$c31; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c32); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c34(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseInnerMemberTypeOperator() { - var s0, s1; - - var key = peg$currPos * 69 + 11, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 126) { - s1 = peg$c35; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c36); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c37(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseInstanceMemberTypeOperator() { - var s0, s1; - - var key = peg$currPos * 69 + 12, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 35) { - s1 = peg$c38; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c39); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c40(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseBroadNamepathExpr() { - var s0; - - var key = peg$currPos * 69 + 13, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseExternalNameExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseModuleNameExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNamepathExpr(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseExternalNameExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13; - - var key = peg$currPos * 69 + 14, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c41) { - s1 = peg$c41; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c42); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s3 = peg$c43; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseMemberName(); - if (s5 !== peg$FAILED) { - s6 = []; - s7 = peg$currPos; - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - s9 = peg$parseInfixNamepathOperator(); - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - if (s10 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c11) { - s11 = peg$c11; - peg$currPos += 6; - } else { - s11 = peg$FAILED; - { peg$fail(peg$c12); } - } - if (s11 === peg$FAILED) { - s11 = null; - } - if (s11 !== peg$FAILED) { - s12 = peg$parse_(); - if (s12 !== peg$FAILED) { - s13 = peg$parseMemberName(); - if (s13 !== peg$FAILED) { - s8 = [s8, s9, s10, s11, s12, s13]; - s7 = s8; - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - while (s7 !== peg$FAILED) { - s6.push(s7); - s7 = peg$currPos; - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - s9 = peg$parseInfixNamepathOperator(); - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - if (s10 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c11) { - s11 = peg$c11; - peg$currPos += 6; - } else { - s11 = peg$FAILED; - { peg$fail(peg$c12); } - } - if (s11 === peg$FAILED) { - s11 = null; - } - if (s11 !== peg$FAILED) { - s12 = peg$parse_(); - if (s12 !== peg$FAILED) { - s13 = peg$parseMemberName(); - if (s13 !== peg$FAILED) { - s8 = [s8, s9, s10, s11, s12, s13]; - s7 = s8; - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } - if (s6 !== peg$FAILED) { - s1 = peg$c45(s5, s6); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseModuleNameExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 69 + 15, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c46) { - s1 = peg$c46; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c47); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s3 = peg$c43; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseModulePathExpr(); - if (s5 !== peg$FAILED) { - s1 = peg$c48(s5); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseModulePathExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - - var key = peg$currPos * 69 + 16, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseFilePathExpr(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseInfixNamepathOperator(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c11) { - s7 = peg$c11; - peg$currPos += 6; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c12); } - } - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - s9 = peg$parseMemberName(); - if (s9 !== peg$FAILED) { - s4 = [s4, s5, s6, s7, s8, s9]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseInfixNamepathOperator(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c11) { - s7 = peg$c11; - peg$currPos += 6; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c12); } - } - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - s9 = peg$parseMemberName(); - if (s9 !== peg$FAILED) { - s4 = [s4, s5, s6, s7, s8, s9]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s1 = peg$c49(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFilePathExpr() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 69 + 17, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c17; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c17; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c50(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c25; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c25; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c51(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$currPos; - s2 = []; - if (peg$c52.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c53); } - } - if (s3 !== peg$FAILED) { - while (s3 !== peg$FAILED) { - s2.push(s3); - if (peg$c52.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c53); } - } - } - } else { - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - s1 = input.substring(s1, peg$currPos); - } else { - s1 = s2; - } - if (s1 !== peg$FAILED) { - s1 = peg$c54(s1); - } - s0 = s1; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseAnyTypeExpr() { - var s0, s1; - - var key = peg$currPos * 69 + 18, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 42) { - s1 = peg$c55; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c56); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c57(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseUnknownTypeExpr() { - var s0, s1; - - var key = peg$currPos * 69 + 19, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 63) { - s1 = peg$c58; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c59); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c60(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseValueExpr() { - var s0; - - var key = peg$currPos * 69 + 20, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseStringLiteralExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNumberLiteralExpr(); - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseStringLiteralExpr() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 69 + 21, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c25; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c25; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c61(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c17; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c17; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c62(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseNumberLiteralExpr() { - var s0, s1; - - var key = peg$currPos * 69 + 22, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseBinNumberLiteralExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseOctNumberLiteralExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseHexNumberLiteralExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseDecimalNumberLiteralExpr(); - } - } - } - if (s1 !== peg$FAILED) { - s1 = peg$c63(s1); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseDecimalNumberLiteralExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 69 + 23, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 43) { - s2 = peg$c64; - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c65); } - } - if (s2 === peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 45) { - s2 = peg$c66; - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c67); } - } - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - s3 = peg$parseUnsignedDecimalNumberLiteralExpr(); - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseUnsignedDecimalNumberLiteralExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 69 + 24, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - s2 = peg$currPos; - s3 = []; - if (peg$c68.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c69); } - } - if (s4 !== peg$FAILED) { - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c68.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c69); } - } - } - } else { - s3 = peg$FAILED; - } - if (s3 !== peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 46) { - s5 = peg$c31; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c32); } - } - if (s5 !== peg$FAILED) { - s6 = []; - if (peg$c68.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c69); } - } - if (s7 !== peg$FAILED) { - while (s7 !== peg$FAILED) { - s6.push(s7); - if (peg$c68.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c69); } - } - } - } else { - s6 = peg$FAILED; - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = null; - } - if (s4 !== peg$FAILED) { - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - if (s2 === peg$FAILED) { - s2 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 46) { - s3 = peg$c31; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c32); } - } - if (s3 !== peg$FAILED) { - s4 = []; - if (peg$c68.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c69); } - } - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c68.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c69); } - } - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s3 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 101) { - s4 = peg$c70; - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c71); } - } - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 43) { - s5 = peg$c64; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c65); } - } - if (s5 === peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 45) { - s5 = peg$c66; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c67); } - } - } - if (s5 === peg$FAILED) { - s5 = null; - } - if (s5 !== peg$FAILED) { - s6 = []; - if (peg$c68.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c69); } - } - if (s7 !== peg$FAILED) { - while (s7 !== peg$FAILED) { - s6.push(s7); - if (peg$c68.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c69); } - } - } - } else { - s6 = peg$FAILED; - } - if (s6 !== peg$FAILED) { - s4 = [s4, s5, s6]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = null; - } - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseBinNumberLiteralExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 69 + 25, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 45) { - s2 = peg$c66; - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c67); } - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c72) { - s3 = peg$c72; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c73); } - } - if (s3 !== peg$FAILED) { - s4 = []; - if (peg$c74.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c75); } - } - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c74.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c75); } - } - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s2 = [s2, s3, s4]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseOctNumberLiteralExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 69 + 26, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 45) { - s2 = peg$c66; - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c67); } - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c76) { - s3 = peg$c76; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c77); } - } - if (s3 !== peg$FAILED) { - s4 = []; - if (peg$c78.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c79); } - } - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c78.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c79); } - } - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s2 = [s2, s3, s4]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseHexNumberLiteralExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 69 + 27, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 45) { - s2 = peg$c66; - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c67); } - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c80) { - s3 = peg$c80; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c81); } - } - if (s3 !== peg$FAILED) { - s4 = []; - if (peg$c82.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c83); } - } - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c82.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c83); } - } - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s2 = [s2, s3, s4]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseUnionTypeExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 69 + 28, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseUnionTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 124) { - s3 = peg$c84; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c85); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseUnionTypeExpr(); - if (s5 === peg$FAILED) { - s5 = peg$parseUnionTypeExprOperand(); - } - if (s5 !== peg$FAILED) { - s1 = peg$c86(s1, s5); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseUnionTypeExprOperand() { - var s0; - - var key = peg$currPos * 69 + 29, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseUnaryUnionTypeExpr() { - var s0; - - var key = peg$currPos * 69 + 30, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseSuffixUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parsePrefixUnaryUnionTypeExpr(); - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixUnaryUnionTypeExpr() { - var s0; - - var key = peg$currPos * 69 + 31, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parsePrefixOptionalTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parsePrefixNotNullableTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parsePrefixNullableTypeExpr(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixUnaryUnionTypeExprOperand() { - var s0; - - var key = peg$currPos * 69 + 32, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixNullableTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 69 + 33, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 63) { - s1 = peg$c58; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c59); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); - if (s3 !== peg$FAILED) { - s1 = peg$c87(s1, s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixNotNullableTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 69 + 34, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 33) { - s1 = peg$c88; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c89); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); - if (s3 !== peg$FAILED) { - s1 = peg$c90(s1, s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixOptionalTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 69 + 35, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 61) { - s1 = peg$c91; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c92); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); - if (s3 !== peg$FAILED) { - s1 = peg$c93(s1, s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixUnaryUnionTypeExpr() { - var s0; - - var key = peg$currPos * 69 + 36, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseSuffixOptionalTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseSuffixNullableTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseSuffixNotNullableTypeExpr(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixUnaryUnionTypeExprOperand() { - var s0; - - var key = peg$currPos * 69 + 37, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parsePrefixUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixNullableTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 69 + 38, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 63) { - s3 = peg$c58; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c59); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c94(s1); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixNotNullableTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 69 + 39, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 33) { - s3 = peg$c88; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c89); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c95(s1); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixOptionalTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 69 + 40, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseSuffixNullableTypeExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseSuffixNotNullableTypeExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 61) { - s3 = peg$c91; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c92); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c96(s1); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 69 + 41, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseGenericTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseGenericTypeStartToken(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseGenericTypeExprTypeParamList(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseGenericTypeEndToken(); - if (s7 !== peg$FAILED) { - s1 = peg$c97(s1, s3, s5); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeExprOperand() { - var s0; - - var key = peg$currPos * 69 + 42, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeExprTypeParamOperand() { - var s0; - - var key = peg$currPos * 69 + 43, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeExprTypeParamList() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 69 + 44, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseGenericTypeExprTypeParamOperand(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c98; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c99); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseGenericTypeExprTypeParamOperand(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c98; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c99); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseGenericTypeExprTypeParamOperand(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s1 = peg$c100(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeStartToken() { - var s0; - - var key = peg$currPos * 69 + 45, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseGenericTypeEcmaScriptFlavoredStartToken(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeTypeScriptFlavoredStartToken(); - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeEcmaScriptFlavoredStartToken() { - var s0, s1; - - var key = peg$currPos * 69 + 46, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c101) { - s1 = peg$c101; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c102); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c103(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeTypeScriptFlavoredStartToken() { - var s0, s1; - - var key = peg$currPos * 69 + 47, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 60) { - s1 = peg$c104; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c105); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c106(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeEndToken() { - var s0; - - var key = peg$currPos * 69 + 48, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - if (input.charCodeAt(peg$currPos) === 62) { - s0 = peg$c107; - peg$currPos++; - } else { - s0 = peg$FAILED; - { peg$fail(peg$c108); } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseArrayTypeExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 69 + 49, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseArrayTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 91) { - s5 = peg$c109; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c110); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 93) { - s7 = peg$c111; - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c112); } - } - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 !== peg$FAILED) { - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 91) { - s5 = peg$c109; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c110); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 93) { - s7 = peg$c111; - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c112); } - } - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - } else { - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - s1 = peg$c113(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseArrayTypeExprOperand() { - var s0; - - var key = peg$currPos * 69 + 50, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8; - - var key = peg$currPos * 69 + 51, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c114) { - s1 = peg$c114; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c115); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseFunctionTypeExprParamsList(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 58) { - s6 = peg$c43; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s6 !== peg$FAILED) { - s7 = peg$parse_(); - if (s7 !== peg$FAILED) { - s8 = peg$parseFunctionTypeExprReturnableOperand(); - if (s8 !== peg$FAILED) { - s6 = [s6, s7, s8]; - s5 = s6; - } else { - peg$currPos = s5; - s5 = peg$FAILED; - } - } else { - peg$currPos = s5; - s5 = peg$FAILED; - } - } else { - peg$currPos = s5; - s5 = peg$FAILED; - } - if (s5 === peg$FAILED) { - s5 = null; - } - if (s5 !== peg$FAILED) { - s1 = peg$c116(s3, s5); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExprParamsList() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - - var key = peg$currPos * 69 + 52, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c117; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c118); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseFunctionTypeExprModifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c98; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c99); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseFunctionTypeExprParams(); - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s9 = peg$c119; - peg$currPos++; - } else { - s9 = peg$FAILED; - { peg$fail(peg$c120); } - } - if (s9 !== peg$FAILED) { - s1 = peg$c121(s3, s7); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c117; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c118); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseFunctionTypeExprModifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s5 = peg$c119; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c120); } - } - if (s5 !== peg$FAILED) { - s1 = peg$c122(s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c117; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c118); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s3 = peg$c119; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c120); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c123(); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c117; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c118); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseFunctionTypeExprParams(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s5 = peg$c119; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c120); } - } - if (s5 !== peg$FAILED) { - s1 = peg$c124(s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExprModifier() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 69 + 53, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c125) { - s2 = peg$c125; - peg$currPos += 4; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c126); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - if (s3 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s4 = peg$c43; - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - s6 = peg$parseFunctionTypeExprParamOperand(); - if (s6 !== peg$FAILED) { - s2 = [s2, s3, s4, s5, s6]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s1 = peg$c127(s1); - } - s0 = s1; - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c128) { - s2 = peg$c128; - peg$currPos += 3; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c129); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - if (s3 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s4 = peg$c43; - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - s6 = peg$parseFunctionTypeExprParamOperand(); - if (s6 !== peg$FAILED) { - s2 = [s2, s3, s4, s5, s6]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s1 = peg$c130(s1); - } - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExprParams() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 69 + 54, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = []; - s2 = peg$currPos; - s3 = peg$parseFunctionTypeExprParamOperand(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c98; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c99); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s3 = [s3, s4, s5, s6]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = peg$currPos; - s3 = peg$parseFunctionTypeExprParamOperand(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c98; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c99); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s3 = [s3, s4, s5, s6]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseVariadicTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseVariadicTypeExprOperand(); - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - s1 = peg$c131(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExprParamOperand() { - var s0; - - var key = peg$currPos * 69 + 55, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExprReturnableOperand() { - var s0; - - var key = peg$currPos * 69 + 56, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parsePrefixUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseRecordTypeExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 69 + 57, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 123) { - s1 = peg$c132; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c133); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseRecordTypeExprEntries(); - if (s3 === peg$FAILED) { - s3 = null; - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 125) { - s5 = peg$c134; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c135); } - } - if (s5 !== peg$FAILED) { - s1 = peg$c136(s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseRecordTypeExprEntries() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 69 + 58, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseRecordTypeExprEntry(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$currPos; - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s6 = peg$c98; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c99); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 59) { - s6 = peg$c137; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c138); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - s5 = []; - if (peg$c1.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c2); } - } - while (s6 !== peg$FAILED) { - s5.push(s6); - if (peg$c1.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c2); } - } - } - if (s5 !== peg$FAILED) { - if (peg$c3.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c4); } - } - if (s6 === peg$FAILED) { - s6 = null; - } - if (s6 !== peg$FAILED) { - if (peg$c5.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c6); } - } - if (s7 !== peg$FAILED) { - s5 = [s5, s6, s7]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - s6 = peg$parseRecordTypeExprEntry(); - if (s6 !== peg$FAILED) { - s4 = [s4, s5, s6]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$currPos; - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s6 = peg$c98; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c99); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 59) { - s6 = peg$c137; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c138); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - s5 = []; - if (peg$c1.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c2); } - } - while (s6 !== peg$FAILED) { - s5.push(s6); - if (peg$c1.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c2); } - } - } - if (s5 !== peg$FAILED) { - if (peg$c3.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c4); } - } - if (s6 === peg$FAILED) { - s6 = null; - } - if (s6 !== peg$FAILED) { - if (peg$c5.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c6); } - } - if (s7 !== peg$FAILED) { - s5 = [s5, s6, s7]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - s6 = peg$parseRecordTypeExprEntry(); - if (s6 !== peg$FAILED) { - s4 = [s4, s5, s6]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c98; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c99); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 59) { - s5 = peg$c137; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c138); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = peg$currPos; - s4 = []; - if (peg$c1.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c2); } - } - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c1.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c2); } - } - } - if (s4 !== peg$FAILED) { - if (peg$c3.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c4); } - } - if (s5 === peg$FAILED) { - s5 = null; - } - if (s5 !== peg$FAILED) { - if (peg$c5.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c6); } - } - if (s6 !== peg$FAILED) { - s4 = [s4, s5, s6]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - } - if (s3 === peg$FAILED) { - s3 = null; - } - if (s3 !== peg$FAILED) { - s1 = peg$c139(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseRecordTypeExprEntry() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8; - - var key = peg$currPos * 69 + 59, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c140) { - s2 = peg$c140; - peg$currPos += 8; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c141); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse__(); - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 === peg$FAILED) { - s1 = null; - } - if (s1 !== peg$FAILED) { - s2 = peg$parseRecordTypeExprEntryKey(); - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - if (s3 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 63) { - s4 = peg$c58; - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c59); } - } - if (s4 === peg$FAILED) { - s4 = null; - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s6 = peg$c43; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s6 !== peg$FAILED) { - s7 = peg$parse_(); - if (s7 !== peg$FAILED) { - s8 = peg$parseRecordTypeExprEntryOperand(); - if (s8 !== peg$FAILED) { - s1 = peg$c142(s1, s2, s4, s8); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c140) { - s2 = peg$c140; - peg$currPos += 8; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c141); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse__(); - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 === peg$FAILED) { - s1 = null; - } - if (s1 !== peg$FAILED) { - s2 = peg$parseRecordTypeExprEntryKey(); - if (s2 !== peg$FAILED) { - s1 = peg$c143(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseRecordTypeExprEntryKey() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 69 + 60, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c25; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c25; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c144(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c17; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c17; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c145(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$currPos; - s2 = peg$parseJsIdentifier(); - if (s2 === peg$FAILED) { - s2 = peg$parseUnsignedDecimalNumberLiteralExpr(); - } - if (s2 !== peg$FAILED) { - s1 = input.substring(s1, peg$currPos); - } else { - s1 = s2; - } - if (s1 !== peg$FAILED) { - s1 = peg$c146(s1); - } - s0 = s1; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseRecordTypeExprEntryOperand() { - var s0; - - var key = peg$currPos * 69 + 61, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseParenthesizedExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 69 + 62, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c117; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c118); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseParenthesizedExprOperand(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s5 = peg$c119; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c120); } - } - if (s5 !== peg$FAILED) { - s1 = peg$c147(s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseParenthesizedExprOperand() { - var s0; - - var key = peg$currPos * 69 + 63, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseVariadicTypeExpr() { - var s0; - - var key = peg$currPos * 69 + 64, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parsePrefixVariadicTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseSuffixVariadicTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyVariadicTypeExpr(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixVariadicTypeExpr() { - var s0, s1, s2; - - var key = peg$currPos * 69 + 65, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c148) { - s1 = peg$c148; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c149); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseVariadicTypeExprOperand(); - if (s2 !== peg$FAILED) { - s1 = peg$c150(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixVariadicTypeExpr() { - var s0, s1, s2; - - var key = peg$currPos * 69 + 66, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseVariadicTypeExprOperand(); - if (s1 !== peg$FAILED) { - if (input.substr(peg$currPos, 3) === peg$c148) { - s2 = peg$c148; - peg$currPos += 3; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c149); } - } - if (s2 !== peg$FAILED) { - s1 = peg$c151(s1); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseAnyVariadicTypeExpr() { - var s0, s1; - - var key = peg$currPos * 69 + 67, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c148) { - s1 = peg$c148; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c149); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c152(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseVariadicTypeExprOperand() { - var s0; - - var key = peg$currPos * 69 + 68, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - - const meta = SyntaxType; - const { - GenericTypeSyntax, - VariadicTypeSyntax, OptionalTypeSyntax, - NullableTypeSyntax, NotNullableTypeSyntax, - } = meta; - const NodeType = NodeType_1; - - const NamepathOperatorType = { - MEMBER: 'MEMBER', - INNER_MEMBER: 'INNER_MEMBER', - INSTANCE_MEMBER: 'INSTANCE_MEMBER', - }; - - - peg$result = peg$startRuleFunction(); - - if (peg$result !== peg$FAILED && peg$currPos === input.length) { - return peg$result; - } else { - if (peg$result !== peg$FAILED && peg$currPos < input.length) { - peg$fail(peg$endExpectation()); - } - - throw peg$buildStructuredError( - peg$maxFailExpected, - peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, - peg$maxFailPos < input.length - ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) - : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) - ); - } -} - -var jsdoctypeJsdoc = { - SyntaxError: peg$SyntaxError$2, - parse: peg$parse$2 -}; - -/* - * Generated by PEG.js 0.10.0. - * - * http://pegjs.org/ - */ - -function peg$subclass$1(child, parent) { - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor(); -} - -function peg$SyntaxError$1(message, expected, found, location) { - this.message = message; - this.expected = expected; - this.found = found; - this.location = location; - this.name = "SyntaxError"; - - if (typeof Error.captureStackTrace === "function") { - Error.captureStackTrace(this, peg$SyntaxError$1); - } -} - -peg$subclass$1(peg$SyntaxError$1, Error); - -peg$SyntaxError$1.buildMessage = function(expected, found) { - var DESCRIBE_EXPECTATION_FNS = { - literal: function(expectation) { - return "\"" + literalEscape(expectation.text) + "\""; - }, - - "class": function(expectation) { - var escapedParts = "", - i; - - for (i = 0; i < expectation.parts.length; i++) { - escapedParts += expectation.parts[i] instanceof Array - ? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1]) - : classEscape(expectation.parts[i]); - } - - return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]"; - }, - - any: function(expectation) { - return "any character"; - }, - - end: function(expectation) { - return "end of input"; - }, - - other: function(expectation) { - return expectation.description; - } - }; - - function hex(ch) { - return ch.charCodeAt(0).toString(16).toUpperCase(); - } - - function literalEscape(s) { - return s - .replace(/\\/g, '\\\\') - .replace(/"/g, '\\"') - .replace(/\0/g, '\\0') - .replace(/\t/g, '\\t') - .replace(/\n/g, '\\n') - .replace(/\r/g, '\\r') - .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) - .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); }); - } - - function classEscape(s) { - return s - .replace(/\\/g, '\\\\') - .replace(/\]/g, '\\]') - .replace(/\^/g, '\\^') - .replace(/-/g, '\\-') - .replace(/\0/g, '\\0') - .replace(/\t/g, '\\t') - .replace(/\n/g, '\\n') - .replace(/\r/g, '\\r') - .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) - .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); }); - } - - function describeExpectation(expectation) { - return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); - } - - function describeExpected(expected) { - var descriptions = new Array(expected.length), - i, j; - - for (i = 0; i < expected.length; i++) { - descriptions[i] = describeExpectation(expected[i]); - } - - descriptions.sort(); - - if (descriptions.length > 0) { - for (i = 1, j = 1; i < descriptions.length; i++) { - if (descriptions[i - 1] !== descriptions[i]) { - descriptions[j] = descriptions[i]; - j++; - } - } - descriptions.length = j; - } - - switch (descriptions.length) { - case 1: - return descriptions[0]; - - case 2: - return descriptions[0] + " or " + descriptions[1]; - - default: - return descriptions.slice(0, -1).join(", ") - + ", or " - + descriptions[descriptions.length - 1]; - } - } - - function describeFound(found) { - return found ? "\"" + literalEscape(found) + "\"" : "end of input"; - } - - return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; -}; - -function peg$parse$1(input, options) { - options = options !== void 0 ? options : {}; - - var peg$FAILED = {}, - - peg$startRuleFunctions = { TopTypeExpr: peg$parseTopTypeExpr, NamepathExpr: peg$parseNamepathExpr, BroadNamepathExpr: peg$parseBroadNamepathExpr, ExternalNameExpr: peg$parseExternalNameExpr, ModuleNameExpr: peg$parseModuleNameExpr }, - peg$startRuleFunction = peg$parseTopTypeExpr, - - peg$c0 = function(expr) { - return expr; - }, - peg$c1 = /^[ \t]/, - peg$c2 = peg$classExpectation([" ", "\t"], false, false), - peg$c3 = /^[\r]/, - peg$c4 = peg$classExpectation(["\r"], false, false), - peg$c5 = /^[\n]/, - peg$c6 = peg$classExpectation(["\n"], false, false), - peg$c7 = /^[a-zA-Z_$]/, - peg$c8 = peg$classExpectation([["a", "z"], ["A", "Z"], "_", "$"], false, false), - peg$c9 = /^[a-zA-Z0-9_$]/, - peg$c10 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$"], false, false), - peg$c11 = "event:", - peg$c12 = peg$literalExpectation("event:", false), - peg$c13 = function(rootOwner, memberPartWithOperators) { - return memberPartWithOperators.reduce(function(owner, tokens) { - const operatorType = tokens[1]; - const eventNamespace = tokens[3]; - const MemberName = tokens[5]; - const {quoteStyle, name: memberName} = MemberName; - - switch (operatorType) { - case NamepathOperatorType.MEMBER: - return { - type: NodeType.MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - case NamepathOperatorType.INSTANCE_MEMBER: - return { - type: NodeType.INSTANCE_MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - case NamepathOperatorType.INNER_MEMBER: - return { - type: NodeType.INNER_MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - /* istanbul ignore next */ - default: - throw new Error('Unexpected operator type: "' + operatorType + '"'); - } - }, rootOwner); - }, - peg$c14 = /^[a-zA-Z0-9_$\-]/, - peg$c15 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$", "-"], false, false), - peg$c16 = function(name) { - return { - type: NodeType.NAME, - name - }; - }, - peg$c17 = "'", - peg$c18 = peg$literalExpectation("'", false), - peg$c19 = /^[^\\']/, - peg$c20 = peg$classExpectation(["\\", "'"], true, false), - peg$c21 = "\\", - peg$c22 = peg$literalExpectation("\\", false), - peg$c23 = peg$anyExpectation(), - peg$c24 = function(name) { - return { - quoteStyle: 'single', - name: name.replace(/\\'/g, "'") - .replace(/\\\\/gu, '\\') - }; - }, - peg$c25 = "\"", - peg$c26 = peg$literalExpectation("\"", false), - peg$c27 = /^[^\\"]/, - peg$c28 = peg$classExpectation(["\\", "\""], true, false), - peg$c29 = function(name) { - return { - quoteStyle: 'double', - name: name.replace(/\\"/gu, '"') - .replace(/\\\\/gu, '\\') - }; - }, - peg$c30 = function(name) { - return { - quoteStyle: 'none', - name - }; - }, - peg$c31 = ".", - peg$c32 = peg$literalExpectation(".", false), - peg$c33 = function(rootOwner, memberPart) { - return memberPart.reduce(function(owner, tokens) { - return { - type: NodeType.MEMBER, - owner, - name: tokens[3] - } - }, rootOwner); - }, - peg$c34 = function() { - return NamepathOperatorType.MEMBER; - }, - peg$c35 = "~", - peg$c36 = peg$literalExpectation("~", false), - peg$c37 = function() { - return NamepathOperatorType.INNER_MEMBER; - }, - peg$c38 = "#", - peg$c39 = peg$literalExpectation("#", false), - peg$c40 = function() { - return NamepathOperatorType.INSTANCE_MEMBER; - }, - peg$c41 = "external", - peg$c42 = peg$literalExpectation("external", false), - peg$c43 = ":", - peg$c44 = peg$literalExpectation(":", false), - peg$c45 = function(external, memberPartWithOperators) { - return memberPartWithOperators.reduce(function(owner, tokens) { - const operatorType = tokens[1]; - const eventNamespace = tokens[3]; - const MemberName = tokens[5]; - const {quoteStyle, name: memberName} = MemberName; - - switch (operatorType) { - case NamepathOperatorType.MEMBER: - return { - type: NodeType.MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - case NamepathOperatorType.INSTANCE_MEMBER: - return { - type: NodeType.INSTANCE_MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - case NamepathOperatorType.INNER_MEMBER: - return { - type: NodeType.INNER_MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - /* istanbul ignore next */ - default: - throw new Error('Unexpected operator type: "' + operatorType + '"'); - } - }, Object.assign({ - type: NodeType.EXTERNAL - }, external)); - }, - peg$c46 = "module", - peg$c47 = peg$literalExpectation("module", false), - peg$c48 = function(value) { - return { - type: NodeType.MODULE, - value, - }; - }, - peg$c49 = function(rootOwner, memberPartWithOperators) { - return memberPartWithOperators.reduce(function(owner, tokens) { - const operatorType = tokens[1]; - const eventNamespace = tokens[3]; - const MemberName = tokens[5]; - const {quoteStyle, name: memberName} = MemberName; - - switch (operatorType) { - case NamepathOperatorType.MEMBER: - return { - type: NodeType.MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - case NamepathOperatorType.INSTANCE_MEMBER: - return { - type: NodeType.INSTANCE_MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - case NamepathOperatorType.INNER_MEMBER: - return { - type: NodeType.INNER_MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - /* istanbul ignore next */ - default: - throw new Error('Unexpected operator type: "' + operatorType + '"'); - } - }, rootOwner); - }, - peg$c50 = function(path) { - return { - quoteStyle: 'single', - type: NodeType.FILE_PATH, - path: path.replace(/\\'/g, "'") - .replace(/\\\\/gu, '\\') - }; - }, - peg$c51 = function(path) { - return { - quoteStyle: 'double', - type: NodeType.FILE_PATH, - path: path.replace(/\\"/gu, '"') - .replace(/\\\\/gu, '\\') - }; - }, - peg$c52 = /^[a-zA-Z0-9_$\/\-]/, - peg$c53 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$", "/", "-"], false, false), - peg$c54 = function(path) { - return { - quoteStyle: 'none', - type: NodeType.FILE_PATH, - path, - }; - }, - peg$c55 = "*", - peg$c56 = peg$literalExpectation("*", false), - peg$c57 = function() { - return { type: NodeType.ANY }; - }, - peg$c58 = "?", - peg$c59 = peg$literalExpectation("?", false), - peg$c60 = function() { - return { type: NodeType.UNKNOWN }; - }, - peg$c61 = function(value) { - return { - type: NodeType.STRING_VALUE, - quoteStyle: 'double', - string: value.replace(/\\"/gu, '"') - .replace(/\\\\/gu, '\\') - }; - }, - peg$c62 = function(value) { - return { - type: NodeType.STRING_VALUE, - quoteStyle: 'single', - string: value.replace(/\\'/g, "'") - .replace(/\\\\/gu, '\\') - }; - }, - peg$c63 = function(value) { - return { - type: NodeType.NUMBER_VALUE, - number: value - }; - }, - peg$c64 = "+", - peg$c65 = peg$literalExpectation("+", false), - peg$c66 = "-", - peg$c67 = peg$literalExpectation("-", false), - peg$c68 = /^[0-9]/, - peg$c69 = peg$classExpectation([["0", "9"]], false, false), - peg$c70 = "e", - peg$c71 = peg$literalExpectation("e", false), - peg$c72 = "0b", - peg$c73 = peg$literalExpectation("0b", false), - peg$c74 = /^[01]/, - peg$c75 = peg$classExpectation(["0", "1"], false, false), - peg$c76 = "0o", - peg$c77 = peg$literalExpectation("0o", false), - peg$c78 = /^[0-7]/, - peg$c79 = peg$classExpectation([["0", "7"]], false, false), - peg$c80 = "0x", - peg$c81 = peg$literalExpectation("0x", false), - peg$c82 = /^[0-9a-fA-F]/, - peg$c83 = peg$classExpectation([["0", "9"], ["a", "f"], ["A", "F"]], false, false), - peg$c84 = "|", - peg$c85 = peg$literalExpectation("|", false), - peg$c86 = function(left, right) { - return { - type: NodeType.UNION, - left, - right, - }; - }, - peg$c87 = "typeof", - peg$c88 = peg$literalExpectation("typeof", false), - peg$c89 = function(operator, name) { - return { - type: NodeType.TYPE_QUERY, - name, - }; - }, - peg$c90 = function(operator, operand) { - return { - type: NodeType.NULLABLE, - value: operand, - meta: { syntax: NullableTypeSyntax.PREFIX_QUESTION_MARK }, - }; - }, - peg$c91 = "!", - peg$c92 = peg$literalExpectation("!", false), - peg$c93 = function(operator, operand) { - return { - type: NodeType.NOT_NULLABLE, - value: operand, - meta: { syntax: NotNullableTypeSyntax.PREFIX_BANG }, - }; - }, - peg$c94 = "=", - peg$c95 = peg$literalExpectation("=", false), - peg$c96 = function(operator, operand) { - return { - type: NodeType.OPTIONAL, - value: operand, - meta: { syntax: OptionalTypeSyntax.PREFIX_EQUALS_SIGN }, - }; - }, - peg$c97 = function(operand, operator) { - return { - type: NodeType.NULLABLE, - value: operand, - meta: { syntax: NullableTypeSyntax.SUFFIX_QUESTION_MARK }, - }; - }, - peg$c98 = function(operand, operator) { - return { - type: NodeType.NOT_NULLABLE, - value: operand, - meta: { syntax: NotNullableTypeSyntax.SUFFIX_BANG }, - }; - }, - peg$c99 = function(operand, operator) { - return { - type: NodeType.OPTIONAL, - value: operand, - meta: { syntax: OptionalTypeSyntax.SUFFIX_EQUALS_SIGN }, - }; - }, - peg$c100 = function(operand, syntax, params) { - return { - type: NodeType.GENERIC, - subject: operand, - objects: params, - meta: { syntax }, - }; - }, - peg$c101 = ",", - peg$c102 = peg$literalExpectation(",", false), - peg$c103 = function(first, restsWithComma) { - return restsWithComma.reduce(function(params, tokens) { - return params.concat([tokens[3]]); - }, [first]); - }, - peg$c104 = ".<", - peg$c105 = peg$literalExpectation(".<", false), - peg$c106 = function() { - return GenericTypeSyntax.ANGLE_BRACKET_WITH_DOT; - }, - peg$c107 = "<", - peg$c108 = peg$literalExpectation("<", false), - peg$c109 = function() { - return GenericTypeSyntax.ANGLE_BRACKET; - }, - peg$c110 = ">", - peg$c111 = peg$literalExpectation(">", false), - peg$c112 = "function", - peg$c113 = peg$literalExpectation("function", false), - peg$c114 = function(paramsPart, returnedTypePart) { - const returnedTypeNode = returnedTypePart ? returnedTypePart[2] : null; - - return { - type: NodeType.FUNCTION, - params: paramsPart.params, - returns: returnedTypeNode, - this: paramsPart.modifier.nodeThis, - new: paramsPart.modifier.nodeNew, - }; - }, - peg$c115 = "(", - peg$c116 = peg$literalExpectation("(", false), - peg$c117 = ")", - peg$c118 = peg$literalExpectation(")", false), - peg$c119 = function(modifier, params) { - return { params, modifier }; - }, - peg$c120 = function(modifier) { - return { params: [], modifier }; - }, - peg$c121 = function() { - return { params: [], modifier: { nodeThis: null, nodeNew: null } }; - }, - peg$c122 = function(params) { - return { params, modifier: { nodeThis: null, nodeNew: null } }; - }, - peg$c123 = "this", - peg$c124 = peg$literalExpectation("this", false), - peg$c125 = function(modifierThis) { - return { nodeThis: modifierThis[4], nodeNew: null }; - }, - peg$c126 = "new", - peg$c127 = peg$literalExpectation("new", false), - peg$c128 = function(modifierNew) { - return { nodeThis: null, nodeNew: modifierNew[4] }; - }, - peg$c129 = function(paramsWithComma, lastParam) { - return paramsWithComma.reduceRight(function(params, tokens) { - const [param] = tokens; - return [param].concat(params); - }, lastParam ? [lastParam] : []); - }, - peg$c130 = "{", - peg$c131 = peg$literalExpectation("{", false), - peg$c132 = "}", - peg$c133 = peg$literalExpectation("}", false), - peg$c134 = function(entries) { - return { - type: NodeType.RECORD, - entries: entries || [], - }; - }, - peg$c135 = ";", - peg$c136 = peg$literalExpectation(";", false), - peg$c137 = function(first, restWithComma) { - return restWithComma.reduce(function(entries, tokens) { - const entry = tokens[2]; - return entries.concat([entry]); - }, [first]); - }, - peg$c138 = "readonly", - peg$c139 = peg$literalExpectation("readonly", false), - peg$c140 = function(readonly, keyInfo, optional, value) { - const {quoteStyle, key} = keyInfo; - return { - type: NodeType.RECORD_ENTRY, - key, - quoteStyle, - value: - optional === '?' ? { - type: NodeType.OPTIONAL, - value, - meta: { syntax: OptionalTypeSyntax.SUFFIX_KEY_QUESTION_MARK }, - } : - value, - readonly: Boolean(readonly) - }; - }, - peg$c141 = function(readonly, keyInfo) { - const {quoteStyle, key} = keyInfo; - return { - type: NodeType.RECORD_ENTRY, - key, - quoteStyle, - value: null, - readonly: Boolean(readonly) - }; - }, - peg$c142 = function(key) { - return { - quoteStyle: 'double', - key: key.replace(/\\"/gu, '"') - .replace(/\\\\/gu, '\\') - }; - }, - peg$c143 = function(key) { - return { - quoteStyle: 'single', - key: key.replace(/\\'/g, "'") - .replace(/\\\\/gu, '\\') - }; - }, - peg$c144 = function(key) { - return { - quoteStyle: 'none', - key - }; - }, - peg$c145 = function(wrapped) { - return { - type: NodeType.PARENTHESIS, - value: wrapped, - }; - }, - peg$c146 = "...", - peg$c147 = peg$literalExpectation("...", false), - peg$c148 = function(operand) { - return { - type: NodeType.VARIADIC, - value: operand, - meta: { syntax: VariadicTypeSyntax.PREFIX_DOTS }, - }; - }, - peg$c149 = function(operand) { - return { - type: NodeType.VARIADIC, - value: operand, - meta: { syntax: VariadicTypeSyntax.SUFFIX_DOTS }, - }; - }, - peg$c150 = function() { - return { - type: NodeType.VARIADIC, - value: { type: NodeType.ANY }, - meta: { syntax: VariadicTypeSyntax.ONLY_DOTS }, - }; - }, - - peg$currPos = 0, - peg$posDetailsCache = [{ line: 1, column: 1 }], - peg$maxFailPos = 0, - peg$maxFailExpected = [], - peg$resultsCache = {}, - - peg$result; - - if ("startRule" in options) { - if (!(options.startRule in peg$startRuleFunctions)) { - throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); - } - - peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; - } - - function peg$literalExpectation(text, ignoreCase) { - return { type: "literal", text: text, ignoreCase: ignoreCase }; - } - - function peg$classExpectation(parts, inverted, ignoreCase) { - return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase }; - } - - function peg$anyExpectation() { - return { type: "any" }; - } - - function peg$endExpectation() { - return { type: "end" }; - } - - function peg$computePosDetails(pos) { - var details = peg$posDetailsCache[pos], p; - - if (details) { - return details; - } else { - p = pos - 1; - while (!peg$posDetailsCache[p]) { - p--; - } - - details = peg$posDetailsCache[p]; - details = { - line: details.line, - column: details.column - }; - - while (p < pos) { - if (input.charCodeAt(p) === 10) { - details.line++; - details.column = 1; - } else { - details.column++; - } - - p++; - } - - peg$posDetailsCache[pos] = details; - return details; - } - } - - function peg$computeLocation(startPos, endPos) { - var startPosDetails = peg$computePosDetails(startPos), - endPosDetails = peg$computePosDetails(endPos); - - return { - start: { - offset: startPos, - line: startPosDetails.line, - column: startPosDetails.column - }, - end: { - offset: endPos, - line: endPosDetails.line, - column: endPosDetails.column - } - }; - } - - function peg$fail(expected) { - if (peg$currPos < peg$maxFailPos) { return; } - - if (peg$currPos > peg$maxFailPos) { - peg$maxFailPos = peg$currPos; - peg$maxFailExpected = []; - } - - peg$maxFailExpected.push(expected); - } - - function peg$buildStructuredError(expected, found, location) { - return new peg$SyntaxError$1( - peg$SyntaxError$1.buildMessage(expected, found), - expected, - found, - location - ); - } - - function peg$parseTopTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 68 + 0, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parse_(); - if (s1 !== peg$FAILED) { - s2 = peg$parseVariadicTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseUnionTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseUnaryUnionTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseGenericTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseRecordTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseFunctionTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseTypeQueryExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseBroadNamepathExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseParenthesizedExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseValueExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseAnyTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - if (s3 !== peg$FAILED) { - s1 = peg$c0(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseWS() { - var s0, s1, s2; - - var key = peg$currPos * 68 + 1, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - if (peg$c1.test(input.charAt(peg$currPos))) { - s0 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s0 = peg$FAILED; - { peg$fail(peg$c2); } - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (peg$c3.test(input.charAt(peg$currPos))) { - s1 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c4); } - } - if (s1 === peg$FAILED) { - s1 = null; - } - if (s1 !== peg$FAILED) { - if (peg$c5.test(input.charAt(peg$currPos))) { - s2 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c6); } - } - if (s2 !== peg$FAILED) { - s1 = [s1, s2]; - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parse_() { - var s0, s1; - - var key = peg$currPos * 68 + 2, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = []; - s1 = peg$parseWS(); - while (s1 !== peg$FAILED) { - s0.push(s1); - s1 = peg$parseWS(); - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parse__() { - var s0, s1; - - var key = peg$currPos * 68 + 3, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = []; - s1 = peg$parseWS(); - if (s1 !== peg$FAILED) { - while (s1 !== peg$FAILED) { - s0.push(s1); - s1 = peg$parseWS(); - } - } else { - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseJsIdentifier() { - var s0, s1, s2, s3, s4; - - var key = peg$currPos * 68 + 4, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (peg$c7.test(input.charAt(peg$currPos))) { - s2 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c8); } - } - if (s2 !== peg$FAILED) { - s3 = []; - if (peg$c9.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c10); } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c9.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c10); } - } - } - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseNamepathExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - - var key = peg$currPos * 68 + 5, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseParenthesizedExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseTypeNameExprJsDocFlavored(); - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseInfixNamepathOperator(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c11) { - s7 = peg$c11; - peg$currPos += 6; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c12); } - } - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - s9 = peg$parseMemberName(); - if (s9 !== peg$FAILED) { - s4 = [s4, s5, s6, s7, s8, s9]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseInfixNamepathOperator(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c11) { - s7 = peg$c11; - peg$currPos += 6; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c12); } - } - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - s9 = peg$parseMemberName(); - if (s9 !== peg$FAILED) { - s4 = [s4, s5, s6, s7, s8, s9]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s1 = peg$c13(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseTypeNameExprJsDocFlavored() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 68 + 6, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - s2 = peg$currPos; - if (peg$c7.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c8); } - } - if (s3 !== peg$FAILED) { - s4 = []; - if (peg$c14.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c15); } - } - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c14.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c15); } - } - } - if (s4 !== peg$FAILED) { - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - s1 = input.substring(s1, peg$currPos); - } else { - s1 = s2; - } - if (s1 !== peg$FAILED) { - s1 = peg$c16(s1); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseMemberName() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 68 + 7, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c17; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c17; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c24(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c25; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c25; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c29(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$parseJsIdentifier(); - if (s1 !== peg$FAILED) { - s1 = peg$c30(s1); - } - s0 = s1; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseInfixNamepathOperator() { - var s0; - - var key = peg$currPos * 68 + 8, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseMemberTypeOperator(); - if (s0 === peg$FAILED) { - s0 = peg$parseInstanceMemberTypeOperator(); - if (s0 === peg$FAILED) { - s0 = peg$parseInnerMemberTypeOperator(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseQualifiedMemberName() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 68 + 9, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseTypeNameExprJsDocFlavored(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 46) { - s5 = peg$c31; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c32); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseTypeNameExprJsDocFlavored(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 46) { - s5 = peg$c31; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c32); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseTypeNameExprJsDocFlavored(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s1 = peg$c33(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseMemberTypeOperator() { - var s0, s1; - - var key = peg$currPos * 68 + 10, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 46) { - s1 = peg$c31; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c32); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c34(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseInnerMemberTypeOperator() { - var s0, s1; - - var key = peg$currPos * 68 + 11, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 126) { - s1 = peg$c35; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c36); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c37(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseInstanceMemberTypeOperator() { - var s0, s1; - - var key = peg$currPos * 68 + 12, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 35) { - s1 = peg$c38; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c39); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c40(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseBroadNamepathExpr() { - var s0; - - var key = peg$currPos * 68 + 13, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseExternalNameExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseModuleNameExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNamepathExpr(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseExternalNameExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13; - - var key = peg$currPos * 68 + 14, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c41) { - s1 = peg$c41; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c42); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s3 = peg$c43; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseMemberName(); - if (s5 !== peg$FAILED) { - s6 = []; - s7 = peg$currPos; - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - s9 = peg$parseInfixNamepathOperator(); - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - if (s10 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c11) { - s11 = peg$c11; - peg$currPos += 6; - } else { - s11 = peg$FAILED; - { peg$fail(peg$c12); } - } - if (s11 === peg$FAILED) { - s11 = null; - } - if (s11 !== peg$FAILED) { - s12 = peg$parse_(); - if (s12 !== peg$FAILED) { - s13 = peg$parseMemberName(); - if (s13 !== peg$FAILED) { - s8 = [s8, s9, s10, s11, s12, s13]; - s7 = s8; - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - while (s7 !== peg$FAILED) { - s6.push(s7); - s7 = peg$currPos; - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - s9 = peg$parseInfixNamepathOperator(); - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - if (s10 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c11) { - s11 = peg$c11; - peg$currPos += 6; - } else { - s11 = peg$FAILED; - { peg$fail(peg$c12); } - } - if (s11 === peg$FAILED) { - s11 = null; - } - if (s11 !== peg$FAILED) { - s12 = peg$parse_(); - if (s12 !== peg$FAILED) { - s13 = peg$parseMemberName(); - if (s13 !== peg$FAILED) { - s8 = [s8, s9, s10, s11, s12, s13]; - s7 = s8; - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } else { - peg$currPos = s7; - s7 = peg$FAILED; - } - } - if (s6 !== peg$FAILED) { - s1 = peg$c45(s5, s6); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseModuleNameExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 68 + 15, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c46) { - s1 = peg$c46; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c47); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s3 = peg$c43; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseModulePathExpr(); - if (s5 !== peg$FAILED) { - s1 = peg$c48(s5); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseModulePathExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - - var key = peg$currPos * 68 + 16, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseFilePathExpr(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseInfixNamepathOperator(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c11) { - s7 = peg$c11; - peg$currPos += 6; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c12); } - } - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - s9 = peg$parseMemberName(); - if (s9 !== peg$FAILED) { - s4 = [s4, s5, s6, s7, s8, s9]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseInfixNamepathOperator(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c11) { - s7 = peg$c11; - peg$currPos += 6; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c12); } - } - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - s9 = peg$parseMemberName(); - if (s9 !== peg$FAILED) { - s4 = [s4, s5, s6, s7, s8, s9]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s1 = peg$c49(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFilePathExpr() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 68 + 17, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c17; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c17; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c50(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c25; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c25; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c51(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$currPos; - s2 = []; - if (peg$c52.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c53); } - } - if (s3 !== peg$FAILED) { - while (s3 !== peg$FAILED) { - s2.push(s3); - if (peg$c52.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c53); } - } - } - } else { - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - s1 = input.substring(s1, peg$currPos); - } else { - s1 = s2; - } - if (s1 !== peg$FAILED) { - s1 = peg$c54(s1); - } - s0 = s1; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseAnyTypeExpr() { - var s0, s1; - - var key = peg$currPos * 68 + 18, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 42) { - s1 = peg$c55; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c56); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c57(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseUnknownTypeExpr() { - var s0, s1; - - var key = peg$currPos * 68 + 19, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 63) { - s1 = peg$c58; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c59); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c60(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseValueExpr() { - var s0; - - var key = peg$currPos * 68 + 20, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseStringLiteralExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNumberLiteralExpr(); - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseStringLiteralExpr() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 68 + 21, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c25; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c25; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c61(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c17; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c17; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c62(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseNumberLiteralExpr() { - var s0, s1; - - var key = peg$currPos * 68 + 22, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseBinNumberLiteralExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseOctNumberLiteralExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseHexNumberLiteralExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseDecimalNumberLiteralExpr(); - } - } - } - if (s1 !== peg$FAILED) { - s1 = peg$c63(s1); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseDecimalNumberLiteralExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 68 + 23, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 43) { - s2 = peg$c64; - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c65); } - } - if (s2 === peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 45) { - s2 = peg$c66; - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c67); } - } - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - s3 = peg$parseUnsignedDecimalNumberLiteralExpr(); - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseUnsignedDecimalNumberLiteralExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 68 + 24, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - s2 = peg$currPos; - s3 = []; - if (peg$c68.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c69); } - } - if (s4 !== peg$FAILED) { - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c68.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c69); } - } - } - } else { - s3 = peg$FAILED; - } - if (s3 !== peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 46) { - s5 = peg$c31; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c32); } - } - if (s5 !== peg$FAILED) { - s6 = []; - if (peg$c68.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c69); } - } - if (s7 !== peg$FAILED) { - while (s7 !== peg$FAILED) { - s6.push(s7); - if (peg$c68.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c69); } - } - } - } else { - s6 = peg$FAILED; - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = null; - } - if (s4 !== peg$FAILED) { - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - if (s2 === peg$FAILED) { - s2 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 46) { - s3 = peg$c31; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c32); } - } - if (s3 !== peg$FAILED) { - s4 = []; - if (peg$c68.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c69); } - } - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c68.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c69); } - } - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s3 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 101) { - s4 = peg$c70; - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c71); } - } - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 43) { - s5 = peg$c64; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c65); } - } - if (s5 === peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 45) { - s5 = peg$c66; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c67); } - } - } - if (s5 === peg$FAILED) { - s5 = null; - } - if (s5 !== peg$FAILED) { - s6 = []; - if (peg$c68.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c69); } - } - if (s7 !== peg$FAILED) { - while (s7 !== peg$FAILED) { - s6.push(s7); - if (peg$c68.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c69); } - } - } - } else { - s6 = peg$FAILED; - } - if (s6 !== peg$FAILED) { - s4 = [s4, s5, s6]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = null; - } - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseBinNumberLiteralExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 68 + 25, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 45) { - s2 = peg$c66; - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c67); } - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c72) { - s3 = peg$c72; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c73); } - } - if (s3 !== peg$FAILED) { - s4 = []; - if (peg$c74.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c75); } - } - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c74.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c75); } - } - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s2 = [s2, s3, s4]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseOctNumberLiteralExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 68 + 26, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 45) { - s2 = peg$c66; - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c67); } - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c76) { - s3 = peg$c76; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c77); } - } - if (s3 !== peg$FAILED) { - s4 = []; - if (peg$c78.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c79); } - } - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c78.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c79); } - } - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s2 = [s2, s3, s4]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseHexNumberLiteralExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 68 + 27, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 45) { - s2 = peg$c66; - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c67); } - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c80) { - s3 = peg$c80; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c81); } - } - if (s3 !== peg$FAILED) { - s4 = []; - if (peg$c82.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c83); } - } - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c82.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c83); } - } - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s2 = [s2, s3, s4]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseUnionTypeExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 68 + 28, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseUnionTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 124) { - s3 = peg$c84; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c85); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseUnionTypeExpr(); - if (s5 === peg$FAILED) { - s5 = peg$parseUnionTypeExprOperand(); - } - if (s5 !== peg$FAILED) { - s1 = peg$c86(s1, s5); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseUnionTypeExprOperand() { - var s0; - - var key = peg$currPos * 68 + 29, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseUnaryUnionTypeExpr() { - var s0; - - var key = peg$currPos * 68 + 30, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseSuffixUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parsePrefixUnaryUnionTypeExpr(); - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixUnaryUnionTypeExpr() { - var s0; - - var key = peg$currPos * 68 + 31, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parsePrefixOptionalTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parsePrefixNotNullableTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parsePrefixNullableTypeExpr(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixUnaryUnionTypeExprOperand() { - var s0; - - var key = peg$currPos * 68 + 32, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseTypeQueryExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 68 + 33, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c87) { - s1 = peg$c87; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c88); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseQualifiedMemberName(); - if (s3 !== peg$FAILED) { - s1 = peg$c89(s1, s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixNullableTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 68 + 34, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 63) { - s1 = peg$c58; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c59); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); - if (s3 !== peg$FAILED) { - s1 = peg$c90(s1, s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixNotNullableTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 68 + 35, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 33) { - s1 = peg$c91; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c92); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); - if (s3 !== peg$FAILED) { - s1 = peg$c93(s1, s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixOptionalTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 68 + 36, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 61) { - s1 = peg$c94; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c95); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); - if (s3 !== peg$FAILED) { - s1 = peg$c96(s1, s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixUnaryUnionTypeExpr() { - var s0; - - var key = peg$currPos * 68 + 37, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseSuffixOptionalTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseSuffixNullableTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseSuffixNotNullableTypeExpr(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixUnaryUnionTypeExprOperand() { - var s0; - - var key = peg$currPos * 68 + 38, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parsePrefixUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixNullableTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 68 + 39, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 63) { - s3 = peg$c58; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c59); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c97(s1); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixNotNullableTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 68 + 40, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 33) { - s3 = peg$c91; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c92); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c98(s1); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixOptionalTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 68 + 41, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseSuffixNullableTypeExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseSuffixNotNullableTypeExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 61) { - s3 = peg$c94; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c95); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c99(s1); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 68 + 42, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseGenericTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseGenericTypeStartToken(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseGenericTypeExprTypeParamList(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseGenericTypeEndToken(); - if (s7 !== peg$FAILED) { - s1 = peg$c100(s1, s3, s5); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeExprOperand() { - var s0; - - var key = peg$currPos * 68 + 43, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeExprTypeParamOperand() { - var s0; - - var key = peg$currPos * 68 + 44, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeExprTypeParamList() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 68 + 45, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseGenericTypeExprTypeParamOperand(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c101; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c102); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseGenericTypeExprTypeParamOperand(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c101; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c102); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseGenericTypeExprTypeParamOperand(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s1 = peg$c103(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeStartToken() { - var s0; - - var key = peg$currPos * 68 + 46, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseGenericTypeEcmaScriptFlavoredStartToken(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeTypeScriptFlavoredStartToken(); - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeEcmaScriptFlavoredStartToken() { - var s0, s1; - - var key = peg$currPos * 68 + 47, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c104) { - s1 = peg$c104; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c105); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c106(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeTypeScriptFlavoredStartToken() { - var s0, s1; - - var key = peg$currPos * 68 + 48, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 60) { - s1 = peg$c107; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c108); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c109(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeEndToken() { - var s0; - - var key = peg$currPos * 68 + 49, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - if (input.charCodeAt(peg$currPos) === 62) { - s0 = peg$c110; - peg$currPos++; - } else { - s0 = peg$FAILED; - { peg$fail(peg$c111); } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8; - - var key = peg$currPos * 68 + 50, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c112) { - s1 = peg$c112; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c113); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseFunctionTypeExprParamsList(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 58) { - s6 = peg$c43; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s6 !== peg$FAILED) { - s7 = peg$parse_(); - if (s7 !== peg$FAILED) { - s8 = peg$parseFunctionTypeExprReturnableOperand(); - if (s8 !== peg$FAILED) { - s6 = [s6, s7, s8]; - s5 = s6; - } else { - peg$currPos = s5; - s5 = peg$FAILED; - } - } else { - peg$currPos = s5; - s5 = peg$FAILED; - } - } else { - peg$currPos = s5; - s5 = peg$FAILED; - } - if (s5 === peg$FAILED) { - s5 = null; - } - if (s5 !== peg$FAILED) { - s1 = peg$c114(s3, s5); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExprParamsList() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - - var key = peg$currPos * 68 + 51, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c115; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c116); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseFunctionTypeExprModifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c101; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c102); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseFunctionTypeExprParams(); - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s9 = peg$c117; - peg$currPos++; - } else { - s9 = peg$FAILED; - { peg$fail(peg$c118); } - } - if (s9 !== peg$FAILED) { - s1 = peg$c119(s3, s7); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c115; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c116); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseFunctionTypeExprModifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s5 = peg$c117; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c118); } - } - if (s5 !== peg$FAILED) { - s1 = peg$c120(s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c115; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c116); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s3 = peg$c117; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c118); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c121(); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c115; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c116); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseFunctionTypeExprParams(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s5 = peg$c117; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c118); } - } - if (s5 !== peg$FAILED) { - s1 = peg$c122(s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExprModifier() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 68 + 52, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c123) { - s2 = peg$c123; - peg$currPos += 4; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c124); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - if (s3 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s4 = peg$c43; - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - s6 = peg$parseFunctionTypeExprParamOperand(); - if (s6 !== peg$FAILED) { - s2 = [s2, s3, s4, s5, s6]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s1 = peg$c125(s1); - } - s0 = s1; - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c126) { - s2 = peg$c126; - peg$currPos += 3; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c127); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - if (s3 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s4 = peg$c43; - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - s6 = peg$parseFunctionTypeExprParamOperand(); - if (s6 !== peg$FAILED) { - s2 = [s2, s3, s4, s5, s6]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s1 = peg$c128(s1); - } - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExprParams() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 68 + 53, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = []; - s2 = peg$currPos; - s3 = peg$parseFunctionTypeExprParamOperand(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c101; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c102); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s3 = [s3, s4, s5, s6]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = peg$currPos; - s3 = peg$parseFunctionTypeExprParamOperand(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c101; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c102); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s3 = [s3, s4, s5, s6]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseVariadicTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseVariadicTypeExprOperand(); - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - s1 = peg$c129(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExprParamOperand() { - var s0; - - var key = peg$currPos * 68 + 54, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExprReturnableOperand() { - var s0; - - var key = peg$currPos * 68 + 55, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parsePrefixUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseRecordTypeExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 68 + 56, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 123) { - s1 = peg$c130; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c131); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseRecordTypeExprEntries(); - if (s3 === peg$FAILED) { - s3 = null; - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 125) { - s5 = peg$c132; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c133); } - } - if (s5 !== peg$FAILED) { - s1 = peg$c134(s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseRecordTypeExprEntries() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 68 + 57, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseRecordTypeExprEntry(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$currPos; - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s6 = peg$c101; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c102); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 59) { - s6 = peg$c135; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c136); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - s5 = []; - if (peg$c1.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c2); } - } - while (s6 !== peg$FAILED) { - s5.push(s6); - if (peg$c1.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c2); } - } - } - if (s5 !== peg$FAILED) { - if (peg$c3.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c4); } - } - if (s6 === peg$FAILED) { - s6 = null; - } - if (s6 !== peg$FAILED) { - if (peg$c5.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c6); } - } - if (s7 !== peg$FAILED) { - s5 = [s5, s6, s7]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - s6 = peg$parseRecordTypeExprEntry(); - if (s6 !== peg$FAILED) { - s4 = [s4, s5, s6]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$currPos; - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s6 = peg$c101; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c102); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 59) { - s6 = peg$c135; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c136); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - s5 = []; - if (peg$c1.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c2); } - } - while (s6 !== peg$FAILED) { - s5.push(s6); - if (peg$c1.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c2); } - } - } - if (s5 !== peg$FAILED) { - if (peg$c3.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c4); } - } - if (s6 === peg$FAILED) { - s6 = null; - } - if (s6 !== peg$FAILED) { - if (peg$c5.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c6); } - } - if (s7 !== peg$FAILED) { - s5 = [s5, s6, s7]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - s6 = peg$parseRecordTypeExprEntry(); - if (s6 !== peg$FAILED) { - s4 = [s4, s5, s6]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c101; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c102); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 59) { - s5 = peg$c135; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c136); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = peg$currPos; - s4 = []; - if (peg$c1.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c2); } - } - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c1.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c2); } - } - } - if (s4 !== peg$FAILED) { - if (peg$c3.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c4); } - } - if (s5 === peg$FAILED) { - s5 = null; - } - if (s5 !== peg$FAILED) { - if (peg$c5.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c6); } - } - if (s6 !== peg$FAILED) { - s4 = [s4, s5, s6]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - } - if (s3 === peg$FAILED) { - s3 = null; - } - if (s3 !== peg$FAILED) { - s1 = peg$c137(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseRecordTypeExprEntry() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8; - - var key = peg$currPos * 68 + 58, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c138) { - s2 = peg$c138; - peg$currPos += 8; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c139); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse__(); - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 === peg$FAILED) { - s1 = null; - } - if (s1 !== peg$FAILED) { - s2 = peg$parseRecordTypeExprEntryKey(); - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - if (s3 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 63) { - s4 = peg$c58; - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c59); } - } - if (s4 === peg$FAILED) { - s4 = null; - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s6 = peg$c43; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c44); } - } - if (s6 !== peg$FAILED) { - s7 = peg$parse_(); - if (s7 !== peg$FAILED) { - s8 = peg$parseRecordTypeExprEntryOperand(); - if (s8 !== peg$FAILED) { - s1 = peg$c140(s1, s2, s4, s8); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c138) { - s2 = peg$c138; - peg$currPos += 8; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c139); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse__(); - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 === peg$FAILED) { - s1 = null; - } - if (s1 !== peg$FAILED) { - s2 = peg$parseRecordTypeExprEntryKey(); - if (s2 !== peg$FAILED) { - s1 = peg$c141(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseRecordTypeExprEntryKey() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 68 + 59, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c25; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c25; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c142(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c17; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c17; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c143(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$currPos; - s2 = peg$parseJsIdentifier(); - if (s2 === peg$FAILED) { - s2 = peg$parseUnsignedDecimalNumberLiteralExpr(); - } - if (s2 !== peg$FAILED) { - s1 = input.substring(s1, peg$currPos); - } else { - s1 = s2; - } - if (s1 !== peg$FAILED) { - s1 = peg$c144(s1); - } - s0 = s1; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseRecordTypeExprEntryOperand() { - var s0; - - var key = peg$currPos * 68 + 60, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseParenthesizedExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 68 + 61, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c115; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c116); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseParenthesizedExprOperand(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s5 = peg$c117; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c118); } - } - if (s5 !== peg$FAILED) { - s1 = peg$c145(s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseParenthesizedExprOperand() { - var s0; - - var key = peg$currPos * 68 + 62, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseVariadicTypeExpr() { - var s0; - - var key = peg$currPos * 68 + 63, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parsePrefixVariadicTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseSuffixVariadicTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyVariadicTypeExpr(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixVariadicTypeExpr() { - var s0, s1, s2; - - var key = peg$currPos * 68 + 64, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c146) { - s1 = peg$c146; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c147); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseVariadicTypeExprOperand(); - if (s2 !== peg$FAILED) { - s1 = peg$c148(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixVariadicTypeExpr() { - var s0, s1, s2; - - var key = peg$currPos * 68 + 65, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseVariadicTypeExprOperand(); - if (s1 !== peg$FAILED) { - if (input.substr(peg$currPos, 3) === peg$c146) { - s2 = peg$c146; - peg$currPos += 3; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c147); } - } - if (s2 !== peg$FAILED) { - s1 = peg$c149(s1); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseAnyVariadicTypeExpr() { - var s0, s1; - - var key = peg$currPos * 68 + 66, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c146) { - s1 = peg$c146; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c147); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c150(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseVariadicTypeExprOperand() { - var s0; - - var key = peg$currPos * 68 + 67, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseBroadNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - - const meta = SyntaxType; - const { - GenericTypeSyntax, - VariadicTypeSyntax, OptionalTypeSyntax, - NullableTypeSyntax, NotNullableTypeSyntax, - } = meta; - const NodeType = NodeType_1; - - const NamepathOperatorType = { - MEMBER: 'MEMBER', - INNER_MEMBER: 'INNER_MEMBER', - INSTANCE_MEMBER: 'INSTANCE_MEMBER', - }; - - - peg$result = peg$startRuleFunction(); - - if (peg$result !== peg$FAILED && peg$currPos === input.length) { - return peg$result; - } else { - if (peg$result !== peg$FAILED && peg$currPos < input.length) { - peg$fail(peg$endExpectation()); - } - - throw peg$buildStructuredError( - peg$maxFailExpected, - peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, - peg$maxFailPos < input.length - ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) - : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) - ); - } -} - -var jsdoctypeClosure = { - SyntaxError: peg$SyntaxError$1, - parse: peg$parse$1 -}; - -/* - * Generated by PEG.js 0.10.0. - * - * http://pegjs.org/ - */ - -function peg$subclass(child, parent) { - function ctor() { this.constructor = child; } - ctor.prototype = parent.prototype; - child.prototype = new ctor(); -} - -function peg$SyntaxError(message, expected, found, location) { - this.message = message; - this.expected = expected; - this.found = found; - this.location = location; - this.name = "SyntaxError"; - - if (typeof Error.captureStackTrace === "function") { - Error.captureStackTrace(this, peg$SyntaxError); - } -} - -peg$subclass(peg$SyntaxError, Error); - -peg$SyntaxError.buildMessage = function(expected, found) { - var DESCRIBE_EXPECTATION_FNS = { - literal: function(expectation) { - return "\"" + literalEscape(expectation.text) + "\""; - }, - - "class": function(expectation) { - var escapedParts = "", - i; - - for (i = 0; i < expectation.parts.length; i++) { - escapedParts += expectation.parts[i] instanceof Array - ? classEscape(expectation.parts[i][0]) + "-" + classEscape(expectation.parts[i][1]) - : classEscape(expectation.parts[i]); - } - - return "[" + (expectation.inverted ? "^" : "") + escapedParts + "]"; - }, - - any: function(expectation) { - return "any character"; - }, - - end: function(expectation) { - return "end of input"; - }, - - other: function(expectation) { - return expectation.description; - } - }; - - function hex(ch) { - return ch.charCodeAt(0).toString(16).toUpperCase(); - } - - function literalEscape(s) { - return s - .replace(/\\/g, '\\\\') - .replace(/"/g, '\\"') - .replace(/\0/g, '\\0') - .replace(/\t/g, '\\t') - .replace(/\n/g, '\\n') - .replace(/\r/g, '\\r') - .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) - .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); }); - } - - function classEscape(s) { - return s - .replace(/\\/g, '\\\\') - .replace(/\]/g, '\\]') - .replace(/\^/g, '\\^') - .replace(/-/g, '\\-') - .replace(/\0/g, '\\0') - .replace(/\t/g, '\\t') - .replace(/\n/g, '\\n') - .replace(/\r/g, '\\r') - .replace(/[\x00-\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) - .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return '\\x' + hex(ch); }); - } - - function describeExpectation(expectation) { - return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); - } - - function describeExpected(expected) { - var descriptions = new Array(expected.length), - i, j; - - for (i = 0; i < expected.length; i++) { - descriptions[i] = describeExpectation(expected[i]); - } - - descriptions.sort(); - - if (descriptions.length > 0) { - for (i = 1, j = 1; i < descriptions.length; i++) { - if (descriptions[i - 1] !== descriptions[i]) { - descriptions[j] = descriptions[i]; - j++; - } - } - descriptions.length = j; - } - - switch (descriptions.length) { - case 1: - return descriptions[0]; - - case 2: - return descriptions[0] + " or " + descriptions[1]; - - default: - return descriptions.slice(0, -1).join(", ") - + ", or " - + descriptions[descriptions.length - 1]; - } - } - - function describeFound(found) { - return found ? "\"" + literalEscape(found) + "\"" : "end of input"; - } - - return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; -}; - -function peg$parse(input, options) { - options = options !== void 0 ? options : {}; - - var peg$FAILED = {}, - - peg$startRuleFunctions = { TopTypeExpr: peg$parseTopTypeExpr, NamepathExpr: peg$parseNamepathExpr, BroadNamepathExpr: peg$parseBroadNamepathExpr }, - peg$startRuleFunction = peg$parseTopTypeExpr, - - peg$c0 = function(expr) { - return expr; - }, - peg$c1 = /^[ \t]/, - peg$c2 = peg$classExpectation([" ", "\t"], false, false), - peg$c3 = /^[\r]/, - peg$c4 = peg$classExpectation(["\r"], false, false), - peg$c5 = /^[\n]/, - peg$c6 = peg$classExpectation(["\n"], false, false), - peg$c7 = /^[a-zA-Z_$]/, - peg$c8 = peg$classExpectation([["a", "z"], ["A", "Z"], "_", "$"], false, false), - peg$c9 = /^[a-zA-Z0-9_$]/, - peg$c10 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$"], false, false), - peg$c11 = "event:", - peg$c12 = peg$literalExpectation("event:", false), - peg$c13 = function(rootOwner, memberPartWithOperators) { - return memberPartWithOperators.reduce(function(owner, tokens) { - const operatorType = tokens[1]; - const eventNamespace = tokens[3]; - const MemberName = tokens[5]; - const {quoteStyle, name: memberName} = MemberName; - - switch (operatorType) { - case NamepathOperatorType.MEMBER: - return { - type: NodeType.MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - case NamepathOperatorType.INSTANCE_MEMBER: - return { - type: NodeType.INSTANCE_MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - case NamepathOperatorType.INNER_MEMBER: - return { - type: NodeType.INNER_MEMBER, - owner, - name: memberName, - quoteStyle, - hasEventPrefix: Boolean(eventNamespace), - }; - /* istanbul ignore next */ - default: - throw new Error('Unexpected operator type: "' + operatorType + '"'); - } - }, rootOwner); - }, - peg$c14 = /^[a-zA-Z0-9_$\-]/, - peg$c15 = peg$classExpectation([["a", "z"], ["A", "Z"], ["0", "9"], "_", "$", "-"], false, false), - peg$c16 = function(name) { - return { - type: NodeType.NAME, - name - }; - }, - peg$c17 = "'", - peg$c18 = peg$literalExpectation("'", false), - peg$c19 = /^[^\\']/, - peg$c20 = peg$classExpectation(["\\", "'"], true, false), - peg$c21 = "\\", - peg$c22 = peg$literalExpectation("\\", false), - peg$c23 = peg$anyExpectation(), - peg$c24 = function(name) { - return { - quoteStyle: 'single', - name: name.replace(/\\'/g, "'") - .replace(/\\\\/gu, '\\') - }; - }, - peg$c25 = "\"", - peg$c26 = peg$literalExpectation("\"", false), - peg$c27 = /^[^\\"]/, - peg$c28 = peg$classExpectation(["\\", "\""], true, false), - peg$c29 = function(name) { - return { - quoteStyle: 'double', - name: name.replace(/\\"/gu, '"') - .replace(/\\\\/gu, '\\') - }; - }, - peg$c30 = function(name) { - return { - quoteStyle: 'none', - name - }; - }, - peg$c31 = ".", - peg$c32 = peg$literalExpectation(".", false), - peg$c33 = function(rootOwner, memberPart) { - return memberPart.reduce(function(owner, tokens) { - return { - type: NodeType.MEMBER, - owner, - name: tokens[3] - } - }, rootOwner); - }, - peg$c34 = function() { - return NamepathOperatorType.MEMBER; - }, - peg$c35 = "~", - peg$c36 = peg$literalExpectation("~", false), - peg$c37 = function() { - return NamepathOperatorType.INNER_MEMBER; - }, - peg$c38 = "#", - peg$c39 = peg$literalExpectation("#", false), - peg$c40 = function() { - return NamepathOperatorType.INSTANCE_MEMBER; - }, - peg$c41 = "*", - peg$c42 = peg$literalExpectation("*", false), - peg$c43 = function() { - return { type: NodeType.ANY }; - }, - peg$c44 = "?", - peg$c45 = peg$literalExpectation("?", false), - peg$c46 = function() { - return { type: NodeType.UNKNOWN }; - }, - peg$c47 = function(value) { - return { - type: NodeType.STRING_VALUE, - quoteStyle: 'double', - string: value.replace(/\\"/gu, '"') - .replace(/\\\\/gu, '\\') - }; - }, - peg$c48 = function(value) { - return { - type: NodeType.STRING_VALUE, - quoteStyle: 'single', - string: value.replace(/\\'/g, "'") - .replace(/\\\\/gu, '\\') - }; - }, - peg$c49 = function(value) { - return { - type: NodeType.NUMBER_VALUE, - number: value - }; - }, - peg$c50 = "+", - peg$c51 = peg$literalExpectation("+", false), - peg$c52 = "-", - peg$c53 = peg$literalExpectation("-", false), - peg$c54 = /^[0-9]/, - peg$c55 = peg$classExpectation([["0", "9"]], false, false), - peg$c56 = "e", - peg$c57 = peg$literalExpectation("e", false), - peg$c58 = "0b", - peg$c59 = peg$literalExpectation("0b", false), - peg$c60 = /^[01]/, - peg$c61 = peg$classExpectation(["0", "1"], false, false), - peg$c62 = "0o", - peg$c63 = peg$literalExpectation("0o", false), - peg$c64 = /^[0-7]/, - peg$c65 = peg$classExpectation([["0", "7"]], false, false), - peg$c66 = "0x", - peg$c67 = peg$literalExpectation("0x", false), - peg$c68 = /^[0-9a-fA-F]/, - peg$c69 = peg$classExpectation([["0", "9"], ["a", "f"], ["A", "F"]], false, false), - peg$c70 = "&", - peg$c71 = peg$literalExpectation("&", false), - peg$c72 = function(left, right) { - return { - type: NodeType.INTERSECTION, - left, - right, - }; - }, - peg$c73 = "|", - peg$c74 = peg$literalExpectation("|", false), - peg$c75 = function(left, right) { - return { - type: NodeType.UNION, - left, - right, - }; - }, - peg$c76 = "typeof", - peg$c77 = peg$literalExpectation("typeof", false), - peg$c78 = function(operator, name) { - return { - type: NodeType.TYPE_QUERY, - name, - }; - }, - peg$c79 = "keyof", - peg$c80 = peg$literalExpectation("keyof", false), - peg$c81 = function(operator, operand) { - return { - type: NodeType.KEY_QUERY, - value: operand, - } - }, - peg$c82 = "import", - peg$c83 = peg$literalExpectation("import", false), - peg$c84 = "(", - peg$c85 = peg$literalExpectation("(", false), - peg$c86 = ")", - peg$c87 = peg$literalExpectation(")", false), - peg$c88 = function(operator, path) { - return { type: NodeType.IMPORT, path }; - }, - peg$c89 = function(operator, operand) { - return { - type: NodeType.NULLABLE, - value: operand, - meta: { syntax: NullableTypeSyntax.PREFIX_QUESTION_MARK }, - }; - }, - peg$c90 = "!", - peg$c91 = peg$literalExpectation("!", false), - peg$c92 = function(operator, operand) { - return { - type: NodeType.NOT_NULLABLE, - value: operand, - meta: { syntax: NotNullableTypeSyntax.PREFIX_BANG }, - }; - }, - peg$c93 = "=", - peg$c94 = peg$literalExpectation("=", false), - peg$c95 = function(operator, operand) { - return { - type: NodeType.OPTIONAL, - value: operand, - meta: { syntax: OptionalTypeSyntax.PREFIX_EQUALS_SIGN }, - }; - }, - peg$c96 = function(operand, operator) { - return { - type: NodeType.NULLABLE, - value: operand, - meta: { syntax: NullableTypeSyntax.SUFFIX_QUESTION_MARK }, - }; - }, - peg$c97 = function(operand, operator) { - return { - type: NodeType.NOT_NULLABLE, - value: operand, - meta: { syntax: NotNullableTypeSyntax.SUFFIX_BANG }, - }; - }, - peg$c98 = function(operand, operator) { - return { - type: NodeType.OPTIONAL, - value: operand, - meta: { syntax: OptionalTypeSyntax.SUFFIX_EQUALS_SIGN }, - }; - }, - peg$c99 = function(operand, syntax, params) { - return { - type: NodeType.GENERIC, - subject: operand, - objects: params, - meta: { syntax }, - }; - }, - peg$c100 = ",", - peg$c101 = peg$literalExpectation(",", false), - peg$c102 = function(first, restsWithComma) { - return restsWithComma.reduce(function(params, tokens) { - return params.concat([tokens[3]]); - }, [first]); - }, - peg$c103 = ".<", - peg$c104 = peg$literalExpectation(".<", false), - peg$c105 = function() { - return GenericTypeSyntax.ANGLE_BRACKET_WITH_DOT; - }, - peg$c106 = "<", - peg$c107 = peg$literalExpectation("<", false), - peg$c108 = function() { - return GenericTypeSyntax.ANGLE_BRACKET; - }, - peg$c109 = ">", - peg$c110 = peg$literalExpectation(">", false), - peg$c111 = "[", - peg$c112 = peg$literalExpectation("[", false), - peg$c113 = "]", - peg$c114 = peg$literalExpectation("]", false), - peg$c115 = function(operand, brackets) { - return brackets.reduce(function(operand) { - return { - type: NodeType.GENERIC, - subject: { - type: NodeType.NAME, - name: 'Array' - }, - objects: [ operand ], - meta: { syntax: GenericTypeSyntax.SQUARE_BRACKET }, - }; - }, operand); - }, - peg$c116 = "new", - peg$c117 = peg$literalExpectation("new", false), - peg$c118 = "=>", - peg$c119 = peg$literalExpectation("=>", false), - peg$c120 = function(newModifier, paramsPart, returnedTypeNode) { - return { - type: NodeType.ARROW, - params: paramsPart, - returns: returnedTypeNode, - new: newModifier - }; - }, - peg$c121 = function() { - return []; - }, - peg$c122 = function(params) { - return params; - }, - peg$c123 = ":", - peg$c124 = peg$literalExpectation(":", false), - peg$c125 = function(paramsWithComma, lastParam) { - return paramsWithComma.reduceRight(function(params, tokens) { - const param = { type: NodeType.NAMED_PARAMETER, name: tokens[0], typeName: tokens[4] }; - return [param].concat(params); - }, lastParam ? [lastParam] : []); - }, - peg$c126 = "...", - peg$c127 = peg$literalExpectation("...", false), - peg$c128 = function(spread, id, type) { - const operand = { type: NodeType.NAMED_PARAMETER, name: id, typeName: type }; - if (spread) { - return { - type: NodeType.VARIADIC, - value: operand, - meta: { syntax: VariadicTypeSyntax.PREFIX_DOTS }, - }; - } - else { - return operand; - } - }, - peg$c129 = "function", - peg$c130 = peg$literalExpectation("function", false), - peg$c131 = function(paramsPart, returnedTypePart) { - const returnedTypeNode = returnedTypePart ? returnedTypePart[2] : null; - - return { - type: NodeType.FUNCTION, - params: paramsPart.params, - returns: returnedTypeNode, - this: paramsPart.modifier.nodeThis, - new: paramsPart.modifier.nodeNew, - }; - }, - peg$c132 = function(modifier, params) { - return { params, modifier }; - }, - peg$c133 = function(modifier) { - return { params: [], modifier }; - }, - peg$c134 = function() { - return { params: [], modifier: { nodeThis: null, nodeNew: null } }; - }, - peg$c135 = function(params) { - return { params, modifier: { nodeThis: null, nodeNew: null } }; - }, - peg$c136 = "this", - peg$c137 = peg$literalExpectation("this", false), - peg$c138 = function(modifierThis) { - return { nodeThis: modifierThis[4], nodeNew: null }; - }, - peg$c139 = function(modifierNew) { - return { nodeThis: null, nodeNew: modifierNew[4] }; - }, - peg$c140 = function(paramsWithComma, lastParam) { - return paramsWithComma.reduceRight(function(params, tokens) { - const [param] = tokens; - return [param].concat(params); - }, lastParam ? [lastParam] : []); - }, - peg$c141 = "{", - peg$c142 = peg$literalExpectation("{", false), - peg$c143 = "}", - peg$c144 = peg$literalExpectation("}", false), - peg$c145 = function(entries) { - return { - type: NodeType.RECORD, - entries: entries || [], - }; - }, - peg$c146 = ";", - peg$c147 = peg$literalExpectation(";", false), - peg$c148 = function(first, restWithComma) { - return restWithComma.reduce(function(entries, tokens) { - const entry = tokens[2]; - return entries.concat([entry]); - }, [first]); - }, - peg$c149 = "readonly", - peg$c150 = peg$literalExpectation("readonly", false), - peg$c151 = function(readonly, keyInfo, optional, value) { - const {quoteStyle, key} = keyInfo; - return { - type: NodeType.RECORD_ENTRY, - key, - quoteStyle, - value: - optional === '?' ? { - type: NodeType.OPTIONAL, - value, - meta: { syntax: OptionalTypeSyntax.SUFFIX_KEY_QUESTION_MARK }, - } : - value, - readonly: Boolean(readonly) - }; - }, - peg$c152 = function(readonly, keyInfo) { - const {quoteStyle, key} = keyInfo; - return { - type: NodeType.RECORD_ENTRY, - key, - quoteStyle, - value: null, - readonly: Boolean(readonly) - }; - }, - peg$c153 = function(key) { - return { - quoteStyle: 'double', - key: key.replace(/\\"/gu, '"') - .replace(/\\\\/gu, '\\') - }; - }, - peg$c154 = function(key) { - return { - quoteStyle: 'single', - key: key.replace(/\\'/g, "'") - .replace(/\\\\/gu, '\\') - }; - }, - peg$c155 = function(key) { - return { - quoteStyle: 'none', - key - }; - }, - peg$c156 = function(entries) { - return { - type: NodeType.TUPLE, - entries, - } - }, - peg$c157 = function(restWithComma, last) { - return restWithComma.reduceRight((entries, tokens) => { - let [entry] = tokens; - return [entry].concat(entries); - }, last ? [last] : []); - }, - peg$c158 = function(wrapped) { - return { - type: NodeType.PARENTHESIS, - value: wrapped, - }; - }, - peg$c159 = function(operand) { - return { - type: NodeType.VARIADIC, - value: operand, - meta: { syntax: VariadicTypeSyntax.PREFIX_DOTS }, - }; - }, - peg$c160 = function(operand) { - return { - type: NodeType.VARIADIC, - value: operand, - meta: { syntax: VariadicTypeSyntax.SUFFIX_DOTS }, - }; - }, - peg$c161 = function() { - return { - type: NodeType.VARIADIC, - value: { type: NodeType.ANY }, - meta: { syntax: VariadicTypeSyntax.ONLY_DOTS }, - }; - }, - - peg$currPos = 0, - peg$posDetailsCache = [{ line: 1, column: 1 }], - peg$maxFailPos = 0, - peg$maxFailExpected = [], - peg$resultsCache = {}, - - peg$result; - - if ("startRule" in options) { - if (!(options.startRule in peg$startRuleFunctions)) { - throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); - } - - peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; - } - - function peg$literalExpectation(text, ignoreCase) { - return { type: "literal", text: text, ignoreCase: ignoreCase }; - } - - function peg$classExpectation(parts, inverted, ignoreCase) { - return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase }; - } - - function peg$anyExpectation() { - return { type: "any" }; - } - - function peg$endExpectation() { - return { type: "end" }; - } - - function peg$computePosDetails(pos) { - var details = peg$posDetailsCache[pos], p; - - if (details) { - return details; - } else { - p = pos - 1; - while (!peg$posDetailsCache[p]) { - p--; - } - - details = peg$posDetailsCache[p]; - details = { - line: details.line, - column: details.column - }; - - while (p < pos) { - if (input.charCodeAt(p) === 10) { - details.line++; - details.column = 1; - } else { - details.column++; - } - - p++; - } - - peg$posDetailsCache[pos] = details; - return details; - } - } - - function peg$computeLocation(startPos, endPos) { - var startPosDetails = peg$computePosDetails(startPos), - endPosDetails = peg$computePosDetails(endPos); - - return { - start: { - offset: startPos, - line: startPosDetails.line, - column: startPosDetails.column - }, - end: { - offset: endPos, - line: endPosDetails.line, - column: endPosDetails.column - } - }; - } - - function peg$fail(expected) { - if (peg$currPos < peg$maxFailPos) { return; } - - if (peg$currPos > peg$maxFailPos) { - peg$maxFailPos = peg$currPos; - peg$maxFailExpected = []; - } - - peg$maxFailExpected.push(expected); - } - - function peg$buildStructuredError(expected, found, location) { - return new peg$SyntaxError( - peg$SyntaxError.buildMessage(expected, found), - expected, - found, - location - ); - } - - function peg$parseTopTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 78 + 0, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parse_(); - if (s1 !== peg$FAILED) { - s2 = peg$parseVariadicTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseUnionTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseIntersectionTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseUnaryUnionTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseArrayTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseGenericTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseRecordTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseTupleTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseArrowTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseFunctionTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseTypeQueryExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseKeyQueryExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseNamepathExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseParenthesizedExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseValueExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseAnyTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - if (s3 !== peg$FAILED) { - s1 = peg$c0(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseWS() { - var s0, s1, s2; - - var key = peg$currPos * 78 + 1, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - if (peg$c1.test(input.charAt(peg$currPos))) { - s0 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s0 = peg$FAILED; - { peg$fail(peg$c2); } - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (peg$c3.test(input.charAt(peg$currPos))) { - s1 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c4); } - } - if (s1 === peg$FAILED) { - s1 = null; - } - if (s1 !== peg$FAILED) { - if (peg$c5.test(input.charAt(peg$currPos))) { - s2 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c6); } - } - if (s2 !== peg$FAILED) { - s1 = [s1, s2]; - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parse_() { - var s0, s1; - - var key = peg$currPos * 78 + 2, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = []; - s1 = peg$parseWS(); - while (s1 !== peg$FAILED) { - s0.push(s1); - s1 = peg$parseWS(); - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parse__() { - var s0, s1; - - var key = peg$currPos * 78 + 3, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = []; - s1 = peg$parseWS(); - if (s1 !== peg$FAILED) { - while (s1 !== peg$FAILED) { - s0.push(s1); - s1 = peg$parseWS(); - } - } else { - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseJsIdentifier() { - var s0, s1, s2, s3, s4; - - var key = peg$currPos * 78 + 4, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (peg$c7.test(input.charAt(peg$currPos))) { - s2 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c8); } - } - if (s2 !== peg$FAILED) { - s3 = []; - if (peg$c9.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c10); } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c9.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c10); } - } - } - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseNamepathExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - - var key = peg$currPos * 78 + 5, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseParenthesizedExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseImportTypeExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseTypeNameExprJsDocFlavored(); - } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseInfixNamepathOperator(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c11) { - s7 = peg$c11; - peg$currPos += 6; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c12); } - } - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - s9 = peg$parseMemberName(); - if (s9 !== peg$FAILED) { - s4 = [s4, s5, s6, s7, s8, s9]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseInfixNamepathOperator(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.substr(peg$currPos, 6) === peg$c11) { - s7 = peg$c11; - peg$currPos += 6; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c12); } - } - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - s9 = peg$parseMemberName(); - if (s9 !== peg$FAILED) { - s4 = [s4, s5, s6, s7, s8, s9]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s1 = peg$c13(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseTypeNameExprJsDocFlavored() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 78 + 6, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - s2 = peg$currPos; - if (peg$c7.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c8); } - } - if (s3 !== peg$FAILED) { - s4 = []; - if (peg$c14.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c15); } - } - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c14.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c15); } - } - } - if (s4 !== peg$FAILED) { - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - s1 = input.substring(s1, peg$currPos); - } else { - s1 = s2; - } - if (s1 !== peg$FAILED) { - s1 = peg$c16(s1); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseMemberName() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 78 + 7, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c17; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c17; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c24(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c25; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c25; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c29(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$parseJsIdentifier(); - if (s1 !== peg$FAILED) { - s1 = peg$c30(s1); - } - s0 = s1; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseInfixNamepathOperator() { - var s0; - - var key = peg$currPos * 78 + 8, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseMemberTypeOperator(); - if (s0 === peg$FAILED) { - s0 = peg$parseInstanceMemberTypeOperator(); - if (s0 === peg$FAILED) { - s0 = peg$parseInnerMemberTypeOperator(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseQualifiedMemberName() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 78 + 9, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseTypeNameExprJsDocFlavored(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 46) { - s5 = peg$c31; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c32); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseTypeNameExprJsDocFlavored(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 46) { - s5 = peg$c31; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c32); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseTypeNameExprJsDocFlavored(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s1 = peg$c33(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseMemberTypeOperator() { - var s0, s1; - - var key = peg$currPos * 78 + 10, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 46) { - s1 = peg$c31; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c32); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c34(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseInnerMemberTypeOperator() { - var s0, s1; - - var key = peg$currPos * 78 + 11, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 126) { - s1 = peg$c35; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c36); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c37(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseInstanceMemberTypeOperator() { - var s0, s1; - - var key = peg$currPos * 78 + 12, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 35) { - s1 = peg$c38; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c39); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c40(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseBroadNamepathExpr() { - var s0; - - var key = peg$currPos * 78 + 13, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseNamepathExpr(); - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseAnyTypeExpr() { - var s0, s1; - - var key = peg$currPos * 78 + 14, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 42) { - s1 = peg$c41; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c42); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c43(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseUnknownTypeExpr() { - var s0, s1; - - var key = peg$currPos * 78 + 15, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 63) { - s1 = peg$c44; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c45); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c46(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseValueExpr() { - var s0; - - var key = peg$currPos * 78 + 16, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseStringLiteralExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNumberLiteralExpr(); - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseStringLiteralExpr() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 78 + 17, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c25; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c25; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c47(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c17; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c17; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c48(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseNumberLiteralExpr() { - var s0, s1; - - var key = peg$currPos * 78 + 18, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseBinNumberLiteralExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseOctNumberLiteralExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseHexNumberLiteralExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseDecimalNumberLiteralExpr(); - } - } - } - if (s1 !== peg$FAILED) { - s1 = peg$c49(s1); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseDecimalNumberLiteralExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 78 + 19, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 43) { - s2 = peg$c50; - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c51); } - } - if (s2 === peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 45) { - s2 = peg$c52; - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c53); } - } - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - s3 = peg$parseUnsignedDecimalNumberLiteralExpr(); - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseUnsignedDecimalNumberLiteralExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 78 + 20, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - s2 = peg$currPos; - s3 = []; - if (peg$c54.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c55); } - } - if (s4 !== peg$FAILED) { - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c54.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c55); } - } - } - } else { - s3 = peg$FAILED; - } - if (s3 !== peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 46) { - s5 = peg$c31; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c32); } - } - if (s5 !== peg$FAILED) { - s6 = []; - if (peg$c54.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c55); } - } - if (s7 !== peg$FAILED) { - while (s7 !== peg$FAILED) { - s6.push(s7); - if (peg$c54.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c55); } - } - } - } else { - s6 = peg$FAILED; - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = null; - } - if (s4 !== peg$FAILED) { - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - if (s2 === peg$FAILED) { - s2 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 46) { - s3 = peg$c31; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c32); } - } - if (s3 !== peg$FAILED) { - s4 = []; - if (peg$c54.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c55); } - } - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c54.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c55); } - } - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s3 = [s3, s4]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s3 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 101) { - s4 = peg$c56; - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c57); } - } - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 43) { - s5 = peg$c50; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c51); } - } - if (s5 === peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 45) { - s5 = peg$c52; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c53); } - } - } - if (s5 === peg$FAILED) { - s5 = null; - } - if (s5 !== peg$FAILED) { - s6 = []; - if (peg$c54.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c55); } - } - if (s7 !== peg$FAILED) { - while (s7 !== peg$FAILED) { - s6.push(s7); - if (peg$c54.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c55); } - } - } - } else { - s6 = peg$FAILED; - } - if (s6 !== peg$FAILED) { - s4 = [s4, s5, s6]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = null; - } - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseBinNumberLiteralExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 78 + 21, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 45) { - s2 = peg$c52; - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c53); } - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c58) { - s3 = peg$c58; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c59); } - } - if (s3 !== peg$FAILED) { - s4 = []; - if (peg$c60.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c61); } - } - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c60.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c61); } - } - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s2 = [s2, s3, s4]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseOctNumberLiteralExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 78 + 22, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 45) { - s2 = peg$c52; - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c53); } - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c62) { - s3 = peg$c62; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c63); } - } - if (s3 !== peg$FAILED) { - s4 = []; - if (peg$c64.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c65); } - } - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c64.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c65); } - } - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s2 = [s2, s3, s4]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseHexNumberLiteralExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 78 + 23, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 45) { - s2 = peg$c52; - peg$currPos++; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c53); } - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c66) { - s3 = peg$c66; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c67); } - } - if (s3 !== peg$FAILED) { - s4 = []; - if (peg$c68.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c69); } - } - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c68.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c69); } - } - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s2 = [s2, s3, s4]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s0 = input.substring(s0, peg$currPos); - } else { - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseIntersectionTypeExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 78 + 24, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseIntersectionTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 38) { - s3 = peg$c70; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c71); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseIntersectionTypeExpr(); - if (s5 === peg$FAILED) { - s5 = peg$parseIntersectionTypeExprOperand(); - } - if (s5 !== peg$FAILED) { - s1 = peg$c72(s1, s5); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseIntersectionTypeExprOperand() { - var s0; - - var key = peg$currPos * 78 + 25, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseKeyQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseUnionTypeExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 78 + 26, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseUnionTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 124) { - s3 = peg$c73; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c74); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseUnionTypeExpr(); - if (s5 === peg$FAILED) { - s5 = peg$parseUnionTypeExprOperand(); - } - if (s5 !== peg$FAILED) { - s1 = peg$c75(s1, s5); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseUnionTypeExprOperand() { - var s0; - - var key = peg$currPos * 78 + 27, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseKeyQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseUnaryUnionTypeExpr() { - var s0; - - var key = peg$currPos * 78 + 28, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseSuffixUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parsePrefixUnaryUnionTypeExpr(); - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixUnaryUnionTypeExpr() { - var s0; - - var key = peg$currPos * 78 + 29, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parsePrefixOptionalTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parsePrefixNotNullableTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parsePrefixNullableTypeExpr(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixUnaryUnionTypeExprOperand() { - var s0; - - var key = peg$currPos * 78 + 30, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseTypeQueryExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 78 + 31, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c76) { - s1 = peg$c76; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c77); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseQualifiedMemberName(); - if (s3 !== peg$FAILED) { - s1 = peg$c78(s1, s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseKeyQueryExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 78 + 32, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 5) === peg$c79) { - s1 = peg$c79; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c80); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse__(); - if (s2 !== peg$FAILED) { - s3 = peg$parseKeyQueryExprOperand(); - if (s3 !== peg$FAILED) { - s1 = peg$c81(s1, s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.substr(peg$currPos, 5) === peg$c79) { - s1 = peg$c79; - peg$currPos += 5; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c80); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseParenthesizedExpr(); - if (s2 !== peg$FAILED) { - s1 = peg$c81(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseKeyQueryExprOperand() { - var s0; - - var key = peg$currPos * 78 + 33, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseIntersectionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseKeyQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseImportTypeExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 78 + 34, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 6) === peg$c82) { - s1 = peg$c82; - peg$currPos += 6; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c83); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 40) { - s3 = peg$c84; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c85); } - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseStringLiteralExpr(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s7 = peg$c86; - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c87); } - } - if (s7 !== peg$FAILED) { - s1 = peg$c88(s1, s5); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixNullableTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 78 + 35, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 63) { - s1 = peg$c44; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c45); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); - if (s3 !== peg$FAILED) { - s1 = peg$c89(s1, s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixNotNullableTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 78 + 36, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 33) { - s1 = peg$c90; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c91); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); - if (s3 !== peg$FAILED) { - s1 = peg$c92(s1, s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixOptionalTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 78 + 37, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 61) { - s1 = peg$c93; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c94); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parsePrefixUnaryUnionTypeExprOperand(); - if (s3 !== peg$FAILED) { - s1 = peg$c95(s1, s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixUnaryUnionTypeExpr() { - var s0; - - var key = peg$currPos * 78 + 38, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseSuffixOptionalTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseSuffixNullableTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseSuffixNotNullableTypeExpr(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixUnaryUnionTypeExprOperand() { - var s0; - - var key = peg$currPos * 78 + 39, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parsePrefixUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixNullableTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 78 + 40, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 63) { - s3 = peg$c44; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c45); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c96(s1); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixNotNullableTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 78 + 41, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 33) { - s3 = peg$c90; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c91); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c97(s1); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixOptionalTypeExpr() { - var s0, s1, s2, s3; - - var key = peg$currPos * 78 + 42, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseSuffixNullableTypeExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseSuffixNotNullableTypeExpr(); - if (s1 === peg$FAILED) { - s1 = peg$parseSuffixUnaryUnionTypeExprOperand(); - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 61) { - s3 = peg$c93; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c94); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c98(s1); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 78 + 43, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseGenericTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseGenericTypeStartToken(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$parseGenericTypeExprTypeParamList(); - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseGenericTypeEndToken(); - if (s7 !== peg$FAILED) { - s1 = peg$c99(s1, s3, s5); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeExprOperand() { - var s0; - - var key = peg$currPos * 78 + 44, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeExprTypeParamOperand() { - var s0; - - var key = peg$currPos * 78 + 45, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseIntersectionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseKeyQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeExprTypeParamList() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 78 + 46, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseGenericTypeExprTypeParamOperand(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c100; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c101); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseGenericTypeExprTypeParamOperand(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c100; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c101); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseGenericTypeExprTypeParamOperand(); - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s1 = peg$c102(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeStartToken() { - var s0; - - var key = peg$currPos * 78 + 47, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseGenericTypeEcmaScriptFlavoredStartToken(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeTypeScriptFlavoredStartToken(); - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeEcmaScriptFlavoredStartToken() { - var s0, s1; - - var key = peg$currPos * 78 + 48, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c103) { - s1 = peg$c103; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c104); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c105(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeTypeScriptFlavoredStartToken() { - var s0, s1; - - var key = peg$currPos * 78 + 49, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 60) { - s1 = peg$c106; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c107); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c108(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseGenericTypeEndToken() { - var s0; - - var key = peg$currPos * 78 + 50, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - if (input.charCodeAt(peg$currPos) === 62) { - s0 = peg$c109; - peg$currPos++; - } else { - s0 = peg$FAILED; - { peg$fail(peg$c110); } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseArrayTypeExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 78 + 51, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseArrayTypeExprOperand(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 91) { - s5 = peg$c111; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c112); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 93) { - s7 = peg$c113; - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c114); } - } - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 !== peg$FAILED) { - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 91) { - s5 = peg$c111; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c112); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 93) { - s7 = peg$c113; - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c114); } - } - if (s7 !== peg$FAILED) { - s4 = [s4, s5, s6, s7]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - } else { - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - s1 = peg$c115(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseArrayTypeExprOperand() { - var s0; - - var key = peg$currPos * 78 + 52, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseKeyQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseArrowTypeExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 78 + 53, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c116) { - s1 = peg$c116; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c117); } - } - if (s1 === peg$FAILED) { - s1 = null; - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseArrowTypeExprParamsList(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c118) { - s5 = peg$c118; - peg$currPos += 2; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c119); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseFunctionTypeExprReturnableOperand(); - if (s7 !== peg$FAILED) { - s1 = peg$c120(s1, s3, s7); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseArrowTypeExprParamsList() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 78 + 54, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c84; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c85); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s3 = peg$c86; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c87); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c121(); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c84; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c85); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseArrowTypeExprParams(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s5 = peg$c86; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c87); } - } - if (s5 !== peg$FAILED) { - s1 = peg$c122(s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseArrowTypeExprParams() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10; - - var key = peg$currPos * 78 + 55, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = []; - s2 = peg$currPos; - s3 = peg$parseJsIdentifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s5 = peg$c123; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c124); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseFunctionTypeExprParamOperand(); - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s9 = peg$c100; - peg$currPos++; - } else { - s9 = peg$FAILED; - { peg$fail(peg$c101); } - } - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - if (s10 !== peg$FAILED) { - s3 = [s3, s4, s5, s6, s7, s8, s9, s10]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = peg$currPos; - s3 = peg$parseJsIdentifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s5 = peg$c123; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c124); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseFunctionTypeExprParamOperand(); - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s9 = peg$c100; - peg$currPos++; - } else { - s9 = peg$FAILED; - { peg$fail(peg$c101); } - } - if (s9 !== peg$FAILED) { - s10 = peg$parse_(); - if (s10 !== peg$FAILED) { - s3 = [s3, s4, s5, s6, s7, s8, s9, s10]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseVariadicNameExpr(); - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - s1 = peg$c125(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseVariadicNameExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 78 + 56, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c126) { - s1 = peg$c126; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c127); } - } - if (s1 === peg$FAILED) { - s1 = null; - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseJsIdentifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s5 = peg$c123; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c124); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseFunctionTypeExprParamOperand(); - if (s7 === peg$FAILED) { - s7 = null; - } - if (s7 !== peg$FAILED) { - s1 = peg$c128(s1, s3, s7); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExpr() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8; - - var key = peg$currPos * 78 + 57, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c129) { - s1 = peg$c129; - peg$currPos += 8; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c130); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseFunctionTypeExprParamsList(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - s5 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 58) { - s6 = peg$c123; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c124); } - } - if (s6 !== peg$FAILED) { - s7 = peg$parse_(); - if (s7 !== peg$FAILED) { - s8 = peg$parseFunctionTypeExprReturnableOperand(); - if (s8 !== peg$FAILED) { - s6 = [s6, s7, s8]; - s5 = s6; - } else { - peg$currPos = s5; - s5 = peg$FAILED; - } - } else { - peg$currPos = s5; - s5 = peg$FAILED; - } - } else { - peg$currPos = s5; - s5 = peg$FAILED; - } - if (s5 === peg$FAILED) { - s5 = null; - } - if (s5 !== peg$FAILED) { - s1 = peg$c131(s3, s5); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExprParamsList() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - - var key = peg$currPos * 78 + 58, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c84; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c85); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseFunctionTypeExprModifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c100; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c101); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s7 = peg$parseFunctionTypeExprParams(); - if (s7 !== peg$FAILED) { - s8 = peg$parse_(); - if (s8 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s9 = peg$c86; - peg$currPos++; - } else { - s9 = peg$FAILED; - { peg$fail(peg$c87); } - } - if (s9 !== peg$FAILED) { - s1 = peg$c132(s3, s7); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c84; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c85); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseFunctionTypeExprModifier(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s5 = peg$c86; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c87); } - } - if (s5 !== peg$FAILED) { - s1 = peg$c133(s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c84; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c85); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s3 = peg$c86; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c87); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c134(); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c84; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c85); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseFunctionTypeExprParams(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s5 = peg$c86; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c87); } - } - if (s5 !== peg$FAILED) { - s1 = peg$c135(s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExprModifier() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 78 + 59, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.substr(peg$currPos, 4) === peg$c136) { - s2 = peg$c136; - peg$currPos += 4; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c137); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - if (s3 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s4 = peg$c123; - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c124); } - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - s6 = peg$parseFunctionTypeExprParamOperand(); - if (s6 !== peg$FAILED) { - s2 = [s2, s3, s4, s5, s6]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s1 = peg$c138(s1); - } - s0 = s1; - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c116) { - s2 = peg$c116; - peg$currPos += 3; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c117); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - if (s3 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s4 = peg$c123; - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c124); } - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - s6 = peg$parseFunctionTypeExprParamOperand(); - if (s6 !== peg$FAILED) { - s2 = [s2, s3, s4, s5, s6]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - s1 = peg$c139(s1); - } - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExprParams() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 78 + 60, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = []; - s2 = peg$currPos; - s3 = peg$parseFunctionTypeExprParamOperand(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c100; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c101); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s3 = [s3, s4, s5, s6]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = peg$currPos; - s3 = peg$parseFunctionTypeExprParamOperand(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c100; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c101); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s3 = [s3, s4, s5, s6]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseVariadicTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseVariadicTypeExprOperand(); - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - s1 = peg$c140(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExprParamOperand() { - var s0; - - var key = peg$currPos * 78 + 61, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseIntersectionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseKeyQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseFunctionTypeExprReturnableOperand() { - var s0; - - var key = peg$currPos * 78 + 62, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parsePrefixUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseKeyQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseRecordTypeExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 78 + 63, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 123) { - s1 = peg$c141; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c142); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseRecordTypeExprEntries(); - if (s3 === peg$FAILED) { - s3 = null; - } - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 125) { - s5 = peg$c143; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c144); } - } - if (s5 !== peg$FAILED) { - s1 = peg$c145(s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseRecordTypeExprEntries() { - var s0, s1, s2, s3, s4, s5, s6, s7; - - var key = peg$currPos * 78 + 64, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseRecordTypeExprEntry(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = peg$currPos; - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s6 = peg$c100; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c101); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 59) { - s6 = peg$c146; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c147); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - s5 = []; - if (peg$c1.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c2); } - } - while (s6 !== peg$FAILED) { - s5.push(s6); - if (peg$c1.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c2); } - } - } - if (s5 !== peg$FAILED) { - if (peg$c3.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c4); } - } - if (s6 === peg$FAILED) { - s6 = null; - } - if (s6 !== peg$FAILED) { - if (peg$c5.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c6); } - } - if (s7 !== peg$FAILED) { - s5 = [s5, s6, s7]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - s6 = peg$parseRecordTypeExprEntry(); - if (s6 !== peg$FAILED) { - s4 = [s4, s5, s6]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = peg$currPos; - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s6 = peg$c100; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c101); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 59) { - s6 = peg$c146; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c147); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - s5 = []; - if (peg$c1.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c2); } - } - while (s6 !== peg$FAILED) { - s5.push(s6); - if (peg$c1.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c2); } - } - } - if (s5 !== peg$FAILED) { - if (peg$c3.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c4); } - } - if (s6 === peg$FAILED) { - s6 = null; - } - if (s6 !== peg$FAILED) { - if (peg$c5.test(input.charAt(peg$currPos))) { - s7 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s7 = peg$FAILED; - { peg$fail(peg$c6); } - } - if (s7 !== peg$FAILED) { - s5 = [s5, s6, s7]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - s6 = peg$parseRecordTypeExprEntry(); - if (s6 !== peg$FAILED) { - s4 = [s4, s5, s6]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - if (s2 !== peg$FAILED) { - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c100; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c101); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = peg$currPos; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 59) { - s5 = peg$c146; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c147); } - } - if (s5 !== peg$FAILED) { - s4 = [s4, s5]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - if (s3 === peg$FAILED) { - s3 = peg$currPos; - s4 = []; - if (peg$c1.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c2); } - } - while (s5 !== peg$FAILED) { - s4.push(s5); - if (peg$c1.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c2); } - } - } - if (s4 !== peg$FAILED) { - if (peg$c3.test(input.charAt(peg$currPos))) { - s5 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c4); } - } - if (s5 === peg$FAILED) { - s5 = null; - } - if (s5 !== peg$FAILED) { - if (peg$c5.test(input.charAt(peg$currPos))) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c6); } - } - if (s6 !== peg$FAILED) { - s4 = [s4, s5, s6]; - s3 = s4; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - } - if (s3 === peg$FAILED) { - s3 = null; - } - if (s3 !== peg$FAILED) { - s1 = peg$c148(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseRecordTypeExprEntry() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8; - - var key = peg$currPos * 78 + 65, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c149) { - s2 = peg$c149; - peg$currPos += 8; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c150); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse__(); - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 === peg$FAILED) { - s1 = null; - } - if (s1 !== peg$FAILED) { - s2 = peg$parseRecordTypeExprEntryKey(); - if (s2 !== peg$FAILED) { - s3 = peg$parse_(); - if (s3 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 63) { - s4 = peg$c44; - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c45); } - } - if (s4 === peg$FAILED) { - s4 = null; - } - if (s4 !== peg$FAILED) { - s5 = peg$parse_(); - if (s5 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 58) { - s6 = peg$c123; - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c124); } - } - if (s6 !== peg$FAILED) { - s7 = peg$parse_(); - if (s7 !== peg$FAILED) { - s8 = peg$parseRecordTypeExprEntryOperand(); - if (s8 !== peg$FAILED) { - s1 = peg$c151(s1, s2, s4, s8); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$currPos; - if (input.substr(peg$currPos, 8) === peg$c149) { - s2 = peg$c149; - peg$currPos += 8; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c150); } - } - if (s2 !== peg$FAILED) { - s3 = peg$parse__(); - if (s3 !== peg$FAILED) { - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 === peg$FAILED) { - s1 = null; - } - if (s1 !== peg$FAILED) { - s2 = peg$parseRecordTypeExprEntryKey(); - if (s2 !== peg$FAILED) { - s1 = peg$c152(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseRecordTypeExprEntryKey() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 78 + 66, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s1 = peg$c25; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c27.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c28); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 34) { - s3 = peg$c25; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c26); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c153(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s1 = peg$c17; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s1 !== peg$FAILED) { - s2 = peg$currPos; - s3 = []; - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$c19.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - { peg$fail(peg$c20); } - } - if (s4 === peg$FAILED) { - s4 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 92) { - s5 = peg$c21; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c22); } - } - if (s5 !== peg$FAILED) { - if (input.length > peg$currPos) { - s6 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s6 = peg$FAILED; - { peg$fail(peg$c23); } - } - if (s6 !== peg$FAILED) { - s5 = [s5, s6]; - s4 = s5; - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } else { - peg$currPos = s4; - s4 = peg$FAILED; - } - } - } - if (s3 !== peg$FAILED) { - s2 = input.substring(s2, peg$currPos); - } else { - s2 = s3; - } - if (s2 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 39) { - s3 = peg$c17; - peg$currPos++; - } else { - s3 = peg$FAILED; - { peg$fail(peg$c18); } - } - if (s3 !== peg$FAILED) { - s1 = peg$c154(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$currPos; - s2 = peg$parseJsIdentifier(); - if (s2 === peg$FAILED) { - s2 = peg$parseUnsignedDecimalNumberLiteralExpr(); - } - if (s2 !== peg$FAILED) { - s1 = input.substring(s1, peg$currPos); - } else { - s1 = s2; - } - if (s1 !== peg$FAILED) { - s1 = peg$c155(s1); - } - s0 = s1; - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseRecordTypeExprEntryOperand() { - var s0; - - var key = peg$currPos * 78 + 67, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseIntersectionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseTupleTypeExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 78 + 68, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 91) { - s1 = peg$c111; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c112); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseTupleTypeExprEntries(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 93) { - s5 = peg$c113; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c114); } - } - if (s5 !== peg$FAILED) { - s1 = peg$c156(s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseTupleTypeExprEntries() { - var s0, s1, s2, s3, s4, s5, s6; - - var key = peg$currPos * 78 + 69, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = []; - s2 = peg$currPos; - s3 = peg$parseTupleTypeExprOperand(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c100; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c101); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s3 = [s3, s4, s5, s6]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = peg$currPos; - s3 = peg$parseTupleTypeExprOperand(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 44) { - s5 = peg$c100; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c101); } - } - if (s5 !== peg$FAILED) { - s6 = peg$parse_(); - if (s6 !== peg$FAILED) { - s3 = [s3, s4, s5, s6]; - s2 = s3; - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } else { - peg$currPos = s2; - s2 = peg$FAILED; - } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseVariadicTypeExpr(); - if (s2 === peg$FAILED) { - s2 = peg$parseVariadicTypeExprOperand(); - } - if (s2 === peg$FAILED) { - s2 = null; - } - if (s2 !== peg$FAILED) { - s1 = peg$c157(s1, s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseTupleTypeExprOperand() { - var s0; - - var key = peg$currPos * 78 + 70, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseIntersectionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseKeyQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseParenthesizedExpr() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 78 + 71, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 40) { - s1 = peg$c84; - peg$currPos++; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c85); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parse_(); - if (s2 !== peg$FAILED) { - s3 = peg$parseParenthesizedExprOperand(); - if (s3 !== peg$FAILED) { - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - if (input.charCodeAt(peg$currPos) === 41) { - s5 = peg$c86; - peg$currPos++; - } else { - s5 = peg$FAILED; - { peg$fail(peg$c87); } - } - if (s5 !== peg$FAILED) { - s1 = peg$c158(s3); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseParenthesizedExprOperand() { - var s0; - - var key = peg$currPos * 78 + 72, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseIntersectionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseKeyQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseVariadicTypeExpr() { - var s0; - - var key = peg$currPos * 78 + 73, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parsePrefixVariadicTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseSuffixVariadicTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyVariadicTypeExpr(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsePrefixVariadicTypeExpr() { - var s0, s1, s2; - - var key = peg$currPos * 78 + 74, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c126) { - s1 = peg$c126; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c127); } - } - if (s1 !== peg$FAILED) { - s2 = peg$parseVariadicTypeExprOperand(); - if (s2 !== peg$FAILED) { - s1 = peg$c159(s2); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseSuffixVariadicTypeExpr() { - var s0, s1, s2; - - var key = peg$currPos * 78 + 75, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parseVariadicTypeExprOperand(); - if (s1 !== peg$FAILED) { - if (input.substr(peg$currPos, 3) === peg$c126) { - s2 = peg$c126; - peg$currPos += 3; - } else { - s2 = peg$FAILED; - { peg$fail(peg$c127); } - } - if (s2 !== peg$FAILED) { - s1 = peg$c160(s1); - s0 = s1; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseAnyVariadicTypeExpr() { - var s0, s1; - - var key = peg$currPos * 78 + 76, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - if (input.substr(peg$currPos, 3) === peg$c126) { - s1 = peg$c126; - peg$currPos += 3; - } else { - s1 = peg$FAILED; - { peg$fail(peg$c127); } - } - if (s1 !== peg$FAILED) { - s1 = peg$c161(); - } - s0 = s1; - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseVariadicTypeExprOperand() { - var s0; - - var key = peg$currPos * 78 + 77, - cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseIntersectionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnaryUnionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseRecordTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTupleTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrowTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseFunctionTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseParenthesizedExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseTypeQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseKeyQueryExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseArrayTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseGenericTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseNamepathExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseValueExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseAnyTypeExpr(); - if (s0 === peg$FAILED) { - s0 = peg$parseUnknownTypeExpr(); - } - } - } - } - } - } - } - } - } - } - } - } - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - - const meta = SyntaxType; - const { - GenericTypeSyntax, - VariadicTypeSyntax, OptionalTypeSyntax, - NullableTypeSyntax, NotNullableTypeSyntax, - } = meta; - const NodeType = NodeType_1; - - const NamepathOperatorType = { - MEMBER: 'MEMBER', - INNER_MEMBER: 'INNER_MEMBER', - INSTANCE_MEMBER: 'INSTANCE_MEMBER', - }; - - - peg$result = peg$startRuleFunction(); - - if (peg$result !== peg$FAILED && peg$currPos === input.length) { - return peg$result; - } else { - if (peg$result !== peg$FAILED && peg$currPos < input.length) { - peg$fail(peg$endExpectation()); - } - - throw peg$buildStructuredError( - peg$maxFailExpected, - peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, - peg$maxFailPos < input.length - ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) - : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) - ); - } -} - -var jsdoctypeTypescript = { - SyntaxError: peg$SyntaxError, - parse: peg$parse -}; - -/** - * @typedef AstNode - * @property {string} type - * @property {'none'|'single'|'double'} [quoteStyle] - * @property {boolean} [readonly] - * @property {string} [key] - * @property {string} [name] - * @property {string} [number] - * @property {string} [path] - * @property {string} [string] - * @property {boolean} [hasEventPrefix] - * @property {boolean} [typeName] - * @property {Object} [meta] - * @property {AstNode} [returns] - * @property {AstNode} [new] - * @property {AstNode} [value] - * @property {AstNode} [left] - * @property {AstNode} [right] - * @property {AstNode} [owner] - * @property {AstNode} [subject] - * @property {AstNode} [this] - * @property {AstNode[]} [entries] - * @property {AstNode[]} [objects] - * @property {AstNode[]} [params] - */ - -const { - parse: parse$2, SyntaxError: JSDocTypeSyntaxError$1, -} = jsdoctypePermissive; - -const { - parse: parseJsdoc, SyntaxError: JSDocSyntaxError$1, -} = jsdoctypeJsdoc; -const { - parse: parseClosure, SyntaxError: ClosureSyntaxError$1, -} = jsdoctypeClosure; -const { - parse: parseTypeScript, SyntaxError: TypeScriptSyntaxError$1, -} = jsdoctypeTypescript; - -const {inspect} = util__default['default']; - -var parsing = { - - /** - * A class for JSDoc-like type expression syntax errors. - * @constructor - * @extends {Error} - */ - JSDocTypeSyntaxError: JSDocTypeSyntaxError$1, - - /** - * A class for JSDoc-specific type expression syntax errors. - * @constructor - * @extends {Error} - */ - JSDocSyntaxError: JSDocSyntaxError$1, - - /** - * A class for Closure type expression syntax errors. - * @constructor - * @extends {Error} - */ - ClosureSyntaxError: ClosureSyntaxError$1, - - /** - * A class for TypeScript type expression syntax errors. - * @constructor - * @extends {Error} - */ - TypeScriptSyntaxError: TypeScriptSyntaxError$1, - - /** - * @typedef {object} ParseOptions - * @property {"permissive"|"jsdoc"|"closure"|"typescript"} [mode='permissive'] - * @property {"TopTypeExpr"|"BroadNamepathExpr"|"NamepathExpr"|"ExternalNameExpr"|"ModuleNameExpr"} [startRule="TopTypeExpr"] - */ - - /** - * Parse the specified type expression string. - * @param {string} typeExprStr Type expression string. - * @param {ParseOptions} opts - * @return {AstNode} AST. - */ - parse (typeExprStr, {mode = 'permissive', startRule = 'TopTypeExpr'} = {}) { - switch (mode) { - case 'jsdoc': - return parseJsdoc(typeExprStr, {startRule}); - case 'closure': - return parseClosure(typeExprStr, {startRule}); - case 'typescript': - return parseTypeScript(typeExprStr, {startRule}); - case 'permissive': - return parse$2(typeExprStr, {startRule}); - default: - throw new TypeError('Unrecognized mode: ' + inspect(mode)); - } - }, -}; - -const {OPTIONAL, PARENTHESIS} = NodeType_1; -const {OptionalTypeSyntax, VariadicTypeSyntax} = SyntaxType; -const {format} = util__default['default']; - -/** @typedef {import('./parsing').AstNode} AstNode */ -/** @typedef {(node) => string} ConcretePublish */ -/** @typedef {{ [T in import('./NodeType').Type]: (node: AstNode, publish: ConcretePublish) => string }} Publisher */ - -/** - * @param {AstNode} node - * @param {Publisher} [opt_publisher] - * @return {string} - */ -function publish$1(node, opt_publisher) { - const publisher = opt_publisher || createDefaultPublisher$1(); - return publisher[node.type](node, function(childNode) { - return publish$1(childNode, publisher); - }); -} - -/** - * @private - * @param {string} str - * @param {'none'|'single'|'double'|undefined} quoteStyle - * @returns {string} Formatted string - */ -function addQuotesForName (str, quoteStyle) { - // For `MemberName`, not strings - if (!quoteStyle || quoteStyle === 'none') { - return str; - } - const singleQuoteStyle = quoteStyle === 'single'; - - return format( - singleQuoteStyle - ? "'%s'" - : '"%s"', - str - .replace(/\\/g, '\\\\') - .replace( - singleQuoteStyle ? /'/gu : /"/gu, - '\\' + (singleQuoteStyle ? "'" : '"') - ) - ); -} - -/** @return {Publisher} */ -function createDefaultPublisher$1() { - return { - NAME (nameNode) { - return nameNode.name; - }, - MEMBER (memberNode, concretePublish) { - return format('%s.%s%s', concretePublish(memberNode.owner), - memberNode.hasEventPrefix ? 'event:' : '', - addQuotesForName(memberNode.name, memberNode.quoteStyle)); - }, - UNION (unionNode, concretePublish) { - return format('%s | %s', concretePublish(unionNode.left), - concretePublish(unionNode.right)); - }, - INTERSECTION (unionNode, concretePublish) { - return format('%s & %s', concretePublish(unionNode.left), - concretePublish(unionNode.right)); - }, - VARIADIC (variadicNode, concretePublish) { - if (variadicNode.meta.syntax === VariadicTypeSyntax.ONLY_DOTS) { - return '...'; - } - return format('...%s', concretePublish(variadicNode.value)); - }, - RECORD (recordNode, concretePublish) { - const concretePublishedEntries = recordNode.entries.map(concretePublish); - return format('{%s}', concretePublishedEntries.join(', ')); - }, - RECORD_ENTRY (entryNode, concretePublish) { - const {readonly, value, key, quoteStyle} = entryNode; - const readonlyString = readonly ? 'readonly ' : ''; - if (!value) return readonlyString + addQuotesForName(key, quoteStyle); - const keySuffix = ( - value.type === OPTIONAL && - value.meta.syntax === OptionalTypeSyntax.SUFFIX_KEY_QUESTION_MARK - ) - ? '?' - : ''; - return format('%s%s%s: %s', readonlyString, addQuotesForName(key, quoteStyle), keySuffix, concretePublish(value)); - }, - TUPLE (tupleNode, concretePublish) { - const concretePublishedEntries = tupleNode.entries.map(concretePublish); - return format('[%s]', concretePublishedEntries.join(', ')); - }, - GENERIC (genericNode, concretePublish) { - const concretePublishedObjects = genericNode.objects.map(concretePublish); - switch (genericNode.meta.syntax) { - case 'SQUARE_BRACKET': - return format('%s[]', concretePublishedObjects.join(', ')); - case 'ANGLE_BRACKET_WITH_DOT': - return format('%s.<%s>', concretePublish(genericNode.subject), - concretePublishedObjects.join(', ')); - } - return format('%s<%s>', concretePublish(genericNode.subject), - concretePublishedObjects.join(', ')); - }, - MODULE (moduleNode, concretePublish) { - return format('module:%s', concretePublish(moduleNode.value)); - }, - FILE_PATH (filePathNode) { - return addQuotesForName(filePathNode.path, filePathNode.quoteStyle); - }, - OPTIONAL (optionalNode, concretePublish) { - if (optionalNode.meta.syntax === OptionalTypeSyntax.SUFFIX_KEY_QUESTION_MARK) { - return concretePublish(optionalNode.value); - } - return format('%s=', concretePublish(optionalNode.value)); - }, - NULLABLE (nullableNode, concretePublish) { - return format('?%s', concretePublish(nullableNode.value)); - }, - NOT_NULLABLE (notNullableNode, concretePublish) { - return format('!%s', concretePublish(notNullableNode.value)); - }, - FUNCTION (functionNode, concretePublish) { - const publidshedParams = functionNode.params.map(concretePublish); - - if (functionNode.new) { - publidshedParams.unshift(format('new: %s', - concretePublish(functionNode.new))); - } - - if (functionNode.this) { - publidshedParams.unshift(format('this: %s', - concretePublish(functionNode.this))); - } - - if (functionNode.returns) { - return format('function(%s): %s', publidshedParams.join(', '), - concretePublish(functionNode.returns)); - } - - return format('function(%s)', publidshedParams.join(', ')); - }, - ARROW (functionNode, concretePublish) { - const publishedParams = functionNode.params.map(concretePublish); - return (functionNode.new ? 'new ' : '') + format('(%s) => %s', publishedParams.join(', '), concretePublish(functionNode.returns)); - }, - NAMED_PARAMETER (parameterNode, concretePublish) { - return parameterNode.name + ': ' + concretePublish(parameterNode.typeName); - }, - ANY () { - return '*'; - }, - UNKNOWN () { - return '?'; - }, - INNER_MEMBER (memberNode, concretePublish) { - return concretePublish(memberNode.owner) + '~' + - (memberNode.hasEventPrefix ? 'event:' : '') + - addQuotesForName(memberNode.name, memberNode.quoteStyle); - }, - INSTANCE_MEMBER (memberNode, concretePublish) { - return concretePublish(memberNode.owner) + '#' + - (memberNode.hasEventPrefix ? 'event:' : '') + - addQuotesForName(memberNode.name, memberNode.quoteStyle); - }, - STRING_VALUE (stringValueNode) { - return addQuotesForName(stringValueNode.string, stringValueNode.quoteStyle) - }, - NUMBER_VALUE (numberValueNode) { - return numberValueNode.number; - }, - EXTERNAL (externalNode /* , concretePublish */) { - const {name, quoteStyle} = externalNode; - return format('external:%s', addQuotesForName(name, quoteStyle)); - }, - PARENTHESIS (parenthesizedNode, concretePublish) { - return format('(%s)', concretePublish(parenthesizedNode.value)); - }, - TYPE_QUERY (typeQueryNode, concretePublish) { - return format('typeof %s', concretePublish(typeQueryNode.name)); - }, - KEY_QUERY (keyQueryNode, concretePublish) { - if (keyQueryNode.value.type === PARENTHESIS) { - return format('keyof%s', concretePublish(keyQueryNode.value)); - } - return format('keyof %s', concretePublish(keyQueryNode.value)); - }, - IMPORT (importNode, concretePublish) { - return format('import(%s)', concretePublish(importNode.path)); - }, - }; -} - - -var publishing = { - publish: publish$1, - createDefaultPublisher: createDefaultPublisher$1, -}; - -/** @typedef {import('./NodeType').Type} NodeType */ -/** @typedef {{ type: NodeType }} Node */ -/** @typedef {(node: Node, parentPropName: string | null, parentNode: Node | null) => void} TraversalCallback */ - -/** - * Traverse the specified AST. - * @param {Node} node AST to traverse. - * @param {TraversalCallback} [opt_onEnter] Callback for onEnter. - * @param {TraversalCallback} [opt_onLeave] Callback for onLeave. - */ -function traverse$1(node, opt_onEnter, opt_onLeave) { - if (opt_onEnter) opt_onEnter(node, null, null); - - const childNodeInfo = _collectChildNodeInfo(node); - childNodeInfo.forEach(function([childNode, parentPropName, parentNode]) { - traverse$1(childNode, opt_onEnter ? (node, pn, pNode) => { - opt_onEnter(node, pn || parentPropName, pNode || parentNode); - } : null, opt_onLeave ? (node, pn, pNode) => { - opt_onLeave(node, pn || parentPropName, pNode || parentNode); - } : null); - }); - - if (opt_onLeave) opt_onLeave(node, null, null); -} - - -/** - * @private - */ -const _PropertyAccessor = { - NODE (fn, node, parentPropName, parentNode) { - fn(node, parentPropName, parentNode); - }, - NODE_LIST (fn, nodes, parentPropName, parentNode) { - nodes.forEach(function(node) { - fn(node, parentPropName, parentNode); - }); - }, - NULLABLE_NODE (fn, opt_node, parentPropName, parentNode) { - if (opt_node) fn(opt_node, parentPropName, parentNode); - }, -}; - - -/** - * @private - * @type {{ [T in NodeType]: object }} - */ -const _childNodesMap = { - NAME: {}, - NAMED_PARAMETER: { - typeName: _PropertyAccessor.NULLABLE_NODE, - }, - MEMBER: { - owner: _PropertyAccessor.NODE, - }, - UNION: { - left: _PropertyAccessor.NODE, - right: _PropertyAccessor.NODE, - }, - INTERSECTION: { - left: _PropertyAccessor.NODE, - right: _PropertyAccessor.NODE, - }, - VARIADIC: { - value: _PropertyAccessor.NODE, - }, - RECORD: { - entries: _PropertyAccessor.NODE_LIST, - }, - RECORD_ENTRY: { - value: _PropertyAccessor.NULLABLE_NODE, - }, - TUPLE: { - entries: _PropertyAccessor.NODE_LIST, - }, - GENERIC: { - subject: _PropertyAccessor.NODE, - objects: _PropertyAccessor.NODE_LIST, - }, - MODULE: { - value: _PropertyAccessor.NODE, - }, - OPTIONAL: { - value: _PropertyAccessor.NODE, - }, - NULLABLE: { - value: _PropertyAccessor.NODE, - }, - NOT_NULLABLE: { - value: _PropertyAccessor.NODE, - }, - FUNCTION: { - params: _PropertyAccessor.NODE_LIST, - returns: _PropertyAccessor.NULLABLE_NODE, - this: _PropertyAccessor.NULLABLE_NODE, - new: _PropertyAccessor.NULLABLE_NODE, - }, - ARROW: { - params: _PropertyAccessor.NODE_LIST, - returns: _PropertyAccessor.NULLABLE_NODE, - }, - ANY: {}, - UNKNOWN: {}, - INNER_MEMBER: { - owner: _PropertyAccessor.NODE, - }, - INSTANCE_MEMBER: { - owner: _PropertyAccessor.NODE, - }, - STRING_VALUE: {}, - NUMBER_VALUE: {}, - EXTERNAL: {}, - FILE_PATH: {}, - PARENTHESIS: { - value: _PropertyAccessor.NODE, - }, - TYPE_QUERY: { - name: _PropertyAccessor.NODE, - }, - KEY_QUERY: { - value: _PropertyAccessor.NODE, - }, - IMPORT: { - path: _PropertyAccessor.NODE, - }, -}; - - -/** - * @private - * @param {Node} node - */ -function _collectChildNodeInfo(node) { - const childNodeInfo = []; - const propAccessorMap = _childNodesMap[node.type]; - - Object.keys(propAccessorMap).forEach(function(propName) { - const propAccessor = propAccessorMap[propName]; - propAccessor((node, propName, parentNode) => { - childNodeInfo.push([node, propName, parentNode]); - }, node[propName], propName, node); - }); - - return childNodeInfo; -} - -var traversing = { - traverse: traverse$1, -}; - -/** @typedef {import('./lib/parsing').AstNode} AstNode */ - -const { - parse: parse$1, - JSDocTypeSyntaxError, - JSDocSyntaxError, - ClosureSyntaxError, - TypeScriptSyntaxError, -} = parsing; -const {publish, createDefaultPublisher} = publishing; -const {traverse} = traversing; - - - -/** - * Namespace for jsdoctypeparser. - * @namespace - * @exports jsdoctypeparser - */ -var jsdoctypeparser = { - parse: parse$1, - JSDocTypeSyntaxError, - JSDocSyntaxError, - ClosureSyntaxError, - TypeScriptSyntaxError, - publish, - createDefaultPublisher, - traverse, - NodeType: NodeType_1, - SyntaxType, -}; - -var checkTypes = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - - - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const strictNativeTypes = ['undefined', 'null', 'boolean', 'number', 'bigint', 'string', 'symbol', 'object', 'Array', 'Function', 'Date', 'RegExp']; - -const adjustNames = (type, preferred, isGenericMatch, nodeName, node, parentNode) => { - let ret = preferred; - - if (isGenericMatch) { - if (preferred === '[]') { - if (parentNode.objects[0].type === 'UNION') { - parentNode.objects[0] = { - type: 'PARENTHESIS', - value: parentNode.objects[0] - }; - } - - parentNode.meta.syntax = 'SQUARE_BRACKET'; - ret = 'Array'; - } else { - const dotBracketEnd = preferred.match(/\.(?:<>)?$/u); - - if (dotBracketEnd) { - parentNode.meta.syntax = 'ANGLE_BRACKET_WITH_DOT'; - ret = preferred.slice(0, -dotBracketEnd[0].length); - } else { - const bracketEnd = preferred.endsWith('<>'); - - if (bracketEnd) { - parentNode.meta.syntax = 'ANGLE_BRACKET'; - ret = preferred.slice(0, -2); - } else if (parentNode.meta.syntax === 'SQUARE_BRACKET' && (nodeName === '[]' || nodeName === 'Array')) { - parentNode.meta.syntax = 'ANGLE_BRACKET'; - } - } - } - } else if (type === 'ANY') { - node.type = 'NAME'; - } - - node.name = ret.replace(/(?:\.|<>|\.<>|\[\])$/u, ''); // For bare pseudo-types like `<>` - - if (!ret) { - node.name = nodeName; - } -}; - -var _default = (0, _iterateJsdoc.default)(({ - jsdocNode, - sourceCode, - report, - utils, - settings, - context -}) => { - const jsdocTagsWithPossibleType = utils.filterTags(tag => { - return utils.tagMightHaveTypePosition(tag.tag); - }); - const { - preferredTypes, - structuredTags, - mode - } = settings; - const { - noDefaults, - unifyParentAndChildTypeChecks, - exemptTagContexts = [] - } = context.options[0] || {}; - - const getPreferredTypeInfo = (_type, nodeName, parentName, parentNode) => { - let hasMatchingPreferredType; - let isGenericMatch; - let typeName = nodeName; - - if (Object.keys(preferredTypes).length) { - const parentType = parentName === 'subject'; - - if (unifyParentAndChildTypeChecks || parentType) { - var _parentNode$meta; - - const syntax = parentNode === null || parentNode === void 0 ? void 0 : (_parentNode$meta = parentNode.meta) === null || _parentNode$meta === void 0 ? void 0 : _parentNode$meta.syntax; - [['.', 'ANGLE_BRACKET_WITH_DOT'], ['.<>', 'ANGLE_BRACKET_WITH_DOT'], ['<>', 'ANGLE_BRACKET']].some(([checkPostFix, syn]) => { - isGenericMatch = (preferredTypes === null || preferredTypes === void 0 ? void 0 : preferredTypes[nodeName + checkPostFix]) !== undefined && syntax === syn; - - if (isGenericMatch) { - typeName += checkPostFix; - } - - return isGenericMatch; - }); - - if (!isGenericMatch && parentType) { - [['[]', 'SQUARE_BRACKET'], ['.', 'ANGLE_BRACKET_WITH_DOT'], ['.<>', 'ANGLE_BRACKET_WITH_DOT'], ['<>', 'ANGLE_BRACKET']].some(([checkPostFix, syn]) => { - isGenericMatch = (preferredTypes === null || preferredTypes === void 0 ? void 0 : preferredTypes[checkPostFix]) !== undefined && syntax === syn; - - if (isGenericMatch) { - typeName = checkPostFix; - } - - return isGenericMatch; - }); - } - } - - const directNameMatch = (preferredTypes === null || preferredTypes === void 0 ? void 0 : preferredTypes[nodeName]) !== undefined && !Object.values(preferredTypes).includes(nodeName); - const unifiedSyntaxParentMatch = parentType && directNameMatch && unifyParentAndChildTypeChecks; - isGenericMatch = isGenericMatch || unifiedSyntaxParentMatch; - hasMatchingPreferredType = isGenericMatch || directNameMatch && !parentType; - } - - return [hasMatchingPreferredType, typeName, isGenericMatch]; - }; - - jsdocTagsWithPossibleType.forEach(jsdocTag => { - const invalidTypes = []; - let typeAst; - - try { - typeAst = (0, jsdoctypeparser.parse)(jsdocTag.type, { - mode - }); - } catch { - return; - } - - const tagName = jsdocTag.tag; - (0, jsdoctypeparser.traverse)(typeAst, (node, parentName, parentNode) => { - const { - type, - name - } = node; - - if (!['NAME', 'ANY'].includes(type)) { - return; - } - - let nodeName = type === 'ANY' ? '*' : name; - const [hasMatchingPreferredType, typeName, isGenericMatch] = getPreferredTypeInfo(type, nodeName, parentName, parentNode); - let preferred; - let types; - - if (hasMatchingPreferredType) { - const preferredSetting = preferredTypes[typeName]; - nodeName = typeName === '[]' ? typeName : nodeName; - - if (!preferredSetting) { - invalidTypes.push([nodeName]); - } else if (typeof preferredSetting === 'string') { - preferred = preferredSetting; - invalidTypes.push([nodeName, preferred]); - } else if (typeof preferredSetting === 'object') { - preferred = preferredSetting === null || preferredSetting === void 0 ? void 0 : preferredSetting.replacement; - invalidTypes.push([nodeName, preferred, preferredSetting === null || preferredSetting === void 0 ? void 0 : preferredSetting.message]); - } else { - utils.reportSettings('Invalid `settings.jsdoc.preferredTypes`. Values must be falsy, a string, or an object.'); - return; - } - } else if (Object.entries(structuredTags).some(([tag, { - type: typs - }]) => { - types = typs; - return tag === tagName && Array.isArray(types) && !types.includes(nodeName); - })) { - invalidTypes.push([nodeName, types]); - } else if (!noDefaults && type === 'NAME') { - for (const strictNativeType of strictNativeTypes) { - if (strictNativeType === 'object' && mode === 'typescript') { - continue; - } - - if (strictNativeType.toLowerCase() === nodeName.toLowerCase() && strictNativeType !== nodeName && ( // Don't report if user has own map for a strict native type - !preferredTypes || (preferredTypes === null || preferredTypes === void 0 ? void 0 : preferredTypes[strictNativeType]) === undefined)) { - preferred = strictNativeType; - invalidTypes.push([nodeName, preferred]); - break; - } - } - } // For fixer - - - if (preferred) { - adjustNames(type, preferred, isGenericMatch, nodeName, node, parentNode); - } - }); - - if (invalidTypes.length) { - const fixedType = (0, jsdoctypeparser.publish)(typeAst); - invalidTypes.forEach(([badType, preferredType = '', message]) => { - const fix = fixer => { - return fixer.replaceText(jsdocNode, sourceCode.getText(jsdocNode).replace(`{${jsdocTag.type}}`, `{${fixedType}}`)); - }; - - const tagValue = jsdocTag.name ? ` "${jsdocTag.name}"` : ''; - - if (exemptTagContexts.some(({ - tag, - types - }) => { - return tag === tagName && (types === true || types.includes(jsdocTag.type)); - })) { - return; - } - - report(message || `Invalid JSDoc @${tagName}${tagValue} type "${badType}"` + (preferredType ? '; ' : '.') + (preferredType ? `prefer: ${JSON.stringify(preferredType)}.` : ''), preferredType ? fix : null, jsdocTag, message ? { - tagName, - tagValue - } : null); - }); - } - }); -}, { - iterateAllJsdocs: true, - meta: { - docs: { - description: 'Reports invalid types.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-types' - }, - fixable: 'code', - schema: [{ - additionalProperties: false, - properties: { - exemptTagContexts: { - items: { - additionalProperties: false, - properties: { - tag: { - type: 'string' - }, - types: { - oneOf: [{ - type: 'boolean' - }, { - items: { - type: 'string' - }, - type: 'array' - }] - } - }, - type: 'object' - }, - type: 'array' - }, - noDefaults: { - type: 'boolean' - }, - unifyParentAndChildTypeChecks: { - type: 'boolean' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=checkTypes.js.map -}); - -var require$$0 = [ - "0BSD", - "AAL", - "ADSL", - "AFL-1.1", - "AFL-1.2", - "AFL-2.0", - "AFL-2.1", - "AFL-3.0", - "AGPL-1.0-only", - "AGPL-1.0-or-later", - "AGPL-3.0-only", - "AGPL-3.0-or-later", - "AMDPLPA", - "AML", - "AMPAS", - "ANTLR-PD", - "ANTLR-PD-fallback", - "APAFML", - "APL-1.0", - "APSL-1.0", - "APSL-1.1", - "APSL-1.2", - "APSL-2.0", - "Abstyles", - "Adobe-2006", - "Adobe-Glyph", - "Afmparse", - "Aladdin", - "Apache-1.0", - "Apache-1.1", - "Apache-2.0", - "Artistic-1.0", - "Artistic-1.0-Perl", - "Artistic-1.0-cl8", - "Artistic-2.0", - "BSD-1-Clause", - "BSD-2-Clause", - "BSD-2-Clause-Patent", - "BSD-2-Clause-Views", - "BSD-3-Clause", - "BSD-3-Clause-Attribution", - "BSD-3-Clause-Clear", - "BSD-3-Clause-LBNL", - "BSD-3-Clause-No-Nuclear-License", - "BSD-3-Clause-No-Nuclear-License-2014", - "BSD-3-Clause-No-Nuclear-Warranty", - "BSD-3-Clause-Open-MPI", - "BSD-4-Clause", - "BSD-4-Clause-UC", - "BSD-Protection", - "BSD-Source-Code", - "BSL-1.0", - "BUSL-1.1", - "Bahyph", - "Barr", - "Beerware", - "BitTorrent-1.0", - "BitTorrent-1.1", - "BlueOak-1.0.0", - "Borceux", - "CAL-1.0", - "CAL-1.0-Combined-Work-Exception", - "CATOSL-1.1", - "CC-BY-1.0", - "CC-BY-2.0", - "CC-BY-2.5", - "CC-BY-3.0", - "CC-BY-3.0-AT", - "CC-BY-3.0-US", - "CC-BY-4.0", - "CC-BY-NC-1.0", - "CC-BY-NC-2.0", - "CC-BY-NC-2.5", - "CC-BY-NC-3.0", - "CC-BY-NC-4.0", - "CC-BY-NC-ND-1.0", - "CC-BY-NC-ND-2.0", - "CC-BY-NC-ND-2.5", - "CC-BY-NC-ND-3.0", - "CC-BY-NC-ND-3.0-IGO", - "CC-BY-NC-ND-4.0", - "CC-BY-NC-SA-1.0", - "CC-BY-NC-SA-2.0", - "CC-BY-NC-SA-2.5", - "CC-BY-NC-SA-3.0", - "CC-BY-NC-SA-4.0", - "CC-BY-ND-1.0", - "CC-BY-ND-2.0", - "CC-BY-ND-2.5", - "CC-BY-ND-3.0", - "CC-BY-ND-4.0", - "CC-BY-SA-1.0", - "CC-BY-SA-2.0", - "CC-BY-SA-2.0-UK", - "CC-BY-SA-2.5", - "CC-BY-SA-3.0", - "CC-BY-SA-3.0-AT", - "CC-BY-SA-4.0", - "CC-PDDC", - "CC0-1.0", - "CDDL-1.0", - "CDDL-1.1", - "CDLA-Permissive-1.0", - "CDLA-Sharing-1.0", - "CECILL-1.0", - "CECILL-1.1", - "CECILL-2.0", - "CECILL-2.1", - "CECILL-B", - "CECILL-C", - "CERN-OHL-1.1", - "CERN-OHL-1.2", - "CERN-OHL-P-2.0", - "CERN-OHL-S-2.0", - "CERN-OHL-W-2.0", - "CNRI-Jython", - "CNRI-Python", - "CNRI-Python-GPL-Compatible", - "CPAL-1.0", - "CPL-1.0", - "CPOL-1.02", - "CUA-OPL-1.0", - "Caldera", - "ClArtistic", - "Condor-1.1", - "Crossword", - "CrystalStacker", - "Cube", - "D-FSL-1.0", - "DOC", - "DSDP", - "Dotseqn", - "ECL-1.0", - "ECL-2.0", - "EFL-1.0", - "EFL-2.0", - "EPICS", - "EPL-1.0", - "EPL-2.0", - "EUDatagrid", - "EUPL-1.0", - "EUPL-1.1", - "EUPL-1.2", - "Entessa", - "ErlPL-1.1", - "Eurosym", - "FSFAP", - "FSFUL", - "FSFULLR", - "FTL", - "Fair", - "Frameworx-1.0", - "FreeImage", - "GFDL-1.1-invariants-only", - "GFDL-1.1-invariants-or-later", - "GFDL-1.1-no-invariants-only", - "GFDL-1.1-no-invariants-or-later", - "GFDL-1.1-only", - "GFDL-1.1-or-later", - "GFDL-1.2-invariants-only", - "GFDL-1.2-invariants-or-later", - "GFDL-1.2-no-invariants-only", - "GFDL-1.2-no-invariants-or-later", - "GFDL-1.2-only", - "GFDL-1.2-or-later", - "GFDL-1.3-invariants-only", - "GFDL-1.3-invariants-or-later", - "GFDL-1.3-no-invariants-only", - "GFDL-1.3-no-invariants-or-later", - "GFDL-1.3-only", - "GFDL-1.3-or-later", - "GL2PS", - "GLWTPL", - "GPL-1.0-only", - "GPL-1.0-or-later", - "GPL-2.0-only", - "GPL-2.0-or-later", - "GPL-3.0-only", - "GPL-3.0-or-later", - "Giftware", - "Glide", - "Glulxe", - "HPND", - "HPND-sell-variant", - "HTMLTIDY", - "HaskellReport", - "Hippocratic-2.1", - "IBM-pibs", - "ICU", - "IJG", - "IPA", - "IPL-1.0", - "ISC", - "ImageMagick", - "Imlib2", - "Info-ZIP", - "Intel", - "Intel-ACPI", - "Interbase-1.0", - "JPNIC", - "JSON", - "JasPer-2.0", - "LAL-1.2", - "LAL-1.3", - "LGPL-2.0-only", - "LGPL-2.0-or-later", - "LGPL-2.1-only", - "LGPL-2.1-or-later", - "LGPL-3.0-only", - "LGPL-3.0-or-later", - "LGPLLR", - "LPL-1.0", - "LPL-1.02", - "LPPL-1.0", - "LPPL-1.1", - "LPPL-1.2", - "LPPL-1.3a", - "LPPL-1.3c", - "Latex2e", - "Leptonica", - "LiLiQ-P-1.1", - "LiLiQ-R-1.1", - "LiLiQ-Rplus-1.1", - "Libpng", - "Linux-OpenIB", - "MIT", - "MIT-0", - "MIT-CMU", - "MIT-advertising", - "MIT-enna", - "MIT-feh", - "MIT-open-group", - "MITNFA", - "MPL-1.0", - "MPL-1.1", - "MPL-2.0", - "MPL-2.0-no-copyleft-exception", - "MS-PL", - "MS-RL", - "MTLL", - "MakeIndex", - "MirOS", - "Motosoto", - "MulanPSL-1.0", - "MulanPSL-2.0", - "Multics", - "Mup", - "NASA-1.3", - "NBPL-1.0", - "NCGL-UK-2.0", - "NCSA", - "NGPL", - "NIST-PD", - "NIST-PD-fallback", - "NLOD-1.0", - "NLPL", - "NOSL", - "NPL-1.0", - "NPL-1.1", - "NPOSL-3.0", - "NRL", - "NTP", - "NTP-0", - "Naumen", - "Net-SNMP", - "NetCDF", - "Newsletr", - "Nokia", - "Noweb", - "O-UDA-1.0", - "OCCT-PL", - "OCLC-2.0", - "ODC-By-1.0", - "ODbL-1.0", - "OFL-1.0", - "OFL-1.0-RFN", - "OFL-1.0-no-RFN", - "OFL-1.1", - "OFL-1.1-RFN", - "OFL-1.1-no-RFN", - "OGC-1.0", - "OGL-Canada-2.0", - "OGL-UK-1.0", - "OGL-UK-2.0", - "OGL-UK-3.0", - "OGTSL", - "OLDAP-1.1", - "OLDAP-1.2", - "OLDAP-1.3", - "OLDAP-1.4", - "OLDAP-2.0", - "OLDAP-2.0.1", - "OLDAP-2.1", - "OLDAP-2.2", - "OLDAP-2.2.1", - "OLDAP-2.2.2", - "OLDAP-2.3", - "OLDAP-2.4", - "OLDAP-2.5", - "OLDAP-2.6", - "OLDAP-2.7", - "OLDAP-2.8", - "OML", - "OPL-1.0", - "OSET-PL-2.1", - "OSL-1.0", - "OSL-1.1", - "OSL-2.0", - "OSL-2.1", - "OSL-3.0", - "OpenSSL", - "PDDL-1.0", - "PHP-3.0", - "PHP-3.01", - "PSF-2.0", - "Parity-6.0.0", - "Parity-7.0.0", - "Plexus", - "PolyForm-Noncommercial-1.0.0", - "PolyForm-Small-Business-1.0.0", - "PostgreSQL", - "Python-2.0", - "QPL-1.0", - "Qhull", - "RHeCos-1.1", - "RPL-1.1", - "RPL-1.5", - "RPSL-1.0", - "RSA-MD", - "RSCPL", - "Rdisc", - "Ruby", - "SAX-PD", - "SCEA", - "SGI-B-1.0", - "SGI-B-1.1", - "SGI-B-2.0", - "SHL-0.5", - "SHL-0.51", - "SISSL", - "SISSL-1.2", - "SMLNJ", - "SMPPL", - "SNIA", - "SPL-1.0", - "SSH-OpenSSH", - "SSH-short", - "SSPL-1.0", - "SWL", - "Saxpath", - "Sendmail", - "Sendmail-8.23", - "SimPL-2.0", - "Sleepycat", - "Spencer-86", - "Spencer-94", - "Spencer-99", - "SugarCRM-1.1.3", - "TAPR-OHL-1.0", - "TCL", - "TCP-wrappers", - "TMate", - "TORQUE-1.1", - "TOSL", - "TU-Berlin-1.0", - "TU-Berlin-2.0", - "UCL-1.0", - "UPL-1.0", - "Unicode-DFS-2015", - "Unicode-DFS-2016", - "Unicode-TOU", - "Unlicense", - "VOSTROM", - "VSL-1.0", - "Vim", - "W3C", - "W3C-19980720", - "W3C-20150513", - "WTFPL", - "Watcom-1.0", - "Wsuipa", - "X11", - "XFree86-1.1", - "XSkat", - "Xerox", - "Xnet", - "YPL-1.0", - "YPL-1.1", - "ZPL-1.1", - "ZPL-2.0", - "ZPL-2.1", - "Zed", - "Zend-2.0", - "Zimbra-1.3", - "Zimbra-1.4", - "Zlib", - "blessing", - "bzip2-1.0.5", - "bzip2-1.0.6", - "copyleft-next-0.3.0", - "copyleft-next-0.3.1", - "curl", - "diffmark", - "dvipdfm", - "eGenix", - "etalab-2.0", - "gSOAP-1.3b", - "gnuplot", - "iMatix", - "libpng-2.0", - "libselinux-1.0", - "libtiff", - "mpich2", - "psfrag", - "psutils", - "xinetd", - "xpp", - "zlib-acknowledgement" -]; - -var require$$1 = [ - "AGPL-1.0", - "AGPL-3.0", - "BSD-2-Clause-FreeBSD", - "BSD-2-Clause-NetBSD", - "GFDL-1.1", - "GFDL-1.2", - "GFDL-1.3", - "GPL-1.0", - "GPL-2.0", - "GPL-2.0-with-GCC-exception", - "GPL-2.0-with-autoconf-exception", - "GPL-2.0-with-bison-exception", - "GPL-2.0-with-classpath-exception", - "GPL-2.0-with-font-exception", - "GPL-3.0", - "GPL-3.0-with-GCC-exception", - "GPL-3.0-with-autoconf-exception", - "LGPL-2.0", - "LGPL-2.1", - "LGPL-3.0", - "Nunit", - "StandardML-NJ", - "eCos-2.0", - "wxWindows" -]; - -var exceptions = [ - "389-exception", - "Autoconf-exception-2.0", - "Autoconf-exception-3.0", - "Bison-exception-2.2", - "Bootloader-exception", - "Classpath-exception-2.0", - "CLISP-exception-2.0", - "DigiRule-FOSS-exception", - "eCos-exception-2.0", - "Fawkes-Runtime-exception", - "FLTK-exception", - "Font-exception-2.0", - "freertos-exception-2.0", - "GCC-exception-2.0", - "GCC-exception-3.1", - "gnu-javamail-exception", - "GPL-3.0-linking-exception", - "GPL-3.0-linking-source-exception", - "GPL-CC-1.0", - "i2p-gpl-java-exception", - "Libtool-exception", - "Linux-syscall-note", - "LLVM-exception", - "LZMA-exception", - "mif-exception", - "Nokia-Qt-exception-1.1", - "OCaml-LGPL-linking-exception", - "OCCT-exception-1.0", - "OpenJDK-assembly-exception-1.0", - "openvpn-openssl-exception", - "PS-or-PDF-font-exception-20170817", - "Qt-GPL-exception-1.0", - "Qt-LGPL-exception-1.1", - "Qwt-exception-1.0", - "Swift-exception", - "u-boot-exception-2.0", - "Universal-FOSS-exception-1.0", - "WxWindows-exception-3.1" -]; - -var licenses = [] - .concat(require$$0) - .concat(require$$1); - - -var scan = function (source) { - var index = 0; - - function hasMore () { - return index < source.length - } - - // `value` can be a regexp or a string. - // If it is recognized, the matching source string is returned and - // the index is incremented. Otherwise `undefined` is returned. - function read (value) { - if (value instanceof RegExp) { - var chars = source.slice(index); - var match = chars.match(value); - if (match) { - index += match[0].length; - return match[0] - } - } else { - if (source.indexOf(value, index) === index) { - index += value.length; - return value - } - } - } - - function skipWhitespace () { - read(/[ ]*/); - } - - function operator () { - var string; - var possibilities = ['WITH', 'AND', 'OR', '(', ')', ':', '+']; - for (var i = 0; i < possibilities.length; i++) { - string = read(possibilities[i]); - if (string) { - break - } - } - - if (string === '+' && index > 1 && source[index - 2] === ' ') { - throw new Error('Space before `+`') - } - - return string && { - type: 'OPERATOR', - string: string - } - } - - function idstring () { - return read(/[A-Za-z0-9-.]+/) - } - - function expectIdstring () { - var string = idstring(); - if (!string) { - throw new Error('Expected idstring at offset ' + index) - } - return string - } - - function documentRef () { - if (read('DocumentRef-')) { - var string = expectIdstring(); - return { type: 'DOCUMENTREF', string: string } - } - } - - function licenseRef () { - if (read('LicenseRef-')) { - var string = expectIdstring(); - return { type: 'LICENSEREF', string: string } - } - } - - function identifier () { - var begin = index; - var string = idstring(); - - if (licenses.indexOf(string) !== -1) { - return { - type: 'LICENSE', - string: string - } - } else if (exceptions.indexOf(string) !== -1) { - return { - type: 'EXCEPTION', - string: string - } - } - - index = begin; - } - - // Tries to read the next token. Returns `undefined` if no token is - // recognized. - function parseToken () { - // Ordering matters - return ( - operator() || - documentRef() || - licenseRef() || - identifier() - ) - } - - var tokens = []; - while (hasMore()) { - skipWhitespace(); - if (!hasMore()) { - break - } - - var token = parseToken(); - if (!token) { - throw new Error('Unexpected `' + source[index] + - '` at offset ' + index) - } - - tokens.push(token); - } - return tokens -}; - -// The ABNF grammar in the spec is totally ambiguous. -// -// This parser follows the operator precedence defined in the -// `Order of Precedence and Parentheses` section. - -var parse = function (tokens) { - var index = 0; - - function hasMore () { - return index < tokens.length - } - - function token () { - return hasMore() ? tokens[index] : null - } - - function next () { - if (!hasMore()) { - throw new Error() - } - index++; - } - - function parseOperator (operator) { - var t = token(); - if (t && t.type === 'OPERATOR' && operator === t.string) { - next(); - return t.string - } - } - - function parseWith () { - if (parseOperator('WITH')) { - var t = token(); - if (t && t.type === 'EXCEPTION') { - next(); - return t.string - } - throw new Error('Expected exception after `WITH`') - } - } - - function parseLicenseRef () { - // TODO: Actually, everything is concatenated into one string - // for backward-compatibility but it could be better to return - // a nice structure. - var begin = index; - var string = ''; - var t = token(); - if (t.type === 'DOCUMENTREF') { - next(); - string += 'DocumentRef-' + t.string + ':'; - if (!parseOperator(':')) { - throw new Error('Expected `:` after `DocumentRef-...`') - } - } - t = token(); - if (t.type === 'LICENSEREF') { - next(); - string += 'LicenseRef-' + t.string; - return { license: string } - } - index = begin; - } - - function parseLicense () { - var t = token(); - if (t && t.type === 'LICENSE') { - next(); - var node = { license: t.string }; - if (parseOperator('+')) { - node.plus = true; - } - var exception = parseWith(); - if (exception) { - node.exception = exception; - } - return node - } - } - - function parseParenthesizedExpression () { - var left = parseOperator('('); - if (!left) { - return - } - - var expr = parseExpression(); - - if (!parseOperator(')')) { - throw new Error('Expected `)`') - } - - return expr - } - - function parseAtom () { - return ( - parseParenthesizedExpression() || - parseLicenseRef() || - parseLicense() - ) - } - - function makeBinaryOpParser (operator, nextParser) { - return function parseBinaryOp () { - var left = nextParser(); - if (!left) { - return - } - - if (!parseOperator(operator)) { - return left - } - - var right = parseBinaryOp(); - if (!right) { - throw new Error('Expected expression') - } - return { - left: left, - conjunction: operator.toLowerCase(), - right: right - } - } - } - - var parseAnd = makeBinaryOpParser('AND', parseAtom); - var parseExpression = makeBinaryOpParser('OR', parseAnd); - - var node = parseExpression(); - if (!node || hasMore()) { - throw new Error('Syntax error') - } - return node -}; - -var spdxExpressionParse = function (source) { - return parse(scan(source)) -}; - -var checkValues = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _semver = _interopRequireDefault(require$$0__default$2['default']); - -var _spdxExpressionParse = _interopRequireDefault(spdxExpressionParse); - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var _default = (0, _iterateJsdoc.default)(({ - utils, - report, - context -}) => { - const options = context.options[0] || {}; - const { - allowedLicenses = null, - allowedAuthors = null, - licensePattern = '/([^\n]*)/gu' - } = options; - utils.forEachPreferredTag('version', (jsdocParameter, targetTagName) => { - const version = jsdocParameter.description.trim(); - - if (!version) { - report(`Missing JSDoc @${targetTagName}.`, null, jsdocParameter); - } else if (!_semver.default.valid(version)) { - report(`Invalid JSDoc @${targetTagName}: "${jsdocParameter.description}".`, null, jsdocParameter); - } - }); - utils.forEachPreferredTag('since', (jsdocParameter, targetTagName) => { - const version = jsdocParameter.description.trim(); - - if (!version) { - report(`Missing JSDoc @${targetTagName}.`, null, jsdocParameter); - } else if (!_semver.default.valid(version)) { - report(`Invalid JSDoc @${targetTagName}: "${jsdocParameter.description}".`, null, jsdocParameter); - } - }); - utils.forEachPreferredTag('license', (jsdocParameter, targetTagName) => { - const licenseRegex = utils.getRegexFromString(licensePattern, 'g'); - const match = jsdocParameter.description.match(licenseRegex); - const license = match && match[1] || match[0]; - - if (!license.trim()) { - report(`Missing JSDoc @${targetTagName}.`, null, jsdocParameter); - } else if (allowedLicenses) { - if (allowedLicenses !== true && !allowedLicenses.includes(license)) { - report(`Invalid JSDoc @${targetTagName}: "${license}"; expected one of ${allowedLicenses.join(', ')}.`, null, jsdocParameter); - } - } else { - try { - (0, _spdxExpressionParse.default)(license); - } catch { - report(`Invalid JSDoc @${targetTagName}: "${license}"; expected SPDX expression: https://spdx.org/licenses/.`, null, jsdocParameter); - } - } - }); - utils.forEachPreferredTag('author', (jsdocParameter, targetTagName) => { - const author = jsdocParameter.description.trim(); - - if (!author) { - report(`Missing JSDoc @${targetTagName}.`, null, jsdocParameter); - } else if (allowedAuthors && !allowedAuthors.includes(author)) { - report(`Invalid JSDoc @${targetTagName}: "${jsdocParameter.description}"; expected one of ${allowedAuthors.join(', ')}.`, null, jsdocParameter); - } - }); -}, { - iterateAllJsdocs: true, - meta: { - docs: { - description: 'This rule checks the values for a handful of tags: `@version`, `@since`, `@license` and `@author`.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-values' - }, - schema: [{ - additionalProperties: false, - properties: { - allowedAuthors: { - items: { - type: 'string' - }, - type: 'array' - }, - allowedLicenses: { - anyOf: [{ - items: { - type: 'string' - }, - type: 'array' - }, { - type: 'boolean' - }] - }, - licensePattern: { - type: 'string' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=checkValues.js.map -}); - -var emptyTags = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const defaultEmptyTags = new Set(['abstract', 'async', 'generator', 'global', 'hideconstructor', 'ignore', 'inner', 'instance', 'override', 'readonly', // jsdoc doesn't use this form in its docs, but allow for compatibility with -// TypeScript which allows and Closure which requires -'inheritDoc', // jsdoc doesn't use but allow for TypeScript -'internal']); -const emptyIfNotClosure = new Set(['package', 'private', 'protected', 'public', 'static', // Closure doesn't allow with this casing -'inheritdoc']); - -var _default = (0, _iterateJsdoc.default)(({ - settings, - jsdoc, - utils -}) => { - const emptyTags = utils.filterTags(({ - tag: tagName - }) => { - return defaultEmptyTags.has(tagName) || utils.hasOptionTag(tagName) && jsdoc.tags.some(({ - tag - }) => { - return tag === tagName; - }) || settings.mode !== 'closure' && emptyIfNotClosure.has(tagName); - }); - emptyTags.forEach(tag => { - const content = tag.name || tag.description || tag.type; - - if (content.trim()) { - const fix = () => { - utils.setTag(tag); - }; - - utils.reportJSDoc(`@${tag.tag} should be empty.`, tag, fix, true); - } - }); -}, { - checkInternal: true, - checkPrivate: true, - iterateAllJsdocs: true, - meta: { - docs: { - description: 'Expects specific tags to be empty of any content.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-empty-tags' - }, - fixable: 'code', - schema: [{ - additionalProperties: false, - properties: { - tags: { - items: { - type: 'string' - }, - type: 'array' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=emptyTags.js.map -}); - -var implementsOnClasses = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var _default = (0, _iterateJsdoc.default)(({ - report, - utils -}) => { - const iteratingFunction = utils.isIteratingFunction(); - - if (iteratingFunction) { - if (utils.hasATag(['class', 'constructor']) || utils.isConstructor()) { - return; - } - } else if (!utils.isVirtualFunction()) { - return; - } - - utils.forEachPreferredTag('implements', tag => { - report('@implements used on a non-constructor function', null, tag); - }); -}, { - contextDefaults: true, - meta: { - docs: { - description: 'Reports an issue with any non-constructor function using `@implements`.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-implements-on-classes' - }, - schema: [{ - additionalProperties: false, - properties: { - contexts: { - items: { - type: 'string' - }, - type: 'array' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=implementsOnClasses.js.map -}); - -var matchDescription = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _lodash = _interopRequireDefault(lodash__default['default']); - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -// If supporting Node >= 10, we could loosen the default to this for the -// initial letter: \\p{Upper} -const matchDescriptionDefault = '^[A-Z`\\d_][\\s\\S]*[.?!`]$'; - -const stringOrDefault = (value, userDefault) => { - return typeof value === 'string' ? value : userDefault || matchDescriptionDefault; -}; - -var _default = (0, _iterateJsdoc.default)(({ - jsdoc, - report, - context, - utils -}) => { - const options = context.options[0] || {}; - - const validateDescription = (description, tag) => { - if (!tag && options.mainDescription === false) { - return; - } - - let tagValue = options.mainDescription; - - if (tag) { - const tagName = tag.tag; - tagValue = options.tags[tagName]; - } - - const regex = utils.getRegexFromString(stringOrDefault(tagValue, options.matchDescription)); - - if (!regex.test(description)) { - report('JSDoc description does not satisfy the regex pattern.', null, tag || { - // Add one as description would typically be into block - line: jsdoc.source[0].number + 1 - }); - } - }; - - if (jsdoc.description) { - const { - description - } = utils.getDescription(); - validateDescription(description.replace(/\s+$/, '')); - } - - if (!options.tags || !Object.keys(options.tags).length) { - return; - } - - const hasOptionTag = tagName => { - return Boolean(options.tags[tagName]); - }; - - utils.forEachPreferredTag('description', (matchingJsdocTag, targetTagName) => { - const description = (matchingJsdocTag.name + ' ' + matchingJsdocTag.description).trim(); - - if (hasOptionTag(targetTagName)) { - validateDescription(description, matchingJsdocTag); - } - }, true); - const whitelistedTags = utils.filterTags(({ - tag: tagName - }) => { - return hasOptionTag(tagName); - }); - const { - tagsWithNames, - tagsWithoutNames - } = utils.getTagsByType(whitelistedTags); - tagsWithNames.some(tag => { - const description = _lodash.default.trimStart(tag.description, '- '); - - return validateDescription(description, tag); - }); - tagsWithoutNames.some(tag => { - const description = (tag.name + ' ' + tag.description).trim(); - return validateDescription(description, tag); - }); -}, { - contextDefaults: true, - meta: { - docs: { - description: 'Enforces a regular expression pattern on descriptions.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-match-description' - }, - schema: [{ - additionalProperties: false, - properties: { - contexts: { - items: { - type: 'string' - }, - type: 'array' - }, - mainDescription: { - oneOf: [{ - format: 'regex', - type: 'string' - }, { - type: 'boolean' - }] - }, - matchDescription: { - format: 'regex', - type: 'string' - }, - tags: { - patternProperties: { - '.*': { - oneOf: [{ - format: 'regex', - type: 'string' - }, { - enum: [true], - type: 'boolean' - }] - } - }, - type: 'object' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=matchDescription.js.map -}); - -var newlineAfterDescription = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _lodash = _interopRequireDefault(lodash__default['default']); - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var _default = (0, _iterateJsdoc.default)(({ - jsdoc, - report, - context, - jsdocNode, - sourceCode, - indent, - utils -}) => { - let always; - - if (!jsdoc.description.trim() || !jsdoc.tags.length) { - return; - } - - if (_lodash.default.has(context.options, 0)) { - always = context.options[0] === 'always'; - } else { - always = true; - } - - const { - description, - lastDescriptionLine - } = utils.getDescription(); - const descriptionEndsWithANewline = /\n\r?$/.test(description); - - if (always) { - if (!descriptionEndsWithANewline) { - const sourceLines = sourceCode.getText(jsdocNode).split('\n'); - report('There must be a newline after the description of the JSDoc block.', fixer => { - // Add the new line - const injectedLine = `${indent} *` + (sourceLines[lastDescriptionLine].endsWith('\r') ? '\r' : ''); - sourceLines.splice(lastDescriptionLine + 1, 0, injectedLine); - return fixer.replaceText(jsdocNode, sourceLines.join('\n')); - }, { - line: lastDescriptionLine - }); - } - } else if (descriptionEndsWithANewline) { - const sourceLines = sourceCode.getText(jsdocNode).split('\n'); - report('There must be no newline after the description of the JSDoc block.', fixer => { - // Remove the extra line - sourceLines.splice(lastDescriptionLine, 1); - return fixer.replaceText(jsdocNode, sourceLines.join('\n')); - }, { - line: lastDescriptionLine - }); - } -}, { - iterateAllJsdocs: true, - meta: { - docs: { - description: 'Enforces a consistent padding of the block description.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-newline-after-description' - }, - fixable: 'whitespace', - schema: [{ - enum: ['always', 'never'], - type: 'string' - }], - type: 'layout' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=newlineAfterDescription.js.map -}); - -var noBadBlocks = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - - - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const commentRegexp = /^\/\*(?!\*)/; - -var _default = (0, _iterateJsdoc.default)(({ - context, - sourceCode, - allComments, - makeReport -}) => { - const [{ - ignore = ['ts-check', 'ts-expect-error', 'ts-ignore', 'ts-nocheck'] - } = {}] = context.options; - const nonJsdocNodes = allComments.filter(comment => { - const commentText = sourceCode.getText(comment); - - if (!commentRegexp.test(commentText)) { - return false; - } - - const [{ - tags = {} - } = {}] = (0, lib.parse)(`${commentText.slice(0, 2)}*${commentText.slice(2)}`); - return tags.length && !tags.some(({ - tag - }) => { - return ignore.includes(tag); - }); - }); - - if (!nonJsdocNodes.length) { - return; - } - - nonJsdocNodes.forEach(node => { - const report = makeReport(context, node); - - const fix = fixer => { - const text = sourceCode.getText(node); - return fixer.replaceText(node, text.replace('/*', '/**')); - }; - - report('Expected JSDoc-like comment to begin with two asterisks.', fix); - }); -}, { - checkFile: true, - meta: { - docs: { - description: 'This rule checks for multi-line-style comments which fail to meet the criteria of a jsdoc block.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-no-bad-blocks' - }, - fixable: 'code', - schema: [{ - additionalProperties: false, - properties: { - ignore: { - items: { - type: 'string' - }, - type: 'array' - } - }, - type: 'object' - }], - type: 'layout' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=noBadBlocks.js.map -}); - -var noDefaults = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var _default = (0, _iterateJsdoc.default)(({ - context, - utils -}) => { - const { - noOptionalParamNames - } = context.options[0] || {}; - const paramTags = utils.getPresentTags(['param', 'arg', 'argument']); - paramTags.forEach(tag => { - if (noOptionalParamNames && tag.optional) { - utils.reportJSDoc(`Optional param names are not permitted on @${tag.tag}.`, tag, () => { - utils.changeTag(tag, { - name: tag.name.replace(/([^=]*)(=.+)?/, '$1') - }); - }); - } else if (tag.default) { - utils.reportJSDoc(`Defaults are not permitted on @${tag.tag}.`, tag, () => { - utils.changeTag(tag, { - name: tag.name.replace(/([^=]*)(=.+)?/, '[$1]') - }); - }); - } - }); - const defaultTags = utils.getPresentTags(['default', 'defaultvalue']); - defaultTags.forEach(tag => { - if (tag.description.trim()) { - utils.reportJSDoc(`Default values are not permitted on @${tag.tag}.`, tag, () => { - utils.changeTag(tag, { - description: '', - postTag: '' - }); - }); - } - }); -}, { - contextDefaults: true, - meta: { - docs: { - description: 'This rule reports defaults being used on the relevant portion of `@param` or `@default`.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-no-defaults' - }, - fixable: 'code', - schema: [{ - additionalProperties: false, - properties: { - contexts: { - items: { - type: 'string' - }, - type: 'array' - }, - noOptionalParamNames: { - type: 'boolean' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=noDefaults.js.map -}); - -var noTypes = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const removeType = ({ - tokens -}) => { - tokens.postTag = ''; - tokens.type = ''; -}; - -var _default = (0, _iterateJsdoc.default)(({ - utils -}) => { - if (!utils.isIteratingFunction() && !utils.isVirtualFunction()) { - return; - } - - const tags = utils.getPresentTags(['param', 'arg', 'argument', 'returns', 'return']); - tags.forEach(tag => { - if (tag.type) { - utils.reportJSDoc(`Types are not permitted on @${tag.tag}.`, tag, () => { - tag.source.forEach(removeType); - }); - } - }); -}, { - contextDefaults: true, - meta: { - docs: { - description: 'This rule reports types being used on `@param` or `@returns`.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-no-types' - }, - fixable: 'code', - schema: [{ - additionalProperties: false, - properties: { - contexts: { - items: { - type: 'string' - }, - type: 'array' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=noTypes.js.map -}); - -var noUndefinedTypes = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - - - -var _lodash = _interopRequireDefault(lodash__default['default']); - - - -var _iterateJsdoc = _interopRequireWildcard(iterateJsdoc_1); - -var _jsdocUtils = _interopRequireDefault(jsdocUtils); - -function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; } - -function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const extraTypes = ['null', 'undefined', 'void', 'string', 'boolean', 'object', 'function', 'symbol', 'number', 'bigint', 'NaN', 'Infinity', 'any', '*', 'this', 'true', 'false', 'Array', 'Object', 'RegExp', 'Date', 'Function']; - -const stripPseudoTypes = str => { - return str && str.replace(/(?:\.|<>|\.<>|\[\])$/u, ''); -}; - -var _default = (0, _iterateJsdoc.default)(({ - context, - node, - report, - settings, - sourceCode, - utils -}) => { - var _globalScope$childSco; - - const { - scopeManager - } = sourceCode; - const { - globalScope - } = scopeManager; - const { - definedTypes = [] - } = context.options[0] || {}; - let definedPreferredTypes = []; - const { - preferredTypes, - structuredTags, - mode - } = settings; - - if (Object.keys(preferredTypes).length) { - definedPreferredTypes = Object.values(preferredTypes).map(preferredType => { - if (typeof preferredType === 'string') { - // May become an empty string but will be filtered out below - return stripPseudoTypes(preferredType); - } - - if (!preferredType) { - return undefined; - } - - if (typeof preferredType !== 'object') { - utils.reportSettings('Invalid `settings.jsdoc.preferredTypes`. Values must be falsy, a string, or an object.'); - } - - return stripPseudoTypes(preferredType.replacement); - }).filter(preferredType => { - return preferredType; - }); - } - - const typedefDeclarations = (0, _lodash.default)(context.getAllComments()).filter(comment => { - return comment.value.startsWith('*'); - }).map(commentNode => { - return (0, _iterateJsdoc.parseComment)(commentNode, ''); - }).flatMap(doc => { - return doc.tags.filter(({ - tag - }) => { - return utils.isNamepathDefiningTag(tag); - }); - }).map(tag => { - return tag.name; - }).value(); - const ancestorNodes = []; - let currentScope = scopeManager.acquire(node); - - while (currentScope && currentScope.block.type !== 'Program') { - ancestorNodes.push(currentScope.block); - currentScope = currentScope.upper; - } // `currentScope` may be `null` or `Program`, so in such a case, - // we look to present tags instead - - - let templateTags = ancestorNodes.length ? (0, _lodash.default)(ancestorNodes).flatMap(ancestorNode => { - const commentNode = (0, getJSDocComment_1.getJSDocComment)(sourceCode, ancestorNode, settings); - - if (!commentNode) { - return []; - } - - const jsdoc = (0, _iterateJsdoc.parseComment)(commentNode, ''); - return _jsdocUtils.default.filterTags(jsdoc.tags, tag => { - return 'template' === tag.tag; - }); - }).value() : utils.getPresentTags('template'); - const classJsdoc = utils.getClassJsdoc(); - - if (classJsdoc !== null && classJsdoc !== void 0 && classJsdoc.tags) { - templateTags = templateTags.concat(classJsdoc.tags.filter(({ - tag - }) => { - return tag === 'template'; - })); - } - - const closureGenericTypes = _lodash.default.flatMap(templateTags, tag => { - return utils.parseClosureTemplateTag(tag); - }); // In modules, including Node, there is a global scope at top with the - // Program scope inside - - - const cjsOrESMScope = ((_globalScope$childSco = globalScope.childScopes[0]) === null || _globalScope$childSco === void 0 ? void 0 : _globalScope$childSco.block.type) === 'Program'; - const allDefinedTypes = new Set(globalScope.variables.map(({ - name - }) => { - return name; - }) // If the file is a module, concat the variables from the module scope. - .concat(cjsOrESMScope ? _lodash.default.flatMap(globalScope.childScopes, ({ - variables - }) => { - return variables; - }, []).map(({ - name - }) => { - return name; - }) : []).concat(extraTypes).concat(typedefDeclarations).concat(definedTypes).concat(definedPreferredTypes).concat(settings.mode === 'jsdoc' ? [] : closureGenericTypes)); - const jsdocTagsWithPossibleType = utils.filterTags(({ - tag - }) => { - return utils.tagMightHaveTypePosition(tag); - }); - jsdocTagsWithPossibleType.forEach(tag => { - let parsedType; - - try { - parsedType = (0, jsdoctypeparser.parse)(tag.type, { - mode - }); - } catch { - // On syntax error, will be handled by valid-types. - return; - } - - (0, jsdoctypeparser.traverse)(parsedType, ({ - type, - name - }) => { - if (type === 'NAME') { - var _structuredTags$tag$t; - - const structuredTypes = (_structuredTags$tag$t = structuredTags[tag.tag]) === null || _structuredTags$tag$t === void 0 ? void 0 : _structuredTags$tag$t.type; - - if (!allDefinedTypes.has(name) && (!Array.isArray(structuredTypes) || !structuredTypes.includes(name))) { - report(`The type '${name}' is undefined.`, null, tag); - } else if (!extraTypes.includes(name)) { - context.markVariableAsUsed(name); - } - } - }); - }); -}, { - iterateAllJsdocs: true, - meta: { - docs: { - description: 'Checks that types in jsdoc comments are defined.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-no-undefined-types' - }, - schema: [{ - additionalProperties: false, - properties: { - definedTypes: { - items: { - type: 'string' - }, - type: 'array' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=noUndefinedTypes.js.map -}); - -var requireDescription = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _lodash = _interopRequireDefault(lodash__default['default']); - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var _default = (0, _iterateJsdoc.default)(({ - jsdoc, - report, - utils, - context -}) => { - if (utils.avoidDocs()) { - return; - } - - const { - descriptionStyle = 'body' - } = context.options[0] || {}; - let targetTagName = utils.getPreferredTagName({ - // We skip reporting except when `@description` is essential to the rule, - // so user can block the tag and still meaningfully use this rule - // even if the tag is present (and `check-tag-names` is the one to - // normally report the fact that it is blocked but present) - skipReportingBlockedTag: descriptionStyle !== 'tag', - tagName: 'description' - }); - - if (!targetTagName) { - return; - } - - const isBlocked = typeof targetTagName === 'object' && targetTagName.blocked; - - if (isBlocked) { - targetTagName = targetTagName.tagName; - } - - const checkDescription = description => { - const exampleContent = _lodash.default.compact(description.trim().split('\n')); - - return exampleContent.length; - }; - - if (descriptionStyle !== 'tag') { - const { - description - } = utils.getDescription(); - - if (checkDescription(description || '')) { - return; - } - - if (descriptionStyle === 'body') { - const descTags = utils.getPresentTags(['desc', 'description']); - - if (descTags.length) { - const [{ - tag: tagName - }] = descTags; - report(`Remove the @${tagName} tag to leave a plain block description or add additional description text above the @${tagName} line.`); - } else { - report('Missing JSDoc block description.'); - } - - return; - } - } - - const functionExamples = isBlocked ? [] : _lodash.default.filter(jsdoc.tags, { - tag: targetTagName - }); - - if (!functionExamples.length) { - report(descriptionStyle === 'any' ? `Missing JSDoc block description or @${targetTagName} declaration.` : `Missing JSDoc @${targetTagName} declaration.`); - return; - } - - functionExamples.forEach(example => { - if (!checkDescription(`${example.name} ${example.description}`)) { - report(`Missing JSDoc @${targetTagName} description.`); - } - }); -}, { - contextDefaults: true, - meta: { - docs: { - description: 'Requires that all functions have a description.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-description' - }, - schema: [{ - additionalProperties: false, - properties: { - checkConstructors: { - default: true, - type: 'boolean' - }, - checkGetters: { - default: true, - type: 'boolean' - }, - checkSetters: { - default: true, - type: 'boolean' - }, - contexts: { - items: { - type: 'string' - }, - type: 'array' - }, - descriptionStyle: { - enum: ['body', 'tag', 'any'], - type: 'string' - }, - exemptedBy: { - items: { - type: 'string' - }, - type: 'array' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requireDescription.js.map -}); - -var mainUmd = createCommonjsModule(function (module, exports) { -(function (global, factory) { - factory(exports) ; -}(commonjsGlobal, (function (exports) { - function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } - } - - function _defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } - } - - function _createClass(Constructor, protoProps, staticProps) { - if (protoProps) _defineProperties(Constructor.prototype, protoProps); - if (staticProps) _defineProperties(Constructor, staticProps); - return Constructor; - } - - function _setPrototypeOf(o, p) { - _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { - o.__proto__ = p; - return o; - }; - - return _setPrototypeOf(o, p); - } - - function _isNativeReflectConstruct() { - if (typeof Reflect === "undefined" || !Reflect.construct) return false; - if (Reflect.construct.sham) return false; - if (typeof Proxy === "function") return true; - - try { - Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); - return true; - } catch (e) { - return false; - } - } - - function _construct(Parent, args, Class) { - if (_isNativeReflectConstruct()) { - _construct = Reflect.construct; - } else { - _construct = function _construct(Parent, args, Class) { - var a = [null]; - a.push.apply(a, args); - var Constructor = Function.bind.apply(Parent, a); - var instance = new Constructor(); - if (Class) _setPrototypeOf(instance, Class.prototype); - return instance; - }; - } - - return _construct.apply(null, arguments); - } - - /* eslint-disable node/no-unsupported-features/es-syntax */ - - /** - * @param {RegExp} regex - * @param {string} newFlags - * @param {Integer} [newLastIndex=regex.lastIndex] - * @returns {RegExp} - */ - function mixinRegex(regex, newFlags) { - var newLastIndex = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : regex.lastIndex; - newFlags = newFlags || ''; - regex = new RegExp(regex.source, (newFlags.includes('g') ? 'g' : regex.global ? 'g' : '') + (newFlags.includes('i') ? 'i' : regex.ignoreCase ? 'i' : '') + (newFlags.includes('m') ? 'm' : regex.multiline ? 'm' : '') + (newFlags.includes('u') ? 'u' : regex.unicode ? 'u' : '') + (newFlags.includes('y') ? 'y' : regex.sticky ? 'y' : '') + (newFlags.includes('s') ? 's' : regex.dotAll ? 's' : '')); - regex.lastIndex = newLastIndex; - return regex; - } - - exports.RegExtras = /*#__PURE__*/function () { - function RegExtras(regex, flags, newLastIndex) { - _classCallCheck(this, RegExtras); - - this.regex = mixinRegex(typeof regex === 'string' ? new RegExp(regex) : mixinRegex(regex), flags || '', newLastIndex); - } - - _createClass(RegExtras, [{ - key: "forEach", - value: function forEach(str, cb) { - var thisObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; - var regex = mixinRegex(this.regex, 'g'); - var matches, - n0, - i = 0; - - while ((matches = regex.exec(str)) !== null) { - n0 = matches.splice(0, 1); - cb.apply(thisObj, matches.concat(i++, n0)); - } - - return this; - } - }, { - key: "some", - value: function some(str, cb) { - var thisObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; - var regex = mixinRegex(this.regex, 'g'); - var matches, - ret, - n0, - i = 0; - - while ((matches = regex.exec(str)) !== null) { - n0 = matches.splice(0, 1); - ret = cb.apply(thisObj, matches.concat(i++, n0)); - - if (ret) { - return true; - } - } - - return false; - } - }, { - key: "every", - value: function every(str, cb) { - var thisObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; - var regex = mixinRegex(this.regex, 'g'); - var matches, - ret, - n0, - i = 0; - - while ((matches = regex.exec(str)) !== null) { - n0 = matches.splice(0, 1); - ret = cb.apply(thisObj, matches.concat(i++, n0)); - - if (!ret) { - return false; - } - } - - return true; - } - }, { - key: "map", - value: function map(str, cb) { - var thisObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; - var ret = []; - var regex = mixinRegex(this.regex, 'g'); - var matches, - n0, - i = 0; - - while ((matches = regex.exec(str)) !== null) { - n0 = matches.splice(0, 1); - ret.push(cb.apply(thisObj, matches.concat(i++, n0))); - } - - return ret; - } - }, { - key: "filter", - value: function filter(str, cb) { - var thisObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; - var matches, - n0, - i = 0; - var ret = [], - regex = mixinRegex(this.regex, 'g'); - - while ((matches = regex.exec(str)) !== null) { - n0 = matches.splice(0, 1); - matches = matches.concat(i++, n0); - - if (cb.apply(thisObj, matches)) { - ret.push(n0[0]); - } - } - - return ret; - } - }, { - key: "reduce", - value: function reduce(str, cb, prev) { - var thisObj = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : null; - var matches, - n0, - i = 0; - var regex = mixinRegex(this.regex, 'g'); - - if (!prev) { - if ((matches = regex.exec(str)) !== null) { - n0 = matches.splice(0, 1); - prev = cb.apply(thisObj, [''].concat(matches.concat(i++, n0))); - } - } - - while ((matches = regex.exec(str)) !== null) { - n0 = matches.splice(0, 1); - prev = cb.apply(thisObj, [prev].concat(matches.concat(i++, n0))); - } - - return prev; - } - }, { - key: "reduceRight", - value: function reduceRight(str, cb, prevOrig, thisObjOrig) { - var matches, - n0, - i, - thisObj = thisObjOrig, - prev = prevOrig; - var matchesContainer = [], - regex = mixinRegex(this.regex, 'g'); - thisObj = thisObj || null; - - while ((matches = regex.exec(str)) !== null) { - matchesContainer.push(matches); - } - - i = matchesContainer.length; - - if (!i) { - if (arguments.length < 3) { - throw new TypeError('reduce of empty matches array with no initial value'); - } - - return prev; - } - - if (!prev) { - matches = matchesContainer.splice(-1)[0]; - n0 = matches.splice(0, 1); - prev = cb.apply(thisObj, [''].concat(matches.concat(i--, n0))); - } - - matchesContainer.reduceRight(function (container, mtches) { - n0 = mtches.splice(0, 1); - prev = cb.apply(thisObj, [prev].concat(mtches.concat(i--, n0))); - return container; - }, matchesContainer); - return prev; - } - }, { - key: "find", - value: function find(str, cb) { - var thisObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; - var matches, - ret, - n0, - i = 0; - var regex = mixinRegex(this.regex, 'g'); - - while ((matches = regex.exec(str)) !== null) { - n0 = matches.splice(0, 1); - ret = cb.apply(thisObj, matches.concat(i++, n0)); - - if (ret) { - return n0[0]; - } - } - - return false; - } - }, { - key: "findIndex", - value: function findIndex(str, cb) { - var thisObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; - var regex = mixinRegex(this.regex, 'g'); - var matches, - i = 0; - - while ((matches = regex.exec(str)) !== null) { - var n0 = matches.splice(0, 1); - var ret = cb.apply(thisObj, matches.concat(i++, n0)); - - if (ret) { - return i - 1; - } - } - - return -1; - } - }, { - key: "findExec", - value: function findExec(str, cb) { - var thisObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; - var regex = mixinRegex(this.regex, 'g'); - var matches, - i = 0; - - while ((matches = regex.exec(str)) !== null) { - var n0 = matches.splice(0, 1); - var ret = cb.apply(thisObj, matches.concat(i++, n0)); - - if (ret) { - return matches; - } - } - - return false; - } - }, { - key: "filterExec", - value: function filterExec(str, cb) { - var thisObj = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; - var matches, - n0, - i = 0; - var ret = [], - regex = mixinRegex(this.regex, 'g'); - - while ((matches = regex.exec(str)) !== null) { - n0 = matches.splice(0, 1); - matches.push(i++, n0[0]); - - if (cb.apply(thisObj, matches)) { - ret.push(matches); - } - } - - return ret; - } - }]); - - return RegExtras; - }(); - - var _RegExtras = exports.RegExtras; - - exports.RegExtras = function RegExtras() { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - // eslint-disable-line no-class-assign - return _construct(_RegExtras, args); - }; - - exports.RegExtras.prototype = _RegExtras.prototype; - exports.RegExtras.mixinRegex = mixinRegex; - - exports.mixinRegex = mixinRegex; - - Object.defineProperty(exports, '__esModule', { value: true }); - -}))); -}); - -var requireDescriptionCompleteSentence = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _lodash = _interopRequireDefault(lodash__default['default']); - - - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const otherDescriptiveTags = new Set([// 'copyright' and 'see' might be good addition, but as the former may be -// sensitive text, and the latter may have just a link, they are not -// included by default -'summary', 'file', 'fileoverview', 'overview', 'classdesc', 'todo', 'deprecated', 'throws', 'exception', 'yields', 'yield']); - -const extractParagraphs = text => { - return text.split(/(? { - const txt = text // Remove all {} tags. - .replace(/\{[\s\S]*?\}\s*/gu, '') // Remove custom abbreviations - .replace(abbreviationsRegex, ''); - const sentenceEndGrouping = /([.?!])(?:\s+|$)/u; - const puncts = (0, mainUmd.RegExtras)(sentenceEndGrouping).map(txt, punct => { - return punct; - }); - return txt.split(/[.?!](?:\s+|$)/u) // Re-add the dot. - .map((sentence, idx) => { - return /^\s*$/u.test(sentence) ? sentence : `${sentence}${puncts[idx] || ''}`; - }); -}; - -const isNewLinePrecededByAPeriod = text => { - let lastLineEndsSentence; - const lines = text.split('\n'); - return !lines.some(line => { - if (lastLineEndsSentence === false && /^[A-Z][a-z]/u.test(line)) { - return true; - } - - lastLineEndsSentence = /[.:?!|]$/u.test(line); - return false; - }); -}; - -const isCapitalized = str => { - return str[0] === str[0].toUpperCase(); -}; - -const isTable = str => { - return str.charAt() === '|'; -}; - -const capitalize = str => { - return str.charAt(0).toUpperCase() + str.slice(1); -}; - -const validateDescription = (description, reportOrig, jsdocNode, abbreviationsRegex, sourceCode, tag, newlineBeforeCapsAssumesBadSentenceEnd) => { - if (!description) { - return false; - } - - const paragraphs = extractParagraphs(description); - return paragraphs.some((paragraph, parIdx) => { - const sentences = extractSentences(paragraph, abbreviationsRegex); - - const fix = fixer => { - let text = sourceCode.getText(jsdocNode); - - if (!/[.:?!]$/u.test(paragraph)) { - const line = paragraph.split('\n').pop(); - text = text.replace(new RegExp(`${_lodash.default.escapeRegExp(line)}$`, 'mu'), `${line}.`); - } - - for (const sentence of sentences.filter(sentence_ => { - return !/^\s*$/u.test(sentence_) && !isCapitalized(sentence_) && !isTable(sentence_); - })) { - const beginning = sentence.split('\n')[0]; - - if (tag.tag) { - const reg = new RegExp(`(@${_lodash.default.escapeRegExp(tag.tag)}.*)${_lodash.default.escapeRegExp(beginning)}`, 'u'); - text = text.replace(reg, (_$0, $1) => { - return $1 + capitalize(beginning); - }); - } else { - text = text.replace(new RegExp('((?:[.!?]|\\*|\\})\\s*)' + _lodash.default.escapeRegExp(beginning), 'u'), '$1' + capitalize(beginning)); - } - } - - return fixer.replaceText(jsdocNode, text); - }; - - const report = (msg, fixer, tagObj) => { - if ('line' in tagObj) { - tagObj.line += parIdx * 2; - } else { - tagObj.source[0].number += parIdx * 2; - } // Avoid errors if old column doesn't exist here - - - tagObj.column = 0; - reportOrig(msg, fixer, tagObj); - }; - - if (sentences.some(sentence => { - return !/^\s*$/u.test(sentence) && !isCapitalized(sentence) && !isTable(sentence); - })) { - report('Sentence should start with an uppercase character.', fix, tag); - } - - const paragraphNoAbbreviations = paragraph.replace(abbreviationsRegex, ''); - - if (!/[.!?|]\s*$/u.test(paragraphNoAbbreviations)) { - report('Sentence must end with a period.', fix, tag); - return true; - } - - if (newlineBeforeCapsAssumesBadSentenceEnd && !isNewLinePrecededByAPeriod(paragraphNoAbbreviations)) { - report('A line of text is started with an uppercase character, but preceding line does not end the sentence.', null, tag); - return true; - } - - return false; - }); -}; - -var _default = (0, _iterateJsdoc.default)(({ - sourceCode, - context, - jsdoc, - report, - jsdocNode, - utils -}) => { - const options = context.options[0] || {}; - const { - abbreviations = [], - newlineBeforeCapsAssumesBadSentenceEnd = false - } = options; - const abbreviationsRegex = abbreviations.length ? new RegExp('\\b' + abbreviations.map(abbreviation => { - return _lodash.default.escapeRegExp(abbreviation.replace(/\.$/g, '') + '.'); - }).join('|') + '(?:$|\\s)', 'gu') : ''; - const { - description - } = utils.getDescription(); - - if (validateDescription(description, report, jsdocNode, abbreviationsRegex, sourceCode, { - line: jsdoc.source[0].number + 1 - }, newlineBeforeCapsAssumesBadSentenceEnd)) { - return; - } - - utils.forEachPreferredTag('description', matchingJsdocTag => { - const desc = `${matchingJsdocTag.name} ${matchingJsdocTag.description}`.trim(); - validateDescription(desc, report, jsdocNode, abbreviationsRegex, sourceCode, matchingJsdocTag, newlineBeforeCapsAssumesBadSentenceEnd); - }, true); - const { - tagsWithNames - } = utils.getTagsByType(jsdoc.tags); - const tagsWithoutNames = utils.filterTags(({ - tag: tagName - }) => { - return otherDescriptiveTags.has(tagName) || utils.hasOptionTag(tagName) && !tagsWithNames.some(({ - tag - }) => { - // If user accidentally adds tags with names (or like `returns` - // get parsed as having names), do not add to this list - return tag === tagName; - }); - }); - tagsWithNames.some(tag => { - const desc = _lodash.default.trimStart(tag.description, '- ').trimEnd(); - - return validateDescription(desc, report, jsdocNode, abbreviationsRegex, sourceCode, tag, newlineBeforeCapsAssumesBadSentenceEnd); - }); - tagsWithoutNames.some(tag => { - const desc = `${tag.name} ${tag.description}`.trim(); - return validateDescription(desc, report, jsdocNode, abbreviationsRegex, sourceCode, tag, newlineBeforeCapsAssumesBadSentenceEnd); - }); -}, { - iterateAllJsdocs: true, - meta: { - docs: { - description: 'Requires that block description, explicit `@description`, and `@param`/`@returns` tag descriptions are written in complete sentences.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-description-complete-sentence' - }, - fixable: 'code', - schema: [{ - additionalProperties: false, - properties: { - abbreviations: { - items: { - type: 'string' - }, - type: 'array' - }, - newlineBeforeCapsAssumesBadSentenceEnd: { - type: 'boolean' - }, - tags: { - items: { - type: 'string' - }, - type: 'array' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requireDescriptionCompleteSentence.js.map -}); - -var requireExample = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _lodash = _interopRequireDefault(lodash__default['default']); - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var _default = (0, _iterateJsdoc.default)(({ - context, - jsdoc, - report, - utils -}) => { - if (utils.avoidDocs()) { - return; - } - - const { - exemptNoArguments = false - } = context.options[0] || {}; - const targetTagName = 'example'; - - const functionExamples = _lodash.default.filter(jsdoc.tags, { - tag: targetTagName - }); - - if (!functionExamples.length) { - if (exemptNoArguments && utils.isIteratingFunction() && !utils.hasParams()) { - return; - } - - utils.reportJSDoc(`Missing JSDoc @${targetTagName} declaration.`, null, () => { - utils.addTag(targetTagName); - }); - return; - } - - functionExamples.forEach(example => { - const exampleContent = _lodash.default.compact(`${example.name} ${example.description}`.trim().split('\n')); - - if (!exampleContent.length) { - report(`Missing JSDoc @${targetTagName} description.`); - } - }); -}, { - contextDefaults: true, - meta: { - docs: { - description: 'Requires that all functions have examples.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-example' - }, - fixable: 'code', - schema: [{ - additionalProperties: false, - properties: { - checkConstructors: { - default: true, - type: 'boolean' - }, - checkGetters: { - default: false, - type: 'boolean' - }, - checkSetters: { - default: false, - type: 'boolean' - }, - contexts: { - items: { - type: 'string' - }, - type: 'array' - }, - exemptedBy: { - items: { - type: 'string' - }, - type: 'array' - }, - exemptNoArguments: { - default: false, - type: 'boolean' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requireExample.js.map -}); - -var requireFileOverview = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const defaultTags = { - file: { - initialCommentsOnly: true, - mustExist: true, - preventDuplicates: true - } -}; - -const setDefaults = state => { - // First iteration - if (!state.globalTags) { - state.globalTags = {}; - state.hasDuplicates = {}; - state.hasTag = {}; - state.hasNonCommentBeforeTag = {}; - } -}; - -var _default = (0, _iterateJsdoc.default)(({ - jsdocNode, - state, - utils, - context -}) => { - const { - tags = defaultTags - } = context.options[0] || {}; - setDefaults(state); - - for (const tagName of Object.keys(tags)) { - const targetTagName = utils.getPreferredTagName({ - tagName - }); - const hasTag = targetTagName && utils.hasTag(targetTagName); - state.hasTag[tagName] = hasTag || state.hasTag[tagName]; - const hasDuplicate = state.hasDuplicates[tagName]; - - if (hasDuplicate === false) { - // Was marked before, so if a tag now, is a dupe - state.hasDuplicates[tagName] = hasTag; - } else if (!hasDuplicate && hasTag) { - // No dupes set before, but has first tag, so change state - // from `undefined` to `false` so can detect next time - state.hasDuplicates[tagName] = false; - state.hasNonCommentBeforeTag[tagName] = state.hasNonComment && state.hasNonComment < jsdocNode.range[0]; - } - } -}, { - exit({ - context, - state, - utils - }) { - setDefaults(state); - const { - tags = defaultTags - } = context.options[0] || {}; - - for (const [tagName, { - mustExist = false, - preventDuplicates = false, - initialCommentsOnly = false - }] of Object.entries(tags)) { - const obj = utils.getPreferredTagNameObject({ - tagName - }); - - if (obj && obj.blocked) { - utils.reportSettings(`\`settings.jsdoc.tagNamePreference\` cannot block @${obj.tagName} ` + 'for the `require-file-overview` rule'); - } else { - const targetTagName = obj && obj.replacement || obj; - - if (mustExist && !state.hasTag[tagName]) { - utils.reportSettings(`Missing @${targetTagName}`); - } - - if (preventDuplicates && state.hasDuplicates[tagName]) { - utils.reportSettings(`Duplicate @${targetTagName}`); - } - - if (initialCommentsOnly && state.hasNonCommentBeforeTag[tagName]) { - utils.reportSettings(`@${targetTagName} should be at the beginning of the file`); - } - } - } - }, - - iterateAllJsdocs: true, - meta: { - docs: { - description: 'Checks that all files have one `@file`, `@fileoverview`, or `@overview` tag at the beginning of the file.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-file-overview' - }, - schema: [{ - additionalProperties: false, - properties: { - tags: { - patternProperties: { - '.*': { - additionalProperties: false, - properties: { - initialCommentsOnly: { - type: 'boolean' - }, - mustExist: { - type: 'boolean' - }, - preventDuplicates: { - type: 'boolean' - } - }, - type: 'object' - } - }, - type: 'object' - } - }, - type: 'object' - }], - type: 'suggestion' - }, - - nonComment({ - state, - node - }) { - if (!state.hasNonComment) { - state.hasNonComment = node.range[0]; - } - } - -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requireFileOverview.js.map -}); - -var requireHyphenBeforeParamDescription = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var _default = (0, _iterateJsdoc.default)(({ - sourceCode, - utils, - report, - context, - jsdoc, - jsdocNode -}) => { - const [mainCircumstance, { - tags - } = {}] = context.options; - - const checkHyphens = (jsdocTag, targetTagName, circumstance = mainCircumstance) => { - const always = !circumstance || circumstance === 'always'; - - if (!jsdocTag.description.trim()) { - return; - } - - const startsWithHyphen = /^\s*-/u.test(jsdocTag.description); - - if (always) { - if (!startsWithHyphen) { - report(`There must be a hyphen before @${targetTagName} description.`, fixer => { - const lineIndex = jsdocTag.line; - const sourceLines = sourceCode.getText(jsdocNode).split('\n'); // Get start index of description, accounting for multi-line descriptions - - const description = jsdocTag.description.split('\n')[0]; - const descriptionIndex = sourceLines[lineIndex].lastIndexOf(description); - const replacementLine = sourceLines[lineIndex].slice(0, descriptionIndex) + '- ' + description; - sourceLines.splice(lineIndex, 1, replacementLine); - const replacement = sourceLines.join('\n'); - return fixer.replaceText(jsdocNode, replacement); - }, jsdocTag); - } - } else if (startsWithHyphen) { - report(`There must be no hyphen before @${targetTagName} description.`, fixer => { - const [unwantedPart] = /^\s*-\s*/u.exec(jsdocTag.description); - const replacement = sourceCode.getText(jsdocNode).replace(jsdocTag.description, jsdocTag.description.slice(unwantedPart.length)); - return fixer.replaceText(jsdocNode, replacement); - }, jsdocTag); - } - }; - - utils.forEachPreferredTag('param', checkHyphens); - - if (tags) { - const tagEntries = Object.entries(tags); - tagEntries.forEach(([tagName, circumstance]) => { - if (tagName === '*') { - const preferredParamTag = utils.getPreferredTagName({ - tagName: 'param' - }); - jsdoc.tags.forEach(({ - tag - }) => { - if (tag === preferredParamTag || tagEntries.some(([tagNme]) => { - return tagNme !== '*' && tagNme === tag; - })) { - return; - } - - utils.forEachPreferredTag(tag, (jsdocTag, targetTagName) => { - checkHyphens(jsdocTag, targetTagName, circumstance); - }); - }); - return; - } - - utils.forEachPreferredTag(tagName, (jsdocTag, targetTagName) => { - checkHyphens(jsdocTag, targetTagName, circumstance); - }); - }); - } -}, { - iterateAllJsdocs: true, - meta: { - docs: { - description: 'Requires a hyphen before the `@param` description.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-hyphen-before-param-description' - }, - fixable: 'code', - schema: [{ - enum: ['always', 'never'], - type: 'string' - }, { - additionalProperties: false, - properties: { - tags: { - anyOf: [{ - patternProperties: { - '.*': { - enum: ['always', 'never'], - type: 'string' - } - }, - type: 'object' - }, { - enum: ['any'], - type: 'string' - }] - } - }, - type: 'object' - }], - type: 'layout' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requireHyphenBeforeParamDescription.js.map -}); - -var exportParser = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _debug = _interopRequireDefault(require$$0__default['default']); - - - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const debug = (0, _debug.default)('requireExportJsdoc'); - -const createNode = function () { - return { - props: {} - }; -}; - -const getSymbolValue = function (symbol) { - /* istanbul ignore next */ - if (!symbol) { - /* istanbul ignore next */ - return null; - } - /* istanbul ignore next */ - - - if (symbol.type === 'literal') { - return symbol.value.value; - } - /* istanbul ignore next */ - - - return null; -}; - -const getIdentifier = function (node, globals, scope, opts) { - if (opts.simpleIdentifier) { - // Type is Identier for noncomputed properties - const identifierLiteral = createNode(); - identifierLiteral.type = 'literal'; - identifierLiteral.value = { - value: node.name - }; - return identifierLiteral; - } - /* istanbul ignore next */ - - - const block = scope || globals; // As scopes are not currently supported, they are not traversed upwards recursively - - if (block.props[node.name]) { - return block.props[node.name]; - } // Seems this will only be entered once scopes added and entered - - /* istanbul ignore next */ - - - if (globals.props[node.name]) { - return globals.props[node.name]; - } - - return null; -}; - -let createSymbol = null; - -const getSymbol = function (node, globals, scope, opt) { - const opts = opt || {}; - /* istanbul ignore next */ - - switch (node.type) { - case 'Identifier': - { - return getIdentifier(node, globals, scope, opts); - } - - case 'MemberExpression': - { - const obj = getSymbol(node.object, globals, scope, opts); - const propertySymbol = getSymbol(node.property, globals, scope, { - simpleIdentifier: !node.computed - }); - const propertyValue = getSymbolValue(propertySymbol); - /* istanbul ignore next */ - - if (obj && propertyValue && obj.props[propertyValue]) { - const block = obj.props[propertyValue]; - return block; - } - /* - if (opts.createMissingProps && propertyValue) { - obj.props[propertyValue] = createNode(); - return obj.props[propertyValue]; - } - */ - - /* istanbul ignore next */ - - - debug(`MemberExpression: Missing property ${node.property.name}`); - /* istanbul ignore next */ - - return null; - } - - case 'TSTypeAliasDeclaration': - case 'TSEnumDeclaration': - case 'TSInterfaceDeclaration': - case 'ClassDeclaration': - case 'ClassExpression': - case 'FunctionExpression': - case 'FunctionDeclaration': - case 'ArrowFunctionExpression': - { - const val = createNode(); - val.props.prototype = createNode(); - val.props.prototype.type = 'object'; - val.type = 'object'; - val.value = node; - return val; - } - - case 'AssignmentExpression': - { - return createSymbol(node.left, globals, node.right, scope, opts); - } - - case 'ClassBody': - { - const val = createNode(); - node.body.forEach(method => { - val.props[method.key.name] = createNode(); - val.props[method.key.name].type = 'object'; - val.props[method.key.name].value = method.value; - }); - val.type = 'object'; - val.value = node; - return val; - } - - case 'ObjectExpression': - { - const val = createNode(); - val.type = 'object'; - node.properties.forEach(prop => { - if ([// @typescript-eslint/parser, espree, acorn, etc. - 'SpreadElement', // @babel/eslint-parser - 'ExperimentalSpreadProperty'].includes(prop.type)) { - return; - } - - const propVal = getSymbol(prop.value, globals, scope, opts); - /* istanbul ignore next */ - - if (propVal) { - val.props[prop.key.name] = propVal; - } - }); - return val; - } - - case 'Literal': - { - const val = createNode(); - val.type = 'literal'; - val.value = node; - return val; - } - } - /* istanbul ignore next */ - - - return null; -}; - -const createBlockSymbol = function (block, name, value, globals, isGlobal) { - block.props[name] = value; - - if (isGlobal && globals.props.window && globals.props.window.special) { - globals.props.window.props[name] = value; - } -}; - -createSymbol = function (node, globals, value, scope, isGlobal) { - const block = scope || globals; - let symbol; - - switch (node.type) { - case 'FunctionDeclaration': - /* istanbul ignore next */ - // Fall through - - case 'TSEnumDeclaration': - case 'TSInterfaceDeclaration': - /* istanbul ignore next */ - // Fall through - - case 'TSTypeAliasDeclaration': - case 'ClassDeclaration': - { - /* istanbul ignore next */ - if (node.id && node.id.type === 'Identifier') { - return createSymbol(node.id, globals, node, globals); - } - /* istanbul ignore next */ - - - break; - } - - case 'Identifier': - { - if (value) { - const valueSymbol = getSymbol(value, globals, block); - /* istanbul ignore next */ - - if (valueSymbol) { - createBlockSymbol(block, node.name, valueSymbol, globals, isGlobal); - return block.props[node.name]; - } - /* istanbul ignore next */ - - - debug('Identifier: Missing value symbol for %s', node.name); - } else { - createBlockSymbol(block, node.name, createNode(), globals, isGlobal); - return block.props[node.name]; - } - /* istanbul ignore next */ - - - break; - } - - case 'MemberExpression': - { - symbol = getSymbol(node.object, globals, block); - const propertySymbol = getSymbol(node.property, globals, block, { - simpleIdentifier: !node.computed - }); - const propertyValue = getSymbolValue(propertySymbol); - - if (symbol && propertyValue) { - createBlockSymbol(symbol, propertyValue, getSymbol(value, globals, block), globals, isGlobal); - return symbol.props[propertyValue]; - } - /* istanbul ignore next */ - - - debug('MemberExpression: Missing symbol: %s', node.property.name); - break; - } - } - - return null; -}; // Creates variables from variable definitions - - -const initVariables = function (node, globals, opts) { - switch (node.type) { - case 'Program': - { - node.body.forEach(childNode => { - initVariables(childNode, globals, opts); - }); - break; - } - - case 'ExpressionStatement': - { - initVariables(node.expression, globals, opts); - break; - } - - case 'VariableDeclaration': - { - node.declarations.forEach(declaration => { - // let and const - const symbol = createSymbol(declaration.id, globals, null, globals); - - if (opts.initWindow && node.kind === 'var' && globals.props.window) { - // If var, also add to window - globals.props.window.props[declaration.id.name] = symbol; - } - }); - break; - } - - case 'ExportNamedDeclaration': - { - if (node.declaration) { - initVariables(node.declaration, globals, opts); - } - - break; - } - } -}; // Populates variable maps using AST - - -const mapVariables = function (node, globals, opt, isExport) { - /* istanbul ignore next */ - const opts = opt || {}; - /* istanbul ignore next */ - - switch (node.type) { - case 'Program': - { - if (opts.ancestorsOnly) { - return false; - } - - node.body.forEach(childNode => { - mapVariables(childNode, globals, opts); - }); - break; - } - - case 'ExpressionStatement': - { - mapVariables(node.expression, globals, opts); - break; - } - - case 'AssignmentExpression': - { - createSymbol(node.left, globals, node.right); - break; - } - - case 'VariableDeclaration': - { - node.declarations.forEach(declaration => { - const isGlobal = opts.initWindow && node.kind === 'var' && globals.props.window; - const symbol = createSymbol(declaration.id, globals, declaration.init, globals, isGlobal); - - if (symbol && isExport) { - symbol.exported = true; - } - }); - break; - } - - case 'FunctionDeclaration': - { - /* istanbul ignore next */ - if (node.id.type === 'Identifier') { - createSymbol(node.id, globals, node, globals, true); - } - - break; - } - - case 'ExportDefaultDeclaration': - { - const symbol = createSymbol(node.declaration, globals, node.declaration); - - if (symbol) { - symbol.exported = true; - } else if (!node.id) { - globals.ANONYMOUS_DEFAULT = node.declaration; - } - - break; - } - - case 'ExportNamedDeclaration': - { - if (node.declaration) { - if (node.declaration.type === 'VariableDeclaration') { - mapVariables(node.declaration, globals, opts, true); - } else { - const symbol = createSymbol(node.declaration, globals, node.declaration); - /* istanbul ignore next */ - - if (symbol) { - symbol.exported = true; - } - } - } - - node.specifiers.forEach(specifier => { - mapVariables(specifier, globals, opts); - }); - break; - } - - case 'ExportSpecifier': - { - const symbol = getSymbol(node.local, globals, globals); - /* istanbul ignore next */ - - if (symbol) { - symbol.exported = true; - } - - break; - } - - case 'ClassDeclaration': - { - createSymbol(node.id, globals, node.body, globals); - break; - } - - default: - { - /* istanbul ignore next */ - return false; - } - } - - return true; -}; - -const findNode = function (node, block, cache) { - let blockCache = cache || []; - /* istanbul ignore next */ - - if (!block || blockCache.includes(block)) { - return false; - } - - blockCache = blockCache.slice(); - blockCache.push(block); - - if ((block.type === 'object' || block.type === 'MethodDefinition') && block.value === node) { - return true; - } - - const { - props = block.body - } = block; - - for (const propval of Object.values(props || {})) { - if (Array.isArray(propval)) { - /* istanbul ignore if */ - if (propval.some(val => { - return findNode(node, val, blockCache); - })) { - return true; - } - } else if (findNode(node, propval, blockCache)) { - return true; - } - } - - return false; -}; - -const exportTypes = new Set(['ExportNamedDeclaration', 'ExportDefaultDeclaration']); - -const getExportAncestor = function (nde) { - let node = nde; - - while (node) { - if (exportTypes.has(node.type)) { - return node; - } - - node = node.parent; - } - - return false; -}; - -const canExportedByAncestorType = new Set(['TSPropertySignature', 'TSMethodSignature', 'ClassProperty', 'Method']); -const canExportChildrenType = new Set(['TSInterfaceBody', 'TSInterfaceDeclaration', 'ClassDefinition', 'ClassExpression', 'Program']); - -const isExportByAncestor = function (nde) { - if (!canExportedByAncestorType.has(nde.type)) { - return false; - } - - let node = nde.parent; - - while (node) { - if (exportTypes.has(node.type)) { - return node; - } - - if (!canExportChildrenType.has(node.type)) { - return false; - } - - node = node.parent; - } - - return false; -}; - -const findExportedNode = function (block, node, cache) { - /* istanbul ignore next */ - if (block === null) { - return false; - } - - const blockCache = cache || []; - const { - props - } = block; - - for (const propval of Object.values(props)) { - blockCache.push(propval); - - if (propval.exported && (node === propval.value || findNode(node, propval.value))) { - return true; - } // No need to check `propval` for exported nodes as ESM - // exports are only global - - } - - return false; -}; - -const isNodeExported = function (node, globals, opt) { - if (opt.initModuleExports && globals.props.module && globals.props.module.props.exports && findNode(node, globals.props.module.props.exports)) { - return true; - } - - if (opt.initWindow && globals.props.window && findNode(node, globals.props.window)) { - return true; - } - - if (opt.esm && findExportedNode(globals, node)) { - return true; - } - - return false; -}; - -const parseRecursive = function (node, globalVars, opts) { - // Iterate from top using recursion - stop at first processed node from top - if (node.parent && parseRecursive(node.parent, globalVars, opts)) { - return true; - } - - return mapVariables(node, globalVars, opts); -}; - -const parse = function (ast, node, opt) { - /* istanbul ignore next */ - const opts = opt || { - ancestorsOnly: false, - esm: true, - initModuleExports: true, - initWindow: true - }; - const globalVars = createNode(); - - if (opts.initModuleExports) { - globalVars.props.module = createNode(); - globalVars.props.module.props.exports = createNode(); - globalVars.props.exports = globalVars.props.module.props.exports; - } - - if (opts.initWindow) { - globalVars.props.window = createNode(); - globalVars.props.window.special = true; - } - - if (opts.ancestorsOnly) { - parseRecursive(node, globalVars, opts); - } else { - initVariables(ast, globalVars, opts); - mapVariables(ast, globalVars, opts); - } - - return { - globalVars - }; -}; - -const isUncommentedExport = function (node, sourceCode, opt, settings) { - // console.log({node}); - // Optimize with ancestor check for esm - if (opt.esm) { - const exportNode = getExportAncestor(node); // Is export node comment - - if (exportNode && !(0, getJSDocComment_1.findJSDocComment)(exportNode, sourceCode, settings)) { - return true; - } - /** Some typescript types are not in variable map, but inherit exported (interface property and method)*/ - - - if (isExportByAncestor(node) && !(0, getJSDocComment_1.findJSDocComment)(node, sourceCode, settings)) { - return true; - } - } - - const parseResult = parse(sourceCode.ast, node, opt); - return isNodeExported(node, parseResult.globalVars, opt); -}; - -var _default = { - isUncommentedExport, - parse -}; -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=exportParser.js.map -}); - -var requireJsdoc = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _lodash = _interopRequireDefault(lodash__default['default']); - - - -var _exportParser = _interopRequireDefault(exportParser); - - - -var _jsdocUtils = _interopRequireDefault(jsdocUtils); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const OPTIONS_SCHEMA = { - additionalProperties: false, - properties: { - checkConstructors: { - default: true, - type: 'boolean' - }, - checkGetters: { - anyOf: [{ - type: 'boolean' - }, { - enum: ['no-setter'], - type: 'string' - }], - default: true - }, - checkSetters: { - anyOf: [{ - type: 'boolean' - }, { - enum: ['no-getter'], - type: 'string' - }], - default: true - }, - contexts: { - items: { - anyOf: [{ - type: 'string' - }, { - additionalProperties: false, - properties: { - context: { - type: 'string' - }, - inlineCommentBlock: { - type: 'boolean' - } - }, - type: 'object' - }] - }, - type: 'array' - }, - enableFixer: { - default: true, - type: 'boolean' - }, - exemptEmptyConstructors: { - default: false, - type: 'boolean' - }, - exemptEmptyFunctions: { - default: false, - type: 'boolean' - }, - publicOnly: { - oneOf: [{ - default: false, - type: 'boolean' - }, { - additionalProperties: false, - default: {}, - properties: { - ancestorsOnly: { - type: 'boolean' - }, - cjs: { - type: 'boolean' - }, - esm: { - type: 'boolean' - }, - window: { - type: 'boolean' - } - }, - type: 'object' - }] - }, - require: { - additionalProperties: false, - default: {}, - properties: { - ArrowFunctionExpression: { - default: false, - type: 'boolean' - }, - ClassDeclaration: { - default: false, - type: 'boolean' - }, - ClassExpression: { - default: false, - type: 'boolean' - }, - FunctionDeclaration: { - default: true, - type: 'boolean' - }, - FunctionExpression: { - default: false, - type: 'boolean' - }, - MethodDefinition: { - default: false, - type: 'boolean' - } - }, - type: 'object' - } - }, - type: 'object' -}; - -const getOption = (context, baseObject, option, key) => { - if (!_lodash.default.has(context, `options[0][${option}][${key}]`)) { - return baseObject.properties[key].default; - } - - return context.options[0][option][key]; -}; - -const getOptions = context => { - const { - publicOnly, - contexts = [], - exemptEmptyConstructors = true, - exemptEmptyFunctions = false, - enableFixer = true - } = context.options[0] || {}; - return { - contexts, - enableFixer, - exemptEmptyConstructors, - exemptEmptyFunctions, - publicOnly: (baseObj => { - if (!publicOnly) { - return false; - } - - const properties = {}; - Object.keys(baseObj.properties).forEach(prop => { - const opt = getOption(context, baseObj, 'publicOnly', prop); - properties[prop] = opt; - }); - return properties; - })(OPTIONS_SCHEMA.properties.publicOnly.oneOf[1]), - require: (baseObj => { - const properties = {}; - Object.keys(baseObj.properties).forEach(prop => { - const opt = getOption(context, baseObj, 'require', prop); - properties[prop] = opt; - }); - return properties; - })(OPTIONS_SCHEMA.properties.require) - }; -}; - -var _default = { - create(context) { - const sourceCode = context.getSourceCode(); - const settings = (0, iterateJsdoc_1.getSettings)(context); - - if (!settings) { - return {}; - } - - const { - require: requireOption, - contexts, - publicOnly, - exemptEmptyFunctions, - exemptEmptyConstructors, - enableFixer - } = getOptions(context); - - const checkJsDoc = (node, isFunctionContext) => { - const jsDocNode = (0, getJSDocComment_1.getJSDocComment)(sourceCode, node, settings); - - if (jsDocNode) { - return; - } // For those who have options configured against ANY constructors (or setters or getters) being reported - - - if (_jsdocUtils.default.exemptSpeciaMethods({ - tags: [] - }, node, context, [OPTIONS_SCHEMA])) { - return; - } - - if ( // Avoid reporting param-less, return-less functions (when `exemptEmptyFunctions` option is set) - exemptEmptyFunctions && isFunctionContext || // Avoid reporting param-less, return-less constructor methods (when `exemptEmptyConstructors` option is set) - exemptEmptyConstructors && _jsdocUtils.default.isConstructor(node)) { - const functionParameterNames = _jsdocUtils.default.getFunctionParameterNames(node); - - if (!functionParameterNames.length && !_jsdocUtils.default.hasReturnValue(node, context)) { - return; - } - } - - const fix = fixer => { - // Default to one line break if the `minLines`/`maxLines` settings allow - const lines = settings.minLines === 0 && settings.maxLines >= 1 ? 1 : settings.minLines; - let baseNode = (0, getJSDocComment_1.getReducedASTNode)(node, sourceCode); - const decorator = (0, getJSDocComment_1.getDecorator)(baseNode); - - if (decorator) { - baseNode = decorator; - } - - const indent = _jsdocUtils.default.getIndent({ - text: sourceCode.getText(baseNode, baseNode.loc.start.column) - }); - - const { - inlineCommentBlock - } = contexts.find(({ - context: ctxt - }) => { - return ctxt === node.type; - }) || {}; - const insertion = (inlineCommentBlock ? '/** ' : `/**\n${indent}*\n${indent}`) + `*/${'\n'.repeat(lines)}${indent.slice(0, -1)}`; - return fixer.insertTextBefore(baseNode, insertion); - }; - - const report = () => { - const loc = { - end: node.loc.start + 1, - start: node.loc.start - }; - context.report({ - fix: enableFixer ? fix : null, - loc, - messageId: 'missingJsDoc', - node - }); - }; - - if (publicOnly) { - var _publicOnly$ancestors, _publicOnly$esm, _publicOnly$cjs, _publicOnly$window; - - const opt = { - ancestorsOnly: Boolean((_publicOnly$ancestors = publicOnly === null || publicOnly === void 0 ? void 0 : publicOnly.ancestorsOnly) !== null && _publicOnly$ancestors !== void 0 ? _publicOnly$ancestors : false), - esm: Boolean((_publicOnly$esm = publicOnly === null || publicOnly === void 0 ? void 0 : publicOnly.esm) !== null && _publicOnly$esm !== void 0 ? _publicOnly$esm : true), - initModuleExports: Boolean((_publicOnly$cjs = publicOnly === null || publicOnly === void 0 ? void 0 : publicOnly.cjs) !== null && _publicOnly$cjs !== void 0 ? _publicOnly$cjs : true), - initWindow: Boolean((_publicOnly$window = publicOnly === null || publicOnly === void 0 ? void 0 : publicOnly.window) !== null && _publicOnly$window !== void 0 ? _publicOnly$window : false) - }; - - const exported = _exportParser.default.isUncommentedExport(node, sourceCode, opt, settings); - - if (exported) { - report(); - } - } else { - report(); - } - }; - - const hasOption = prop => { - return requireOption[prop] || contexts.some(ctxt => { - return typeof ctxt === 'object' ? ctxt.context === prop : ctxt === prop; - }); - }; - - return { ..._jsdocUtils.default.getContextObject(_jsdocUtils.default.enforcedContexts(context, []), checkJsDoc), - - ArrowFunctionExpression(node) { - if (!hasOption('ArrowFunctionExpression')) { - return; - } - - if (['VariableDeclarator', 'AssignmentExpression', 'ExportDefaultDeclaration'].includes(node.parent.type) || ['Property', 'ObjectProperty', 'ClassProperty'].includes(node.parent.type) && node === node.parent.value) { - checkJsDoc(node, true); - } - }, - - ClassDeclaration(node) { - if (!hasOption('ClassDeclaration')) { - return; - } - - checkJsDoc(node); - }, - - ClassExpression(node) { - if (!hasOption('ClassExpression')) { - return; - } - - checkJsDoc(node); - }, - - FunctionDeclaration(node) { - if (!hasOption('FunctionDeclaration')) { - return; - } - - checkJsDoc(node, true); - }, - - FunctionExpression(node) { - if (hasOption('MethodDefinition') && node.parent.type === 'MethodDefinition') { - checkJsDoc(node, true); - return; - } - - if (!hasOption('FunctionExpression')) { - return; - } - - if (['VariableDeclarator', 'AssignmentExpression', 'ExportDefaultDeclaration'].includes(node.parent.type) || ['Property', 'ObjectProperty', 'ClassProperty'].includes(node.parent.type) && node === node.parent.value) { - checkJsDoc(node, true); - } - } - - }; - }, - - meta: { - docs: { - category: 'Stylistic Issues', - description: 'Require JSDoc comments', - recommended: 'true', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-jsdoc' - }, - fixable: 'code', - messages: { - missingJsDoc: 'Missing JSDoc comment.' - }, - schema: [OPTIONS_SCHEMA], - type: 'suggestion' - } -}; -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requireJsdoc.js.map -}); - -var requireParam = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _lodash = _interopRequireDefault(lodash__default['default']); - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const rootNamer = (desiredRoots, currentIndex) => { - let name; - let idx = currentIndex; - const incremented = desiredRoots.length <= 1; - - if (incremented) { - const base = desiredRoots[0]; - const suffix = idx++; - name = `${base}${suffix}`; - } else { - name = desiredRoots.shift(); - } - - return [name, incremented, () => { - return rootNamer(desiredRoots, idx); - }]; -}; - -var _default = (0, _iterateJsdoc.default)(({ - jsdoc, - utils, - context -}) => { - const preferredTagName = utils.getPreferredTagName({ - tagName: 'param' - }); - - if (!preferredTagName) { - return; - } - - const jsdocParameterNames = utils.getJsdocTagsDeep(preferredTagName); - const shallowJsdocParameterNames = jsdocParameterNames.filter(tag => { - return !tag.name.includes('.'); - }).map((tag, idx) => { - return { ...tag, - idx - }; - }); - - if (utils.avoidDocs()) { - return; - } // Param type is specified by type in @type - - - if (utils.hasTag('type')) { - return; - } - - const { - autoIncrementBase = 0, - checkRestProperty = false, - checkDestructured = true, - checkDestructuredRoots = true, - checkTypesPattern = '/^(?:[oO]bject|[aA]rray|PlainObject|Generic(?:Object|Array))$/', - enableFixer = true, - enableRootFixer = true, - enableRestElementFixer = true, - unnamedRootBase = ['root'], - useDefaultObjectProperties = false - } = context.options[0] || {}; - const checkTypesRegex = utils.getRegexFromString(checkTypesPattern); - const missingTags = []; - const functionParameterNames = utils.getFunctionParameterNames(useDefaultObjectProperties); - const flattenedRoots = utils.flattenRoots(functionParameterNames).names; - const paramIndex = {}; - - const hasParamIndex = cur => { - return _lodash.default.has(paramIndex, utils.dropPathSegmentQuotes(String(cur))); - }; - - const getParamIndex = cur => { - return paramIndex[utils.dropPathSegmentQuotes(String(cur))]; - }; - - const setParamIndex = (cur, idx) => { - paramIndex[utils.dropPathSegmentQuotes(String(cur))] = idx; - }; - - flattenedRoots.forEach((cur, idx) => { - setParamIndex(cur, idx); - }); - - const findExpectedIndex = (jsdocTags, indexAtFunctionParams) => { - const remainingRoots = functionParameterNames.slice(indexAtFunctionParams || 0); - const foundIndex = jsdocTags.findIndex(({ - name, - newAdd - }) => { - return !newAdd && remainingRoots.some(remainingRoot => { - if (Array.isArray(remainingRoot)) { - return remainingRoot[1].names.includes(name); - } - - if (typeof remainingRoot === 'object') { - return name === remainingRoot.name; - } - - return name === remainingRoot; - }); - }); - const tags = foundIndex > -1 ? jsdocTags.slice(0, foundIndex) : jsdocTags.filter(({ - tag - }) => { - return tag === preferredTagName; - }); - let tagLineCount = 0; - tags.forEach(({ - source - }) => { - source.forEach(({ - tokens: { - end - } - }) => { - if (!end) { - tagLineCount++; - } - }); - }); - return tagLineCount; - }; - - let [nextRootName, incremented, namer] = rootNamer([...unnamedRootBase], autoIncrementBase); - functionParameterNames.forEach((functionParameterName, functionParameterIdx) => { - let inc; - - if (Array.isArray(functionParameterName)) { - const matchedJsdoc = shallowJsdocParameterNames[functionParameterIdx] || jsdocParameterNames[functionParameterIdx]; - let rootName; - - if (functionParameterName[0]) { - rootName = functionParameterName[0]; - } else if (matchedJsdoc && matchedJsdoc.name) { - rootName = matchedJsdoc.name; - - if (matchedJsdoc.type && matchedJsdoc.type.search(checkTypesRegex) === -1) { - return; - } - } else { - rootName = nextRootName; - inc = incremented; - [nextRootName, incremented, namer] = namer(); - } - - const { - hasRestElement, - hasPropertyRest, - rests, - names - } = functionParameterName[1]; - const notCheckingNames = []; - - if (!enableRestElementFixer && hasRestElement) { - return; - } - - if (!checkDestructuredRoots) { - return; - } - - names.forEach((paramName, idx) => { - // Add root if the root name is not in the docs (and is not already - // in the tags to be fixed) - if (!jsdocParameterNames.find(({ - name - }) => { - return name === rootName; - }) && !missingTags.find(({ - functionParameterName: fpn - }) => { - return fpn === rootName; - })) { - const emptyParamIdx = jsdocParameterNames.findIndex(({ - name - }) => { - return !name; - }); - - if (emptyParamIdx > -1) { - missingTags.push({ - functionParameterIdx: emptyParamIdx, - functionParameterName: rootName, - inc, - remove: true - }); - } else { - missingTags.push({ - functionParameterIdx: hasParamIndex(rootName) ? getParamIndex(rootName) : getParamIndex(paramName), - functionParameterName: rootName, - inc - }); - } - } - - if (!checkDestructured) { - return; - } - - if (!checkRestProperty && rests[idx]) { - return; - } - - const fullParamName = `${rootName}.${paramName}`; - const notCheckingName = jsdocParameterNames.find(({ - name, - type: paramType - }) => { - return utils.comparePaths(name)(fullParamName) && paramType.search(checkTypesRegex) === -1 && paramType !== ''; - }); - - if (notCheckingName !== undefined) { - notCheckingNames.push(notCheckingName.name); - } - - if (notCheckingNames.find(name => { - return fullParamName.startsWith(name); - })) { - return; - } - - if (jsdocParameterNames && !jsdocParameterNames.find(({ - name - }) => { - return utils.comparePaths(name)(fullParamName); - })) { - missingTags.push({ - functionParameterIdx: getParamIndex(functionParameterName[0] ? fullParamName : paramName), - functionParameterName: fullParamName, - inc, - type: hasRestElement && !hasPropertyRest ? '{...any}' : undefined - }); - } - }); - return; - } - - let funcParamName; - let type; - - if (typeof functionParameterName === 'object') { - if (!enableRestElementFixer && functionParameterName.restElement) { - return; - } - - funcParamName = functionParameterName.name; - type = '{...any}'; - } else { - funcParamName = functionParameterName; - } - - if (jsdocParameterNames && !jsdocParameterNames.find(({ - name - }) => { - return name === funcParamName; - })) { - missingTags.push({ - functionParameterIdx: getParamIndex(funcParamName), - functionParameterName: funcParamName, - inc, - type - }); - } - }); - - const fix = ({ - functionParameterIdx, - functionParameterName, - remove, - inc, - type - }) => { - if (inc && !enableRootFixer) { - return; - } - - const createTokens = (tagIndex, sourceIndex, spliceCount) => { - // console.log(sourceIndex, tagIndex, jsdoc.tags, jsdoc.source); - const tokens = { - number: sourceIndex + 1, - tokens: { - delimiter: '*', - description: '', - end: '', - name: functionParameterName, - newAdd: true, - postDelimiter: ' ', - postName: '', - postTag: ' ', - postType: type ? ' ' : '', - start: jsdoc.source[sourceIndex].tokens.start, - tag: `@${preferredTagName}`, - type: type !== null && type !== void 0 ? type : '' - } - }; - jsdoc.tags.splice(tagIndex, spliceCount, { - name: functionParameterName, - newAdd: true, - source: [tokens], - tag: preferredTagName, - type: type !== null && type !== void 0 ? type : '' - }); - const firstNumber = jsdoc.source[0].number; - jsdoc.source.splice(sourceIndex, spliceCount, tokens); - jsdoc.source.slice(sourceIndex).forEach((src, idx) => { - src.number = firstNumber + sourceIndex + idx; - }); - }; - - const offset = jsdoc.source.findIndex(({ - tokens: { - tag, - end - } - }) => { - return tag || end; - }); - - if (remove) { - createTokens(functionParameterIdx, offset + functionParameterIdx, 1); - } else { - const expectedIdx = findExpectedIndex(jsdoc.tags, functionParameterIdx); - createTokens(expectedIdx, offset + expectedIdx, 0); - } - }; - - const fixer = () => { - missingTags.forEach(missingTag => { - fix(missingTag); - }); - }; - - missingTags.forEach(({ - functionParameterName - }) => { - utils.reportJSDoc(`Missing JSDoc @${preferredTagName} "${functionParameterName}" declaration.`, null, enableFixer ? fixer : null); - }); -}, { - contextDefaults: true, - meta: { - docs: { - description: 'Requires that all function parameters are documented.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-param' - }, - fixable: 'code', - schema: [{ - additionalProperties: false, - properties: { - autoIncrementBase: { - default: 0, - type: 'integer' - }, - checkConstructors: { - default: true, - type: 'boolean' - }, - checkDestructured: { - default: true, - type: 'boolean' - }, - checkDestructuredRoots: { - default: true, - type: 'boolean' - }, - checkGetters: { - default: false, - type: 'boolean' - }, - checkRestProperty: { - default: false, - type: 'boolean' - }, - checkSetters: { - default: false, - type: 'boolean' - }, - checkTypesPattern: { - type: 'string' - }, - contexts: { - items: { - type: 'string' - }, - type: 'array' - }, - enableFixer: { - type: 'boolean' - }, - enableRestElementFixer: { - type: 'boolean' - }, - enableRootFixer: { - type: 'boolean' - }, - exemptedBy: { - items: { - type: 'string' - }, - type: 'array' - }, - unnamedRootBase: { - items: { - type: 'string' - }, - type: 'array' - }, - useDefaultObjectProperties: { - type: 'boolean' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requireParam.js.map -}); - -var requireParamDescription = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var _default = (0, _iterateJsdoc.default)(({ - report, - utils -}) => { - utils.forEachPreferredTag('param', (jsdocParameter, targetTagName) => { - if (!jsdocParameter.description.trim()) { - report(`Missing JSDoc @${targetTagName} "${jsdocParameter.name}" description.`, null, jsdocParameter); - } - }); -}, { - contextDefaults: true, - meta: { - docs: { - description: 'Requires that each `@param` tag has a `description` value.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-param-description' - }, - schema: [{ - additionalProperties: false, - properties: { - contexts: { - items: { - type: 'string' - }, - type: 'array' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requireParamDescription.js.map -}); - -var requireParamName = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var _default = (0, _iterateJsdoc.default)(({ - report, - utils -}) => { - utils.forEachPreferredTag('param', (jsdocParameter, targetTagName) => { - if (jsdocParameter.tag && jsdocParameter.name === '') { - report(`There must be an identifier after @${targetTagName} ${jsdocParameter.type === '' ? 'type' : 'tag'}.`, null, jsdocParameter); - } - }); -}, { - contextDefaults: true, - meta: { - docs: { - description: 'Requires that all function parameters have names.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-param-name' - }, - schema: [{ - additionalProperties: false, - properties: { - contexts: { - items: { - type: 'string' - }, - type: 'array' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requireParamName.js.map -}); - -var requireParamType = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var _default = (0, _iterateJsdoc.default)(({ - report, - utils -}) => { - utils.forEachPreferredTag('param', (jsdocParameter, targetTagName) => { - if (!jsdocParameter.type) { - report(`Missing JSDoc @${targetTagName} "${jsdocParameter.name}" type.`, null, jsdocParameter); - } - }); -}, { - contextDefaults: true, - meta: { - docs: { - description: 'Requires that each `@param` tag has a `type` value.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-param-type' - }, - schema: [{ - additionalProperties: false, - properties: { - contexts: { - items: { - type: 'string' - }, - type: 'array' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requireParamType.js.map -}); - -var requireProperty = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var _default = (0, _iterateJsdoc.default)(({ - utils -}) => { - const propertyAssociatedTags = utils.filterTags(({ - tag - }) => { - return ['typedef', 'namespace'].includes(tag); - }); - - if (!propertyAssociatedTags.length) { - return; - } - - const targetTagName = utils.getPreferredTagName({ - tagName: 'property' - }); - - if (utils.hasATag([targetTagName])) { - return; - } - - propertyAssociatedTags.forEach(propertyAssociatedTag => { - if (!['object', 'Object', 'PlainObject'].includes(propertyAssociatedTag.type)) { - return; - } - - utils.reportJSDoc(`Missing JSDoc @${targetTagName}.`, null, () => { - utils.addTag(targetTagName); - }); - }); -}, { - iterateAllJsdocs: true, - meta: { - docs: { - description: 'Requires that all `@typedef` and `@namespace` tags have `@property` when their type is a plain `object`, `Object`, or `PlainObject`.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-property' - }, - fixable: 'code', - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requireProperty.js.map -}); - -var requirePropertyDescription = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var _default = (0, _iterateJsdoc.default)(({ - report, - utils -}) => { - utils.forEachPreferredTag('property', (jsdoc, targetTagName) => { - if (!jsdoc.description.trim()) { - report(`Missing JSDoc @${targetTagName} "${jsdoc.name}" description.`, null, jsdoc); - } - }); -}, { - iterateAllJsdocs: true, - meta: { - docs: { - description: 'Requires that each `@property` tag has a `description` value.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-property-description' - }, - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requirePropertyDescription.js.map -}); - -var requirePropertyName = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var _default = (0, _iterateJsdoc.default)(({ - report, - utils -}) => { - utils.forEachPreferredTag('property', (jsdoc, targetTagName) => { - if (jsdoc.tag && jsdoc.name === '') { - report(`There must be an identifier after @${targetTagName} ${jsdoc.type === '' ? 'type' : 'tag'}.`, null, jsdoc); - } - }); -}, { - iterateAllJsdocs: true, - meta: { - docs: { - description: 'Requires that all function `@property` tags have names.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-property-name' - }, - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requirePropertyName.js.map -}); - -var requirePropertyType = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var _default = (0, _iterateJsdoc.default)(({ - report, - utils -}) => { - utils.forEachPreferredTag('property', (jsdoc, targetTagName) => { - if (!jsdoc.type) { - report(`Missing JSDoc @${targetTagName} "${jsdoc.name}" type.`, null, jsdoc); - } - }); -}, { - iterateAllJsdocs: true, - meta: { - docs: { - description: 'Requires that each `@property` tag has a `type` value.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-property-type' - }, - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requirePropertyType.js.map -}); - -var requireReturns = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** - * We can skip checking for a return value, in case the documentation is inherited - * or the method is either a constructor or an abstract method. - * - * In either of these cases the return value is optional or not defined. - * - * @param {*} utils - * a reference to the utils which are used to probe if a tag is present or not. - * @returns {boolean} - * true in case deep checking can be skipped; otherwise false. - */ -const canSkip = utils => { - return utils.hasATag([// inheritdoc implies that all documentation is inherited - // see https://jsdoc.app/tags-inheritdoc.html - // - // Abstract methods are by definition incomplete, - // so it is not an error if it declares a return value but does not implement it. - 'abstract', 'virtual', // Constructors do not have a return value by definition (https://jsdoc.app/tags-class.html) - // So we can bail out here, too. - 'class', 'constructor', // Return type is specified by type in @type - 'type', // This seems to imply a class as well - 'interface']) || utils.avoidDocs(); -}; - -var _default = (0, _iterateJsdoc.default)(({ - report, - utils, - context -}) => { - const { - forceRequireReturn = false, - forceReturnsWithAsync = false - } = context.options[0] || {}; // A preflight check. We do not need to run a deep check - // in case the @returns comment is optional or undefined. - - if (canSkip(utils)) { - return; - } - - const tagName = utils.getPreferredTagName({ - tagName: 'returns' - }); - - if (!tagName) { - return; - } - - const tags = utils.getTags(tagName); - - if (tags.length > 1) { - report(`Found more than one @${tagName} declaration.`); - } - - const iteratingFunction = utils.isIteratingFunction(); // In case the code returns something, we expect a return value in JSDoc. - - const [tag] = tags; - const missingReturnTag = typeof tag === 'undefined' || tag === null; - - const shouldReport = () => { - if (!missingReturnTag) { - return false; - } - - if (forceRequireReturn && (iteratingFunction || utils.isVirtualFunction())) { - return true; - } - - const isAsync = !iteratingFunction && utils.hasTag('async') || iteratingFunction && utils.isAsync(); - - if (forceReturnsWithAsync && isAsync) { - return true; - } - - return iteratingFunction && utils.hasValueOrExecutorHasNonEmptyResolveValue(forceReturnsWithAsync); - }; - - if (shouldReport()) { - report(`Missing JSDoc @${tagName} declaration.`); - } -}, { - contextDefaults: true, - meta: { - docs: { - description: 'Requires returns are documented.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-returns' - }, - schema: [{ - additionalProperties: false, - properties: { - checkConstructors: { - default: false, - type: 'boolean' - }, - checkGetters: { - default: true, - type: 'boolean' - }, - contexts: { - items: { - type: 'string' - }, - type: 'array' - }, - exemptedBy: { - items: { - type: 'string' - }, - type: 'array' - }, - forceRequireReturn: { - default: false, - type: 'boolean' - }, - forceReturnsWithAsync: { - default: false, - type: 'boolean' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requireReturns.js.map -}); - -var requireReturnsCheck = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const canSkip = (utils, settings) => { - const voidingTags = [// An abstract function is by definition incomplete - // so it is perfectly fine if a return is documented but - // not present within the function. - // A subclass may inherit the doc and implement the - // missing return. - 'abstract', 'virtual', // A constructor function returns `this` by default, so may be `@returns` - // tag indicating this but no explicit return - 'class', 'constructor', 'interface']; - - if (settings.mode === 'closure') { - // Structural Interface in GCC terms, equivalent to @interface tag as far as this rule is concerned - voidingTags.push('record'); - } - - return utils.hasATag(voidingTags) || utils.isConstructor() || utils.classHasTag('interface') || settings.mode === 'closure' && utils.classHasTag('record'); -}; - -var _default = (0, _iterateJsdoc.default)(({ - context, - report, - settings, - utils -}) => { - const { - exemptAsync = true, - reportMissingReturnForUndefinedTypes = false - } = context.options[0] || {}; - - if (canSkip(utils, settings)) { - return; - } - - if (exemptAsync && utils.isAsync()) { - return; - } - - const tagName = utils.getPreferredTagName({ - tagName: 'returns' - }); - - if (!tagName) { - return; - } - - const tags = utils.getTags(tagName); - - if (tags.length === 0) { - return; - } - - if (tags.length > 1) { - report(`Found more than one @${tagName} declaration.`); - return; - } // In case a return value is declared in JSDoc, we also expect one in the code. - - - if ((reportMissingReturnForUndefinedTypes || utils.hasDefinedTypeTag(tags[0])) && !utils.hasValueOrExecutorHasNonEmptyResolveValue(exemptAsync)) { - report(`JSDoc @${tagName} declaration present but return expression not available in function.`); - } -}, { - meta: { - docs: { - description: 'Requires a return statement in function body if a `@returns` tag is specified in jsdoc comment.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-returns-check' - }, - schema: [{ - additionalProperties: false, - properties: { - exemptAsync: { - default: true, - type: 'boolean' - }, - reportMissingReturnForUndefinedTypes: { - default: false, - type: 'boolean' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requireReturnsCheck.js.map -}); - -var requireReturnsDescription = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var _default = (0, _iterateJsdoc.default)(({ - report, - utils -}) => { - utils.forEachPreferredTag('returns', (jsdocTag, targetTagName) => { - const type = jsdocTag.type && jsdocTag.type.trim(); - - if (['void', 'undefined', 'Promise', 'Promise'].includes(type)) { - return; - } - - if (!jsdocTag.description.trim()) { - report(`Missing JSDoc @${targetTagName} description.`, null, jsdocTag); - } - }); -}, { - contextDefaults: true, - meta: { - docs: { - description: 'Requires that the `@returns` tag has a `description` value.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-returns-description' - }, - schema: [{ - additionalProperties: false, - properties: { - contexts: { - items: { - type: 'string' - }, - type: 'array' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requireReturnsDescription.js.map -}); - -var requireReturnsType = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var _default = (0, _iterateJsdoc.default)(({ - report, - utils -}) => { - utils.forEachPreferredTag('returns', (jsdocTag, targetTagName) => { - if (!jsdocTag.type) { - report(`Missing JSDoc @${targetTagName} type.`, null, jsdocTag); - } - }); -}, { - contextDefaults: true, - meta: { - docs: { - description: 'Requires that `@returns` tag has `type` value.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-returns-type' - }, - schema: [{ - additionalProperties: false, - properties: { - contexts: { - items: { - type: 'string' - }, - type: 'array' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requireReturnsType.js.map -}); - -var requireThrows = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** - * We can skip checking for a throws value, in case the documentation is inherited - * or the method is either a constructor or an abstract method. - * - * @param {*} utils - * a reference to the utils which are used to probe if a tag is present or not. - * @returns {boolean} - * true in case deep checking can be skipped; otherwise false. - */ -const canSkip = utils => { - return utils.hasATag([// inheritdoc implies that all documentation is inherited - // see https://jsdoc.app/tags-inheritdoc.html - // - // Abstract methods are by definition incomplete, - // so it is not necessary to document that they throw an error. - 'abstract', 'virtual', // The designated type can itself document `@throws` - 'type']) || utils.avoidDocs(); -}; - -var _default = (0, _iterateJsdoc.default)(({ - report, - utils -}) => { - // A preflight check. We do not need to run a deep check for abstract - // functions. - if (canSkip(utils)) { - return; - } - - const tagName = utils.getPreferredTagName({ - tagName: 'throws' - }); - - if (!tagName) { - return; - } - - const tags = utils.getTags(tagName); - const iteratingFunction = utils.isIteratingFunction(); // In case the code returns something, we expect a return value in JSDoc. - - const [tag] = tags; - const missingThrowsTag = typeof tag === 'undefined' || tag === null; - - const shouldReport = () => { - if (!missingThrowsTag) { - return false; - } - - return iteratingFunction && utils.hasThrowValue(); - }; - - if (shouldReport()) { - report(`Missing JSDoc @${tagName} declaration.`); - } -}, { - contextDefaults: true, - meta: { - docs: { - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-returns' - }, - schema: [{ - additionalProperties: false, - properties: { - contexts: { - items: { - type: 'string' - }, - type: 'array' - }, - exemptedBy: { - items: { - type: 'string' - }, - type: 'array' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requireThrows.js.map -}); - -var requireYields = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -/** - * We can skip checking for a yield value, in case the documentation is inherited - * or the method has a constructor or abstract tag. - * - * In either of these cases the yield value is optional or not defined. - * - * @param {*} utils - * a reference to the utils which are used to probe if a tag is present or not. - * @returns {boolean} - * true in case deep checking can be skipped; otherwise false. - */ -const canSkip = utils => { - return utils.hasATag([// inheritdoc implies that all documentation is inherited - // see https://jsdoc.app/tags-inheritdoc.html - // - // Abstract methods are by definition incomplete, - // so it is not an error if it declares a yield value but does not implement it. - 'abstract', 'virtual', // Constructors do not have a yield value - // so we can bail out here, too. - 'class', 'constructor', // Yield (and any `next`) type is specified accompanying the targeted - // @type - 'type', // This seems to imply a class as well - 'interface']) || utils.avoidDocs(); -}; - -const checkTagName = (utils, report, tagName) => { - const preferredTagName = utils.getPreferredTagName({ - tagName - }); - - if (!preferredTagName) { - return []; - } - - const tags = utils.getTags(preferredTagName); - - if (tags.length > 1) { - report(`Found more than one @${preferredTagName} declaration.`); - } // In case the code yields something, we expect a yields value in JSDoc. - - - const [tag] = tags; - const missingTag = typeof tag === 'undefined' || tag === null; - return [preferredTagName, missingTag]; -}; - -var _default = (0, _iterateJsdoc.default)(({ - report, - utils, - context -}) => { - const { - next = false, - nextWithGeneratorTag = false, - forceRequireNext = false, - forceRequireYields = false, - withGeneratorTag = true - } = context.options[0] || {}; // A preflight check. We do not need to run a deep check - // in case the @yield comment is optional or undefined. - - if (canSkip(utils)) { - return; - } - - const iteratingFunction = utils.isIteratingFunction(); - const [preferredYieldTagName, missingYieldTag] = checkTagName(utils, report, 'yields'); - - if (preferredYieldTagName) { - const shouldReportYields = () => { - if (!missingYieldTag) { - return false; - } - - if (withGeneratorTag && utils.hasTag('generator') || forceRequireYields && iteratingFunction && utils.isGenerator()) { - return true; - } - - return iteratingFunction && utils.isGenerator() && utils.hasYieldValue(); - }; - - if (shouldReportYields()) { - report(`Missing JSDoc @${preferredYieldTagName} declaration.`); - } - } - - if (next || nextWithGeneratorTag || forceRequireNext) { - const [preferredNextTagName, missingNextTag] = checkTagName(utils, report, 'next'); - - if (!preferredNextTagName) { - return; - } - - const shouldReportNext = () => { - if (!missingNextTag) { - return false; - } - - if (nextWithGeneratorTag && utils.hasTag('generator')) { - return true; - } - - if (!next && !forceRequireNext || !iteratingFunction || !utils.isGenerator()) { - return false; - } - - return forceRequireNext || utils.hasYieldReturnValue(); - }; - - if (shouldReportNext()) { - report(`Missing JSDoc @${preferredNextTagName} declaration.`); - } - } -}, { - contextDefaults: true, - meta: { - docs: { - description: 'Requires yields are documented.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-yields' - }, - schema: [{ - additionalProperties: false, - properties: { - contexts: { - items: { - type: 'string' - }, - type: 'array' - }, - exemptedBy: { - items: { - type: 'string' - }, - type: 'array' - }, - forceRequireNext: { - default: false, - type: 'boolean' - }, - forceRequireYields: { - default: false, - type: 'boolean' - }, - next: { - default: false, - type: 'boolean' - }, - nextWithGeneratorTag: { - default: false, - type: 'boolean' - }, - withGeneratorTag: { - default: true, - type: 'boolean' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requireYields.js.map -}); - -var requireYieldsCheck = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const canSkip = (utils, settings) => { - const voidingTags = [// An abstract function is by definition incomplete - // so it is perfectly fine if a yield is documented but - // not present within the function. - // A subclass may inherit the doc and implement the - // missing yield. - 'abstract', 'virtual', // Constructor functions do not have a yield value - // so we can bail here, too. - 'class', 'constructor', // This seems to imply a class as well - 'interface']; - - if (settings.mode === 'closure') { - // Structural Interface in GCC terms, equivalent to @interface tag as far as this rule is concerned - voidingTags.push('record'); - } - - return utils.hasATag(voidingTags) || utils.isConstructor() || utils.classHasTag('interface') || settings.mode === 'closure' && utils.classHasTag('record'); -}; - -const checkTagName = (utils, report, tagName) => { - const preferredTagName = utils.getPreferredTagName({ - tagName - }); - - if (!preferredTagName) { - return []; - } - - const tags = utils.getTags(preferredTagName); - - if (tags.length === 0) { - return []; - } - - if (tags.length > 1) { - report(`Found more than one @${preferredTagName} declaration.`); - return []; - } - - return [preferredTagName, tags[0]]; -}; - -var _default = (0, _iterateJsdoc.default)(({ - context, - report, - settings, - utils -}) => { - if (canSkip(utils, settings)) { - return; - } - - const { - next = false, - checkGeneratorsOnly = false - } = context.options[0] || {}; - const [preferredYieldTagName, yieldTag] = checkTagName(utils, report, 'yields'); - - if (preferredYieldTagName) { - const shouldReportYields = () => { - if (checkGeneratorsOnly && !utils.isGenerator()) { - return true; - } - - return utils.hasDefinedTypeTag(yieldTag) && !utils.hasYieldValue(); - }; // In case a yield value is declared in JSDoc, we also expect one in the code. - - - if (shouldReportYields()) { - report(`JSDoc @${preferredYieldTagName} declaration present but yield expression not available in function.`); - } - } - - if (next) { - const [preferredNextTagName, nextTag] = checkTagName(utils, report, 'next'); - - if (preferredNextTagName) { - const shouldReportNext = () => { - if (checkGeneratorsOnly && !utils.isGenerator()) { - return true; - } - - return utils.hasDefinedTypeTag(nextTag) && !utils.hasYieldReturnValue(); - }; - - if (shouldReportNext()) { - report(`JSDoc @${preferredNextTagName} declaration present but yield expression with return value not available in function.`); - } - } - } -}, { - meta: { - docs: { - description: 'Requires a yield statement in function body if a `@yields` tag is specified in jsdoc comment.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-yields-check' - }, - schema: [{ - additionalProperties: false, - properties: { - checkGeneratorsOnly: { - default: false, - type: 'boolean' - }, - contexts: { - items: { - type: 'string' - }, - type: 'array' - }, - exemptedBy: { - items: { - type: 'string' - }, - type: 'array' - }, - next: { - default: false, - type: 'boolean' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=requireYieldsCheck.js.map -}); - -var validTypes = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - - - -var _iterateJsdoc = _interopRequireDefault(iterateJsdoc_1); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -const asExpression = /as\s+/u; - -var _default = (0, _iterateJsdoc.default)(({ - jsdoc, - report, - utils, - context, - settings -}) => { - const { - allowEmptyNamepaths = false - } = context.options[0] || {}; - const { - mode - } = settings; - - const tryParseIgnoreError = path => { - try { - (0, jsdoctypeparser.parse)(path, { - mode - }); - return true; - } catch {// Keep the original error for including the whole type - } - - return false; - }; // eslint-disable-next-line complexity - - - jsdoc.tags.forEach(tag => { - const validNamepathParsing = function (namepath, tagName) { - if (tryParseIgnoreError(namepath)) { - return true; - } - - let handled = false; - - if (tagName) { - switch (tagName) { - case 'module': - { - if (!namepath.startsWith('module:')) { - handled = tryParseIgnoreError(`module:${namepath}`); - } - - break; - } - - case 'memberof': - case 'memberof!': - { - const endChar = namepath.slice(-1); - - if (['#', '.', '~'].includes(endChar)) { - handled = tryParseIgnoreError(namepath.slice(0, -1)); - } - - break; - } - - case 'borrows': - { - const startChar = namepath.charAt(); - - if (['#', '.', '~'].includes(startChar)) { - handled = tryParseIgnoreError(namepath.slice(1)); - } - } - } - } - - if (!handled) { - report(`Syntax error in namepath: ${namepath}`, null, tag); - return false; - } - - return true; - }; - - const validTypeParsing = function (type) { - try { - (0, jsdoctypeparser.parse)(type, { - mode - }); - } catch { - report(`Syntax error in type: ${type}`, null, tag); - return false; - } - - return true; - }; - - if (tag.tag === 'borrows') { - const thisNamepath = tag.description.replace(asExpression, '').trim(); - - if (!asExpression.test(tag.description) || !thisNamepath) { - report(`@borrows must have an "as" expression. Found "${tag.description}"`, null, tag); - return; - } - - if (validNamepathParsing(thisNamepath, 'borrows')) { - const thatNamepath = tag.name; - validNamepathParsing(thatNamepath); - } - - return; - } - - const otherModeMaps = ['jsdoc', 'typescript', 'closure', 'permissive'].filter(mde => { - return mde !== mode; - }).map(mde => { - return utils.getTagStructureForMode(mde); - }); - const tagMightHaveNamePosition = utils.tagMightHaveNamePosition(tag.tag, otherModeMaps); - - if (tagMightHaveNamePosition !== true && tag.name) { - const modeInfo = tagMightHaveNamePosition === false ? '' : ` in "${mode}" mode`; - report(`@${tag.tag} should not have a name${modeInfo}.`, null, tag); - return; - } - - const mightHaveTypePosition = utils.tagMightHaveTypePosition(tag.tag, otherModeMaps); - - if (mightHaveTypePosition !== true && tag.type) { - const modeInfo = mightHaveTypePosition === false ? '' : ` in "${mode}" mode`; - report(`@${tag.tag} should not have a bracketed type${modeInfo}.`, null, tag); - return; - } // REQUIRED NAME - - - const tagMustHaveNamePosition = utils.tagMustHaveNamePosition(tag.tag, otherModeMaps); // Don't handle `@param` here though it does require name as handled by - // `require-param-name` (`@property` would similarly seem to require one, - // but is handled by `require-property-name`) - - if (tagMustHaveNamePosition !== false && !tag.name && !allowEmptyNamepaths && !['param', 'arg', 'argument', 'property', 'prop'].includes(tag.tag) && (tag.tag !== 'see' || !tag.description.includes('{@link'))) { - const modeInfo = tagMustHaveNamePosition === true ? '' : ` in "${mode}" mode`; - report(`Tag @${tag.tag} must have a name/namepath${modeInfo}.`, null, tag); - return; - } // REQUIRED TYPE - - - const mustHaveTypePosition = utils.tagMustHaveTypePosition(tag.tag, otherModeMaps); - - if (mustHaveTypePosition !== false && !tag.type) { - const modeInfo = mustHaveTypePosition === true ? '' : ` in "${mode}" mode`; - report(`Tag @${tag.tag} must have a type${modeInfo}.`, null, tag); - return; - } // REQUIRED TYPE OR NAME/NAMEPATH - - - const tagMissingRequiredTypeOrNamepath = utils.tagMissingRequiredTypeOrNamepath(tag, otherModeMaps); - - if (tagMissingRequiredTypeOrNamepath !== false && !allowEmptyNamepaths) { - const modeInfo = tagMissingRequiredTypeOrNamepath === true ? '' : ` in "${mode}" mode`; - report(`Tag @${tag.tag} must have either a type or namepath${modeInfo}.`, null, tag); - return; - } // VALID TYPE - - - const hasTypePosition = mightHaveTypePosition === true && Boolean(tag.type); - - if (hasTypePosition) { - validTypeParsing(tag.type); - } // VALID NAME/NAMEPATH - - - const hasNameOrNamepathPosition = (tagMustHaveNamePosition !== false || utils.tagMightHaveNamepath(tag.tag)) && Boolean(tag.name); - - if (hasNameOrNamepathPosition) { - if (mode !== 'jsdoc' && tag.tag === 'template') { - utils.parseClosureTemplateTag(tag).forEach(namepath => { - validNamepathParsing(namepath); - }); - } else { - validNamepathParsing(tag.name, tag.tag); - } - } - }); -}, { - iterateAllJsdocs: true, - meta: { - docs: { - description: 'Requires all types to be valid JSDoc or Closure compiler types without syntax errors.', - url: 'https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-valid-types' - }, - schema: [{ - additionalProperies: false, - properties: { - allowEmptyNamepaths: { - default: false, - type: 'boolean' - } - }, - type: 'object' - }], - type: 'suggestion' - } -}); - -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=validTypes.js.map -}); - -var dist = createCommonjsModule(function (module, exports) { - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = void 0; - -var _checkAccess = _interopRequireDefault(checkAccess); - -var _checkAlignment = _interopRequireDefault(checkAlignment); - -var _checkExamples = _interopRequireDefault(checkExamples); - -var _checkIndentation = _interopRequireDefault(checkIndentation); - -var _checkLineAlignment = _interopRequireDefault(checkLineAlignment); - -var _checkParamNames = _interopRequireDefault(checkParamNames); - -var _checkPropertyNames = _interopRequireDefault(checkPropertyNames); - -var _checkSyntax = _interopRequireDefault(checkSyntax); - -var _checkTagNames = _interopRequireDefault(checkTagNames); - -var _checkTypes = _interopRequireDefault(checkTypes); - -var _checkValues = _interopRequireDefault(checkValues); - -var _emptyTags = _interopRequireDefault(emptyTags); - -var _implementsOnClasses = _interopRequireDefault(implementsOnClasses); - -var _matchDescription = _interopRequireDefault(matchDescription); - -var _newlineAfterDescription = _interopRequireDefault(newlineAfterDescription); - -var _noBadBlocks = _interopRequireDefault(noBadBlocks); - -var _noDefaults = _interopRequireDefault(noDefaults); - -var _noTypes = _interopRequireDefault(noTypes); - -var _noUndefinedTypes = _interopRequireDefault(noUndefinedTypes); - -var _requireDescription = _interopRequireDefault(requireDescription); - -var _requireDescriptionCompleteSentence = _interopRequireDefault(requireDescriptionCompleteSentence); - -var _requireExample = _interopRequireDefault(requireExample); - -var _requireFileOverview = _interopRequireDefault(requireFileOverview); - -var _requireHyphenBeforeParamDescription = _interopRequireDefault(requireHyphenBeforeParamDescription); - -var _requireJsdoc = _interopRequireDefault(requireJsdoc); - -var _requireParam = _interopRequireDefault(requireParam); - -var _requireParamDescription = _interopRequireDefault(requireParamDescription); - -var _requireParamName = _interopRequireDefault(requireParamName); - -var _requireParamType = _interopRequireDefault(requireParamType); - -var _requireProperty = _interopRequireDefault(requireProperty); - -var _requirePropertyDescription = _interopRequireDefault(requirePropertyDescription); - -var _requirePropertyName = _interopRequireDefault(requirePropertyName); - -var _requirePropertyType = _interopRequireDefault(requirePropertyType); - -var _requireReturns = _interopRequireDefault(requireReturns); - -var _requireReturnsCheck = _interopRequireDefault(requireReturnsCheck); - -var _requireReturnsDescription = _interopRequireDefault(requireReturnsDescription); - -var _requireReturnsType = _interopRequireDefault(requireReturnsType); - -var _requireThrows = _interopRequireDefault(requireThrows); - -var _requireYields = _interopRequireDefault(requireYields); - -var _requireYieldsCheck = _interopRequireDefault(requireYieldsCheck); - -var _validTypes = _interopRequireDefault(validTypes); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -var _default = { - configs: { - recommended: { - plugins: ['jsdoc'], - rules: { - 'jsdoc/check-access': 'warn', - 'jsdoc/check-alignment': 'warn', - 'jsdoc/check-examples': 'off', - 'jsdoc/check-indentation': 'off', - 'jsdoc/check-line-alignment': 'off', - 'jsdoc/check-param-names': 'warn', - 'jsdoc/check-property-names': 'warn', - 'jsdoc/check-syntax': 'off', - 'jsdoc/check-tag-names': 'warn', - 'jsdoc/check-types': 'warn', - 'jsdoc/check-values': 'warn', - 'jsdoc/empty-tags': 'warn', - 'jsdoc/implements-on-classes': 'warn', - 'jsdoc/match-description': 'off', - 'jsdoc/newline-after-description': 'warn', - 'jsdoc/no-bad-blocks': 'off', - 'jsdoc/no-defaults': 'off', - 'jsdoc/no-types': 'off', - 'jsdoc/no-undefined-types': 'warn', - 'jsdoc/require-description': 'off', - 'jsdoc/require-description-complete-sentence': 'off', - 'jsdoc/require-example': 'off', - 'jsdoc/require-file-overview': 'off', - 'jsdoc/require-hyphen-before-param-description': 'off', - 'jsdoc/require-jsdoc': 'warn', - 'jsdoc/require-param': 'warn', - 'jsdoc/require-param-description': 'warn', - 'jsdoc/require-param-name': 'warn', - 'jsdoc/require-param-type': 'warn', - 'jsdoc/require-property': 'warn', - 'jsdoc/require-property-description': 'warn', - 'jsdoc/require-property-name': 'warn', - 'jsdoc/require-property-type': 'warn', - 'jsdoc/require-returns': 'warn', - 'jsdoc/require-returns-check': 'warn', - 'jsdoc/require-returns-description': 'warn', - 'jsdoc/require-returns-type': 'warn', - 'jsdoc/require-throws': 'off', - 'jsdoc/require-yields': 'warn', - 'jsdoc/require-yields-check': 'warn', - 'jsdoc/valid-types': 'warn' - } - } - }, - rules: { - 'check-access': _checkAccess.default, - 'check-alignment': _checkAlignment.default, - 'check-examples': _checkExamples.default, - 'check-indentation': _checkIndentation.default, - 'check-line-alignment': _checkLineAlignment.default, - 'check-param-names': _checkParamNames.default, - 'check-property-names': _checkPropertyNames.default, - 'check-syntax': _checkSyntax.default, - 'check-tag-names': _checkTagNames.default, - 'check-types': _checkTypes.default, - 'check-values': _checkValues.default, - 'empty-tags': _emptyTags.default, - 'implements-on-classes': _implementsOnClasses.default, - 'match-description': _matchDescription.default, - 'newline-after-description': _newlineAfterDescription.default, - 'no-bad-blocks': _noBadBlocks.default, - 'no-defaults': _noDefaults.default, - 'no-types': _noTypes.default, - 'no-undefined-types': _noUndefinedTypes.default, - 'require-description': _requireDescription.default, - 'require-description-complete-sentence': _requireDescriptionCompleteSentence.default, - 'require-example': _requireExample.default, - 'require-file-overview': _requireFileOverview.default, - 'require-hyphen-before-param-description': _requireHyphenBeforeParamDescription.default, - 'require-jsdoc': _requireJsdoc.default, - 'require-param': _requireParam.default, - 'require-param-description': _requireParamDescription.default, - 'require-param-name': _requireParamName.default, - 'require-param-type': _requireParamType.default, - 'require-property': _requireProperty.default, - 'require-property-description': _requirePropertyDescription.default, - 'require-property-name': _requirePropertyName.default, - 'require-property-type': _requirePropertyType.default, - 'require-returns': _requireReturns.default, - 'require-returns-check': _requireReturnsCheck.default, - 'require-returns-description': _requireReturnsDescription.default, - 'require-returns-type': _requireReturnsType.default, - 'require-throws': _requireThrows.default, - 'require-yields': _requireYields.default, - 'require-yields-check': _requireYieldsCheck.default, - 'valid-types': _validTypes.default - } -}; -exports.default = _default; -module.exports = exports.default; -//# sourceMappingURL=index.js.map -}); - -var index = /*@__PURE__*/getDefaultExportFromCjs(dist); - -module.exports = index; +const n=e=>{var t,n,r,o,s;return(null==e||null===(t=e.declaration)||void 0===t||null===(n=t.decorators)||void 0===n?void 0:n[0])||(null==e||null===(r=e.decorators)||void 0===r?void 0:r[0])||(null==e||null===(o=e.parent)||void 0===o||null===(s=o.decorators)||void 0===s?void 0:s[0])};t.getDecorator=n;const r=new Set(["CallExpression","OptionalCallExpression","NewExpression"]),o=new Set(["VariableDeclaration","ExpressionStatement","MethodDefinition","Property","ObjectProperty","ClassProperty"]),s=function(e,t){let{parent:n}=e;switch(e.type){case"TSFunctionType":return function(e){const{parent:t}=e,n=t.parent,r=n.parent,o=r&&r.parent;if("TSTypeAnnotation"!==t.type)return e;switch(n.type){case"ClassProperty":case"TSDeclareFunction":case"TSMethodSignature":case"TSPropertySignature":return n;case"ArrowFunctionExpression":return"VariableDeclarator"===r.type?o.parent:e;case"FunctionExpression":if("MethodDefinition"===r.type)return r;default:if("Identifier"!==n.type)return e}switch(r.type){case"ArrowFunctionExpression":return"VariableDeclarator"===o.type&&"VariableDeclaration"===o.parent.type?o.parent:e;case"FunctionDeclaration":return r;case"VariableDeclarator":if("VariableDeclaration"===o.type)return o;default:return e}}(e);case"TSInterfaceDeclaration":case"TSTypeAliasDeclaration":case"TSEnumDeclaration":case"ClassDeclaration":case"FunctionDeclaration":return"ExportDefaultDeclaration"===(s=n).type||"ExportNamedDeclaration"===s.type||"ExportAllDeclaration"===s.type||"ExportSpecifier"===s.type?n:e;case"TSDeclareFunction":case"ClassExpression":case"ObjectExpression":case"ArrowFunctionExpression":case"TSEmptyBodyFunctionExpression":case"FunctionExpression":if(!r.has(n.type)){for(;!t.getCommentsBefore(n).length&&!/Function/u.test(n.type)&&!o.has(n.type)&&(n=n.parent,n););if(n&&"FunctionDeclaration"!==n.type&&"Program"!==n.type)return n.parent&&"ExportNamedDeclaration"===n.parent.type?n.parent:n}return e;default:return e}var s};t.getReducedASTNode=s;const a=(e,t,r)=>{const{minLines:o,maxLines:s}=r;let a=e,i=null;for(;a;){const e=n(a);if(e&&(a=e),i=t.getTokenBefore(a,{includeComments:!0}),!i||"Line"!==(c=i).type&&"Block"!==c.type&&"Shebang"!==c.type)return null;if("Line"!==i.type)break;a=i}var c;return"Block"===i.type&&"*"===i.value.charAt(0)&&a.loc.start.line-i.loc.end.line>=o&&a.loc.start.line-i.loc.end.line<=s?i:null};t.findJSDocComment=a;const i=function(e,t,n){const r=s(t,e);return a(r,e,n)};t.getJSDocComment=i;var c=i;t.default=c})),Ye=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=function(){const e=new WeakMap;return{hasBeenWarned:(t,n)=>e.has(t)&&e.get(t).has(n),markSettingAsWarned(t,n){e.has(t)||e.set(t,new Set),e.get(t).add(n)}}};t.default=n,e.exports=t.default})),He=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=e=>{const t="jsdoc"===e,n="closure"===e,r="typescript"===e,o="permissive"===e,s=t||r,a=r||n,i=n||o,c=s||o;return new Map([["alias",new Map([["nameContents","namepath-referencing"],["typeOrNameRequired",!0]])],["arg",new Map([["nameContents","namepath-defining"],["nameRequired",!0],["typeAllowed",!0]])],["argument",new Map([["nameContents","namepath-defining"],["nameRequired",!0],["typeAllowed",!0]])],["augments",new Map([["nameContents","namepath-referencing"],["typeAllowed",!0],["typeOrNameRequired",!0]])],["borrows",new Map([["nameContents","namepath-referencing"],["typeOrNameRequired",!0]])],["callback",new Map([["nameContents","namepath-defining"],["nameRequired",!0]])],["class",new Map([["nameContents","namepath-defining"],["typeAllowed",!0]])],["const",new Map([["nameContents","namepath-defining"],["typeAllowed",!0]])],["constant",new Map([["nameContents","namepath-defining"],["typeAllowed",!0]])],["constructor",new Map([["nameContents","namepath-defining"],["typeAllowed",!0]])],["define",new Map([["typeRequired",n]])],["emits",new Map([["nameContents","namepath-referencing"]])],["enum",new Map([["typeAllowed",!0]])],["event",new Map([["nameRequired",!0],["nameContents","namepath-defining"]])],["exception",new Map([["typeAllowed",!0]])],["export",new Map([["typeAllowed",i]])],["extends",new Map([["nameContents","namepath-referencing"],["typeAllowed",i],["nameRequired",s],["typeOrNameRequired",i]])],["external",new Map([["nameContents","namepath-defining"],["nameRequired",!0]])],["fires",new Map([["nameContents","namepath-referencing"]])],["function",new Map([["nameContents","namepath-defining"]])],["func",new Map([["nameContents","namepath-defining"]])],["host",new Map([["nameContents","namepath-defining"],["nameRequired",!0],["typeOrNameRequired",!0]])],["interface",new Map([["nameContents",!!c&&"namepath-defining"]])],["implements",new Map([["typeRequired",!0]])],["lends",new Map([["nameContents","namepath-referencing"],["typeOrNameRequired",!0]])],["listens",new Map([["nameContents","namepath-referencing"]])],["member",new Map([["nameContents","namepath-defining"],["typeAllowed",!0]])],["memberof",new Map([["nameContents","namepath-referencing"],["typeOrNameRequired",!0]])],["memberof!",new Map([["nameContents","namepath-referencing"],["typeOrNameRequired",!0]])],["method",new Map([["nameContents","namepath-defining"]])],["mixes",new Map([["nameContents","namepath-referencing"],["typeOrNameRequired",!0]])],["mixin",new Map([["nameContents","namepath-defining"]])],["modifies",new Map([["typeAllowed",!0]])],["module",new Map([["nameContents",t?"namepath-defining":"text"],["typeAllowed",!0]])],["name",new Map([["nameContents","namepath-defining"],["nameRequired",!0],["typeOrNameRequired",!0]])],["namespace",new Map([["nameContents","namepath-defining"],["typeAllowed",!0]])],["package",new Map([["typeAllowed",i]])],["param",new Map([["nameContents","namepath-defining"],["nameRequired",!0],["typeAllowed",!0]])],["private",new Map([["typeAllowed",i]])],["prop",new Map([["nameContents","namepath-defining"],["nameRequired",!0],["typeAllowed",!0]])],["property",new Map([["nameContents","namepath-defining"],["nameRequired",!0],["typeAllowed",!0]])],["protected",new Map([["typeAllowed",i]])],["public",new Map([["typeAllowed",i]])],["returns",new Map([["typeAllowed",!0]])],["return",new Map([["typeAllowed",!0]])],["see",new Map([["nameContents","text"]])],["static",new Map([["typeAllowed",i]])],["template",new Map([["nameContents",t?"text":"namepath-referencing"],["typeAllowed",a||o]])],["this",new Map([["nameContents",!!t&&"namepath-referencing"],["typeRequired",a],["typeOrNameRequired",t]])],["throws",new Map([["typeAllowed",!0]])],["type",new Map([["typeRequired",!0]])],["typedef",new Map([["nameContents","namepath-defining"],["nameRequired",c],["typeAllowed",!0],["typeOrNameRequired",!0]])],["var",new Map([["nameContents","namepath-defining"],["typeAllowed",!0]])],["yields",new Map([["typeAllowed",!0]])],["yield",new Map([["typeAllowed",!0]])]])};t.default=n,e.exports=t.default})),Xe=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.typeScriptTags=t.closureTags=t.jsdocTags=void 0;const n={modifies:[],abstract:["virtual"],access:[],alias:[],async:[],augments:["extends"],author:[],borrows:[],callback:[],class:["constructor"],classdesc:[],constant:["const"],constructs:[],copyright:[],default:["defaultvalue"],deprecated:[],description:["desc"],enum:[],event:[],example:[],exports:[],external:["host"],file:["fileoverview","overview"],fires:["emits"],function:["func","method"],generator:[],global:[],hideconstructor:[],ignore:[],implements:[],inheritdoc:[],inheritDoc:[],inner:[],instance:[],interface:[],kind:[],lends:[],license:[],listens:[],member:["var"],memberof:[],"memberof!":[],mixes:[],mixin:[],module:[],name:[],namespace:[],override:[],package:[],param:["arg","argument"],private:[],property:["prop"],protected:[],public:[],readonly:[],requires:[],returns:["return"],see:[],since:[],static:[],summary:[],this:[],throws:["exception"],todo:[],tutorial:[],type:[],typedef:[],variation:[],version:[],yields:["yield"]};t.jsdocTags=n;const r={...n,template:[]};t.typeScriptTags=r;const{inheritdoc:o,returns:s,...a}=r,i={...a,closurePrimitive:[],customElement:[],expose:[],hidden:[],idGenerator:[],meaning:[],mixinClass:[],mixinFunction:[],ngInject:[],owner:[],typeSummary:[],wizaction:[],define:[],dict:[],export:[],externs:[],final:[],implicitCast:[],noalias:[],nocollapse:[],nocompile:[],noinline:[],nosideeffects:[],polymer:[],polymerBehavior:[],preserve:[],record:[],return:["returns"],struct:[],suppress:[],unrestricted:[]};t.closureTags=i})),Qe=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=s(F.default),r=s(Ye),o=s(He);function s(e){return e&&e.__esModule?e:{default:e}}let a;const i=(e,t="")=>{let n=!1,r=!1;const o=[],s=e.reduce(((e,s)=>{if(Array.isArray(s)){let a;Array.isArray(s[1])?a=s[1]:(s[1].hasRestElement&&(n=!0),s[1].hasPropertyRest&&(r=!0),a=s[1].names);const c=i(a,t?`${t}.${s[0]}`:s[0]);c.hasRestElement&&(n=!0),c.hasPropertyRest&&(r=!0);const l=[t?`${t}.${s[0]}`:s[0],...c.names].filter(Boolean);return o.push(!1,...c.rests),e.concat(l)}return"object"==typeof s?(s.isRestProperty?(r=!0,o.push(!0)):o.push(!1),s.restElement&&(n=!0),e.push(t?`${t}.${s.name}`:s.name)):void 0!==s&&(o.push(!1),e.push(t?`${t}.${s}`:s)),e}),[]);return{hasPropertyRest:r,hasRestElement:n,names:s,rests:o}},c=e=>{if("TSIndexSignature"!==e.type&&"TSConstructSignatureDeclaration"!==e.type&&"TSCallSignatureDeclaration"!==e.type)return e.typeAnnotation&&"TSTypeLiteral"===e.typeAnnotation.typeAnnotation.type?[e.key.name,e.typeAnnotation.typeAnnotation.members.map((e=>c(e)))]:e.key.name},l=(0,r.default)(),u=(e,t)=>{switch(e){case"jsdoc":return Xe.jsdocTags;case"typescript":return Xe.typeScriptTags;case"closure":case"permissive":return Xe.closureTags;default:return l.hasBeenWarned(t,"mode")||(t.report({loc:{start:{column:1,line:1}},message:`Unrecognized value \`${e}\` for \`settings.jsdoc.mode\`.`}),l.markSettingAsWarned(t,"mode")),Xe.jsdocTags}},p=(e,t,r,o={})=>{var s;const a=Object.values(o);if(a.includes(r)||a.some((e=>e&&"object"==typeof e&&e.replacement===r)))return r;const i=n.default.mapKeys(o,((e,t)=>t.replace("tag ","")));if(n.default.has(i,r))return i[r];const c=u(t,e),l=null===(s=Object.entries(c).find((([,e])=>e.includes(r))))||void 0===s?void 0:s[0];return l||r},d=(e,t)=>{const r=t.toLowerCase();return n.default.some(e.tags,(e=>e.tag.toLowerCase()===r))},f=(e,t)=>t.some((t=>d(e,t))),m=(e,t)=>(e.has(t)||e.set(t,new Map),e.get(t)),g=(e,t=a)=>{Object.entries(e).forEach((([e,{name:n,type:r,required:o=[]}])=>{const s=m(t,e);s.set("nameContents",n),s.set("typeAllowed",r);const a=o.includes("name");if(a&&!1===n)throw new Error('Cannot add "name" to `require` with the tag\'s `name` set to `false`');s.set("nameRequired",a);const i=o.includes("type");if(i&&!1===r)throw new Error('Cannot add "type" to `require` with the tag\'s `type` set to `false`');s.set("typeRequired",i);const c=o.includes("typeOrNameRequired");if(c&&!1===n)throw new Error('Cannot add "typeOrNameRequired" to `require` with the tag\'s `name` set to `false`');if(c&&!1===r)throw new Error('Cannot add "typeOrNameRequired" to `require` with the tag\'s `type` set to `false`');s.set("typeOrNameRequired",c)}))},h=(e,t=a)=>m(t,e).get("typeRequired"),y=(e,t=a)=>{if(h(e,t))return!0;const n=m(t,e).get("typeAllowed");return void 0===n||n},x=new Set(["namepath-defining","namepath-referencing"]),b=(e,t=a)=>{const n=m(t,e);return x.has(n.get("nameContents"))},E=(e,t=a)=>m(t,e).get("nameRequired"),S=(e,t)=>{if(!e)return!1;switch(e.type){case"FunctionExpression":case"FunctionDeclaration":case"ArrowFunctionExpression":return e.expression||S(e.body,t);case"BlockStatement":return e.body.some((e=>"FunctionDeclaration"!==e.type&&S(e,t)));case"LabeledStatement":case"WhileStatement":case"DoWhileStatement":case"ForStatement":case"ForInStatement":case"ForOfStatement":case"WithStatement":return S(e.body,t);case"IfStatement":return S(e.consequent,t)||S(e.alternate,t);case"TryStatement":return S(e.block,t)||S(e.handler&&e.handler.body,t)||S(e.finalizer,t);case"SwitchStatement":return e.cases.some((e=>e.consequent.some((e=>S(e,t)))));case"ReturnStatement":return null!==e.argument&&(!t||!(e=>"NewExpression"===e.type&&"Identifier"===e.callee.type&&"Promise"===e.callee.name)(e.argument)||t(e.argument));default:return!1}},C=(e,t)=>{if(!e)return!1;switch(e.type){case"OptionalCallExpression":case"CallExpression":return e.callee.name===t&&(e.arguments.length>1||void 0!==e.arguments[0])||e.arguments.some((e=>"Identifier"===e.type&&e.name===t||C(e,t)));case"ChainExpression":case"Decorator":case"ExpressionStatement":return C(e.expression,t);case"ClassBody":case"BlockStatement":return e.body.some((e=>C(e,t)));case"FunctionExpression":case"FunctionDeclaration":case"ArrowFunctionExpression":var n;return(null===(n=e.params[0])||void 0===n?void 0:n.name)!==t&&C(e.body,t);case"LabeledStatement":case"WhileStatement":case"DoWhileStatement":case"ForStatement":case"ForInStatement":case"ForOfStatement":case"WithStatement":return C(e.body,t);case"ConditionalExpression":case"IfStatement":return C(e.test,t)||C(e.consequent,t)||C(e.alternate,t);case"TryStatement":return C(e.block,t)||C(e.handler&&e.handler.body,t)||C(e.finalizer,t);case"SwitchStatement":return e.cases.some((e=>e.consequent.some((e=>C(e,t)))));case"ArrayPattern":case"ArrayExpression":return e.elements.some((e=>C(e,t)));case"AssignmentPattern":return C(e.right,t);case"AssignmentExpression":case"BinaryExpression":case"LogicalExpression":return C(e.left,t)||C(e.right,t);case"SequenceExpression":case"TemplateLiteral":return e.expressions.some((e=>C(e,t)));case"ObjectPattern":case"ObjectExpression":return e.properties.some((e=>C(e,t)));case"ClassMethod":case"MethodDefinition":return e.decorators&&e.decorators.some((e=>C(e,t)))||e.computed&&C(e.key,t)||C(e.value,t);case"ObjectProperty":case"ClassProperty":case"Property":return e.computed&&C(e.key,t)||C(e.value,t);case"ObjectMethod":return e.computed&&C(e.key,t)||e.arguments.some((e=>C(e,t)));case"ClassExpression":case"ClassDeclaration":return C(e.body,t);case"AwaitExpression":case"SpreadElement":case"UnaryExpression":case"YieldExpression":return C(e.argument,t);case"VariableDeclaration":return e.declarations.some((e=>C(e,t)));case"VariableDeclarator":return C(e.id,t)||C(e.init,t);case"TaggedTemplateExpression":return C(e.quasi,t);case"OptionalMemberExpression":case"MemberExpression":return C(e.object,t)||C(e.property,t);case"Import":case"ImportExpression":return C(e.source,t);case"ReturnStatement":return null!==e.argument&&C(e.argument,t);default:return!1}},v=(e,t)=>{if(!e)return!1;switch(e.type){case"BlockStatement":return e.body.some((e=>!["ArrowFunctionExpression","FunctionDeclaration","FunctionExpression"].includes(e.type)&&v(e,t)));case"OptionalCallExpression":case"CallExpression":return e.arguments.some((e=>v(e,t)));case"ChainExpression":case"ExpressionStatement":return v(e.expression,t);case"LabeledStatement":case"WhileStatement":case"DoWhileStatement":case"ForStatement":case"ForInStatement":case"ForOfStatement":case"WithStatement":return v(e.body,t);case"ConditionalExpression":case"IfStatement":return v(e.test,t)||v(e.consequent,t)||v(e.alternate,t);case"TryStatement":return v(e.block,t)||v(e.handler&&e.handler.body,t)||v(e.finalizer,t);case"SwitchStatement":return e.cases.some((e=>e.consequent.some((e=>v(e,t)))));case"ArrayPattern":case"ArrayExpression":return e.elements.some((e=>v(e,t)));case"AssignmentPattern":return v(e.right,t);case"VariableDeclaration":return e.declarations.some((e=>v(e,t)));case"VariableDeclarator":return v(e.id,t)||v(e.init,t);case"AssignmentExpression":case"BinaryExpression":case"LogicalExpression":return v(e.left,t)||v(e.right,t);case"SequenceExpression":case"TemplateLiteral":return e.expressions.some((e=>v(e,t)));case"ObjectPattern":case"ObjectExpression":return e.properties.some((e=>v(e,t)));case"ObjectProperty":case"ClassProperty":case"Property":return e.computed&&v(e.key,t)||v(e.value,t);case"ObjectMethod":return e.computed&&v(e.key,t)||e.arguments.some((e=>v(e,t)));case"SpreadElement":case"UnaryExpression":return v(e.argument,t);case"TaggedTemplateExpression":return v(e.quasi,t);case"OptionalMemberExpression":case"MemberExpression":return v(e.object,t)||v(e.property,t);case"Import":case"ImportExpression":return v(e.source,t);case"ReturnStatement":return null!==e.argument&&v(e.argument,t);case"YieldExpression":return t?"VariableDeclarator"===e.parent.type:null!==e.argument;default:return!1}},A=(e,t)=>{if(!e)return!1;switch(e.type){case"FunctionExpression":case"FunctionDeclaration":case"ArrowFunctionExpression":return!t&&A(e.body,!0);case"BlockStatement":return e.body.some((e=>"FunctionDeclaration"!==e.type&&A(e)));case"LabeledStatement":case"WhileStatement":case"DoWhileStatement":case"ForStatement":case"ForInStatement":case"ForOfStatement":case"WithStatement":return A(e.body);case"IfStatement":return A(e.consequent)||A(e.alternate);case"TryStatement":return A(e.handler&&e.handler.body)||A(e.finalizer);case"SwitchStatement":return e.cases.some((e=>e.consequent.some((e=>A(e)))));case"ThrowStatement":return!0;default:return!1}},k=(e,t)=>e.filter(t),w=new Set(["param","arg","argument","property","prop","template","returns","return"]),P=e=>{var t;return"MethodDefinition"===(null==e?void 0:e.type)&&"constructor"===e.kind||"constructor"===(null==e||null===(t=e.parent)||void 0===t?void 0:t.kind)},T=e=>e&&"get"===e.parent.kind,I=e=>e&&"set"===e.parent.kind,D=e=>{const{type:t,kind:n,key:{name:r}}=e,o="get"===n?"set":"get",s="MethodDefinition"===t?"body":"properties";return e.parent[s].some((({kind:e,key:{name:t}})=>e===o&&t===r))},O=e=>e.replace(/\.(['"])(.*)\1/gu,".$2");var B={comparePaths:e=>t=>t===e||O(t)===O(e),dropPathSegmentQuotes:O,enforcedContexts:(e,t)=>{const{contexts:n=(!0===t?["ArrowFunctionExpression","FunctionDeclaration","FunctionExpression"]:t)}=e.options[0]||{};return n},exemptSpeciaMethods:(e,t,n,r)=>{const o=e=>{var t,o;const s=r[0].properties;return null!==(t=null===(o=n.options[0])||void 0===o?void 0:o[e])&&void 0!==t?t:s[e]&&s[e].default},s=o("checkGetters"),a=o("checkSetters");return!o("checkConstructors")&&(P(t)||f(e,["class","constructor"]))||T(t)&&(!s||"no-setter"===s&&D(t.parent))||I(t)&&(!a||"no-getter"===a&&D(t.parent))},filterTags:k,flattenRoots:i,getContextObject:(e,t)=>{const n={};return e.forEach((e=>{"object"==typeof e?n[e.context]=t:n[e]=t})),n},getFunctionParameterNames:(e,t)=>{const r=(e,o)=>{var s,a;if(n.default.has(e,"typeAnnotation")||n.default.has(e,"left.typeAnnotation")){const t=n.default.has(e,"left.typeAnnotation")?e.left.typeAnnotation:e.typeAnnotation;if("TSTypeLiteral"===t.typeAnnotation.type){const r=t.typeAnnotation.members.map((e=>c(e))),o={...i(r),annotationParamName:e.name};return n.default.has(e,"name")||n.default.has(e,"left.name")?[n.default.has(e,"left.name")?e.left.name:e.name,o]:[void 0,o]}}if(n.default.has(e,"name"))return e.name;if(n.default.has(e,"left.name"))return e.left.name;if("ObjectPattern"===e.type||"ObjectPattern"===(null===(s=e.left)||void 0===s?void 0:s.type)){var l;const t=(e.properties||(null===(l=e.left)||void 0===l?void 0:l.properties)).map((e=>r(e,!0)));return[void 0,i(t)]}if("Property"===e.type){switch(e.value.type){case"ArrayPattern":return[e.key.name,e.value.elements.map(((e,t)=>({name:t,restElement:"RestElement"===e.type})))];case"ObjectPattern":return[e.key.name,e.value.properties.map((e=>r(e,o)))];case"AssignmentPattern":switch(e.value.left.type){case"Identifier":if(t&&"ObjectExpression"===e.value.right.type)return[e.key.name,e.value.right.properties.map((e=>r(e,o)))];break;case"ObjectPattern":return[e.key.name,e.value.left.properties.map((e=>r(e,o)))];case"ArrayPattern":return[e.key.name,e.value.left.elements.map(((e,t)=>({name:t,restElement:"RestElement"===e.type})))]}}switch(e.key.type){case"Identifier":return e.key.name;case"Literal":return e.key.raw||e.key.value;default:return}}if("ArrayPattern"===e.type||"ArrayPattern"===(null===(a=e.left)||void 0===a?void 0:a.type)){var u;const t=(e.elements||(null===(u=e.left)||void 0===u?void 0:u.elements)).map(((e,t)=>({name:t,restElement:"RestElement"===e.type})));return[void 0,i(t)]}if(["RestElement","ExperimentalRestProperty"].includes(e.type))return{isRestProperty:o,name:e.argument.name,restElement:!0};if("TSParameterProperty"===e.type)return r(e.parameter,!0);throw new Error(`Unsupported function signature format: \`${e.type}\`.`)};return(e.params||e.value.params).map((e=>r(e)))},getIndent:e=>{var t,n;return(null!==(t=null===(n=e.text.match(/^\n*([ \t]+)/u))||void 0===n?void 0:n[1])&&void 0!==t?t:"")+" "},getJsdocTagsDeep:(e,t)=>{const n=[];return e.tags.forEach((({name:e,tag:r,type:o},s)=>{r===t&&n.push({idx:s,name:e,type:o})})),n},getPreferredTagName:p,getRegexFromString:(e,t)=>{const n=e.match(/^\/(.*)\/([gimyus]*)$/us);let r="u",o=e;n&&([,o,r]=n,r||(r="u"));return r=[...new Set(r+(t||""))].join(""),new RegExp(o,r)},getTagsByType:(e,t,n,r)=>{const o=p(e,t,"description",r),s=[];return{tagsWithNames:k(n,(e=>{const{tag:t}=e,n=w.has(t);return n||t===o||s.push(e),n})),tagsWithoutNames:s}},getTagStructureForMode:(e,t)=>{const n=(0,o.default)(e);try{g(t,n)}catch{}return n},hasATag:f,hasDefinedTypeTag:e=>{if(null==e)return!1;const t=e.type.trim();return"undefined"!==t&&"void"!==t},hasParams:e=>e.params.length,hasReturnValue:S,hasTag:d,hasThrowValue:A,hasValueOrExecutorHasNonEmptyResolveValue:(e,t)=>S(e,(e=>{if(t)return!0;const[{params:n,body:r}={}]=e.arguments;if(null==n||!n.length)return!1;const[{name:o}]=n;return C(r,o)})),hasYieldValue:(e,t)=>e.generator&&(e.expression||v(e.body,t)),isConstructor:P,isGetter:T,isNamepathDefiningTag:(e,t=a)=>"namepath-defining"===m(t,e).get("nameContents"),isSetter:I,isValidTag:(e,t,r,o)=>{const s=u(t,e),a=o;return Object.keys(s).concat(n.default.flatten(Object.values(s))).concat(a).includes(r)},overrideTagStructure:g,parseClosureTemplateTag:e=>e.name.split(",").map((e=>e.trim())),setTagStructure:e=>{a=(0,o.default)(e)},tagMightHaveNamepath:b,tagMightHaveNamePosition:(e,t=a)=>{const n=m(t,e).get("nameContents");return void 0===n||Boolean(n)},tagMightHaveTypePosition:y,tagMissingRequiredTypeOrNamepath:(e,t=a)=>{const n=h(e.tag,t),r=y(e.tag,t)&&Boolean(e.type),o=(E(e.tag,t)||b(e.tag,t))&&Boolean(e.name),s=((e,t)=>m(t,e).get("typeOrNameRequired"))(e.tag,t),i=((e,t)=>y(e,t)||b(e,t))(e.tag,t)&&(r||o);return s&&!i&&!n},tagMustHaveNamePosition:E,tagMustHaveTypePosition:h};t.default=B,e.exports=t.default})),Ze=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){var n;const r=null==t||null===(n=t.meta)||void 0===n?void 0:n.type;if(!r||!["problem","suggestion","layout"].includes(r))throw new TypeError('Rule must include `meta.type` option (with value "problem", "suggestion", or "layout")');if("function"!=typeof e)throw new TypeError("The iterator argument must be a function.");if(t.checkFile)return((e,t)=>({create(t){const n=t.getSourceCode(),r=f(t);return r?{"Program:exit"(){const o=n.getAllComments(),{lines:s}=n,a=d(t,r);e({allComments:o,context:t,lines:s,makeReport:m,settings:r,sourceCode:n,utils:a})}}:{}},meta:t.meta}))(e,t);if(t.iterateAllJsdocs)return h(e,t);return{create(n){let r;if(t.contextDefaults&&(r=i.default.enforcedContexts(n,t.contextDefaults),r.includes("any")))return h(e,t).create(n);const o=n.getSourceCode(),s=f(n);if(!s)return{};const{lines:a}=o,c=r=>{const i=(0,Ke.getJSDocComment)(o,r,s);i&&g(t,n,a,i,r,s,o,e)};return t.contextDefaults?i.default.getContextObject(r,c):{ArrowFunctionExpression:c,FunctionDeclaration:c,FunctionExpression:c}},meta:t.meta}},t.parseComment=t.getSettings=void 0;var n=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var t=l();if(t&&t.has(e))return t.get(e);var n={},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if(Object.prototype.hasOwnProperty.call(e,o)){var s=r?Object.getOwnPropertyDescriptor(e,o):null;s&&(s.get||s.set)?Object.defineProperty(n,o,s):n[o]=e[o]}n.default=e,t&&t.set(e,n);return n}(ke),r=c(Ae),o=c(be),s=c(Ce),a=c(F.default),i=c(Qe);function c(e){return e&&e.__esModule?e:{default:e}}function l(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return l=function(){return e},e}const u=new Map,p=(e,t)=>(0,Je.parse)(`/*${e.value}*/`,{tokenizers:[(0,o.default)(),e=>["default","defaultvalue","see"].includes(e.tag)?e:(0,s.default)()(e),e=>{if("template"===e.tag){const t=e.source[0].tokens.description,n=t.search(/(?"see"===e.tag&&/\{@link.+?\}/u.test(e.source[0].source))(e)?e:(0,r.default)()(e)},e=>(0,n.default)((0,n.getJoiner)("preserve"))(e)]})[0]||(0,le.seedBlock)({source:[{number:0,tokens:(0,le.seedTokens)({delimiter:"/**",description:"",end:"",postDelimiter:"",start:""})},{number:1,tokens:(0,le.seedTokens)({delimiter:"",description:"",end:"*/",postDelimiter:"",start:t+" "})}]});t.parseComment=p;const d=(e,{tagNamePreference:t,mode:n})=>{const r={reportSettings:t=>{e.report({loc:{start:{column:1,line:1}},message:t})},parseClosureTemplateTag:e=>i.default.parseClosureTemplateTag(e),getPreferredTagNameObject:({tagName:r})=>{const o=i.default.getPreferredTagName(e,n,r,t);return!1===o||o&&"object"==typeof o&&!o.replacement?{blocked:!0,tagName:r}:o}};return r},f=e=>{var t,n,r,o,s,a,c,l,u,p,d,f,m,g,h,y,x;const b={ignorePrivate:Boolean(null===(t=e.settings.jsdoc)||void 0===t?void 0:t.ignorePrivate),ignoreInternal:Boolean(null===(n=e.settings.jsdoc)||void 0===n?void 0:n.ignoreInternal),maxLines:Number(null!==(r=null===(o=e.settings.jsdoc)||void 0===o?void 0:o.maxLines)&&void 0!==r?r:1),minLines:Number(null!==(s=null===(a=e.settings.jsdoc)||void 0===a?void 0:a.minLines)&&void 0!==s?s:0),tagNamePreference:null!==(c=null===(l=e.settings.jsdoc)||void 0===l?void 0:l.tagNamePreference)&&void 0!==c?c:{},preferredTypes:null!==(u=null===(p=e.settings.jsdoc)||void 0===p?void 0:p.preferredTypes)&&void 0!==u?u:{},structuredTags:null!==(d=null===(f=e.settings.jsdoc)||void 0===f?void 0:f.structuredTags)&&void 0!==d?d:{},overrideReplacesDocs:null===(m=e.settings.jsdoc)||void 0===m?void 0:m.overrideReplacesDocs,implementsReplacesDocs:null===(g=e.settings.jsdoc)||void 0===g?void 0:g.implementsReplacesDocs,augmentsExtendsReplacesDocs:null===(h=e.settings.jsdoc)||void 0===h?void 0:h.augmentsExtendsReplacesDocs,mode:null!==(y=null===(x=e.settings.jsdoc)||void 0===x?void 0:x.mode)&&void 0!==y?y:e.parserPath.includes("@typescript-eslint")?"typescript":"jsdoc"};i.default.setTagStructure(b.mode);try{i.default.overrideTagStructure(b.structuredTags)}catch(t){return e.report({loc:{start:{column:1,line:1}},message:t.message}),!1}return b};t.getSettings=f;const m=(e,t)=>(n,r=null,o=null,s=null)=>{let a;if(o){"line"in o||(o.line=o.source[0].number);const e=t.loc.start.line+o.line;if(a={end:{line:e},start:{line:e}},o.column){const e=t.loc.start.column+o.column;a.end.column=e,a.start.column=e}}e.report({data:s,fix:r,loc:a,message:n,node:t})},g=(e,t,n,r,o,s,c,l,f,g)=>{const h=n[r.loc.start.line-1].charAt(0).repeat(r.loc.start.column),y=p(r,h),x=m(t,r),b=((e,t,n,r,o,s,c,l,u)=>{const f=s.getAncestors(),m=s.getSourceCode(),g=d(s,r),{tagNamePreference:h,overrideReplacesDocs:y,implementsReplacesDocs:x,augmentsExtendsReplacesDocs:b,maxLines:E,minLines:S,mode:C}=r;return g.isIteratingFunction=()=>!c||["MethodDefinition","ArrowFunctionExpression","FunctionDeclaration","FunctionExpression"].includes(e&&e.type),g.isVirtualFunction=()=>c&&g.hasATag(["callback","function","func","method"]),g.stringify=(e,t)=>(0,Je.stringify)(t?(0,le.rewireSpecs)(e):e),g.reportJSDoc=(e,r,s,a)=>{o(e,s?e=>{s();const r=g.stringify(t,a);return e.replaceText(n,r)}:null,r)},g.getRegexFromString=(e,t)=>i.default.getRegexFromString(e,t),g.getDescription=()=>{const e=[];let n;return t.source[0].tokens.description&&e.push(t.source[0].tokens.description),t.source.slice(1).some((({tokens:{description:t,tag:r,end:o}},s)=>r||o?(n=s,!0):(e.push(t),!1))),{description:e.join("\n"),lastDescriptionLine:n}},g.changeTag=(e,...t)=>{e.source.forEach(((e,n)=>{e.tokens={...e.tokens,...t[n]}}))},g.setTag=(e,t)=>{e.source=[{number:e.line,tokens:(0,le.seedTokens)({delimiter:"*",postDelimiter:" ",start:u+" ",tag:"@"+e.tag,...t})}]},g.removeTag=e=>{const{source:n}=t.tags[e];let r;const o=t.source[0].number;n.forEach((({number:e})=>{const n=t.source.findIndex((({number:t,tokens:{end:n}})=>e===t&&!n));n>-1&&(t.source.splice(n,1),r=n)})),t.source.slice(r).forEach(((e,t)=>{e.number=o+r+t}))},g.addTag=e=>{var n,r,o;const s=(null!==(n=null===(r=t.tags[t.tags.length-1])||void 0===r||null===(o=r.source[0])||void 0===o?void 0:o.number)&&void 0!==n?n:0)+1;t.source.splice(s,0,{number:s,source:"",tokens:(0,le.seedTokens)({delimiter:"*",postDelimiter:" ",start:u+" ",tag:`@${e}`})}),t.source.slice(s+1).forEach((e=>{e.number++}))},g.flattenRoots=e=>i.default.flattenRoots(e),g.getFunctionParameterNames=t=>i.default.getFunctionParameterNames(e,t),g.hasParams=()=>i.default.hasParams(e),g.isGenerator=()=>e&&(e.generator||"MethodDefinition"===e.type&&e.value.generator||["ExportNamedDeclaration","ExportDefaultDeclaration"].includes(e.type)&&e.declaration.generator),g.isConstructor=()=>i.default.isConstructor(e),g.getJsdocTagsDeep=e=>{const n=g.getPreferredTagName({tagName:e});return!!n&&i.default.getJsdocTagsDeep(t,n)},g.getPreferredTagName=({tagName:e,skipReportingBlockedTag:t=!1,allowObjectReturn:n=!1,defaultMessage:r=`Unexpected tag \`@${e}\``})=>{const a=i.default.getPreferredTagName(s,C,e,h),c=a&&"object"==typeof a;if(g.hasTag(e)&&(!1===a||c&&!a.replacement)){if(t)return{blocked:!0,tagName:e};const n=c&&a.message||r;return o(n,null,g.getTags(e)[0]),!1}return c&&!n?a.replacement:a},g.isValidTag=(e,t)=>i.default.isValidTag(s,C,e,t),g.hasATag=e=>i.default.hasATag(t,e),g.hasTag=e=>i.default.hasTag(t,e),g.comparePaths=e=>i.default.comparePaths(e),g.dropPathSegmentQuotes=e=>i.default.dropPathSegmentQuotes(e),g.avoidDocs=()=>{var n,r;if(!1!==y&&(g.hasTag("override")||g.classHasTag("override"))||!1!==x&&(g.hasTag("implements")||g.classHasTag("implements"))||b&&(g.hasATag(["augments","extends"])||g.classHasTag("augments")||g.classHasTag("extends")))return!0;if(i.default.exemptSpeciaMethods(t,e,s,l.meta.schema))return!0;const o=null!==(n=null===(r=s.options[0])||void 0===r?void 0:r.exemptedBy)&&void 0!==n?n:["inheritDoc",..."closure"===C?[]:["inheritdoc"]];return!(!o.length||!g.getPresentTags(o).length)},["tagMightHaveNamePosition","tagMightHaveTypePosition"].forEach((e=>{g[e]=(t,n)=>!!i.default[e](t)||!!n&&(!!n.some((n=>i.default[e](t,n)))&&{otherMode:!0})})),["tagMustHaveNamePosition","tagMustHaveTypePosition","tagMissingRequiredTypeOrNamepath"].forEach((e=>{g[e]=(t,n)=>!!i.default[e](t)&&(!!n.every((n=>i.default[e](t,n)))||{otherMode:!1})})),["isNamepathDefiningTag","tagMightHaveNamepath"].forEach((e=>{g[e]=t=>i.default[e](t)})),g.getTagStructureForMode=e=>i.default.getTagStructureForMode(e,r.structuredTags),g.hasDefinedTypeTag=e=>i.default.hasDefinedTypeTag(e),g.hasValueOrExecutorHasNonEmptyResolveValue=t=>i.default.hasValueOrExecutorHasNonEmptyResolveValue(e,t),g.hasYieldValue=()=>["ExportNamedDeclaration","ExportDefaultDeclaration"].includes(e.type)?i.default.hasYieldValue(e.declaration):i.default.hasYieldValue(e),g.hasYieldReturnValue=()=>i.default.hasYieldValue(e,!0),g.hasThrowValue=()=>i.default.hasThrowValue(e),g.isAsync=()=>e.async,g.getTags=e=>g.filterTags((t=>t.tag===e)),g.getPresentTags=e=>g.filterTags((t=>e.includes(t.tag))),g.filterTags=e=>i.default.filterTags(t.tags,e),g.getTagsByType=e=>i.default.getTagsByType(s,C,e,h),g.hasOptionTag=e=>{var t;const{tags:n}=null!==(t=s.options[0])&&void 0!==t?t:{};return Boolean(n&&n.includes(e))},g.getClassNode=()=>[...f,e].reverse().find((e=>e&&["ClassDeclaration","ClassExpression"].includes(e.type)))||null,g.getClassJsdoc=()=>{const e=g.getClassNode();if(!e)return null;const t=(0,Ke.getJSDocComment)(m,e,{maxLines:E,minLines:S});if(t){const e=" ".repeat(t.loc.start.column);return p(t,e)}return null},g.classHasTag=e=>{const t=g.getClassJsdoc();return Boolean(t)&&i.default.hasTag(t,e)},g.forEachPreferredTag=(e,n,r=!1)=>{const o=g.getPreferredTagName({skipReportingBlockedTag:r,tagName:e});!o||r&&o&&"object"==typeof o||a.default.filter(t.tags,{tag:o}).forEach((e=>{n(e,o)}))},g})(o,y,r,s,x,t,g,e,h);!e.checkInternal&&s.ignoreInternal&&b.hasTag("internal")||!e.checkPrivate&&s.ignorePrivate&&(b.hasTag("private")||a.default.filter(y.tags,{tag:"access"}).some((({description:e})=>"private"===e)))||l({context:t,globalState:u,indent:h,iteratingAll:g,jsdoc:y,jsdocNode:r,node:o,report:x,settings:s,sourceCode:c,state:f,utils:b})},h=(e,t)=>{const n=[];let r;const o=(n,o,s,a,i)=>{const c=n.getSourceCode(),{lines:l}=c,u=d(n,r);s.forEach((s=>{/^\/\*\*\s/.test(c.getText(s))&&g(t,n,l,s,o,r,c,e,a,!0)})),i&&t.exit&&t.exit({context:n,state:a,utils:u})};return{create(e){const s=e.getSourceCode();if(r=f(e),!r)return{};const a={};return{"*:not(Program)"(i){if(i!==(0,Ke.getReducedASTNode)(i,s))return;const c=(0,Ke.getJSDocComment)(s,i,r);n.includes(c)||(c?(n.push(c),o(e,i,[c],a)):t.nonComment&&t.nonComment({node:i,state:a}))},"Program:exit"(){const t=s.getAllComments().filter((e=>!n.includes(e)));o(e,null,t,a,!0)}}},meta:t.meta}}})),et=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n,r=(n=Ze)&&n.__esModule?n:{default:n};const o=["package","private","protected","public"];var s=(0,r.default)((({report:e,utils:t})=>{t.forEachPreferredTag("access",((t,n)=>{const r="access"===n?t.description:t.name+" "+t.description;o.includes(r.trim())||e(`Missing valid JSDoc @${n} level.`,null,t)}));const n=t.getTags("access").length,r=t.getPresentTags(o).length;n&&r&&e("The @access tag may not be used with specific access-control tags (@package, @private, @protected, or @public)."),(n>1||r>1)&&e("At most one access-control tag may be present on a jsdoc block.")}),{checkPrivate:!0,iterateAllJsdocs:!0,meta:{docs:{description:"Checks that `@access` tags have a valid value.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-access"},type:"suggestion"}});t.default=s,e.exports=t.default})),tt=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n,r=(n=Ze)&&n.__esModule?n:{default:n};const o=e=>e.replace(/^\s+/u,"");var s=(0,r.default)((({sourceCode:e,jsdocNode:t,report:n,indent:r})=>{const s=r.length+1,a=e.getText(t).split("\n").slice(1).map((e=>e.split("*")[0])).filter((e=>!o(e).length)),i=n=>{const s=e.getText(t).split("\n").map(((e,t)=>!t||o(e.split("*")[0]).length?e:`${r} ${o(e)}`)).join("\n");return n.replaceText(t,s)};a.some(((e,t)=>e.length!==s&&(n("Expected JSDoc block to be aligned.",i,{line:t+1}),!0)))}),{iterateAllJsdocs:!0,meta:{docs:{description:"Reports invalid alignment of JSDoc block asterisks.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-alignment"},fixable:"code",type:"layout"}});t.default=s,e.exports=t.default})),nt={configFile:null,baseConfig:!1,rulePaths:[],useEslintrc:!0,envs:[],globals:[],extensions:null,ignore:!0,ignorePath:void 0,cache:!1,cacheLocation:"",cacheFile:".eslintcache",cacheStrategy:"metadata",fix:!1,allowInlineConfig:!0,reportUnusedDisableDirectives:void 0,globInputPaths:!0},rt={name:"eslint",version:"7.24.0",author:"Nicholas C. Zakas ",description:"An AST-based pattern checker for JavaScript.",bin:{eslint:"./bin/eslint.js"},main:"./lib/api.js",scripts:{test:"node Makefile.js test","test:cli":"mocha",lint:"node Makefile.js lint",fix:"node Makefile.js lint -- fix",fuzz:"node Makefile.js fuzz","generate-release":"node Makefile.js generateRelease","generate-alpharelease":"node Makefile.js generatePrerelease -- alpha","generate-betarelease":"node Makefile.js generatePrerelease -- beta","generate-rcrelease":"node Makefile.js generatePrerelease -- rc","publish-release":"node Makefile.js publishRelease",docs:"node Makefile.js docs",gensite:"node Makefile.js gensite",webpack:"node Makefile.js webpack",perf:"node Makefile.js perf"},gitHooks:{"pre-commit":"lint-staged"},"lint-staged":{"*.js":["eslint --fix","git add"],"*.md":"markdownlint"},files:["LICENSE","README.md","bin","conf","lib","messages"],repository:"eslint/eslint",funding:"https://opencollective.com/eslint",homepage:"https://eslint.org",bugs:"https://github.com/eslint/eslint/issues/",dependencies:{"@babel/code-frame":"7.12.11","@eslint/eslintrc":"^0.4.0",ajv:"^6.10.0",chalk:"^4.0.0","cross-spawn":"^7.0.2",debug:"^4.0.1",doctrine:"^3.0.0",enquirer:"^2.3.5","eslint-scope":"^5.1.1","eslint-utils":"^2.1.0","eslint-visitor-keys":"^2.0.0",espree:"^7.3.1",esquery:"^1.4.0",esutils:"^2.0.2","file-entry-cache":"^6.0.1","functional-red-black-tree":"^1.0.1","glob-parent":"^5.0.0",globals:"^13.6.0",ignore:"^4.0.6","import-fresh":"^3.0.0",imurmurhash:"^0.1.4","is-glob":"^4.0.0","js-yaml":"^3.13.1","json-stable-stringify-without-jsonify":"^1.0.1",levn:"^0.4.1",lodash:"^4.17.21",minimatch:"^3.0.4","natural-compare":"^1.4.0",optionator:"^0.9.1",progress:"^2.0.0",regexpp:"^3.1.0",semver:"^7.2.1","strip-ansi":"^6.0.0","strip-json-comments":"^3.1.0",table:"^6.0.4","text-table":"^0.2.0","v8-compile-cache":"^2.0.3"},devDependencies:{"@babel/core":"^7.4.3","@babel/preset-env":"^7.4.3",acorn:"^7.2.0","babel-loader":"^8.0.5",chai:"^4.0.1",cheerio:"^0.22.0","common-tags":"^1.8.0","core-js":"^3.1.3",dateformat:"^3.0.3",ejs:"^3.0.2","escape-string-regexp":"^3.0.0",eslint:"file:.","eslint-config-eslint":"file:packages/eslint-config-eslint","eslint-plugin-eslint-plugin":"^2.2.1","eslint-plugin-internal-rules":"file:tools/internal-rules","eslint-plugin-jsdoc":"^25.4.3","eslint-plugin-node":"^11.1.0","eslint-release":"^2.0.0",eslump:"^2.0.0",esprima:"^4.0.1","fs-teardown":"^0.1.0",glob:"^7.1.6",jsdoc:"^3.5.5",karma:"^6.1.1","karma-chrome-launcher":"^3.1.0","karma-mocha":"^2.0.1","karma-mocha-reporter":"^2.2.5","karma-webpack":"^5.0.0","lint-staged":"^10.1.2","load-perf":"^0.2.0",markdownlint:"^0.19.0","markdownlint-cli":"^0.22.0",memfs:"^3.0.1",mocha:"^8.3.2","mocha-junit-reporter":"^2.0.0","node-polyfill-webpack-plugin":"^1.0.3","npm-license":"^0.3.3",nyc:"^15.0.1",proxyquire:"^2.0.1",puppeteer:"^7.1.0",recast:"^0.19.0","regenerator-runtime":"^0.13.2",shelljs:"^0.8.2",sinon:"^9.0.1",temp:"^0.9.0",webpack:"^5.23.0","webpack-cli":"^4.5.0",yorkie:"^2.0.0"},keywords:["ast","lint","javascript","ecmascript","espree"],license:"MIT",engines:{node:"^10.12.0 || >=12.0.0"}};const ot=N.default.createRequire||N.default.createRequireFromPath;var st={resolve(e,t){try{return ot(t).resolve(e)}catch(n){throw"object"==typeof n&&null!==n&&"MODULE_NOT_FOUND"===n.code&&!n.requireStack&&n.message.includes(e)&&(n.message+=`\nRequire stack:\n- ${t}`),n}}};const{escapeRegExp:at}=F.default,{Minimatch:ct}=R.default,{Legacy:{IgnorePattern:lt,CascadingConfigArrayFactory:ut}}=B.default,pt=M.default("eslint:file-enumerator"),dt={dot:!0,matchBase:!0},ft=/(?:(?:^\.)|(?:[/\\]\.))[^/\\.].*/u,mt=new WeakMap;function gt(e){try{return D.default.statSync(e)}catch(e){if("ENOENT"!==e.code)throw e;return null}}function ht(e){if(e){const t=e.map((e=>at(e.startsWith(".")?e.slice(1):e)));return new RegExp(`.\\.(?:${t.join("|")})$`,"u")}return null}class yt extends Error{constructor(e,t){super(`No files matching '${e}' were found${t?" (glob was disabled)":""}.`),this.messageTemplate="file-not-found",this.messageData={pattern:e,globDisabled:t}}}class xt extends Error{constructor(e){super(`All files matched by '${e}' are ignored.`),this.messageTemplate="all-files-ignored",this.messageData={pattern:e}}}var bt={FileEnumerator:class{constructor({cwd:e=process.cwd(),configArrayFactory:t=new ut({cwd:e,eslintRecommendedPath:O.default.resolve(__dirname,"../../conf/eslint-recommended.js"),eslintAllPath:O.default.resolve(__dirname,"../../conf/eslint-all.js")}),extensions:n=null,globInputPaths:r=!0,errorOnUnmatchedPattern:o=!0,ignore:s=!0}={}){mt.set(this,{configArrayFactory:t,cwd:e,defaultIgnores:lt.createDefaultIgnore(e),extensionRegExp:ht(n),globInputPaths:r,errorOnUnmatchedPattern:o,ignoreFlag:s})}isTargetPath(e,t){const{configArrayFactory:n,extensionRegExp:r}=mt.get(this);if(r)return r.test(e);if(e.endsWith(".js"))return!0;return(t||n.getConfigArrayForFile(e,{ignoreNotFoundError:!0})).isAdditionalTargetPath(e)}*iterateFiles(e){const{globInputPaths:t,errorOnUnmatchedPattern:n}=mt.get(this),r=Array.isArray(e)?e:[e];pt("Start to iterate files: %o",r);const o=new Set;for(const e of r){let r=!1,s=!1;if(e){for(const{config:t,filePath:n,flag:a}of this._iterateFiles(e))r=!0,1!==a&&(s=!0,o.has(n)||(o.add(n),yield{config:t,filePath:n,ignored:2===a}));if(n){if(!r)throw new yt(e,!t&&L.default(e));if(!s)throw new xt(e)}}}pt(`Complete iterating files: ${JSON.stringify(r)}`)}_iterateFiles(e){const{cwd:t,globInputPaths:n}=mt.get(this),r=O.default.resolve(t,e),o=ft.test(e),s=gt(r);return s&&s.isDirectory()?this._iterateFilesWithDirectory(r,o):s&&s.isFile()?this._iterateFilesWithFile(r):n&&function(e){return L.default("\\"===O.default.sep?e.replace(/\\/gu,"/"):e)}(e)?this._iterateFilesWithGlob(r,o):[]}_iterateFilesWithFile(e){pt(`File: ${e}`);const{configArrayFactory:t}=mt.get(this),n=t.getConfigArrayForFile(e);return[{config:n,filePath:e,flag:this._isIgnoredFile(e,{config:n,direct:!0})?2:0}]}_iterateFilesWithDirectory(e,t){return pt(`Directory: ${e}`),this._iterateFilesRecursive(e,{dotfiles:t,recursive:!0,selector:null})}_iterateFilesWithGlob(e,t){pt(`Glob: ${e}`);const n=O.default.resolve(j.default(e)),r=e.slice(n.length+1),o=/\*\*|\/|\\/u.test(r),s=new ct(e,dt);return pt(`recursive? ${o}`),this._iterateFilesRecursive(n,{dotfiles:t,recursive:o,selector:s})}*_iterateFilesRecursive(e,t){pt(`Enter the directory: ${e}`);const{configArrayFactory:n}=mt.get(this);let r=null;for(const o of function(e){try{return D.default.readdirSync(e,{withFileTypes:!0})}catch(e){if("ENOENT"!==e.code)throw e;return[]}}(e)){const s=O.default.join(e,o.name),a=o.isSymbolicLink()?gt(s):o;if(a)if(a.isFile()){r||(r=n.getConfigArrayForFile(s,{ignoreNotFoundError:!0}));if(t.selector?t.selector.match(s):this.isTargetPath(s,r)){const e=this._isIgnoredFile(s,{...t,config:r}),a=e?1:0;pt(`Yield: ${o.name}${e?" but ignored":""}`),yield{config:n.getConfigArrayForFile(s),filePath:s,flag:a}}else pt(`Didn't match: ${o.name}`)}else if(t.recursive&&a.isDirectory()){r||(r=n.getConfigArrayForFile(s,{ignoreNotFoundError:!0}));this._isIgnoredFile(s+O.default.sep,{...t,config:r})||(yield*this._iterateFilesRecursive(s,t))}}pt(`Leave the directory: ${e}`)}_isIgnoredFile(e,{config:t,dotfiles:n=!1,direct:r=!1}){const{configArrayFactory:o,defaultIgnores:s,ignoreFlag:a}=mt.get(this);if(a){return((t||o.getConfigArrayForFile(e,{ignoreNotFoundError:!0})).extractConfig(e).ignores||s)(e,n)}return!r&&s(e,n)}}};const Et=function(e,t){const n={};for(const[r,o]of Object.entries(e))Object.hasOwnProperty.call(t,r)||(n[r]=o);return n}(U.default.es2015,U.default.es5),St={Atomics:!1,SharedArrayBuffer:!1},Ct={BigInt:!1,BigInt64Array:!1,BigUint64Array:!1,globalThis:!1};var vt=new Map(Object.entries({builtin:{globals:U.default.es5},es6:{globals:Et,parserOptions:{ecmaVersion:6}},es2015:{globals:Et,parserOptions:{ecmaVersion:6}},es2017:{globals:{...Et,...St},parserOptions:{ecmaVersion:8}},es2020:{globals:{...Et,...St,...Ct},parserOptions:{ecmaVersion:11}},es2021:{globals:{...Et,...St,...Ct,AggregateError:!1,FinalizationRegistry:!1,WeakRef:!1},parserOptions:{ecmaVersion:12}},browser:{globals:U.default.browser},node:{globals:U.default.node,parserOptions:{ecmaFeatures:{globalReturn:!0}}},"shared-node-browser":{globals:U.default["shared-node-browser"]},worker:{globals:U.default.worker},serviceworker:{globals:U.default.serviceworker},commonjs:{globals:U.default.commonjs,parserOptions:{ecmaFeatures:{globalReturn:!0}}},amd:{globals:U.default.amd},mocha:{globals:U.default.mocha},jasmine:{globals:U.default.jasmine},jest:{globals:U.default.jest},phantomjs:{globals:U.default.phantomjs},jquery:{globals:U.default.jquery},qunit:{globals:U.default.qunit},prototypejs:{globals:U.default.prototypejs},shelljs:{globals:U.default.shelljs},meteor:{globals:U.default.meteor},mongo:{globals:U.default.mongo},protractor:{globals:U.default.protractor},applescript:{globals:U.default.applescript},nashorn:{globals:U.default.nashorn},atomtest:{globals:U.default.atomtest},embertest:{globals:U.default.embertest},webextensions:{globals:U.default.webextensions},greasemonkey:{globals:U.default.greasemonkey}}));const At=/\r\n|[\r\n\u2028\u2029]/u;var kt={breakableTypePattern:/^(?:(?:Do)?While|For(?:In|Of)?|Switch)Statement$/u,lineBreakPattern:At,createGlobalLinebreakMatcher:function(){return new RegExp(At.source,"gu")},shebangPattern:/^#!([^\r\n]+)/u},wt=ie((function(e){const t=["off","warn","error"],n=t.reduce(((e,t,n)=>(e[t]=n,e)),{}),r=[0,1,2,"off","warn","error"];e.exports={getRuleSeverity(e){const t=Array.isArray(e)?e[0]:e;return 0===t||1===t||2===t?t:"string"==typeof t&&n[t.toLowerCase()]||0},normalizeToStrings(e){e.rules&&Object.keys(e.rules).forEach((n=>{const r=e.rules[n];"number"==typeof r?e.rules[n]=t[r]||t[0]:Array.isArray(r)&&"number"==typeof r[0]&&(r[0]=t[r[0]]||t[0])}))},isErrorSeverity:t=>2===e.exports.getRuleSeverity(t),isValidSeverity(e){let t=Array.isArray(e)?e[0]:e;return"string"==typeof t&&(t=t.toLowerCase()),-1!==r.indexOf(t)},isEverySeverityValid(e){return Object.keys(e).every((t=>this.isValidSeverity(e[t])))},normalizeConfigGlobal(e){switch(e){case"off":return"off";case!0:case"true":case"writeable":case"writable":return"writable";case null:case!1:case"false":case"readable":case"readonly":return"readonly";default:throw new Error(`'${e}' is not a valid configuration for a global (use 'readonly', 'writable', or 'off')`)}}}}));const Pt={$schema:{type:"string"},env:{type:"object"},extends:{$ref:"#/definitions/stringOrStrings"},globals:{type:"object"},overrides:{type:"array",items:{$ref:"#/definitions/overrideConfig"},additionalItems:!1},parser:{type:["string","null"]},parserOptions:{type:"object"},plugins:{type:"array"},processor:{type:"string"},rules:{type:"object"},settings:{type:"object"},noInlineConfig:{type:"boolean"},reportUnusedDisableDirectives:{type:"boolean"},ecmaFeatures:{type:"object"}};var Tt={definitions:{stringOrStrings:{oneOf:[{type:"string"},{type:"array",items:{type:"string"},additionalItems:!1}]},stringOrStringsRequired:{oneOf:[{type:"string"},{type:"array",items:{type:"string"},additionalItems:!1,minItems:1}]},objectConfig:{type:"object",properties:{root:{type:"boolean"},ignorePatterns:{$ref:"#/definitions/stringOrStrings"},...Pt},additionalProperties:!1},overrideConfig:{type:"object",properties:{excludedFiles:{$ref:"#/definitions/stringOrStrings"},files:{$ref:"#/definitions/stringOrStringsRequired"},...Pt},required:["files"],additionalProperties:!1}},$ref:"#/definitions/objectConfig"};const It={ESLINT_LEGACY_ECMAFEATURES:"The 'ecmaFeatures' config file property is deprecated and has no effect.",ESLINT_PERSONAL_CONFIG_LOAD:"'~/.eslintrc.*' config files have been deprecated. Please use a config file per project or the '--config' option.",ESLINT_PERSONAL_CONFIG_SUPPRESS:"'~/.eslintrc.*' config files have been deprecated. Please remove it or add 'root:true' to the config files in your projects in order to avoid loading '~/.eslintrc.*' accidentally."},Ft=new Set;var Dt={emitDeprecationWarning:function(e,t){const n=JSON.stringify({source:e,errorCode:t});if(Ft.has(n))return;Ft.add(n);const r=O.default.relative(process.cwd(),e),o=It[t];process.emitWarning(`${o} (found in "${r}")`,"DeprecationWarning",t)}},Ot={id:"http://json-schema.org/draft-04/schema#",$schema:"http://json-schema.org/draft-04/schema#",description:"Core schema meta-schema",definitions:{schemaArray:{type:"array",minItems:1,items:{$ref:"#"}},positiveInteger:{type:"integer",minimum:0},positiveIntegerDefault0:{allOf:[{$ref:"#/definitions/positiveInteger"},{default:0}]},simpleTypes:{enum:["array","boolean","integer","null","number","object","string"]},stringArray:{type:"array",items:{type:"string"},minItems:1,uniqueItems:!0}},type:"object",properties:{id:{type:"string"},$schema:{type:"string"},title:{type:"string"},description:{type:"string"},default:{},multipleOf:{type:"number",minimum:0,exclusiveMinimum:!0},maximum:{type:"number"},exclusiveMaximum:{type:"boolean",default:!1},minimum:{type:"number"},exclusiveMinimum:{type:"boolean",default:!1},maxLength:{$ref:"#/definitions/positiveInteger"},minLength:{$ref:"#/definitions/positiveIntegerDefault0"},pattern:{type:"string",format:"regex"},additionalItems:{anyOf:[{type:"boolean"},{$ref:"#"}],default:{}},items:{anyOf:[{$ref:"#"},{$ref:"#/definitions/schemaArray"}],default:{}},maxItems:{$ref:"#/definitions/positiveInteger"},minItems:{$ref:"#/definitions/positiveIntegerDefault0"},uniqueItems:{type:"boolean",default:!1},maxProperties:{$ref:"#/definitions/positiveInteger"},minProperties:{$ref:"#/definitions/positiveIntegerDefault0"},required:{$ref:"#/definitions/stringArray"},additionalProperties:{anyOf:[{type:"boolean"},{$ref:"#"}],default:{}},definitions:{type:"object",additionalProperties:{$ref:"#"},default:{}},properties:{type:"object",additionalProperties:{$ref:"#"},default:{}},patternProperties:{type:"object",additionalProperties:{$ref:"#"},default:{}},dependencies:{type:"object",additionalProperties:{anyOf:[{$ref:"#"},{$ref:"#/definitions/stringArray"}]}},enum:{type:"array",minItems:1,uniqueItems:!0},type:{anyOf:[{$ref:"#/definitions/simpleTypes"},{type:"array",items:{$ref:"#/definitions/simpleTypes"},minItems:1,uniqueItems:!0}]},format:{type:"string"},allOf:{$ref:"#/definitions/schemaArray"},anyOf:{$ref:"#/definitions/schemaArray"},oneOf:{$ref:"#/definitions/schemaArray"},not:{$ref:"#"}},dependencies:{exclusiveMaximum:["maximum"],exclusiveMinimum:["minimum"]},default:{}};const{emitDeprecationWarning:Bt}=Dt,Nt=((e={})=>{const t=new W.default({meta:!1,useDefaults:!0,validateSchema:!1,missingRefs:"ignore",verbose:!0,schemaId:"auto",...e});return t.addMetaSchema(Ot),t._opts.defaultMeta=Ot.id,t})(),jt=new WeakMap,Lt=Function.prototype;let Rt;const Mt={error:2,warn:1,off:0},_t=new WeakSet;const $t=M.default("eslint:traverser");function qt(){}class Ut{constructor(){this._current=null,this._parents=[],this._skipped=!1,this._broken=!1,this._visitorKeys=null,this._enter=null,this._leave=null}current(){return this._current}parents(){return this._parents.slice(0)}break(){this._broken=!0}skip(){this._skipped=!0}traverse(e,t){this._current=null,this._parents=[],this._skipped=!1,this._broken=!1,this._visitorKeys=t.visitorKeys||$.default.KEYS,this._enter=t.enter||qt,this._leave=t.leave||qt,this._traverse(e,null)}_traverse(e,t){if(null!==(n=e)&&"object"==typeof n&&"string"==typeof n.type){var n;if(this._current=e,this._skipped=!1,this._enter(e,t),!this._skipped&&!this._broken){const t=function(e,t){let n=e[t.type];return n||(n=$.default.getKeys(t),$t('Unknown node type "%s": Estimated visitor keys %j',t.type,n)),n}(this._visitorKeys,e);if(t.length>=1){this._parents.push(e);for(let n=0;n=0&&r=n?r:r+1}return 0},Kt=function(e,t,n){if(n in t)return t[n]-1;if(n-1 in t){const r=t[n-1],o=r>=0&&rn?r-1:r}return e.length-1},Yt=class extends Wt{constructor(e){super(),this.cursor=e}moveNext(){const e=this.cursor.moveNext();return this.current=this.cursor.current,e}},Ht=class extends Yt{constructor(e,t){super(e),this.predicate=t}moveNext(){const e=this.predicate;for(;super.moveNext();)if(e(this.current))return!0;return!1}},Xt=class extends Wt{constructor(e,t,n,r,o){super(),this.tokens=e,this.index=Jt(e,n,r),this.indexEnd=Kt(e,n,o)}moveNext(){return this.index<=this.indexEnd&&(this.current=this.tokens[this.index],this.index+=1,!0)}getOneToken(){return this.index<=this.indexEnd?this.tokens[this.index]:null}getAllTokens(){return this.tokens.slice(this.index,this.indexEnd+1)}},Qt=class extends Yt{constructor(e,t){super(e),this.count=t}moveNext(){return this.count>0&&(this.count-=1,super.moveNext())}},Zt=class extends Yt{constructor(e,t){super(e),this.count=t}moveNext(){for(;this.count>0;)if(this.count-=1,!super.moveNext())return!1;return super.moveNext()}};class en{constructor(e,t){this.TokenCursor=e,this.TokenCommentCursor=t}createBaseCursor(e,t,n,r,o,s){return new(s?this.TokenCommentCursor:this.TokenCursor)(e,t,n,r,o)}createCursor(e,t,n,r,o,s,a,i,c){let l=this.createBaseCursor(e,t,n,r,o,s);return a&&(l=new Ht(l,a)),i>=1&&(l=new Zt(l,i)),c>=0&&(l=new Qt(l,c)),l}}var tn={forward:new en(Xt,class extends Wt{constructor(e,t,n,r,o){super(),this.tokens=e,this.comments=t,this.tokenIndex=Jt(e,n,r),this.commentIndex=zt(t,r),this.border=o}moveNext(){const e=this.tokenIndex=this.indexEnd&&(this.current=this.tokens[this.index],this.index-=1,!0)}getOneToken(){return this.index>=this.indexEnd?this.tokens[this.index]:null}},class extends Wt{constructor(e,t,n,r,o){super(),this.tokens=e,this.comments=t,this.tokenIndex=Kt(e,n,o),this.commentIndex=zt(t,o)-1,this.border=r}moveNext(){const e=this.tokenIndex>=0?this.tokens[this.tokenIndex]:null,t=this.commentIndex>=0?this.comments[this.commentIndex]:null;return e&&(!t||e.range[1]>t.range[1])?(this.current=e,this.tokenIndex-=1):t?(this.current=t,this.commentIndex-=1):this.current=null,Boolean(this.current)&&(-1===this.border||this.current.range[0]>=this.border)}})},nn=class extends Xt{constructor(e,t,n,r,o,s,a){super(e,t,n,r,o),this.index=Math.max(0,this.index-s),this.indexEnd=Math.min(e.length-1,this.indexEnd+a)}};const{isCommentToken:rn}=G.default,on=Symbol("tokens"),sn=Symbol("comments"),an=Symbol("indexMap");function cn(e,t,n,r,o,s,a){let i=!1,c=0,l=null;return"number"==typeof a?c=0|a:"function"==typeof a?l=a:a&&(i=!!a.includeComments,c=0|a.skip,l=a.filter||null),z.default(c>=0,"options.skip should be zero or a positive integer."),z.default(!l||"function"==typeof l,"options.filter should be a function."),e.createCursor(t,n,r,o,s,i,l,c,-1)}function ln(e,t,n,r,o,s,a){let i=!1,c=0,l=!1,u=null;return"number"==typeof a?(c=0|a,l=!0):"function"==typeof a?u=a:a&&(i=!!a.includeComments,c=0|a.count,l="number"==typeof a.count,u=a.filter||null),z.default(c>=0,"options.count should be zero or a positive integer."),z.default(!u||"function"==typeof u,"options.filter should be a function."),e.createCursor(t,n,r,o,s,i,u,0,l?c:-1)}function un(e,t,n,r,o,s,a){return void 0===s&&void 0===a?new Xt(e,t,n,r,o):"number"==typeof s||void 0===s?new nn(e,t,n,r,o,0|s,0|a):ln(tn.forward,e,t,n,r,o,s)}function pn(e){const t=[];let n=e.getOneToken();for(;n&&rn(n);)t.push(n),n=e.getOneToken();return t}const{isCommentToken:dn}=G.default;function fn(e,t,n,r){if(function(e,t){return e.range[0]<=t.range[0]&&e.range[1]>=t.range[0]||t.range[0]<=e.range[0]&&t.range[1]>=e.range[0]}(t,n))return!1;const[o,s]=t.range[1]<=n.range[0]?[t,n]:[n,t],a=e.getLastToken(o)||o,i=e.getFirstToken(s)||s;let c=a;for(;c!==i;){const t=e.getTokenAfter(c,{includeComments:!0});if(c.range[1]!==t.range[0]||r&&t!==i&&"JSXText"===t.type&&/\s/u.test(t.value))return!0;c=t}return!1}var mn={SourceCode:class extends class{constructor(e,t){this[on]=e,this[sn]=t,this[an]=function(e,t){const n=Object.create(null);let r=0,o=0,s=0,a=null;for(;r=t.length||re.parent.end);)t.trailing.push(n),n=this.getTokenAfter(n,{includeComments:!0})}return this._commentCache.set(e,t),t}getJSDocComment(e){const t=e=>{const t=this.getTokenBefore(e,{includeComments:!0});return t&&dn(t)&&"Block"===t.type&&"*"===t.value.charAt(0)&&e.loc.start.line-t.loc.end.line<=1?t:null};let n=e.parent;switch(e.type){case"ClassDeclaration":case"FunctionDeclaration":return t("ExportDefaultDeclaration"===(r=n).type||"ExportNamedDeclaration"===r.type||"ExportAllDeclaration"===r.type||"ExportSpecifier"===r.type?n:e);case"ClassExpression":return t(n.parent);case"ArrowFunctionExpression":case"FunctionExpression":if("CallExpression"!==n.type&&"NewExpression"!==n.type){for(;!this.getCommentsBefore(n).length&&!/Function/u.test(n.type)&&"MethodDefinition"!==n.type&&"Property"!==n.type&&(n=n.parent,n););if(n&&"FunctionDeclaration"!==n.type&&"Program"!==n.type)return t(n)}return t(e);default:return null}var r}getNodeByRangeIndex(e){let t=null;return Vt.traverse(this.ast,{visitorKeys:this.visitorKeys,enter(n){n.range[0]<=e&&ethis.text.length)throw new RangeError(`Index out of range (requested index ${e}, but source text has length ${this.text.length}).`);if(e===this.text.length)return{line:this.lines.length,column:this.lines[this.lines.length-1].length};const t=F.default.sortedLastIndex(this.lineStartIndices,e);return{line:t,column:e-this.lineStartIndices[t-1]}}getIndexFromLoc(e){if("object"!=typeof e||"number"!=typeof e.line||"number"!=typeof e.column)throw new TypeError("Expected `loc` to be an object with numeric `line` and `column` properties.");if(e.line<=0)throw new RangeError(`Line number out of range (line ${e.line} requested). Line numbers should be 1-based.`);if(e.line>this.lineStartIndices.length)throw new RangeError(`Line number out of range (line ${e.line} requested, but only ${this.lineStartIndices.length} lines present).`);const t=this.lineStartIndices[e.line-1],n=e.line===this.lineStartIndices.length?this.text.length:this.lineStartIndices[e.line],r=t+e.column;if(e.line===this.lineStartIndices.length&&r>n||e.line=n)throw new RangeError(`Column number out of range (column ${e.column} requested, but the length of line ${e.line} is ${n-t}).`);return r}}};const gn=M.default("eslint:code-path");function hn(e){return e.id+(e.reachable?"":"!")}function yn(e,t){const n=t?`:${t}`:"";switch(e.type){case"Identifier":return`${e.type}${n} (${e.name})`;case"Literal":return`${e.type}${n} (${e.value})`;default:return`${e.type}${n}`}}var xn={enabled:gn.enabled,dump:gn,dumpState:gn.enabled?function(e,t,n){for(let r=0;r=0&&o.nodes[t]===yn(e,"enter")?o.nodes[t]=yn(e,void 0):o.nodes.push(yn(e,"exit"))}else o.nodes.push(yn(e,"enter"))}gn([`${t.currentSegments.map(hn).join(",")})`,`${e.type}${n?":exit":""}`].join(" "))}:gn,dumpDot:gn.enabled?function(e){let t='\ndigraph {\nnode[shape=box,style="rounded,filled",fillcolor=white];\ninitial[label="",shape=circle,style=filled,fillcolor=black,width=0.25,height=0.25];\n';e.returnedSegments.length>0&&(t+='final[label="",shape=doublecircle,style=filled,fillcolor=black,width=0.25,height=0.25];\n'),e.thrownSegments.length>0&&(t+='thrown[label="✘",shape=circle,width=0.3,height=0.3,fixedsize];\n');const n=Object.create(null),r=this.makeDotArrows(e,n);for(const e in n){const r=n[e];t+=`${e}[`,r.reachable?t+='label="':t+='style="rounded,dashed,filled",fillcolor="#FF9800",label="<>\\n',r.internal.nodes.length>0?t+=r.internal.nodes.join("\\n"):t+="????",t+='"];\n'}t+=`${r}\n`,t+="}",gn("DOT",t)}:gn,makeDotArrows(e,t){const n=[[e.initialSegment,0]],r=t||Object.create(null);let o=e.initialSegment.id,s=`initial->${e.initialSegment.id}`;for(;n.length>0;){const e=n.pop(),t=e[0],a=e[1];if(r[t.id]&&0===a)continue;r[t.id]=t;const i=t.allNextSegments[a];i&&(o===t.id?s+=`->${i.id}`:s+=`;\n${t.id}->${i.id}`,o=i.id,n.unshift([t,1+a]),n.push([i,0]))}return e.returnedSegments.forEach((e=>{o===e.id?s+="->final":s+=`;\n${e.id}->final`,o=null})),e.thrownSegments.forEach((e=>{o===e.id?s+="->thrown":s+=`;\n${e.id}->thrown`,o=null})),`${s};`}};function bn(e){return e.reachable}class En{constructor(e,t,n){this.id=e,this.nextSegments=[],this.prevSegments=t.filter(bn),this.allNextSegments=[],this.allPrevSegments=t,this.reachable=n,Object.defineProperty(this,"internal",{value:{used:!1,loopedPrevSegments:[]}}),xn.enabled&&(this.internal.nodes=[])}isLoopedPrevSegment(e){return-1!==this.internal.loopedPrevSegments.indexOf(e)}static newRoot(e){return new En(e,[],!0)}static newNext(e,t){return new En(e,En.flattenUnusedSegments(t),t.some(bn))}static newUnreachable(e,t){const n=new En(e,En.flattenUnusedSegments(t),!1);return En.markUsed(n),n}static newDisconnected(e,t){return new En(e,[],t.some(bn))}static markUsed(e){if(e.internal.used)return;let t;if(e.internal.used=!0,e.reachable)for(t=0;t=0?t:o.length+t,a=n>=0?n:o.length+n,i=[];for(let t=0;te.count;){const t=[];for(let r=0,o=n.length/2|0;r0&&e.some(Cn)}makeNext(e,t){return vn(this,e,t,Sn.newNext)}makeUnreachable(e,t){return vn(this,e,t,Sn.newUnreachable)}makeDisconnected(e,t){return vn(this,e,t,Sn.newDisconnected)}add(e){z.default(e.length>=this.count,`${e.length} >= ${this.count}`),this.segmentsList.push(An(this,e))}replaceHead(e){z.default(e.length>=this.count,`${e.length} >= ${this.count}`),this.segmentsList.splice(-1,1,An(this,e))}addAll(e){z.default(e.count===this.count);const t=e.segmentsList;for(let e=0;e=2&&Sn.markPrevSegmentAsLooped(s,n),e.notifyLooped(n,s)}}function On(e,t,n){t.processed||(t.trueForkContext.add(n),t.falseForkContext.add(n),t.qqForkContext.add(n)),!0!==e.test&&e.brokenForkContext.addAll(t.falseForkContext),e.endOfTestSegments=t.trueForkContext.makeNext(0,-1)}var Bn=class{constructor(e,t){this.idGenerator=e,this.notifyLooped=t,this.forkContext=wn.newRoot(e),this.choiceContext=null,this.switchContext=null,this.tryContext=null,this.loopContext=null,this.breakContext=null,this.chainContext=null,this.currentSegments=[],this.initialSegment=this.forkContext.head[0];const n=this.finalSegments=[],r=this.returnedForkContext=[],o=this.thrownForkContext=[];r.add=Pn.bind(null,r,o,n),o.add=Pn.bind(null,o,r,n)}get headSegments(){return this.forkContext.head}get parentForkContext(){const e=this.forkContext;return e&&e.upper}pushForkContext(e){return this.forkContext=wn.newEmpty(this.forkContext,e),this.forkContext}popForkContext(){const e=this.forkContext;return this.forkContext=e.upper,this.forkContext.replaceHead(e.makeNext(0,-1)),e}forkPath(){this.forkContext.add(this.parentForkContext.makeNext(-1,-1))}forkBypassPath(){this.forkContext.add(this.parentForkContext.head)}pushChoiceContext(e,t){this.choiceContext={upper:this.choiceContext,kind:e,isForkingAsResult:t,trueForkContext:wn.newEmpty(this.forkContext),falseForkContext:wn.newEmpty(this.forkContext),qqForkContext:wn.newEmpty(this.forkContext),processed:!1}}popChoiceContext(){const e=this.choiceContext;this.choiceContext=e.upper;const t=this.forkContext,n=t.head;switch(e.kind){case"&&":case"||":case"??":if(e.processed||(e.trueForkContext.add(n),e.falseForkContext.add(n),e.qqForkContext.add(n)),e.isForkingAsResult){const t=this.choiceContext;return t.trueForkContext.addAll(e.trueForkContext),t.falseForkContext.addAll(e.falseForkContext),t.qqForkContext.addAll(e.qqForkContext),t.processed=!0,e}break;case"test":e.processed?(e.falseForkContext.clear(),e.falseForkContext.add(n)):(e.trueForkContext.clear(),e.trueForkContext.add(n));break;case"loop":return e;default:throw new Error("unreachable")}const r=e.trueForkContext;return r.addAll(e.falseForkContext),t.replaceHead(r.makeNext(0,-1)),e}makeLogicalRight(){const e=this.choiceContext,t=this.forkContext;if(e.processed){let n;switch(e.kind){case"&&":n=e.trueForkContext;break;case"||":n=e.falseForkContext;break;case"??":n=e.qqForkContext;break;default:throw new Error("unreachable")}t.replaceHead(n.makeNext(0,-1)),n.clear(),e.processed=!1}else{switch(e.kind){case"&&":e.falseForkContext.add(t.head);break;case"||":e.trueForkContext.add(t.head);break;case"??":e.trueForkContext.add(t.head),e.falseForkContext.add(t.head);break;default:throw new Error("unreachable")}t.replaceHead(t.makeNext(-1,-1))}}makeIfConsequent(){const e=this.choiceContext,t=this.forkContext;e.processed||(e.trueForkContext.add(t.head),e.falseForkContext.add(t.head),e.qqForkContext.add(t.head)),e.processed=!1,t.replaceHead(e.trueForkContext.makeNext(0,-1))}makeIfAlternate(){const e=this.choiceContext,t=this.forkContext;e.trueForkContext.clear(),e.trueForkContext.add(t.head),e.processed=!0,t.replaceHead(e.falseForkContext.makeNext(0,-1))}pushChainContext(){this.chainContext={upper:this.chainContext,countChoiceContexts:0}}popChainContext(){const e=this.chainContext;this.chainContext=e.upper;for(let t=e.countChoiceContexts;t>0;--t)this.popChoiceContext()}makeOptionalNode(){this.chainContext&&(this.chainContext.countChoiceContexts+=1,this.pushChoiceContext("??",!1))}makeOptionalRight(){this.chainContext&&this.makeLogicalRight()}pushSwitchContext(e,t){this.switchContext={upper:this.switchContext,hasCase:e,defaultSegments:null,defaultBodySegments:null,foundDefault:!1,lastIsDefault:!1,countForks:0},this.pushBreakContext(!0,t)}popSwitchContext(){const e=this.switchContext;this.switchContext=e.upper;const t=this.forkContext,n=this.popBreakContext().brokenForkContext;if(0===e.countForks)return void(n.empty||(n.add(t.makeNext(-1,-1)),t.replaceHead(n.makeNext(0,-1))));const r=t.head;this.forkBypassPath();const o=t.head;n.add(r),e.lastIsDefault||(e.defaultBodySegments?(!function(e,t){for(let n=0;n0&&e[0].reachable&&this.returnedForkContext.add(e)}};var Nn=class{constructor(e){this.prefix=String(e),this.n=0}next(){return this.n=1+this.n|0,this.n<0&&(this.n=1),this.prefix+this.n}};var jn=class{constructor(e,t,n){this.id=e,this.upper=t,this.childCodePaths=[],Object.defineProperty(this,"internal",{value:new Bn(new Nn(`${e}_`),n)}),t&&t.childCodePaths.push(this)}static getState(e){return e.internal}get initialSegment(){return this.internal.initialSegment}get finalSegments(){return this.internal.finalSegments}get returnedSegments(){return this.internal.returnedForkContext}get thrownSegments(){return this.internal.thrownForkContext}get currentSegments(){return this.internal.currentSegments}traverseSegments(e,t){let n,r;"function"==typeof e?(r=e,n={}):(n=e||{},r=t);const o=n.first||this.internal.initialSegment,s=n.last;let a=null,i=0,c=0,l=null;const u=Object.create(null),p=[[o,0]];let d=null,f=!1;const m={skip(){p.length<=1?f=!0:d=p[p.length-2][0]},break(){f=!0}};function g(e){return u[e.id]||l.isLoopedPrevSegment(e)}for(;p.length>0;){if(a=p[p.length-1],l=a[0],i=a[1],0===i){if(u[l.id]){p.pop();continue}if(l!==o&&l.prevSegments.length>0&&!l.prevSegments.every(g)){p.pop();continue}if(d&&-1!==l.prevSegments.indexOf(d)&&(d=null),u[l.id]=!0,!d&&(r.call(this,l,m),l===s&&m.skip(),f))break}c=l.nextSegments.length-1,i=1&&o.arguments[0]===t&&r.makeOptionalRight();break;case"MemberExpression":!0===o.optional&&o.property===t&&r.makeOptionalRight();break;case"LogicalExpression":o.right===t&&Mn(o.operator)&&r.makeLogicalRight();break;case"AssignmentExpression":o.right===t&&_n(o.operator)&&r.makeLogicalRight();break;case"ConditionalExpression":case"IfStatement":o.consequent===t?r.makeIfConsequent():o.alternate===t&&r.makeIfAlternate();break;case"SwitchCase":o.consequent[0]===t&&r.makeSwitchCaseBody(!1,!o.test);break;case"TryStatement":o.handler===t?r.makeCatchBlock():o.finalizer===t&&r.makeFinallyBlock();break;case"WhileStatement":o.test===t?r.makeWhileTest(Un(t)):(z.default(o.body===t),r.makeWhileBody());break;case"DoWhileStatement":o.body===t?r.makeDoWhileBody():(z.default(o.test===t),r.makeDoWhileTest(Un(t)));break;case"ForStatement":o.test===t?r.makeForTest(Un(t)):o.update===t?r.makeForUpdate():o.body===t&&r.makeForBody();break;case"ForInStatement":case"ForOfStatement":o.left===t?r.makeForInOfLeft():o.right===t?r.makeForInOfRight():(z.default(o.body===t),r.makeForInOfBody());break;case"AssignmentPattern":o.right===t&&(r.pushForkContext(),r.forkBypassPath(),r.forkPath())}}(this,e),function(e,t){let n=e.codePath,r=n&&jn.getState(n);const o=t.parent;switch(t.type){case"Program":case"FunctionDeclaration":case"FunctionExpression":case"ArrowFunctionExpression":n&&(Vn(e,t),xn.dumpState(t,r,!1)),n=e.codePath=new jn(e.idGenerator.next(),n,e.onLooped),r=jn.getState(n),xn.dump(`onCodePathStart ${n.id}`),e.emitter.emit("onCodePathStart",n,t);break;case"ChainExpression":r.pushChainContext();break;case"CallExpression":case"MemberExpression":!0===t.optional&&r.makeOptionalNode();break;case"LogicalExpression":Mn(t.operator)&&r.pushChoiceContext(t.operator,qn(t));break;case"AssignmentExpression":_n(t.operator)&&r.pushChoiceContext(t.operator.slice(0,-1),qn(t));break;case"ConditionalExpression":case"IfStatement":r.pushChoiceContext("test",!1);break;case"SwitchStatement":r.pushSwitchContext(t.cases.some(Rn),$n(t));break;case"TryStatement":r.pushTryContext(Boolean(t.finalizer));break;case"SwitchCase":o.discriminant!==t&&o.cases[0]!==t&&r.forkPath();break;case"WhileStatement":case"DoWhileStatement":case"ForStatement":case"ForInStatement":case"ForOfStatement":r.pushLoopContext(t.type,$n(t));break;case"LabeledStatement":Ln.test(t.body.type)||r.pushBreakContext(!1,t.label.name)}Vn(e,t),xn.dumpState(t,r,!1)}(this,e),this.original.enterNode(e),this.currentNode=null}leaveNode(e){this.currentNode=e,function(e,t){const n=e.codePath,r=jn.getState(n);let o=!1;switch(t.type){case"ChainExpression":r.popChainContext();break;case"IfStatement":case"ConditionalExpression":r.popChoiceContext();break;case"LogicalExpression":Mn(t.operator)&&r.popChoiceContext();break;case"AssignmentExpression":_n(t.operator)&&r.popChoiceContext();break;case"SwitchStatement":r.popSwitchContext();break;case"SwitchCase":0===t.consequent.length&&r.makeSwitchCaseBody(!0,!t.test),r.forkContext.reachable&&(o=!0);break;case"TryStatement":r.popTryContext();break;case"BreakStatement":Vn(e,t),r.makeBreak(t.label&&t.label.name),o=!0;break;case"ContinueStatement":Vn(e,t),r.makeContinue(t.label&&t.label.name),o=!0;break;case"ReturnStatement":Vn(e,t),r.makeReturn(),o=!0;break;case"ThrowStatement":Vn(e,t),r.makeThrow(),o=!0;break;case"Identifier":(function(e){const t=e.parent;switch(t.type){case"LabeledStatement":case"BreakStatement":case"ContinueStatement":case"ArrayPattern":case"RestElement":case"ImportSpecifier":case"ImportDefaultSpecifier":case"ImportNamespaceSpecifier":case"CatchClause":return!1;case"FunctionDeclaration":case"FunctionExpression":case"ArrowFunctionExpression":case"ClassDeclaration":case"ClassExpression":case"VariableDeclarator":return t.id!==e;case"Property":case"MethodDefinition":return t.key!==e||t.computed||t.shorthand;case"AssignmentPattern":return t.key!==e;default:return!0}})(t)&&(r.makeFirstThrowablePathInTryBlock(),o=!0);break;case"CallExpression":case"ImportExpression":case"MemberExpression":case"NewExpression":case"YieldExpression":r.makeFirstThrowablePathInTryBlock();break;case"WhileStatement":case"DoWhileStatement":case"ForStatement":case"ForInStatement":case"ForOfStatement":r.popLoopContext();break;case"AssignmentPattern":r.popForkContext();break;case"LabeledStatement":Ln.test(t.body.type)||r.popBreakContext()}o||Vn(e,t),xn.dumpState(t,r,!0)}(this,e),this.original.leaveNode(e),Wn(this,e),this.currentNode=null}onLooped(e,t){e.reachable&&t.reachable&&(xn.dump(`onCodePathSegmentLoop ${e.id} -> ${t.id}`),this.emitter.emit("onCodePathSegmentLoop",e,t,this.currentNode))}};function zn(e,t){return e.line-t.line||e.column-t.column}function Jn(e){const t=[];let n=0,r=null;const o=new Map,s=new Set,a=new Set;for(const i of e.problems){for(;n"disable"===e.type&&!a.has(e))).map((t=>({ruleId:null,message:t.ruleId?`Unused eslint-disable directive (no problems were reported from '${t.ruleId}').`:"Unused eslint-disable directive (no problems were reported).",line:t.unprocessedDirective.line,column:t.unprocessedDirective.column,severity:"warn"===e.reportUnusedDisableDirectives?1:2,nodeType:null})))}}const Kn=M.default("eslint:config-comment-parser");function Yn(e){switch(e.type){case"identifier":return[e.value];case"matches":{const t=e.selectors.map(Yn);return t.every(Boolean)?F.default.union(...t):null}case"compound":{const t=e.selectors.map(Yn).filter((e=>e));return t.length?F.default.intersection(...t):null}case"child":case"descendant":case"sibling":case"adjacent":return Yn(e.right);default:return null}}function Hn(e){switch(e.type){case"child":case"descendant":case"sibling":case"adjacent":return Hn(e.left)+Hn(e.right);case"compound":case"not":case"matches":return e.selectors.reduce(((e,t)=>e+Hn(t)),0);case"attribute":case"field":case"nth-child":case"nth-last-child":return 1;default:return 0}}function Xn(e){switch(e.type){case"child":case"descendant":case"sibling":case"adjacent":return Xn(e.left)+Xn(e.right);case"compound":case"not":case"matches":return e.selectors.reduce(((e,t)=>e+Xn(t)),0);case"identifier":return 1;default:return 0}}function Qn(e,t){return e.attributeCount-t.attributeCount||e.identifierCount-t.identifierCount||(e.rawSelector<=t.rawSelector?-1:1)}const Zn=F.default.memoize((e=>{const t=function(e){try{return K.default.parse(e.replace(/:exit$/u,""))}catch(t){if(t.location&&t.location.start&&"number"==typeof t.location.start.offset)throw new SyntaxError(`Syntax error in selector "${e}" at position ${t.location.start.offset}: ${t.message}`);throw t}}(e);return{rawSelector:e,isExit:e.endsWith(":exit"),parsedSelector:t,listenerTypes:Yn(t),attributeCount:Hn(t),identifierCount:Xn(t)}}));var er=class{constructor(e,t){this.emitter=e,this.esqueryOptions=t,this.currentAncestry=[],this.enterSelectorsByNodeType=new Map,this.exitSelectorsByNodeType=new Map,this.anyTypeEnterSelectors=[],this.anyTypeExitSelectors=[],e.eventNames().forEach((e=>{const t=Zn(e);if(t.listenerTypes){const e=t.isExit?this.exitSelectorsByNodeType:this.enterSelectorsByNodeType;return void t.listenerTypes.forEach((n=>{e.has(n)||e.set(n,[]),e.get(n).push(t)}))}(t.isExit?this.anyTypeExitSelectors:this.anyTypeEnterSelectors).push(t)})),this.anyTypeEnterSelectors.sort(Qn),this.anyTypeExitSelectors.sort(Qn),this.enterSelectorsByNodeType.forEach((e=>e.sort(Qn))),this.exitSelectorsByNodeType.forEach((e=>e.sort(Qn)))}applySelector(e,t){K.default.matches(e,t.parsedSelector,this.currentAncestry,this.esqueryOptions)&&this.emitter.emit(t.rawSelector,e)}applySelectors(e,t){const n=(t?this.exitSelectorsByNodeType:this.enterSelectorsByNodeType).get(e.type)||[],r=t?this.anyTypeExitSelectors:this.anyTypeEnterSelectors;let o=0,s=0;for(;o=n.length||str(e[1],t),insertTextBefore(e,t){return this.insertTextBeforeRange(e.range,t)},insertTextBeforeRange:(e,t)=>tr(e[0],t),replaceText(e,t){return this.replaceTextRange(e.range,t)},replaceTextRange:(e,t)=>({range:e,text:t}),remove(e){return this.removeRange(e.range)},removeRange:e=>({range:e,text:""})}),rr=(e,t)=>t?e.replace(/\{\{([^{}]+?)\}\}/gu,((e,n)=>{const r=n.trim();return r in t?t[r]:e})):e;function or(e){return e.loc?e.loc.start?e.loc:{start:e.loc,end:null}:e.node.loc}function sr(e){e&&z.default(e.range&&"number"==typeof e.range[0]&&"number"==typeof e.range[1],`Fix has invalid range: ${JSON.stringify(e,null,2)}`)}function ar(e,t){return e.range[0]-t.range[0]||e.range[1]-t.range[1]}function ir(e,t){if("function"!=typeof e.fix)return null;const n=e.fix(nr);return n&&Symbol.iterator in n?function(e,t){for(const t of e)sr(t);if(0===e.length)return null;if(1===e.length)return e[0];e.sort(ar);const n=t.text,r=e[0].range[0],o=e[e.length-1].range[1];let s="",a=Number.MIN_SAFE_INTEGER;for(const t of e)z.default(t.range[0]>=a,"Fix objects must not be overlapped in a report."),t.range[0]>=0&&(s+=n.slice(Math.max(0,r,a),t.range[0])),s+=t.text,a=t.range[1];return s+=n.slice(Math.max(0,r,a),o),{range:[r,o],text:s}}(Array.from(n),t):(sr(n),n)}function cr(e,t,n){return e.suggest&&Array.isArray(e.suggest)?e.suggest.map((e=>{const r=e.desc||n[e.messageId];return{...e,desc:rr(r,e.data),fix:ir(e,t)}})).filter((({fix:e})=>e)):[]}var lr=function(e){return(...t)=>{const n=function(...e){return 1===e.length?Object.assign({},e[0]):"string"==typeof e[1]?{node:e[0],message:e[1],data:e[2],fix:e[3]}:{node:e[0],loc:e[1],message:e[2],data:e[3],fix:e[4]}}(...t),r=e.messageIds;let o;if(function(e){e.node?z.default("object"==typeof e.node,"Node must be an object"):z.default(e.loc,"Node must be provided when reporting error if location is not provided")}(n),n.messageId){if(!r)throw new TypeError("context.report() called with a messageId, but no messages were present in the rule metadata.");const e=n.messageId;if(n.message)throw new TypeError("context.report() called with a message and a messageId. Please only pass one.");if(!r||!Object.prototype.hasOwnProperty.call(r,e))throw new TypeError(`context.report() called with a messageId of '${e}' which is not present in the 'messages' config: ${JSON.stringify(r,null,2)}`);o=r[e]}else{if(!n.message)throw new TypeError("Missing `message` property in report() call; add a message that describes the linting problem.");o=n.message}return function(e,t){e&&Array.isArray(e)&&e.forEach((e=>{if(e.messageId){const{messageId:n}=e;if(!t)throw new TypeError(`context.report() called with a suggest option with a messageId '${n}', but no messages were present in the rule metadata.`);if(!t[n])throw new TypeError(`context.report() called with a suggest option with a messageId '${n}' which is not present in the 'messages' config: ${JSON.stringify(t,null,2)}`);if(e.desc)throw new TypeError("context.report() called with a suggest option that defines both a 'messageId' and an 'desc'. Please only pass one.")}else if(!e.desc)throw new TypeError("context.report() called with a suggest option that doesn't have either a `desc` or `messageId`");if("function"!=typeof e.fix)throw new TypeError(`context.report() called with a suggest option without a fix function. See: ${e}`)}))}(n.suggest,r),function(e){const t={ruleId:e.ruleId,severity:e.severity,message:e.message,line:e.loc.start.line,column:e.loc.start.column+1,nodeType:e.node&&e.node.type||null};return e.messageId&&(t.messageId=e.messageId),e.loc.end&&(t.endLine=e.loc.end.line,t.endColumn=e.loc.end.column+1),e.fix&&(t.fix=e.fix),e.suggestions&&e.suggestions.length>0&&(t.suggestions=e.suggestions),t}({ruleId:e.ruleId,severity:e.severity,node:n.node,message:rr(o,n.data),messageId:n.messageId,loc:or(n),fix:e.disableFixes?null:ir(n,e.sourceCode),suggestions:e.disableFixes?[]:cr(n,e.sourceCode,r)})}};const ur=M.default("eslint:rules");class pr extends Map{constructor(e){let t=e.length;super(ur.enabled?e.map((([e,n])=>{let r=null;return[e,()=>(r||(ur("Loading rule %o (remaining=%d)",e,--t),r=n()),r)]})):e),Object.defineProperty(pr.prototype,"set",{configurable:!0,value:void 0})}get(e){const t=super.get(e);return t&&t()}*values(){for(const e of super.values())yield e()}*entries(){for(const[e,t]of super.entries())yield[e,t()]}forEach(e,t){for(const[n,r]of super.entries())e.call(t,r(),n,this)}}Object.defineProperties(pr.prototype,{clear:{configurable:!0,value:void 0},delete:{configurable:!0,value:void 0},[Symbol.iterator]:{configurable:!0,writable:!0,value:pr.prototype.entries}});var dr={LazyLoadingRuleMap:pr},fr=ie((function(e){const{breakableTypePattern:t,createGlobalLinebreakMatcher:n,lineBreakPattern:r,shebangPattern:o}=kt,s=/^(?:Function(?:Declaration|Expression)|ArrowFunctionExpression)$/u,a=/^(?:DoWhile|For|ForIn|ForOf|While)Statement$/u,i=/Array$/u,c=/^(?:every|filter|find|findIndex|forEach|map|some)$/u,l=/^(?:bind|call|apply)$/u,u=/^[\s*]*@this/mu,p=new Set(["\r\n","\r","\n","\u2028","\u2029"]),d=new Set(["Program","BlockStatement","SwitchCase"]),f=/^(?:0|0[0-7]*[89]\d*|[1-9](?:_?\d)*)$/u,m=/^(?:[^\\]|\\.)*\\(?:[1-9]|0[0-9])/us,g=new Set(["&&=","||=","??="]);function h(e,t,n){const r=e.identifier,o=0===t||n[t-1].identifier!==r;return r&&!1===e.init&&e.isWrite()&&o}function y(e){return e[0]!==e[0].toLocaleLowerCase()}function x(e){return e.id&&y(e.id.name)}function b(e){for(let t=e;t;t=t.parent)if(s.test(t.type))return t;return null}function E(e){return Boolean(e&&s.test(e.type))}function S(e){return Boolean(e&&a.test(e.type))}function C(e){return"Literal"===e.type&&null===e.value&&!e.regex&&!e.bigint}function v(e){return C(e)||"Identifier"===e.type&&"undefined"===e.name||"UnaryExpression"===e.type&&"void"===e.operator}function A(e){return"CallExpression"===e.parent.type&&e.parent.callee===e}function k(e){switch(e.type){case"Literal":if(null!==e.value)return String(e.value);if(C(e))return String(e.value);if(e.regex)return`/${e.regex.pattern}/${e.regex.flags}`;if(e.bigint)return e.bigint;break;case"TemplateLiteral":if(0===e.expressions.length&&1===e.quasis.length)return e.quasis[0].value.cooked}return null}function w(e){let t;switch(e&&e.type){case"ChainExpression":return w(e.expression);case"Property":case"MethodDefinition":t=e.key;break;case"MemberExpression":t=e.property}return t?"Identifier"!==t.type||e.computed?k(t):t.name:null}function P(e){return e&&"ChainExpression"===e.type?e.expression:e}function T(e,t){return"string"==typeof t?e===t:t.test(e)}function I(e,t){return"Identifier"===e.type&&T(e.name,t)}function D(e,t,n){const r=P(e);if("MemberExpression"!==r.type)return!1;if(t&&!I(r.object,t))return!1;if(n){const e=w(r);if("string"!=typeof e||!T(e,n))return!1}return!0}function O(e,t){return e.regex||t.regex?Boolean(e.regex&&t.regex&&e.regex.pattern===t.regex.pattern&&e.regex.flags===t.regex.flags):e.bigint||t.bigint?e.bigint===t.bigint:e.value===t.value}function B(e){return D(e,"Reflect","apply")}function N(e){return D(e,i,"from")}function j(e){return D(e,null,c)}function L(e){return t=>!e(t)}function R(e){return"=>"===e.value&&"Punctuator"===e.type}function M(e){return","===e.value&&"Punctuator"===e.type}function _(e){return"."===e.value&&"Punctuator"===e.type}function $(e){return"?."===e.value&&"Punctuator"===e.type}function U(e){return";"===e.value&&"Punctuator"===e.type}function V(e){return":"===e.value&&"Punctuator"===e.type}function W(e){return"("===e.value&&"Punctuator"===e.type}function G(e){return")"===e.value&&"Punctuator"===e.type}function z(e){return"["===e.value&&"Punctuator"===e.type}function J(e){return"]"===e.value&&"Punctuator"===e.type}function K(e){return"{"===e.value&&"Punctuator"===e.type}function H(e){return"}"===e.value&&"Punctuator"===e.type}function X(e,t){return e.id?t.getTokenAfter(e.id,W):t.getFirstToken(e,W)}function Q(e){return"LogicalExpression"===e.type&&("&&"===e.operator||"||"===e.operator)}function Z(e){return"LogicalExpression"===e.type&&"??"===e.operator}e.exports={COMMENTS_IGNORE_PATTERN:/^\s*(?:eslint|jshint\s+|jslint\s+|istanbul\s+|globals?\s+|exported\s+|jscs)/u,LINEBREAKS:p,LINEBREAK_MATCHER:r,SHEBANG_MATCHER:o,STATEMENT_LIST_PARENTS:d,isTokenOnSameLine:(e,t)=>e.loc.end.line===t.loc.start.line,isNullOrUndefined:v,isCallee:A,isES5Constructor:x,getUpperFunction:b,isFunction:E,isLoop:S,isInLoop:function(e){for(let t=e;t&&!E(t);t=t.parent)if(S(t))return!0;return!1},isArrayFromMethod:N,isParenthesised:function(e,t){const n=e.getTokenBefore(t),r=e.getTokenAfter(t);return Boolean(n&&r)&&"("===n.value&&n.range[1]<=t.range[0]&&")"===r.value&&r.range[0]>=t.range[1]},createGlobalLinebreakMatcher:n,equalTokens:function(e,t,n){const r=n.getTokens(e),o=n.getTokens(t);if(r.length!==o.length)return!1;for(let e=0;e"Literal"===e.type&&"string"==typeof e.value||"TemplateLiteral"===e.type,isBreakableStatement:e=>t.test(e.type),getModifyingReferences:e=>e.filter(h),isSurroundedBy:(e,t)=>e[0]===t&&e[e.length-1]===t,isDirectiveComment(e){const t=e.value.trim();return"Line"===e.type&&0===t.indexOf("eslint-")||"Block"===e.type&&(0===t.indexOf("global ")||0===t.indexOf("eslint ")||0===t.indexOf("eslint-"))},getTrailingStatement:Y.default.ast.trailingStatement,getVariableByName(e,t){let n=e;for(;n;){const e=n.set.get(t);if(e)return e;n=n.upper}return null},isDefaultThisBinding(e,t,{capIsConstructor:n=!0}={}){if(n&&x(e)||function(e,t){const n=t.getJSDocComment(e);return!(!n||!u.test(n.value))||t.getCommentsBefore(e).some((e=>u.test(e.value)))}(e,t))return!1;const r=null===e.id;let o=e;for(;o;){const e=o.parent;switch(e.type){case"LogicalExpression":case"ConditionalExpression":case"ChainExpression":o=e;break;case"ReturnStatement":{const t=b(e);if(null===t||!A(t))return!0;o=t.parent;break}case"ArrowFunctionExpression":if(o!==e.body||!A(e))return!0;o=e.parent;break;case"Property":case"MethodDefinition":return e.value!==o;case"AssignmentExpression":case"AssignmentPattern":return"MemberExpression"!==e.left.type&&!(n&&r&&"Identifier"===e.left.type&&y(e.left.name));case"VariableDeclarator":return!(n&&r&&e.init===o&&"Identifier"===e.id.type&&y(e.id.name));case"MemberExpression":if(e.object===o&&D(e,null,l)){const t="ChainExpression"===e.parent.type?e.parent:e;return!(A(t)&&t.parent.arguments.length>=1&&!v(t.parent.arguments[0]))}return!0;case"CallExpression":return B(e.callee)?3!==e.arguments.length||e.arguments[0]!==o||v(e.arguments[1]):N(e.callee)?3!==e.arguments.length||e.arguments[1]!==o||v(e.arguments[2]):!j(e.callee)||(2!==e.arguments.length||e.arguments[0]!==o||v(e.arguments[1]));default:return!0}}return!0},getPrecedence(e){switch(e.type){case"SequenceExpression":return 0;case"AssignmentExpression":case"ArrowFunctionExpression":case"YieldExpression":return 1;case"ConditionalExpression":return 3;case"LogicalExpression":switch(e.operator){case"||":case"??":return 4;case"&&":return 5}case"BinaryExpression":switch(e.operator){case"|":return 6;case"^":return 7;case"&":return 8;case"==":case"!=":case"===":case"!==":return 9;case"<":case"<=":case">":case">=":case"in":case"instanceof":return 10;case"<<":case">>":case">>>":return 11;case"+":case"-":return 12;case"*":case"/":case"%":return 13;case"**":return 15}case"UnaryExpression":case"AwaitExpression":return 16;case"UpdateExpression":return 17;case"CallExpression":case"ChainExpression":case"ImportExpression":return 18;case"NewExpression":return 19;default:return 20}},isEmptyBlock:e=>Boolean(e&&"BlockStatement"===e.type&&0===e.body.length),isEmptyFunction:t=>E(t)&&e.exports.isEmptyBlock(t.body),getDirectivePrologue(e){const t=[];if("Program"===e.type||"FunctionDeclaration"===e.type||"FunctionExpression"===e.type||"ArrowFunctionExpression"===e.type&&"BlockStatement"===e.body.type){const n="Program"===e.type?e.body:e.body.body;for(const e of n){if("ExpressionStatement"!==e.type||"Literal"!==e.expression.type)break;t.push(e)}}return t},isDecimalInteger:e=>"Literal"===e.type&&"number"==typeof e.value&&f.test(e.raw),isDecimalIntegerNumericToken:e=>"Numeric"===e.type&&f.test(e.value),getFunctionNameWithKind(e){const t=e.parent,n=[];if("MethodDefinition"===t.type&&t.static&&n.push("static"),e.async&&n.push("async"),e.generator&&n.push("generator"),"ArrowFunctionExpression"===e.type)n.push("arrow","function");else if("Property"===t.type||"MethodDefinition"===t.type){if("constructor"===t.kind)return"constructor";"get"===t.kind?n.push("getter"):"set"===t.kind?n.push("setter"):n.push("method")}else n.push("function");if(e.id)n.push(`'${e.id.name}'`);else{const e=w(t);null!==e&&n.push(`'${e}'`)}return n.join(" ")},getFunctionHeadLoc(e,t){const n=e.parent;let r=null,o=null;if("ArrowFunctionExpression"===e.type){const n=t.getTokenBefore(e.body,R);r=n.loc.start,o=n.loc.end}else"Property"===n.type||"MethodDefinition"===n.type?(r=n.loc.start,o=X(e,t).loc.start):(r=e.loc.start,o=X(e,t).loc.start);return{start:Object.assign({},r),end:Object.assign({},o)}},getNextLocation:(e,{line:t,column:n})=>n"Literal"===e.type&&("number"==typeof e.value||Boolean(e.bigint)),canTokensBeAdjacent(e,t){const n={ecmaVersion:q.default.latestEcmaVersion,comment:!0,range:!0};let r,o;if("string"==typeof e){let t;try{t=q.default.tokenize(e,n)}catch{return!1}const o=t.comments;if(r=t[t.length-1],o.length){const e=o[o.length-1];e.range[0]>r.range[0]&&(r=e)}}else r=e;if("Shebang"===r.type)return!1;if("string"==typeof t){let e;try{e=q.default.tokenize(t,n)}catch{return!1}const r=e.comments;if(o=e[0],r.length){const e=r[0];e.range[0]m.test(e),isLogicalExpression:Q,isCoalesceExpression:Z,isMixedLogicalAndCoalesceExpressions:function(e,t){return Q(e)&&Z(t)||Z(e)&&Q(t)},isNullLiteral:C,getStaticStringValue:k,getStaticPropertyName:w,skipChainExpression:P,isSpecificId:I,isSpecificMemberAccess:D,equalLiteralValue:O,isSameReference:function e(t,n,r=!1){if(t.type!==n.type)return"ChainExpression"===t.type?e(t.expression,n,r):"ChainExpression"===n.type&&e(t,n.expression,r);switch(t.type){case"Super":case"ThisExpression":return!0;case"Identifier":return t.name===n.name;case"Literal":return O(t,n);case"ChainExpression":return e(t.expression,n.expression,r);case"MemberExpression":if(!r){const o=w(t);if(null!==o)return e(t.object,n.object,r)&&o===w(n)}return t.computed===n.computed&&e(t.object,n.object,r)&&e(t.property,n.property,r);default:return!1}},isLogicalAssignmentOperator:function(e){return g.has(e)}}}));function mr(e){return"get"===e.kind||"set"===e.kind}function gr(e,t,n,r){const o=e.parent;return"CallExpression"===o.type&&fr.isSpecificMemberAccess(o.callee,n,r)&&o.arguments[t]===e}var hr={meta:{type:"suggestion",docs:{description:"enforce getter and setter pairs in objects and classes",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/accessor-pairs"},schema:[{type:"object",properties:{getWithoutSet:{type:"boolean",default:!1},setWithoutGet:{type:"boolean",default:!0},enforceForClassMembers:{type:"boolean",default:!0}},additionalProperties:!1}],messages:{missingGetterInPropertyDescriptor:"Getter is not present in property descriptor.",missingSetterInPropertyDescriptor:"Setter is not present in property descriptor.",missingGetterInObjectLiteral:"Getter is not present for {{ name }}.",missingSetterInObjectLiteral:"Setter is not present for {{ name }}.",missingGetterInClass:"Getter is not present for class {{ name }}.",missingSetterInClass:"Setter is not present for class {{ name }}."}},create(e){const t=e.options[0]||{},n=!0===t.getWithoutSet,r=!1!==t.setWithoutGet,o=!1!==t.enforceForClassMembers,s=e.getSourceCode();function a(t,n){"Property"===t.type?e.report({node:t,messageId:`${n}InObjectLiteral`,loc:fr.getFunctionHeadLoc(t.value,s),data:{name:fr.getFunctionNameWithKind(t.value)}}):"MethodDefinition"===t.type?e.report({node:t,messageId:`${n}InClass`,loc:fr.getFunctionHeadLoc(t.value,s),data:{name:fr.getFunctionNameWithKind(t.value)}}):e.report({node:t,messageId:`${n}InPropertyDescriptor`})}function i(e,t){for(const n of e)a(n,t)}function c(e){const t=fr.getStaticPropertyName(e);return{key:null!==t?t:s.getTokens(e.key),getters:"get"===e.kind?[e]:[],setters:"set"===e.kind?[e]:[]}}function l(e,t){const n=e.find((e=>{return n=e.key,r=t.key,"string"==typeof n&&"string"==typeof r?n===r:!(!Array.isArray(n)||!Array.isArray(r))&&function(e,t){if(e.length!==t.length)return!1;for(let n=0;n"Property"===e.type)))}(e),function(e){if(gr(e,2,"Object","defineProperty")||gr(e,2,"Reflect","defineProperty"))return!0;const t=e.parent.parent;return"ObjectExpression"===t.type&&(gr(t,1,"Object","create")||gr(t,1,"Object","defineProperties"))}(e)&&function(e){const t=e.properties.filter((e=>"Property"===e.type&&"init"===e.kind&&!e.computed)).map((({key:e})=>e.name)),o=t.includes("get"),s=t.includes("set");r&&s&&!o&&a(e,"missingGetter"),n&&o&&!s&&a(e,"missingSetter")}(e)},o&&(p.ClassBody=function(e){const t=e.body.filter((e=>"MethodDefinition"===e.type));u(t.filter((e=>e.static))),u(t.filter((e=>!e.static)))})),p}},yr={meta:{type:"layout",docs:{description:"enforce linebreaks after opening and before closing array brackets",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/array-bracket-newline"},fixable:"whitespace",schema:[{oneOf:[{enum:["always","never","consistent"]},{type:"object",properties:{multiline:{type:"boolean"},minItems:{type:["integer","null"],minimum:0}},additionalProperties:!1}]}],messages:{unexpectedOpeningLinebreak:"There should be no linebreak after '['.",unexpectedClosingLinebreak:"There should be no linebreak before ']'.",missingOpeningLinebreak:"A linebreak is required after '['.",missingClosingLinebreak:"A linebreak is required before ']'."}},create(e){const t=e.getSourceCode();function n(e){const t=function(e){let t=!1,n=!1,r=0;return e?"consistent"===e?(t=!0,r=Number.POSITIVE_INFINITY):"always"===e||0===e.minItems?r=0:"never"===e?r=Number.POSITIVE_INFINITY:(n=Boolean(e.multiline),r=e.minItems||Number.POSITIVE_INFINITY):(t=!1,n=!0,r=Number.POSITIVE_INFINITY),{consistent:t,multiline:n,minItems:r}}(e);return{ArrayExpression:t,ArrayPattern:t}}function r(r){const o=r.elements,s=n(e.options[0])[r.type],a=t.getFirstToken(r),i=t.getLastToken(r),c=t.getTokenAfter(a,{includeComments:!0}),l=t.getTokenBefore(i,{includeComments:!0}),u=t.getTokenAfter(a),p=t.getTokenBefore(i);o.length>=s.minItems||s.multiline&&o.length>0&&c.loc.start.line!==l.loc.end.line||0===o.length&&"Block"===c.type&&c.loc.start.line!==l.loc.end.line&&c===l||s.consistent&&a.loc.end.line!==u.loc.start.line?(fr.isTokenOnSameLine(a,u)&&function(t,n){e.report({node:t,loc:n.loc,messageId:"missingOpeningLinebreak",fix:e=>e.insertTextAfter(n,"\n")})}(r,a),fr.isTokenOnSameLine(p,i)&&function(t,n){e.report({node:t,loc:n.loc,messageId:"missingClosingLinebreak",fix:e=>e.insertTextBefore(n,"\n")})}(r,i)):(fr.isTokenOnSameLine(a,u)||function(n,r){e.report({node:n,loc:r.loc,messageId:"unexpectedOpeningLinebreak",fix(e){const n=t.getTokenAfter(r,{includeComments:!0});return fr.isCommentToken(n)?null:e.removeRange([r.range[1],n.range[0]])}})}(r,a),fr.isTokenOnSameLine(p,i)||function(n,r){e.report({node:n,loc:r.loc,messageId:"unexpectedClosingLinebreak",fix(e){const n=t.getTokenBefore(r,{includeComments:!0});return fr.isCommentToken(n)?null:e.removeRange([n.range[1],r.range[0]])}})}(r,i))}return{ArrayPattern:r,ArrayExpression:r}}},xr={meta:{type:"layout",docs:{description:"enforce consistent spacing inside array brackets",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/array-bracket-spacing"},fixable:"whitespace",schema:[{enum:["always","never"]},{type:"object",properties:{singleValue:{type:"boolean"},objectsInArrays:{type:"boolean"},arraysInArrays:{type:"boolean"}},additionalProperties:!1}],messages:{unexpectedSpaceAfter:"There should be no space after '{{tokenValue}}'.",unexpectedSpaceBefore:"There should be no space before '{{tokenValue}}'.",missingSpaceAfter:"A space is required after '{{tokenValue}}'.",missingSpaceBefore:"A space is required before '{{tokenValue}}'."}},create(e){const t="always"===e.options[0],n=e.getSourceCode();function r(n){return!!e.options[1]&&e.options[1][n]===!t}const o={spaced:t,singleElementException:r("singleValue"),objectsInArraysException:r("objectsInArrays"),arraysInArraysException:r("arraysInArrays")};function s(e){return e&&("ObjectExpression"===e.type||"ObjectPattern"===e.type)}function a(e){return e&&("ArrayExpression"===e.type||"ArrayPattern"===e.type)}function i(t){if(o.spaced&&0===t.elements.length)return;const r=n.getFirstToken(t),i=n.getFirstToken(t,1),c=t.typeAnnotation?n.getTokenBefore(t.typeAnnotation):n.getLastToken(t),l=n.getTokenBefore(c),u=t.elements[0],p=t.elements[t.elements.length-1],d=o.objectsInArraysException&&s(u)||o.arraysInArraysException&&a(u)||o.singleElementException&&1===t.elements.length?!o.spaced:o.spaced,f=o.objectsInArraysException&&s(p)||o.arraysInArraysException&&a(p)||o.singleElementException&&1===t.elements.length?!o.spaced:o.spaced;fr.isTokenOnSameLine(r,i)&&(d&&!n.isSpaceBetweenTokens(r,i)&&function(t,n){e.report({node:t,loc:n.loc,messageId:"missingSpaceAfter",data:{tokenValue:n.value},fix:e=>e.insertTextAfter(n," ")})}(t,r),!d&&n.isSpaceBetweenTokens(r,i)&&function(t,r){const o=n.getTokenAfter(r);e.report({node:t,loc:{start:r.loc.end,end:o.loc.start},messageId:"unexpectedSpaceAfter",data:{tokenValue:r.value},fix:e=>e.removeRange([r.range[1],o.range[0]])})}(t,r)),r!==l&&fr.isTokenOnSameLine(l,c)&&(f&&!n.isSpaceBetweenTokens(l,c)&&function(t,n){e.report({node:t,loc:n.loc,messageId:"missingSpaceBefore",data:{tokenValue:n.value},fix:e=>e.insertTextBefore(n," ")})}(t,c),!f&&n.isSpaceBetweenTokens(l,c)&&function(t,r){const o=n.getTokenBefore(r);e.report({node:t,loc:{start:o.loc.end,end:r.loc.start},messageId:"unexpectedSpaceBefore",data:{tokenValue:r.value},fix:e=>e.removeRange([o.range[1],r.range[0]])})}(t,c))}return{ArrayPattern:i,ArrayExpression:i}}};const br=/^(?:Arrow)?FunctionExpression$/u,Er=/^(?:every|filter|find(?:Index)?|flatMap|forEach|map|reduce(?:Right)?|some|sort)$/u;function Sr(e){return e.reachable}function Cr(e){return fr.isSpecificMemberAccess(e,null,Er)}function vr(e){return["from","of","isArray"].includes(e)?"Array.".concat(e):"Array.prototype.".concat(e)}var Ar={meta:{type:"problem",docs:{description:"enforce `return` statements in callbacks of array methods",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/array-callback-return"},schema:[{type:"object",properties:{allowImplicit:{type:"boolean",default:!1},checkForEach:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{expectedAtEnd:"{{arrayMethodName}}() expects a value to be returned at the end of {{name}}.",expectedInside:"{{arrayMethodName}}() expects a return value from {{name}}.",expectedReturnValue:"{{arrayMethodName}}() expects a return value from {{name}}.",expectedNoReturnValue:"{{arrayMethodName}}() expects no useless return value from {{name}}."}},create(e){const t=e.options[0]||{allowImplicit:!1,checkForEach:!1},n=e.getSourceCode();let r={arrayMethodName:null,upper:null,codePath:null,hasReturn:!1,shouldCheck:!1,node:null};function o(o){if(!r.shouldCheck)return;let s=null;if("forEach"===r.arrayMethodName?t.checkForEach&&"ArrowFunctionExpression"===o.type&&o.expression&&(s="expectedNoReturnValue"):"BlockStatement"===o.body.type&&r.codePath.currentSegments.some(Sr)&&(s=r.hasReturn?"expectedAtEnd":"expectedInside"),s){const t=fr.getFunctionNameWithKind(o);e.report({node:o,loc:fr.getFunctionHeadLoc(o,n),messageId:s,data:{name:t,arrayMethodName:vr(r.arrayMethodName)}})}}return{onCodePathStart(e,t){let n=null;br.test(t.type)&&(n=function(e){let t=e;for(;t;){const e=t.parent;switch(e.type){case"LogicalExpression":case"ConditionalExpression":case"ChainExpression":t=e;break;case"ReturnStatement":{const n=fr.getUpperFunction(e);if(null===n||!fr.isCallee(n))return null;t=n.parent;break}case"CallExpression":return fr.isArrayFromMethod(e.callee)&&e.arguments.length>=2&&e.arguments[1]===t?"from":Cr(e.callee)&&e.arguments.length>=1&&e.arguments[0]===t?fr.getStaticPropertyName(e.callee):null;default:return null}}return null}(t)),r={arrayMethodName:n,upper:r,codePath:e,hasReturn:!1,shouldCheck:n&&!t.async&&!t.generator,node:t}},onCodePathEnd(){r=r.upper},ReturnStatement(n){if(!r.shouldCheck)return;r.hasReturn=!0;let o=null;"forEach"===r.arrayMethodName?t.checkForEach&&n.argument&&(o="expectedNoReturnValue"):t.allowImplicit||n.argument||(o="expectedReturnValue"),o&&e.report({node:n,messageId:o,data:{name:fr.getFunctionNameWithKind(r.node),arrayMethodName:vr(r.arrayMethodName)}})},"FunctionExpression:exit":o,"ArrowFunctionExpression:exit":o}}},kr={meta:{type:"layout",docs:{description:"enforce line breaks after each array element",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/array-element-newline"},fixable:"whitespace",schema:{definitions:{basicConfig:{oneOf:[{enum:["always","never","consistent"]},{type:"object",properties:{multiline:{type:"boolean"},minItems:{type:["integer","null"],minimum:0}},additionalProperties:!1}]}},items:[{oneOf:[{$ref:"#/definitions/basicConfig"},{type:"object",properties:{ArrayExpression:{$ref:"#/definitions/basicConfig"},ArrayPattern:{$ref:"#/definitions/basicConfig"}},additionalProperties:!1,minProperties:1}]}]},messages:{unexpectedLineBreak:"There should be no linebreak here.",missingLineBreak:"There should be a linebreak after this element."}},create(e){const t=e.getSourceCode();function n(e){let t,n=!1,r=!1;const o=e||"always";return o&&"always"!==o&&0!==o.minItems?"never"===o?t=Number.POSITIVE_INFINITY:"consistent"===o?(n=!0,t=Number.POSITIVE_INFINITY):(r=Boolean(o.multiline),t=o.minItems||Number.POSITIVE_INFINITY):t=0,{consistent:n,multiline:r,minItems:t}}function r(r){const o=r.elements,s=function(e){if(e&&(e.ArrayExpression||e.ArrayPattern)){let t,r;return e.ArrayExpression&&(t=n(e.ArrayExpression)),e.ArrayPattern&&(r=n(e.ArrayPattern)),{ArrayExpression:t,ArrayPattern:r}}const t=n(e);return{ArrayExpression:t,ArrayPattern:t}}(e.options[0])[r.type];if(!s)return;let a=!1;s.multiline&&(a=o.filter((e=>null!==e)).some((e=>e.loc.start.line!==e.loc.end.line)));const i=r.elements.map(((e,n)=>{const r=o[n-1];if(0===n||null===e||null===r)return!1;const s=t.getFirstTokenBetween(r,e,fr.isCommaToken),a=t.getTokenBefore(s),i=t.getTokenAfter(s);return!fr.isTokenOnSameLine(a,i)})).filter((e=>!0===e)).length,c=o.length>=s.minItems||s.multiline&&a||s.consistent&&i>0&&i{const s=o[r-1];if(0===r||null===n||null===s)return;const a=t.getFirstTokenBetween(s,n,fr.isCommaToken),i=t.getTokenBefore(a),l=t.getTokenAfter(a);c?fr.isTokenOnSameLine(i,l)&&function(n){const r=t.getTokenBefore(n,{includeComments:!0});e.report({loc:{start:r.loc.end,end:n.loc.start},messageId:"missingLineBreak",fix:e=>e.replaceTextRange([r.range[1],n.range[0]],"\n")})}(l):fr.isTokenOnSameLine(i,l)||function(n){const r=t.getTokenBefore(n,{includeComments:!0});e.report({loc:{start:r.loc.end,end:n.loc.start},messageId:"unexpectedLineBreak",fix(e){if(fr.isCommentToken(r))return null;if(!fr.isTokenOnSameLine(r,n))return e.replaceTextRange([r.range[1],n.range[0]]," ");const o=t.getTokenBefore(r,{includeComments:!0});return fr.isCommentToken(o)?null:e.replaceTextRange([o.range[1],r.range[0]],"")}})}(l)}))}return{ArrayPattern:r,ArrayExpression:r}}},wr={meta:{type:"suggestion",docs:{description:"require braces around arrow function bodies",category:"ECMAScript 6",recommended:!1,url:"https://eslint.org/docs/rules/arrow-body-style"},schema:{anyOf:[{type:"array",items:[{enum:["always","never"]}],minItems:0,maxItems:1},{type:"array",items:[{enum:["as-needed"]},{type:"object",properties:{requireReturnForObjectLiteral:{type:"boolean"}},additionalProperties:!1}],minItems:0,maxItems:2}]},fixable:"code",messages:{unexpectedOtherBlock:"Unexpected block statement surrounding arrow body.",unexpectedEmptyBlock:"Unexpected block statement surrounding arrow body; put a value of `undefined` immediately after the `=>`.",unexpectedObjectBlock:"Unexpected block statement surrounding arrow body; parenthesize the returned value and move it immediately after the `=>`.",unexpectedSingleBlock:"Unexpected block statement surrounding arrow body; move the returned value immediately after the `=>`.",expectedBlock:"Expected block statement surrounding arrow body."}},create(e){const t=e.options,n="always"===t[0],r=!t[0]||"as-needed"===t[0],o="never"===t[0],s=t[1]&&t[1].requireReturnForObjectLiteral,a=e.getSourceCode();let i=null;function c(e){return!(!e||!e.parent)&&("ForStatement"===e.parent.type&&e.parent.init===e||c(e.parent))}function l(t){const l=t.body;if("BlockStatement"===l.type){const n=l.body;if(1!==n.length&&!o)return;if(r&&s&&"ReturnStatement"===n[0].type&&n[0].argument&&"ObjectExpression"===n[0].argument.type)return;if(o||r&&"ReturnStatement"===n[0].type){let r;r=0===n.length?"unexpectedEmptyBlock":n.length>1?"unexpectedOtherBlock":null===n[0].argument?"unexpectedSingleBlock":fr.isOpeningBraceToken(a.getFirstToken(n[0],{skip:1}))?"unexpectedObjectBlock":"unexpectedSingleBlock",e.report({node:t,loc:l.loc,messageId:r,fix(e){const r=[];if(1!==n.length||"ReturnStatement"!==n[0].type||!n[0].argument||(o=a.getTokenAfter(l))&&"Punctuator"===o.type&&/^[([/`+-]/u.test(o.value))return r;var o;const s=a.getFirstToken(l),u=a.getLastToken(l),p=a.getFirstToken(n[0],1),d=a.getLastToken(n[0]);return a.commentsExistBetween(s,p)||a.commentsExistBetween(d,u)?r.push(e.remove(s),e.remove(u),e.remove(a.getTokenAfter(s))):r.push(e.removeRange([s.range[0],p.range[0]]),e.removeRange([d.range[1],u.range[1]])),(fr.isOpeningBraceToken(p)||"SequenceExpression"===n[0].argument.type||i.hasInOperator&&c(t))&&(fr.isParenthesised(a,n[0].argument)||r.push(e.insertTextBefore(p,"("),e.insertTextAfter(d,")"))),fr.isSemicolonToken(d)&&r.push(e.remove(d)),r}})}}else(n||r&&s&&"ObjectExpression"===l.type)&&e.report({node:t,loc:l.loc,messageId:"expectedBlock",fix(e){const n=[],r=a.getTokenBefore(l,fr.isArrowToken),[o,s]=a.getTokensAfter(r,{count:2}),i=a.getLastToken(t);if(fr.isOpeningParenToken(o)&&fr.isOpeningBraceToken(s)){const t=o,r=s;fr.isTokenOnSameLine(t,r)?n.push(e.replaceText(t,"{return ")):n.push(e.replaceText(t,"{"),e.insertTextBefore(r,"return ")),n.push(e.remove(function(e){let t=a.getNodeByRangeIndex(e.range[0]);for(;!fr.isParenthesised(a,t);)t=t.parent;return a.getTokenAfter(t)}(r))),n.push(e.insertTextAfter(i,"}"))}else n.push(e.insertTextBefore(o,"{return ")),n.push(e.insertTextAfter(i,"}"));return n}})}return{"BinaryExpression[operator='in']"(){let e=i;for(;e;)e.hasInOperator=!0,e=e.upper},ArrowFunctionExpression(){i={upper:i,hasInOperator:!1}},"ArrowFunctionExpression:exit"(e){l(e),i=i.upper}}}};var Pr={meta:{type:"layout",docs:{description:"require parentheses around arrow function arguments",category:"ECMAScript 6",recommended:!1,url:"https://eslint.org/docs/rules/arrow-parens"},fixable:"code",schema:[{enum:["always","as-needed"]},{type:"object",properties:{requireForBlockBody:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{unexpectedParens:"Unexpected parentheses around single function argument.",expectedParens:"Expected parentheses around arrow function argument.",unexpectedParensInline:"Unexpected parentheses around single function argument having a body with no curly braces.",expectedParensBlock:"Expected parentheses around arrow function argument having a body with curly braces."}},create(e){const t="as-needed"===e.options[0],n=t&&e.options[1]&&!0===e.options[1].requireForBlockBody,r=e.getSourceCode();function o(e){return r.getTokenAfter(e.params[0],fr.isClosingParenToken)}return{"ArrowFunctionExpression[params.length=1]"(s){const a=!t||n&&function(e){return"BlockStatement"===e.body.type}(s),i=function(e){const t=r.getTokenBefore(e.params[0]);return t&&fr.isOpeningParenToken(t)&&e.range[0]<=t.range[0]?t:null}(s),c=null!==i,[l]=s.params;a&&!c&&e.report({node:s,messageId:n?"expectedParensBlock":"expectedParens",loc:l.loc,*fix(e){yield e.insertTextBefore(l,"("),yield e.insertTextAfter(l,")")}}),a||!c||"Identifier"!==l.type||l.typeAnnotation||s.returnType||function(e,t){return r.commentsExistBetween(t,o(e))}(s,i)||function(e,t){const n=e.async?1:0;return r.getFirstToken(e,{skip:n})!==t}(s,i)||e.report({node:s,messageId:n?"unexpectedParensInline":"unexpectedParens",loc:l.loc,*fix(e){const t=r.getTokenBefore(i),n=o(s);t&&t.range[1]===i.range[0]&&!fr.canTokensBeAdjacent(t,r.getFirstToken(l))&&(yield e.insertTextBefore(i," ")),yield e.removeRange([i.range[0],l.range[0]]),yield e.removeRange([l.range[1],n.range[1]])}})}}}},Tr={meta:{type:"layout",docs:{description:"enforce consistent spacing before and after the arrow in arrow functions",category:"ECMAScript 6",recommended:!1,url:"https://eslint.org/docs/rules/arrow-spacing"},fixable:"whitespace",schema:[{type:"object",properties:{before:{type:"boolean",default:!0},after:{type:"boolean",default:!0}},additionalProperties:!1}],messages:{expectedBefore:"Missing space before =>.",unexpectedBefore:"Unexpected space before =>.",expectedAfter:"Missing space after =>.",unexpectedAfter:"Unexpected space after =>."}},create(e){const t=Object.assign({},e.options[0]);t.before=!1!==t.before,t.after=!1!==t.after;const n=e.getSourceCode();return{ArrowFunctionExpression:function(r){const o=function(e){const t=n.getTokenBefore(e.body,fr.isArrowToken);return{before:n.getTokenBefore(t),arrow:t,after:n.getTokenAfter(t)}}(r),s=function(e){return{before:e.arrow.range[0]-e.before.range[1],after:e.after.range[0]-e.arrow.range[1]}}(o);t.before?0===s.before&&e.report({node:o.before,messageId:"expectedBefore",fix:e=>e.insertTextBefore(o.arrow," ")}):s.before>0&&e.report({node:o.before,messageId:"unexpectedBefore",fix:e=>e.removeRange([o.before.range[1],o.arrow.range[0]])}),t.after?0===s.after&&e.report({node:o.after,messageId:"expectedAfter",fix:e=>e.insertTextAfter(o.arrow," ")}):s.after>0&&e.report({node:o.after,messageId:"unexpectedAfter",fix:e=>e.removeRange([o.arrow.range[1],o.after.range[0]])})}}}},Ir={meta:{type:"suggestion",docs:{description:"enforce the use of variables within the scope they are defined",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/block-scoped-var"},schema:[],messages:{outOfScope:"'{{name}}' used outside of binding context."}},create(e){let t=[];function n(e){t.push(e.range)}function r(){t.pop()}function o(t){const n=t.identifier;e.report({node:n,messageId:"outOfScope",data:{name:n.name}})}return{Program(e){t=[e.range]},BlockStatement:n,"BlockStatement:exit":r,ForStatement:n,"ForStatement:exit":r,ForInStatement:n,"ForInStatement:exit":r,ForOfStatement:n,"ForOfStatement:exit":r,SwitchStatement:n,"SwitchStatement:exit":r,CatchClause:n,"CatchClause:exit":r,VariableDeclaration:function(n){if("var"!==n.kind)return;const r=t[t.length-1];function s(e){const t=e.identifier.range;return t[0]r[1]}const a=e.getDeclaredVariables(n);for(let e=0;e0?r.getTokenBefore(e.cases[0]):r.getLastToken(e,1):r.getFirstToken(e)}(s),i=r.getLastToken(s),c=r.getTokenAfter(a,{includeComments:!0}),l=r.getTokenBefore(i,{includeComments:!0});if("Punctuator"===a.type&&"{"===a.value&&"Punctuator"===i.type&&"}"===i.value&&c!==i&&(t||"Line"!==c.type)){if(!o(a,c)){let r=a.loc;"extra"===n&&(r={start:a.loc.end,end:c.loc.start}),e.report({node:s,loc:r,messageId:n,data:{location:"after",token:a.value},fix:e=>t?e.insertTextBefore(c," "):e.removeRange([a.range[1],c.range[0]])})}if(!o(l,i)){let r=i.loc;"extra"===n&&(r={start:l.loc.end,end:i.loc.start}),e.report({node:s,loc:r,messageId:n,data:{location:"before",token:i.value},fix:e=>t?e.insertTextAfter(l," "):e.removeRange([l.range[1],i.range[0]])})}}}return{BlockStatement:s,SwitchStatement:s}}},Dr={meta:{type:"layout",docs:{description:"enforce consistent brace style for blocks",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/brace-style"},schema:[{enum:["1tbs","stroustrup","allman"]},{type:"object",properties:{allowSingleLine:{type:"boolean",default:!1}},additionalProperties:!1}],fixable:"whitespace",messages:{nextLineOpen:"Opening curly brace does not appear on the same line as controlling statement.",sameLineOpen:"Opening curly brace appears on the same line as controlling statement.",blockSameLine:"Statement inside of curly braces should be on next line.",nextLineClose:"Closing curly brace does not appear on the same line as the subsequent block.",singleLineClose:"Closing curly brace should be on the same line as opening curly brace or on the line after the previous block.",sameLineClose:"Closing curly brace appears on the same line as the subsequent block."}},create(e){const t=e.options[0]||"1tbs",n=e.options[1]||{},r=e.getSourceCode();function o(e,t){const n=[e.range[1],t.range[0]];return r.text.slice(n[0],n[1]).trim()?null:e=>e.replaceTextRange(n," ")}function s(s,a){const i=r.getTokenBefore(s),c=r.getTokenAfter(s),l=r.getTokenBefore(a),u=n.allowSingleLine&&fr.isTokenOnSameLine(s,a);"allman"===t||fr.isTokenOnSameLine(i,s)||e.report({node:s,messageId:"nextLineOpen",fix:o(i,s)}),"allman"===t&&fr.isTokenOnSameLine(i,s)&&!u&&e.report({node:s,messageId:"sameLineOpen",fix:e=>e.insertTextBefore(s,"\n")}),fr.isTokenOnSameLine(s,c)&&c!==a&&!u&&e.report({node:s,messageId:"blockSameLine",fix:e=>e.insertTextAfter(s,"\n")}),l!==s&&!u&&fr.isTokenOnSameLine(l,a)&&e.report({node:a,messageId:"singleLineClose",fix:e=>e.insertTextBefore(a,"\n")})}function a(n){const s=r.getTokenAfter(n);"1tbs"!==t||fr.isTokenOnSameLine(n,s)||e.report({node:n,messageId:"nextLineClose",fix:o(n,s)}),"1tbs"!==t&&fr.isTokenOnSameLine(n,s)&&e.report({node:n,messageId:"sameLineClose",fix:e=>e.insertTextAfter(n,"\n")})}return{BlockStatement(e){fr.STATEMENT_LIST_PARENTS.has(e.parent.type)||s(r.getFirstToken(e),r.getLastToken(e))},ClassBody(e){s(r.getFirstToken(e),r.getLastToken(e))},SwitchStatement(e){const t=r.getLastToken(e);s(r.getTokenBefore(e.cases.length?e.cases[0]:t),t)},IfStatement(e){"BlockStatement"===e.consequent.type&&e.alternate&&a(r.getLastToken(e.consequent))},TryStatement(e){a(r.getLastToken(e.block)),e.handler&&e.finalizer&&a(r.getLastToken(e.handler.body))}}}},Or={meta:{deprecated:!0,replacedBy:[],type:"suggestion",docs:{description:"require `return` statements after callbacks",category:"Node.js and CommonJS",recommended:!1,url:"https://eslint.org/docs/rules/callback-return"},schema:[{type:"array",items:{type:"string"}}],messages:{missingReturn:"Expected return with your callback function."}},create(e){const t=e.options[0]||["callback","cb","next"],n=e.getSourceCode();function r(e,t){return e.parent?-1===t.indexOf(e.parent.type)?r(e.parent,t):e.parent:null}function o(e){if("Identifier"===e.type)return!0;if("MemberExpression"===e.type){if("Identifier"===e.object.type)return!0;if("MemberExpression"===e.object.type)return o(e.object)}return!1}function s(e){return o(e.callee)&&t.indexOf(n.getText(e.callee))>-1}function a(e,t){return!(!t||"ExpressionStatement"!==t.type)&&(t.expression===e||("BinaryExpression"===t.expression.type||"LogicalExpression"===t.expression.type)&&t.expression.right===e)}return{CallExpression(t){if(!s(t))return;const n=r(t,["BlockStatement","ReturnStatement","ArrowFunctionExpression"])||{};if("ReturnStatement"!==n.type&&"ArrowFunctionExpression"!==n.type){if("BlockStatement"===n.type){const e=n.body[n.body.length-1];if(a(t,e)){const e=n.parent.type;if("FunctionExpression"===e||"FunctionDeclaration"===e||"ArrowFunctionExpression"===e)return}if("ReturnStatement"===e.type&&a(t,n.body[n.body.length-2]))return}r(t,["FunctionDeclaration","FunctionExpression","ArrowFunctionExpression"])&&e.report({node:t,messageId:"missingReturn"})}}}}},Br={meta:{type:"suggestion",docs:{description:"enforce camelcase naming convention",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/camelcase"},schema:[{type:"object",properties:{ignoreDestructuring:{type:"boolean",default:!1},ignoreImports:{type:"boolean",default:!1},ignoreGlobals:{type:"boolean",default:!1},properties:{enum:["always","never"]},allow:{type:"array",items:[{type:"string"}],minItems:0,uniqueItems:!0}},additionalProperties:!1}],messages:{notCamelCase:"Identifier '{{name}}' is not in camel case."}},create(e){const t=e.options[0]||{};let n=t.properties||"";const r=t.ignoreDestructuring,o=t.ignoreImports,s=t.ignoreGlobals,a=t.allow||[];let i;"always"!==n&&"never"!==n&&(n="always");const c=[],l=new Set(["CallExpression","NewExpression"]);function u(t){c.includes(t)||(c.push(t),e.report({node:t,messageId:"notCamelCase",data:{name:t.name}}))}return{Program(){i=e.getScope()},Identifier(e){const t=e.name,c=function(e){return e.includes("_")&&e!==e.toUpperCase()}(t.replace(/^_+|_+$/gu,"")),p="MemberExpression"===e.parent.type?e.parent.parent:e.parent;if(!function(e){return a.some((t=>e===t||e.match(new RegExp(t,"u"))))}(t)&&(!s||!function(e){const t=i.set.get(e.name);return t&&0===t.defs.length&&t.references.some((t=>t.identifier===e))}(e)||function(e){const t=e.parent;return"Property"===t.type&&"ObjectExpression"===t.parent.type&&!t.computed&&t.key===e}(e)))if("MemberExpression"===e.parent.type){if("never"===n)return;("Identifier"===e.parent.object.type&&e.parent.object.name===e.name&&c||"AssignmentExpression"===p.type&&c&&("MemberExpression"!==p.right.type||"MemberExpression"===p.left.type&&p.left.property.name===e.name)||function(e){if("MemberExpression"===e.parent.type&&e.parent.property===e&&!e.parent.computed){const t=e.parent.parent;return"Property"===t.type&&t.value===e.parent&&"ObjectPattern"===t.parent.type||"ArrayPattern"===t.type||"RestElement"===t.type||"AssignmentPattern"===t.type&&t.left===e.parent}return!1}(e)&&c)&&u(e)}else if("Property"===e.parent.type||"AssignmentPattern"===e.parent.type){if(e.parent.parent&&"ObjectPattern"===e.parent.parent.type){e.parent.shorthand&&e.parent.value.left&&c&&u(e);const t=e.parent.key.name===e.parent.value.name;if(c&&e.parent.computed&&u(e),e.parent.key===e&&e.parent.value!==e)return;!(e.parent.value.name&&c)||t&&r||u(e)}if("never"===n||r&&function(e){let t=e;for(;t;){const e=t.parent;if(e&&"Property"===e.type&&e.computed&&e.key===t)return!1;if("ObjectPattern"===t.type)return!0;t=e}return!1}(e))return;c&&!l.has(p.type)&&e.parent.right!==e&&u(e)}else if(["ImportSpecifier","ImportNamespaceSpecifier","ImportDefaultSpecifier"].includes(e.parent.type)){if("ImportSpecifier"===e.parent.type&&o)return;e.parent.local&&e.parent.local.name===e.name&&c&&u(e)}else c&&!l.has(p.type)&&u(e)}}}},Nr=/[A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF30-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD801[\uDC00-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDE00-\uDE11\uDE13-\uDE2B\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF5D-\uDF61]|\uD805[\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDE00-\uDE2F\uDE44\uDE80-\uDEAA]|\uD806[\uDCA0-\uDCDF\uDCFF\uDEC0-\uDEF8]|\uD808[\uDC00-\uDF98]|[\uD80C\uD840-\uD868\uD86A-\uD86C][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F]|\uD82C[\uDC00\uDC01]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D]|\uD87E[\uDC00-\uDE1D]/u;const jr=fr.COMMENTS_IGNORE_PATTERN,Lr=/\s/gu,Rr=/^\s*[^:/?#\s]+:\/\/[^?#]/u,Mr={type:"object",properties:{ignorePattern:{type:"string"},ignoreInlineComments:{type:"boolean"},ignoreConsecutiveComments:{type:"boolean"}},additionalProperties:!1},_r={ignorePattern:"",ignoreInlineComments:!1,ignoreConsecutiveComments:!1};function $r(e,t){return Object.assign({},_r,e[t]||e)}var qr={meta:{type:"suggestion",docs:{description:"enforce or disallow capitalization of the first letter of a comment",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/capitalized-comments"},fixable:"code",schema:[{enum:["always","never"]},{oneOf:[Mr,{type:"object",properties:{line:Mr,block:Mr},additionalProperties:!1}]}],messages:{unexpectedLowercaseComment:"Comments should not begin with a lowercase character.",unexpectedUppercaseComment:"Comments should not begin with an uppercase character."}},create(e){const t=e.options[0]||"always",n=function(e={}){return{Line:$r(e,"line"),Block:$r(e,"block")}}(e.options[1]),r=e.getSourceCode();function o(e,n){if(jr.test(e.value))return!0;const o=e.value.replace(/\*/gu,"");if(n.ignorePatternRegExp&&n.ignorePatternRegExp.test(o))return!0;if(n.ignoreInlineComments&&function(e){const t=r.getTokenBefore(e,{includeComments:!0}),n=r.getTokenAfter(e,{includeComments:!0});return Boolean(t&&n&&e.loc.start.line===t.loc.end.line&&e.loc.end.line===n.loc.start.line)}(e))return!0;if(n.ignoreConsecutiveComments&&function(e){const t=r.getTokenBefore(e,{includeComments:!0});return Boolean(t&&-1!==["Block","Line"].indexOf(t.type))}(e))return!0;if(Rr.test(o))return!0;const s=o.replace(Lr,"");if(0===s.length)return!0;const a=s[0];if(!Nr.test(a))return!0;const i=a!==a.toLocaleLowerCase(),c=a!==a.toLocaleUpperCase();return("always"!==t||!c)&&("never"!==t||!i)}function s(r){const s=n[r.type];if(!o(r,s)){const n="always"===t?"unexpectedLowercaseComment":"unexpectedUppercaseComment";e.report({node:null,loc:r.loc,messageId:n,fix(e){const n=r.value.match(Nr);return e.replaceTextRange([r.range[0]+n.index+2,r.range[0]+n.index+3],"always"===t?n[0].toLocaleUpperCase():n[0].toLocaleLowerCase())}})}}return function(e){Object.keys(e).forEach((t=>{const n=e[t].ignorePattern;if(n){const r=RegExp(`^\\s*(?:${n})`,"u");e[t].ignorePatternRegExp=r}}))}(n),{Program(){r.getAllComments().filter((e=>"Shebang"!==e.type)).forEach(s)}}}},Ur={meta:{type:"suggestion",docs:{description:"enforce that class methods utilize `this`",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/class-methods-use-this"},schema:[{type:"object",properties:{exceptMethods:{type:"array",items:{type:"string"}}},additionalProperties:!1}],messages:{missingThis:"Expected 'this' to be used by class {{name}}."}},create(e){const t=Object.assign({},e.options[0]),n=new Set(t.exceptMethods||[]),r=[];function o(){r.push(!1)}function s(t){const o=r.pop();(function(e){return function(e){return!e.static&&"constructor"!==e.kind&&"MethodDefinition"===e.type}(e)&&(e.computed||!n.has(e.key.name))})(t.parent)&&!o&&e.report({node:t,messageId:"missingThis",data:{name:fr.getFunctionNameWithKind(t)}})}function a(){r.length&&(r[r.length-1]=!0)}return{FunctionDeclaration:o,"FunctionDeclaration:exit":s,FunctionExpression:o,"FunctionExpression:exit":s,ThisExpression:a,Super:a}}};const Vr=Object.freeze({arrays:"never",objects:"never",imports:"never",exports:"never",functions:"never"});var Wr={meta:{type:"layout",docs:{description:"require or disallow trailing commas",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/comma-dangle"},fixable:"code",schema:{definitions:{value:{enum:["always-multiline","always","never","only-multiline"]},valueWithIgnore:{enum:["always-multiline","always","ignore","never","only-multiline"]}},type:"array",items:[{oneOf:[{$ref:"#/definitions/value"},{type:"object",properties:{arrays:{$ref:"#/definitions/valueWithIgnore"},objects:{$ref:"#/definitions/valueWithIgnore"},imports:{$ref:"#/definitions/valueWithIgnore"},exports:{$ref:"#/definitions/valueWithIgnore"},functions:{$ref:"#/definitions/valueWithIgnore"}},additionalProperties:!1}]}]},messages:{unexpected:"Unexpected trailing comma.",missing:"Missing trailing comma."}},create(e){const t=(n=e.options[0],r=e.parserOptions.ecmaVersion,"string"==typeof n?{arrays:n,objects:n,imports:n,exports:n,functions:!r||r<8?"ignore":n}:"object"==typeof n&&null!==n?{arrays:n.arrays||Vr.arrays,objects:n.objects||Vr.objects,imports:n.imports||Vr.imports,exports:n.exports||Vr.exports,functions:n.functions||Vr.functions}:Vr);var n,r;const o=e.getSourceCode();function s(e){switch(e.type){case"ObjectExpression":case"ObjectPattern":return F.default.last(e.properties);case"ArrayExpression":case"ArrayPattern":return F.default.last(e.elements);case"ImportDeclaration":case"ExportNamedDeclaration":return F.default.last(e.specifiers);case"FunctionDeclaration":case"FunctionExpression":case"ArrowFunctionExpression":return F.default.last(e.params);case"CallExpression":case"NewExpression":return F.default.last(e.arguments);default:return null}}function a(e,t){switch(e.type){case"ObjectExpression":case"ArrayExpression":case"CallExpression":case"NewExpression":return o.getLastToken(e,1);default:{const e=o.getTokenAfter(t);return fr.isCommaToken(e)?e:o.getLastToken(t)}}}function i(e){const t=s(e);if(!t)return!1;const n=a(e,t);return o.getTokenAfter(n).loc.end.line!==n.loc.end.line}function c(t){const n=s(t);if(!n||"ImportDeclaration"===t.type&&"ImportSpecifier"!==n.type)return;const r=a(t,n);fr.isCommaToken(r)&&e.report({node:n,loc:r.loc,messageId:"unexpected",fix:e=>e.remove(r)})}function l(t){const n=s(t);if(!n||"ImportDeclaration"===t.type&&"ImportSpecifier"!==n.type)return;if(!function(e){return!("RestElement"===e.type||"RestProperty"===e.type||"ExperimentalRestProperty"===e.type)}(n))return void c(t);const r=a(t,n);","!==r.value&&e.report({node:n,loc:{start:r.loc.end,end:fr.getNextLocation(o,r.loc.end)},messageId:"missing",fix:e=>e.insertTextAfter(r,",")})}const u={always:l,"always-multiline":function(e){i(e)?l(e):c(e)},"only-multiline":function(e){i(e)||c(e)},never:c,ignore:F.default.noop};return{ObjectExpression:u[t.objects],ObjectPattern:u[t.objects],ArrayExpression:u[t.arrays],ArrayPattern:u[t.arrays],ImportDeclaration:u[t.imports],ExportNamedDeclaration:u[t.exports],FunctionDeclaration:u[t.functions],FunctionExpression:u[t.functions],ArrowFunctionExpression:u[t.functions],CallExpression:u[t.functions],NewExpression:u[t.functions]}}},Gr={meta:{type:"layout",docs:{description:"enforce consistent spacing before and after commas",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/comma-spacing"},fixable:"whitespace",schema:[{type:"object",properties:{before:{type:"boolean",default:!1},after:{type:"boolean",default:!0}},additionalProperties:!1}],messages:{missing:"A space is required {{loc}} ','.",unexpected:"There should be no space {{loc}} ','."}},create(e){const t=e.getSourceCode(),n=t.tokensAndComments,r={before:!!e.options[0]&&e.options[0].before,after:!e.options[0]||e.options[0].after},o=[];function s(t,n,o){e.report({node:t,fix(e){if(r[n])return"before"===n?e.insertTextBefore(t," "):e.insertTextAfter(t," ");let s,a;return"before"===n?(s=o.range[1],a=t.range[0]):(s=t.range[1],a=o.range[0]),e.replaceTextRange([s,a],"")},messageId:r[n]?"missing":"unexpected",data:{loc:n}})}function a(e){let n=t.getFirstToken(e);e.elements.forEach((e=>{let r;null===e?(r=t.getTokenAfter(n),fr.isCommaToken(r)&&o.push(r)):r=t.getTokenAfter(e),n=r}))}return{"Program:exit"(){n.forEach(((e,a)=>{if(!fr.isCommaToken(e))return;if(e&&"JSXText"===e.type)return;const i=n[a-1],c=n[a+1];var l,u;l={comma:e,left:fr.isCommaToken(i)||o.indexOf(e)>-1?null:i,right:fr.isCommaToken(c)?null:c},u=e,l.left&&fr.isTokenOnSameLine(l.left,l.comma)&&r.before!==t.isSpaceBetweenTokens(l.left,l.comma)&&s(u,"before",l.left),l.right&&fr.isClosingParenToken(l.right)||l.right&&!r.after&&"Line"===l.right.type||l.right&&fr.isTokenOnSameLine(l.comma,l.right)&&r.after!==t.isSpaceBetweenTokens(l.comma,l.right)&&s(u,"after",l.right)}))},ArrayExpression:a,ArrayPattern:a}}},zr={meta:{type:"layout",docs:{description:"enforce consistent comma style",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/comma-style"},fixable:"code",schema:[{enum:["first","last"]},{type:"object",properties:{exceptions:{type:"object",additionalProperties:{type:"boolean"}}},additionalProperties:!1}],messages:{unexpectedLineBeforeAndAfterComma:"Bad line breaking before and after ','.",expectedCommaFirst:"',' should be placed first.",expectedCommaLast:"',' should be placed last."}},create(e){const t=e.options[0]||"last",n=e.getSourceCode(),r={ArrayPattern:!0,ArrowFunctionExpression:!0,CallExpression:!0,FunctionDeclaration:!0,FunctionExpression:!0,ImportDeclaration:!0,ObjectPattern:!0,NewExpression:!0};if(2===e.options.length&&Object.prototype.hasOwnProperty.call(e.options[1],"exceptions")){const t=Object.keys(e.options[1].exceptions);for(let n=0;n1||o){let t=n.getFirstToken(e);if(r.forEach((e=>{const r=e?n.getTokenBefore(e):t,o=e?n.getFirstToken(e):n.getTokenAfter(r),a=e||o;if(fr.isCommaToken(r)&&s(t,r,o,a),e){const r=n.getTokenAfter(e,fr.isNotClosingParenToken);t=r?n.getTokenBefore(r):n.ast.tokens[n.ast.tokens.length-1]}})),o){const t=n.getLastToken(e),r=n.getTokenBefore(t);fr.isCommaToken(r)&&s(n.getTokenBefore(r),r,t,t)}}}const i={};return r.VariableDeclaration||(i.VariableDeclaration=function(e){a(e,"declarations")}),r.ObjectExpression||(i.ObjectExpression=function(e){a(e,"properties")}),r.ObjectPattern||(i.ObjectPattern=function(e){a(e,"properties")}),r.ArrayExpression||(i.ArrayExpression=function(e){a(e,"elements")}),r.ArrayPattern||(i.ArrayPattern=function(e){a(e,"elements")}),r.FunctionDeclaration||(i.FunctionDeclaration=function(e){a(e,"params")}),r.FunctionExpression||(i.FunctionExpression=function(e){a(e,"params")}),r.ArrowFunctionExpression||(i.ArrowFunctionExpression=function(e){a(e,"params")}),r.CallExpression||(i.CallExpression=function(e){a(e,"arguments")}),r.ImportDeclaration||(i.ImportDeclaration=function(e){a(e,"specifiers")}),r.NewExpression||(i.NewExpression=function(e){a(e,"arguments")}),i}},Jr={meta:{type:"suggestion",docs:{description:"enforce a maximum cyclomatic complexity allowed in a program",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/complexity"},schema:[{oneOf:[{type:"integer",minimum:0},{type:"object",properties:{maximum:{type:"integer",minimum:0},max:{type:"integer",minimum:0}},additionalProperties:!1}]}],messages:{complex:"{{name}} has a complexity of {{complexity}}. Maximum allowed is {{max}}."}},create(e){const t=e.options[0];let n=20;"object"==typeof t&&(Object.prototype.hasOwnProperty.call(t,"maximum")||Object.prototype.hasOwnProperty.call(t,"max"))?n=t.maximum||t.max:"number"==typeof t&&(n=t);const r=[];function o(){r.push(1)}function s(t){const o=F.default.upperFirst(fr.getFunctionNameWithKind(t)),s=r.pop();s>n&&e.report({node:t,messageId:"complex",data:{name:o,complexity:s,max:n}})}function a(){r.length&&r[r.length-1]++}return{FunctionDeclaration:o,FunctionExpression:o,ArrowFunctionExpression:o,"FunctionDeclaration:exit":s,"FunctionExpression:exit":s,"ArrowFunctionExpression:exit":s,CatchClause:a,ConditionalExpression:a,LogicalExpression:a,ForStatement:a,ForInStatement:a,ForOfStatement:a,IfStatement:a,SwitchCase:function(e){e.test&&a()},WhileStatement:a,DoWhileStatement:a,AssignmentExpression(e){fr.isLogicalAssignmentOperator(e.operator)&&a()}}}},Kr={meta:{type:"layout",docs:{description:"enforce consistent spacing inside computed property brackets",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/computed-property-spacing"},fixable:"whitespace",schema:[{enum:["always","never"]},{type:"object",properties:{enforceForClassMembers:{type:"boolean",default:!0}},additionalProperties:!1}],messages:{unexpectedSpaceBefore:"There should be no space before '{{tokenValue}}'.",unexpectedSpaceAfter:"There should be no space after '{{tokenValue}}'.",missingSpaceBefore:"A space is required before '{{tokenValue}}'.",missingSpaceAfter:"A space is required after '{{tokenValue}}'."}},create(e){const t=e.getSourceCode(),n="always"===e.options[0],r=!e.options[1]||e.options[1].enforceForClassMembers;function o(r){return function(o){if(!o.computed)return;const s=o[r],a=t.getTokenBefore(s,fr.isOpeningBracketToken),i=t.getTokenAfter(a,{includeComments:!0}),c=t.getTokenAfter(s,fr.isClosingBracketToken),l=t.getTokenBefore(c,{includeComments:!0});fr.isTokenOnSameLine(a,i)&&(n?!t.isSpaceBetweenTokens(a,i)&&fr.isTokenOnSameLine(a,i)&&function(t,n){e.report({node:t,loc:n.loc,messageId:"missingSpaceAfter",data:{tokenValue:n.value},fix:e=>e.insertTextAfter(n," ")})}(o,a):t.isSpaceBetweenTokens(a,i)&&function(t,n,r){e.report({node:t,loc:{start:n.loc.end,end:r.loc.start},messageId:"unexpectedSpaceAfter",data:{tokenValue:n.value},fix:e=>e.removeRange([n.range[1],r.range[0]])})}(o,a,i)),fr.isTokenOnSameLine(l,c)&&(n?!t.isSpaceBetweenTokens(l,c)&&fr.isTokenOnSameLine(l,c)&&function(t,n){e.report({node:t,loc:n.loc,messageId:"missingSpaceBefore",data:{tokenValue:n.value},fix:e=>e.insertTextBefore(n," ")})}(o,c):t.isSpaceBetweenTokens(l,c)&&function(t,n,r){e.report({node:t,loc:{start:r.loc.end,end:n.loc.start},messageId:"unexpectedSpaceBefore",data:{tokenValue:n.value},fix:e=>e.removeRange([r.range[1],n.range[0]])})}(o,c,l))}}const s={Property:o("key"),MemberExpression:o("property")};return r&&(s.MethodDefinition=o("key")),s}};function Yr(e){return!e.reachable}var Hr={meta:{type:"suggestion",docs:{description:"require `return` statements to either always or never specify values",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/consistent-return"},schema:[{type:"object",properties:{treatUndefinedAsUnspecified:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{missingReturn:"Expected to return a value at the end of {{name}}.",missingReturnValue:"{{name}} expected a return value.",unexpectedReturnValue:"{{name}} expected no return value."}},create(e){const t=!0===(e.options[0]||{}).treatUndefinedAsUnspecified;let n=null;function r(t){let r,o;!n.hasReturnValue||n.codePath.currentSegments.every(Yr)||fr.isES5Constructor(t)||function(e){return"FunctionExpression"===e.type&&e.parent&&"MethodDefinition"===e.parent.type&&"constructor"===e.parent.kind}(t)||("Program"===t.type?(r={line:1,column:0},o="program"):r="ArrowFunctionExpression"===t.type?e.getSourceCode().getTokenBefore(t.body,fr.isArrowToken).loc.start:"MethodDefinition"===t.parent.type||"Property"===t.parent.type&&t.parent.method?t.parent.key.loc.start:(t.id||t).loc.start,o||(o=fr.getFunctionNameWithKind(t)),e.report({node:t,loc:r,messageId:"missingReturn",data:{name:o}}))}return{onCodePathStart(e,t){n={upper:n,codePath:e,hasReturn:!1,hasReturnValue:!1,messageId:"",node:t}},onCodePathEnd(){n=n.upper},ReturnStatement(r){const o=r.argument;let s=Boolean(o);t&&s&&(s=!fr.isSpecificId(o,"undefined")&&"void"!==o.operator),n.hasReturn?n.hasReturnValue!==s&&e.report({node:r,messageId:n.messageId,data:n.data}):(n.hasReturn=!0,n.hasReturnValue=s,n.messageId=s?"missingReturnValue":"unexpectedReturnValue",n.data={name:"Program"===n.node.type?"Program":F.default.upperFirst(fr.getFunctionNameWithKind(n.node))})},"Program:exit":r,"FunctionDeclaration:exit":r,"FunctionExpression:exit":r,"ArrowFunctionExpression:exit":r}}},Xr={meta:{type:"suggestion",docs:{description:"enforce consistent naming when capturing the current execution context",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/consistent-this"},schema:{type:"array",items:{type:"string",minLength:1},uniqueItems:!0},messages:{aliasNotAssignedToThis:"Designated alias '{{name}}' is not assigned to 'this'.",unexpectedAlias:"Unexpected alias '{{name}}' for 'this'."}},create(e){let t=[];function n(t,n){e.report({node:t,messageId:"aliasNotAssignedToThis",data:{name:n}})}function r(r,o,s){const a="ThisExpression"===s.type;-1!==t.indexOf(o)?(!a||r.operator&&"="!==r.operator)&&n(r,o):a&&e.report({node:r,messageId:"unexpectedAlias",data:{name:o}})}function o(){const r=e.getScope();t.forEach((e=>{!function(e,t){const r=t.set.get(e);r&&(r.defs.some((e=>"VariableDeclarator"===e.node.type&&null!==e.node.init))||r.references.some((e=>{const n=e.writeExpr;return e.from===t&&n&&"ThisExpression"===n.type&&"="===n.parent.operator}))||r.defs.map((e=>e.node)).forEach((t=>{n(t,e)})))}(e,r)}))}return 0===e.options.length?t.push("that"):t=e.options,{"Program:exit":o,"FunctionExpression:exit":o,"FunctionDeclaration:exit":o,VariableDeclarator(e){const t=e.id,n="ArrayPattern"===t.type||"ObjectPattern"===t.type;null===e.init||n||r(e,t.name,e.init)},AssignmentExpression(e){"Identifier"===e.left.type&&r(e,e.left.name,e.right)}}}};function Qr(e){return e.reachable}function Zr(e){if(!e)return!1;switch(e.type){case"ClassExpression":case"FunctionExpression":case"ThisExpression":case"MemberExpression":case"CallExpression":case"NewExpression":case"ChainExpression":case"YieldExpression":case"TaggedTemplateExpression":case"MetaProperty":return!0;case"Identifier":return"undefined"!==e.name;case"AssignmentExpression":return["=","&&="].includes(e.operator)?Zr(e.right):!!["||=","??="].includes(e.operator)&&(Zr(e.left)||Zr(e.right));case"LogicalExpression":return"&&"===e.operator?Zr(e.right):Zr(e.left)||Zr(e.right);case"ConditionalExpression":return Zr(e.alternate)||Zr(e.consequent);case"SequenceExpression":return Zr(e.expressions[e.expressions.length-1]);default:return!1}}var eo={meta:{type:"problem",docs:{description:"require `super()` calls in constructors",category:"ECMAScript 6",recommended:!0,url:"https://eslint.org/docs/rules/constructor-super"},schema:[],messages:{missingSome:"Lacked a call of 'super()' in some code paths.",missingAll:"Expected to call 'super()'.",duplicate:"Unexpected duplicate 'super()'.",badSuper:"Unexpected 'super()' because 'super' is not a constructor.",unexpected:"Unexpected 'super()'."}},create(e){let t=null,n=Object.create(null);function r(e){return e.reachable&&n[e.id].calledInSomePaths}function o(e){return!(1!==e.nextSegments.length||!e.nextSegments[0].isLoopedPrevSegment(e))||e.reachable&&n[e.id].calledInEveryPaths}return{onCodePathStart(e,n){if(function(e){return"FunctionExpression"===e.type&&"MethodDefinition"===e.parent.type&&"constructor"===e.parent.kind}(n)){const r=n.parent.parent.parent.superClass;t={upper:t,isConstructor:!0,hasExtends:Boolean(r),superIsConstructor:Zr(r),codePath:e}}else t={upper:t,isConstructor:!1,hasExtends:!1,superIsConstructor:!1,codePath:e}},onCodePathEnd(n,s){const a=t.hasExtends;if(t=t.upper,!a)return;const i=n.returnedSegments,c=i.every(o),l=i.some(r);c||e.report({messageId:l?"missingSome":"missingAll",node:s.parent})},onCodePathSegmentStart(e){if(!(t&&t.isConstructor&&t.hasExtends))return;const s=n[e.id]={calledInSomePaths:!1,calledInEveryPaths:!1,validNodes:[]},a=e.prevSegments;a.length>0&&(s.calledInSomePaths=a.some(r),s.calledInEveryPaths=a.every(o))},onCodePathSegmentLoop(s,a){if(!(t&&t.isConstructor&&t.hasExtends))return;const i=a.prevSegments.length>=2;t.codePath.traverseSegments({first:a,last:s},(t=>{const s=n[t.id],a=t.prevSegments;if(s.calledInSomePaths=a.some(r),s.calledInEveryPaths=a.every(o),s.calledInSomePaths||i){const t=s.validNodes;s.validNodes=[];for(let n=0;n0}else f=!a(i);else f=!0;return{actual:d,expected:f,check(){null!==this.expected&&this.expected!==this.actual&&(this.expected?e.report({node:o,loc:("else"!==l?o:c(o)).loc.start,messageId:p&&p.condition?"missingCurlyAfterCondition":"missingCurlyAfter",data:{name:l},fix:e=>e.replaceText(i,`{${s.getText(i)}}`)}):e.report({node:o,loc:("else"!==l?o:c(o)).loc.start,messageId:p&&p.condition?"unexpectedCurlyAfterCondition":"unexpectedCurlyAfter",data:{name:l},fix(e){const t="DoWhileStatement"===o.type&&s.getTokenBefore(i).range[1]===i.range[0]&&!fr.canTokensBeAdjacent("do",s.getFirstToken(i,{skip:1})),n=s.getFirstToken(i),r=s.getLastToken(i),a=s.getTokenBefore(r);if(function(e){const t=s.getTokenBefore(e),n=s.getTokenAfter(e),r=s.getNodeByRangeIndex(t.range[0]);return!(fr.isSemicolonToken(t)||!n||"BlockStatement"===r.type&&"FunctionExpression"!==r.parent.type&&"ArrowFunctionExpression"!==r.parent.type||t.loc.end.line!==n.loc.start.line&&!/^[([/`+-]/u.test(n.value)&&("Punctuator"!==t.type||"++"!==t.value&&"--"!==t.value))}(r))return null;const c=s.getText().slice(n.range[1],a.range[0])+s.getText(a)+s.getText().slice(a.range[1],r.range[0]);return e.replaceText(i,(t?" ":"")+c)}}))}}}return{IfStatement(e){const t=e.parent;"IfStatement"===t.type&&t.alternate===e||function(e){const t=[];for(let n=e;n;n=n.alternate)if(t.push(p(n,n.consequent,"if",{condition:!0})),n.alternate&&"IfStatement"!==n.alternate.type){t.push(p(n,n.alternate,"else"));break}if(o){const e=t.some((e=>null!==e.expected?e.expected:e.actual));t.forEach((t=>{t.expected=e}))}return t}(e).forEach((e=>{e.check()}))},WhileStatement(e){p(e,e.body,"while",{condition:!0}).check()},DoWhileStatement(e){p(e,e.body,"do").check()},ForStatement(e){p(e,e.body,"for",{condition:!0}).check()},ForInStatement(e){p(e,e.body,"for-in").check()},ForOfStatement(e){p(e,e.body,"for-of").check()}}}};const no=/^no default$/iu;var ro={meta:{type:"suggestion",docs:{description:"require `default` cases in `switch` statements",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/default-case"},schema:[{type:"object",properties:{commentPattern:{type:"string"}},additionalProperties:!1}],messages:{missingDefaultCase:"Expected a default case."}},create(e){const t=e.options[0]||{},n=t.commentPattern?new RegExp(t.commentPattern,"u"):no,r=e.getSourceCode();function o(e){return e[e.length-1]}return{SwitchStatement(t){if(!t.cases.length)return;if(!t.cases.some((e=>null===e.test))){let s;const a=o(t.cases),i=r.getCommentsAfter(a);i.length&&(s=o(i)),s&&n.test(s.value.trim())||e.report({node:t,messageId:"missingDefaultCase"})}}}}},oo={meta:{type:"suggestion",docs:{description:"enforce default clauses in switch statements to be last",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/default-case-last"},schema:[],messages:{notLast:"Default clause should be the last clause."}},create:e=>({SwitchStatement(t){const n=t.cases,r=n.findIndex((e=>null===e.test));if(-1!==r&&r!==n.length-1){const t=n[r];e.report({node:t,messageId:"notLast"})}}})},so={meta:{type:"suggestion",docs:{description:"enforce default parameters to be last",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/default-param-last"},schema:[],messages:{shouldBeLast:"Default parameters should be last."}},create(e){function t(t){let n=!1;for(let r=t.params.length-1;r>=0;r-=1){const o=t.params[r];"AssignmentPattern"===o.type||"RestElement"===o.type?n&&"AssignmentPattern"===o.type&&e.report({node:o,messageId:"shouldBeLast"}):n=!0}}return{FunctionDeclaration:t,FunctionExpression:t,ArrowFunctionExpression:t}}},ao={meta:{type:"layout",docs:{description:"enforce consistent newlines before and after dots",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/dot-location"},schema:[{enum:["object","property"]}],fixable:"code",messages:{expectedDotAfterObject:"Expected dot to be on same line as object.",expectedDotBeforeProperty:"Expected dot to be on same line as property."}},create(e){const t=e.options[0],n="object"===t||!t,r=e.getSourceCode();return{MemberExpression:function(t){t.computed||function(t){const o=t.property,s=r.getTokenBefore(o);if(n){const n=r.getTokenBefore(s);fr.isTokenOnSameLine(n,s)||e.report({node:t,loc:s.loc,messageId:"expectedDotAfterObject",*fix(e){s.value.startsWith(".")&&fr.isDecimalIntegerNumericToken(n)?yield e.insertTextAfter(n,` ${s.value}`):yield e.insertTextAfter(n,s.value),yield e.remove(s)}})}else fr.isTokenOnSameLine(s,o)||e.report({node:t,loc:s.loc,messageId:"expectedDotBeforeProperty",*fix(e){yield e.remove(s),yield e.insertTextBefore(o,s.value)}})}(t)}}}},io=["abstract","boolean","break","byte","case","catch","char","class","const","continue","debugger","default","delete","do","double","else","enum","export","extends","false","final","finally","float","for","function","goto","if","implements","import","in","instanceof","int","interface","long","native","new","null","package","private","protected","public","return","short","static","super","switch","synchronized","this","throw","throws","transient","true","try","typeof","var","void","volatile","while","with"];const co=/^[a-zA-Z_$][a-zA-Z0-9_$]*$/u,lo=new Set(["string","boolean"]);var uo={meta:{type:"suggestion",docs:{description:"enforce dot notation whenever possible",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/dot-notation"},schema:[{type:"object",properties:{allowKeywords:{type:"boolean",default:!0},allowPattern:{type:"string",default:""}},additionalProperties:!1}],fixable:"code",messages:{useDot:"[{{key}}] is better written in dot notation.",useBrackets:".{{key}} is a syntax error."}},create(e){const t=e.options[0]||{},n=void 0===t.allowKeywords||t.allowKeywords,r=e.getSourceCode();let o;function s(t,s){if(co.test(s)&&(n||-1===io.indexOf(String(s)))&&(!o||!o.test(s))){const n="Literal"===t.property.type?JSON.stringify(s):`\`${s}\``;e.report({node:t.property,messageId:"useDot",data:{key:n},*fix(e){const n=r.getTokenAfter(t.object,fr.isOpeningBracketToken),o=r.getLastToken(t),a=r.getTokenAfter(t);r.commentsExistBetween(n,o)||(t.optional||(yield e.insertTextBefore(n,fr.isDecimalInteger(t.object)?" .":".")),yield e.replaceTextRange([n.range[0],o.range[1]],s),a&&o.range[1]===a.range[0]&&!fr.canTokensBeAdjacent(String(s),a)&&(yield e.insertTextAfter(t," ")))}})}}return t.allowPattern&&(o=new RegExp(t.allowPattern,"u")),{MemberExpression(t){t.computed&&"Literal"===t.property.type&&(lo.has(typeof t.property.value)||fr.isNullLiteral(t.property))&&s(t,t.property.value),t.computed&&"TemplateLiteral"===t.property.type&&0===t.property.expressions.length&&s(t,t.property.quasis[0].value.cooked),n||t.computed||-1===io.indexOf(String(t.property.name))||e.report({node:t.property,messageId:"useBrackets",data:{key:t.property.name},*fix(e){const n=r.getTokenBefore(t.property);("Identifier"!==t.object.type||"let"!==t.object.name||t.optional)&&(r.commentsExistBetween(n,t.property)||(t.optional||(yield e.remove(n)),yield e.replaceText(t.property,`["${t.property.name}"]`)))}})}}}},po={meta:{type:"layout",docs:{description:"require or disallow newline at the end of files",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/eol-last"},fixable:"whitespace",schema:[{enum:["always","never","unix","windows"]}],messages:{missing:"Newline required at end of file but not found.",unexpected:"Newline not allowed at end of file."}},create:e=>({Program:function(t){const n=e.getSourceCode(),r=n.getText(),o={column:F.default.last(n.lines).length,line:n.lines.length},s=r.endsWith("\n");if(!r.length)return;let a=e.options[0]||"always",i=!1;"unix"===a&&(a="always"),"windows"===a&&(a="always",i=!0),"always"!==a||s?"never"===a&&s&&e.report({node:t,loc:o,messageId:"unexpected",fix(e){const t=/(?:\r?\n)+$/u.exec(n.text).index,r=n.text.length;return e.replaceTextRange([t,r],"")}}):e.report({node:t,loc:o,messageId:"missing",fix:e=>e.insertTextAfterRange([0,r.length],i?"\r\n":"\n")})}})},fo={meta:{type:"suggestion",docs:{description:"require the use of `===` and `!==`",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/eqeqeq"},schema:{anyOf:[{type:"array",items:[{enum:["always"]},{type:"object",properties:{null:{enum:["always","never","ignore"]}},additionalProperties:!1}],additionalItems:!1},{type:"array",items:[{enum:["smart","allow-null"]}],additionalItems:!1}]},fixable:"code",messages:{unexpected:"Expected '{{expectedOperator}}' and instead saw '{{actualOperator}}'."}},create(e){const t=e.options[0]||"always",n=e.options[1]||{},r=e.getSourceCode(),o="always"===t?n.null||"always":"ignore",s="always"===o,a="never"===o;function i(e){return"UnaryExpression"===e.type&&"typeof"===e.operator}function c(e){return i(e.left)||i(e.right)}function l(e){return"Literal"===e.left.type&&"Literal"===e.right.type&&typeof e.left.value==typeof e.right.value}function u(t,n){const o=r.getFirstTokenBetween(t.left,t.right,(e=>e.value===t.operator));e.report({node:t,loc:o.loc,messageId:"unexpected",data:{expectedOperator:n,actualOperator:t.operator},fix:e=>c(t)||l(t)?e.replaceText(o,n):null})}return{BinaryExpression(e){const n=function(e){return fr.isNullLiteral(e.right)||fr.isNullLiteral(e.left)}(e);"=="===e.operator||"!="===e.operator?"smart"===t&&(c(e)||l(e)||n)||!s&&n||u(e,`${e.operator}=`):a&&n&&u(e,e.operator.slice(0,-1))}}}},mo={meta:{type:"problem",docs:{description:'enforce "for" loop update clause moving the counter in the right direction.',category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/for-direction"},fixable:null,schema:[],messages:{incorrectDirection:"The update clause in this loop moves the variable in the wrong direction."}},create(e){function t(t){e.report({node:t,messageId:"incorrectDirection"})}function n(e,t){if("UnaryExpression"===e.right.type){if("-"===e.right.operator)return-t}else if("Identifier"===e.right.type)return 0;return t}return{ForStatement(e){if(e.test&&"BinaryExpression"===e.test.type&&"Identifier"===e.test.left.type&&e.update){const r=e.test.left.name,o=e.test.operator,s=e.update;let a;if("<"===o||"<="===o)a=-1;else{if(">"!==o&&">="!==o)return;a=1}"UpdateExpression"===s.type?function(e,t){if("Identifier"===e.argument.type&&e.argument.name===t){if("++"===e.operator)return 1;if("--"===e.operator)return-1}return 0}(s,r)===a&&t(e):"AssignmentExpression"===s.type&&function(e,t){if(e.left.name===t){if("+="===e.operator)return n(e,1);if("-="===e.operator)return n(e,-1)}return 0}(s,r)===a&&t(e)}}}}},go={meta:{type:"layout",docs:{description:"require or disallow spacing between function identifiers and their invocations",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/func-call-spacing"},fixable:"whitespace",schema:{anyOf:[{type:"array",items:[{enum:["never"]}],minItems:0,maxItems:1},{type:"array",items:[{enum:["always"]},{type:"object",properties:{allowNewlines:{type:"boolean"}},additionalProperties:!1}],minItems:0,maxItems:2}]},messages:{unexpectedWhitespace:"Unexpected whitespace between function name and paren.",unexpectedNewline:"Unexpected newline between function name and paren.",missing:"Missing space between function name and paren."}},create(e){const t="always"!==e.options[0],n=!t&&e.options[1]&&e.options[1].allowNewlines,r=e.getSourceCode(),o=r.getText();function s(s,a,i){const c=o.slice(a.range[1],i.range[0]).replace(/\/\*.*?\*\//gu,""),l=/\s/u.test(c),u=l&&fr.LINEBREAK_MATCHER.test(c);t&&l?e.report({node:s,loc:{start:a.loc.end,end:{line:i.loc.start.line,column:i.loc.start.column-1}},messageId:"unexpectedWhitespace",fix:e=>r.commentsExistBetween(a,i)?null:s.optional?e.replaceTextRange([a.range[1],i.range[0]],"?."):u?null:e.removeRange([a.range[1],i.range[0]])}):t||l?t||n||!u||e.report({node:s,loc:{start:a.loc.end,end:i.loc.start},messageId:"unexpectedNewline",fix(e){if(!s.optional)return null;if(r.commentsExistBetween(a,i))return null;const t=[a.range[1],i.range[0]],n=r.getTokenAfter(a);return n.range[0]===a.range[1]?e.replaceTextRange(t,"?. "):n.range[1]===i.range[0]?e.replaceTextRange(t," ?."):e.replaceTextRange(t," ?. ")}}):e.report({node:s,loc:{start:{line:a.loc.end.line,column:a.loc.end.column-1},end:i.loc.start},messageId:"missing",fix:e=>s.optional?null:e.insertTextBefore(i," ")})}return{"CallExpression, NewExpression"(e){const t=r.getLastToken(e),n=r.getLastToken(e.callee),o=r.getFirstTokenBetween(n,t,fr.isOpeningParenToken),a=o&&r.getTokenBefore(o,fr.isNotQuestionDotToken);o&&o.range[1]=6?Y.default.keyword.isIdentifierES6(e):Y.default.keyword.isIdentifierES5(e)}const yo={type:"object",properties:{considerPropertyDescriptor:{type:"boolean"},includeCommonJSModuleExports:{type:"boolean"}},additionalProperties:!1};var xo={meta:{type:"suggestion",docs:{description:"require function names to match the name of the variable or property to which they are assigned",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/func-name-matching"},schema:{anyOf:[{type:"array",additionalItems:!1,items:[{enum:["always","never"]},yo]},{type:"array",additionalItems:!1,items:[yo]}]},messages:{matchProperty:"Function name `{{funcName}}` should match property name `{{name}}`.",matchVariable:"Function name `{{funcName}}` should match variable name `{{name}}`.",notMatchProperty:"Function name `{{funcName}}` should not match property name `{{name}}`.",notMatchVariable:"Function name `{{funcName}}` should not match variable name `{{name}}`."}},create(e){const t=("object"==typeof e.options[0]?e.options[0]:e.options[1])||{},n="string"==typeof e.options[0]?e.options[0]:"always",r=t.considerPropertyDescriptor,o=t.includeCommonJSModuleExports,s=e.parserOptions&&e.parserOptions.ecmaVersion?e.parserOptions.ecmaVersion:5;function a(e,t,n){return!!n&&("CallExpression"===n.type&&fr.isSpecificMemberAccess(n.callee,e,t))}function i(e,t){return"always"===n&&e!==t||"never"===n&&e===t}function c(t,r,o,s){let a;a="always"===n&&s?"matchProperty":"always"===n?"matchVariable":s?"notMatchProperty":"notMatchVariable",e.report({node:t,messageId:a,data:{name:r,funcName:o}})}function l(e){return"Literal"===e.type&&"string"==typeof e.value}return{VariableDeclarator(e){e.init&&"FunctionExpression"===e.init.type&&"Identifier"===e.id.type&&e.init.id&&i(e.id.name,e.init.id.name)&&c(e,e.id.name,e.init.id.name,!1)},AssignmentExpression(e){if("FunctionExpression"!==e.right.type||e.left.computed&&"Literal"!==e.left.property.type||!o&&function(e){if("MemberExpression"===e.type&&"Identifier"===e.object.type&&"module"===e.object.name){if("Identifier"===e.property.type&&"exports"===e.property.name)return!0;if("Literal"===e.property.type&&"exports"===e.property.value)return!0}return!1}(e.left)||"Identifier"!==e.left.type&&"MemberExpression"!==e.left.type)return;const t="MemberExpression"===e.left.type,n=t?fr.getStaticPropertyName(e.left):e.left.name;e.right.id&&ho(n)&&i(n,e.right.id.name)&&c(e,n,e.right.id.name,t)},Property(e){if("FunctionExpression"===e.value.type&&e.value.id&&(!e.computed||l(e.key)))if("Identifier"!==e.key.type)l(e.key)&&ho(e.key.value,s)&&i(e.key.value,e.value.id.name)&&c(e,e.key.value,e.value.id.name,!0);else{const t=e.value.id.name;let n=e.key.name;if(r&&"value"===n)if(a("Object","defineProperty",e.parent.parent)||a("Reflect","defineProperty",e.parent.parent)){const n=e.parent.parent.arguments[1];l(n)&&i(n.value,t)&&c(e,n.value,t,!0)}else a("Object","defineProperties",e.parent.parent.parent.parent)||a("Object","create",e.parent.parent.parent.parent)?(n=e.parent.parent.key.name,!e.parent.parent.computed&&i(n,t)&&c(e,n,t,!0)):i(n,t)&&c(e,n,t,!0);else i(n,t)&&c(e,n,t,!0)}}}}};var bo={meta:{type:"suggestion",docs:{description:"require or disallow named `function` expressions",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/func-names"},schema:{definitions:{value:{enum:["always","as-needed","never"]}},items:[{$ref:"#/definitions/value"},{type:"object",properties:{generators:{$ref:"#/definitions/value"}},additionalProperties:!1}]},messages:{unnamed:"Unexpected unnamed {{name}}.",named:"Unexpected named {{name}}."}},create(e){const t=e.getSourceCode();function n(e){const t=e.parent;return"MethodDefinition"===t.type||"Property"===t.type&&(t.method||"get"===t.kind||"set"===t.kind)}function r(n){e.report({node:n,messageId:"unnamed",loc:fr.getFunctionHeadLoc(n,t),data:{name:fr.getFunctionNameWithKind(n)}})}function o(o){const s=e.getDeclaredVariables(o)[0];if((a=s)&&"FunctionName"===a.defs[0].type&&s.references.length>0)return;var a;const i=Boolean(o.id&&o.id.name),c=function(t){return t.generator&&e.options.length>1&&e.options[1].generators?e.options[1].generators:e.options[0]||"always"}(o);"never"===c?i&&"FunctionDeclaration"!==o.type&&function(n){e.report({node:n,messageId:"named",loc:fr.getFunctionHeadLoc(n,t),data:{name:fr.getFunctionNameWithKind(n)}})}(o):"as-needed"===c?i||function(e){const t=e.parent;return n(e)||"VariableDeclarator"===t.type&&"Identifier"===t.id.type&&t.init===e||"Property"===t.type&&t.value===e||"AssignmentExpression"===t.type&&"Identifier"===t.left.type&&t.right===e||"AssignmentPattern"===t.type&&"Identifier"===t.left.type&&t.right===e}(o)||r(o):i||n(o)||r(o)}return{"FunctionExpression:exit":o,"ExportDefaultDeclaration > FunctionDeclaration":o}}},Eo={meta:{type:"suggestion",docs:{description:"enforce the consistent use of either `function` declarations or expressions",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/func-style"},schema:[{enum:["declaration","expression"]},{type:"object",properties:{allowArrowFunctions:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{expression:"Expected a function expression.",declaration:"Expected a function declaration."}},create(e){const t=e.options[0],n=e.options[1]&&e.options[1].allowArrowFunctions,r="declaration"===t,o=[],s={FunctionDeclaration(t){o.push(!1),r||"ExportDefaultDeclaration"===t.parent.type||e.report({node:t,messageId:"expression"})},"FunctionDeclaration:exit"(){o.pop()},FunctionExpression(t){o.push(!1),r&&"VariableDeclarator"===t.parent.type&&e.report({node:t.parent,messageId:"declaration"})},"FunctionExpression:exit"(){o.pop()},ThisExpression(){o.length>0&&(o[o.length-1]=!0)}};return n||(s.ArrowFunctionExpression=function(){o.push(!1)},s["ArrowFunctionExpression:exit"]=function(t){const n=o.pop();r&&!n&&"VariableDeclarator"===t.parent.type&&e.report({node:t.parent,messageId:"declaration"})}),s}},So={meta:{type:"layout",docs:{description:"enforce line breaks between arguments of a function call",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/function-call-argument-newline"},fixable:"whitespace",schema:[{enum:["always","never","consistent"]}],messages:{unexpectedLineBreak:"There should be no line break here.",missingLineBreak:"There should be a line break after this argument."}},create(e){const t=e.getSourceCode(),n={messageId:"unexpectedLineBreak",check:(e,t)=>e.loc.end.line!==t.loc.start.line,createFix:(e,t)=>n=>n.replaceTextRange([t.range[1],e.range[0]]," ")},r={messageId:"missingLineBreak",check:(e,t)=>e.loc.end.line===t.loc.start.line,createFix:(e,t)=>n=>n.replaceTextRange([t.range[1],e.range[0]],"\n")};function o(n,r){for(let o=1;on!==e.length-1&&t.loc.end.line!==e[n+1].loc.start.line)):s?t:e.length>=a}return a="object"==typeof n?n.minItems:"always"===n?0:"never"===n?1/0:null,{[["ArrowFunctionExpression","CallExpression","FunctionDeclaration","FunctionExpression","ImportExpression","NewExpression"]](n){const r=function(e){switch(e.type){case"NewExpression":if(!(e.arguments.length||fr.isOpeningParenToken(t.getLastToken(e,{skip:1}))&&fr.isClosingParenToken(t.getLastToken(e))))return null;case"CallExpression":return{leftParen:t.getTokenAfter(e.callee,fr.isOpeningParenToken),rightParen:t.getLastToken(e)};case"FunctionDeclaration":case"FunctionExpression":{const n=t.getFirstToken(e,fr.isOpeningParenToken);return{leftParen:n,rightParen:e.params.length?t.getTokenAfter(e.params[e.params.length-1],fr.isClosingParenToken):t.getTokenAfter(n)}}case"ArrowFunctionExpression":{const n=t.getFirstToken(e,{skip:e.async?1:0});return fr.isOpeningParenToken(n)?{leftParen:n,rightParen:t.getTokenBefore(e.body,fr.isClosingParenToken)}:null}case"ImportExpression":return{leftParen:t.getFirstToken(e,1),rightParen:t.getLastToken(e)};default:throw new TypeError(`unexpected node with type ${e.type}`)}}(n);let s;s="ImportExpression"===n.type?[n.source]:fr.isFunction(n)?n.params:n.arguments,r&&(function(n,r){const o=n.leftParen,s=n.rightParen,a=t.getTokenAfter(o),c=t.getTokenBefore(s),l=!fr.isTokenOnSameLine(o,a),u=!fr.isTokenOnSameLine(c,s),p=i(r,l);l&&!p?e.report({node:o,messageId:"unexpectedAfter",fix:e=>t.getText().slice(o.range[1],a.range[0]).trim()?null:e.removeRange([o.range[1],a.range[0]])}):!l&&p&&e.report({node:o,messageId:"expectedAfter",fix:e=>e.insertTextAfter(o,"\n")}),u&&!p?e.report({node:s,messageId:"unexpectedBefore",fix:e=>t.getText().slice(c.range[1],s.range[0]).trim()?null:e.removeRange([c.range[1],s.range[0]])}):!u&&p&&e.report({node:s,messageId:"expectedBefore",fix:e=>e.insertTextBefore(s,"\n")})}(r,s),o&&function(n,r){const o=n.leftParen,s=t.getTokenAfter(o),a=i(r,!fr.isTokenOnSameLine(o,s));for(let t=0;t<=r.length-2;t++){const n=r[t],o=r[t+1];n.loc.end.line===o.loc.start.line&&a&&e.report({node:n,messageId:"expectedBetween",fix:e=>e.insertTextBefore(o,"\n")})}}(r,s))}}}};const vo={oneOf:[{enum:["before","after","both","neither"]},{type:"object",properties:{before:{type:"boolean"},after:{type:"boolean"}},additionalProperties:!1}]};var Ao={meta:{type:"layout",docs:{description:"enforce consistent spacing around `*` operators in generator functions",category:"ECMAScript 6",recommended:!1,url:"https://eslint.org/docs/rules/generator-star-spacing"},fixable:"whitespace",schema:[{oneOf:[{enum:["before","after","both","neither"]},{type:"object",properties:{before:{type:"boolean"},after:{type:"boolean"},named:vo,anonymous:vo,method:vo},additionalProperties:!1}]}],messages:{missingBefore:"Missing space before *.",missingAfter:"Missing space after *.",unexpectedBefore:"Unexpected space before *.",unexpectedAfter:"Unexpected space after *."}},create(e){const t={before:{before:!0,after:!1},after:{before:!1,after:!0},both:{before:!0,after:!0},neither:{before:!1,after:!1}};function n(e,n){return e?"string"==typeof e?t[e]:Object.assign({},n,e):n}const r=function(e){const r=n(e,t.before);return{named:n(e.named,r),anonymous:n(e.anonymous,r),method:n(e.method,r)}}(e.options[0]||{}),o=e.getSourceCode();function s(e){return"*"===e.value&&"Punctuator"===e.type}function a(t,n,o,s){if(!!(s.range[0]-o.range[1])!==r[t][n]){const i="*"===o.value,c=r[t][n],l=i?o:s,u=`${c?"missing":"unexpected"}${a=n,a[0].toUpperCase()+a.slice(1)}`;e.report({node:l,messageId:u,fix:e=>c?i?e.insertTextAfter(l," "):e.insertTextBefore(l," "):e.removeRange([o.range[1],s.range[0]])})}var a}function i(e){if(!e.generator)return;const t=function(e){return o.getFirstToken(e.parent.method||"MethodDefinition"===e.parent.type?e.parent:e,s)}(e),n=o.getTokenBefore(t),r=o.getTokenAfter(t);let i="named";"MethodDefinition"===e.parent.type||"Property"===e.parent.type&&e.parent.method?i="method":e.id||(i="anonymous"),"method"===i&&t===o.getFirstToken(e.parent)||a(i,"before",n,t),a(i,"after",t,r)}return{FunctionDeclaration:i,FunctionExpression:i}}};const ko=/^(?:Arrow)?FunctionExpression$/u;function wo(e){return e.reachable}var Po={meta:{type:"problem",docs:{description:"enforce `return` statements in getters",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/getter-return"},fixable:null,schema:[{type:"object",properties:{allowImplicit:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{expected:"Expected to return a value in {{name}}.",expectedAlways:"Expected {{name}} to always return a value."}},create(e){const t=e.options[0]||{allowImplicit:!1},n=e.getSourceCode();let r={upper:null,codePath:null,hasReturn:!1,shouldCheck:!1,node:null};function o(t){r.shouldCheck&&r.codePath.currentSegments.some(wo)&&e.report({node:t,loc:fr.getFunctionHeadLoc(t,n),messageId:r.hasReturn?"expectedAlways":"expected",data:{name:fr.getFunctionNameWithKind(r.node)}})}function s(e){const t=e.parent;if(ko.test(e.type)&&"BlockStatement"===e.body.type){if("get"===t.kind)return!0;if("Property"===t.type&&"get"===fr.getStaticPropertyName(t)&&"ObjectExpression"===t.parent.type){if("CallExpression"===t.parent.parent.type&&"defineProperty"===fr.getStaticPropertyName(t.parent.parent.callee))return!0;if("Property"===t.parent.parent.type&&"ObjectExpression"===t.parent.parent.parent.type&&"CallExpression"===t.parent.parent.parent.parent.type&&"defineProperties"===fr.getStaticPropertyName(t.parent.parent.parent.parent.callee))return!0}}return!1}return{onCodePathStart(e,t){r={upper:r,codePath:e,hasReturn:!1,shouldCheck:s(t),node:t}},onCodePathEnd(){r=r.upper},ReturnStatement(n){r.shouldCheck&&(r.hasReturn=!0,t.allowImplicit||n.argument||e.report({node:n,messageId:"expected",data:{name:fr.getFunctionNameWithKind(r.node)}}))},"FunctionExpression:exit":o,"ArrowFunctionExpression:exit":o}}};const To=["AssignmentExpression","VariableDeclarator","MemberExpression","ExpressionStatement","CallExpression","ConditionalExpression","Program","VariableDeclaration","ChainExpression"];var Io={meta:{deprecated:!0,replacedBy:[],type:"suggestion",docs:{description:"require `require()` calls to be placed at top-level module scope",category:"Node.js and CommonJS",recommended:!1,url:"https://eslint.org/docs/rules/global-require"},schema:[],messages:{unexpected:"Unexpected require()."}},create:e=>({CallExpression(t){const n=e.getScope();if("require"===t.callee.name&&!function(e,t){const n=function(e,t){const n=e.references.filter((e=>e.identifier.range[0]===t.range[0]&&e.identifier.range[1]===t.range[1]));return 1===n.length?n[0]:null}(e,t);return n&&n.resolved&&n.resolved.defs.length>0}(n,t.callee)){e.getAncestors().every((e=>To.indexOf(e.type)>-1))||e.report({node:t,messageId:"unexpected"})}}})};function Fo(e){return"get"===e.kind||"set"===e.kind}var Do={meta:{type:"suggestion",docs:{description:"require grouped accessor pairs in object literals and classes",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/grouped-accessor-pairs"},schema:[{enum:["anyOrder","getBeforeSet","setBeforeGet"]}],messages:{notGrouped:"Accessor pair {{ formerName }} and {{ latterName }} should be grouped.",invalidOrder:"Expected {{ latterName }} to be before {{ formerName }}."}},create(e){const t=e.options[0]||"anyOrder",n=e.getSourceCode();function r(t,r,o){e.report({node:o,messageId:t,loc:fr.getFunctionHeadLoc(o.value,n),data:{formerName:fr.getFunctionNameWithKind(r.value),latterName:fr.getFunctionNameWithKind(o.value)}})}function o(e){const t=fr.getStaticPropertyName(e);return{key:null!==t?t:n.getTokens(e.key),getters:"get"===e.kind?[e]:[],setters:"set"===e.kind?[e]:[]}}function s(e,t){const n=e.find((e=>{return n=e.key,r=t.key,"string"==typeof n&&"string"==typeof r?n===r:!(!Array.isArray(n)||!Array.isArray(r))&&function(e,t){if(e.length!==t.length)return!1;for(let n=0;n1?r("notGrouped",l,u):("getBeforeSet"===t&&i>c||"setBeforeGet"===t&&i"Property"===e.type))},ClassBody(e){a(e.body,(e=>"MethodDefinition"===e.type&&!e.static)),a(e.body,(e=>"MethodDefinition"===e.type&&e.static))}}}},Oo={meta:{type:"suggestion",docs:{description:"require `for-in` loops to include an `if` statement",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/guard-for-in"},schema:[],messages:{wrap:"The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype."}},create:e=>({ForInStatement(t){const n=t.body;if("EmptyStatement"!==n.type&&"IfStatement"!==n.type&&!("BlockStatement"===n.type&&0===n.body.length||"BlockStatement"===n.type&&1===n.body.length&&"IfStatement"===n.body[0].type)){if("BlockStatement"===n.type&&n.body.length>=1&&"IfStatement"===n.body[0].type){const e=n.body[0];if("ContinueStatement"===e.consequent.type)return;if("BlockStatement"===e.consequent.type&&1===e.consequent.body.length&&"ContinueStatement"===e.consequent.body[0].type)return}e.report({node:t,messageId:"wrap"})}}})},Bo={meta:{deprecated:!0,replacedBy:[],type:"suggestion",docs:{description:"require error handling in callbacks",category:"Node.js and CommonJS",recommended:!1,url:"https://eslint.org/docs/rules/handle-callback-err"},schema:[{type:"string"}],messages:{expected:"Expected error to be handled."}},create(e){const t=e.options[0]||"err";function n(n){const r=function(e){return e.variables.filter((e=>e.defs[0]&&"Parameter"===e.defs[0].type))}(e.getScope())[0];r&&function(e){if("^"===t[0])return new RegExp(t,"u").test(e);return e===t}(r.name)&&0===r.references.length&&e.report({node:n,messageId:"expected"})}return{FunctionDeclaration:n,FunctionExpression:n,ArrowFunctionExpression:n}}};var No={meta:{deprecated:!0,replacedBy:["id-denylist"],type:"suggestion",docs:{description:"disallow specified identifiers",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/id-blacklist"},schema:{type:"array",items:{type:"string"},uniqueItems:!0},messages:{restricted:"Identifier '{{name}}' is restricted."}},create(e){const t=new Set(e.options),n=new Set;let r;function o(e){const t=e.parent;return"MemberExpression"!==t.type||t.property!==e||t.computed?!("CallExpression"===t.type||"NewExpression"===t.type||function(e){const t=e.parent;return"ImportSpecifier"===t.type&&t.imported!==t.local&&t.imported===e||"ExportSpecifier"===t.type&&t.parent.source&&t.local!==t.exported&&t.local===e}(e)||function(e){const t=e.parent;return!t.computed&&"Property"===t.type&&"ObjectPattern"===t.parent.type&&t.value!==e&&t.key===e}(e)||function(e){const t=r.set.get(e.name);return t&&0===t.defs.length&&t.references.some((t=>t.identifier===e))}(e)&&!function(e){const t=e.parent;return"Property"===t.type&&"ObjectExpression"===t.parent.type&&t.shorthand}(e)):function(e){const t=e.parent;return"AssignmentExpression"===t.type&&t.left===e||"ArrayPattern"===t.type||"RestElement"===t.type||"Property"===t.type&&t.value===e&&"ObjectPattern"===t.parent.type||"AssignmentPattern"===t.type&&t.left===e}(t)}return{Program(){r=e.getScope()},Identifier(r){(function(e){return t.has(e)})(r.name)&&o(r)&&function(t){n.has(t)||(e.report({node:t,messageId:"restricted",data:{name:t.name}}),n.add(t))}(r)}}}};var jo={meta:{type:"suggestion",docs:{description:"disallow specified identifiers",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/id-denylist"},schema:{type:"array",items:{type:"string"},uniqueItems:!0},messages:{restricted:"Identifier '{{name}}' is restricted."}},create(e){const t=new Set(e.options),n=new Set;let r;function o(e){const t=e.parent;return"MemberExpression"!==t.type||t.property!==e||t.computed?!("CallExpression"===t.type||"NewExpression"===t.type||function(e){const t=e.parent;return"ImportSpecifier"===t.type&&t.imported!==t.local&&t.imported===e||"ExportSpecifier"===t.type&&t.parent.source&&t.local!==t.exported&&t.local===e}(e)||function(e){const t=e.parent;return!t.computed&&"Property"===t.type&&"ObjectPattern"===t.parent.type&&t.value!==e&&t.key===e}(e)||function(e){const t=r.set.get(e.name);return t&&0===t.defs.length&&t.references.some((t=>t.identifier===e))}(e)&&!function(e){const t=e.parent;return"Property"===t.type&&"ObjectExpression"===t.parent.type&&t.shorthand}(e)):function(e){const t=e.parent;return"AssignmentExpression"===t.type&&t.left===e||"ArrayPattern"===t.type||"RestElement"===t.type||"Property"===t.type&&t.value===e&&"ObjectPattern"===t.parent.type||"AssignmentPattern"===t.type&&t.left===e}(t)}return{Program(){r=e.getScope()},Identifier(r){(function(e){return t.has(e)})(r.name)&&o(r)&&function(t){n.has(t)||(e.report({node:t,messageId:"restricted",data:{name:t.name}}),n.add(t))}(r)}}}},Lo={meta:{type:"suggestion",docs:{description:"enforce minimum and maximum identifier lengths",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/id-length"},schema:[{type:"object",properties:{min:{type:"integer",default:2},max:{type:"integer"},exceptions:{type:"array",uniqueItems:!0,items:{type:"string"}},exceptionPatterns:{type:"array",uniqueItems:!0,items:{type:"string"}},properties:{enum:["always","never"]}},additionalProperties:!1}],messages:{tooShort:"Identifier name '{{name}}' is too short (< {{min}}).",tooLong:"Identifier name '{{name}}' is too long (> {{max}})."}},create(e){const t=e.options[0]||{},n=void 0!==t.min?t.min:2,r=void 0!==t.max?t.max:1/0,o="never"!==t.properties,s=new Set(t.exceptions),a=(t.exceptionPatterns||[]).map((e=>new RegExp(e,"u"))),i=new Set;const c={MemberExpression:o&&function(e){return!e.computed&&(e.parent.left===e&&"AssignmentExpression"===e.parent.type||"Property"===e.parent.type&&e.parent.value===e&&"ObjectPattern"===e.parent.parent.type&&e.parent.parent.parent.left===e.parent.parent)},AssignmentPattern:(e,t)=>e.left===t,VariableDeclarator:(e,t)=>e.id===t,Property:(e,t)=>"ObjectPattern"===e.parent.type?e.value!==e.key&&e.value===t||e.value===e.key&&e.key===t&&o:o&&!e.computed&&e.key===t,ImportDefaultSpecifier:!0,RestElement:!0,FunctionExpression:!0,ArrowFunctionExpression:!0,ClassDeclaration:!0,FunctionDeclaration:!0,MethodDefinition:!0,CatchClause:!0,ArrayPattern:!0};return{Identifier(t){const o=t.name,l=t.parent,u=o.lengthr;if(!u&&!p||s.has(o)||function(e){return a.some((t=>t.test(e)))}(o))return;const d=c[l.type];!d||i.has(t)||!0!==d&&!d(l,t)||(i.add(t),e.report({node:t,messageId:u?"tooShort":"tooLong",data:{name:o,min:n,max:r}}))}}}},Ro={meta:{type:"suggestion",docs:{description:"require identifiers to match a specified regular expression",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/id-match"},schema:[{type:"string"},{type:"object",properties:{properties:{type:"boolean",default:!1},onlyDeclarations:{type:"boolean",default:!1},ignoreDestructuring:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{notMatch:"Identifier '{{name}}' does not match the pattern '{{pattern}}'."}},create(e){const t=e.options[0]||"^.+$",n=new RegExp(t,"u"),r=e.options[1]||{},o=!!r.properties,s=!!r.onlyDeclarations,a=!!r.ignoreDestructuring,i=new Map,c=new Set(["CallExpression","NewExpression"]),l=new Set(["FunctionDeclaration","VariableDeclarator"]),u=new Set(["ImportSpecifier","ImportNamespaceSpecifier","ImportDefaultSpecifier"]);function p(e){return!n.test(e)}function d(e,t){return(!s||l.has(e.type))&&!c.has(e.type)&&p(t)}function f(n){i.has(n)||(e.report({node:n,messageId:"notMatch",data:{name:n.name,pattern:t}}),i.set(n,!0))}return{Identifier(e){const t=e.name,n=e.parent,r="MemberExpression"===n.type?n.parent:n;if("MemberExpression"===n.type){if(!o)return;"Identifier"===n.object.type&&n.object.name===t||"AssignmentExpression"===r.type&&"MemberExpression"===r.left.type&&r.left.property.name===e.name?p(t)&&f(e):"AssignmentExpression"===r.type&&"MemberExpression"!==r.right.type&&p(t)&&f(e)}else if("Property"===n.type||"AssignmentPattern"===n.type){if(n.parent&&"ObjectPattern"===n.parent.type){n.shorthand&&n.value.left&&p(t)&&f(e);const r=n.key.name===n.value.name;if(!r&&n.key===e)return;!(n.value.name&&p(t))||r&&a||f(e)}if(!o||a&&function(e){let{parent:t}=e;for(;t;){if("ObjectPattern"===t.type)return!0;t=t.parent}return!1}(e))return;n.right!==e&&d(r,t)&&f(e)}else u.has(n.type)?n.local&&n.local.name===e.name&&p(t)&&f(e):d(r,t)&&f(e)}}}};const{isCommentToken:Mo,isNotOpeningParenToken:_o}=fr;var $o={meta:{type:"layout",docs:{description:"enforce the location of arrow function bodies",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/implicit-arrow-linebreak"},fixable:"whitespace",schema:[{enum:["beside","below"]}],messages:{expected:"Expected a linebreak before this expression.",unexpected:"Expected no linebreak before this expression."}},create(e){const t=e.getSourceCode(),n=e.options[0]||"beside";return{ArrowFunctionExpression:r=>function(r){if("BlockStatement"===r.body.type)return;const o=t.getTokenBefore(r.body,_o),s=t.getTokenAfter(o);o.loc.end.line===s.loc.start.line&&"below"===n?e.report({node:s,messageId:"expected",fix:e=>e.insertTextBefore(s,"\n")}):o.loc.end.line!==s.loc.start.line&&"beside"===n&&e.report({node:s,messageId:"unexpected",fix:e=>t.getFirstTokenBetween(o,s,{includeComments:!0,filter:Mo})?null:e.replaceTextRange([o.range[1],s.range[0]]," ")})}(r)}}};const qo=new Set(["AssignmentExpression","AssignmentPattern","ArrayExpression","ArrayPattern","ArrowFunctionExpression","AwaitExpression","BlockStatement","BinaryExpression","BreakStatement","CallExpression","CatchClause","ChainExpression","ClassBody","ClassDeclaration","ClassExpression","ConditionalExpression","ContinueStatement","DoWhileStatement","DebuggerStatement","EmptyStatement","ExperimentalRestProperty","ExperimentalSpreadProperty","ExpressionStatement","ForStatement","ForInStatement","ForOfStatement","FunctionDeclaration","FunctionExpression","Identifier","IfStatement","Literal","LabeledStatement","LogicalExpression","MemberExpression","MetaProperty","MethodDefinition","NewExpression","ObjectExpression","ObjectPattern","Program","Property","RestElement","ReturnStatement","SequenceExpression","SpreadElement","Super","SwitchCase","SwitchStatement","TaggedTemplateExpression","TemplateElement","TemplateLiteral","ThisExpression","ThrowStatement","TryStatement","UnaryExpression","UpdateExpression","VariableDeclaration","VariableDeclarator","WhileStatement","WithStatement","YieldExpression","JSXFragment","JSXOpeningFragment","JSXClosingFragment","JSXIdentifier","JSXNamespacedName","JSXMemberExpression","JSXEmptyExpression","JSXExpressionContainer","JSXElement","JSXClosingElement","JSXOpeningElement","JSXAttribute","JSXSpreadAttribute","JSXText","ExportDefaultDeclaration","ExportNamedDeclaration","ExportAllDeclaration","ExportSpecifier","ImportDeclaration","ImportSpecifier","ImportDefaultSpecifier","ImportNamespaceSpecifier","ImportExpression"]);class Uo{constructor(){this._rbTree=H.default()}insert(e,t){const n=this._rbTree.find(e);n.valid?this._rbTree=n.update(t):this._rbTree=this._rbTree.insert(e,t)}findLe(e){const t=this._rbTree.le(e);return t&&{key:t.key,value:t.value}}deleteRange(e,t){if(e===t)return;const n=this._rbTree.ge(e);for(;n.valid&&n.key(t.has(n.loc.start.line)||t.set(n.loc.start.line,n),!t.has(n.loc.end.line)&&e.text.slice(n.range[1]-n.loc.end.column,n.range[1]).trim()&&t.set(n.loc.end.line,n),t)),new Map)}getFirstTokenOfLine(e){return this.firstTokensByLineNumber.get(e.loc.start.line)}isFirstTokenOfLine(e){return this.getFirstTokenOfLine(e)===e}getTokenIndent(e){return this.sourceCode.text.slice(e.range[0]-e.loc.start.column,e.range[0])}}class Wo{constructor(e,t,n){this._tokenInfo=e,this._indentSize=t,this._indentType=n,this._tree=new Uo,this._tree.insert(0,{offset:0,from:null,force:!1}),this._lockedFirstTokens=new WeakMap,this._desiredIndentCache=new WeakMap,this._ignoredTokens=new WeakSet}_getOffsetDescriptor(e){return this._tree.findLe(e.range[0]).value}matchOffsetOf(e,t){this._lockedFirstTokens.set(t,e)}setDesiredOffset(e,t,n){return this.setDesiredOffsets(e.range,t,n)}setDesiredOffsets(e,t,n,r){const o={offset:n,from:t,force:r},s=this._tree.findLe(e[1]).value,a=t&&t.range[0]>=e[0]&&t.range[1]<=e[1],i=a&&this._getOffsetDescriptor(t);this._tree.deleteRange(e[0]+1,e[1]),this._tree.insert(e[0],o),a&&(this._tree.insert(t.range[0],i),this._tree.insert(t.range[1],o)),this._tree.insert(e[1],s)}getDesiredIndent(e){if(!this._desiredIndentCache.has(e))if(this._ignoredTokens.has(e))this._desiredIndentCache.set(e,this._tokenInfo.getTokenIndent(e));else if(this._lockedFirstTokens.has(e)){const t=this._lockedFirstTokens.get(e);this._desiredIndentCache.set(e,this.getDesiredIndent(this._tokenInfo.getFirstTokenOfLine(t))+this._indentType.repeat(t.loc.start.column-this._tokenInfo.getFirstTokenOfLine(t).loc.start.column))}else{const t=this._getOffsetDescriptor(e),n=!t.from||t.from.loc.start.line!==e.loc.start.line||/^\s*?\n/u.test(e.value)||t.force?t.offset*this._indentSize:0;this._desiredIndentCache.set(e,(t.from?this.getDesiredIndent(t.from):"")+this._indentType.repeat(n))}return this._desiredIndentCache.get(e)}ignoreToken(e){this._tokenInfo.isFirstTokenOfLine(e)&&this._ignoredTokens.add(e)}getFirstDependency(e){return this._getOffsetDescriptor(e).from}}const Go={oneOf:[{type:"integer",minimum:0},{enum:["first","off"]}]};var zo={meta:{type:"layout",docs:{description:"enforce consistent indentation",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/indent"},fixable:"whitespace",schema:[{oneOf:[{enum:["tab"]},{type:"integer",minimum:0}]},{type:"object",properties:{SwitchCase:{type:"integer",minimum:0,default:0},VariableDeclarator:{oneOf:[Go,{type:"object",properties:{var:Go,let:Go,const:Go},additionalProperties:!1}]},outerIIFEBody:{oneOf:[{type:"integer",minimum:0},{enum:["off"]}]},MemberExpression:{oneOf:[{type:"integer",minimum:0},{enum:["off"]}]},FunctionDeclaration:{type:"object",properties:{parameters:Go,body:{type:"integer",minimum:0}},additionalProperties:!1},FunctionExpression:{type:"object",properties:{parameters:Go,body:{type:"integer",minimum:0}},additionalProperties:!1},CallExpression:{type:"object",properties:{arguments:Go},additionalProperties:!1},ArrayExpression:Go,ObjectExpression:Go,ImportDeclaration:Go,flatTernaryExpressions:{type:"boolean",default:!1},offsetTernaryExpressions:{type:"boolean",default:!1},ignoredNodes:{type:"array",items:{type:"string",not:{pattern:":exit$"}}},ignoreComments:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{wrongIndentation:"Expected indentation of {{expected}} but found {{actual}}."}},create(e){let t="space",n=4;const r={SwitchCase:0,VariableDeclarator:{var:1,let:1,const:1},outerIIFEBody:1,FunctionDeclaration:{parameters:1,body:1},FunctionExpression:{parameters:1,body:1},CallExpression:{arguments:1},MemberExpression:1,ArrayExpression:1,ObjectExpression:1,ImportDeclaration:1,flatTernaryExpressions:!1,ignoredNodes:[],ignoreComments:!1};e.options.length&&("tab"===e.options[0]?(n=1,t="tab"):(n=e.options[0],t="space"),e.options[1]&&(Object.assign(r,e.options[1]),"number"!=typeof r.VariableDeclarator&&"first"!==r.VariableDeclarator||(r.VariableDeclarator={var:r.VariableDeclarator,let:r.VariableDeclarator,const:r.VariableDeclarator})));const o=e.getSourceCode(),s=new Vo(o),a=new Wo(s,n,"space"===t?" ":"\t"),i=new WeakSet;function c(e,n,r){let o;return o=n>0?"space"===t?n:`${n} ${"space"+(1===n?"":"s")}`:r>0?"tab"===t?r:`${r} ${"tab"+(1===r?"":"s")}`:"0",{expected:`${e} ${t}${1===e?"":"s"}`,actual:o}}function l(e,t){const n=s.getTokenIndent(e);return n===t||n.includes(" ")&&n.includes("\t")}function u(e,t,n,r){function i(e){let n=o.getTokenBefore(e);for(;fr.isOpeningParenToken(n)&&n!==t;)n=o.getTokenBefore(n);return o.getTokenAfter(n)}a.setDesiredOffsets([t.range[1],n.range[0]],t,"number"==typeof r?r:1),a.setDesiredOffset(n,t,0),"first"===r&&e.length&&!e[0]||e.forEach(((n,c)=>{if(n&&("off"===r&&a.ignoreToken(i(n)),0!==c))if("first"===r&&s.isFirstTokenOfLine(i(n)))a.matchOffsetOf(i(e[0]),i(n));else{const r=e[c-1],s=r&&i(r),l=r&&o.getLastToken(r);r&&l.loc.end.line-function(e){const t=e.match(/\s*$/u)[0].match(fr.createGlobalLinebreakMatcher());return null===t?0:t.length}(l.value)>t.loc.end.line&&a.setDesiredOffsets([r.range[1],n.range[1]],s,0)}}))}function p(e){if("BlockStatement"!==e.type){const t=o.getTokenBefore(e,fr.isNotOpeningParenToken);let n=o.getFirstToken(e),r=o.getLastToken(e);for(;fr.isOpeningParenToken(o.getTokenBefore(n))&&fr.isClosingParenToken(o.getTokenAfter(r));)n=o.getTokenBefore(n),r=o.getTokenAfter(r);a.setDesiredOffsets([n.range[0],r.range[1]],t,1);const s=o.getLastToken(e);"EmptyStatement"!==e.type&&fr.isSemicolonToken(s)&&a.setDesiredOffset(s,t,0)}}function d(e){let t;t=e.arguments.length?o.getFirstTokenBetween(e.callee,e.arguments[0],fr.isOpeningParenToken):o.getLastToken(e,1);const n=o.getLastToken(e);if(i.add(t),i.add(n),e.optional){const n=o.getTokenAfter(e.callee,fr.isQuestionDotToken),r=o.getTokensBetween(e.callee,n,{filter:fr.isClosingParenToken}).length,s=r?o.getTokenBefore(e.callee,{skip:r-1}):o.getFirstToken(e.callee),i=o.getTokenBefore(n),c=i.loc.end.line===t.loc.start.line?i:s;a.setDesiredOffset(n,c,1)}const s="TaggedTemplateExpression"===e.callee.type?o.getFirstToken(e.callee.quasi):t,c=o.getTokenBefore(s);a.setDesiredOffset(t,c,0),u(e.arguments,t,n,r.CallExpression.arguments)}function f(e){const t=new Set(o.getTokens(e,{includeComments:!0}));t.forEach((e=>{if(!t.has(a.getFirstDependency(e))){const t=s.getFirstTokenOfLine(e);e===t?a.ignoreToken(e):a.setDesiredOffset(e,t,0)}}))}function m(e,t){const n=e.loc.end.line,r=t.loc.start.line;if(n===r||n===r-1)return!1;for(let e=n+1;et.value===e.operator));a.setDesiredOffsets([t.range[0],e.range[1]],o.getLastToken(e.left),1),a.ignoreToken(t),a.ignoreToken(o.getTokenAfter(t))},"BinaryExpression, LogicalExpression"(e){const t=o.getFirstTokenBetween(e.left,e.right,(t=>t.value===e.operator)),n=o.getTokenAfter(t);a.ignoreToken(t),a.ignoreToken(n),a.setDesiredOffset(n,t,0)},"BlockStatement, ClassBody"(e){let t;t=e.parent&&function(e){if(!e.parent||"CallExpression"!==e.parent.type||e.parent.callee!==e)return!1;let t=e.parent&&e.parent.parent;for(;"UnaryExpression"===t.type&&["!","~","+","-"].indexOf(t.operator)>-1||"AssignmentExpression"===t.type||"LogicalExpression"===t.type||"SequenceExpression"===t.type||"VariableDeclarator"===t.type;)t=t.parent;return("ExpressionStatement"===t.type||"VariableDeclaration"===t.type)&&"Program"===t.parent.type}(e.parent)?r.outerIIFEBody:!e.parent||"FunctionExpression"!==e.parent.type&&"ArrowFunctionExpression"!==e.parent.type?e.parent&&"FunctionDeclaration"===e.parent.type?r.FunctionDeclaration.body:1:r.FunctionExpression.body,fr.STATEMENT_LIST_PARENTS.has(e.parent.type)||a.setDesiredOffset(o.getFirstToken(e),o.getFirstToken(e.parent),0),u(e.body,o.getFirstToken(e),o.getLastToken(e),t)},CallExpression:d,"ClassDeclaration[superClass], ClassExpression[superClass]"(e){const t=o.getFirstToken(e),n=o.getTokenBefore(e.superClass,fr.isNotOpeningParenToken);a.setDesiredOffsets([n.range[0],e.body.range[0]],t,1)},ConditionalExpression(e){const t=o.getFirstToken(e);if(!r.flatTernaryExpressions||!fr.isTokenOnSameLine(e.test,e.consequent)||function(e,t){let n=t;for(;n.parent&&!n.parent.type.endsWith("Statement")&&!n.parent.type.endsWith("Declaration");)n=n.parent;return n=n.parent,!n||n.loc.start.line===e.loc.start.line}(t,e)){const n=o.getFirstTokenBetween(e.test,e.consequent,(e=>"Punctuator"===e.type&&"?"===e.value)),s=o.getFirstTokenBetween(e.consequent,e.alternate,(e=>"Punctuator"===e.type&&":"===e.value)),i=o.getTokenAfter(n),c=o.getTokenBefore(s),l=o.getTokenAfter(s);a.setDesiredOffset(n,t,1),a.setDesiredOffset(s,t,1),a.setDesiredOffset(i,t,"Punctuator"===i.type&&r.offsetTernaryExpressions?2:1),c.loc.end.line===l.loc.start.line?a.setDesiredOffset(l,i,0):a.setDesiredOffset(l,t,"Punctuator"===l.type&&r.offsetTernaryExpressions?2:1)}},"DoWhileStatement, WhileStatement, ForInStatement, ForOfStatement":e=>p(e.body),ExportNamedDeclaration(e){if(null===e.declaration){const t=o.getLastToken(e,fr.isClosingBraceToken);u(e.specifiers,o.getFirstToken(e,{skip:1}),t,1),e.source&&a.setDesiredOffsets([t.range[1],e.range[1]],o.getFirstToken(e),1)}},ForStatement(e){const t=o.getFirstToken(e,1);e.init&&a.setDesiredOffsets(e.init.range,t,1),e.test&&a.setDesiredOffsets(e.test.range,t,1),e.update&&a.setDesiredOffsets(e.update.range,t,1),p(e.body)},"FunctionDeclaration, FunctionExpression"(e){const t=o.getTokenBefore(e.body),n=o.getTokenBefore(e.params.length?e.params[0]:t);i.add(n),i.add(t),u(e.params,n,t,r[e.type].parameters)},IfStatement(e){p(e.consequent),e.alternate&&"IfStatement"!==e.alternate.type&&p(e.alternate)},ImportDeclaration(e){if(e.specifiers.some((e=>"ImportSpecifier"===e.type))){const t=o.getFirstToken(e,fr.isOpeningBraceToken),n=o.getLastToken(e,fr.isClosingBraceToken);u(e.specifiers.filter((e=>"ImportSpecifier"===e.type)),t,n,r.ImportDeclaration)}const t=o.getLastToken(e,(e=>"Identifier"===e.type&&"from"===e.value)),n=o.getLastToken(e,(e=>"String"===e.type)),s=o.getLastToken(e,(e=>"Punctuator"===e.type&&";"===e.value));if(t){const r=s&&s.range[1]===n.range[1]?e.range[1]:n.range[1];a.setDesiredOffsets([t.range[0],r],o.getFirstToken(e),1)}},ImportExpression(e){const t=o.getFirstToken(e,1),n=o.getLastToken(e);i.add(t),i.add(n),a.setDesiredOffset(t,o.getTokenBefore(t),0),u([e.source],t,n,r.CallExpression.arguments)},"MemberExpression, JSXMemberExpression, MetaProperty"(e){const t="MetaProperty"===e.type?e.meta:e.object,n=o.getFirstTokenBetween(t,e.property,fr.isNotClosingParenToken),s=o.getTokenAfter(n),i=o.getTokensBetween(t,e.property,{filter:fr.isClosingParenToken}).length,c=i?o.getTokenBefore(t,{skip:i-1}):o.getFirstToken(t),l=o.getTokenBefore(n),u=e.computed?n:s;e.computed&&(a.setDesiredOffset(o.getLastToken(e),n,0),a.setDesiredOffsets(e.property.range,n,1));const p=l.loc.end.line===u.loc.start.line?l:c;"number"==typeof r.MemberExpression?(a.setDesiredOffset(n,p,r.MemberExpression),a.setDesiredOffset(s,e.computed?n:p,r.MemberExpression)):(a.ignoreToken(n),a.ignoreToken(s),a.setDesiredOffset(n,p,0),a.setDesiredOffset(s,n,0))},NewExpression(e){(e.arguments.length>0||fr.isClosingParenToken(o.getLastToken(e))&&fr.isOpeningParenToken(o.getLastToken(e,1)))&&d(e)},Property(e){if(!e.shorthand&&!e.method&&"init"===e.kind){const t=o.getFirstTokenBetween(e.key,e.value,fr.isColonToken);a.ignoreToken(o.getTokenAfter(t))}},SwitchStatement(e){const t=o.getTokenAfter(e.discriminant,fr.isOpeningBraceToken),n=o.getLastToken(e);a.setDesiredOffsets([t.range[1],n.range[0]],t,r.SwitchCase),e.cases.length&&o.getTokensBetween(e.cases[e.cases.length-1],n,{includeComments:!0,filter:fr.isCommentToken}).forEach((e=>a.ignoreToken(e)))},SwitchCase(e){if(1!==e.consequent.length||"BlockStatement"!==e.consequent[0].type){const t=o.getFirstToken(e),n=o.getTokenAfter(e);a.setDesiredOffsets([t.range[1],n.range[0]],t,1)}},TemplateLiteral(e){e.expressions.forEach(((t,n)=>{const r=e.quasis[n],s=e.quasis[n+1],i=r.loc.start.line===r.loc.end.line?o.getFirstToken(r):null;a.setDesiredOffsets([r.range[1],s.range[0]],i,1),a.setDesiredOffset(o.getFirstToken(s),i,0)}))},VariableDeclaration(e){let t=Object.prototype.hasOwnProperty.call(r.VariableDeclarator,e.kind)?r.VariableDeclarator[e.kind]:1;const n=o.getFirstToken(e),s=o.getLastToken(e);if("first"===r.VariableDeclarator[e.kind]){if(e.declarations.length>1)return void u(e.declarations,n,s,"first");t=1}e.declarations[e.declarations.length-1].loc.start.line>e.loc.start.line?a.setDesiredOffsets(e.range,n,t,!0):a.setDesiredOffsets(e.range,n,t),fr.isSemicolonToken(s)&&a.ignoreToken(s)},VariableDeclarator(e){if(e.init){const t=o.getTokenBefore(e.init,fr.isNotOpeningParenToken),n=o.getTokenAfter(t);a.ignoreToken(t),a.ignoreToken(n),a.setDesiredOffsets([n.range[0],e.range[1]],t,1),a.setDesiredOffset(t,o.getLastToken(e.id),0)}},"JSXAttribute[value]"(e){const t=o.getFirstTokenBetween(e.name,e.value,(e=>"Punctuator"===e.type&&"="===e.value));a.setDesiredOffsets([t.range[0],e.value.range[1]],o.getFirstToken(e.name),1)},JSXElement(e){e.closingElement&&u(e.children,o.getFirstToken(e.openingElement),o.getFirstToken(e.closingElement),1)},JSXOpeningElement(e){const t=o.getFirstToken(e);let n;e.selfClosing?(n=o.getLastToken(e,{skip:1}),a.setDesiredOffset(o.getLastToken(e),n,0)):n=o.getLastToken(e),a.setDesiredOffsets(e.name.range,o.getFirstToken(e)),u(e.attributes,t,n,1)},JSXClosingElement(e){const t=o.getFirstToken(e);a.setDesiredOffsets(e.name.range,t,1)},JSXFragment(e){const t=o.getFirstToken(e.openingFragment),n=o.getFirstToken(e.closingFragment);u(e.children,t,n,1)},JSXOpeningFragment(e){const t=o.getFirstToken(e),n=o.getLastToken(e);a.setDesiredOffsets(e.range,t,1),a.matchOffsetOf(t,n)},JSXClosingFragment(e){const t=o.getFirstToken(e),n=o.getLastToken(e,{skip:1}),r=o.getLastToken(e),s=fr.isTokenOnSameLine(n,r)?n:r;a.setDesiredOffsets(e.range,t,1),a.matchOffsetOf(t,s)},JSXExpressionContainer(e){const t=o.getFirstToken(e),n=o.getLastToken(e);a.setDesiredOffsets([t.range[1],n.range[0]],t,1)},JSXSpreadAttribute(e){const t=o.getFirstToken(e),n=o.getLastToken(e);a.setDesiredOffsets([t.range[1],n.range[0]],t,1)},"*"(e){const t=o.getFirstToken(e);t&&!g.has(t)&&a.setDesiredOffsets(e.range,t,0)}},y=[],x=F.default.mapValues(h,(e=>t=>y.push({listener:e,node:t}))),b=new Set;function E(e){b.add(e),g.add(o.getFirstToken(e))}const S=r.ignoredNodes.reduce(((e,t)=>Object.assign(e,{[t]:E})),{});return Object.assign(x,S,{"*:exit"(e){qo.has(e.type)||E(e)},"Program:exit"(){r.ignoreComments&&o.getAllComments().forEach((e=>a.ignoreToken(e))),y.filter((e=>!b.has(e.node))).forEach((e=>e.listener(e.node))),b.forEach(f),function(e){const t=[],n=[];e.forEach((e=>{fr.isOpeningParenToken(e)?t.push(e):fr.isClosingParenToken(e)&&n.unshift({left:t.pop(),right:e})})),n.forEach((e=>{const t=e.left,n=e.right;if(!i.has(t)&&!i.has(n)){const e=new Set(o.getTokensBetween(t,n));e.forEach((n=>{e.has(a.getFirstDependency(n))||a.setDesiredOffset(n,t,1)}))}a.setDesiredOffset(n,t,0)}))}(o.ast.tokens);const t=o.ast.comments.reduce(((e,t)=>{const n=o.getTokenBefore(t,{includeComments:!0});return e.set(t,e.has(n)?e.get(n):n)}),new WeakMap);o.lines.forEach(((n,r)=>{const i=r+1;if(!s.firstTokensByLineNumber.has(i))return;const u=s.firstTokensByLineNumber.get(i);if(u.loc.start.line===i){if(fr.isCommentToken(u)){const e=t.get(u),n=e?o.getTokenAfter(e):o.ast.tokens[0],r=e&&!m(e,u),s=n&&!m(u,n);if(n&&fr.isSemicolonToken(n)&&!fr.isTokenOnSameLine(u,n)&&a.setDesiredOffset(u,n,0),r&&l(u,a.getDesiredIndent(e))||s&&l(u,a.getDesiredIndent(n)))return}l(u,a.getDesiredIndent(u))||function(t,n){const r=Array.from(s.getTokenIndent(t)),o=r.filter((e=>" "===e)).length,a=r.filter((e=>"\t"===e)).length;e.report({node:t,messageId:"wrongIndentation",data:c(n.length,o,a),loc:{start:{line:t.loc.start.line,column:0},end:{line:t.loc.start.line,column:t.loc.start.column}},fix(e){const r=[t.range[0]-t.loc.start.column,t.range[0]],o=n;return e.replaceTextRange(r,o)}})}(u,a.getDesiredIndent(u))}}))}})}},Jo={meta:{type:"layout",docs:{description:"enforce consistent indentation",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/indent-legacy"},deprecated:!0,replacedBy:["indent"],fixable:"whitespace",schema:[{oneOf:[{enum:["tab"]},{type:"integer",minimum:0}]},{type:"object",properties:{SwitchCase:{type:"integer",minimum:0},VariableDeclarator:{oneOf:[{type:"integer",minimum:0},{type:"object",properties:{var:{type:"integer",minimum:0},let:{type:"integer",minimum:0},const:{type:"integer",minimum:0}}}]},outerIIFEBody:{type:"integer",minimum:0},MemberExpression:{type:"integer",minimum:0},FunctionDeclaration:{type:"object",properties:{parameters:{oneOf:[{type:"integer",minimum:0},{enum:["first"]}]},body:{type:"integer",minimum:0}}},FunctionExpression:{type:"object",properties:{parameters:{oneOf:[{type:"integer",minimum:0},{enum:["first"]}]},body:{type:"integer",minimum:0}}},CallExpression:{type:"object",properties:{parameters:{oneOf:[{type:"integer",minimum:0},{enum:["first"]}]}}},ArrayExpression:{oneOf:[{type:"integer",minimum:0},{enum:["first"]}]},ObjectExpression:{oneOf:[{type:"integer",minimum:0},{enum:["first"]}]}},additionalProperties:!1}],messages:{expected:"Expected indentation of {{expected}} but found {{actual}}."}},create(e){const t=null;let n="space",r=4;const o={SwitchCase:0,VariableDeclarator:{var:1,let:1,const:1},outerIIFEBody:null,FunctionDeclaration:{parameters:t,body:1},FunctionExpression:{parameters:t,body:1},CallExpression:{arguments:t},ArrayExpression:1,ObjectExpression:1},s=e.getSourceCode();if(e.options.length&&("tab"===e.options[0]?(r=1,n="tab"):"number"==typeof e.options[0]&&(r=e.options[0],n="space"),e.options[1])){const t=e.options[1];o.SwitchCase=t.SwitchCase||0;const n=t.VariableDeclarator;"number"==typeof n?o.VariableDeclarator={var:n,let:n,const:n}:"object"==typeof n&&Object.assign(o.VariableDeclarator,n),"number"==typeof t.outerIIFEBody&&(o.outerIIFEBody=t.outerIIFEBody),"number"==typeof t.MemberExpression&&(o.MemberExpression=t.MemberExpression),"object"==typeof t.FunctionDeclaration&&Object.assign(o.FunctionDeclaration,t.FunctionDeclaration),"object"==typeof t.FunctionExpression&&Object.assign(o.FunctionExpression,t.FunctionExpression),"object"==typeof t.CallExpression&&Object.assign(o.CallExpression,t.CallExpression),"number"!=typeof t.ArrayExpression&&"string"!=typeof t.ArrayExpression||(o.ArrayExpression=t.ArrayExpression),"number"!=typeof t.ObjectExpression&&"string"!=typeof t.ObjectExpression||(o.ObjectExpression=t.ObjectExpression)}const a={};function i(e,t,r){const o="space"+(1===t?"":"s"),s="tab"+(1===r?"":"s");let a;return a=t>0&&r>0?`${t} ${o} and ${r} ${s}`:t>0?"space"===n?t:`${t} ${o}`:r>0?"tab"===n?r:`${r} ${s}`:"0",{expected:`${e} ${n}${1===e?"":"s"}`,actual:a}}function c(t,r,o,s,a,c){if(o&&s)return;const l=("space"===n?" ":"\t").repeat(r),u=c?[t.range[1]-t.loc.end.column,t.range[1]-t.loc.end.column+o+s]:[t.range[0]-t.loc.start.column,t.range[0]-t.loc.start.column+o+s];e.report({node:t,loc:a,messageId:"expected",data:i(r,o,s),fix:e=>e.replaceTextRange(u,l)})}function l(e,t){const r=t?s.getLastToken(e):s.getFirstToken(e),o=s.getText(r,r.loc.start.column).split(""),a=o.slice(0,o.findIndex((e=>" "!==e&&"\t"!==e))),i=a.filter((e=>" "===e)).length,c=a.filter((e=>"\t"===e)).length;return{space:i,tab:c,goodChar:"space"===n?i:c,badChar:"space"===n?c:i}}function u(e,t){const n=!0===t?s.getLastToken(e,1):s.getTokenBefore(e);return(!0===t?e.loc.end.line:e.loc.start.line)!==(n?n.loc.end.line:-1)}function p(e,t){const n=l(e,!1);if("ArrayExpression"===e.type||"ObjectExpression"===e.type||n.goodChar===t&&0===n.badChar||!u(e)||c(e,t,n.space,n.tab),"IfStatement"===e.type&&e.alternate){p(s.getTokenBefore(e.alternate),t),u(e.alternate)||p(e.alternate,t)}if("TryStatement"===e.type&&e.handler){p(s.getFirstToken(e.handler),t)}if("TryStatement"===e.type&&e.finalizer){p(s.getTokenBefore(e.finalizer),t)}if("DoWhileStatement"===e.type){p(s.getTokenAfter(e.body),t)}}function d(e,t){e.forEach((e=>p(e,t)))}function f(e,t){const n=s.getLastToken(e),r=l(n,!0);r.goodChar===t&&0===r.badChar||!u(e,!0)||c(e,t,r.space,r.tab,{line:n.loc.start.line,column:n.loc.start.column},!0)}function m(e,t,n){let r=e.parent;const o=new Set(n||["Program"]);for(;r.type!==t&&!o.has(r.type)&&"Program"!==r.type;)r=r.parent;return r.type===t?r:null}function g(e){return m(e,"VariableDeclarator")}function h(e,t){return t&&t.parent.loc.start.line===e.loc.start.line&&t.parent.declarations.length>1}function y(e){const t=s.getLastToken(e);return e.loc.start.line===t.loc.end.line}function x(e){if(y(e))return;let t,n,s="ArrayExpression"===e.type?e.elements:e.properties;s=s.filter((e=>null!==e));const a=g(e);if(u(e)){const n=e.parent;if(t=l(n).goodChar,!(a&&a.loc.start.line===e.loc.start.line||"VariableDeclarator"===n.type&&a!==a.parent.declarations[0]))if("VariableDeclarator"===n.type&&a.loc.start.line===n.loc.start.line)t+=r*o.VariableDeclarator[a.parent.kind];else if("ObjectExpression"===n.type||"ArrayExpression"===n.type){const s="ObjectExpression"===e.parent.type?e.parent.properties:e.parent.elements;s[0]&&s[0].loc.start.line===n.loc.start.line&&s[0].loc.end.line!==n.loc.start.line||("number"==typeof o[n.type]?t+=o[n.type]*r:t=s[0].loc.start.column)}else"CallExpression"===n.type||"NewExpression"===n.type?"number"==typeof o.CallExpression.arguments?t+=o.CallExpression.arguments*r:"first"===o.CallExpression.arguments?-1!==n.arguments.indexOf(e)&&(t=n.arguments[0].loc.start.column):t+=r:"LogicalExpression"!==n.type&&"ArrowFunctionExpression"!==n.type||(t+=r);!function(e,t){const n=l(e,!1);n.goodChar===t&&0===n.badChar||!u(e)||c(e,t,n.space,n.tab,{line:e.loc.start.line,column:e.loc.start.column})}(e,t)}else t=l(e).goodChar;n="first"===o[e.type]?s.length?s[0].loc.start.column:0:t+r*o[e.type],h(e,a)&&(n+=r*o.VariableDeclarator[a.parent.kind]),d(s,n),s.length>0&&s[s.length-1].loc.end.line===e.loc.end.line||f(e,t+(h(e,a)?o.VariableDeclarator[a.parent.kind]*r:0))}function b(e){if(y(e))return;if(e.parent&&("FunctionExpression"===e.parent.type||"FunctionDeclaration"===e.parent.type||"ArrowFunctionExpression"===e.parent.type))return void function(e){const t=e.parent;let n;if(n=!t.parent||"Property"!==t.parent.type&&"ArrayExpression"!==t.parent.type?l(t).goodChar:l(t,!1).goodChar,"CallExpression"===t.parent.type){const r=t.parent;"FunctionExpression"!==t.type&&"ArrowFunctionExpression"!==t.type?r&&r.loc.start.line=2&&t.arguments[1]===e&&t.arguments[0].loc.end.line>t.arguments[0].loc.start.line}(t)&&r.callee.loc.start.line===r.callee.loc.end.line&&!u(t)&&(n=l(r).goodChar)}let s=r;null!==o.outerIIFEBody&&function(e){const t=e.parent;let n=t.parent;if("CallExpression"!==t.type||t.callee!==e)return!1;for(;"UnaryExpression"===n.type&&("!"===n.operator||"~"===n.operator||"+"===n.operator||"-"===n.operator)||"AssignmentExpression"===n.type||"LogicalExpression"===n.type||"SequenceExpression"===n.type||"VariableDeclarator"===n.type;)n=n.parent;return("ExpressionStatement"===n.type||"VariableDeclaration"===n.type)&&n.parent&&"Program"===n.parent.type}(t)?s=o.outerIIFEBody*r:"FunctionExpression"===t.type?s=o.FunctionExpression.body*r:"FunctionDeclaration"===t.type&&(s=o.FunctionDeclaration.body*r),n+=s;const a=g(e);a&&h(e,a)&&(n+=r*o.VariableDeclarator[a.parent.kind]),e.body.length>0&&d(e.body,n),f(e,n-s)}(e);let t,n=[];t=e.parent&&-1!==["IfStatement","WhileStatement","ForStatement","ForInStatement","ForOfStatement","DoWhileStatement","ClassDeclaration","TryStatement"].indexOf(e.parent.type)&&function(e){return"BlockStatement"===e.type||"ClassBody"===e.type||e.body&&"BlockStatement"===e.body.type||e.consequent&&"BlockStatement"===e.consequent.type}(e)?l(e.parent).goodChar:e.parent&&"CatchClause"===e.parent.type?l(e.parent.parent).goodChar:l(e).goodChar,n="IfStatement"===e.type&&"BlockStatement"!==e.consequent.type?[e.consequent]:Array.isArray(e.body)?e.body:[e.body],n.length>0&&d(n,t+r),"BlockStatement"===e.type&&f(e,t)}function E(e){"BlockStatement"!==e.body.type&&b(e)}function S(e,t){const n="SwitchStatement"===e.type?e:e.parent,s=void 0===t?l(n).goodChar:t;let i;return a[n.loc.start.line]?a[n.loc.start.line]:(i=n.cases.length>0&&0===o.SwitchCase?s:s+r*o.SwitchCase,a[n.loc.start.line]=i,i)}return{Program(e){e.body.length>0&&d(e.body,l(e).goodChar)},ClassBody:b,BlockStatement:b,WhileStatement:E,ForStatement:E,ForInStatement:E,ForOfStatement:E,DoWhileStatement:E,IfStatement(e){"BlockStatement"!==e.consequent.type&&e.consequent.loc.start.line>e.loc.start.line&&b(e)},VariableDeclaration(e){e.declarations[e.declarations.length-1].loc.start.line>e.declarations[0].loc.start.line&&function(e){const t=function(e){return e.declarations.reduce(((t,n)=>{const r=t[t.length-1];return(n.loc.start.line!==e.loc.start.line&&!r||r&&r.loc.start.line!==n.loc.start.line)&&t.push(n),t}),[])}(e),n=l(e).goodChar,a=t[t.length-1],i=n+r*o.VariableDeclarator[e.kind];if(d(t,i),s.getLastToken(e).loc.end.line<=a.loc.end.line)return;const c=s.getTokenBefore(a);","===c.value?f(e,l(c).goodChar):f(e,i-r)}(e)},ObjectExpression(e){x(e)},ArrayExpression(e){x(e)},MemberExpression(e){if(void 0===o.MemberExpression)return;if(y(e))return;if(m(e,"VariableDeclarator",["FunctionExpression","ArrowFunctionExpression"]))return;if(m(e,"AssignmentExpression",["FunctionExpression"]))return;const t=l(e).goodChar+r*o.MemberExpression,n=[e.property],a=s.getTokenBefore(e.property);"Punctuator"===a.type&&"."===a.value&&n.push(a),d(n,t)},SwitchStatement(e){const t=l(e).goodChar,n=S(e,t);d(e.cases,n),f(e,t)},SwitchCase(e){if(y(e))return;const t=S(e);d(e.consequent,t+r)},FunctionDeclaration(e){y(e)||("first"===o.FunctionDeclaration.parameters&&e.params.length?d(e.params.slice(1),e.params[0].loc.start.column):null!==o.FunctionDeclaration.parameters&&d(e.params,l(e).goodChar+r*o.FunctionDeclaration.parameters))},FunctionExpression(e){y(e)||("first"===o.FunctionExpression.parameters&&e.params.length?d(e.params.slice(1),e.params[0].loc.start.column):null!==o.FunctionExpression.parameters&&d(e.params,l(e).goodChar+r*o.FunctionExpression.parameters))},ReturnStatement(e){if(y(e))return;const t=l(e).goodChar;!function(e){const t=s.getText(e).replace(s.getText(e.argument),"");return/^return\s*?\(\s*?\);*?/u.test(t)}(e)?p(e,t):function(e,t){const n=s.getLastToken(e,fr.isClosingParenToken);if(s.getText(n,n.loc.start.column).slice(0,-1).trim())return;const r=l(n,!0);r.goodChar!==t&&c(e,t,r.space,r.tab,{line:n.loc.start.line,column:n.loc.start.column},!0)}(e,t)},CallExpression(e){y(e)||("first"===o.CallExpression.arguments&&e.arguments.length?d(e.arguments.slice(1),e.arguments[0].loc.start.column):null!==o.CallExpression.arguments&&d(e.arguments,l(e).goodChar+r*o.CallExpression.arguments))}}}};function Ko(e){return"ForInStatement"===e.type||"ForOfStatement"===e.type||"ForStatement"===e.type}function Yo(e){const t=e.parent,n=t.parent;return Ko(n)?"ForStatement"===n.type?n.init===t:n.left===t:Boolean(e.init)}var Ho={meta:{type:"suggestion",docs:{description:"require or disallow initialization in variable declarations",category:"Variables",recommended:!1,url:"https://eslint.org/docs/rules/init-declarations"},schema:{anyOf:[{type:"array",items:[{enum:["always"]}],minItems:0,maxItems:1},{type:"array",items:[{enum:["never"]},{type:"object",properties:{ignoreForLoopInit:{type:"boolean"}},additionalProperties:!1}],minItems:0,maxItems:2}]},messages:{initialized:"Variable '{{idName}}' should be initialized on declaration.",notInitialized:"Variable '{{idName}}' should not be initialized on declaration."}},create(e){const t="always",n=e.options[0]||t,r=e.options[1]||{};return{"VariableDeclaration:exit"(o){const s=o.kind,a=o.declarations;for(let i=0;ie.replace(/'/gu,'"')},"prefer-single":{quote:"'",description:"doublequote",convert:e=>e.replace(/"/gu,"'")}};var Qo={meta:{type:"layout",docs:{description:"enforce the consistent use of either double or single quotes in JSX attributes",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/jsx-quotes"},fixable:"whitespace",schema:[{enum:["prefer-single","prefer-double"]}],messages:{unexpected:"Unexpected usage of {{description}}."}},create(e){const t=e.options[0]||"prefer-double",n=Xo[t];return{JSXAttribute(t){const r=t.value;r&&fr.isStringLiteral(r)&&!function(e){return-1!==e.value.indexOf(n.quote)||fr.isSurroundedBy(e.raw,n.quote)}(r)&&e.report({node:r,messageId:"unexpected",data:{description:n.description},fix:e=>e.replaceText(r,n.convert(r.raw))})}}}};function Zo(e){return e[e.length-1]}function es(e){return e.loc.end.line===e.loc.start.line}function ts(e,t){return e.mode=t.mode||"strict",void 0!==t.beforeColon?e.beforeColon=+t.beforeColon:e.beforeColon=0,void 0!==t.afterColon?e.afterColon=+t.afterColon:e.afterColon=1,void 0!==t.align&&("object"==typeof t.align?e.align=t.align:e.align={on:t.align,mode:e.mode,beforeColon:e.beforeColon,afterColon:e.afterColon}),e}var ns={meta:{type:"layout",docs:{description:"enforce consistent spacing between keys and values in object literal properties",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/key-spacing"},fixable:"whitespace",schema:[{anyOf:[{type:"object",properties:{align:{anyOf:[{enum:["colon","value"]},{type:"object",properties:{mode:{enum:["strict","minimum"]},on:{enum:["colon","value"]},beforeColon:{type:"boolean"},afterColon:{type:"boolean"}},additionalProperties:!1}]},mode:{enum:["strict","minimum"]},beforeColon:{type:"boolean"},afterColon:{type:"boolean"}},additionalProperties:!1},{type:"object",properties:{singleLine:{type:"object",properties:{mode:{enum:["strict","minimum"]},beforeColon:{type:"boolean"},afterColon:{type:"boolean"}},additionalProperties:!1},multiLine:{type:"object",properties:{align:{anyOf:[{enum:["colon","value"]},{type:"object",properties:{mode:{enum:["strict","minimum"]},on:{enum:["colon","value"]},beforeColon:{type:"boolean"},afterColon:{type:"boolean"}},additionalProperties:!1}]},mode:{enum:["strict","minimum"]},beforeColon:{type:"boolean"},afterColon:{type:"boolean"}},additionalProperties:!1}},additionalProperties:!1},{type:"object",properties:{singleLine:{type:"object",properties:{mode:{enum:["strict","minimum"]},beforeColon:{type:"boolean"},afterColon:{type:"boolean"}},additionalProperties:!1},multiLine:{type:"object",properties:{mode:{enum:["strict","minimum"]},beforeColon:{type:"boolean"},afterColon:{type:"boolean"}},additionalProperties:!1},align:{type:"object",properties:{mode:{enum:["strict","minimum"]},on:{enum:["colon","value"]},beforeColon:{type:"boolean"},afterColon:{type:"boolean"}},additionalProperties:!1}},additionalProperties:!1}]}],messages:{extraKey:"Extra space after {{computed}}key '{{key}}'.",extraValue:"Extra space before value for {{computed}}key '{{key}}'.",missingKey:"Missing space after {{computed}}key '{{key}}'.",missingValue:"Missing space before value for {{computed}}key '{{key}}'."}},create(e){const t=e.options[0]||{},n=(a={},"object"==typeof(i=t).align?(a.align=ts({},i.align),a.align.on=i.align.on||"colon",a.align.mode=i.align.mode||"strict",a.multiLine=ts({},i.multiLine||i),a.singleLine=ts({},i.singleLine||i)):(a.multiLine=ts({},i.multiLine||i),a.singleLine=ts({},i.singleLine||i),a.multiLine.align&&(a.align={on:a.multiLine.align.on,mode:a.multiLine.align.mode||a.multiLine.mode,beforeColon:a.multiLine.align.beforeColon,afterColon:a.multiLine.align.afterColon})),a),r=n.multiLine,o=n.singleLine,s=n.align||null;var a,i;const c=e.getSourceCode();function l(e){return!(e.method||e.shorthand||"init"!==e.kind||"Property"!==e.type)}function u(e){const t=e.key;return e.computed?c.getText().slice(t.range[0],t.range[1]):fr.getStaticPropertyName(e)}function p(t,n,r,o,s){const a=r.length-o,i=(h=t.key,c.getTokenAfter(h,fr.isColonToken)),l=c.getTokenBefore(i,{includeComments:!0}),p=c.getTokenAfter(i,{includeComments:!0}),d="key"===n,f=a>0,m=Math.abs(a),g=Array(m+1).join(" ");var h;const y=d?l.loc.end:i.loc.start,x=d?i.loc.start:p.loc.start,b=d?l.loc:p.loc,E=f?{start:y,end:x}:b;if((a&&"strict"===s||a<0&&"minimum"===s||a>0&&!o&&"minimum"===s)&&(!o||(S=r,!fr.LINEBREAK_MATCHER.test(S)))){let r;if(f){let e;e=d?[l.range[1],l.range[1]+m]:[p.range[0]-m,p.range[0]],r=function(t){return t.removeRange(e)}}else r=d?function(e){return e.insertTextAfter(l,g)}:function(e){return e.insertTextBefore(p,g)};let o="";o=f?"key"===n?"extraKey":"extraValue":"key"===n?"missingKey":"missingValue",e.report({node:t[n],loc:E,messageId:o,data:{computed:t.computed?"computed ":"",key:u(t)},fix:r})}var S}function d(e){const t=c.getFirstToken(e);return function(e){const t=c.getTokenAfter(e,fr.isColonToken);return c.getTokenBefore(t)}(e.key).range[1]-t.range[0]}function f(e){const t=/(\s*):(\s*)/u.exec(c.getText().slice(e.key.range[1],e.value.range[0]));return t?{beforeColon:t[1],afterColon:t[2]}:null}function m(e){return 1===e.properties.length?[e.properties]:e.properties.reduce(((e,t)=>{const n=Zo(e),r=Zo(n);return!r||function(e,t){const n=e.loc.start.line,r=t.loc.start.line;if(r-n<=1)return!0;const o=c.getCommentsBefore(t);if(o.length&&o[0].loc.start.line-n<=1&&r-Zo(o).loc.end.line<=1){for(let e=1;e1)return!1;return!0}return!1}(r,t)?n.push(t):e.push([t]),e}),[[]])}function g(e,t){const n=f(e);n&&(p(e,"key",n.beforeColon,t.beforeColon,t.mode),p(e,"value",n.afterColon,t.afterColon,t.mode))}function h(e,t){const n=e.length;for(let r=0;r{const t=e.filter(l);t.length>0&&function(e){const[t]=e,n=Zo(e);return t.loc.start.line===n.loc.end.line}(t)?h(t,r):function(e){const t=e.length,n=e.map(d),o=s.on;let a,i,c,l=Math.max(...n);s&&t>1?(a=s.beforeColon,i=s.afterColon,c=s.mode):(a=r.beforeColon,i=r.afterColon,c=s.mode),l+="colon"===o?a:i;for(let r=0;r]$/u,os=/^(?:[([{<~!]|\+\+?|--?)$/u,ss=/^[)\]}>*]$/u,as=/^[{*]$/u,is=/\$\{$/u,cs=/^\}/u,ls=/^(?:JSXElement|RegularExpression|String|Template)$/u,us=io.concat(["as","async","await","from","get","let","of","set","yield"]);function ps(e){return"Template"===e.type&&is.test(e.value)}function ds(e){return"Template"===e.type&&cs.test(e.value)}!function(){us.sort();for(let e=1;e(e[t]={type:"object",properties:{before:{type:"boolean"},after:{type:"boolean"}},additionalProperties:!1},e)),{}),additionalProperties:!1}},additionalProperties:!1}],messages:{expectedBefore:'Expected space(s) before "{{value}}".',expectedAfter:'Expected space(s) after "{{value}}".',unexpectedBefore:'Unexpected space(s) before "{{value}}".',unexpectedAfter:'Unexpected space(s) after "{{value}}".'}},create(e){const t=e.getSourceCode();function n(n,r){const o=t.getTokenBefore(n);o&&(ls.test(o.type)||r.test(o.value))&&!ps(o)&&fr.isTokenOnSameLine(o,n)&&!t.isSpaceBetweenTokens(o,n)&&e.report({loc:n.loc,messageId:"expectedBefore",data:n,fix:e=>e.insertTextBefore(n," ")})}function r(n,r){const o=t.getTokenBefore(n);o&&(ls.test(o.type)||r.test(o.value))&&!ps(o)&&fr.isTokenOnSameLine(o,n)&&t.isSpaceBetweenTokens(o,n)&&e.report({loc:{start:o.loc.end,end:n.loc.start},messageId:"unexpectedBefore",data:n,fix:e=>e.removeRange([o.range[1],n.range[0]])})}function o(n,r){const o=t.getTokenAfter(n);o&&(ls.test(o.type)||r.test(o.value))&&!ds(o)&&fr.isTokenOnSameLine(n,o)&&!t.isSpaceBetweenTokens(n,o)&&e.report({loc:n.loc,messageId:"expectedAfter",data:n,fix:e=>e.insertTextAfter(n," ")})}function s(n,r){const o=t.getTokenAfter(n);o&&(ls.test(o.type)||r.test(o.value))&&!ds(o)&&fr.isTokenOnSameLine(n,o)&&t.isSpaceBetweenTokens(n,o)&&e.report({loc:{start:n.loc.end,end:o.loc.start},messageId:"unexpectedAfter",data:n,fix:e=>e.removeRange([n.range[1],o.range[0]])})}const a=function(e={}){const t=!1!==e.before,a=!1!==e.after,i={before:t?n:r,after:a?o:s},c=e&&e.overrides||{},l=Object.create(null);for(let e=0;e{switch(e.value){case"get":case"set":case"async":return!0;default:return!1}}));if(!n)throw new Error("Failed to find token get, set, or async beside method name");l(n)}}return{DebuggerStatement:u,WithStatement:u,BreakStatement:u,ContinueStatement:u,ReturnStatement:u,ThrowStatement:u,TryStatement:function(e){u(e),u(e.handler),d(e.finalizer)},IfStatement:function(e){u(e),d(e.alternate)},SwitchStatement:u,SwitchCase:u,DoWhileStatement:function(e){u(e),d(e.test)},ForInStatement:function(e){u(e),d(e.right)},ForOfStatement:function(e){e.await?(i(t.getFirstToken(e,0)),c(t.getFirstToken(e,1))):u(e),l(t.getTokenBefore(e.right,fr.isNotOpeningParenToken))},ForStatement:u,WhileStatement:u,ClassDeclaration:m,ExportNamedDeclaration:g,ExportDefaultDeclaration:g,ExportAllDeclaration:g,FunctionDeclaration:f,ImportDeclaration:g,VariableDeclaration:u,ArrowFunctionExpression:f,AwaitExpression:function(e){i(t.getFirstToken(e))},ClassExpression:m,FunctionExpression:f,NewExpression:p,Super:p,ThisExpression:p,UnaryExpression:p,YieldExpression:p,ImportNamespaceSpecifier:function(e){i(t.getFirstToken(e,1),ss)},MethodDefinition:h,Property:h}}},ms={meta:{type:"layout",docs:{description:"enforce position of line comments",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/line-comment-position"},schema:[{oneOf:[{enum:["above","beside"]},{type:"object",properties:{position:{enum:["above","beside"]},ignorePattern:{type:"string"},applyDefaultPatterns:{type:"boolean"},applyDefaultIgnorePatterns:{type:"boolean"}},additionalProperties:!1}]}],messages:{above:"Expected comment to be above code.",beside:"Expected comment to be beside code."}},create(e){const t=e.options[0];let n,r,o=!0;t&&"string"!=typeof t?(n=!t.position||"above"===t.position,r=t.ignorePattern,o=Object.prototype.hasOwnProperty.call(t,"applyDefaultIgnorePatterns")?t.applyDefaultIgnorePatterns:!1!==t.applyDefaultPatterns):n=!t||"above"===t;const s=fr.COMMENTS_IGNORE_PATTERN,a=/^\s*falls?\s?through/u,i=new RegExp(r,"u"),c=e.getSourceCode();return{Program(){c.getAllComments().filter((e=>"Line"===e.type)).forEach((t=>{if(o&&(s.test(t.value)||a.test(t.value)))return;if(r&&i.test(t.value))return;const l=c.getTokenBefore(t,{includeComments:!0}),u=l&&l.loc.end.line===t.loc.start.line;n?u&&e.report({node:t,messageId:"above"}):u||e.report({node:t,messageId:"beside"})}))}}}},gs={meta:{type:"layout",docs:{description:"enforce consistent linebreak style",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/linebreak-style"},fixable:"whitespace",schema:[{enum:["unix","windows"]}],messages:{expectedLF:"Expected linebreaks to be 'LF' but found 'CRLF'.",expectedCRLF:"Expected linebreaks to be 'CRLF' but found 'LF'."}},create(e){const t=e.getSourceCode();function n(e,t){return function(n){return n.replaceTextRange(e,t)}}return{Program:function(r){const o="unix"===(e.options[0]||"unix"),s=o?"\n":"\r\n",a=t.getText(),i=fr.createGlobalLinebreakMatcher();let c,l=0;for(;null!==(c=i.exec(a));){if(l++,c[0]===s)continue;const a=c.index,i=[a,a+c[0].length];e.report({node:r,loc:{start:{line:l,column:t.lines[l-1].length},end:{line:l+1,column:0}},messageId:o?"expectedLF":"expectedCRLF",fix:n(i,s)})}}}}};var hs={meta:{type:"layout",docs:{description:"require empty lines around comments",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/lines-around-comment"},fixable:"whitespace",schema:[{type:"object",properties:{beforeBlockComment:{type:"boolean",default:!0},afterBlockComment:{type:"boolean",default:!1},beforeLineComment:{type:"boolean",default:!1},afterLineComment:{type:"boolean",default:!1},allowBlockStart:{type:"boolean",default:!1},allowBlockEnd:{type:"boolean",default:!1},allowClassStart:{type:"boolean"},allowClassEnd:{type:"boolean"},allowObjectStart:{type:"boolean"},allowObjectEnd:{type:"boolean"},allowArrayStart:{type:"boolean"},allowArrayEnd:{type:"boolean"},ignorePattern:{type:"string"},applyDefaultIgnorePatterns:{type:"boolean"}},additionalProperties:!1}],messages:{after:"Expected line after comment.",before:"Expected line before comment."}},create(e){const t=Object.assign({},e.options[0]),n=t.ignorePattern,r=fr.COMMENTS_IGNORE_PATTERN,o=new RegExp(n,"u"),s=!1!==t.applyDefaultIgnorePatterns;t.beforeBlockComment=void 0===t.beforeBlockComment||t.beforeBlockComment;const a=e.getSourceCode(),i=a.lines,c=i.length+1,l=a.getAllComments(),u=function(e){const t=[];return e.forEach((e=>{const n=e.loc.start.line,r=e.loc.end.line;t.push(n,r)})),t}(l),p=function(e){return e.map(((e,t)=>({code:e.trim(),num:t+1}))).filter((e=>!e.code)).map((e=>e.num))}(i),d=u.concat(p);function f(e,t){return e.type===t||e.body&&e.body.type===t||e.consequent&&e.consequent.type===t}function m(e){return a.getNodeByRangeIndex(e.range[0])}function g(e,t){const n=m(e);return n&&f(n,t)&&e.loc.start.line-n.loc.start.line==1}function h(e,t){const n=m(e);return n&&f(n,t)&&n.loc.end.line-e.loc.end.line==1}function y(e){return g(e,"ClassBody")}function x(e){return h(e,"ClassBody")}function b(i,l){if(s&&r.test(i.value))return;if(n&&o.test(i.value))return;let u=l.after,p=l.before;const f=i.loc.start.line-1,m=i.loc.end.line+1,b=function(e){let t=e;do{t=a.getTokenBefore(t,{includeComments:!0})}while(t&&fr.isCommentToken(t));if(t&&fr.isTokenOnSameLine(t,e))return!0;t=e;do{t=a.getTokenAfter(t,{includeComments:!0})}while(t&&fr.isCommentToken(t));return!(!t||!fr.isTokenOnSameLine(e,t))}(i),E=t.allowBlockStart&&function(e){return g(e,"ClassBody")||g(e,"BlockStatement")||g(e,"SwitchCase")}(i)&&!(!1===t.allowClassStart&&y(i)),S=t.allowBlockEnd&&function(e){return h(e,"ClassBody")||h(e,"BlockStatement")||h(e,"SwitchCase")||h(e,"SwitchStatement")}(i)&&!(!1===t.allowClassEnd&&x(i)),C=t.allowClassStart&&y(i),v=t.allowClassEnd&&x(i),A=t.allowObjectStart&&function(e){return g(e,"ObjectExpression")||g(e,"ObjectPattern")}(i),k=t.allowObjectEnd&&function(e){return h(e,"ObjectExpression")||h(e,"ObjectPattern")}(i),w=t.allowArrayStart&&function(e){return g(e,"ArrayExpression")||g(e,"ArrayPattern")}(i),P=t.allowArrayEnd&&function(e){return h(e,"ArrayExpression")||h(e,"ArrayPattern")}(i),T=E||C||A||w,I=S||v||k||P;if(f<1&&(p=!1),m>=c&&(u=!1),b)return;const F=a.getTokenBefore(i,{includeComments:!0}),D=a.getTokenAfter(i,{includeComments:!0});if(!T&&p&&!d.includes(f)&&(!fr.isCommentToken(F)||!fr.isTokenOnSameLine(F,i))){const t=i.range[0]-i.loc.start.column,n=[t,t];e.report({node:i,messageId:"before",fix:e=>e.insertTextBeforeRange(n,"\n")})}I||!u||d.includes(m)||fr.isCommentToken(D)&&fr.isTokenOnSameLine(i,D)||e.report({node:i,messageId:"after",fix:e=>e.insertTextAfter(i,"\n")})}return{Program(){l.forEach((e=>{"Line"===e.type?(t.beforeLineComment||t.afterLineComment)&&b(e,{after:t.afterLineComment,before:t.beforeLineComment}):"Block"===e.type&&(t.beforeBlockComment||t.afterBlockComment)&&b(e,{after:t.afterBlockComment,before:t.beforeBlockComment})}))}}}},ys={meta:{type:"layout",docs:{description:"require or disallow newlines around directives",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/lines-around-directive"},schema:[{oneOf:[{enum:["always","never"]},{type:"object",properties:{before:{enum:["always","never"]},after:{enum:["always","never"]}},additionalProperties:!1,minProperties:2}]}],fixable:"whitespace",messages:{expected:'Expected newline {{location}} "{{value}}" directive.',unexpected:'Unexpected newline {{location}} "{{value}}" directive.'},deprecated:!0,replacedBy:["padding-line-between-statements"]},create(e){const t=e.getSourceCode(),n=e.options[0]||"always",r="string"==typeof n?n:n.before,o="string"==typeof n?n:n.after;function s(e){const n=t.getTokenBefore(e,{includeComments:!0}),r=n?n.loc.end.line:0;return e.loc.start.line-r>=2}function a(e){const n=t.getLastToken(e),r=t.getTokenBefore(n);return fr.isSemicolonToken(n)&&n.loc.start.line>r.loc.end.line?r:n}function i(e){const n=a(e);return t.getTokenAfter(n,{includeComments:!0}).loc.start.line-n.loc.end.line>=2}function c(t,n,r){e.report({node:t,messageId:r?"expected":"unexpected",data:{value:t.expression.value,location:n},fix(e){const o=a(t);return r?"before"===n?e.insertTextBefore(t,"\n"):e.insertTextAfter(o,"\n"):e.removeRange("before"===n?[t.range[0]-1,t.range[0]]:[o.range[1],o.range[1]+1])}})}function l(e){const n=fr.getDirectivePrologue(e);if(!n.length)return;const a=n[0],l=t.getCommentsBefore(a);l.length?("always"!==r||s(a)||c(a,"before",!0),"never"===r&&s(a)&&c(a,"before",!1)):"Program"===e.type&&"never"===r&&!l.length&&s(a)&&c(a,"before",!1);const u=n[n.length-1],p="Program"===e.type?e.body:e.body.body;(u!==p[p.length-1]||u.trailingComments)&&("always"!==o||i(u)||c(u,"after",!0),"never"===o&&i(u)&&c(u,"after",!1))}return{Program:l,FunctionDeclaration:l,FunctionExpression:l,ArrowFunctionExpression:l}}},xs={meta:{type:"layout",docs:{description:"require or disallow an empty line between class members",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/lines-between-class-members"},fixable:"whitespace",schema:[{enum:["always","never"]},{type:"object",properties:{exceptAfterSingleLine:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{never:"Unexpected blank line between class members.",always:"Expected blank line between class members."}},create(e){const t=[];t[0]=e.options[0]||"always",t[1]=e.options[1]||{exceptAfterSingleLine:!1};const n=e.getSourceCode();function r(e,t,o){const s=n.getTokenAfter(e,{includeComments:!0});return s!==t&&s.loc.start.line-e.loc.end.line<=o?r(s,t,o):e}function o(e,t,r){const s=n.getTokenBefore(e,{includeComments:!0});return s!==t&&e.loc.start.line-s.loc.end.line<=r?o(s,t,r):e}return{ClassBody(s){const a=s.body;for(let s=0;s1,h=(i=f,c=m,0!==n.getTokensBetween(i,c,{includeComments:!0}).length),y=r(u,p,0);("always"===t[0]&&!d&&!g||"never"===t[0]&&g)&&e.report({node:a[s+1],messageId:g?"never":"always",fix:e=>h?null:g?e.replaceTextRange([f.range[1],m.range[0]],"\n"):e.insertTextAfter(y,"\n")})}var i,c}}}},bs={meta:{type:"suggestion",docs:{description:"enforce a maximum number of classes per file",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/max-classes-per-file"},schema:[{type:"integer",minimum:1}],messages:{maximumExceeded:"File has too many classes ({{ classCount }}). Maximum allowed is {{ max }}."}},create(e){const t=e.options[0]||1;let n=0;return{Program(){n=0},"Program:exit"(r){n>t&&e.report({node:r,messageId:"maximumExceeded",data:{classCount:n,max:t}})},"ClassDeclaration, ClassExpression"(){n++}}}},Es={meta:{type:"suggestion",docs:{description:"enforce a maximum depth that blocks can be nested",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/max-depth"},schema:[{oneOf:[{type:"integer",minimum:0},{type:"object",properties:{maximum:{type:"integer",minimum:0},max:{type:"integer",minimum:0}},additionalProperties:!1}]}],messages:{tooDeeply:"Blocks are nested too deeply ({{depth}}). Maximum allowed is {{maxDepth}}."}},create(e){const t=[],n=e.options[0];let r=4;function o(){t.push(0)}function s(){t.pop()}function a(n){const o=++t[t.length-1];o>r&&e.report({node:n,messageId:"tooDeeply",data:{depth:o,maxDepth:r}})}function i(){t[t.length-1]--}return"object"==typeof n&&(Object.prototype.hasOwnProperty.call(n,"maximum")||Object.prototype.hasOwnProperty.call(n,"max"))&&(r=n.maximum||n.max),"number"==typeof n&&(r=n),{Program:o,FunctionDeclaration:o,FunctionExpression:o,ArrowFunctionExpression:o,IfStatement(e){"IfStatement"!==e.parent.type&&a(e)},SwitchStatement:a,TryStatement:a,DoWhileStatement:a,WhileStatement:a,WithStatement:a,ForStatement:a,ForInStatement:a,ForOfStatement:a,"IfStatement:exit":i,"SwitchStatement:exit":i,"TryStatement:exit":i,"DoWhileStatement:exit":i,"WhileStatement:exit":i,"WithStatement:exit":i,"ForStatement:exit":i,"ForInStatement:exit":i,"ForOfStatement:exit":i,"FunctionDeclaration:exit":s,"FunctionExpression:exit":s,"ArrowFunctionExpression:exit":s,"Program:exit":s}}};const Ss={type:"object",properties:{code:{type:"integer",minimum:0},comments:{type:"integer",minimum:0},tabWidth:{type:"integer",minimum:0},ignorePattern:{type:"string"},ignoreComments:{type:"boolean"},ignoreStrings:{type:"boolean"},ignoreUrls:{type:"boolean"},ignoreTemplateLiterals:{type:"boolean"},ignoreRegExpLiterals:{type:"boolean"},ignoreTrailingComments:{type:"boolean"}},additionalProperties:!1},Cs={anyOf:[Ss,{type:"integer",minimum:0}]};var vs={meta:{type:"layout",docs:{description:"enforce a maximum line length",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/max-len"},schema:[Cs,Cs,Ss],messages:{max:"This line has a length of {{lineLength}}. Maximum allowed is {{maxLength}}.",maxComment:"This line has a comment length of {{lineLength}}. Maximum allowed is {{maxCommentLength}}."}},create(e){const t=/[^:/?#]:\/\/[^?#]/u,n=e.getSourceCode();const r=Object.assign({},e.options[e.options.length-1]);"number"==typeof e.options[0]&&(r.code=e.options[0]),"number"==typeof e.options[1]&&(r.tabWidth=e.options[1]);const o="number"==typeof r.code?r.code:80,s="number"==typeof r.tabWidth?r.tabWidth:4,a=!!r.ignoreComments,i=!!r.ignoreStrings,c=!!r.ignoreTemplateLiterals,l=!!r.ignoreRegExpLiterals,u=!!r.ignoreTrailingComments||!!r.ignoreComments,p=!!r.ignoreUrls,d=r.comments;let f=r.ignorePattern||null;function m(e,t,n){return n&&n.loc.start.line===t&&t<=n.loc.end.line&&(n.loc.end.line>t||n.loc.end.column===e.length)}function g(e,t){return e.slice(0,t.loc.start.column).replace(/\s+$/u,"")}function h(e,t){for(let s=t.loc.start.line;s<=t.loc.end.line;++s)n=e,r=s,o=t,Array.isArray(n[r])||(n[r]=[]),n[r].push(o);var n,r,o;return e}return f&&(f=new RegExp(f,"u")),{Program:function(r){const y=n.lines,x=a||d||u?function(){const e=[];return n.getAllComments().forEach((t=>{const r=n.getNodeByRangeIndex(t.range[0]);!function(e){if(!e||!e.parent||"JSXEmptyExpression"!==e.type||"JSXExpressionContainer"!==e.parent.type)return!1;const t=e.parent;return t.loc.start.line===t.loc.end.line}(r)?e.push(t):e[e.length-1]!==r.parent&&e.push(r.parent)})),e}():[];let b=0;const E=n.ast.tokens.filter((e=>"String"===e.type||"JSXText"===e.type&&"JSXAttribute"===n.getNodeByRangeIndex(e.range[0]-1).type)).reduce(h,{}),S=n.ast.tokens.filter((e=>"Template"===e.type)).reduce(h,{}),C=n.ast.tokens.filter((e=>"RegularExpression"===e.type)).reduce(h,{});y.forEach(((n,h)=>{const y=h+1;let v,A=!1;if(bt||o.line===t&&o.column===e.length)}(n,y,e))A=!0,v=n;else if(u&&m(n,y,e)){v=g(n,e);let t=b;for(;m(v,y,x[--t]);)v=g(v,x[t])}else v=n}else v=n;if(f&&f.test(v)||p&&t.test(v)||i&&E[y]||c&&S[y]||l&&C[y])return;const k=function(e,t){let n=0;return e.replace(/\t/gu,((e,r)=>{n+=t-(t?(r+n)%t:0)-1})),Array.from(e).length+n}(v,s),w=A&&d;if(A&&a)return;const P={start:{line:y,column:0},end:{line:y,column:v.length}};w?k>d&&e.report({node:r,loc:P,messageId:"maxComment",data:{lineLength:k,maxCommentLength:d}}):k>o&&e.report({node:r,loc:P,messageId:"max",data:{lineLength:k,maxLength:o}})}))}}}},As={meta:{type:"suggestion",docs:{description:"enforce a maximum number of lines per file",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/max-lines"},schema:[{oneOf:[{type:"integer",minimum:0},{type:"object",properties:{max:{type:"integer",minimum:0},skipComments:{type:"boolean"},skipBlankLines:{type:"boolean"}},additionalProperties:!1}]}],messages:{exceed:"File has too many lines ({{actual}}). Maximum allowed is {{max}}."}},create(e){const t=e.options[0];let n=300;"object"==typeof t&&Object.prototype.hasOwnProperty.call(t,"max")?n=t.max:"number"==typeof t&&(n=t);const r=t&&t.skipComments,o=t&&t.skipBlankLines,s=e.getSourceCode();function a(e){return e&&("Block"===e.type||"Line"===e.type)}return{"Program:exit"(){let t=s.lines.map(((e,t)=>({lineNumber:t+1,text:e})));if(t.length>1&&""===F.default.last(t).text&&t.pop(),o&&(t=t.filter((e=>""!==e.text.trim()))),r){const e=s.getAllComments(),n=F.default.flatten(e.map((e=>function(e){let t,n=e.loc.start.line,r=e.loc.end.line;t=e;do{t=s.getTokenBefore(t,{includeComments:!0})}while(a(t));t&&fr.isTokenOnSameLine(t,e)&&(n+=1),t=e;do{t=s.getTokenAfter(t,{includeComments:!0})}while(a(t));return t&&fr.isTokenOnSameLine(e,t)&&(r-=1),n<=r?F.default.range(n,r+1):[]}(e))));t=t.filter((e=>!n.includes(e.lineNumber)))}if(t.length>n){const r={start:{line:t[n].lineNumber,column:0},end:{line:s.lines.length,column:F.default.last(s.lines).length}};e.report({loc:r,messageId:"exceed",data:{max:n,actual:t.length}})}}}}};var ks={meta:{type:"suggestion",docs:{description:"enforce a maximum number of lines of code in a function",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/max-lines-per-function"},schema:[{oneOf:[{type:"object",properties:{max:{type:"integer",minimum:0},skipComments:{type:"boolean"},skipBlankLines:{type:"boolean"},IIFEs:{type:"boolean"}},additionalProperties:!1},{type:"integer",minimum:1}]}],messages:{exceed:"{{name}} has too many lines ({{lineCount}}). Maximum allowed is {{maxLines}}."}},create(e){const t=e.getSourceCode(),n=t.lines,r=e.options[0];let o=50,s=!1,a=!1,i=!1;"object"==typeof r?(o="number"==typeof r.max?r.max:50,s=!!r.skipComments,a=!!r.skipBlankLines,i=!!r.IIFEs):"number"==typeof r&&(o=r);const c=function(e){const t=new Map;return e.forEach((e=>{for(let n=e.loc.start.line;n<=e.loc.end.line;n++)t.set(n,e)})),t}(t.getAllComments());function l(e,t,n){const r=n.loc.start,o=n.loc.end,s=r.line===t&&!e.slice(0,r.column).trim(),a=o.line===t&&!e.slice(o.column).trim();return n&&(r.linet||a)}function u(t){const r=function(e){return!!e.parent&&e===e.parent.value&&("MethodDefinition"===e.parent.type||"Property"===e.parent.type&&(!0===e.parent.method||"get"===e.parent.kind||"set"===e.parent.kind))}(t)?t.parent:t;if(!i&&function(e){return("FunctionExpression"===e.type||"ArrowFunctionExpression"===e.type)&&e.parent&&"CallExpression"===e.parent.type&&e.parent.callee===e}(r))return;let u=0;for(let e=r.loc.start.line-1;eo){const n=F.default.upperFirst(fr.getFunctionNameWithKind(t));e.report({node:r,messageId:"exceed",data:{name:n,lineCount:u,maxLines:o}})}}return{FunctionDeclaration:u,FunctionExpression:u,ArrowFunctionExpression:u}}},ws={meta:{type:"suggestion",docs:{description:"enforce a maximum depth that callbacks can be nested",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/max-nested-callbacks"},schema:[{oneOf:[{type:"integer",minimum:0},{type:"object",properties:{maximum:{type:"integer",minimum:0},max:{type:"integer",minimum:0}},additionalProperties:!1}]}],messages:{exceed:"Too many nested callbacks ({{num}}). Maximum allowed is {{max}}."}},create(e){const t=e.options[0];let n=10;"object"==typeof t&&(Object.prototype.hasOwnProperty.call(t,"maximum")||Object.prototype.hasOwnProperty.call(t,"max"))?n=t.maximum||t.max:"number"==typeof t&&(n=t);const r=[];function o(t){if("CallExpression"===t.parent.type&&r.push(t),r.length>n){const o={num:r.length,max:n};e.report({node:t,messageId:"exceed",data:o})}}function s(){r.pop()}return{ArrowFunctionExpression:o,"ArrowFunctionExpression:exit":s,FunctionExpression:o,"FunctionExpression:exit":s}}},Ps={meta:{type:"suggestion",docs:{description:"enforce a maximum number of parameters in function definitions",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/max-params"},schema:[{oneOf:[{type:"integer",minimum:0},{type:"object",properties:{maximum:{type:"integer",minimum:0},max:{type:"integer",minimum:0}},additionalProperties:!1}]}],messages:{exceed:"{{name}} has too many parameters ({{count}}). Maximum allowed is {{max}}."}},create(e){const t=e.getSourceCode(),n=e.options[0];let r=3;function o(n){n.params.length>r&&e.report({loc:fr.getFunctionHeadLoc(n,t),node:n,messageId:"exceed",data:{name:F.default.upperFirst(fr.getFunctionNameWithKind(n)),count:n.params.length,max:r}})}return"object"==typeof n&&(Object.prototype.hasOwnProperty.call(n,"maximum")||Object.prototype.hasOwnProperty.call(n,"max"))&&(r=n.maximum||n.max),"number"==typeof n&&(r=n),{FunctionDeclaration:o,ArrowFunctionExpression:o,FunctionExpression:o}}},Ts={meta:{type:"suggestion",docs:{description:"enforce a maximum number of statements allowed in function blocks",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/max-statements"},schema:[{oneOf:[{type:"integer",minimum:0},{type:"object",properties:{maximum:{type:"integer",minimum:0},max:{type:"integer",minimum:0}},additionalProperties:!1}]},{type:"object",properties:{ignoreTopLevelFunctions:{type:"boolean"}},additionalProperties:!1}],messages:{exceed:"{{name}} has too many statements ({{count}}). Maximum allowed is {{max}}."}},create(e){const t=[],n=e.options[0],r=e.options[1]&&e.options[1].ignoreTopLevelFunctions||!1,o=[];let s=10;function a(t,n,r){if(n>r){const o=F.default.upperFirst(fr.getFunctionNameWithKind(t));e.report({node:t,messageId:"exceed",data:{name:o,count:n,max:r}})}}function i(){t.push(0)}function c(e){const n=t.pop();r&&0===t.length?o.push({node:e,count:n}):a(e,n,s)}return"object"==typeof n&&(Object.prototype.hasOwnProperty.call(n,"maximum")||Object.prototype.hasOwnProperty.call(n,"max"))?s=n.maximum||n.max:"number"==typeof n&&(s=n),{FunctionDeclaration:i,FunctionExpression:i,ArrowFunctionExpression:i,BlockStatement:function(e){t[t.length-1]+=e.body.length},"FunctionDeclaration:exit":c,"FunctionExpression:exit":c,"ArrowFunctionExpression:exit":c,"Program:exit"(){1!==o.length&&o.forEach((e=>{const t=e.count;a(e.node,t,s)}))}}}},Is={meta:{type:"layout",docs:{description:"enforce a maximum number of statements allowed per line",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/max-statements-per-line"},schema:[{type:"object",properties:{max:{type:"integer",minimum:1,default:1}},additionalProperties:!1}],messages:{exceed:"This line has {{numberOfStatementsOnThisLine}} {{statements}}. Maximum allowed is {{maxStatementsPerLine}}."}},create(e){const t=e.getSourceCode(),n=e.options[0]||{},r=void 0!==n.max?n.max:1;let o,s=0,a=0;const i=/^(?:(?:DoWhile|For|ForIn|ForOf|If|Labeled|While)Statement|Export(?:Default|Named)Declaration)$/u;function c(){o&&e.report({node:o,messageId:"exceed",data:{numberOfStatementsOnThisLine:a,maxStatementsPerLine:r,statements:1===a?"statement":"statements"}}),o=null}function l(e){const t=e.loc.start.line;i.test(e.parent.type)&&e.parent.alternate!==e||(t===s?a+=1:(c(),a=1,s=t),a===r+1&&(o=o||e))}function u(e){const n=function(e){return t.getLastToken(e,fr.isNotSemicolonToken)}(e).loc.end.line;n!==s&&(c(),a=1,s=n)}return{BreakStatement:l,ClassDeclaration:l,ContinueStatement:l,DebuggerStatement:l,DoWhileStatement:l,ExpressionStatement:l,ForInStatement:l,ForOfStatement:l,ForStatement:l,FunctionDeclaration:l,IfStatement:l,ImportDeclaration:l,LabeledStatement:l,ReturnStatement:l,SwitchStatement:l,ThrowStatement:l,TryStatement:l,VariableDeclaration:l,WhileStatement:l,WithStatement:l,ExportNamedDeclaration:l,ExportDefaultDeclaration:l,ExportAllDeclaration:l,"BreakStatement:exit":u,"ClassDeclaration:exit":u,"ContinueStatement:exit":u,"DebuggerStatement:exit":u,"DoWhileStatement:exit":u,"ExpressionStatement:exit":u,"ForInStatement:exit":u,"ForOfStatement:exit":u,"ForStatement:exit":u,"FunctionDeclaration:exit":u,"IfStatement:exit":u,"ImportDeclaration:exit":u,"LabeledStatement:exit":u,"ReturnStatement:exit":u,"SwitchStatement:exit":u,"ThrowStatement:exit":u,"TryStatement:exit":u,"VariableDeclaration:exit":u,"WhileStatement:exit":u,"WithStatement:exit":u,"ExportNamedDeclaration:exit":u,"ExportDefaultDeclaration:exit":u,"ExportAllDeclaration:exit":u,"Program:exit":c}}},Fs={meta:{type:"suggestion",docs:{description:"enforce a particular style for multiline comments",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/multiline-comment-style"},fixable:"whitespace",schema:[{enum:["starred-block","separate-lines","bare-block"]}],messages:{expectedBlock:"Expected a block comment instead of consecutive line comments.",expectedBareBlock:"Expected a block comment without padding stars.",startNewline:"Expected a linebreak after '/*'.",endNewline:"Expected a linebreak before '*/'.",missingStar:"Expected a '*' at the start of this line.",alignment:"Expected this line to be aligned with the start of the comment.",expectedLines:"Expected multiple line comments instead of a block comment."}},create(e){const t=e.getSourceCode(),n=e.options[0]||"starred-block";function r([e]){if("Block"!==e.type)return!1;const t=e.value.split(fr.LINEBREAK_MATCHER);return t.length>0&&t.every(((e,n)=>(0===n||n===t.length-1?/^\s*$/u:/^\s*\*/u).test(e)))}function o([e]){if("Block"!==e.type)return!1;const t=e.value.split(fr.LINEBREAK_MATCHER);return/^\*\s*$/u.test(t[0])&&t.slice(1,-1).every((e=>/^\s* /u.test(e)))&&/^\s*$/u.test(t[t.length-1])}function s(e){const[n]=e;return"Line"===n.type?function(e){const t=e.map((({value:e})=>e)).filter((e=>e.trim().length)).every((e=>e.startsWith(" ")));return e.map((({value:e})=>t?e.replace(/^ /u,""):e))}(e):r(e)?function(e){const t=e.value.split(fr.LINEBREAK_MATCHER).filter(((e,t,n)=>!(0===t||t===n.length-1))).map((e=>e.replace(/^\s*$/u,""))),n=t.map((e=>e.replace(/\s*\*/u,""))).filter((e=>e.trim().length)).every((e=>e.startsWith(" ")));return t.map((e=>e.replace(n?/\s*\* ?/u:/\s*\*/u,"")))}(n):function(e){const n=e.value.split(fr.LINEBREAK_MATCHER).map((e=>e.replace(/^\s*$/u,""))),r=`${t.text.slice(e.range[0]-e.loc.start.column,e.range[0])} `;let o="";for(const[e,t]of n.entries()){if(!t.trim().length||0===e)continue;const[,n]=t.match(/^(\s*\*?\s*)/u);if(n.lengtho.length&&(o=e)}}return n.map((e=>{const t=e.match(/^(\s*\*?\s*)(.*)/u),[,n,s]=t;return n.length>r.length?`${n.slice(r.length-(o.length+n.length))}${s}`:n.lengthe.includes("*/"))))if(n.length>1)e.report({loc:{start:r.loc.start,end:n[n.length-1].loc.end},messageId:"expectedBlock",fix(e){const t=[r.range[0],n[n.length-1].range[1]];return o.some((e=>e.startsWith("/")))?null:e.replaceTextRange(t,function(e,t){const n=a(e);return`/*\n${t.map((e=>`${n} * ${e}`)).join("\n")}\n${n} */`}(r,o))}});else{const n=r.value.split(fr.LINEBREAK_MATCHER),o=`${a(r)} *`;if(!/^\*?\s*$/u.test(n[0])){const t=r.value.startsWith("*")?r.range[0]+1:r.range[0];e.report({loc:{start:r.loc.start,end:{line:r.loc.start.line,column:r.loc.start.column+2}},messageId:"startNewline",fix:e=>e.insertTextAfterRange([t,t+2],`\n${o}`)})}/^\s*$/u.test(n[n.length-1])||e.report({loc:{start:{line:r.loc.end.line,column:r.loc.end.column-2},end:r.loc.end},messageId:"endNewline",fix:e=>e.replaceTextRange([r.range[1]-2,r.range[1]],`\n${o}/`)});for(let s=r.loc.start.line+1;s<=r.loc.end.line;s++){const a=t.lines[s-1],i=/^\s*\*/u.test(a)?"alignment":"missingStar";a.startsWith(o)||e.report({loc:{start:{line:s,column:0},end:{line:s,column:a.length}},messageId:i,fix(e){const c=t.getIndexFromLoc({line:s,column:0});if("alignment"===i){const[,t=""]=a.match(/^(\s*\*)/u)||[],n=c+t.length;return e.replaceTextRange([c,n],o)}const[,l=""]=a.match(/^(\s*)/u)||[],u=c+l.length;let p;for(const[e,o]of n.entries()){if(!/\S+/u.test(o))continue;const n=t.lines[r.loc.start.line-1+e],[,s="",i=""]=n.match(/^(\s*(?:\/?\*)?(\s*))/u)||[];p=`${l.slice(s.length)}${i}`,/^\s*\//u.test(a)&&0===p.length&&(p+=" ");break}return e.replaceTextRange([c,u],`${o}${p}`)}})}}},"separate-lines"(n){const[r]=n;if("Block"!==r.type||o(n))return;const i=s(n),c=t.getTokenAfter(r,{includeComments:!0});c&&r.loc.end.line===c.loc.start.line||e.report({loc:{start:r.loc.start,end:{line:r.loc.start.line,column:r.loc.start.column+2}},messageId:"expectedLines",fix:e=>e.replaceText(r,function(e,t){return t.map((e=>`// ${e}`)).join(`\n${a(e)}`)}(r,i))})},"bare-block"(t){if(o(t))return;const[n]=t,a=s(t);"Line"===n.type&&a.length>1&&!a.some((e=>e.includes("*/")))&&e.report({loc:{start:n.loc.start,end:t[t.length-1].loc.end},messageId:"expectedBlock",fix:e=>e.replaceTextRange([n.range[0],t[t.length-1].range[1]],i(n,a))}),r(t)&&e.report({loc:{start:n.loc.start,end:{line:n.loc.start.line,column:n.loc.start.column+2}},messageId:"expectedBareBlock",fix:e=>e.replaceText(n,i(n,a))})}};return{Program:()=>t.getAllComments().filter((e=>"Shebang"!==e.type)).filter((e=>!fr.COMMENTS_IGNORE_PATTERN.test(e.value))).filter((e=>{const n=t.getTokenBefore(e,{includeComments:!0});return!n||n.loc.end.line{const s=t.getTokenBefore(n,{includeComments:!0});return"Line"===n.type&&r&&"Line"===o[r-1].type&&s&&s.loc.end.line===n.loc.start.line-1&&s===o[r-1]?e[e.length-1].push(n):e.push([n]),e}),[]).filter((e=>!(1===e.length&&e[0].loc.start.line===e[0].loc.end.line))).forEach(c[n])}}},Ds={meta:{type:"layout",docs:{description:"enforce newlines between operands of ternary expressions",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/multiline-ternary"},schema:[{enum:["always","always-multiline","never"]}],messages:{expectedTestCons:"Expected newline between test and consequent of ternary expression.",expectedConsAlt:"Expected newline between consequent and alternate of ternary expression.",unexpectedTestCons:"Unexpected newline between test and consequent of ternary expression.",unexpectedConsAlt:"Unexpected newline between consequent and alternate of ternary expression."},fixable:"whitespace"},create(e){const t=e.getSourceCode(),n=e.options[0],r="never"!==n,o="always-multiline"===n;return{ConditionalExpression(n){const s=t.getTokenAfter(n.test,fr.isNotClosingParenToken),a=t.getTokenAfter(n.consequent,fr.isNotClosingParenToken),i=t.getFirstToken(n),c=t.getTokenBefore(s),l=t.getTokenAfter(s),u=t.getTokenBefore(a),p=t.getTokenAfter(a),d=fr.isTokenOnSameLine(c,l),f=fr.isTokenOnSameLine(u,p),m=!!t.getCommentsInside(n).length;if(r){if(o&&n.loc.start.line===n.loc.end.line)return;d&&e.report({node:n.test,loc:{start:i.loc.start,end:c.loc.end},messageId:"expectedTestCons",fix:e=>m?null:e.replaceTextRange([c.range[1],s.range[0]],"\n")}),f&&e.report({node:n.consequent,loc:{start:l.loc.start,end:u.loc.end},messageId:"expectedConsAlt",fix:e=>m?null:e.replaceTextRange([u.range[1],a.range[0]],"\n")})}else d||e.report({node:n.test,loc:{start:i.loc.start,end:c.loc.end},messageId:"unexpectedTestCons",fix:e=>{if(m)return null;const t=[],n=fr.isTokenOnSameLine(c,s),r=fr.isTokenOnSameLine(s,l);return n||t.push(e.removeRange([c.range[1],s.range[0]])),r||t.push(e.removeRange([s.range[1],l.range[0]])),t}}),f||e.report({node:n.consequent,loc:{start:l.loc.start,end:u.loc.end},messageId:"unexpectedConsAlt",fix:e=>{if(m)return null;const t=[],n=fr.isTokenOnSameLine(u,a),r=fr.isTokenOnSameLine(a,p);return n||t.push(e.removeRange([u.range[1],a.range[0]])),r||t.push(e.removeRange([a.range[1],p.range[0]])),t}})}}}};const Os=["Array","Boolean","Date","Error","Function","Number","Object","RegExp","String","Symbol","BigInt"];function Bs(e,t,n){if(Object.prototype.hasOwnProperty.call(e,t)&&!Array.isArray(e[t]))throw new TypeError(`${t}, if provided, must be an Array`);return e[t]||n}function Ns(e,t){return e[t]=!0,e}var js={meta:{type:"suggestion",docs:{description:"require constructor names to begin with a capital letter",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/new-cap"},schema:[{type:"object",properties:{newIsCap:{type:"boolean",default:!0},capIsNew:{type:"boolean",default:!0},newIsCapExceptions:{type:"array",items:{type:"string"}},newIsCapExceptionPattern:{type:"string"},capIsNewExceptions:{type:"array",items:{type:"string"}},capIsNewExceptionPattern:{type:"string"},properties:{type:"boolean",default:!0}},additionalProperties:!1}],messages:{upper:"A function with a name starting with an uppercase letter should only be used as a constructor.",lower:"A constructor name should not start with a lowercase letter."}},create(e){const t=Object.assign({},e.options[0]);t.newIsCap=!1!==t.newIsCap,t.capIsNew=!1!==t.capIsNew;const n=!1===t.properties,r=Bs(t,"newIsCapExceptions",[]).reduce(Ns,{}),o=t.newIsCapExceptionPattern?new RegExp(t.newIsCapExceptionPattern,"u"):null,s=function(e){let t=Bs(e,"capIsNewExceptions",Os);return t!==Os&&(t=t.concat(Os)),t.reduce(Ns,{})}(t),a=t.capIsNewExceptionPattern?new RegExp(t.capIsNewExceptionPattern,"u"):null,i={},c=e.getSourceCode();function l(e){return"Identifier"===e.callee.type?e.callee.name:fr.getStaticPropertyName(e.callee)||""}function u(e){const t=e.charAt(0),n=t.toLowerCase();return n===t.toUpperCase()?"non-alpha":t===n?"lower":"upper"}function p(e,t,r,o){const s=c.getText(t.callee);if(e[r]||e[s])return!0;if(o&&o.test(s))return!0;const a=fr.skipChainExpression(t.callee);return"UTC"===r&&"MemberExpression"===a.type?"Identifier"===a.object.type&&"Date"===a.object.name:n&&"MemberExpression"===a.type}function d(t,n){let r=fr.skipChainExpression(t.callee);"MemberExpression"===r.type&&(r=r.property),e.report({node:t,loc:r.loc,messageId:n})}return t.newIsCap&&(i.NewExpression=function(e){const t=l(e);if(t){"lower"!==u(t)||p(r,e,t,o)||d(e,"lower")}}),t.capIsNew&&(i.CallExpression=function(e){const t=l(e);if(t){"upper"!==u(t)||p(s,e,t,a)||d(e,"upper")}}),i}},Ls={meta:{type:"layout",docs:{description:"enforce or disallow parentheses when invoking a constructor with no arguments",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/new-parens"},fixable:"code",schema:{anyOf:[{type:"array",items:[{enum:["always","never"]}],minItems:0,maxItems:1}]},messages:{missing:"Missing '()' invoking a constructor.",unnecessary:"Unnecessary '()' invoking a constructor with no arguments."}},create(e){const t="never"!==e.options[0],n=e.getSourceCode();return{NewExpression(r){if(0!==r.arguments.length)return;const o=n.getLastToken(r),s=o&&fr.isClosingParenToken(o)&&fr.isOpeningParenToken(n.getTokenBefore(o))&&r.callee.range[1]e.insertTextAfter(r,"()")}):s&&e.report({node:r,messageId:"unnecessary",fix:e=>[e.remove(n.getTokenBefore(o)),e.remove(o),e.insertTextBefore(r,"("),e.insertTextAfter(r,")")]})}}}},Rs={meta:{type:"layout",docs:{description:"require or disallow an empty line after variable declarations",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/newline-after-var"},schema:[{enum:["never","always"]}],fixable:"whitespace",messages:{expected:"Expected blank line after variable declarations.",unexpected:"Unexpected blank line after variable declarations."},deprecated:!0,replacedBy:["padding-line-between-statements"]},create(e){const t=e.getSourceCode(),n="never"===e.options[0]?"never":"always",r=t.getAllComments().reduce(((e,t)=>(e[t.loc.start.line]=t.loc.end.line,e)),{});function o(e){const t=r[e];return r[t+1]?o(t+1):t}return{VariableDeclaration:function(s){const a=function(e){const n=t.getLastToken(e);if("Punctuator"===n.type&&";"===n.value){const e=t.getTokenBefore(n);if(e.loc.end.line!==n.loc.start.line)return e}return n}(s),i=a===t.getLastToken(s)?t.getTokenAfter(s):t.getLastToken(s),c=a.loc.end.line+1;if(!i)return;if("ForStatement"===(l=s.parent.type)||"ForInStatement"===l||"ForOfStatement"===l)return;var l,u;if("ExportNamedDeclaration"===(u=s.parent.type)||"ExportSpecifier"===u||"ExportDefaultDeclaration"===u||"ExportAllDeclaration"===u)return;if("Keyword"===i.type&&function(e){return"var"===e||"let"===e||"const"===e}(i.value))return;if(function(e){const n=t.getTokenAfter(e);return!n||"Punctuator"===n.type&&"}"===n.value}(s))return;const p=i.loc.start.line>c,d=void 0!==r[c];var f;"never"===n&&p&&!d&&e.report({node:s,messageId:"unexpected",data:{identifier:s.name},fix(e){const n=t.getText().slice(a.range[1],i.range[0]).split(fr.LINEBREAK_MATCHER);return e.replaceTextRange([a.range[1],i.range[0]],`${n.slice(0,-1).join("")}\n${n[n.length-1]}`)}}),"always"!==n||p&&(!d||(f=c,i.loc.start.line>o(f)+1))||e.report({node:s,messageId:"expected",data:{identifier:s.name},fix:e=>(p?o(c):a.loc.end.line)===i.loc.start.line?e.insertTextBefore(i,"\n\n"):e.insertTextBeforeRange([i.range[0]-i.loc.start.column,i.range[1]],"\n")})}}}},Ms={meta:{type:"layout",docs:{description:"require an empty line before `return` statements",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/newline-before-return"},fixable:"whitespace",schema:[],messages:{expected:"Expected newline before return statement."},deprecated:!0,replacedBy:["padding-line-between-statements"]},create(e){const t=e.getSourceCode();function n(e,n){const r=t.getTokenBefore(e);return n.some((e=>r.value===e))}function r(e){const n=e.loc.start.line,r=function(e){const n=t.getTokenBefore(e);let r;return r=n?n.loc.end.line:0,r}(e);return n-r-function(e,n){const r=t.getCommentsBefore(e);let o=0;return r.length?(r.forEach((t=>{o++,"Block"===t.type&&(o+=t.loc.end.line-t.loc.start.line),t.loc.start.line===n&&o--,t.loc.end.line===e.loc.start.line&&o--})),o):o}(e,r)>1}return{ReturnStatement(o){(function(e){const t=e.parent.type;return e.parent.body?Array.isArray(e.parent.body)?e.parent.body[0]===e:e.parent.body===e:n(e,"IfStatement"===t?["else",")"]:"DoWhileStatement"===t?["do"]:"SwitchCase"===t?[":"]:[")"])})(o)||r(o)||e.report({node:o,messageId:"expected",fix(e){if(function(e){const n=t.getCommentsBefore(e),r=n[n.length-1],o=t.getTokenBefore(e);return 0===n.length||r.loc.end.line===o.loc.end.line&&r.loc.end.line!==e.loc.start.line}(o)){const n=t.getTokenBefore(o),r=o.loc.start.line===n.loc.end.line?"\n\n":"\n";return e.insertTextBefore(o,r)}return null}})}}}},_s={meta:{type:"layout",docs:{description:"require a newline after each call in a method chain",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/newline-per-chained-call"},fixable:"whitespace",schema:[{type:"object",properties:{ignoreChainWithDepth:{type:"integer",minimum:1,maximum:10,default:2}},additionalProperties:!1}],messages:{expected:"Expected line break before `{{callee}}`."}},create(e){const t=(e.options[0]||{}).ignoreChainWithDepth||2,n=e.getSourceCode();function r(e){const t=function(e){return e.computed?e.optional?"?.[":"[":e.optional?"?.":"."}(e),r=n.getText(e.property).split(fr.LINEBREAK_MATCHER),o=e.computed&&1===r.length?"]":"";return t+r[0]+o}return{"CallExpression:exit"(o){const s=fr.skipChainExpression(o.callee);if("MemberExpression"!==s.type)return;let a=fr.skipChainExpression(s.object),i=1;for(;a&&a.callee;)i+=1,a=fr.skipChainExpression(fr.skipChainExpression(a.callee).object);if(i>t&&fr.isTokenOnSameLine(s.object,s.property)){const t=n.getTokenAfter(s.object,fr.isNotClosingParenToken);e.report({node:s.property,loc:{start:t.loc.start,end:s.loc.end},messageId:"expected",data:{callee:r(s)},fix:e=>e.insertTextBefore(t,"\n")})}}}}};const{getStaticPropertyName:$s,getVariableByName:qs,skipChainExpression:Us}=fr;function Vs(e){return/^(alert|confirm|prompt)$/u.test(e)}function Ws(e,t){const n=function(e,t){const n=e.references.filter((e=>e.identifier.range[0]===t.range[0]&&e.identifier.range[1]===t.range[1]));return 1===n.length?n[0]:null}(e,t);return n&&n.resolved&&n.resolved.defs.length>0}var Gs={meta:{type:"suggestion",docs:{description:"disallow the use of `alert`, `confirm`, and `prompt`",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-alert"},schema:[],messages:{unexpected:"Unexpected {{name}}."}},create:e=>({CallExpression(t){const n=Us(t.callee),r=e.getScope();if("Identifier"===n.type){const o=n.name;!Ws(r,n)&&Vs(n.name)&&e.report({node:t,messageId:"unexpected",data:{name:o}})}else if("MemberExpression"===n.type&&function(e,t){return"global"===e.type&&"ThisExpression"===t.type||!("Identifier"!==t.type||!("window"===t.name||"globalThis"===t.name&&qs(e,"globalThis")))&&!Ws(e,t)}(r,n.object)){const r=$s(n);Vs(r)&&e.report({node:t,messageId:"unexpected",data:{name:r}})}}})},zs={meta:{type:"suggestion",docs:{description:"disallow `Array` constructors",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/no-array-constructor"},schema:[],messages:{preferLiteral:"The array literal notation [] is preferable."}},create(e){function t(t){1!==t.arguments.length&&"Identifier"===t.callee.type&&"Array"===t.callee.name&&e.report({node:t,messageId:"preferLiteral"})}return{CallExpression:t,NewExpression:t}}},Js={meta:{type:"problem",docs:{description:"disallow using an async function as a Promise executor",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-async-promise-executor"},fixable:null,schema:[],messages:{async:"Promise executor functions should not be async."}},create:e=>({"NewExpression[callee.name='Promise'][arguments.0.async=true]"(t){e.report({node:e.getSourceCode().getFirstToken(t.arguments[0],(e=>"async"===e.value)),messageId:"async"})}})};function Ks(e){const t=e.type;return"FunctionDeclaration"===t||"FunctionExpression"===t||"ArrowFunctionExpression"===t||"ForOfStatement"===t&&!0===e.await}function Ys(e,t){switch(t.type){case"ForStatement":return e===t.test||e===t.update||e===t.body;case"ForOfStatement":case"ForInStatement":return e===t.body;case"WhileStatement":case"DoWhileStatement":return e===t.test||e===t.body;default:return!1}}var Hs={meta:{type:"problem",docs:{description:"disallow `await` inside of loops",category:"Possible Errors",recommended:!1,url:"https://eslint.org/docs/rules/no-await-in-loop"},schema:[],messages:{unexpectedAwait:"Unexpected `await` inside a loop."}},create(e){function t(t){if("ForOfStatement"===t.type&&!t.await)return;let n=t,r=n.parent;for(;r&&!Ks(r);){if(Ys(n,r))return void e.report({node:t,messageId:"unexpectedAwait"});n=r,r=r.parent}}return{AwaitExpression:t,ForOfStatement:t}}};const Xs=["^","|","&","<<",">>",">>>","^=","|=","&=","<<=",">>=",">>>=","~"];var Qs={meta:{type:"suggestion",docs:{description:"disallow bitwise operators",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/no-bitwise"},schema:[{type:"object",properties:{allow:{type:"array",items:{enum:Xs},uniqueItems:!0},int32Hint:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{unexpected:"Unexpected use of '{{operator}}'."}},create(e){const t=e.options[0]||{},n=t.allow||[],r=!0===t.int32Hint;function o(t){!function(e){return-1!==Xs.indexOf(e.operator)}(t)||function(e){return-1!==n.indexOf(e.operator)}(t)||function(e){return r&&"|"===e.operator&&e.right&&"Literal"===e.right.type&&0===e.right.value}(t)||function(t){e.report({node:t,messageId:"unexpected",data:{operator:t.operator}})}(t)}return{AssignmentExpression:o,BinaryExpression:o,UnaryExpression:o}}},Zs={meta:{deprecated:!0,replacedBy:[],type:"problem",docs:{description:"disallow use of the `Buffer()` constructor",category:"Node.js and CommonJS",recommended:!1,url:"https://eslint.org/docs/rules/no-buffer-constructor"},schema:[],messages:{deprecated:"{{expr}} is deprecated. Use Buffer.from(), Buffer.alloc(), or Buffer.allocUnsafe() instead."}},create:e=>({"CallExpression[callee.name='Buffer'], NewExpression[callee.name='Buffer']"(t){e.report({node:t,messageId:"deprecated",data:{expr:"CallExpression"===t.type?"Buffer()":"new Buffer()"}})}})},ea={meta:{type:"suggestion",docs:{description:"disallow the use of `arguments.caller` or `arguments.callee`",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-caller"},schema:[],messages:{unexpected:"Avoid arguments.{{prop}}."}},create:e=>({MemberExpression(t){const n=t.object.name,r=t.property.name;"arguments"===n&&!t.computed&&r&&r.match(/^calle[er]$/u)&&e.report({node:t,messageId:"unexpected",data:{prop:r}})}})},ta={meta:{type:"suggestion",docs:{description:"disallow lexical declarations in case clauses",category:"Best Practices",recommended:!0,url:"https://eslint.org/docs/rules/no-case-declarations"},schema:[],messages:{unexpected:"Unexpected lexical declaration in case block."}},create(e){function t(e){switch(e.type){case"FunctionDeclaration":case"ClassDeclaration":return!0;case"VariableDeclaration":return"var"!==e.kind;default:return!1}}return{SwitchCase(n){for(let r=0;r({"CatchClause[param!=null]"(t){let n=e.getScope();n.block===t&&(n=n.upper),function(e,t){return null!==fr.getVariableByName(e,t)}(n,t.param.name)&&e.report({node:t,messageId:"mutable",data:{name:t.param.name}})}})},ra={meta:{type:"problem",docs:{description:"disallow reassigning class members",category:"ECMAScript 6",recommended:!0,url:"https://eslint.org/docs/rules/no-class-assign"},schema:[],messages:{class:"'{{name}}' is a class."}},create(e){function t(t){fr.getModifyingReferences(t.references).forEach((t=>{e.report({node:t.identifier,messageId:"class",data:{name:t.identifier.name}})}))}function n(n){e.getDeclaredVariables(n).forEach(t)}return{ClassDeclaration:n,ClassExpression:n}}},oa={meta:{type:"problem",docs:{description:"disallow comparing against -0",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-compare-neg-zero"},fixable:null,schema:[],messages:{unexpected:"Do not use the '{{operator}}' operator to compare against -0."}},create(e){function t(e){return"UnaryExpression"===e.type&&"-"===e.operator&&"Literal"===e.argument.type&&0===e.argument.value}const n=new Set([">",">=","<","<=","==","===","!=","!=="]);return{BinaryExpression(r){n.has(r.operator)&&(t(r.left)||t(r.right))&&e.report({node:r,messageId:"unexpected",data:{operator:r.operator}})}}}};const sa=new Set(["IfStatement","WhileStatement","DoWhileStatement","ForStatement","ConditionalExpression"]),aa={DoWhileStatement:"a 'do...while' statement",ForStatement:"a 'for' statement",IfStatement:"an 'if' statement",WhileStatement:"a 'while' statement"};var ia={meta:{type:"problem",docs:{description:"disallow assignment operators in conditional expressions",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-cond-assign"},schema:[{enum:["except-parens","always"]}],messages:{unexpected:"Unexpected assignment within {{type}}.",missing:"Expected a conditional expression and instead saw an assignment."}},create(e){const t=e.options[0]||"except-parens",n=e.getSourceCode();function r(e){return e.parent&&sa.has(e.parent.type)&&e===e.parent.test}function o(t){!t.test||"AssignmentExpression"!==t.test.type||("ForStatement"===t.type?fr.isParenthesised(n,t.test):function(e){const t=n.getTokenBefore(e,1),r=n.getTokenAfter(e,1);return fr.isParenthesised(n,e)&&t&&fr.isOpeningParenToken(t)&&t.range[1]<=e.range[0]&&fr.isClosingParenToken(r)&&r.range[0]>=e.range[1]}(t.test))||e.report({node:t.test,messageId:"missing"})}return"always"===t?{AssignmentExpression:function(t){const n=function(e){let t=e;do{if(r(t))return t.parent}while((t=t.parent)&&!fr.isFunction(t));return null}(t);n&&e.report({node:t,messageId:"unexpected",data:{type:aa[n.type]||n.type}})}}:{DoWhileStatement:o,ForStatement:o,IfStatement:o,WhileStatement:o,ConditionalExpression:o}}};var ca={meta:{type:"suggestion",docs:{description:"disallow arrow functions where they could be confused with comparisons",category:"ECMAScript 6",recommended:!1,url:"https://eslint.org/docs/rules/no-confusing-arrow"},fixable:"code",schema:[{type:"object",properties:{allowParens:{type:"boolean",default:!0}},additionalProperties:!1}],messages:{confusing:"Arrow function used ambiguously with a conditional expression."}},create(e){const t=e.options[0]||{},n=t.allowParens||void 0===t.allowParens,r=e.getSourceCode();return{ArrowFunctionExpression:function(t){const o=t.body;!function(e){return e&&"ConditionalExpression"===e.type}(o)||n&&fr.isParenthesised(r,o)||e.report({node:t,messageId:"confusing",fix:e=>n&&e.replaceText(t.body,`(${r.getText(t.body)})`)})}}}},la={meta:{type:"suggestion",docs:{description:"disallow the use of `console`",category:"Possible Errors",recommended:!1,url:"https://eslint.org/docs/rules/no-console"},schema:[{type:"object",properties:{allow:{type:"array",items:{type:"string"},minItems:1,uniqueItems:!0}},additionalProperties:!1}],messages:{unexpected:"Unexpected console statement."}},create(e){const t=(e.options[0]||{}).allow||[];function n(e){const t=e.identifier;return t&&"console"===t.name}function r(e){const n=e.identifier,r=n.parent;return"MemberExpression"===r.type&&r.object===n&&!function(e){const n=fr.getStaticPropertyName(e);return n&&-1!==t.indexOf(n)}(r)}function o(t){const n=t.identifier.parent;e.report({node:n,loc:n.loc,messageId:"unexpected"})}return{"Program:exit"(){const t=e.getScope(),s=fr.getVariableByName(t,"console"),a=s&&s.defs.length>0,i=s?s.references:t.through.filter(n);a||i.filter(r).forEach(o)}}}},ua={meta:{type:"problem",docs:{description:"disallow reassigning `const` variables",category:"ECMAScript 6",recommended:!0,url:"https://eslint.org/docs/rules/no-const-assign"},schema:[],messages:{const:"'{{name}}' is constant."}},create(e){function t(t){fr.getModifyingReferences(t.references).forEach((t=>{e.report({node:t.identifier,messageId:"const",data:{name:t.identifier.name}})}))}return{VariableDeclaration(n){"const"===n.kind&&e.getDeclaredVariables(n).forEach(t)}}}},pa={meta:{type:"problem",docs:{description:"disallow constant expressions in conditions",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-constant-condition"},schema:[{type:"object",properties:{checkLoops:{type:"boolean",default:!0}},additionalProperties:!1}],messages:{unexpected:"Unexpected constant condition."}},create(e){const t=!1!==(e.options[0]||{}).checkLoops,n=[];let r=new Set;function o(e){return null===e.value?"null"!==e.raw&&("object"==typeof e.regex||null):!!e.value}function s(e,t){switch(e.type){case"Literal":return"||"===t&&!0===o(e)||"&&"===t&&!1===o(e);case"UnaryExpression":return"&&"===t&&"void"===e.operator;case"LogicalExpression":return t===e.operator&&(s(e.left,t)||s(e.right,t));case"AssignmentExpression":return["||=","&&="].includes(e.operator)&&t===e.operator.slice(0,-1)&&s(e.right,t)}return!1}function a(e,t){if(!e)return!0;switch(e.type){case"Literal":case"ArrowFunctionExpression":case"FunctionExpression":case"ObjectExpression":return!0;case"TemplateLiteral":return t&&e.quasis.some((e=>e.value.cooked.length))||e.expressions.every((e=>a(e,t)));case"ArrayExpression":return"BinaryExpression"!==e.parent.type||"+"!==e.parent.operator||e.elements.every((e=>a(e,!1)));case"UnaryExpression":return!!("void"===e.operator||"typeof"===e.operator&&t)||("!"===e.operator?a(e.argument,!0):a(e.argument,!1));case"BinaryExpression":return a(e.left,!1)&&a(e.right,!1)&&"in"!==e.operator;case"LogicalExpression":{const n=a(e.left,t),r=a(e.right,t),o=n&&s(e.left,e.operator),i=t&&r&&s(e.right,e.operator);return n&&r||o||i}case"AssignmentExpression":return"="===e.operator?a(e.right,t):!(!["||=","&&="].includes(e.operator)||!t)&&s(e.right,e.operator.slice(0,-1));case"SequenceExpression":return a(e.expressions[e.expressions.length-1],t)}return!1}function i(t){r.has(t)&&(r.delete(t),e.report({node:t.test,messageId:"unexpected"}))}function c(t){t.test&&a(t.test,!0)&&e.report({node:t.test,messageId:"unexpected"})}function l(){n.push(r),r=new Set}function u(){r=n.pop()}function p(e){t&&function(e){e.test&&a(e.test,!0)&&r.add(e)}(e)}return{ConditionalExpression:c,IfStatement:c,WhileStatement:p,"WhileStatement:exit":i,DoWhileStatement:p,"DoWhileStatement:exit":i,ForStatement:p,"ForStatement > .test":e=>p(e.parent),"ForStatement:exit":i,FunctionDeclaration:l,"FunctionDeclaration:exit":u,FunctionExpression:l,"FunctionExpression:exit":u,YieldExpression:()=>r.clear()}}},da={meta:{type:"problem",docs:{description:"disallow returning value from constructor",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-constructor-return"},schema:{},fixable:null,messages:{unexpected:"Unexpected return statement in constructor."}},create(e){const t=[];return{onCodePathStart(e,n){t.push(n)},onCodePathEnd(){t.pop()},ReturnStatement(n){const r=t[t.length-1];r.parent&&("MethodDefinition"!==r.parent.type||"constructor"!==r.parent.kind||n.parent.parent!==r&&!n.argument||e.report({node:n,messageId:"unexpected"}))}}}},fa={meta:{type:"suggestion",docs:{description:"disallow `continue` statements",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/no-continue"},schema:[],messages:{unexpected:"Unexpected use of continue statement."}},create:e=>({ContinueStatement(t){e.report({node:t,messageId:"unexpected"})}})};const ma=X.default.RegExpValidator,ga=new class{constructor(){this._source="",this._controlChars=[],this._validator=new ma(this)}onPatternEnter(){this._controlChars=[]}onCharacter(e,t,n){n>=0&&n<=31&&(this._source.codePointAt(e)===n||this._source.slice(e,t).startsWith("\\x")||this._source.slice(e,t).startsWith("\\u"))&&this._controlChars.push(`\\x${`0${n.toString(16)}`.slice(-2)}`)}collectControlChars(e){try{this._source=e,this._validator.validatePattern(e)}catch{}return this._controlChars}};var ha={meta:{type:"problem",docs:{description:"disallow control characters in regular expressions",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-control-regex"},schema:[],messages:{unexpected:"Unexpected control character(s) in regular expression: {{controlChars}}."}},create:e=>({Literal(t){const n=function(e){return e.regex?e.regex.pattern:"string"!=typeof e.value||"NewExpression"!==e.parent.type&&"CallExpression"!==e.parent.type||"Identifier"!==e.parent.callee.type||"RegExp"!==e.parent.callee.name||e.parent.arguments[0]!==e?null:e.value}(t);if(n){const r=ga.collectControlChars(n);r.length>0&&e.report({node:t,messageId:"unexpected",data:{controlChars:r.join(", ")}})}}})},ya={meta:{type:"problem",docs:{description:"disallow the use of `debugger`",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-debugger"},fixable:null,schema:[],messages:{unexpected:"Unexpected 'debugger' statement."}},create:e=>({DebuggerStatement(t){e.report({node:t,messageId:"unexpected"})}})},xa={meta:{type:"suggestion",docs:{description:"disallow deleting variables",category:"Variables",recommended:!0,url:"https://eslint.org/docs/rules/no-delete-var"},schema:[],messages:{unexpected:"Variables should not be deleted."}},create:e=>({UnaryExpression(t){"delete"===t.operator&&"Identifier"===t.argument.type&&e.report({node:t,messageId:"unexpected"})}})},ba={meta:{type:"suggestion",docs:{description:"disallow division operators explicitly at the beginning of regular expressions",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-div-regex"},fixable:"code",schema:[],messages:{unexpected:"A regular expression literal can be confused with '/='."}},create(e){const t=e.getSourceCode();return{Literal(n){const r=t.getFirstToken(n);"RegularExpression"===r.type&&"="===r.value[1]&&e.report({node:n,messageId:"unexpected",fix:e=>e.replaceTextRange([r.range[0]+1,r.range[0]+2],"[=]")})}}}},Ea={meta:{type:"problem",docs:{description:"disallow duplicate arguments in `function` definitions",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-dupe-args"},schema:[],messages:{unexpected:"Duplicate param '{{name}}'."}},create(e){function t(e){return"Parameter"===e.type}function n(n){const r=e.getDeclaredVariables(n);for(let o=0;o=2&&e.report({node:n,messageId:"unexpected",data:{name:s.name}})}}return{FunctionDeclaration:n,FunctionExpression:n}}},Sa={meta:{type:"problem",docs:{description:"disallow duplicate class members",category:"ECMAScript 6",recommended:!0,url:"https://eslint.org/docs/rules/no-dupe-class-members"},schema:[],messages:{unexpected:"Duplicate name '{{name}}'."}},create(e){let t=[];return{Program(){t=[]},ClassBody(){t.push(Object.create(null))},"ClassBody:exit"(){t.pop()},MethodDefinition(n){const r=fr.getStaticPropertyName(n);if(null===r||"constructor"===n.kind)return;const o=function(e,n){const r=t[t.length-1],o=`$${e}`;return r[o]||(r[o]={nonStatic:{init:!1,get:!1,set:!1},static:{init:!1,get:!1,set:!1}}),r[o][n?"static":"nonStatic"]}(r,n.static);let s=!1;"get"===n.kind?(s=o.init||o.get,o.get=!0):"set"===n.kind?(s=o.init||o.set,o.set=!0):(s=o.init||o.get||o.set,o.init=!0),s&&e.report({node:n,messageId:"unexpected",data:{name:r}})}}}};function Ca(e,t,n){return t.every((t=>n.some((n=>e(t,n)))))}function va(e,t){return"LogicalExpression"===t.type&&t.operator===e?[...va(e,t.left),...va(e,t.right)]:[t]}const Aa=va.bind(null,"||"),ka=va.bind(null,"&&");var wa={meta:{type:"problem",docs:{description:"disallow duplicate conditions in if-else-if chains",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-dupe-else-if"},schema:[],messages:{unexpected:"This branch can never execute. Its condition is a duplicate or covered by previous conditions in the if-else-if chain."}},create(e){const t=e.getSourceCode();const n=Ca.bind(null,(function e(n,r){return n.type===r.type&&("LogicalExpression"!==n.type||"||"!==n.operator&&"&&"!==n.operator||n.operator!==r.operator?fr.equalTokens(n,r,t):e(n.left,r.left)&&e(n.right,r.right)||e(n.left,r.right)&&e(n.right,r.left))}));return{IfStatement(t){const r=t.test;let o=t,s=("LogicalExpression"===r.type&&"&&"===r.operator?[r,...ka(r)]:[r]).map((e=>Aa(e).map(ka)));for(;o.parent&&"IfStatement"===o.parent.type&&o.parent.alternate===o;){o=o.parent;const t=Aa(o.test).map(ka);if(s=s.map((e=>e.filter((e=>!t.some((t=>n(t,e))))))),s.some((e=>0===e.length))){e.report({node:r,messageId:"unexpected"});break}}}}}};const Pa=/^(?:init|get)$/u,Ta=/^(?:init|set)$/u;class Ia{constructor(e,t){this.upper=e,this.node=t,this.properties=new Map}getPropertyInfo(e){const t=fr.getStaticPropertyName(e);return this.properties.has(t)||this.properties.set(t,{get:!1,set:!1}),this.properties.get(t)}isPropertyDefined(e){const t=this.getPropertyInfo(e);return Pa.test(e.kind)&&t.get||Ta.test(e.kind)&&t.set}defineProperty(e){const t=this.getPropertyInfo(e);Pa.test(e.kind)&&(t.get=!0),Ta.test(e.kind)&&(t.set=!0)}}var Fa={meta:{type:"problem",docs:{description:"disallow duplicate keys in object literals",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-dupe-keys"},schema:[],messages:{unexpected:"Duplicate key '{{name}}'."}},create(e){let t=null;return{ObjectExpression(e){t=new Ia(t,e)},"ObjectExpression:exit"(){t=t.upper},Property(n){const r=fr.getStaticPropertyName(n);"ObjectExpression"===n.parent.type&&null!==r&&(t.isPropertyDefined(n)&&e.report({node:t.node,loc:n.key.loc,messageId:"unexpected",data:{name:r}}),t.defineProperty(n))}}}},Da={meta:{type:"problem",docs:{description:"disallow duplicate case labels",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-duplicate-case"},schema:[],messages:{unexpected:"Duplicate case label."}},create(e){const t=e.getSourceCode();return{SwitchStatement(n){const r=[];for(const o of n.cases)if(o.test){const n=o.test;r.some((e=>{return o=n,(r=e).type===o.type&&fr.equalTokens(r,o,t);var r,o}))?e.report({node:o,messageId:"unexpected"}):r.push(n)}}}}};function Oa(e){return e&&e.source&&e.source.value?e.source.value.trim():""}function Ba(e,t,n,r,o){-1!==r.indexOf(n)&&e.report({node:t,messageId:o,data:{module:n}})}function Na(e,t,n,r){return function(o){const s=Oa(o);s&&(Ba(e,o,s,n,"import"),t&&Ba(e,o,s,r,"importAs"),n.push(s))}}function ja(e,t,n){return function(r){const o=Oa(r);o&&(Ba(e,r,o,n,"export"),Ba(e,r,o,t,"exportAs"),n.push(o))}}var La={meta:{type:"problem",docs:{description:"disallow duplicate module imports",category:"ECMAScript 6",recommended:!1,url:"https://eslint.org/docs/rules/no-duplicate-imports"},schema:[{type:"object",properties:{includeExports:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{import:"'{{module}}' import is duplicated.",importAs:"'{{module}}' import is duplicated as export.",export:"'{{module}}' export is duplicated.",exportAs:"'{{module}}' export is duplicated as import."}},create(e){const t=(e.options[0]||{}).includeExports,n=[],r=[],o={ImportDeclaration:Na(e,t,n,r)};return t&&(o.ExportNamedDeclaration=ja(e,n,r),o.ExportAllDeclaration=ja(e,n,r)),o}};var Ra=class{constructor(e,t){this.fixer=e,this.sourceCode=t,this.retainedRange=null}retainRange(e){return this.retainedRange=e,this}retainEnclosingFunction(e){const t=fr.getUpperFunction(e);return this.retainRange(t?t.range:this.sourceCode.ast.range)}retainSurroundingTokens(e){const t=this.sourceCode.getTokenBefore(e)||e,n=this.sourceCode.getTokenAfter(e)||e;return this.retainRange([t.range[0],n.range[1]])}replaceTextRange(e,t){let n;return n=this.retainedRange?[Math.min(this.retainedRange[0],e[0]),Math.max(this.retainedRange[1],e[1])]:e,this.fixer.replaceTextRange(n,this.sourceCode.text.slice(n[0],e[0])+t+this.sourceCode.text.slice(e[1],n[1]))}remove(e){return this.replaceTextRange(e.range,"")}},Ma={meta:{type:"suggestion",docs:{description:"disallow `else` blocks after `return` statements in `if` statements",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-else-return"},schema:[{type:"object",properties:{allowElseIf:{type:"boolean",default:!0}},additionalProperties:!1}],fixable:"code",messages:{unexpected:"Unnecessary 'else' after 'return'."}},create(e){function t(t){const n=e.getScope();e.report({node:t,messageId:"unexpected",fix:r=>{if(!function(e,t){if("FunctionDeclaration"===e.type)return!1;if("BlockStatement"!==e.type)return!0;const n=t.childScopes.find((({block:t})=>t===e));return!n||function(e,t){if(0===e.length)return!0;const n=t.variableScope;if(t.variables.filter((({defs:e})=>e.length>0)).some((({name:t})=>e.includes(t))))return!1;if(t!==n&&"catch"===t.upper.type&&t.upper.variables.some((({name:t})=>e.includes(t))))return!1;if(t.variables.filter((({defs:e,references:t})=>0===e.length&&t.length>0)).some((({name:t})=>e.includes(t))))return!1;if(t.through.some((t=>e.includes(t.identifier.name))))return!1;if(t!==n){const r=t.block.range;if(n.variables.filter((({name:t})=>e.includes(t))).some((e=>e.defs.some((({node:{range:e}})=>r[0]<=e[0]&&e[1]<=r[1])))))return!1}return!0}(n.variables.map((({name:e})=>e)),t)}(t,n))return null;const o=e.getSourceCode(),s=o.getFirstToken(t),a=o.getTokenBefore(s),i=o.getText(t),c=o.getTokenBefore(a);let l,u;u="Punctuator"===s.type&&"{"===s.value?o.getTokenAfter(s):s;const p="BlockStatement"!==t.parent.consequent.type&&";"!==c.value,d=/^[([/+`-]/u.test(u.value);if(p&&d)return null;const f=o.getLastToken(t),m=o.getTokenBefore(f);if(";"!==m.value){const e=o.getTokenAfter(f),t=e&&/^[([/+`-]/u.test(e.value),n=e&&e.loc.start.line===m.loc.start.line;if(t||n&&"}"!==e.value)return null}return l="Punctuator"===s.type&&"{"===s.value?i.slice(1,-1):i,new Ra(r,o).retainEnclosingFunction(t).replaceTextRange([a.range[0],t.range[1]],l)}})}function n(e){return"ReturnStatement"===e.type}function r(e){if("BlockStatement"===e.type){const t=e.body,r=t[t.length-1];return r&&n(r)}return n(e)}function o(e){return n(e)||function(e){return"IfStatement"===e.type&&function(e){return e.alternate&&e.consequent}(e)&&r(e.alternate)&&r(e.consequent)}(e)}function s(e){return"BlockStatement"===e.type?e.body.some(o):o(e)}return{"IfStatement:exit":!(e.options[0]&&!1===e.options[0].allowElseIf)?function(e){const n=e.parent;if(!fr.STATEMENT_LIST_PARENTS.has(n.type))return;const r=[];let o;for(let t=e;"IfStatement"===t.type;t=t.alternate){if(!t.alternate)return;r.push(t.consequent),o=t.alternate}r.every(s)&&t(o)}:function(e){const n=e.parent;if(!fr.STATEMENT_LIST_PARENTS.has(n.type))return;const r=e.alternate;r&&s(e.consequent)&&t(r)}}}},_a={meta:{type:"suggestion",docs:{description:"disallow empty block statements",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-empty"},schema:[{type:"object",properties:{allowEmptyCatch:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{unexpected:"Empty {{type}} statement."}},create(e){const t=(e.options[0]||{}).allowEmptyCatch||!1,n=e.getSourceCode();return{BlockStatement(r){0===r.body.length&&(fr.isFunction(r.parent)||t&&"CatchClause"===r.parent.type||n.getCommentsInside(r).length>0||e.report({node:r,messageId:"unexpected",data:{type:"block"}}))},SwitchStatement(t){void 0!==t.cases&&0!==t.cases.length||e.report({node:t,messageId:"unexpected",data:{type:"switch"}})}}}};const $a=/^\/([^\\[]|\\.|\[([^\\\]]|\\.)+\])*\/[gimuys]*$/u;var qa={meta:{type:"problem",docs:{description:"disallow empty character classes in regular expressions",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-empty-character-class"},schema:[],messages:{unexpected:"Empty class."}},create(e){const t=e.getSourceCode();return{Literal(n){const r=t.getFirstToken(n);"RegularExpression"!==r.type||$a.test(r.value)||e.report({node:n,messageId:"unexpected"})}}}};var Ua={meta:{type:"suggestion",docs:{description:"disallow empty functions",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-empty-function"},schema:[{type:"object",properties:{allow:{type:"array",items:{enum:Object.freeze(["functions","arrowFunctions","generatorFunctions","methods","generatorMethods","getters","setters","constructors","asyncFunctions","asyncMethods"])},uniqueItems:!0}},additionalProperties:!1}],messages:{unexpected:"Unexpected empty {{name}}."}},create(e){const t=(e.options[0]||{}).allow||[],n=e.getSourceCode();function r(r){const o=function(e){const t=e.parent;let n="";if("ArrowFunctionExpression"===e.type)return"arrowFunctions";if("Property"===t.type){if("get"===t.kind)return"getters";if("set"===t.kind)return"setters";n=t.method?"methods":"functions"}else if("MethodDefinition"===t.type){if("get"===t.kind)return"getters";if("set"===t.kind)return"setters";if("constructor"===t.kind)return"constructors";n="methods"}else n="functions";let r="";if(e.generator)r="generator";else{if(!e.async)return n;r="async"}return r+n[0].toUpperCase()+n.slice(1)}(r),s=fr.getFunctionNameWithKind(r),a=n.getTokens(r.body,{includeComments:!0,filter:fr.isCommentToken});-1===t.indexOf(o)&&"BlockStatement"===r.body.type&&0===r.body.body.length&&0===a.length&&e.report({node:r,loc:r.body.loc,messageId:"unexpected",data:{name:s}})}return{ArrowFunctionExpression:r,FunctionDeclaration:r,FunctionExpression:r}}},Va={meta:{type:"problem",docs:{description:"disallow empty destructuring patterns",category:"Best Practices",recommended:!0,url:"https://eslint.org/docs/rules/no-empty-pattern"},schema:[],messages:{unexpected:"Unexpected empty {{type}} pattern."}},create:e=>({ObjectPattern(t){0===t.properties.length&&e.report({node:t,messageId:"unexpected",data:{type:"object"}})},ArrayPattern(t){0===t.elements.length&&e.report({node:t,messageId:"unexpected",data:{type:"array"}})}})},Wa={meta:{type:"suggestion",docs:{description:"disallow `null` comparisons without type-checking operators",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-eq-null"},schema:[],messages:{unexpected:"Use '===' to compare with null."}},create:e=>({BinaryExpression(t){const n="=="===t.operator||"!="===t.operator;("Literal"===t.right.type&&"null"===t.right.raw&&n||"Literal"===t.left.type&&"null"===t.left.raw&&n)&&e.report({node:t,messageId:"unexpected"})}})};const Ga=Object.freeze(["global","window","globalThis"]);function za(e,t){return fr.isSpecificMemberAccess(e,null,t)}var Ja={meta:{type:"suggestion",docs:{description:"disallow the use of `eval()`",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-eval"},schema:[{type:"object",properties:{allowIndirect:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{unexpected:"eval can be harmful."}},create(e){const t=Boolean(e.options[0]&&e.options[0].allowIndirect),n=e.getSourceCode();let r=null;function o(t){const n=e.getScope().isStrict;r={upper:r,node:t,strict:n,defaultThis:!1,initialized:n}}function s(){r=r.upper}function a(t){const n=t.parent,r="MemberExpression"===t.type?t.property:t,o="CallExpression"===n.type&&n.callee===t?n:t;e.report({node:o,loc:r.loc,messageId:"unexpected"})}return t?{"CallExpression:exit"(e){const t=e.callee;!e.optional&&fr.isSpecificId(t,"eval")&&a(t)}}:{"CallExpression:exit"(e){const t=e.callee;fr.isSpecificId(t,"eval")&&a(t)},Program(t){const n=e.getScope(),o=e.parserOptions.ecmaFeatures||{},s=n.isStrict||"module"===t.sourceType||o.globalReturn&&n.childScopes[0].isStrict;r={upper:null,node:t,strict:s,defaultThis:!0,initialized:!0}},"Program:exit"(){const t=e.getScope();s(),function(e){const t=fr.getVariableByName(e,"eval");if(!t)return;const n=t.references;for(let e=0;e{e.report({node:t.identifier,messageId:"unexpected"})}))}return{CatchClause(n){e.getDeclaredVariables(n).forEach(t)}}}},Ya={meta:{type:"suggestion",docs:{description:"disallow extending native types",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-extend-native"},schema:[{type:"object",properties:{exceptions:{type:"array",items:{type:"string"},uniqueItems:!0}},additionalProperties:!1}],messages:{unexpected:"{{builtin}} prototype is read only, properties should not be added."}},create(e){const t=e.options[0]||{},n=new Set(t.exceptions||[]),r=new Set(Object.keys(U.default.builtin).filter((e=>e[0].toUpperCase()===e[0])).filter((e=>!n.has(e))));function o(t,n){e.report({node:t,messageId:"unexpected",data:{builtin:n}})}function s(e){if(!function(e){return Boolean(e&&e.parent&&"MemberExpression"===e.parent.type&&e.parent.object===e&&"prototype"===fr.getStaticPropertyName(e.parent))}(e))return;const t="ChainExpression"===e.parent.parent.type?e.parent.parent:e.parent;var n;"MemberExpression"===(n=t).parent.type&&n.parent.object===n&&"AssignmentExpression"===n.parent.parent.type&&n.parent.parent.left===n.parent?o(t.parent.parent,e.name):function(e){return"CallExpression"===e.parent.type&&e.parent.arguments[0]===e&&fr.isSpecificMemberAccess(e.parent.callee,"Object",/^definePropert(?:y|ies)$/u)}(t)&&o(t.parent,e.name)}return{"Program:exit"(){const t=e.getScope();r.forEach((e=>{const n=t.set.get(e);n&&n.references&&n.references.map((e=>e.identifier)).forEach(s)}))}}}};const Ha=new Set(["Literal","Identifier","ThisExpression","FunctionExpression"]);var Xa={meta:{type:"suggestion",docs:{description:"disallow unnecessary calls to `.bind()`",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-extra-bind"},schema:[],fixable:"code",messages:{unexpected:"The function binding is unnecessary."}},create(e){const t=e.getSourceCode();let n=null;function r(n){const r=n.parent,o="ChainExpression"===r.parent.type?r.parent.parent:r.parent;e.report({node:o,messageId:"unexpected",loc:r.property.loc,fix(e){if(!function(e){return Ha.has(e.type)}(o.arguments[0]))return null;const n=[[t.getTokenAfter(r.object,fr.isNotClosingParenToken),t.getLastToken(r)],[t.getTokenAfter(r,fr.isNotClosingParenToken),t.getLastToken(o)]],s=n[0][0],a=n[1][1];return t.commentsExistBetween(s,a)?null:n.map((([t,n])=>e.removeRange([t.range[0],n.range[1]])))}})}function o(e){if(!fr.isSpecificMemberAccess(e.parent,null,"bind"))return!1;const t="ChainExpression"===e.parent.parent.type?e.parent.parent:e.parent;return"CallExpression"===t.parent.type&&t.parent.callee===t&&1===t.parent.arguments.length&&"SpreadElement"!==t.parent.arguments[0].type}function s(e){n={isBound:o(e),thisFound:!1,upper:n}}function a(e){n.isBound&&!n.thisFound&&r(e),n=n.upper}return{"ArrowFunctionExpression:exit":function(e){o(e)&&r(e)},FunctionDeclaration:s,"FunctionDeclaration:exit":a,FunctionExpression:s,"FunctionExpression:exit":a,ThisExpression:function(){n&&(n.thisFound=!0)}}}};const Qa=fr.getPrecedence;var Za={meta:{type:"suggestion",docs:{description:"disallow unnecessary boolean casts",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-extra-boolean-cast"},schema:[{type:"object",properties:{enforceForLogicalOperands:{type:"boolean",default:!1}},additionalProperties:!1}],fixable:"code",messages:{unexpectedCall:"Redundant Boolean call.",unexpectedNegation:"Redundant double negation."}},create(e){const t=e.getSourceCode(),n=["IfStatement","DoWhileStatement","WhileStatement","ConditionalExpression","ForStatement"];function r(t){return"ChainExpression"===t.parent.type?r(t.parent):function(e){return function(e){return("CallExpression"===e.type||"NewExpression"===e.type)&&"Identifier"===e.callee.type&&"Boolean"===e.callee.name}(e.parent)&&e===e.parent.arguments[0]||-1!==n.indexOf(e.parent.type)&&e===e.parent.test||"UnaryExpression"===e.parent.type&&"!"===e.parent.operator}(t)||function(t){return"LogicalExpression"===t.type&&("||"===t.operator||"&&"===t.operator)&&e.options.length&&!0===e.options[0].enforceForLogicalOperands}(t.parent)&&r(t.parent)}function o(e){return Boolean(t.getCommentsInside(e).length)}function s(e,n){if("ChainExpression"===e.parent.type)return s(e.parent,n);if(function(e){return G.default.isParenthesized(1,e,t)}(e))return!1;const r=e.parent;switch(r.type){case"CallExpression":case"NewExpression":return"SequenceExpression"===n.type;case"IfStatement":case"DoWhileStatement":case"WhileStatement":case"ForStatement":return!1;case"ConditionalExpression":return Qa(n)<=Qa(r);case"UnaryExpression":return Qa(n)=t||b(e)))}function v(e){return s&&"AssignmentExpression"===e.test.type}function A(e){const n=t.getLastToken(e),r=t.getTokenBefore(n);return e.arguments.length>0||fr.isOpeningParenToken(r)&&fr.isClosingParenToken(n)&&e.callee.range[1]C(e,f))).forEach(F)}function N(e){const t=r(e),n=r(e.left),o=r(e.right),s="**"===e.operator,i=a&&("BinaryExpression"===e.left.type||"LogicalExpression"===e.left.type),c=a&&("BinaryExpression"===e.right.type||"LogicalExpression"===e.right.type);!i&&E(e.left)&&((["AwaitExpression","UnaryExpression"].includes(e.left.type)&&s||fr.isMixedLogicalAndCoalesceExpressions(e.left,e)||!(n>t||n===t&&!s))&&!b(e.left)||F(e.left)),!c&&E(e.right)&&(!fr.isMixedLogicalAndCoalesceExpressions(e.right,e)&&(o>t||o===t&&s)||b(e.right))&&F(e.right)}function j(e){if(!e.superClass)return;(r(e.superClass)>m?E(e.superClass):S(e.superClass))&&F(e.superClass)}function L(e){C(e.argument,f)&&F(e.argument)}function R(e){const r=x(e)?t.getTokenBefore(e):t.getFirstToken(e),o=t.getTokenAfter(r,fr.isNotOpeningParenToken),s=o?t.getTokenAfter(o):null,a=o?t.getTokenAfter(o,fr.isNotClosingParenToken):null;fr.isOpeningParenToken(r)&&(fr.isOpeningBraceToken(o)||"Keyword"===o.type&&("function"===o.value||"class"===o.value||"let"===o.value&&a&&(fr.isOpeningBracketToken(a)||"Identifier"===a.type))||o&&"Identifier"===o.type&&"async"===o.value&&s&&"Keyword"===s.type&&"function"===s.value)&&n.add(o);("ExportDefaultDeclaration"===e.parent.type?C(e,f):E(e))&&F(e)}function M(e,t){return function(e,t){const n=[e];let r=e;for(;r!==t;){if(r=r.parent,null===r)throw new Error("Nodes are not in the ancestor-descendant relationship.");n.push(r)}return n}(t,e).reverse()}function _(e,t){switch(e.type){case"ArrayExpression":case"ArrayPattern":case"BlockStatement":case"ObjectExpression":case"ObjectPattern":case"TemplateLiteral":return!0;case"ArrowFunctionExpression":case"FunctionExpression":return e.params.includes(t);case"CallExpression":case"NewExpression":return e.arguments.includes(t);case"MemberExpression":return e.computed&&e.property===t;case"ConditionalExpression":return e.consequent===t;default:return!1}}function $(e){return g.reports.some((t=>t.node===e))}function q(e){return"MemberExpression"===e.type&&("NewExpression"===e.parent.type&&e.parent.callee===e||e.parent.object===e&&q(e.parent))}return{ArrayExpression(e){e.elements.filter((e=>e&&C(e,f))).forEach(F)},ArrayPattern(e){e.elements.filter((e=>I(e)&&E(e))).forEach(F)},ArrowFunctionExpression(e){if(!(w(e)||"ConditionalExpression"===e.body.type&&l||"BlockStatement"===e.body.type)){const r=t.getFirstToken(e.body,fr.isNotOpeningParenToken),o=t.getTokenBefore(r);fr.isOpeningParenToken(o)&&fr.isOpeningBraceToken(r)&&n.add(r),C(e.body,f)&&F(e.body)}},AssignmentExpression(e){I(e.left)&&E(e.left)&&F(e.left),!w(e)&&C(e.right,r(e))&&F(e.right)},BinaryExpression(e){g&&"in"===e.operator&&g.inExpressionNodes.push(e),N(e)},CallExpression:B,ClassBody(e){e.body.filter((e=>"MethodDefinition"===e.type&&e.computed&&e.key)).filter((e=>C(e.key,f))).forEach((e=>F(e.key)))},ConditionalExpression(e){w(e)||(!v(e)&&C(e.test,r({type:"LogicalExpression",operator:"||"}))&&F(e.test),C(e.consequent,f)&&F(e.consequent),C(e.alternate,f)&&F(e.alternate))},DoWhileStatement(e){E(e.test)&&!v(e)&&F(e.test)},ExportDefaultDeclaration:e=>R(e.declaration),ExpressionStatement:e=>R(e.expression),ForInStatement(e){if("VariableDeclaration"!==e.left.type){const r=t.getFirstToken(e.left,fr.isNotOpeningParenToken);"let"===r.value&&fr.isOpeningBracketToken(t.getTokenAfter(r,fr.isNotClosingParenToken))&&n.add(r)}E(e.left)&&F(e.left),E(e.right)&&F(e.right)},ForOfStatement(e){if("VariableDeclaration"!==e.left.type){const r=t.getFirstToken(e.left,fr.isNotOpeningParenToken);"let"===r.value&&n.add(r)}E(e.left)&&F(e.left),C(e.right,f)&&F(e.right)},ForStatement(e){if(e.test&&E(e.test)&&!v(e)&&F(e.test),e.update&&E(e.update)&&F(e.update),e.init){if("VariableDeclaration"!==e.init.type){const r=t.getFirstToken(e.init,fr.isNotOpeningParenToken);"let"===r.value&&fr.isOpeningBracketToken(t.getTokenAfter(r,fr.isNotClosingParenToken))&&n.add(r)}g={upper:g,inExpressionNodes:[],reports:[]},E(e.init)&&F(e.init)}},"ForStatement > *.init:exit"(e){g.reports.length&&g.inExpressionNodes.forEach((t=>{const n=M(e,t);let r;for(let e=0;et.node!==e))}(r)})),function(){const{upper:e,inExpressionNodes:t,reports:n}=g;e?(e.inExpressionNodes.push(...t),e.reports.push(...n)):n.forEach((({finishReport:e})=>e())),g=e}()},IfStatement(e){E(e.test)&&!v(e)&&F(e.test)},ImportExpression(e){const{source:t}=e;"SequenceExpression"===t.type?S(t)&&F(t):E(t)&&F(t)},LogicalExpression:N,MemberExpression(e){const t=q(e)&&O(e)?S(e.object):E(e.object)&&!(h(e.parent)&&e.parent.callee===e&&d);t&&r(e.object)>=r(e)&&(e.computed||!(fr.isDecimalInteger(e.object)||"Literal"===e.object.type&&e.object.regex))&&F(e.object),t&&"CallExpression"===e.object.type&&F(e.object),t&&!p&&"NewExpression"===e.object.type&&A(e.object)&&F(e.object),t&&e.optional&&"ChainExpression"===e.object.type&&F(e.object),e.computed&&E(e.property)&&F(e.property)},NewExpression:B,ObjectExpression(e){e.properties.filter((e=>e.value&&C(e.value,f))).forEach((e=>F(e.value)))},ObjectPattern(e){e.properties.filter((e=>{const t=e.value;return I(t)&&E(t)})).forEach((e=>F(e.value)))},Property(e){if(e.computed){const{key:t}=e;t&&C(t,f)&&F(t)}},RestElement(e){const t=e.argument;I(t)&&E(t)&&F(t)},ReturnStatement(e){const n=t.getFirstToken(e);w(e)||!e.argument||!P(n,e.argument)||"Literal"===e.argument.type&&e.argument.regex||F(e.argument)},SequenceExpression(e){const t=r(e);e.expressions.filter((e=>C(e,t))).forEach(F)},SwitchCase(e){e.test&&E(e.test)&&F(e.test)},SwitchStatement(e){E(e.discriminant)&&F(e.discriminant)},ThrowStatement(e){P(t.getFirstToken(e),e.argument)&&F(e.argument)},UnaryExpression:D,UpdateExpression(e){if(e.prefix)D(e);else{const{argument:n}=e,r=t.getLastToken(e);n.loc.end.line===r.loc.start.line?D(e):S(n)&&F(n)}},AwaitExpression:D,VariableDeclarator(e){!e.init||!C(e.init,f)||"Literal"===e.init.type&&e.init.regex||F(e.init)},WhileStatement(e){E(e.test)&&!v(e)&&F(e.test)},WithStatement(e){E(e.object)&&F(e.object)},YieldExpression(e){if(e.argument){const n=t.getFirstToken(e);(r(e.argument)>=r(e)&&P(n,e.argument)||S(e.argument))&&F(e.argument)}},ClassDeclaration:j,ClassExpression:j,SpreadElement:L,SpreadProperty:L,ExperimentalSpreadProperty:L,TemplateLiteral(e){e.expressions.filter((e=>e&&E(e))).forEach(F)},AssignmentPattern(e){const{left:t,right:n}=e;I(t)&&E(t)&&F(t),n&&C(n,f)&&F(n)}}}},ri={meta:{type:"suggestion",docs:{description:"disallow unnecessary semicolons",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-extra-semi"},fixable:"code",schema:[],messages:{unexpected:"Unnecessary semicolon."}},create(e){const t=e.getSourceCode();function n(t){e.report({node:t,messageId:"unexpected",fix:n=>new Ra(n,e.getSourceCode()).retainSurroundingTokens(t).remove(t)})}function r(e){for(let r=e;"Punctuator"===r.type&&!fr.isClosingBraceToken(r);r=t.getTokenAfter(r))fr.isSemicolonToken(r)&&n(r)}return{EmptyStatement(e){const t=e.parent;-1===["ForStatement","ForInStatement","ForOfStatement","WhileStatement","DoWhileStatement","IfStatement","LabeledStatement","WithStatement"].indexOf(t.type)&&n(e)},ClassBody(e){r(t.getFirstToken(e,1))},MethodDefinition(e){r(t.getTokenAfter(e))}}}};const oi=/falls?\s?through/iu;function si(e){return e.reachable}var ai={meta:{type:"problem",docs:{description:"disallow fallthrough of `case` statements",category:"Best Practices",recommended:!0,url:"https://eslint.org/docs/rules/no-fallthrough"},schema:[{type:"object",properties:{commentPattern:{type:"string",default:""}},additionalProperties:!1}],messages:{case:"Expected a 'break' statement before 'case'.",default:"Expected a 'break' statement before 'default'."}},create(e){const t=e.options[0]||{};let n=null;const r=e.getSourceCode();let o=null,s=null;return s=t.commentPattern?new RegExp(t.commentPattern,"u"):oi,{onCodePathStart(e){n=e},onCodePathEnd(){n=n.upper},SwitchCase(t){o&&!function(e,t,n){const r=t.getSourceCode(),o=F.default.last(r.getCommentsBefore(e));return Boolean(o&&n.test(o.value))}(t,e,s)&&e.report({messageId:t.test?"case":"default",node:t}),o=null},"SwitchCase:exit"(e){const t=r.getTokenAfter(e);n.currentSegments.some(si)&&(e.consequent.length>0||function(e,t){return t.loc.start.line>e.loc.end.line+1}(e,t))&&F.default.last(e.parent.cases)!==e&&(o=e)}}}},ii={meta:{type:"suggestion",docs:{description:"disallow leading or trailing decimal points in numeric literals",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-floating-decimal"},schema:[],fixable:"code",messages:{leading:"A leading decimal point can be confused with a dot.",trailing:"A trailing decimal point can be confused with a dot."}},create(e){const t=e.getSourceCode();return{Literal(n){"number"==typeof n.value&&(n.raw.startsWith(".")&&e.report({node:n,messageId:"leading",fix(e){const r=t.getTokenBefore(n),o=r&&r.range[1]===n.range[0]&&!fr.canTokensBeAdjacent(r,`0${n.raw}`);return e.insertTextBefore(n,o?" 0":"0")}}),n.raw.indexOf(".")===n.raw.length-1&&e.report({node:n,messageId:"trailing",fix:e=>e.insertTextAfter(n,"0")}))}}}},ci={meta:{type:"problem",docs:{description:"disallow reassigning `function` declarations",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-func-assign"},schema:[],messages:{isAFunction:"'{{name}}' is a function."}},create(e){function t(t){var n;"FunctionName"===t.defs[0].type&&(n=t.references,fr.getModifyingReferences(n).forEach((t=>{e.report({node:t.identifier,messageId:"isAFunction",data:{name:t.identifier.name}})})))}function n(n){e.getDeclaredVariables(n).forEach(t)}return{FunctionDeclaration:n,FunctionExpression:n}}},li={meta:{type:"suggestion",docs:{description:"disallow assignments to native objects or read-only global variables",category:"Best Practices",recommended:!0,url:"https://eslint.org/docs/rules/no-global-assign"},schema:[{type:"object",properties:{exceptions:{type:"array",items:{type:"string"},uniqueItems:!0}},additionalProperties:!1}],messages:{globalShouldNotBeModified:"Read-only global '{{name}}' should not be modified."}},create(e){const t=e.options[0],n=t&&t.exceptions||[];function r(t,n,r){const o=t.identifier;!1!==t.init||!t.isWrite()||0!==n&&r[n-1].identifier===o||e.report({node:o,messageId:"globalShouldNotBeModified",data:{name:o.name}})}function o(e){!1===e.writeable&&-1===n.indexOf(e.name)&&e.references.forEach(r)}return{Program(){e.getScope().variables.forEach(o)}}}};const ui=/^(?:i|lastI)ndexOf$/u;function pi(e){return"Literal"===e.type&&"number"==typeof e.value||"CallExpression"===e.type&&("Number"===e.callee.name||"parseInt"===e.callee.name||"parseFloat"===e.callee.name)}function di(e){return fr.isStringLiteral(e)&&(""===e.value||"TemplateLiteral"===e.type&&1===e.quasis.length&&""===e.quasis[0].value.cooked)}function fi(e){return di(e.left)?e.right:e.left}var mi={meta:{type:"suggestion",docs:{description:"disallow shorthand type conversions",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-implicit-coercion"},fixable:"code",schema:[{type:"object",properties:{boolean:{type:"boolean",default:!0},number:{type:"boolean",default:!0},string:{type:"boolean",default:!0},disallowTemplateShorthand:{type:"boolean",default:!1},allow:{type:"array",items:{enum:["~","!!","+","*"]},uniqueItems:!0}},additionalProperties:!1}],messages:{useRecommendation:"use `{{recommendation}}` instead."}},create(e){const t=function(e){return{boolean:!("boolean"in e)||e.boolean,number:!("number"in e)||e.number,string:!("string"in e)||e.string,disallowTemplateShorthand:"disallowTemplateShorthand"in e&&e.disallowTemplateShorthand,allow:e.allow||[]}}(e.options[0]||{}),n=e.getSourceCode();function r(t,r,o){e.report({node:t,messageId:"useRecommendation",data:{recommendation:r},fix(e){if(!o)return null;const s=n.getTokenBefore(t);return s&&s.range[1]===t.range[0]&&!fr.canTokensBeAdjacent(s,r)?e.replaceText(t,` ${r}`):e.replaceText(t,r)}})}return{UnaryExpression(e){let o;if(o=t.allow.indexOf("!!")>=0,!o&&t.boolean&&function(e){return"!"===e.operator&&"UnaryExpression"===e.argument.type&&"!"===e.argument.operator}(e)){r(e,`Boolean(${n.getText(e.argument.argument)})`,!0)}if(o=t.allow.indexOf("~")>=0,!o&&t.boolean&&function(e){if("~"!==e.operator)return!1;const t=fr.skipChainExpression(e.argument);return"CallExpression"===t.type&&fr.isSpecificMemberAccess(t.callee,null,ui)}(e)){const t="ChainExpression"===e.argument.type?">= 0":"!== -1";r(e,`${n.getText(e.argument)} ${t}`,!1)}if(o=t.allow.indexOf("+")>=0,!o&&t.number&&"+"===e.operator&&!pi(e.argument)){r(e,`Number(${n.getText(e.argument)})`,!0)}},"BinaryExpression:exit"(e){let o;o=t.allow.indexOf("*")>=0;const s=!o&&t.number&&function(e){return"*"===e.operator&&("Literal"===e.left.type&&1===e.left.value||"Literal"===e.right.type&&1===e.right.value)}(e)&&function(e){const t=e.left,n=e.right;return"BinaryExpression"===n.type||pi(n)?"BinaryExpression"===t.type||pi(t)?null:t:n}(e);if(s){r(e,`Number(${n.getText(s)})`,!0)}if(o=t.allow.indexOf("+")>=0,!o&&t.string&&function(e){return"+"===e.operator&&(di(e.left)&&!fr.isStringLiteral(e.right)||di(e.right)&&!fr.isStringLiteral(e.left))}(e)){r(e,`String(${n.getText(fi(e))})`,!0)}},AssignmentExpression(e){if(!(t.allow.indexOf("+")>=0)&&t.string&&function(e){return"+="===e.operator&&di(e.right)}(e)){const t=n.getText(fi(e));r(e,`${t} = String(${t})`,!0)}},TemplateLiteral(e){if(!t.disallowTemplateShorthand)return;if("TaggedTemplateExpression"===e.parent.type)return;if(1!==e.expressions.length)return;if(""!==e.quasis[0].value.cooked)return;if(""!==e.quasis[1].value.cooked)return;r(e,`String(${n.getText(e.expressions[0])})`,!0)}}}},gi={meta:{type:"suggestion",docs:{description:"disallow declarations in the global scope",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-implicit-globals"},schema:[{type:"object",properties:{lexicalBindings:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{globalNonLexicalBinding:"Unexpected {{kind}} declaration in the global scope, wrap in an IIFE for a local variable, assign as global property for a global variable.",globalLexicalBinding:"Unexpected {{kind}} declaration in the global scope, wrap in a block or in an IIFE.",globalVariableLeak:"Global variable leak, declare the variable if it is intended to be local.",assignmentToReadonlyGlobal:"Unexpected assignment to read-only global variable.",redeclarationOfReadonlyGlobal:"Unexpected redeclaration of read-only global variable."}},create(e){const t=e.options[0]&&!0===e.options[0].lexicalBindings;function n(t,n,r){e.report({node:t,messageId:n,data:{kind:r}})}return{Program(){const r=e.getScope();r.variables.forEach((e=>{const r=!1===e.writeable;!0===e.writeable||e.defs.forEach((e=>{const o=e.node;("FunctionName"===e.type||"Variable"===e.type&&"var"===e.parent.kind)&&(r?n(o,"redeclarationOfReadonlyGlobal"):n(o,"globalNonLexicalBinding","FunctionName"===e.type?"function":`'${e.parent.kind}'`)),t&&("ClassName"!==e.type&&("Variable"!==e.type||"let"!==e.parent.kind&&"const"!==e.parent.kind)||(r?n(o,"redeclarationOfReadonlyGlobal"):n(o,"globalLexicalBinding","ClassName"===e.type?"class":`'${e.parent.kind}'`)))}))})),r.implicit.variables.forEach((e=>{const t=r.set.get(e.name);let o;if(t){if(t.writeable)return;o="assignmentToReadonlyGlobal"}else o="globalVariableLeak";e.defs.forEach((e=>{n(e.node,o)}))}))}}}};const{getStaticValue:hi}=G.default;var yi={meta:{type:"suggestion",docs:{description:"disallow the use of `eval()`-like methods",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-implied-eval"},schema:[],messages:{impliedEval:"Implied eval. Consider passing a function instead of a string."}},create(e){const t=Object.freeze(["global","window","globalThis"]),n=/^(?:set(?:Interval|Timeout)|execScript)$/u;function r(e){return"Literal"===e.type&&"string"==typeof e.value||"TemplateLiteral"===e.type||"BinaryExpression"===e.type&&"+"===e.operator&&(r(e.left)||r(e.right))}function o(t){const[n]=t.arguments;if(n){const o=hi(n,e.getScope());(o&&"string"==typeof o.value||r(n))&&e.report({node:t,messageId:"impliedEval"})}}function s(e){const{references:t,name:r}=e;t.forEach((e=>{let t=e.identifier.parent;for(;fr.isSpecificMemberAccess(t,null,r);)t=t.parent;if(fr.isSpecificMemberAccess(t,null,n)){const e="ChainExpression"===t.parent.type?t.parent:t,n=e.parent;"CallExpression"===n.type&&n.callee===e&&o(n)}}))}return{CallExpression(e){fr.isSpecificId(e.callee,n)&&o(e)},"Program:exit"(){const n=e.getScope();t.map((e=>fr.getVariableByName(n,e))).filter((e=>!!e&&0===e.defs.length)).forEach(s)}}}};const{findVariable:xi}=G.default,bi=/^(?:assign|definePropert(?:y|ies)|freeze|setPrototypeOf)$/u,Ei=/^(?:(?:define|delete)Property|set(?:PrototypeOf)?)$/u;function Si(e,t){const{parent:n}=e;return"MemberExpression"===n.type&&n.object===e&&(function(e){const{parent:t}=e;return"AssignmentExpression"===t.type&&t.left===e||"ArrayPattern"===t.type||"Property"===t.type&&t.value===e&&"ObjectPattern"===t.parent.type||"RestElement"===t.type||"AssignmentPattern"===t.type&&t.left===e}(n)||function(e){const t="ChainExpression"===e.parent.type?e.parent:e,{parent:n}=t;return"UpdateExpression"===n.type&&n.argument===t||"UnaryExpression"===n.type&&"delete"===n.operator&&n.argument===t}(n)||function(e){const{parent:t}=e;return"ForInStatement"===t.type&&t.left===e||"ForOfStatement"===t.type&&t.left===e}(n))||function(e,t){const{parent:n}=e;if("CallExpression"!==n.type||n.arguments[0]!==e)return!1;const r=fr.skipChainExpression(n.callee);if(!fr.isSpecificMemberAccess(r,"Object",bi)&&!fr.isSpecificMemberAccess(r,"Reflect",Ei))return!1;const o=xi(t,r.object);return null!==o&&"global"===o.scope.type}(e,t)}function Ci(e){let t=e.parent;for(;t&&"AssignmentExpression"!==t.type&&"UpdateExpression"!==t.type&&"UnaryExpression"!==t.type&&"CallExpression"!==t.type&&"ForInStatement"!==t.type&&"ForOfStatement"!==t.type;)t=t.parent;return t||e}var vi={meta:{type:"problem",docs:{description:"disallow assigning to imported bindings",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-import-assign"},schema:[],messages:{readonly:"'{{name}}' is read-only.",readonlyMember:"The members of '{{name}}' are read-only."}},create:e=>({ImportDeclaration(t){const n=e.getScope();for(const r of e.getDeclaredVariables(t)){const t=r.defs.some((e=>"ImportNamespaceSpecifier"===e.node.type));let o=null;for(const s of r.references){const r=s.identifier;r!==o&&(o=r,s.isWrite()?e.report({node:Ci(r),messageId:"readonly",data:{name:r.name}}):t&&Si(r,n)&&e.report({node:Ci(r),messageId:"readonlyMember",data:{name:r.name}}))}}}})},Ai={meta:{type:"suggestion",docs:{description:"disallow inline comments after code",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/no-inline-comments"},schema:[{type:"object",properties:{ignorePattern:{type:"string"}},additionalProperties:!1}],messages:{unexpectedInlineComment:"Unexpected comment inline with code."}},create(e){const t=e.getSourceCode(),n=e.options[0];let r;function o(n){const o=String(t.lines[n.loc.start.line-1]),s=String(t.lines[n.loc.end.line-1]),a=o.slice(0,n.loc.start.column).trim(),i=s.slice(n.loc.end.column).trim(),c=!a,l=!i;if(!(c&&l||r&&r.test(n.value))){if((c||"{"===a)&&(l||"}"===i)){const e=t.getNodeByRangeIndex(n.range[0]);if(e&&"JSXEmptyExpression"===e.type)return}fr.isDirectiveComment(n)||e.report({node:n,messageId:"unexpectedInlineComment"})}}return n&&n.ignorePattern&&(r=new RegExp(n.ignorePattern,"u")),{Program(){t.getAllComments().filter((e=>"Shebang"!==e.type)).forEach(o)}}}};const ki=new Set(["Program","ExportNamedDeclaration","ExportDefaultDeclaration"]),wi=new Set(["FunctionDeclaration","FunctionExpression","ArrowFunctionExpression"]);var Pi={meta:{type:"problem",docs:{description:"disallow variable or `function` declarations in nested blocks",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-inner-declarations"},schema:[{enum:["functions","both"]}],messages:{moveDeclToRoot:"Move {{type}} declaration to {{body}} root."}},create(e){function t(t){const n=t.parent;if("BlockStatement"===n.type&&wi.has(n.parent.type))return;if(ki.has(n.type))return;const r=fr.getUpperFunction(n);e.report({node:t,messageId:"moveDeclToRoot",data:{type:"FunctionDeclaration"===t.type?"function":"variable",body:null===r?"program":"function body"}})}return{FunctionDeclaration:t,VariableDeclaration(n){"both"===e.options[0]&&"var"===n.kind&&t(n)}}}};const Ti=new(0,X.default.RegExpValidator),Ii=/[gimuys]/gu;var Fi={meta:{type:"problem",docs:{description:"disallow invalid regular expression strings in `RegExp` constructors",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-invalid-regexp"},schema:[{type:"object",properties:{allowConstructorFlags:{type:"array",items:{type:"string"}}},additionalProperties:!1}],messages:{regexMessage:"{{message}}."}},create(e){const t=e.options[0];let n=null;if(t&&t.allowConstructorFlags){const e=t.allowConstructorFlags.join("").replace(Ii,"");e&&(n=new RegExp(`[${e}]`,"giu"))}function r(e){return e&&"Literal"===e.type&&"string"==typeof e.value}function o(e,t){try{return Ti.validatePattern(e,undefined,undefined,t),null}catch(e){return e.message}}return{"CallExpression, NewExpression"(t){if("Identifier"!==t.callee.type||"RegExp"!==t.callee.name||!r(t.arguments[0]))return;const s=t.arguments[0].value;let a=function(e){return e.arguments.length<2?"":r(e.arguments[1])?e.arguments[1].value:null}(t);a&&n&&(a=a.replace(n,""));const i=a&&function(e){try{return Ti.validateFlags(e),null}catch{return`Invalid flags supplied to RegExp constructor '${e}'`}}(a)||(null===a?o(s,!0)&&o(s,!1):o(s,a.includes("u")));i&&e.report({node:t,messageId:"regexMessage",data:{message:i}})}}}},Di={meta:{type:"suggestion",docs:{description:"disallow `this` keywords outside of classes or class-like objects",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-invalid-this"},schema:[{type:"object",properties:{capIsConstructor:{type:"boolean",default:!0}},additionalProperties:!1}],messages:{unexpectedThis:"Unexpected 'this'."}},create(e){const t=!1!==(e.options[0]||{}).capIsConstructor,n=[],r=e.getSourceCode();function o(t){n.push({init:!e.getScope().isStrict,node:t,valid:!0})}function s(){n.pop()}return n.getCurrent=function(){const e=this[this.length-1];return e.init||(e.init=!0,e.valid=!fr.isDefaultThisBinding(e.node,r,{capIsConstructor:t})),e},{Program(t){const r=e.getScope(),o=e.parserOptions.ecmaFeatures||{};n.push({init:!0,node:t,valid:!(r.isStrict||"module"===t.sourceType||o.globalReturn&&r.childScopes[0].isStrict)})},"Program:exit"(){n.pop()},FunctionDeclaration:o,"FunctionDeclaration:exit":s,FunctionExpression:o,"FunctionExpression:exit":s,ThisExpression(t){const r=n.getCurrent();r&&!r.valid&&e.report({node:t,messageId:"unexpectedThis"})}}}};const Oi=/[\f\v\u0085\ufeff\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000\u2028\u2029]/u,Bi=/[\f\v\u0085\ufeff\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u202f\u205f\u3000]+/gmu,Ni=/[\u2028\u2029]/gmu,ji=fr.createGlobalLinebreakMatcher();var Li={meta:{type:"problem",docs:{description:"disallow irregular whitespace",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-irregular-whitespace"},schema:[{type:"object",properties:{skipComments:{type:"boolean",default:!1},skipStrings:{type:"boolean",default:!0},skipTemplates:{type:"boolean",default:!1},skipRegExps:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{noIrregularWhitespace:"Irregular whitespace not allowed."}},create(e){let t=[];const n=e.options[0]||{},r=!!n.skipComments,o=!1!==n.skipStrings,s=!!n.skipRegExps,a=!!n.skipTemplates,i=e.getSourceCode(),c=i.getAllComments();function l(e){const n=e.loc.start,r=e.loc.end;t=t.filter((({loc:{start:e}})=>e.line=r.column||e.line>r.line))}function u(e){const t=o&&"string"==typeof e.value,n=s&&Boolean(e.regex);(t||n)&&Oi.test(e.raw)&&l(e)}function p(e){Oi.test(e.value)&&l(e)}function d(){}const f={};return Oi.test(i.getText())?(f.Program=function(e){!function(e){i.lines.forEach(((n,r)=>{const o=r+1;let s;for(;null!==(s=Bi.exec(n));)t.push({node:e,messageId:"noIrregularWhitespace",loc:{start:{line:o,column:s.index},end:{line:o,column:s.index+s[0].length}}})}))}(e),function(e){const n=i.getText(),r=i.lines,o=n.match(ji);let s,a=-1;for(;null!==(s=Ni.exec(n));){const n=o.indexOf(s[0],a+1)||0;t.push({node:e,messageId:"noIrregularWhitespace",loc:{start:{line:n+1,column:r[n].length},end:{line:n+2,column:0}}}),a=n}}(e)},f.Identifier=u,f.Literal=u,f.TemplateElement=a?function(e){"string"==typeof e.value.raw&&Oi.test(e.value.raw)&&l(e)}:d,f["Program:exit"]=function(){r&&c.forEach(p),t.forEach((t=>e.report(t)))}):f.Program=d,f}};const{getStaticPropertyName:Ri}=fr;var Mi={meta:{type:"suggestion",docs:{description:"disallow the use of the `__iterator__` property",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-iterator"},schema:[],messages:{noIterator:"Reserved name '__iterator__'."}},create:e=>({MemberExpression(t){"__iterator__"===Ri(t)&&e.report({node:t,messageId:"noIterator"})}})},_i={meta:{type:"suggestion",docs:{description:"disallow labels that share a name with a variable",category:"Variables",recommended:!1,url:"https://eslint.org/docs/rules/no-label-var"},schema:[],messages:{identifierClashWithLabel:"Found identifier with same name as label."}},create:e=>({LabeledStatement(t){(function(e,t){return null!==fr.getVariableByName(e,t)})(e.getScope(),t.label.name)&&e.report({node:t,messageId:"identifierClashWithLabel"})}})},$i={meta:{type:"suggestion",docs:{description:"disallow labeled statements",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-labels"},schema:[{type:"object",properties:{allowLoop:{type:"boolean",default:!1},allowSwitch:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{unexpectedLabel:"Unexpected labeled statement.",unexpectedLabelInBreak:"Unexpected label in break statement.",unexpectedLabelInContinue:"Unexpected label in continue statement."}},create(e){const t=e.options[0],n=t&&t.allowLoop,r=t&&t.allowSwitch;let o=null;function s(e){return fr.isLoop(e)?"loop":"SwitchStatement"===e.type?"switch":"other"}function a(e){switch(e){case"loop":return n;case"switch":return r;default:return!1}}function i(e){let t=o;for(;t;){if(t.label===e)return t.kind;t=t.upper}return"other"}return{LabeledStatement(e){o={label:e.label.name,kind:s(e.body),upper:o}},"LabeledStatement:exit"(t){a(o.kind)||e.report({node:t,messageId:"unexpectedLabel"}),o=o.upper},BreakStatement(t){t.label&&!a(i(t.label.name))&&e.report({node:t,messageId:"unexpectedLabelInBreak"})},ContinueStatement(t){t.label&&!a(i(t.label.name))&&e.report({node:t,messageId:"unexpectedLabelInContinue"})}}}},qi={meta:{type:"suggestion",docs:{description:"disallow unnecessary nested blocks",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-lone-blocks"},schema:[],messages:{redundantBlock:"Block is redundant.",redundantNestedBlock:"Nested block is redundant."}},create(e){const t=[];let n;function r(t){const n="BlockStatement"===t.parent.type?"redundantNestedBlock":"redundantBlock";e.report({node:t,messageId:n})}function o(e){return"BlockStatement"===e.parent.type||"Program"===e.parent.type||"SwitchCase"===e.parent.type&&!(e.parent.consequent[0]===e&&1===e.parent.consequent.length)}function s(){if(0===t.length)return;const n=e.getAncestors().pop();t[t.length-1]===n&&t.pop()}return n={BlockStatement(e){o(e)&&r(e)}},e.parserOptions.ecmaVersion>=6&&(n={BlockStatement(e){o(e)&&t.push(e)},"BlockStatement:exit"(e){t.length>0&&t[t.length-1]===e?(t.pop(),r(e)):"BlockStatement"===e.parent.type&&1===e.parent.body.length&&r(e)}},n.VariableDeclaration=function(e){"let"!==e.kind&&"const"!==e.kind||s()},n.FunctionDeclaration=function(){e.getScope().isStrict&&s()},n.ClassDeclaration=s),n}},Ui={meta:{type:"suggestion",docs:{description:"disallow `if` statements as the only statement in `else` blocks",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/no-lonely-if"},schema:[],fixable:"code",messages:{unexpectedLonelyIf:"Unexpected if as the only statement in an else block."}},create(e){const t=e.getSourceCode();return{IfStatement(n){const r=e.getAncestors(),o=r.pop(),s=r.pop();o&&"BlockStatement"===o.type&&1===o.body.length&&s&&"IfStatement"===s.type&&o===s.alternate&&e.report({node:n,messageId:"unexpectedLonelyIf",fix(e){const r=t.getFirstToken(o),s=t.getLastToken(o),a=t.getTokenBefore(r),i=t.getTokenAfter(s),c=t.getLastToken(n.consequent),l=t.getText();return l.slice(r.range[1],n.range[0]).trim()||l.slice(n.range[1],s.range[0]).trim()||"BlockStatement"!==n.consequent.type&&";"!==c.value&&i&&(n.consequent.loc.end.line===i.loc.start.line||/^[([/+`-]/u.test(i.value)||"++"===c.value||"--"===c.value)?null:e.replaceTextRange([r.range[0],s.range[1]],(a.range[1]===r.range[0]?" ":"")+t.getText(n))}})}}}};function Vi(e){for(let t=e;t.parent;t=t.parent){const e=t.parent;switch(e.type){case"WhileStatement":case"DoWhileStatement":return e;case"ForStatement":if(e.init!==t)return e;break;case"ForInStatement":case"ForOfStatement":if(e.right!==t)return e;break;case"ArrowFunctionExpression":case"FunctionExpression":case"FunctionDeclaration":return null}}return null}function Wi(e,t){const n=t.resolved,r=n&&n.defs[0],o=r&&r.parent,s=o&&"VariableDeclaration"===o.type?o.kind:"";if("const"===s)return!0;if("let"===s&&o.range[0]>e.range[0]&&o.range[1]=n;)r=o,o=Vi(o);return r}(e,"let"===s?o:null).range[0];return Boolean(n)&&n.references.every((function(e){const t=e.identifier;return!e.isWrite()||n.scope.variableScope===e.from.variableScope&&t.range[0]!Wi(n,e))).map((e=>e.identifier.name));r.length>0&&e.report({node:t,messageId:"unsafeRefs",data:{varNames:`'${r.join("', '")}'`}})}return{ArrowFunctionExpression:t,FunctionExpression:t,FunctionDeclaration:t}}},zi={meta:{type:"problem",docs:{description:"disallow literal numbers that lose precision",category:"Possible Errors",recommended:!1,url:"https://eslint.org/docs/rules/no-loss-of-precision"},schema:[],messages:{noLossOfPrecision:"This number literal will lose precision at runtime."}},create(e){function t(e){return e.raw.replace(/_/gu,"")}function n(e){return`${e.slice(0,1)}.${e.slice(1)}`}function r(e){return e.replace(/^0*/u,"")}function o(e){const t=e.replace("E","e").split("e"),o=t[0],s=e.includes(".")?function(e){const t=r(e);if(t.startsWith(".")){const e=t.split(".").pop(),o=r(e);return{magnitude:o.length-e.length-1,coefficient:n(o)}}return{magnitude:t.indexOf(".")-1,coefficient:n(t.replace(".",""))}}(o):function(e){const t=r(e).replace(/0*$/u,"");return{magnitude:e.startsWith("0")?e.length-2:e.length-1,coefficient:n(t)}}(o);return`${s.coefficient}e${t.length>1?parseInt(t[1],10)+s.magnitude:s.magnitude}`}function s(e){return function(e){return["0x","0X","0b","0B","0o","0O"].every((t=>!e.raw.startsWith(t)))&&!/^0[0-7]+$/u.test(e.raw)}(e)?function(e){const n=o(t(e)),r=n.split("e")[0].replace(".","").length;return r>100||n!==o(e.value.toPrecision(r))}(e):function(e){const n=t(e).toUpperCase();let r=0;return r=n.startsWith("0B")?2:n.startsWith("0X")?16:8,!n.endsWith(e.value.toString(r).toUpperCase())}(e)}return{Literal(t){t.value&&function(e){return"number"==typeof e.value}(t)&&s(t)&&e.report({messageId:"noLossOfPrecision",node:t})}}}};function Ji(e){return"string"==typeof e?BigInt(e.slice(0,-1)):e}var Ki={meta:{type:"suggestion",docs:{description:"disallow magic numbers",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-magic-numbers"},schema:[{type:"object",properties:{detectObjects:{type:"boolean",default:!1},enforceConst:{type:"boolean",default:!1},ignore:{type:"array",items:{anyOf:[{type:"number"},{type:"string",pattern:"^[+-]?(?:0|[1-9][0-9]*)n$"}]},uniqueItems:!0},ignoreArrayIndexes:{type:"boolean",default:!1},ignoreDefaultValues:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{useConst:"Number constants declarations must use 'const'.",noMagic:"No magic number: {{raw}}."}},create(e){const t=e.options[0]||{},n=!!t.detectObjects,r=!!t.enforceConst,o=(t.ignore||[]).map(Ji),s=!!t.ignoreArrayIndexes,a=!!t.ignoreDefaultValues,i=n?[]:["ObjectExpression","Property","AssignmentExpression"];return{Literal(t){if(!fr.isNumericLiteral(t))return;let n,c,l;"UnaryExpression"===t.parent.type&&"-"===t.parent.operator?(n=t.parent,c=-t.value,l=`-${t.raw}`):(n=t,c=t.value,l=t.raw);const u=n.parent;(function(e){return-1!==o.indexOf(e)})(c)||a&&function(e){const t=e.parent;return"AssignmentPattern"===t.type&&t.right===e}(n)||function(e){const t=e.parent;return"CallExpression"===t.type&&e===t.arguments[1]&&(fr.isSpecificId(t.callee,"parseInt")||fr.isSpecificMemberAccess(t.callee,"Number","parseInt"))}(n)||function(e){return 0===e.parent.type.indexOf("JSX")}(n)||s&&function(e,t){const n=e.parent;return"MemberExpression"===n.type&&n.property===e&&(Number.isInteger(t)||"bigint"==typeof t)&&t>=0&&t<4294967295}(n,c)||("VariableDeclarator"===u.type?r&&"const"!==u.parent.kind&&e.report({node:n,messageId:"useConst"}):(-1===i.indexOf(u.type)||"AssignmentExpression"===u.type&&"Identifier"===u.left.type)&&e.report({node:n,messageId:"noMagic",data:{raw:l}}))}}}},Yi={isCombiningCharacter:function(e){return/^[\p{Mc}\p{Me}\p{Mn}]$/u.test(String.fromCodePoint(e))},isEmojiModifier:function(e){return e>=127995&&e<=127999},isRegionalIndicatorSymbol:function(e){return e>=127462&&e<=127487},isSurrogatePair:function(e,t){return e>=55296&&e<56320&&t>=56320&&t<57344}};const{CALL:Hi,CONSTRUCT:Xi,ReferenceTracker:Qi,getStringIfConstant:Zi}=G.default,{RegExpParser:ec,visitRegExpAST:tc}=X.default,{isCombiningCharacter:nc,isEmojiModifier:rc,isRegionalIndicatorSymbol:oc,isSurrogatePair:sc}=Yi;const ac={surrogatePairWithoutUFlag:e=>e.some(((t,n)=>0!==n&&sc(e[n-1],t))),combiningClass:e=>e.some(((t,n)=>0!==n&&nc(t)&&!nc(e[n-1]))),emojiModifier:e=>e.some(((t,n)=>0!==n&&rc(t)&&!rc(e[n-1]))),regionalIndicatorSymbol:e=>e.some(((t,n)=>0!==n&&oc(t)&&oc(e[n-1]))),zwj(e){const t=e.length-1;return e.some(((n,r)=>0!==r&&r!==t&&8205===n&&8205!==e[r-1]&&8205!==e[r+1]))}},ic=Object.keys(ac);var cc={meta:{type:"problem",docs:{description:"disallow characters which are made with multiple code points in character class syntax",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-misleading-character-class"},schema:[],messages:{surrogatePairWithoutUFlag:"Unexpected surrogate pair in character class. Use 'u' flag.",combiningClass:"Unexpected combined character in character class.",emojiModifier:"Unexpected modified Emoji in character class.",regionalIndicatorSymbol:"Unexpected national flag in character class.",zwj:"Unexpected joined character sequence in character class."}},create(e){const t=new ec;function n(n,r,o){const s={surrogatePairWithoutUFlag:!1,combiningClass:!1,variationSelector:!1,emojiModifier:!1,regionalIndicatorSymbol:!1,zwj:!1};let a;try{a=t.parsePattern(r,0,r.length,o.includes("u"))}catch{return}tc(a,{onCharacterClassEnter(e){for(const t of function*(e){let t=[];for(const n of e)switch(n.type){case"Character":t.push(n.value);break;case"CharacterClassRange":t.push(n.min.value),yield t,t=[n.max.value];break;case"CharacterSet":t.length>0&&(yield t,t=[])}t.length>0&&(yield t)}(e.elements))for(const e of ic)s[e]=s[e]||ac[e](t)}});for(const t of ic)s[t]&&e.report({node:n,messageId:t})}return{"Literal[regex]"(e){n(e,e.regex.pattern,e.regex.flags)},Program(){const t=e.getScope(),r=new Qi(t);for(const{node:e}of r.iterateGlobalReferences({RegExp:{[Hi]:!0,[Xi]:!0}})){const[r,o]=e.arguments,s=Zi(r,t),a=Zi(o,t);"string"==typeof s&&n(e,s,a||"")}}}}};const lc=["+","-","*","/","%","**"],uc=["&","|","^","~","<<",">>",">>>"],pc=["==","!=","===","!==",">",">=","<","<="],dc=["&&","||"],fc=["in","instanceof"],mc=[].concat(lc,uc,pc,dc,fc,["?:"],["??"]),gc=[lc,uc,pc,dc,fc],hc=/^(?:Binary|Logical|Conditional)Expression$/u;function yc(e){return"ConditionalExpression"===e.type?e.test:e.left}var xc={meta:{type:"suggestion",docs:{description:"disallow mixed binary operators",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/no-mixed-operators"},schema:[{type:"object",properties:{groups:{type:"array",items:{type:"array",items:{enum:mc},minItems:2,uniqueItems:!0},uniqueItems:!0},allowSamePrecedence:{type:"boolean",default:!0}},additionalProperties:!1}],messages:{unexpectedMixedOperator:"Unexpected mix of '{{leftOperator}}' and '{{rightOperator}}'."}},create(e){const t=e.getSourceCode(),n=function(e={}){return{groups:e.groups&&e.groups.length>0?e.groups:gc,allowSamePrecedence:!1!==e.allowSamePrecedence}}(e.options[0]);function r(e){return t.getTokenAfter(yc(e),fr.isNotClosingParenToken)}function o(o){hc.test(o.parent.type)&&function(e){return e.operator!==e.parent.operator&&!fr.isParenthesised(t,e)}(o)&&!function(e){const t=e,r=e.parent;return o=n.groups,s=t.operator,a="ConditionalExpression"===r.type?"?:":r.operator,!o.some((e=>-1!==e.indexOf(s)&&-1!==e.indexOf(a)))||n.allowSamePrecedence&&fr.getPrecedence(t)===fr.getPrecedence(r);var o,s,a}(o)&&function(t){const n=t.parent,o=yc(n)===t?t:n,s=yc(n)!==t?t:n,a={leftOperator:o.operator||"?:",rightOperator:s.operator||"?:"};e.report({node:o,loc:r(o).loc,messageId:"unexpectedMixedOperator",data:a}),e.report({node:s,loc:r(s).loc,messageId:"unexpectedMixedOperator",data:a})}(o)}return{BinaryExpression:o,LogicalExpression:o}}},bc={meta:{deprecated:!0,replacedBy:[],type:"suggestion",docs:{description:"disallow `require` calls to be mixed with regular variable declarations",category:"Node.js and CommonJS",recommended:!1,url:"https://eslint.org/docs/rules/no-mixed-requires"},schema:[{oneOf:[{type:"boolean"},{type:"object",properties:{grouping:{type:"boolean"},allowCall:{type:"boolean"}},additionalProperties:!1}]}],messages:{noMixRequire:"Do not mix 'require' and other declarations.",noMixCoreModuleFileComputed:"Do not mix core, module, file and computed requires."}},create(e){const t=e.options[0];let n=!1,r=!1;"object"==typeof t?(n=t.grouping,r=t.allowCall):n=!!t;const o=["assert","buffer","child_process","cluster","crypto","dgram","dns","domain","events","fs","http","https","net","os","path","punycode","querystring","readline","repl","smalloc","stream","string_decoder","tls","tty","url","util","v8","vm","zlib"],s="require",a="uninitialized",i="other",c="computed";function l(e){return e?"CallExpression"===e.type&&"Identifier"===e.callee.type&&"require"===e.callee.name?s:r&&"CallExpression"===e.type&&"CallExpression"===e.callee.type?l(e.callee):"MemberExpression"===e.type?l(e.object):i:a}function u(e){if("MemberExpression"===e.type)return u(e.object);if(0===e.arguments.length)return c;const t=e.arguments[0];return"Literal"!==t.type||"string"!=typeof t.value?c:-1!==o.indexOf(t.value)?"core":/^\.{0,2}\//u.test(t.value)?"file":"module"}function p(e){const t={};return e.forEach((e=>{l(e.init)===s&&(t[u(e.init)]=!0)})),Object.keys(t).length<=1}return{VariableDeclaration(t){!function(e){const t={};return e.forEach((e=>{const n=l(e.init);t[n]=!0})),!(!t.require||!t.uninitialized&&!t.other)}(t.declarations)?n&&!p(t.declarations)&&e.report({node:t,messageId:"noMixCoreModuleFileComputed"}):e.report({node:t,messageId:"noMixRequire"})}}}},Ec={meta:{type:"layout",docs:{description:"disallow mixed spaces and tabs for indentation",category:"Stylistic Issues",recommended:!0,url:"https://eslint.org/docs/rules/no-mixed-spaces-and-tabs"},schema:[{enum:["smart-tabs",!0,!1]}],messages:{mixedSpacesAndTabs:"Mixed spaces and tabs."}},create(e){const t=e.getSourceCode();let n;switch(e.options[0]){case!0:case"smart-tabs":n=!0;break;default:n=!1}return{"Program:exit"(r){const o=t.lines,s=t.getAllComments(),a=new Set;s.forEach((e=>{for(let t=e.loc.start.line+1;t<=e.loc.end.line;t++)a.add(t)}));let i=/^(?=( +|\t+))\1(?:\t| )/u;n&&(i=/^(?=(\t*))\1(?=( +))\2\t/u),o.forEach(((n,o)=>{const s=i.exec(n);if(s){const n=o+1,i={start:{line:n,column:s[0].length-2},end:{line:n,column:s[0].length}};if(!a.has(n)){const n=t.getNodeByRangeIndex(t.getIndexFromLoc(i.start));n&&["Literal","TemplateElement"].includes(n.type)||e.report({node:r,loc:i,messageId:"mixedSpacesAndTabs"})}}}))}}}},Sc={meta:{type:"suggestion",docs:{description:"disallow use of chained assignment expressions",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/no-multi-assign"},schema:[{type:"object",properties:{ignoreNonDeclaration:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{unexpectedChain:"Unexpected chained assignment."}},create(e){const t=(e.options[0]||{ignoreNonDeclaration:!1}).ignoreNonDeclaration?["VariableDeclarator"]:["AssignmentExpression","VariableDeclarator"];return{AssignmentExpression(n){-1!==t.indexOf(n.parent.type)&&e.report({node:n,messageId:"unexpectedChain"})}}}},Cc={meta:{type:"layout",docs:{description:"disallow multiple spaces",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-multi-spaces"},fixable:"whitespace",schema:[{type:"object",properties:{exceptions:{type:"object",patternProperties:{"^([A-Z][a-z]*)+$":{type:"boolean"}},additionalProperties:!1},ignoreEOLComments:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{multipleSpaces:"Multiple spaces found before '{{displayValue}}'."}},create(e){const t=e.getSourceCode(),n=e.options[0]||{},r=n.ignoreEOLComments,o=Object.assign({Property:!0},n.exceptions),s=Object.keys(o).filter((e=>o[e])).length>0;function a(e){const t=e.value.split("\n"),n=t[0],r=`${n.slice(0,12)}...`;return 1===t.length&&n.length<=12?n:r}return{Program(){t.tokensAndComments.forEach(((n,i,c)=>{if(i===c.length-1)return;const l=c[i+1];if(!t.text.slice(n.range[1],l.range[0]).includes(" ")||n.loc.end.linee.replaceTextRange([n.range[1],l.range[0]]," ")})}))}}}},vc={meta:{type:"suggestion",docs:{description:"disallow multiline strings",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-multi-str"},schema:[],messages:{multilineString:"Multiline support is limited to browsers supporting ES5 only."}},create:e=>({Literal(t){fr.LINEBREAK_MATCHER.test(t.raw)&&!function(e){return 0===e.type.indexOf("JSX")}(t.parent)&&e.report({node:t,messageId:"multilineString"})}})},Ac={meta:{type:"layout",docs:{description:"disallow multiple empty lines",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/no-multiple-empty-lines"},fixable:"whitespace",schema:[{type:"object",properties:{max:{type:"integer",minimum:0},maxEOF:{type:"integer",minimum:0},maxBOF:{type:"integer",minimum:0}},required:["max"],additionalProperties:!1}],messages:{blankBeginningOfFile:"Too many blank lines at the beginning of file. Max of {{max}} allowed.",blankEndOfFile:"Too many blank lines at the end of file. Max of {{max}} allowed.",consecutiveBlank:"More than {{max}} blank {{pluralizedLines}} not allowed."}},create(e){let t=2,n=t,r=t;e.options.length&&(t=e.options[0].max,n=void 0!==e.options[0].maxEOF?e.options[0].maxEOF:t,r=void 0!==e.options[0].maxBOF?e.options[0].maxBOF:t);const o=e.getSourceCode(),s=""===o.lines[o.lines.length-1]?o.lines.slice(0,-1):o.lines,a=new Set;return{TemplateLiteral(e){e.quasis.forEach((e=>{for(let t=e.loc.start.line;ts.reduce(((e,t,n)=>((t.trim()||a.has(n+1))&&e.push(n+1),e)),[]).concat(s.length+1).reduce(((a,c)=>{let l,u;return 0===a?(l="blankBeginningOfFile",u=r):c===s.length+1?(l="blankEndOfFile",u=n):(l="consecutiveBlank",u=t),c-a-1>u&&e.report({node:i,loc:{start:{line:a+u+1,column:0},end:{line:c,column:0}},messageId:l,data:{max:u,pluralizedLines:1===u?"line":"lines"},fix(e){const t=o.getIndexFromLoc({line:a+1,column:0}),n=c-u,r=n<=s.length?o.getIndexFromLoc({line:n,column:0}):o.text.length;return e.removeRange([t,r])}}),c}),0)}}},kc={meta:{type:"suggestion",docs:{description:"disallow assignments to native objects or read-only global variables",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-native-reassign"},deprecated:!0,replacedBy:["no-global-assign"],schema:[{type:"object",properties:{exceptions:{type:"array",items:{type:"string"},uniqueItems:!0}},additionalProperties:!1}],messages:{nativeReassign:"Read-only global '{{name}}' should not be modified."}},create(e){const t=e.options[0],n=t&&t.exceptions||[];function r(t,n,r){const o=t.identifier;!1!==t.init||!t.isWrite()||0!==n&&r[n-1].identifier===o||e.report({node:o,messageId:"nativeReassign",data:o})}function o(e){!1===e.writeable&&-1===n.indexOf(e.name)&&e.references.forEach(r)}return{Program(){e.getScope().variables.forEach(o)}}}},wc={meta:{type:"suggestion",docs:{description:"disallow negated conditions",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/no-negated-condition"},schema:[],messages:{unexpectedNegated:"Unexpected negated condition."}},create(e){function t(e){return"UnaryExpression"===(t=e.test).type&&"!"===t.operator||function(e){return"BinaryExpression"===e.type&&("!="===e.operator||"!=="===e.operator)}(e.test);var t}return{IfStatement(n){(function(e){return e.alternate&&"IfStatement"!==e.alternate.type})(n)&&t(n)&&e.report({node:n,messageId:"unexpectedNegated"})},ConditionalExpression(n){t(n)&&e.report({node:n,messageId:"unexpectedNegated"})}}}},Pc={meta:{type:"problem",docs:{description:"disallow negating the left operand in `in` expressions",category:"Possible Errors",recommended:!1,url:"https://eslint.org/docs/rules/no-negated-in-lhs"},replacedBy:["no-unsafe-negation"],deprecated:!0,schema:[],messages:{negatedLHS:"The 'in' expression's left operand is negated."}},create:e=>({BinaryExpression(t){"in"===t.operator&&"UnaryExpression"===t.left.type&&"!"===t.left.operator&&e.report({node:t,messageId:"negatedLHS"})}})},Tc={meta:{type:"suggestion",docs:{description:"disallow nested ternary expressions",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/no-nested-ternary"},schema:[],messages:{noNestedTernary:"Do not nest ternary expressions."}},create:e=>({ConditionalExpression(t){"ConditionalExpression"!==t.alternate.type&&"ConditionalExpression"!==t.consequent.type||e.report({node:t,messageId:"noNestedTernary"})}})},Ic={meta:{type:"suggestion",docs:{description:"disallow `new` operators outside of assignments or comparisons",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-new"},schema:[],messages:{noNewStatement:"Do not use 'new' for side effects."}},create:e=>({"ExpressionStatement > NewExpression"(t){e.report({node:t.parent,messageId:"noNewStatement"})}})},Fc={meta:{type:"suggestion",docs:{description:"disallow `new` operators with the `Function` object",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-new-func"},schema:[],messages:{noFunctionConstructor:"The Function constructor is eval."}},create:e=>({"Program:exit"(){const t=e.getScope().set.get("Function");t&&0===t.defs.length&&t.references.forEach((t=>{const n=t.identifier,{parent:r}=n;!r||"NewExpression"!==r.type&&"CallExpression"!==r.type||n!==r.callee||e.report({node:r,messageId:"noFunctionConstructor"})}))}})},Dc={meta:{type:"suggestion",docs:{description:"disallow `Object` constructors",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/no-new-object"},schema:[],messages:{preferLiteral:"The object literal notation {} is preferrable."}},create:e=>({NewExpression(t){const n=fr.getVariableByName(e.getScope(),t.callee.name);n&&n.identifiers.length>0||"Object"===t.callee.name&&e.report({node:t,messageId:"preferLiteral"})}})},Oc={meta:{deprecated:!0,replacedBy:[],type:"suggestion",docs:{description:"disallow `new` operators with calls to `require`",category:"Node.js and CommonJS",recommended:!1,url:"https://eslint.org/docs/rules/no-new-require"},schema:[],messages:{noNewRequire:"Unexpected use of new with require."}},create:e=>({NewExpression(t){"Identifier"===t.callee.type&&"require"===t.callee.name&&e.report({node:t,messageId:"noNewRequire"})}})},Bc={meta:{type:"problem",docs:{description:"disallow `new` operators with the `Symbol` object",category:"ECMAScript 6",recommended:!0,url:"https://eslint.org/docs/rules/no-new-symbol"},schema:[],messages:{noNewSymbol:"`Symbol` cannot be called as a constructor."}},create:e=>({"Program:exit"(){const t=e.getScope().set.get("Symbol");t&&0===t.defs.length&&t.references.forEach((t=>{const n=t.identifier,r=n.parent;r&&"NewExpression"===r.type&&r.callee===n&&e.report({node:n,messageId:"noNewSymbol"})}))}})},Nc={meta:{type:"suggestion",docs:{description:"disallow `new` operators with the `String`, `Number`, and `Boolean` objects",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-new-wrappers"},schema:[],messages:{noConstructor:"Do not use {{fn}} as a constructor."}},create:e=>({NewExpression(t){["String","Number","Boolean"].indexOf(t.callee.name)>-1&&e.report({node:t,messageId:"noConstructor",data:{fn:t.callee.name}})}})};const jc=/\\[89]/u;function Lc(e){return`\\u${e.charCodeAt(0).toString(16).padStart(4,"0")}`}var Rc={meta:{type:"suggestion",docs:{description:"disallow `\\8` and `\\9` escape sequences in string literals",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-nonoctal-decimal-escape",suggestion:!0},schema:[],messages:{decimalEscape:"Don't use '{{decimalEscape}}' escape sequence.",refactor:"Replace '{{original}}' with '{{replacement}}'. This maintains the current functionality.",escapeBackslash:"Replace '{{original}}' with '{{replacement}}' to include the actual backslash character."}},create(e){const t=e.getSourceCode();function n(e,n,r){return{messageId:e,data:{original:t.getText().slice(...n),replacement:r},fix:e=>e.replaceTextRange(n,r)}}return{Literal(r){if("string"!=typeof r.value)return;if(!jc.test(r.raw))return;const o=/(?:[^\\]|(?\\.))*?(?\\[89])/uys;let s;for(;s=o.exec(r.raw);){const{previousEscape:o,decimalEscape:a}=s.groups,i=r.range[0]+s.index+s[0].length,c=i-a.length,l=[c,i],u=[];"\\0"===o?u.push(n("refactor",[c-o.length,i],`${Lc("\0")}${a[1]}`),n("refactor",l,Lc(a[1]))):u.push(n("refactor",l,a[1])),u.push(n("escapeBackslash",l,`\\${a}`)),e.report({node:r,loc:{start:t.getLocFromIndex(c),end:t.getLocFromIndex(i)},messageId:"decimalEscape",data:{decimalEscape:a},suggest:u})}}}}};const{CALL:Mc,CONSTRUCT:_c,ReferenceTracker:$c}=G.default,qc=fr.getStaticPropertyName,Uc=["Atomics","JSON","Math","Reflect"];function Vc(e){return"ChainExpression"===e.type?Vc(e.expression):"MemberExpression"===e.type?qc(e):e.name}var Wc={meta:{type:"problem",docs:{description:"disallow calling global object properties as functions",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-obj-calls"},schema:[],messages:{unexpectedCall:"'{{name}}' is not a function.",unexpectedRefCall:"'{{name}}' is reference to '{{ref}}', which is not a function."}},create:e=>({Program(){const t=e.getScope(),n=new $c(t),r={};for(const e of Uc)r[e]={[Mc]:!0,[_c]:!0};for(const{node:t,path:o}of n.iterateGlobalReferences(r)){const n=Vc(t.callee),r=o[0],s=n===r?"unexpectedCall":"unexpectedRefCall";e.report({node:t,messageId:s,data:{name:n,ref:r}})}}})},Gc={meta:{type:"suggestion",docs:{description:"disallow octal literals",category:"Best Practices",recommended:!0,url:"https://eslint.org/docs/rules/no-octal"},schema:[],messages:{noOcatal:"Octal literals should not be used."}},create:e=>({Literal(t){"number"==typeof t.value&&/^0[0-9]/u.test(t.raw)&&e.report({node:t,messageId:"noOcatal"})}})},zc={meta:{type:"suggestion",docs:{description:"disallow octal escape sequences in string literals",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-octal-escape"},schema:[],messages:{octalEscapeSequence:"Don't use octal: '\\{{sequence}}'. Use '\\u....' instead."}},create:e=>({Literal(t){if("string"!=typeof t.value)return;const n=t.raw.match(/^(?:[^\\]|\\.)*?\\([0-3][0-7]{1,2}|[4-7][0-7]|0(?=[89])|[1-7])/us);n&&e.report({node:t,messageId:"octalEscapeSequence",data:{sequence:n[1]}})}})};const Jc=/(?:Statement|Declaration|Function(?:Expression)?|Program)$/u;var Kc={meta:{type:"suggestion",docs:{description:"disallow reassigning `function` parameters",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-param-reassign"},schema:[{oneOf:[{type:"object",properties:{props:{enum:[!1]}},additionalProperties:!1},{type:"object",properties:{props:{enum:[!0]},ignorePropertyModificationsFor:{type:"array",items:{type:"string"},uniqueItems:!0},ignorePropertyModificationsForRegex:{type:"array",items:{type:"string"},uniqueItems:!0}},additionalProperties:!1}]}],messages:{assignmentToFunctionParam:"Assignment to function parameter '{{name}}'.",assignmentToFunctionParamProp:"Assignment to property of function parameter '{{name}}'."}},create(e){const t=e.options[0]&&e.options[0].props,n=e.options[0]&&e.options[0].ignorePropertyModificationsFor||[],r=e.options[0]&&e.options[0].ignorePropertyModificationsForRegex||[];function o(o,s,a){const i=o.identifier;var c;!i||o.init||0!==s&&a[s-1].identifier===i||(o.isWrite()?e.report({node:i,messageId:"assignmentToFunctionParam",data:{name:i.name}}):t&&function(e){let t=e.identifier,n=t.parent;for(;n&&(!Jc.test(n.type)||"ForInStatement"===n.type||"ForOfStatement"===n.type);){switch(n.type){case"AssignmentExpression":return n.left===t;case"UpdateExpression":return!0;case"UnaryExpression":if("delete"===n.operator)return!0;break;case"ForInStatement":case"ForOfStatement":return n.left===t;case"CallExpression":if(n.callee!==t)return!1;break;case"MemberExpression":if(n.property===t)return!1;break;case"Property":if(n.key===t)return!1;break;case"ConditionalExpression":if(n.test===t)return!1}t=n,n=t.parent}return!1}(o)&&(c=i.name,!n.includes(c)&&!r.some((e=>new RegExp(e,"u").test(c))))&&e.report({node:i,messageId:"assignmentToFunctionParamProp",data:{name:i.name}}))}function s(e){"Parameter"===e.defs[0].type&&e.references.forEach(o)}function a(t){e.getDeclaredVariables(t).forEach(s)}return{"FunctionDeclaration:exit":a,"FunctionExpression:exit":a,"ArrowFunctionExpression:exit":a}}},Yc={meta:{deprecated:!0,replacedBy:[],type:"suggestion",docs:{description:"disallow string concatenation with `__dirname` and `__filename`",category:"Node.js and CommonJS",recommended:!1,url:"https://eslint.org/docs/rules/no-path-concat"},schema:[],messages:{usePathFunctions:"Use path.join() or path.resolve() instead of + to create paths."}},create(e){const t=/^__(?:dir|file)name$/u;return{BinaryExpression(n){const r=n.left,o=n.right;"+"===n.operator&&("Identifier"===r.type&&t.test(r.name)||"Identifier"===o.type&&t.test(o.name))&&e.report({node:n,messageId:"usePathFunctions"})}}}};function Hc(e){const t=e.parent;return"SequenceExpression"===t.type?Hc(t):function(e){const t=e.parent;return"ForStatement"===t.type&&t.update===e}(e)}var Xc={meta:{type:"suggestion",docs:{description:"disallow the unary operators `++` and `--`",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/no-plusplus"},schema:[{type:"object",properties:{allowForLoopAfterthoughts:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{unexpectedUnaryOp:"Unary operator '{{operator}}' used."}},create(e){const t=e.options[0];let n=!1;return"object"==typeof t&&(n=!0===t.allowForLoopAfterthoughts),{UpdateExpression(t){n&&Hc(t)||e.report({node:t,messageId:"unexpectedUnaryOp",data:{operator:t.operator}})}}}},Qc={meta:{deprecated:!0,replacedBy:[],type:"suggestion",docs:{description:"disallow the use of `process.env`",category:"Node.js and CommonJS",recommended:!1,url:"https://eslint.org/docs/rules/no-process-env"},schema:[],messages:{unexpectedProcessEnv:"Unexpected use of process.env."}},create:e=>({MemberExpression(t){const n=t.object.name,r=t.property.name;"process"===n&&!t.computed&&r&&"env"===r&&e.report({node:t,messageId:"unexpectedProcessEnv"})}})},Zc={meta:{deprecated:!0,replacedBy:[],type:"suggestion",docs:{description:"disallow the use of `process.exit()`",category:"Node.js and CommonJS",recommended:!1,url:"https://eslint.org/docs/rules/no-process-exit"},schema:[],messages:{noProcessExit:"Don't use process.exit(); throw an error instead."}},create:e=>({"CallExpression > MemberExpression.callee[object.name = 'process'][property.name = 'exit']"(t){e.report({node:t.parent,messageId:"noProcessExit"})}})};const{findVariable:el}=G.default,tl=new Set(["ArrowFunctionExpression","FunctionExpression"]);function nl(e,t){const n=e.parent;return"NewExpression"===n.type&&n.arguments[0]===e&&"Identifier"===n.callee.type&&"Promise"===n.callee.name&&function(e,t){const n=el(t,e);return null!==n&&"global"===n.scope.type&&0===n.defs.length}(n.callee,function(e){const t=e.upper;return"function-expression-name"===t.type?t.upper:t}(t))}var rl={meta:{type:"problem",docs:{description:"disallow returning values from Promise executor functions",category:"Possible Errors",recommended:!1,url:"https://eslint.org/docs/rules/no-promise-executor-return"},schema:[],messages:{returnsValue:"Return values from promise executor functions cannot be read."}},create(e){let t=null;function n(t){e.report({node:t,messageId:"returnsValue"})}return{onCodePathStart(r,o){t={upper:t,shouldCheck:tl.has(o.type)&&nl(o,e.getScope())},t.shouldCheck&&"ArrowFunctionExpression"===o.type&&o.expression&&n(o.body)},onCodePathEnd(){t=t.upper},ReturnStatement(e){t.shouldCheck&&e.argument&&n(e)}}}};const{getStaticPropertyName:ol}=fr;var sl={meta:{type:"suggestion",docs:{description:"disallow the use of the `__proto__` property",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-proto"},schema:[],messages:{unexpectedProto:"The '__proto__' property is deprecated."}},create:e=>({MemberExpression(t){"__proto__"===ol(t)&&e.report({node:t,messageId:"unexpectedProto"})}})},al={meta:{type:"problem",docs:{description:"disallow calling some `Object.prototype` methods directly on objects",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-prototype-builtins"},schema:[],messages:{prototypeBuildIn:"Do not access Object.prototype method '{{prop}}' from target object."}},create(e){const t=["hasOwnProperty","isPrototypeOf","propertyIsEnumerable"];return{CallExpression:function(n){const r=fr.skipChainExpression(n.callee);if("MemberExpression"!==r.type)return;const o=fr.getStaticPropertyName(r);null!==o&&t.indexOf(o)>-1&&e.report({messageId:"prototypeBuildIn",loc:r.property.loc,data:{prop:o},node:n})}}}},il={meta:{type:"suggestion",docs:{description:"disallow variable redeclaration",category:"Best Practices",recommended:!0,url:"https://eslint.org/docs/rules/no-redeclare"},messages:{redeclared:"'{{id}}' is already defined.",redeclaredAsBuiltin:"'{{id}}' is already defined as a built-in global variable.",redeclaredBySyntax:"'{{id}}' is already defined by a variable declaration."},schema:[{type:"object",properties:{builtinGlobals:{type:"boolean",default:!0}},additionalProperties:!1}]},create(e){const t=Boolean(0===e.options.length||e.options[0].builtinGlobals),n=e.getSourceCode();function*r(e){!t||"readonly"!==e.eslintImplicitGlobalSetting&&"writable"!==e.eslintImplicitGlobalSetting||(yield{type:"builtin"});for(const t of e.identifiers)yield{type:"syntax",node:t,loc:t.loc};if(e.eslintExplicitGlobalComments)for(const t of e.eslintExplicitGlobalComments)yield{type:"comment",node:t,loc:fr.getNameLocationInGlobalDirectiveComment(n,t,e.name)}}function o(t){for(const n of t.variables){const[t,...o]=r(n);if(0===o.length)continue;const s="builtin"===t.type?"redeclaredAsBuiltin":"redeclaredBySyntax",a={id:n.name};for(const{type:n,node:r,loc:i}of o){const o=n===t.type?"redeclared":s;e.report({node:r,loc:i,messageId:o,data:a})}}}function s(t){const n=e.getScope();n.block===t&&o(n)}return{Program(){const t=e.getScope();o(t),"global"===t.type&&t.childScopes[0]&&t.block===t.childScopes[0].block&&o(t.childScopes[0])},FunctionDeclaration:s,FunctionExpression:s,ArrowFunctionExpression:s,BlockStatement:s,ForStatement:s,ForInStatement:s,ForOfStatement:s,SwitchStatement:s}}};const cl=new X.default.RegExpParser,ll=/ {2}/u;function ul(e){return e&&"Literal"===e.type&&"string"==typeof e.value}var pl={meta:{type:"suggestion",docs:{description:"disallow multiple spaces in regular expressions",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-regex-spaces"},schema:[],fixable:"code",messages:{multipleSpaces:"Spaces are hard to count. Use {{{length}}}."}},create(e){function t(t,n,r,o,s){if(!ll.test(r))return;const a=[];let i;try{i=cl.parsePattern(n,0,n.length,s.includes("u"))}catch{return}X.default.visitRegExpAST(i,{onCharacterClassEnter(e){a.push(e)}});const c=/( {2,})(?: [+*{?]|[^+*{?]|$)/gu;let l;for(;l=c.exec(n);){const{1:{length:s},index:i}=l;if(a.every((({start:e,end:t})=>in!==r?null:e.replaceTextRange([o+i,o+i+s],` {${s}}`)})}}function n(n){const r=e.getScope(),o=fr.getVariableByName(r,"RegExp"),s=o&&o.defs.length>0,a=n.arguments[0],i=n.arguments[1];if("Identifier"===n.callee.type&&"RegExp"===n.callee.name&&ul(a)&&!s){t(n,a.value,a.raw.slice(1,-1),a.range[0]+1,ul(i)?i.value:"")}}return{Literal:function(e){if(e.regex){const n=e.regex.pattern,r=e.raw.slice(1,e.raw.lastIndexOf("/"));t(e,n,r,e.range[0]+1,e.regex.flags)}},CallExpression:n,NewExpression:n}}},dl={meta:{type:"suggestion",docs:{description:"disallow specified names in exports",category:"ECMAScript 6",recommended:!1,url:"https://eslint.org/docs/rules/no-restricted-exports"},schema:[{type:"object",properties:{restrictedNamedExports:{type:"array",items:{type:"string"},uniqueItems:!0}},additionalProperties:!1}],messages:{restrictedNamed:"'{{name}}' is restricted from being used as an exported name."}},create(e){const t=new Set(e.options[0]&&e.options[0].restrictedNamedExports);function n(n){const r=n.name;t.has(r)&&e.report({node:n,messageId:"restrictedNamed",data:{name:r}})}return{ExportAllDeclaration(e){e.exported&&n(e.exported)},ExportNamedDeclaration(t){const r=t.declaration;r?"FunctionDeclaration"===r.type||"ClassDeclaration"===r.type?n(r.id):"VariableDeclaration"===r.type&&e.getDeclaredVariables(r).map((e=>e.defs.find((e=>e.parent===r)))).map((e=>e.name)).forEach(n):t.specifiers.map((e=>e.exported)).forEach(n)}}}},fl={meta:{type:"suggestion",docs:{description:"disallow specified global variables",category:"Variables",recommended:!1,url:"https://eslint.org/docs/rules/no-restricted-globals"},schema:{type:"array",items:{oneOf:[{type:"string"},{type:"object",properties:{name:{type:"string"},message:{type:"string"}},required:["name"],additionalProperties:!1}]},uniqueItems:!0,minItems:0},messages:{defaultMessage:"Unexpected use of '{{name}}'.",customMessage:"Unexpected use of '{{name}}'. {{customMessage}}"}},create(e){if(0===e.options.length)return{};const t=e.options.reduce(((e,t)=>("string"==typeof t?e[t]=null:e[t.name]=t.message,e)),{});function n(n){const r=n.identifier.name,o=t[r],s=o?"customMessage":"defaultMessage";e.report({node:n.identifier,messageId:s,data:{name:r,customMessage:o}})}function r(e){return Object.prototype.hasOwnProperty.call(t,e)}return{Program(){const t=e.getScope();t.variables.forEach((e=>{!e.defs.length&&r(e.name)&&e.references.forEach(n)})),t.through.forEach((e=>{r(e.identifier.name)&&n(e)}))}}}};const ml={type:"array",items:{anyOf:[{type:"string"},{type:"object",properties:{name:{type:"string"},message:{type:"string",minLength:1},importNames:{type:"array",items:{type:"string"}}},additionalProperties:!1,required:["name"]}]},uniqueItems:!0};var gl={meta:{type:"suggestion",docs:{description:"disallow specified modules when loaded by `import`",category:"ECMAScript 6",recommended:!1,url:"https://eslint.org/docs/rules/no-restricted-imports"},messages:{path:"'{{importSource}}' import is restricted from being used.",pathWithCustomMessage:"'{{importSource}}' import is restricted from being used. {{customMessage}}",patterns:"'{{importSource}}' import is restricted from being used by a pattern.",everything:"* import is invalid because '{{importNames}}' from '{{importSource}}' is restricted.",everythingWithCustomMessage:"* import is invalid because '{{importNames}}' from '{{importSource}}' is restricted. {{customMessage}}",importName:"'{{importName}}' import from '{{importSource}}' is restricted.",importNameWithCustomMessage:"'{{importName}}' import from '{{importSource}}' is restricted. {{customMessage}}"},schema:{anyOf:[ml,{type:"array",items:[{type:"object",properties:{paths:ml,patterns:{type:"array",items:{type:"string"},uniqueItems:!0}},additionalProperties:!1}],additionalItems:!1}]}},create(e){const t=e.getSourceCode(),n=Array.isArray(e.options)?e.options:[],r="object"==typeof n[0]&&(Object.prototype.hasOwnProperty.call(n[0],"paths")||Object.prototype.hasOwnProperty.call(n[0],"patterns")),o=(r?n[0].paths:e.options)||[],s=(r?n[0].patterns:[])||[];if(0===Object.keys(o).length&&0===s.length)return{};const a=o.reduce(((e,t)=>("string"==typeof t?e[t]={message:null}:e[t.name]={message:t.message,importNames:t.importNames},e)),{}),i=Q.default().add(s);function c(n){const r=n.source.value.trim(),o=new Map;if("ExportAllDeclaration"===n.type){const e=t.getFirstToken(n,1);o.set("*",[{loc:e.loc}])}else if(n.specifiers)for(const e of n.specifiers){let t;const n={loc:e.loc};"ImportDefaultSpecifier"===e.type?t="default":"ImportNamespaceSpecifier"===e.type?t="*":e.imported?t=e.imported.name:e.local&&(t=e.local.name),t&&(o.has(t)?o.get(t).push(n):o.set(t,[n]))}!function(t,n,r){if(!Object.prototype.hasOwnProperty.call(a,t))return;const o=a[t].message,s=a[t].importNames;if(s){if(n.has("*")){const a=n.get("*")[0];e.report({node:r,messageId:o?"everythingWithCustomMessage":"everything",loc:a.loc,data:{importSource:t,importNames:s,customMessage:o}})}s.forEach((s=>{n.has(s)&&n.get(s).forEach((n=>{e.report({node:r,messageId:o?"importNameWithCustomMessage":"importName",loc:n.loc,data:{importSource:t,customMessage:o,importName:s}})}))}))}else e.report({node:r,messageId:o?"pathWithCustomMessage":"path",data:{importSource:t,customMessage:o}})}(r,o,n),function(e){return s.length>0&&i.ignores(e)}(r)&&function(t){const n=t.source.value.trim();e.report({node:t,messageId:"patterns",data:{importSource:n}})}(n)}return{ImportDeclaration:c,ExportNamedDeclaration(e){e.source&&c(e)},ExportAllDeclaration:c}}};const hl={type:"array",items:{anyOf:[{type:"string"},{type:"object",properties:{name:{type:"string"},message:{type:"string",minLength:1}},additionalProperties:!1,required:["name"]}]},uniqueItems:!0};var yl={meta:{deprecated:!0,replacedBy:[],type:"suggestion",docs:{description:"disallow specified modules when loaded by `require`",category:"Node.js and CommonJS",recommended:!1,url:"https://eslint.org/docs/rules/no-restricted-modules"},schema:{anyOf:[hl,{type:"array",items:{type:"object",properties:{paths:hl,patterns:{type:"array",items:{type:"string"},uniqueItems:!0}},additionalProperties:!1},additionalItems:!1}]},messages:{defaultMessage:"'{{name}}' module is restricted from being used.",customMessage:"'{{name}}' module is restricted from being used. {{customMessage}}",patternMessage:"'{{name}}' module is restricted from being used by a pattern."}},create(e){const t=Array.isArray(e.options)?e.options:[],n="object"==typeof t[0]&&(Object.prototype.hasOwnProperty.call(t[0],"paths")||Object.prototype.hasOwnProperty.call(t[0],"patterns")),r=(n?t[0].paths:e.options)||[],o=(n?t[0].patterns:[])||[],s=r.reduce(((e,t)=>("string"==typeof t?e[t]=null:e[t.name]=t.message,e)),{});if(0===Object.keys(r).length&&0===o.length)return{};const a=Q.default().add(o);return{CallExpression(t){if(function(e){return"Identifier"===e.callee.type&&"require"===e.callee.name}(t)&&t.arguments.length){const n=function(e){return function(e){return e&&"Literal"===e.type&&"string"==typeof e.value}(e)?e.value.trim():function(e){return e&&"TemplateLiteral"===e.type&&0===e.expressions.length}(e)?e.quasis[0].value.cooked.trim():null}(t.arguments[0]);n&&(function(e){return Object.prototype.hasOwnProperty.call(s,e)}(n)&&function(t,n){const r=s[n],o=r?"customMessage":"defaultMessage";e.report({node:t,messageId:o,data:{name:n,customMessage:r}})}(t,n),o.length>0&&a.ignores(n)&&e.report({node:t,messageId:"patternMessage",data:{name:n}}))}}}}},xl={meta:{type:"suggestion",docs:{description:"disallow certain properties on certain objects",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-restricted-properties"},schema:{type:"array",items:{anyOf:[{type:"object",properties:{object:{type:"string"},property:{type:"string"},message:{type:"string"}},additionalProperties:!1,required:["object"]},{type:"object",properties:{object:{type:"string"},property:{type:"string"},message:{type:"string"}},additionalProperties:!1,required:["property"]}]},uniqueItems:!0},messages:{restrictedObjectProperty:"'{{objectName}}.{{propertyName}}' is restricted from being used.{{message}}",restrictedProperty:"'{{propertyName}}' is restricted from being used.{{message}}"}},create(e){const t=e.options;if(0===t.length)return{};const n=new Map,r=new Map,o=new Map;function s(t,s,a){if(null===a)return;const i=n.get(s),c=i?i.get(a):r.get(s),l=o.get(a);if(c){const n=c.message?` ${c.message}`:"";e.report({node:t,messageId:"restrictedObjectProperty",data:{objectName:s,propertyName:a,message:n}})}else if(l){const n=l.message?` ${l.message}`:"";e.report({node:t,messageId:"restrictedProperty",data:{propertyName:a,message:n}})}}function a(e){if("Identifier"===e.right.type){const t=e.right.name;"ObjectPattern"===e.left.type&&e.left.properties.forEach((n=>{s(e.left,t,fr.getStaticPropertyName(n))}))}}return t.forEach((e=>{const t=e.object,s=e.property;void 0===t?o.set(s,{message:e.message}):void 0===s?r.set(t,{message:e.message}):(n.has(t)||n.set(t,new Map),n.get(t).set(s,{message:e.message}))})),{MemberExpression(e){s(e,e.object&&e.object.name,fr.getStaticPropertyName(e))},VariableDeclarator(e){if(e.init&&"Identifier"===e.init.type){const t=e.init.name;"ObjectPattern"===e.id.type&&e.id.properties.forEach((n=>{s(e.id,t,fr.getStaticPropertyName(n))}))}},AssignmentExpression:a,AssignmentPattern:a}}},bl={meta:{type:"suggestion",docs:{description:"disallow specified syntax",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/no-restricted-syntax"},schema:{type:"array",items:{oneOf:[{type:"string"},{type:"object",properties:{selector:{type:"string"},message:{type:"string"}},required:["selector"],additionalProperties:!1}]},uniqueItems:!0,minItems:0},messages:{restrictedSyntax:"{{message}}"}},create:e=>e.options.reduce(((t,n)=>{const r="string"==typeof n,o=!r&&Boolean(n.message),s=r?n:n.selector,a=o?n.message:`Using '${s}' is not allowed.`;return Object.assign(t,{[s](t){e.report({node:t,messageId:"restrictedSyntax",data:{message:a}})}})}),{})};const El=/^(?:[a-zA-Z]+?Statement|ArrowFunctionExpression|FunctionExpression|ClassExpression)$/u;var Sl={meta:{type:"suggestion",docs:{description:"disallow assignment operators in `return` statements",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-return-assign"},schema:[{enum:["except-parens","always"]}],messages:{returnAssignment:"Return statement should not contain assignment.",arrowAssignment:"Arrow function should not return assignment."}},create(e){const t="except-parens"!==(e.options[0]||"except-parens"),n=e.getSourceCode();return{AssignmentExpression(r){if(!t&&fr.isParenthesised(n,r))return;let o=r,s=o.parent;for(;s&&!El.test(s.type);)o=s,s=s.parent;s&&"ReturnStatement"===s.type?e.report({node:s,messageId:"returnAssignment"}):s&&"ArrowFunctionExpression"===s.type&&s.body===o&&e.report({node:s,messageId:"arrowAssignment"})}}}},Cl={meta:{type:"suggestion",docs:{description:"disallow unnecessary `return await`",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-return-await"},fixable:null,schema:[],messages:{redundantUseOfAwait:"Redundant use of `await` on a return value."}},create(e){function t(e){let t=e;for(;!fr.isFunction(t)&&"Program"!==t.type;){if("TryStatement"===t.parent.type&&(t===t.parent.block||t===t.parent.handler&&t.parent.finalizer))return!0;t=t.parent}return!1}function n(e){return"ArrowFunctionExpression"===e.parent.type||("ReturnStatement"===e.parent.type?!t(e.parent):"ConditionalExpression"!==e.parent.type||e!==e.parent.consequent&&e!==e.parent.alternate?("LogicalExpression"===e.parent.type&&e===e.parent.right||"SequenceExpression"===e.parent.type&&e===e.parent.expressions[e.parent.expressions.length-1])&&n(e.parent):n(e.parent))}return{AwaitExpression(r){n(r)&&!t(r)&&function(t){e.report({node:e.getSourceCode().getFirstToken(t),loc:t.loc,messageId:"redundantUseOfAwait"})}(r)}}}},vl={meta:{type:"suggestion",docs:{description:"disallow `javascript:` urls",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-script-url"},schema:[],messages:{unexpectedScriptURL:"Script URL is a form of eval."}},create(e){function t(t){const n=fr.getStaticStringValue(t);"string"==typeof n&&0===n.toLowerCase().indexOf("javascript:")&&e.report({node:t,messageId:"unexpectedScriptURL"})}return{Literal(e){e.value&&"string"==typeof e.value&&t(e)},TemplateLiteral(e){e.parent&&"TaggedTemplateExpression"===e.parent.type||t(e)}}}};const Al=/\s+/gu;function kl(e,t,n,r){if(e&&t)if("Identifier"===e.type&&"Identifier"===t.type&&e.name===t.name)r(t);else if("ArrayPattern"===e.type&&"ArrayExpression"===t.type){const o=Math.min(e.elements.length,t.elements.length);for(let s=0;s=1){let o=0;for(let e=t.properties.length-1;e>=0;--e){const n=t.properties[e].type;if("SpreadElement"===n||"ExperimentalSpreadProperty"===n){o=e+1;break}}for(let s=0;s","<",">=","<="]).has(n.operator)&&function(e,n){const r=t.getTokens(e),o=t.getTokens(n);return r.length===o.length&&r.every(((e,t)=>e.type===o[t].type&&e.value===o[t].value))}(n.left,n.right)&&e.report({node:n,messageId:"comparingToSelf"})}}}};const Tl={allowInParentheses:!0};var Il={meta:{type:"suggestion",docs:{description:"disallow comma operators",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-sequences"},schema:[{properties:{allowInParentheses:{type:"boolean",default:!0}},additionalProperties:!1}],messages:{unexpectedCommaExpression:"Unexpected use of comma operator."}},create(e){const t=Object.assign({},Tl,e.options[0]),n=e.getSourceCode(),r={DoWhileStatement:"test",IfStatement:"test",SwitchStatement:"discriminant",WhileStatement:"test",WithStatement:"object",ArrowFunctionExpression:"body"};function o(e){return fr.isParenthesised(n,e)}return{SequenceExpression(s){if("ForStatement"===s.parent.type&&(s===s.parent.init||s===s.parent.update))return;if(t.allowInParentheses)if(function(e){return e.parent&&r[e.parent.type]&&e===e.parent[r[e.parent.type]]}(s)){if(function(e){const t=n.getTokenBefore(e,1),r=n.getTokenAfter(e,1);return o(e)&&t&&r&&fr.isOpeningParenToken(t)&&t.range[1]<=e.range[0]&&fr.isClosingParenToken(r)&&r.range[0]>=e.range[1]}(s))return}else if(o(s))return;const a=n.getTokenAfter(s.expressions[0],fr.isCommaToken);e.report({node:s,loc:a.loc,messageId:"unexpectedCommaExpression"})}}}};const{findVariable:Fl}=G.default;function Dl(e,t,n,r,o){const s=e.parent;return"CallExpression"===s.type&&s.arguments[o]===e&&fr.isSpecificMemberAccess(s.callee,n,r)&&function(e,t){const n=Fl(t,e);return null!==n&&"global"===n.scope.type&&0===n.defs.length}(fr.skipChainExpression(s.callee).object,t)}function Ol(e,t){const n=e.parent;return"set"===n.kind&&n.value===e||!("Property"!==n.type||n.value!==e||"set"!==fr.getStaticPropertyName(n)||"ObjectExpression"!==n.parent.type||!function(e,t){if(Dl(e,t,"Object","defineProperty",2)||Dl(e,t,"Reflect","defineProperty",2))return!0;const n=e.parent;if("Property"===n.type&&n.value===e){const e=n.parent;if("ObjectExpression"===e.type&&(Dl(e,t,"Object","create",1)||Dl(e,t,"Object","defineProperties",1)))return!0}return!1}(n.parent,t))}var Bl={meta:{type:"problem",docs:{description:"disallow returning values from setters",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-setter-return"},schema:[],messages:{returnsValue:"Setter cannot return a value."}},create(e){let t=null;function n(n){const r=function(e){const t=e.upper;return"function-expression-name"===t.type?t.upper:t}(e.getScope());t={upper:t,isSetter:Ol(n,r)}}function r(){t=t.upper}function o(t){e.report({node:t,messageId:"returnsValue"})}return{FunctionDeclaration:n,FunctionExpression:n,ArrowFunctionExpression(e){n(e),t.isSetter&&e.expression&&o(e.body)},"FunctionDeclaration:exit":r,"FunctionExpression:exit":r,"ArrowFunctionExpression:exit":r,ReturnStatement(e){t&&t.isSetter&&e.argument&&o(e)}}}},Nl={meta:{type:"suggestion",docs:{description:"disallow variable declarations from shadowing variables declared in the outer scope",category:"Variables",recommended:!1,url:"https://eslint.org/docs/rules/no-shadow"},schema:[{type:"object",properties:{builtinGlobals:{type:"boolean",default:!1},hoist:{enum:["all","functions","never"],default:"functions"},allow:{type:"array",items:{type:"string"}}},additionalProperties:!1}],messages:{noShadow:"'{{name}}' is already declared in the upper scope on line {{shadowedLine}} column {{shadowedColumn}}.",noShadowGlobal:"'{{name}}' is already a global variable."}},create(e){const t={builtinGlobals:e.options[0]&&e.options[0].builtinGlobals,hoist:e.options[0]&&e.options[0].hoist||"functions",allow:e.options[0]&&e.options[0].allow||[]};function n(e){return-1!==t.allow.indexOf(e.name)}function r(e){const t=e.scope.block;return"ClassDeclaration"===t.type&&t.id===e.identifiers[0]}function o(e,t){const n=t.scope,r=t.defs[0],o=r&&r.parent&&r.parent.range,s=e.scope,a=e.defs[0],i=a&&a.name.range;return o&&i&&o[0]0||t.builtinGlobals&&"writeable"in p)&&!o(u,p)&&("all"===t.hoist||!i(u,p))){const t=a(p),n=t.global?"noShadowGlobal":"noShadow",r={name:u.name};t.global||(r.shadowedLine=t.line,r.shadowedColumn=t.column),e.report({node:u.identifiers[0],messageId:n,data:r})}}}return{"Program:exit"(){const t=e.getScope().childScopes.slice();for(;t.length;){const e=t.pop();t.push(...e.childScopes),c(e)}}}}};function jl(e){return"undefined"===e.name&&e.references.every((e=>!e.isWrite()))&&e.defs.every((e=>"VariableDeclarator"===e.node.type&&null===e.node.init))}var Ll={meta:{type:"suggestion",docs:{description:"disallow identifiers from shadowing restricted names",category:"Variables",recommended:!0,url:"https://eslint.org/docs/rules/no-shadow-restricted-names"},schema:[],messages:{shadowingRestrictedName:"Shadowing of global property '{{name}}'."}},create(e){const t=new Set(["undefined","NaN","Infinity","arguments","eval"]);return{"VariableDeclaration, :function, CatchClause"(n){for(const r of e.getDeclaredVariables(n))r.defs.length>0&&t.has(r.name)&&!jl(r)&&e.report({node:r.defs[0].name,messageId:"shadowingRestrictedName",data:{name:r.name}})}}}},Rl={meta:{type:"layout",docs:{description:"disallow spacing between function identifiers and their applications (deprecated)",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/no-spaced-func"},deprecated:!0,replacedBy:["func-call-spacing"],fixable:"whitespace",schema:[],messages:{noSpacedFunction:"Unexpected space between function name and paren."}},create(e){const t=e.getSourceCode();function n(n){const r=t.getLastToken(n.callee);let o=r,s=t.getTokenAfter(r);for(;s&&s.range[1]e.removeRange([o.range[1],s.range[0]])})}return{CallExpression:n,NewExpression:n}}},Ml={meta:{type:"problem",docs:{description:"disallow sparse arrays",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-sparse-arrays"},schema:[],messages:{unexpectedSparseArray:"Unexpected comma in middle of array."}},create:e=>({ArrayExpression(t){t.elements.indexOf(null)>-1&&e.report({node:t,messageId:"unexpectedSparseArray"})}})},_l={meta:{deprecated:!0,replacedBy:[],type:"suggestion",docs:{description:"disallow synchronous methods",category:"Node.js and CommonJS",recommended:!1,url:"https://eslint.org/docs/rules/no-sync"},schema:[{type:"object",properties:{allowAtRootLevel:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{noSync:"Unexpected sync method: '{{propertyName}}'."}},create:e=>({[e.options[0]&&e.options[0].allowAtRootLevel?":function MemberExpression[property.name=/.*Sync$/]":"MemberExpression[property.name=/.*Sync$/]"](t){e.report({node:t,messageId:"noSync",data:{propertyName:t.property.name}})}})};const $l=/\t+/gu,ql=/\S/u;var Ul={meta:{type:"layout",docs:{description:"disallow all tabs",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/no-tabs"},schema:[{type:"object",properties:{allowIndentationTabs:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{unexpectedTab:"Unexpected tab character."}},create(e){const t=e.getSourceCode(),n=e.options&&e.options[0]&&e.options[0].allowIndentationTabs;return{Program(r){t.getLines().forEach(((t,o)=>{let s;for(;null!==(s=$l.exec(t));)n&&!ql.test(t.slice(0,s.index))||e.report({node:r,loc:{start:{line:o+1,column:s.index},end:{line:o+1,column:s.index+s[0].length}},messageId:"unexpectedTab"})}))}}}},Vl={meta:{type:"problem",docs:{description:"disallow template literal placeholder syntax in regular strings",category:"Possible Errors",recommended:!1,url:"https://eslint.org/docs/rules/no-template-curly-in-string"},schema:[],messages:{unexpectedTemplateExpression:"Unexpected template string expression."}},create(e){const t=/\$\{[^}]+\}/u;return{Literal(n){"string"==typeof n.value&&t.test(n.value)&&e.report({node:n,messageId:"unexpectedTemplateExpression"})}}}},Wl={meta:{type:"suggestion",docs:{description:"disallow ternary operators",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/no-ternary"},schema:[],messages:{noTernaryOperator:"Ternary operator used."}},create:e=>({ConditionalExpression(t){e.report({node:t,messageId:"noTernaryOperator"})}})};var Gl={meta:{type:"problem",docs:{description:"disallow `this`/`super` before calling `super()` in constructors",category:"ECMAScript 6",recommended:!0,url:"https://eslint.org/docs/rules/no-this-before-super"},schema:[],messages:{noBeforeSuper:"'{{kind}}' is not allowed before 'super()'."}},create(e){let t=null,n=Object.create(null);function r(e){return!e.reachable||n[e.id].superCalled}function o(){return Boolean(t&&t.isConstructor&&t.hasExtends)}function s(){return o()&&!t.codePath.currentSegments.every(r)}function a(e){const r=t.codePath.currentSegments;for(let t=0;t{const o=n[t.id];for(let t=0;t0&&e.prevSegments.every(r),invalidNodes:[]})},onCodePathSegmentLoop(e,s){o()&&t.codePath.traverseSegments({first:s,last:e},((e,t)=>{const o=n[e.id];o.superCalled?(o.invalidNodes=[],t.skip()):e.prevSegments.length>0&&e.prevSegments.every(r)&&(o.superCalled=!0,o.invalidNodes=[])}))},ThisExpression(e){s()&&a(e)},Super(e){!fr.isCallee(e)&&s()&&a(e)},"CallExpression:exit"(e){"Super"===e.callee.type&&s()&&function(){const e=t.codePath.currentSegments;for(let t=0;t({ThrowStatement(t){fr.couldBeError(t.argument)?"Identifier"===t.argument.type&&"undefined"===t.argument.name&&e.report({node:t,messageId:"undef"}):e.report({node:t,messageId:"object"})}})},Jl={meta:{type:"layout",docs:{description:"disallow trailing whitespace at the end of lines",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/no-trailing-spaces"},fixable:"whitespace",schema:[{type:"object",properties:{skipBlankLines:{type:"boolean",default:!1},ignoreComments:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{trailingSpace:"Trailing spaces not allowed."}},create(e){const t=e.getSourceCode(),n=e.options[0]||{},r=n.skipBlankLines||!1,o=n.ignoreComments||!1;function s(t,n,r){e.report({node:t,loc:n,messageId:"trailingSpace",fix:e=>e.removeRange(r)})}return{Program:function(e){const n=new RegExp("[ \t  -​ ]+$","u"),a=new RegExp("^[ \t  -​ ]*$","u"),i=t.lines,c=t.getText().match(fr.createGlobalLinebreakMatcher()),l=function(e){const t=new Set;return e.forEach((e=>{const n="Block"===e.type?e.loc.end.line-1:e.loc.end.line;for(let r=e.loc.start.line;r<=n;r++)t.add(r)})),t}(t.getAllComments());let u=0,p=[];for(let d=0,f=i.length;dx.parent.range[0]&&y{const r=t.identifier;!n&&function(e){const t=e.parent;return"UnaryExpression"===t.type&&"typeof"===t.operator}(r)||e.report({node:r,messageId:"undef",data:r})}))}}}},Yl={meta:{type:"suggestion",docs:{description:"disallow initializing variables to `undefined`",category:"Variables",recommended:!1,url:"https://eslint.org/docs/rules/no-undef-init"},schema:[],fixable:"code",messages:{unnecessaryUndefinedInit:"It's not necessary to initialize '{{name}}' to undefined."}},create(e){const t=e.getSourceCode();return{VariableDeclarator(n){const r=t.getText(n.id),o=n.init&&n.init.name,s=e.getScope(),a=fr.getVariableByName(s,"undefined"),i=a&&a.defs.length>0,c=t.getLastToken(n);"undefined"!==o||"const"===n.parent.kind||i||e.report({node:n,messageId:"unnecessaryUndefinedInit",data:{name:r},fix:e=>"var"===n.parent.kind||"ArrayPattern"===n.id.type||"ObjectPattern"===n.id.type||t.commentsExistBetween(n.id,c)?null:e.removeRange([n.id.range[1],n.range[1]])})}}}},Hl={meta:{type:"suggestion",docs:{description:"disallow the use of `undefined` as an identifier",category:"Variables",recommended:!1,url:"https://eslint.org/docs/rules/no-undefined"},schema:[],messages:{unexpectedUndefined:"Unexpected use of undefined."}},create(e){function t(t){e.report({node:t,messageId:"unexpectedUndefined"})}function n(e){const n=e.set.get("undefined");if(!n)return;const r=n.references,o=n.defs;r.filter((e=>!e.init)).forEach((e=>t(e.identifier))),o.forEach((e=>t(e.name)))}return{"Program:exit"(){const t=[e.getScope()];for(;t.length;){const e=t.pop();t.push(...e.childScopes),n(e)}}}}},Xl={meta:{type:"suggestion",docs:{description:"disallow dangling underscores in identifiers",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/no-underscore-dangle"},schema:[{type:"object",properties:{allow:{type:"array",items:{type:"string"}},allowAfterThis:{type:"boolean",default:!1},allowAfterSuper:{type:"boolean",default:!1},allowAfterThisConstructor:{type:"boolean",default:!1},enforceInMethodNames:{type:"boolean",default:!1},allowFunctionParams:{type:"boolean",default:!0}},additionalProperties:!1}],messages:{unexpectedUnderscore:"Unexpected dangling '_' in '{{identifier}}'."}},create(e){const t=e.options[0]||{},n=t.allow?t.allow:[],r=void 0!==t.allowAfterThis&&t.allowAfterThis,o=void 0!==t.allowAfterSuper&&t.allowAfterSuper,s=void 0!==t.allowAfterThisConstructor&&t.allowAfterThisConstructor,a=void 0!==t.enforceInMethodNames&&t.enforceInMethodNames,i=void 0===t.allowFunctionParams||t.allowFunctionParams;function c(e){return n.some((t=>t===e))}function l(e){const t=e.length;return"_"!==e&&("_"===e[0]||"_"===e[t-1])}function u(t){if("FunctionDeclaration"===t.type&&t.id){const n=t.id.name;void 0!==n&&l(n)&&!c(n)&&e.report({node:t,messageId:"unexpectedUnderscore",data:{identifier:n}})}!function(t){i||t.params.forEach((t=>{const{type:n}=t;let r;if(r="RestElement"===n?t.argument:"AssignmentPattern"===n?t.left:t,"Identifier"===r.type){const n=r.name;l(n)&&!c(n)&&e.report({node:t,messageId:"unexpectedUnderscore",data:{identifier:n}})}}))}(t)}function p(t){const n=t.key.name,r="MethodDefinition"===t.type||"Property"===t.type&&t.method;void 0!==n&&a&&r&&l(n)&&!c(n)&&e.report({node:t,messageId:"unexpectedUnderscore",data:{identifier:n}})}return{FunctionDeclaration:u,VariableDeclarator:function(t){const n=t.id.name;void 0===n||!l(n)||function(e){return"_"===e}(n)||c(n)||e.report({node:t,messageId:"unexpectedUnderscore",data:{identifier:n}})},MemberExpression:function(t){const n=t.property.name,a="ThisExpression"===t.object.type,i="Super"===t.object.type,u=function(e){return"MemberExpression"===e.object.type&&"constructor"===e.object.property.name&&"ThisExpression"===e.object.object.type}(t);void 0===n||!l(n)||a&&r||i&&o||u&&s||function(e){return"__proto__"===e}(n)||c(n)||e.report({node:t,messageId:"unexpectedUnderscore",data:{identifier:n}})},MethodDefinition:p,Property:p,FunctionExpression:u,ArrowFunctionExpression:u}}},Ql={meta:{type:"problem",docs:{description:"disallow confusing multiline expressions",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-unexpected-multiline"},schema:[],messages:{function:"Unexpected newline between function and ( of function call.",property:"Unexpected newline between object and [ of property access.",taggedTemplate:"Unexpected newline between template tag and template literal.",division:"Unexpected newline between numerator and division operator."}},create(e){const t=/^[gimsuy]+$/u,n=e.getSourceCode();function r(t,r){const o=n.getTokenAfter(t,fr.isNotClosingParenToken),s=n.getTokenBefore(o);o.loc.start.line!==s.loc.end.line&&e.report({node:t,loc:o.loc,messageId:r})}return{MemberExpression(e){e.computed&&!e.optional&&r(e.object,"property")},TaggedTemplateExpression(t){const{quasi:r}=t;n.getTokenBefore(r).loc.end.line!==r.loc.start.line&&e.report({node:t,loc:{start:r.loc.start,end:{line:r.loc.start.line,column:r.loc.start.column+1}},messageId:"taggedTemplate"})},CallExpression(e){0===e.arguments.length||e.optional||r(e.callee,"function")},"BinaryExpression[operator='/'] > BinaryExpression[operator='/'].left"(e){const o=n.getTokenAfter(e,(e=>"/"===e.value)),s=n.getTokenAfter(o);"Identifier"===s.type&&t.test(s.value)&&o.range[1]===s.range[0]&&r(e.left,"division")}}}};const Zl=/(?:(?:Call|Class|Function|Member|New|Yield)Expression|Statement|Declaration)$/u,eu=/^(?:DoWhile|For|While)Statement$/u,tu=/^(?:BinaryExpression|ConditionalExpression)$/u,nu=/^(?:ArrowFunction|Class|Function)Expression$/u,ru=/^(?:Call|Member|New|TaggedTemplate|Yield)Expression$/u;function ou(e){if(e.init){const t=e.resolved&&e.resolved.defs[0];if(!t||"Variable"!==t.type||"var"!==t.parent.kind)return!1}return e.isWrite()}function su(e){return!e.modified}function au(e){return!(e.modified||e.group)}function iu(e,t){const n=e.range,r=t.identifier.range;return n[0]<=r[0]&&r[1]<=n[1]}const cu={WhileStatement:iu,DoWhileStatement:iu,ForStatement:(e,t)=>iu(e,t)&&!(e.init&&iu(e.init,t))};function lu(e){let t=e.identifier;for(;t;){if("FunctionDeclaration"===t.type)return t.id?t:null;t=t.parent}return null}var uu={meta:{type:"problem",docs:{description:"disallow unmodified loop conditions",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-unmodified-loop-condition"},schema:[],messages:{loopConditionNotModified:"'{{name}}' is not modified in this loop."}},create(e){const t=e.getSourceCode();let n=null;function r(t){const n=t.reference.identifier;e.report({node:n,messageId:"loopConditionNotModified",data:n})}function o(e){e.every(su)&&e.forEach(r)}function s(e){let n=!1;return Vt.traverse(e,{visitorKeys:t.visitorKeys,enter(e){ru.test(e.type)?(n=!0,this.break()):nu.test(e.type)&&this.skip()}}),n}function a(e){if(e.init)return null;let t=null,n=e.identifier,r=n.parent;for(;r;){if(Zl.test(r.type)){if(eu.test(r.type)&&r.test===n)return{reference:e,group:t,isInLoop:cu[r.type].bind(null,r),modified:!1};break}if(tu.test(r.type)){if(s(r))break;t=r}n=r,r=r.parent}return null}function i(e){const t=e.references.map(a).filter(Boolean);if(0===t.length)return;!function(e){for(let t=0;t0&&function(e,t){for(let n=0;n",">=","<","<=","in","instanceof"]),du={"==":"!=","!=":"==","===":"!==","!==":"==="},fu=fr.getPrecedence({type:"LogicalExpression",operator:"||"});var mu={meta:{type:"suggestion",docs:{description:"disallow ternary operators when simpler alternatives exist",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/no-unneeded-ternary"},schema:[{type:"object",properties:{defaultAssignment:{type:"boolean",default:!0}},additionalProperties:!1}],fixable:"code",messages:{unnecessaryConditionalExpression:"Unnecessary use of boolean literals in conditional expression.",unnecessaryConditionalAssignment:"Unnecessary use of conditional expression for default assignment."}},create(e){const t=!1!==(e.options[0]||{}).defaultAssignment,n=e.getSourceCode();function r(e){return"Literal"===e.type&&"boolean"==typeof e.value}function o(e){if("BinaryExpression"===e.type&&Object.prototype.hasOwnProperty.call(du,e.operator)){const t=n.getFirstTokenBetween(e.left,e.right,(t=>t.value===e.operator)),r=n.getText();return r.slice(e.range[0],t.range[0])+du[e.operator]+r.slice(t.range[1],e.range[1])}return fr.getPrecedence(e)s.consequent.value===s.alternate.value?"Identifier"===s.test.type?e.replaceText(s,s.consequent.value.toString()):null:s.alternate.value?e.replaceText(s,o(s.test)):e.replaceText(s,function(e){return"BinaryExpression"===e.type&&pu.has(e.operator)||"UnaryExpression"===e.type&&"!"===e.operator}(s.test)?fr.getParenthesisedText(n,s.test):`!${o(s.test)}`)}):!t&&function(e){return"Identifier"===e.test.type&&"Identifier"===e.consequent.type&&e.test.name===e.consequent.name}(s)&&e.report({node:s,messageId:"unnecessaryConditionalAssignment",fix:e=>{const t=(fr.getPrecedence(s.alternate)=this.startNode.range[0]&&e.range[1]<=this.endNode.range[1]}isConsecutive(e){return this.contains(this.sourceCode.getTokenBefore(e))}merge(e){this.endNode=e}reset(e){this.startNode=this.endNode=e}}var xu={meta:{type:"problem",docs:{description:"disallow unreachable code after `return`, `throw`, `continue`, and `break` statements",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-unreachable"},schema:[],messages:{unreachableCode:"Unreachable code."}},create(e){let t=null;const n=new yu(e.getSourceCode());function r(r){let o=null;if(r&&t.currentSegments.every(hu)){if(n.isEmpty)return void n.reset(r);if(n.contains(r))return;if(n.isConsecutive(r))return void n.merge(r);o=r}n.isEmpty||e.report({messageId:"unreachableCode",loc:n.location,node:n.startNode}),n.reset(o)}return{onCodePathStart(e){t=e},onCodePathEnd(){t=t.upper},BlockStatement:r,BreakStatement:r,ClassDeclaration:r,ContinueStatement:r,DebuggerStatement:r,DoWhileStatement:r,ExpressionStatement:r,ForInStatement:r,ForOfStatement:r,ForStatement:r,IfStatement:r,ImportDeclaration:r,LabeledStatement:r,ReturnStatement:r,SwitchStatement:r,ThrowStatement:r,TryStatement:r,VariableDeclaration(e){("var"!==e.kind||e.declarations.some(gu))&&r(e)},WhileStatement:r,WithStatement:r,ExportNamedDeclaration:r,ExportDefaultDeclaration:r,ExportAllDeclaration:r,"Program:exit"(){r()}}}};const bu=["WhileStatement","DoWhileStatement","ForStatement","ForInStatement","ForOfStatement"];var Eu={meta:{type:"problem",docs:{description:"disallow loops with a body that allows only one iteration",category:"Possible Errors",recommended:!1,url:"https://eslint.org/docs/rules/no-unreachable-loop"},schema:[{type:"object",properties:{ignore:{type:"array",items:{enum:bu},uniqueItems:!0}},additionalProperties:!1}],messages:{invalid:"Invalid loop. Its body allows only one iteration."}},create(e){const t=e.options[0]&&e.options[0].ignore||[],n=(s=t,bu.filter((e=>!s.includes(e)))).join(","),r=new Map,o=new Set;var s;let a=null;return{onCodePathStart(e){a=e},onCodePathEnd(){a=a.upper},[n](e){a.currentSegments.some((e=>e.reachable))&&o.add(e)},onCodePathSegmentStart(e,t){if(function(e){const t=e.parent;if(t)switch(t.type){case"WhileStatement":return e===t.test;case"DoWhileStatement":return e===t.body;case"ForStatement":return e===(t.update||t.test||t.body);case"ForInStatement":case"ForOfStatement":return e===t.left}return!1}(t)){const n=t.parent;r.set(e,n)}},onCodePathSegmentLoop(e,t,n){const s=r.get(t);n!==s&&"ContinueStatement"!==n.type||o.delete(s)},"Program:exit"(){o.forEach((t=>e.report({node:t,messageId:"invalid"})))}}}};const Su=/^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression)$/u,Cu=/^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|DoWhileStatement|WhileStatement|ForOfStatement|ForInStatement|ForStatement|SwitchStatement)$/u,vu=/^(?:Program|(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|DoWhileStatement|WhileStatement|ForOfStatement|ForInStatement|ForStatement)$/u;var Au={meta:{type:"problem",docs:{description:"disallow control flow statements in `finally` blocks",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-unsafe-finally"},schema:[],messages:{unsafeUsage:"Unsafe usage of {{nodeType}}."}},create(e){function t(e){return"TryStatement"===e.parent.type&&e.parent.finalizer===e}function n(n){(function(e,n){let r,o=!1;r="BreakStatement"!==e.type||e.label?"ContinueStatement"===e.type?vu:Su:Cu;for(let s=e;s&&!r.test(s.type);s=s.parent)if(s.parent.label&&n&&s.parent.label.name===n.name&&(o=!0),t(s))return!n||!o;return!1})(n,n.label)&&e.report({messageId:"unsafeUsage",data:{nodeType:n.type},node:n,line:n.loc.line,column:n.loc.column})}return{ReturnStatement:n,ThrowStatement:n,BreakStatement:n,ContinueStatement:n}}};var ku={meta:{type:"problem",docs:{description:"disallow negating the left operand of relational operators",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/no-unsafe-negation",suggestion:!0},schema:[{type:"object",properties:{enforceForOrderingRelations:{type:"boolean",default:!1}},additionalProperties:!1}],fixable:null,messages:{unexpected:"Unexpected negating the left operand of '{{operator}}' operator.",suggestNegatedExpression:"Negate '{{operator}}' expression instead of its left operand. This changes the current behavior.",suggestParenthesisedNegation:"Wrap negation in '()' to make the intention explicit. This preserves the current behavior."}},create(e){const t=e.getSourceCode(),n=!0===(e.options[0]||{}).enforceForOrderingRelations;return{BinaryExpression(r){const o=r.operator,s=n&&("<"===(a=o)||">"===a||">="===a||"<="===a);var a;(function(e){return"in"===e||"instanceof"===e}(o)||s)&&function(e){return"UnaryExpression"===e.type&&"!"===e.operator}(r.left)&&!fr.isParenthesised(t,r.left)&&e.report({node:r,loc:r.left.loc,messageId:"unexpected",data:{operator:o},suggest:[{messageId:"suggestNegatedExpression",data:{operator:o},fix(e){const n=[t.getFirstToken(r.left).range[1],r.range[1]],o=t.text.slice(n[0],n[1]);return e.replaceTextRange(n,`(${o})`)}},{messageId:"suggestParenthesisedNegation",fix:e=>e.replaceText(r.left,`(${t.getText(r.left)})`)}]})}}}};const wu=new Set(["+","-","/","*","%","**"]),Pu=new Set(["+=","-=","/=","*=","%=","**="]),Tu=new Set(["in","instanceof"]);function Iu(e){return"ObjectPattern"===e.type||"ArrayPattern"===e.type}var Fu={meta:{type:"problem",docs:{description:"disallow use of optional chaining in contexts where the `undefined` value is not allowed",category:"Possible Errors",recommended:!1,url:"https://eslint.org/docs/rules/no-unsafe-optional-chaining"},schema:[{type:"object",properties:{disallowArithmeticOperators:{type:"boolean",default:!1}},additionalProperties:!1}],fixable:null,messages:{unsafeOptionalChain:"Unsafe usage of optional chaining. If it short-circuits with 'undefined' the evaluation will throw TypeError.",unsafeArithmetic:"Unsafe arithmetic operation on optional chaining. It can result in NaN."}},create(e){const t=(e.options[0]||{}).disallowArithmeticOperators||!1;function n(t){e.report({messageId:"unsafeOptionalChain",node:t})}function r(t){e.report({messageId:"unsafeArithmetic",node:t})}function o(e,t){if(e)switch(e.type){case"LogicalExpression":"||"===e.operator||"??"===e.operator?o(e.right,t):"&&"===e.operator&&(o(e.left,t),o(e.right,t));break;case"SequenceExpression":o(e.expressions[e.expressions.length-1],t);break;case"ConditionalExpression":o(e.consequent,t),o(e.alternate,t);break;case"AwaitExpression":o(e.argument,t);break;case"ChainExpression":t(e)}}function s(e){o(e,n)}function a(e){o(e,r)}return{"AssignmentExpression, AssignmentPattern"(e){Iu(e.left)&&s(e.right)},"ClassDeclaration, ClassExpression"(e){s(e.superClass)},CallExpression(e){e.optional||s(e.callee)},NewExpression(e){s(e.callee)},VariableDeclarator(e){Iu(e.id)&&s(e.init)},MemberExpression(e){e.optional||s(e.object)},TaggedTemplateExpression(e){s(e.tag)},ForOfStatement(e){s(e.right)},SpreadElement(e){e.parent&&"ObjectExpression"!==e.parent.type&&s(e.argument)},BinaryExpression(e){Tu.has(e.operator)&&s(e.right),t&&wu.has(e.operator)&&(a(e.right),a(e.left))},WithStatement(e){s(e.object)},UnaryExpression(e){t&&wu.has(e.operator)&&a(e.argument)},AssignmentExpression(e){t&&Pu.has(e.operator)&&a(e.right)}}}};function Du(){return!0}function Ou(){return!1}var Bu={meta:{type:"suggestion",docs:{description:"disallow unused expressions",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-unused-expressions"},schema:[{type:"object",properties:{allowShortCircuit:{type:"boolean",default:!1},allowTernary:{type:"boolean",default:!1},allowTaggedTemplates:{type:"boolean",default:!1},enforceForJSX:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{unusedExpression:"Expected an assignment or function call and instead saw an expression."}},create(e){const t=e.options[0]||{},n=t.allowShortCircuit||!1,r=t.allowTernary||!1,o=t.allowTaggedTemplates||!1,s=t.enforceForJSX||!1;function a(e){return"ExpressionStatement"===e.type&&"Literal"===e.expression.type&&"string"==typeof e.expression.value}function i(e,t){const n=t[t.length-1],r=t[t.length-2];return("Program"===n.type||"BlockStatement"===n.type&&/Function/u.test(r.type))&&function(e){return function(e,t){for(let n=0;n=0}const c=Object.assign(Object.create(null),{isDisallowed:e=>(c[e.type]||Ou)(e),ArrayExpression:Du,ArrowFunctionExpression:Du,BinaryExpression:Du,ChainExpression:e=>c.isDisallowed(e.expression),ClassExpression:Du,ConditionalExpression:e=>!r||(c.isDisallowed(e.consequent)||c.isDisallowed(e.alternate)),FunctionExpression:Du,Identifier:Du,JSXElement:()=>s,JSXFragment:()=>s,Literal:Du,LogicalExpression:e=>!n||c.isDisallowed(e.right),MemberExpression:Du,MetaProperty:Du,ObjectExpression:Du,SequenceExpression:Du,TaggedTemplateExpression:()=>!o,TemplateLiteral:Du,ThisExpression:Du,UnaryExpression:e=>"void"!==e.operator&&"delete"!==e.operator});return{ExpressionStatement(t){c.isDisallowed(t.expression)&&!i(t,e.getAncestors())&&e.report({node:t,messageId:"unusedExpression"})}}}},Nu={meta:{type:"suggestion",docs:{description:"disallow unused labels",category:"Best Practices",recommended:!0,url:"https://eslint.org/docs/rules/no-unused-labels"},schema:[],fixable:"code",messages:{unused:"'{{name}}:' is defined but never used."}},create(e){const t=e.getSourceCode();let n=null;function r(e){if(!e.label)return;const t=e.label.name;let r=n;for(;r;){if(r.label===t){r.used=!0;break}r=r.upper}}return{LabeledStatement:function(e){n={label:e.label.name,used:!1,upper:n}},"LabeledStatement:exit":function(r){n.used||e.report({node:r.label,messageId:"unused",data:r.label,fix:e=>t.getTokenAfter(r.label,{includeComments:!0})===t.getTokenBefore(r.body,{includeComments:!0})?e.removeRange([r.range[0],r.body.range[0]]):null}),n=n.upper},BreakStatement:r,ContinueStatement:r}}},ju={meta:{type:"problem",docs:{description:"disallow unused variables",category:"Variables",recommended:!0,url:"https://eslint.org/docs/rules/no-unused-vars"},schema:[{oneOf:[{enum:["all","local"]},{type:"object",properties:{vars:{enum:["all","local"]},varsIgnorePattern:{type:"string"},args:{enum:["all","after-used","none"]},ignoreRestSiblings:{type:"boolean"},argsIgnorePattern:{type:"string"},caughtErrors:{enum:["all","none"]},caughtErrorsIgnorePattern:{type:"string"}},additionalProperties:!1}]}],messages:{unusedVar:"'{{varName}}' is {{action}} but never used{{additional}}."}},create(e){const t=e.getSourceCode(),n=/^(?:RestElement|(?:Experimental)?RestProperty)$/u,r={vars:"all",args:"after-used",ignoreRestSiblings:!1,caughtErrors:"none"},o=e.options[0];function s(e){const t=e.defs&&e.defs[0]&&e.defs[0].type;let n,o;"CatchClause"===t&&r.caughtErrorsIgnorePattern?(n="args",o=r.caughtErrorsIgnorePattern.toString()):"Parameter"===t&&r.argsIgnorePattern?(n="args",o=r.argsIgnorePattern.toString()):"Parameter"!==t&&r.varsIgnorePattern&&(n="vars",o=r.varsIgnorePattern.toString());const s=n?`. Allowed unused ${n} must match ${o}`:"";return{varName:e.name,action:"defined",additional:s}}function a(e){const t=r.varsIgnorePattern?`. Allowed unused vars must match ${r.varsIgnorePattern.toString()}`:"";return{varName:e.name,action:"assigned a value",additional:t}}o&&("string"==typeof o?r.vars=o:(r.vars=o.vars||r.vars,r.args=o.args||r.args,r.ignoreRestSiblings=o.ignoreRestSiblings||r.ignoreRestSiblings,r.caughtErrors=o.caughtErrors||r.caughtErrors,o.varsIgnorePattern&&(r.varsIgnorePattern=new RegExp(o.varsIgnorePattern,"u")),o.argsIgnorePattern&&(r.argsIgnorePattern=new RegExp(o.argsIgnorePattern,"u")),o.caughtErrorsIgnorePattern&&(r.caughtErrorsIgnorePattern=new RegExp(o.caughtErrorsIgnorePattern,"u"))));const i=/(?:Statement|Declaration)$/u;function c(e){const t=e.defs[0];if(t){let e=t.node;if("VariableDeclarator"===e.type)e=e.parent;else if("Parameter"===t.type)return!1;return 0===e.parent.type.indexOf("Export")}return!1}function l(e){return"Property"===e.type&&"ObjectPattern"===e.parent.type&&n.test(e.parent.properties[e.parent.properties.length-1].type)}function u(e){if(r.ignoreRestSiblings){const t=e.defs.some((e=>l(e.name.parent))),n=e.references.some((e=>l(e.identifier.parent)));return t||n}return!1}function p(e,t){return e.range[0]>=t.range[0]&&e.range[1]<=t.range[1]}function d(e,t){const n=fr.getUpperFunction(e);return n&&p(n,t)&&function(e,t){let n=e,r=e.parent;for(;r&&p(r,t);){switch(r.type){case"SequenceExpression":if(r.expressions[r.expressions.length-1]!==n)return!1;break;case"CallExpression":case"NewExpression":return r.callee!==n;case"AssignmentExpression":case"TaggedTemplateExpression":case"YieldExpression":return!0;default:if(i.test(r.type))return!0}n=r,r=r.parent}return!1}(n,t)}function f(e){const t=function(e){const t=[];return e.defs.forEach((e=>{const{type:n,node:r}=e;"FunctionName"===n&&t.push(r),"Variable"!==n||!r.init||"FunctionExpression"!==r.init.type&&"ArrowFunctionExpression"!==r.init.type||t.push(r.init)})),t}(e),n=t.length>0;let r=null;return e.references.some((e=>{if(function(e){let t=e.identifier.parent;return"VariableDeclarator"===t.type&&(t=t.parent.parent),"ForInStatement"===t.type&&(t="BlockStatement"===t.body.type?t.body.body[0]:t.body,!!t&&"ReturnStatement"===t.type)}(e))return!0;const o=function(e,t){const n=e.identifier,r=n.parent,o=r.parent;return e.isRead()&&("AssignmentExpression"===r.type&&"ExpressionStatement"===o.type&&r.left===n||"UpdateExpression"===r.type&&"ExpressionStatement"===o.type||t&&p(n,t)&&!d(n,t))}(e,r);return r=function(e,t){const n=e.identifier,r=n.parent,o=r.parent,s=e.from.variableScope!==e.resolved.scope.variableScope||fr.isInLoop(n);return t&&p(n,t)?t:"AssignmentExpression"!==r.type||"ExpressionStatement"!==o.type||n!==r.left||s?null:r.right}(e,r),function(e){return e.isRead()}(e)&&!o&&!(n&&function(e,t){let n=e.from;for(;n;){if(t.indexOf(n.block)>=0)return!0;n=n.upper}return!1}(e,t))}))}function m(t){const n=t.defs[0],r=e.getDeclaredVariables(n.node);return!r.slice(r.indexOf(t)+1).some((e=>e.references.length>0||e.eslintUsed))}function g(e,t){const n=e.variables,o=e.childScopes;let s,a;if("global"!==e.type||"all"===r.vars)for(s=0,a=n.length;s0)e.report({node:i.references.length?i.references[i.references.length-1].identifier:i.identifiers[0],messageId:"unusedVar",data:i.references.some((e=>e.isWrite()))?a(i):s(i)});else if(i.eslintExplicitGlobalComments){const r=i.eslintExplicitGlobalComments[0];e.report({node:n,loc:fr.getNameLocationInGlobalDirectiveComment(t,r,i.name),messageId:"unusedVar",data:s(i)})}}}}}};const Lu=/^(?:(?:Function|Class)(?:Declaration|Expression)|ArrowFunctionExpression|CatchClause|ImportDeclaration|ExportNamedDeclaration)$/u,Ru=/^For(?:In|Of)Statement$/u;function Mu(e,t){return e&&e.range[0]<=t&&t<=e.range[1]}var _u={meta:{type:"problem",docs:{description:"disallow the use of variables before they are defined",category:"Variables",recommended:!1,url:"https://eslint.org/docs/rules/no-use-before-define"},schema:[{oneOf:[{enum:["nofunc"]},{type:"object",properties:{functions:{type:"boolean"},classes:{type:"boolean"},variables:{type:"boolean"}},additionalProperties:!1}]}],messages:{usedBeforeDefined:"'{{name}}' was used before it was defined."}},create(e){const t=function(e){let t=!0,n=!0,r=!0;return"string"==typeof e?t="nofunc"!==e:"object"==typeof e&&null!==e&&(t=!1!==e.functions,n=!1!==e.classes,r=!1!==e.variables),{functions:t,classes:n,variables:r}}(e.options[0]);function n(r){r.references.forEach((n=>{const r=n.resolved;n.init||!r||0===r.identifiers.length||r.identifiers[0].range[1]=1||"apply"===t.property.name&&2===e.arguments.length&&"ArrayExpression"===e.arguments[1].type)}(n))return;const r=fr.skipChainExpression(n.callee),o=fr.skipChainExpression(r.object);(function(e,t,n){return e?fr.equalTokens(e,t,n):fr.isNullOrUndefined(t)})("MemberExpression"===o.type?o.object:null,n.arguments[0],t)&&e.report({node:n,messageId:"unnecessaryCall",data:{name:r.property.name}})}}}},Qu={meta:{type:"suggestion",docs:{description:"disallow unnecessary `catch` clauses",category:"Best Practices",recommended:!0,url:"https://eslint.org/docs/rules/no-useless-catch"},schema:[],messages:{unnecessaryCatchClause:"Unnecessary catch clause.",unnecessaryCatch:"Unnecessary try/catch wrapper."}},create:e=>({CatchClause(t){t.param&&"Identifier"===t.param.type&&t.body.body.length&&"ThrowStatement"===t.body.body[0].type&&"Identifier"===t.body.body[0].argument.type&&t.body.body[0].argument.name===t.param.name&&(t.parent.finalizer?e.report({node:t,messageId:"unnecessaryCatchClause"}):e.report({node:t.parent,messageId:"unnecessaryCatch"}))}})},Zu={meta:{type:"suggestion",docs:{description:"disallow unnecessary computed property keys in objects and classes",category:"ECMAScript 6",recommended:!1,url:"https://eslint.org/docs/rules/no-useless-computed-key"},schema:[{type:"object",properties:{enforceForClassMembers:{type:"boolean",default:!1}},additionalProperties:!1}],fixable:"code",messages:{unnecessarilyComputedProperty:"Unnecessarily computed property [{{property}}] found."}},create(e){const t=e.getSourceCode();function n(n){if(!n.computed)return;const r=n.key,o=typeof r.value;let s;s="MethodDefinition"===n.type?n.static?"prototype":"constructor":"__proto__","Literal"!==r.type||"string"!==o&&"number"!==o||r.value===s||e.report({node:n,messageId:"unnecessarilyComputedProperty",data:{property:t.getText(r)},fix(e){const n=t.getTokenBefore(r,fr.isOpeningBracketToken),o=t.getTokenAfter(r,fr.isClosingBracketToken);if(t.commentsExistBetween(n,o))return null;const s=t.getTokenBefore(n),a=(s.range[1]===n.range[0]&&!fr.canTokensBeAdjacent(s,t.getFirstToken(r))?" ":"")+r.raw;return e.replaceTextRange([n.range[0],o.range[1]],a)}})}return{Property:n,MethodDefinition:e.options[0]&&e.options[0].enforceForClassMembers?n:F.default.noop}}};function ep(e){return"BinaryExpression"===e.type&&"+"===e.operator}function tp(e){return"+"===e.value&&"Punctuator"===e.type}var np={meta:{type:"suggestion",docs:{description:"disallow unnecessary concatenation of literals or template literals",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-useless-concat"},schema:[],messages:{unexpectedConcat:"Unexpected string concatenation of literals."}},create(e){const t=e.getSourceCode();return{BinaryExpression(n){if("+"!==n.operator)return;const r=function(e){let t=e.left;for(;ep(t);)t=t.right;return t}(n),o=function(e){let t=e.right;for(;ep(t);)t=t.left;return t}(n);if(fr.isStringLiteral(r)&&fr.isStringLiteral(o)&&fr.isTokenOnSameLine(r,o)){const s=t.getFirstTokenBetween(r,o,tp);e.report({node:n,loc:s.loc,messageId:"unexpectedConcat"})}}}}};function rp(e){return"Identifier"===e.type||"RestElement"===e.type}function op(e,t){return"Identifier"===e.type&&"Identifier"===t.type&&e.name===t.name}function sp(e,t){return op(e,t)||function(e,t){return"RestElement"===e.type&&"SpreadElement"===t.type&&op(e.argument,t.argument)}(e,t)}function ap(e,t){return function(e){return 1===e.length&&"ExpressionStatement"===e[0].type&&"CallExpression"===e[0].expression.type&&"Super"===e[0].expression.callee.type}(e)&&t.every(rp)&&(1===(n=e[0].expression.arguments).length&&"SpreadElement"===n[0].type&&"Identifier"===n[0].argument.type&&"arguments"===n[0].argument.name||function(e,t){if(e.length!==t.length)return!1;for(let n=0;n({MethodDefinition:function(t){if("constructor"!==t.kind)return;if(!t.value.body)return;const n=t.value.body.body,r=t.value.params;(t.parent.parent.superClass?ap(n,r):0===n.length)&&e.report({node:t,messageId:"noUselessConstructor"})}})};function cp(e,t){return new Set(function*(){yield*e,yield*t}())}const lp=cp(new Set("\\nrvtbfux"),fr.LINEBREAKS),up=new Set("\\bcdDfnpPrsStvwWxu0123456789]"),pp=cp(up,new Set("^/.$*+?[{}|()Bk"));var dp={meta:{type:"suggestion",docs:{description:"disallow unnecessary escape characters",category:"Best Practices",recommended:!0,url:"https://eslint.org/docs/rules/no-useless-escape",suggestion:!0},messages:{unnecessaryEscape:"Unnecessary escape character: \\{{character}}.",removeEscape:"Remove the `\\`. This maintains the current functionality.",escapeBackslash:"Replace the `\\` with `\\\\` to include the actual backslash character."},schema:[]},create(e){const t=e.getSourceCode();function n(n,r,o){const s=n.range[0]+r,a=[s,s+1],i=t.getLocFromIndex(s);e.report({node:n,loc:{start:i,end:{line:i.line,column:i.column+1}},messageId:"unnecessaryEscape",data:{character:o},suggest:[{messageId:"removeEscape",fix:e=>e.removeRange(a)},{messageId:"escapeBackslash",fix:e=>e.insertTextBeforeRange(a,"\\")}]})}function r(e,t){const r="TemplateElement"===e.type,o=t[0][1];let s,a=!lp.has(o);r?(s="`"===o,"$"===o?a="{"!==t.input[t.index+2]:"{"===o&&(a="$"!==t.input[t.index-1])):s=o===e.raw[0],a&&!s&&n(e,t.index,t[0].slice(1))}function o(e){const o="TemplateElement"===e.type;if(!(o&&e.parent&&e.parent.parent&&"TaggedTemplateExpression"===e.parent.parent.type&&e.parent===e.parent.parent.quasi))if("string"==typeof e.value||o){if("JSXAttribute"===e.parent.type||"JSXElement"===e.parent.type||"JSXFragment"===e.parent.type)return;const n=o?t.getText(e):e.raw,s=/\\[^\d]/gu;let a;for(;a=s.exec(n);)r(e,a)}else e.regex&&function(e){const t=[];return e.split("").reduce(((e,n,r)=>{if(!e.escapeNextChar){if("\\"===n)return Object.assign(e,{escapeNextChar:!0});if("["===n&&!e.inCharClass)return Object.assign(e,{inCharClass:!0,startingCharClass:!0});if("]"===n&&e.inCharClass)return t.length&&t[t.length-1].inCharClass&&(t[t.length-1].endsCharClass=!0),Object.assign(e,{inCharClass:!1,startingCharClass:!1})}return t.push({text:n,index:r,escaped:e.escapeNextChar,inCharClass:e.inCharClass,startsCharClass:e.startingCharClass,endsCharClass:!1}),Object.assign(e,{escapeNextChar:!1,startingCharClass:!1})}),{escapeNextChar:!1,inCharClass:!1,startingCharClass:!1}),t}(e.regex.pattern).filter((e=>!("-"===e.text&&e.inCharClass&&!e.startsCharClass&&!e.endsCharClass))).filter((e=>!("^"===e.text&&e.startsCharClass))).filter((e=>e.escaped)).filter((e=>!(e.inCharClass?up:pp).has(e.text))).forEach((t=>n(e,t.index,t.text)))}return{Literal:o,TemplateElement:o}}},fp={meta:{type:"suggestion",docs:{description:"disallow renaming import, export, and destructured assignments to the same name",category:"ECMAScript 6",recommended:!1,url:"https://eslint.org/docs/rules/no-useless-rename"},fixable:"code",schema:[{type:"object",properties:{ignoreDestructuring:{type:"boolean",default:!1},ignoreImport:{type:"boolean",default:!1},ignoreExport:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{unnecessarilyRenamed:"{{type}} {{name}} unnecessarily renamed."}},create(e){const t=e.getSourceCode(),n=e.options[0]||{},r=!0===n.ignoreDestructuring,o=!0===n.ignoreImport,s=!0===n.ignoreExport;function a(n,r,o){const s="Identifier"===r.type?r.name:r.value;return e.report({node:n,messageId:"unnecessarilyRenamed",data:{name:s,type:o},fix(e){const r="Property"===n.type?n.value:n.local;return t.getCommentsInside(n).length>t.getCommentsInside(r).length||"AssignmentPattern"===r.type&&fr.isParenthesised(t,r.left)?null:e.replaceText(n,t.getText(r))}})}return{ObjectPattern:function(e){if(!r)for(const t of e.properties){if("Property"!==t.type||t.shorthand||t.computed)continue;("Identifier"===t.key.type&&t.key.name||"Literal"===t.key.type&&t.key.value)===("AssignmentPattern"===t.value.type?t.value.left.name:t.value.name)&&a(t,t.key,"Destructuring assignment")}},ImportSpecifier:function(e){o||e.imported.name===e.local.name&&e.imported.range[0]!==e.local.range[0]&&a(e,e.imported,"Import")},ExportSpecifier:function(e){s||e.local.name===e.exported.name&&e.local.range[0]!==e.exported.range[0]&&a(e,e.local,"Export")}}}};function mp(e,t){const n=e.indexOf(t);-1!==n&&e.splice(n,1)}function gp(e){return fr.STATEMENT_LIST_PARENTS.has(e.parent.type)}var hp={meta:{type:"suggestion",docs:{description:"disallow redundant return statements",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-useless-return"},fixable:"code",schema:[],messages:{unnecessaryReturn:"Unnecessary return statement."}},create(e){const t=new WeakMap,n=new WeakSet,r=e.getSourceCode();let o=null;function s(e){const n=t.get(e);return!n||n.returned}function a(e,n,r){const o=r||new WeakSet;for(const r of n)r.reachable?e.push(...t.get(r).uselessReturns):o.has(r)||(o.add(r),a(e,r.allPrevSegments.filter(s),o));return e}function i(e){if(!e.reachable)return n.add(e),void e.allPrevSegments.filter(s).filter((e=>!n.has(e))).forEach(i);const r=t.get(e);for(const e of r.uselessReturns)mp(o.uselessReturns,e);r.uselessReturns=[]}function c(){o.codePath.currentSegments.forEach(i)}return{onCodePathStart(e){o={upper:o,uselessReturns:[],codePath:e}},onCodePathEnd(){for(const t of o.uselessReturns)e.report({node:t,loc:t.loc,messageId:"unnecessaryReturn",fix:e=>gp(t)&&!r.getCommentsInside(t).length?new Ra(e,r).retainEnclosingFunction(t).remove(t):null});o=o.upper},onCodePathSegmentStart(e){const n={uselessReturns:a([],e.allPrevSegments),returned:!1};t.set(e,n)},ReturnStatement(e){if(e.argument&&c(),!(e.argument||fr.isInLoop(e)||function(e){for(let t=e;t&&t.parent&&!fr.isFunction(t);t=t.parent)if("TryStatement"===t.parent.type&&t.parent.finalizer===t)return!0;return!1}(e))&&o.codePath.currentSegments.some((e=>e.reachable))){for(const n of o.codePath.currentSegments){const r=t.get(n);r&&(r.uselessReturns.push(e),r.returned=!0)}o.uselessReturns.push(e)}},ClassDeclaration:c,ContinueStatement:c,DebuggerStatement:c,DoWhileStatement:c,EmptyStatement:c,ExpressionStatement:c,ForInStatement:c,ForOfStatement:c,ForStatement:c,IfStatement:c,ImportDeclaration:c,LabeledStatement:c,SwitchStatement:c,ThrowStatement:c,TryStatement:c,VariableDeclaration:c,WhileStatement:c,WithStatement:c,ExportNamedDeclaration:c,ExportDefaultDeclaration:c,ExportAllDeclaration:c}}};function yp(e){return Boolean(e.scope)&&"global"===e.scope.type}function xp(e){let t=e;for(;"function"!==t.type&&"global"!==t.type;)t=t.upper;return t}function bp(e){const t=xp(e.scope);return e.references.some((e=>xp(e.from)!==t))}function Ep(e){return("ForOfStatement"===e.parent.type||"ForInStatement"===e.parent.type)&&e===e.parent.left}const Sp=/^(?:Program|BlockStatement|SwitchStatement|ForStatement|ForInStatement|ForOfStatement)$/u;function Cp(e){return e.defs.length>=2}function vp(e){return"let"===e.name}var Ap={meta:{type:"suggestion",docs:{description:"require `let` or `const` instead of `var`",category:"ECMAScript 6",recommended:!1,url:"https://eslint.org/docs/rules/no-var"},schema:[],fixable:"code",messages:{unexpectedVar:"Unexpected var, use let or const instead."}},create(e){const t=e.getSourceCode();function n(t){if(!t.init)return!1;return e.getDeclaredVariables(t).some(function(e){const t=e.range[0],n=e.range[1];return e=>{const r=e.defs[0].name,o=r.range[0],s="AssignmentPattern"===r.parent.type?r.parent.right:null,a=s&&s.range[0],i=s&&s.range[1];return e.references.some((e=>{const r=e.identifier.range[0],c=e.identifier.range[1];return!e.init&&(r=a&&c<=i||r>=t&&c<=n)}))}}(t.init))}function r(t){const r=e.getDeclaredVariables(t),o=function(e){for(let t=e;t;t=t.parent)if(Sp.test(t.type))return t;return null}(t);if("SwitchCase"===t.parent.type||t.declarations.some(n)||r.some(yp)||r.some(Cp)||r.some(function(e){function t(t){const n=e.range,r=t.identifier.range;return r[0]n[1]}return function(e){return e.references.some(t)}}(o))||r.some(vp))return!1;if(fr.isInLoop(t)){if(r.some(bp))return!1;if(!Ep(t)&&!function(e){return e.declarations.every((e=>null!==e.init))}(t))return!1}return!!(Ep(t)||"ForStatement"===t.parent.type&&t.parent.init===t||fr.STATEMENT_LIST_PARENTS.has(t.parent.type))}return{"VariableDeclaration:exit"(n){"var"===n.kind&&function(n){e.report({node:n,messageId:"unexpectedVar",fix(e){const o=t.getFirstToken(n,{filter:e=>"var"===e.value});return r(n)?e.replaceText(o,"let"):null}})}(n)}}}},kp={meta:{type:"suggestion",docs:{description:"disallow `void` operators",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-void"},messages:{noVoid:"Expected 'undefined' and instead saw 'void'."},schema:[{type:"object",properties:{allowAsStatement:{type:"boolean",default:!1}},additionalProperties:!1}]},create(e){const t=e.options[0]&&e.options[0].allowAsStatement;return{'UnaryExpression[operator="void"]'(n){t&&n.parent&&"ExpressionStatement"===n.parent.type||e.report({node:n,messageId:"noVoid"})}}}};const{escapeRegExp:wp}=F.default;var Pp={meta:{type:"suggestion",docs:{description:"disallow specified warning terms in comments",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/no-warning-comments"},schema:[{type:"object",properties:{terms:{type:"array",items:{type:"string"}},location:{enum:["start","anywhere"]}},additionalProperties:!1}],messages:{unexpectedComment:"Unexpected '{{matchedTerm}}' comment: '{{comment}}'."}},create(e){const t=e.getSourceCode(),n=e.options[0]||{},r=n.terms||["todo","fixme","xxx"],o=n.location||"start",s=/\bno-warning-comments\b/u;const a=r.map((function(e){const t=wp(e),n="\\b";let r;const s=/\w$/u.test(e)?"\\b":"";return r="start"===o?"^\\s*":/^\w/u.test(e)?n:"","start"===o?new RegExp(r+t+s,"iu"):new RegExp(r+t+s+"|\\b"+e+n,"iu")}));function i(t){const n=t.value;if(fr.isDirectiveComment(t)&&s.test(n))return;(function(e){const t=[];return a.forEach(((n,o)=>{n.test(e)&&t.push(r[o])})),t})(n).forEach((r=>{let o="",s=!1;for(const e of n.trim().split(/\s+/u)){const t=o?`${o} ${e}`:e;if(!(t.length<=40)){s=!0;break}o=t}e.report({node:t,messageId:"unexpectedComment",data:{matchedTerm:r,comment:`${o}${s?"...":""}`}})}))}return{Program(){t.getAllComments().filter((e=>"Shebang"!==e.type)).forEach(i)}}}},Tp={meta:{type:"layout",docs:{description:"disallow whitespace before properties",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/no-whitespace-before-property"},fixable:"whitespace",schema:[],messages:{unexpectedWhitespace:"Unexpected whitespace before property {{propName}}."}},create(e){const t=e.getSourceCode();return{MemberExpression(n){let r,o;fr.isTokenOnSameLine(n.object,n.property)&&(n.computed?(r=t.getTokenBefore(n.property,fr.isOpeningBracketToken),o=t.getTokenBefore(r,n.optional?1:0)):(r=t.getFirstToken(n.property),o=t.getTokenBefore(r,1)),t.isSpaceBetweenTokens(o,r)&&function(n,r,o){e.report({node:n,messageId:"unexpectedWhitespace",data:{propName:t.getText(n.property)},fix(e){let s="";return n.computed||n.optional||!fr.isDecimalInteger(n.object)?t.commentsExistBetween(r,o)?null:(n.optional?s="?.":n.computed||(s="."),e.replaceTextRange([r.range[1],o.range[0]],s)):null}})}(n,o,r))}}}},Ip={meta:{type:"suggestion",docs:{description:"disallow `with` statements",category:"Best Practices",recommended:!0,url:"https://eslint.org/docs/rules/no-with"},schema:[],messages:{unexpectedWith:"Unexpected use of 'with' statement."}},create:e=>({WithStatement(t){e.report({node:t,messageId:"unexpectedWith"})}})};const Fp={enum:["beside","below","any"]};var Dp={meta:{type:"layout",docs:{description:"enforce the location of single-line statements",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/nonblock-statement-body-position"},fixable:"whitespace",schema:[Fp,{properties:{overrides:{properties:{if:Fp,else:Fp,while:Fp,do:Fp,for:Fp},additionalProperties:!1}},additionalProperties:!1}],messages:{expectNoLinebreak:"Expected no linebreak before this statement.",expectLinebreak:"Expected a linebreak before this statement."}},create(e){const t=e.getSourceCode();function n(n,r){const o=function(t){return e.options[1]&&e.options[1].overrides&&e.options[1].overrides[t]||e.options[0]||"beside"}(r);if("BlockStatement"===n.type||"any"===o)return;const s=t.getTokenBefore(n);s.loc.end.line===n.loc.start.line&&"below"===o?e.report({node:n,messageId:"expectLinebreak",fix:e=>e.insertTextBefore(n,"\n")}):s.loc.end.line!==n.loc.start.line&&"beside"===o&&e.report({node:n,messageId:"expectNoLinebreak",fix:e=>t.getText().slice(s.range[1],n.range[0]).trim()?null:e.replaceTextRange([s.range[1],n.range[0]]," ")})}return{IfStatement(e){n(e.consequent,"if"),e.alternate&&"IfStatement"!==e.alternate.type&&n(e.alternate,"else")},WhileStatement:e=>n(e.body,"while"),DoWhileStatement:e=>n(e.body,"do"),ForStatement:e=>n(e.body,"for"),ForInStatement:e=>n(e.body,"for"),ForOfStatement:e=>n(e.body,"for")}}};const Op={oneOf:[{enum:["always","never"]},{type:"object",properties:{multiline:{type:"boolean"},minProperties:{type:"integer",minimum:0},consistent:{type:"boolean"}},additionalProperties:!1,minProperties:1}]};function Bp(e){let t=!1,n=Number.POSITIVE_INFINITY,r=!1;return e?"always"===e?n=0:"never"===e?n=Number.POSITIVE_INFINITY:(t=Boolean(e.multiline),n=e.minProperties||Number.POSITIVE_INFINITY,r=Boolean(e.consistent)):r=!0,{multiline:t,minProperties:n,consistent:r}}var Np={meta:{type:"layout",docs:{description:"enforce consistent line breaks after opening and before closing braces",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/object-curly-newline"},fixable:"whitespace",schema:[{oneOf:[Op,{type:"object",properties:{ObjectExpression:Op,ObjectPattern:Op,ImportDeclaration:Op,ExportDeclaration:Op},additionalProperties:!1,minProperties:1}]}],messages:{unexpectedLinebreakBeforeClosingBrace:"Unexpected line break before this closing brace.",unexpectedLinebreakAfterOpeningBrace:"Unexpected line break after this opening brace.",expectedLinebreakBeforeClosingBrace:"Expected a line break before this closing brace.",expectedLinebreakAfterOpeningBrace:"Expected a line break after this opening brace."}},create(e){const t=e.getSourceCode(),n=function(e){const t=F.default.overSome([F.default.isPlainObject,F.default.isString]);if(F.default.isPlainObject(e)&&Object.values(e).some(t))return{ObjectExpression:Bp(e.ObjectExpression),ObjectPattern:Bp(e.ObjectPattern),ImportDeclaration:Bp(e.ImportDeclaration),ExportNamedDeclaration:Bp(e.ExportDeclaration)};const n=Bp(e);return{ObjectExpression:n,ObjectPattern:n,ImportDeclaration:n,ExportNamedDeclaration:n}}(e.options[0]);function r(r){const o=n[r.type];if("ImportDeclaration"===r.type&&!r.specifiers.some((e=>"ImportSpecifier"===e.type))||"ExportNamedDeclaration"===r.type&&!r.specifiers.some((e=>"ExportSpecifier"===e.type)))return;const s=t.getFirstToken(r,(e=>"{"===e.value));let a;a=r.typeAnnotation?t.getTokenBefore(r.typeAnnotation):t.getLastToken(r,(e=>"}"===e.value));let i=t.getTokenAfter(s,{includeComments:!0}),c=t.getTokenBefore(a,{includeComments:!0});const l=function(e,t,n,r){let o;return o="ObjectExpression"===e.type||"ObjectPattern"===e.type?e.properties:e.specifiers.filter((e=>"ImportSpecifier"===e.type||"ExportSpecifier"===e.type)),o.length>=t.minProperties||t.multiline&&o.length>0&&n.loc.start.line!==r.loc.end.line}(r,o,i,c),u=fr.isCommentToken(i),p=fr.isCommentToken(c);if(i=t.getTokenAfter(s),c=t.getTokenBefore(a),l)fr.isTokenOnSameLine(s,i)&&e.report({messageId:"expectedLinebreakAfterOpeningBrace",node:r,loc:s.loc,fix:e=>u?null:e.insertTextAfter(s,"\n")}),fr.isTokenOnSameLine(c,a)&&e.report({messageId:"expectedLinebreakBeforeClosingBrace",node:r,loc:a.loc,fix:e=>p?null:e.insertTextBefore(a,"\n")});else{const t=o.consistent,n=!fr.isTokenOnSameLine(s,i),l=!fr.isTokenOnSameLine(c,a);(!t&&n||t&&n&&!l)&&e.report({messageId:"unexpectedLinebreakAfterOpeningBrace",node:r,loc:s.loc,fix:e=>u?null:e.removeRange([s.range[1],i.range[0]])}),(!t&&l||t&&!n&&l)&&e.report({messageId:"unexpectedLinebreakBeforeClosingBrace",node:r,loc:a.loc,fix:e=>p?null:e.removeRange([c.range[1],a.range[0]])})}}return{ObjectExpression:r,ObjectPattern:r,ImportDeclaration:r,ExportNamedDeclaration:r}}},jp={meta:{type:"layout",docs:{description:"enforce consistent spacing inside braces",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/object-curly-spacing"},fixable:"whitespace",schema:[{enum:["always","never"]},{type:"object",properties:{arraysInObjects:{type:"boolean"},objectsInObjects:{type:"boolean"}},additionalProperties:!1}],messages:{requireSpaceBefore:"A space is required before '{{token}}'.",requireSpaceAfter:"A space is required after '{{token}}'.",unexpectedSpaceBefore:"There should be no space before '{{token}}'.",unexpectedSpaceAfter:"There should be no space after '{{token}}'."}},create(e){const t="always"===e.options[0],n=e.getSourceCode();function r(n){return!!e.options[1]&&e.options[1][n]===!t}const o={spaced:t,arraysInObjectsException:r("arraysInObjects"),objectsInObjectsException:r("objectsInObjects")};function s(t,r,s,a,i){if(fr.isTokenOnSameLine(r,s)){const a=n.isSpaceBetweenTokens(r,s);o.spaced&&!a&&function(t,n){e.report({node:t,loc:n.loc,messageId:"requireSpaceAfter",data:{token:n.value},fix:e=>e.insertTextAfter(n," ")})}(t,r),!o.spaced&&a&&"Line"!==s.type&&function(t,n){const r=e.getSourceCode().getTokenAfter(n,{includeComments:!0});e.report({node:t,loc:{start:n.loc.end,end:r.loc.start},messageId:"unexpectedSpaceAfter",data:{token:n.value},fix:e=>e.removeRange([n.range[1],r.range[0]])})}(t,r)}if(fr.isTokenOnSameLine(a,i)){const r=(o.arraysInObjectsException&&fr.isClosingBracketToken(a)||o.objectsInObjectsException&&fr.isClosingBraceToken(a))&&n.getNodeByRangeIndex(a.range[0]).type,s=o.arraysInObjectsException&&"ArrayExpression"===r||o.objectsInObjectsException&&("ObjectExpression"===r||"ObjectPattern"===r)?!o.spaced:o.spaced,c=n.isSpaceBetweenTokens(a,i);s&&!c&&function(t,n){e.report({node:t,loc:n.loc,messageId:"requireSpaceBefore",data:{token:n.value},fix:e=>e.insertTextBefore(n," ")})}(t,i),!s&&c&&function(t,n){const r=e.getSourceCode().getTokenBefore(n,{includeComments:!0});e.report({node:t,loc:{start:r.loc.end,end:n.loc.start},messageId:"unexpectedSpaceBefore",data:{token:n.value},fix:e=>e.removeRange([r.range[1],n.range[0]])})}(t,i)}}function a(e){if(0===e.properties.length)return;const t=n.getFirstToken(e),r=function(e){const t=e.properties[e.properties.length-1];return n.getTokenAfter(t,fr.isClosingBraceToken)}(e);s(e,t,n.getTokenAfter(t,{includeComments:!0}),n.getTokenBefore(r,{includeComments:!0}),r)}return{ObjectPattern:a,ObjectExpression:a,ImportDeclaration:function(e){if(0===e.specifiers.length)return;let t=e.specifiers[0];const r=e.specifiers[e.specifiers.length-1];if("ImportSpecifier"!==r.type)return;"ImportSpecifier"!==t.type&&(t=e.specifiers[1]);const o=n.getTokenBefore(t),a=n.getTokenAfter(r,fr.isNotCommaToken);s(e,o,n.getTokenAfter(o,{includeComments:!0}),n.getTokenBefore(a,{includeComments:!0}),a)},ExportNamedDeclaration:function(e){if(0===e.specifiers.length)return;const t=e.specifiers[0],r=e.specifiers[e.specifiers.length-1],o=n.getTokenBefore(t),a=n.getTokenAfter(r,fr.isNotCommaToken);s(e,o,n.getTokenAfter(o,{includeComments:!0}),n.getTokenBefore(a,{includeComments:!0}),a)}}}},Lp={meta:{type:"layout",docs:{description:"enforce placing object properties on separate lines",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/object-property-newline"},schema:[{type:"object",properties:{allowAllPropertiesOnSameLine:{type:"boolean",default:!1},allowMultiplePropertiesPerLine:{type:"boolean",default:!1}},additionalProperties:!1}],fixable:"whitespace",messages:{propertiesOnNewlineAll:"Object properties must go on a new line if they aren't all on the same line.",propertiesOnNewline:"Object properties must go on a new line."}},create(e){const t=e.options[0]&&(e.options[0].allowAllPropertiesOnSameLine||e.options[0].allowMultiplePropertiesPerLine),n=t?"propertiesOnNewlineAll":"propertiesOnNewline",r=e.getSourceCode();return{ObjectExpression(o){if(t&&o.properties.length>1){const e=r.getFirstToken(o.properties[0]),t=r.getLastToken(o.properties[o.properties.length-1]);if(e.loc.end.line===t.loc.start.line)return}for(let t=1;t0){const o=r.filter(g);if(o.length!==r.length)if(o.length>0)e.report({node:t,messageId:"unexpectedMix"});else if(n){r.every(h)&&e.report({node:t,messageId:"expectedAllPropertiesShorthanded"})}}}const x=[],b=new WeakSet,E=new WeakSet;function S(){x.unshift(new Set),e.getScope().variables.filter((e=>"arguments"===e.name)).forEach((e=>{e.references.map((e=>e.identifier)).forEach((e=>E.add(e)))}))}function C(){x.shift()}function v(){x[0].forEach((e=>b.add(e)))}return{Program:S,FunctionDeclaration:S,FunctionExpression:S,"Program:exit":C,"FunctionDeclaration:exit":C,"FunctionExpression:exit":C,ArrowFunctionExpression(e){x[0].add(e)},"ArrowFunctionExpression:exit"(e){x[0].delete(e)},ThisExpression:v,Super:v,MetaProperty(e){"new"===e.meta.name&&"target"===e.property.name&&v()},Identifier(e){E.has(e)&&v()},ObjectExpression(e){s?y(e,!1):a&&y(e,!0)},"Property:exit"(t){const s=t.method||t.shorthand;if("ObjectPattern"!==t.parent.type&&"get"!==t.kind&&"set"!==t.kind&&(!t.computed||"FunctionExpression"===t.value.type||"ArrowFunctionExpression"===t.value.type))if(s)if(t.method&&(o||l&&m(t.key))){const n=o?"expectedMethodLongform":"expectedLiteralMethodLongform";e.report({node:t,messageId:n,fix:e=>function(e,t){const n=t.computed?p.getTokens(t).find((e=>"["===e.value)):p.getFirstToken(t.key),r=t.computed?p.getTokensBetween(t.key,t.value).find((e=>"]"===e.value)):p.getLastToken(t.key),o=p.text.slice(n.range[0],r.range[1]);let s="function";return t.value.async&&(s=`async ${s}`),t.value.generator&&(s=`${s}*`),e.replaceTextRange([t.range[0],r.range[1]],`${o}: ${s}`)}(e,t)})}else o&&e.report({node:t,messageId:"expectedPropertyLongform",fix:e=>e.insertTextAfter(t.key,`: ${t.key.name}`)});else if(!n||t.value.id||"FunctionExpression"!==t.value.type&&"ArrowFunctionExpression"!==t.value.type){if("Identifier"===t.value.type&&t.key.name===t.value.name&&r)e.report({node:t,messageId:"expectedPropertyShorthand",fix:e=>e.replaceText(t,t.value.name)});else if("Identifier"===t.value.type&&"Literal"===t.key.type&&t.key.value===t.value.name&&r){if(l)return;e.report({node:t,messageId:"expectedPropertyShorthand",fix:e=>e.replaceText(t,t.value.name)})}}else{if(c&&"Identifier"===t.key.type&&function(e){const t=d.exec(e);if(!t)return!1;const n=e.charAt(t.index);return n===n.toUpperCase()}(t.key.name))return;if(l&&m(t.key))return;("FunctionExpression"===t.value.type||"ArrowFunctionExpression"===t.value.type&&"BlockStatement"===t.value.body.type&&u&&!b.has(t.value))&&e.report({node:t,messageId:"expectedMethodShorthand",fix:e=>function(e,t){const n=t.computed?p.getFirstToken(t,fr.isOpeningBracketToken):p.getFirstToken(t.key),r=t.computed?p.getFirstTokenBetween(t.key,t.value,fr.isClosingBracketToken):p.getLastToken(t.key),o=p.text.slice(n.range[0],r.range[1]);let s="";if(p.commentsExistBetween(r,t.value))return null;t.value.async&&(s+="async "),t.value.generator&&(s+="*");const a=[n.range[0],t.range[1]],i=s+o;if("FunctionExpression"===t.value.type){const n=p.getTokens(t.value).find((e=>"Keyword"===e.type&&"function"===e.value)),r=t.value.generator?p.getTokenAfter(n):n;return e.replaceTextRange(a,i+p.text.slice(r.range[1],t.value.range[1]))}const c=p.getTokenBefore(t.value.body,fr.isArrowToken),l=p.text.slice(c.range[1],t.value.range[1]);let u,d=!1;if(u=0===t.value.params.length?p.getFirstToken(t.value,fr.isOpeningParenToken):p.getTokenBefore(t.value.params[0]),1===t.value.params.length){const e=fr.isOpeningParenToken(u),n=u.range[0]0&&o.uninitialized===t&&a.uninitialized)&&(!(r.initialized>0&&o.initialized===t&&a.initialized&&!l)&&((!a.required||!l)&&(function(e,n,r){for(let o=0;oe.range[0]===t.parent.range[0])),o=n[r-1];return e=>{const n=a.getTokenBefore(t),r=a.getTokenBefore(n),s=[];return o&&o.kind===a.getText(n)&&(";"===r.value?s.push(e.replaceText(r,",")):s.push(e.insertTextAfter(r,",")),s.push(e.replaceText(n,""))),s}}function y(e){const{parent:t}=e;return n="ExportNamedDeclaration"===t.type?t:e,fr.STATEMENT_LIST_PARENTS.has(n.parent.type)?t=>e.declarations.map((n=>{const r=a.getTokenAfter(n);if(null===r)return null;const o=a.getTokenAfter(r,{includeComments:!0});if(","!==r.value)return null;const s="ExportNamedDeclaration"===e.parent.type?"export ":"";if(o.range[0]===r.range[1])return t.replaceText(r,`; ${s}${e.kind} `);if(o.loc.start.line>r.loc.end.line||"Line"===o.type||"Block"===o.type){let n=o;for(;"Line"===n.type||"Block"===n.type;)n=a.getTokenAfter(n,{includeComments:!0});return t.replaceTextRange([r.range[0],n.range[0]],`;${a.text.slice(r.range[1],n.range[0])}${s}${e.kind} `)}return t.replaceText(r,`; ${s}${e.kind}`)})).filter((e=>e)):null;var n}return{Program:u,FunctionDeclaration:u,FunctionExpression:u,ArrowFunctionExpression:u,BlockStatement:l,ForStatement:l,ForInStatement:l,ForOfStatement:l,SwitchStatement:l,VariableDeclaration:function(o){const a=o.parent,i=o.kind;if(!s[i])return;const c=o.declarations,l=m(c),u=c.some(f)&&!c.every(f);s[i].initialized===t&&s.separateRequires&&u&&e.report({node:o,messageId:"splitRequires"});const p=a.body&&a.body.length>0&&a.body.indexOf(o)||0;if(p>0){const t=a.body[p-1],n="VariableDeclaration"===t.type,u=c.concat(t.declarations||[]);if(n&&t.kind===i&&(!u.some(f)||u.every(f))){const n=m(t.declarations);s[i].initialized===r&&s[i].uninitialized===r?e.report({node:o,messageId:"combine",data:{type:i},fix:h(c)}):s[i].initialized===r&&l.initialized>0&&n.initialized>0?e.report({node:o,messageId:"combineInitialized",data:{type:i},fix:h(c)}):s[i].uninitialized===r&&l.uninitialized>0&&n.uninitialized>0&&e.report({node:o,messageId:"combineUninitialized",data:{type:i},fix:h(c)})}}if(!g(i,c))if(s[i].initialized===t&&s[i].uninitialized===t)e.report({node:o,messageId:"combine",data:{type:i},fix:h(c)});else if(s[i].initialized===t&&l.initialized>0&&e.report({node:o,messageId:"combineInitialized",data:{type:i},fix:h(c)}),s[i].uninitialized===t&&l.uninitialized>0){if(o.parent.left===o&&("ForInStatement"===o.parent.type||"ForOfStatement"===o.parent.type))return;e.report({node:o,messageId:"combineUninitialized",data:{type:i},fix:h(c)})}if("ForStatement"!==a.type||a.init!==o){l.uninitialized+l.initialized>1&&(s[i].initialized===n&&s[i].uninitialized===n?e.report({node:o,messageId:"split",data:{type:i},fix:y(o)}):s[i].initialized===n&&l.initialized>0?e.report({node:o,messageId:"splitInitialized",data:{type:i},fix:y(o)}):s[i].uninitialized===n&&l.uninitialized>0&&e.report({node:o,messageId:"splitUninitialized",data:{type:i},fix:y(o)}))}},"ForStatement:exit":p,"ForOfStatement:exit":p,"ForInStatement:exit":p,"SwitchStatement:exit":p,"BlockStatement:exit":p,"Program:exit":d,"FunctionDeclaration:exit":d,"FunctionExpression:exit":d,"ArrowFunctionExpression:exit":d}}},Gp={meta:{type:"suggestion",docs:{description:"require or disallow newlines around variable declarations",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/one-var-declaration-per-line"},schema:[{enum:["always","initializations"]}],fixable:"whitespace",messages:{expectVarOnNewline:"Expected variable declaration to be on a new line."}},create(e){const t="always"===e.options[0];return{VariableDeclaration:function(n){if("ForStatement"===(r=n.parent.type)||"ForInStatement"===r||"ForOfStatement"===r)return;var r;let o;n.declarations.forEach((r=>{o&&o.loc.end.line===r.loc.start.line&&(t||o.init||r.init)&&e.report({node:n,messageId:"expectVarOnNewline",loc:r.loc,fix:e=>e.insertTextBefore(r,"\n")}),o=r}))}}}};function zp(e){return["*","&","^","|"].indexOf(e)>=0}function Jp(e){return"Identifier"===e.type||"MemberExpression"===e.type&&("Identifier"===e.object.type||"ThisExpression"===e.object.type)&&(!e.computed||"Literal"===e.property.type)}var Kp={meta:{type:"suggestion",docs:{description:"require or disallow assignment operator shorthand where possible",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/operator-assignment"},schema:[{enum:["always","never"]}],fixable:"code",messages:{replaced:"Assignment can be replaced with operator assignment.",unexpected:"Unexpected operator assignment shorthand."}},create(e){const t=e.getSourceCode();function n(e){return t.getFirstTokenBetween(e.left,e.right,(t=>t.value===e.operator))}return{AssignmentExpression:"never"!==e.options[0]?function(r){if("="!==r.operator||"BinaryExpression"!==r.right.type)return;const o=r.left,s=r.right,a=s.operator;(zp(a)||function(e){return["+","-","/","%","<<",">>",">>>","**"].indexOf(e)>=0}(a))&&(fr.isSameReference(o,s.left,!0)?e.report({node:r,messageId:"replaced",fix(e){if(Jp(o)&&Jp(s.left)){const o=n(r),a=n(s),i=t.getText().slice(r.range[0],o.range[0]),c=t.getText().slice(a.range[1],r.right.range[1]);return t.commentsExistBetween(o,a)?null:e.replaceText(r,`${i}${s.operator}=${c}`)}return null}}):fr.isSameReference(o,s.right,!0)&&zp(a)&&e.report({node:r,messageId:"replaced"}))}:function(r){"="===r.operator||fr.isLogicalAssignmentOperator(r.operator)||e.report({node:r,messageId:"unexpected",fix(e){if(Jp(r.left)){const o=t.getFirstToken(r),s=n(r),a=t.getText().slice(r.range[0],s.range[0]),i=r.operator.slice(0,-1);let c;if(t.commentsExistBetween(o,s))return null;if(fr.getPrecedence(r.right)<=fr.getPrecedence({type:"BinaryExpression",operator:i})&&!fr.isParenthesised(t,r.right))c=`${t.text.slice(s.range[1],r.right.range[0])}(${t.getText(r.right)})`;else{const e=t.getTokenAfter(s,{includeComments:!0});let n="";s.range[1]!==e.range[0]||fr.canTokensBeAdjacent({type:"Punctuator",value:i},e)||(n=" "),c=`${n}${t.text.slice(s.range[1],r.range[1])}`}return e.replaceText(r,`${a}= ${a}${i}${c}`)}return null}})}}}},Yp={meta:{type:"layout",docs:{description:"enforce consistent linebreak style for operators",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/operator-linebreak"},schema:[{enum:["after","before","none",null]},{type:"object",properties:{overrides:{type:"object",additionalProperties:{enum:["after","before","none","ignore"]}}},additionalProperties:!1}],fixable:"code",messages:{operatorAtBeginning:"'{{operator}}' should be placed at the beginning of the line.",operatorAtEnd:"'{{operator}}' should be placed at the end of the line.",badLinebreak:"Bad line breaking before and after '{{operator}}'.",noLinebreak:"There should be no line break before or after '{{operator}}'."}},create(e){const t=!e.options[0],n=e.options[0]||"after",r=e.options[1]||{},o=r.overrides?Object.assign({},r.overrides):{};t&&!o["?"]&&(o["?"]="before"),t&&!o[":"]&&(o[":"]="before");const s=e.getSourceCode();function a(t,r){const a=s.getTokenAfter(r,fr.isNotClosingParenToken),i=s.getTokenBefore(a),c=s.getTokenAfter(a),l=a.value,u=o[l],p=u||n,d=function(e,t){return n=>{const r=s.getTokenBefore(e),o=s.getTokenAfter(e),a=s.text.slice(r.range[1],e.range[0]),i=s.text.slice(e.range[1],o.range[0]);let c,l;if(!fr.isTokenOnSameLine(r,e)!=!fr.isTokenOnSameLine(e,o)&&"none"!==t){if(s.getTokenBefore(e,{includeComments:!0})!==r&&s.getTokenAfter(e,{includeComments:!0})!==o)return null;c=i,l=a}else{const e=fr.createGlobalLinebreakMatcher();if(c="before"===t||a.trim()?a:a.replace(e,""),l="after"===t||i.trim()?i:i.replace(e,""),c===a&&l===i)return null}return""===l&&"Punctuator"===o.type&&"+-".includes(e.value)&&o.value===e.value&&(l+=" "),n.replaceTextRange([r.range[1],o.range[0]],c+e.value+l)}}(a,p);fr.isTokenOnSameLine(i,a)&&fr.isTokenOnSameLine(a,c)||("ignore"===u||fr.isTokenOnSameLine(i,a)||fr.isTokenOnSameLine(a,c)?"before"===p&&fr.isTokenOnSameLine(i,a)?e.report({node:t,loc:a.loc,messageId:"operatorAtBeginning",data:{operator:l},fix:d}):"after"===p&&fr.isTokenOnSameLine(a,c)?e.report({node:t,loc:a.loc,messageId:"operatorAtEnd",data:{operator:l},fix:d}):"none"===p&&e.report({node:t,loc:a.loc,messageId:"noLinebreak",data:{operator:l},fix:d}):e.report({node:t,loc:a.loc,messageId:"badLinebreak",data:{operator:l},fix:d}))}function i(e){a(e,e.left)}return{BinaryExpression:i,LogicalExpression:i,AssignmentExpression:i,VariableDeclarator(e){e.init&&a(e,e.id)},ConditionalExpression(e){a(e,e.test),a(e,e.consequent)}}}},Hp={meta:{type:"layout",docs:{description:"require or disallow padding within blocks",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/padded-blocks"},fixable:"whitespace",schema:[{oneOf:[{enum:["always","never"]},{type:"object",properties:{blocks:{enum:["always","never"]},switches:{enum:["always","never"]},classes:{enum:["always","never"]}},additionalProperties:!1,minProperties:1}]},{type:"object",properties:{allowSingleLineBlocks:{type:"boolean"}},additionalProperties:!1}],messages:{alwaysPadBlock:"Block must be padded by blank lines.",neverPadBlock:"Block must not be padded by blank lines."}},create(e){const t={},n=e.options[0]||"always",r=e.options[1]||{};if("string"==typeof n){const e="always"===n;t.blocks=e,t.switches=e,t.classes=e}else Object.prototype.hasOwnProperty.call(n,"blocks")&&(t.blocks="always"===n.blocks),Object.prototype.hasOwnProperty.call(n,"switches")&&(t.switches="always"===n.switches),Object.prototype.hasOwnProperty.call(n,"classes")&&(t.classes="always"===n.classes);Object.prototype.hasOwnProperty.call(r,"allowSingleLineBlocks")&&(t.allowSingleLineBlocks=!0===r.allowSingleLineBlocks);const o=e.getSourceCode();function s(e){return"Line"===e.type||"Block"===e.type}function a(e,t){return t.loc.start.line-e.loc.end.line>=2}function i(n){const r=function(e){let t,n=e;do{t=n,n=o.getTokenAfter(n,{includeComments:!0})}while(s(n)&&n.loc.start.line===t.loc.end.line);return n}(function(e){return"SwitchStatement"===e.type?o.getTokenBefore(e.cases[0]):o.getFirstToken(e)}(n)),i=o.getTokenBefore(r,{includeComments:!0}),c=function(e){let t,n=e;do{t=n,n=o.getTokenBefore(n,{includeComments:!0})}while(s(n)&&n.loc.end.line===t.loc.start.line);return n}(o.getLastToken(n)),l=o.getTokenAfter(c,{includeComments:!0}),u=a(i,r),p=a(c,l);t.allowSingleLineBlocks&&fr.isTokenOnSameLine(i,l)||(!function(e){switch(e.type){case"BlockStatement":return t.blocks;case"SwitchStatement":return t.switches;case"ClassBody":return t.classes;default:throw new Error("unreachable")}}(n)?(u&&e.report({node:n,loc:{start:i.loc.start,end:r.loc.start},fix:e=>e.replaceTextRange([i.range[1],r.range[0]-r.loc.start.column],"\n"),messageId:"neverPadBlock"}),p&&e.report({node:n,loc:{end:l.loc.start,start:c.loc.end},messageId:"neverPadBlock",fix:e=>e.replaceTextRange([c.range[1],l.range[0]-l.loc.start.column],"\n")})):(u||e.report({node:n,loc:{start:i.loc.start,end:r.loc.start},fix:e=>e.insertTextAfter(i,"\n"),messageId:"alwaysPadBlock"}),p||e.report({node:n,loc:{end:l.loc.start,start:c.loc.end},fix:e=>e.insertTextBefore(l,"\n"),messageId:"alwaysPadBlock"})))}const c={};return Object.prototype.hasOwnProperty.call(t,"switches")&&(c.SwitchStatement=function(e){0!==e.cases.length&&i(e)}),Object.prototype.hasOwnProperty.call(t,"blocks")&&(c.BlockStatement=function(e){0!==e.body.length&&i(e)}),Object.prototype.hasOwnProperty.call(t,"classes")&&(c.ClassBody=function(e){0!==e.body.length&&i(e)}),c}};const Xp=`[${Array.from(fr.LINEBREAKS).join("")}]`,Qp=new RegExp(String.raw`^(\s*?${Xp})\s*${Xp}(\s*;?)$`,"u"),Zp=/^(?:module\s*\.\s*)?exports(?:\s*\.|\s*\[|$)/u,ed=/^require\(/u;function td(e){return{test:(t,n)=>n.getFirstToken(t).value===e}}function nd(e){return{test:(t,n)=>t.loc.start.line===t.loc.end.line&&n.getFirstToken(t).value===e}}function rd(e){return{test:(t,n)=>t.loc.start.line!==t.loc.end.line&&n.getFirstToken(t).value===e}}function od(e){return{test:t=>t.type===e}}function sd(e){if("ExpressionStatement"===e.type){let t=fr.skipChainExpression(e.expression);return"UnaryExpression"===t.type&&(t=fr.skipChainExpression(t.argument)),"CallExpression"===t.type&&fr.isFunction(t.callee)}return!1}function ad(e,t){if("DoWhileStatement"===t.type&&"BlockStatement"===t.body.type)return!0;if(sd(t))return!0;const n=e.getLastToken(t,fr.isNotSemicolonToken),r=n&&fr.isClosingBraceToken(n)?e.getNodeByRangeIndex(n.range[0]):null;return Boolean(r)&&("BlockStatement"===r.type||"SwitchStatement"===r.type)}function id(e,t){return"ExpressionStatement"===e.type&&("Program"===e.parent.type||"BlockStatement"===e.parent.type&&fr.isFunction(e.parent.parent))&&"Literal"===e.expression.type&&"string"==typeof e.expression.value&&!fr.isParenthesised(t,e.expression)}function cd(e,t){if(id(e,t)){for(const n of e.parent.body){if(n===e)break;if(!id(n,t))return!1}return!0}return!1}function ld(e,t){const n=e.getLastToken(t),r=e.getTokenBefore(n),o=e.getTokenAfter(n);return Boolean(r&&o&&r.range[0]>=t.range[0]&&fr.isSemicolonToken(n)&&n.loc.start.line!==r.loc.end.line&&n.loc.end.line===o.loc.start.line)?r:n}function ud(e,t,n){return t+n}const pd={any:{verify:function(){}},never:{verify:function(e,t,n,r){0!==r.length&&e.report({node:n,messageId:"unexpectedBlankLine",fix(t){if(r.length>=2)return null;const n=r[0][0],o=r[0][1],s=n.range[1],a=o.range[0],i=e.getSourceCode().text.slice(s,a).replace(Qp,ud);return t.replaceTextRange([s,a],i)}})}},always:{verify:function(e,t,n,r){r.length>0||e.report({node:n,messageId:"expectedBlankLine",fix(r){const o=e.getSourceCode();let s=ld(o,t);const a=o.getFirstTokenBetween(s,n,{includeComments:!0,filter:e=>!fr.isTokenOnSameLine(s,e)||(s=e,!1)})||n,i=fr.isTokenOnSameLine(s,a)?"\n\n":"\n";return r.insertTextAfter(s,i)}})}}},dd={"*":{test:()=>!0},"block-like":{test:(e,t)=>ad(t,e)},"cjs-export":{test:(e,t)=>"ExpressionStatement"===e.type&&"AssignmentExpression"===e.expression.type&&Zp.test(t.getText(e.expression.left))},"cjs-import":{test:(e,t)=>"VariableDeclaration"===e.type&&e.declarations.length>0&&Boolean(e.declarations[0].init)&&ed.test(t.getText(e.declarations[0].init))},directive:{test:cd},expression:{test:(e,t)=>"ExpressionStatement"===e.type&&!cd(e,t)},iife:{test:sd},"multiline-block-like":{test:(e,t)=>e.loc.start.line!==e.loc.end.line&&ad(t,e)},"multiline-expression":{test:(e,t)=>e.loc.start.line!==e.loc.end.line&&"ExpressionStatement"===e.type&&!cd(e,t)},"multiline-const":rd("const"),"multiline-let":rd("let"),"multiline-var":rd("var"),"singleline-const":nd("const"),"singleline-let":nd("let"),"singleline-var":nd("var"),block:od("BlockStatement"),empty:od("EmptyStatement"),function:od("FunctionDeclaration"),break:td("break"),case:td("case"),class:td("class"),const:td("const"),continue:td("continue"),debugger:td("debugger"),default:td("default"),do:td("do"),export:td("export"),for:td("for"),if:td("if"),import:td("import"),let:td("let"),return:td("return"),switch:td("switch"),throw:td("throw"),try:td("try"),var:td("var"),while:td("while"),with:td("with")};var fd={meta:{type:"layout",docs:{description:"require or disallow padding lines between statements",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/padding-line-between-statements"},fixable:"whitespace",schema:{definitions:{paddingType:{enum:Object.keys(pd)},statementType:{anyOf:[{enum:Object.keys(dd)},{type:"array",items:{enum:Object.keys(dd)},minItems:1,uniqueItems:!0,additionalItems:!1}]}},type:"array",items:{type:"object",properties:{blankLine:{$ref:"#/definitions/paddingType"},prev:{$ref:"#/definitions/statementType"},next:{$ref:"#/definitions/statementType"}},additionalProperties:!1,required:["blankLine","prev","next"]},additionalItems:!1},messages:{unexpectedBlankLine:"Unexpected blank line before this statement.",expectedBlankLine:"Expected blank line before this statement."}},create(e){const t=e.getSourceCode(),n=e.options||[];let r=null;function o(){r={upper:r,prevNode:null}}function s(){r=r.upper}function a(e,n){let r=e;for(;"LabeledStatement"===r.type;)r=r.body;return Array.isArray(n)?n.some(a.bind(null,r)):dd[n].test(r,t)}function i(o){const s=o.parent.type;if(!(fr.STATEMENT_LIST_PARENTS.has(s)||"SwitchStatement"===s))return;const i=r.prevNode;if(i){const r=function(e,t){for(let r=n.length-1;r>=0;--r){const o=n[r];if(a(e,o.prev)&&a(t,o.next))return pd[o.blankLine]}return pd.any}(i,o),s=function(e,n){const r=[];let o=ld(t,e);if(n.loc.start.line-o.loc.end.line>=2)do{const e=t.getTokenAfter(o,{includeComments:!0});e.loc.start.line-o.loc.end.line>=2&&r.push([o,e]),o=e}while(o.range[0]0)return;const c=function(e){const t=e.variables;for(let e=0;e0)return;const l=function(e){const t={isCallback:!1,isLexicalThis:!1};let n=e,r=e.parent,o=!1;for(;n;){switch(r.type){case"LogicalExpression":case"ChainExpression":case"ConditionalExpression":break;case"MemberExpression":if(r.object!==n||r.property.computed||"Identifier"!==r.property.type||"bind"!==r.property.name)return t;{const e="ChainExpression"===r.parent.type?r.parent:r;if(!fr.isCallee(e))return t;o||(o=!0,t.isLexicalThis=1===e.parent.arguments.length&&"ThisExpression"===e.parent.arguments[0].type),r=e.parent}break;case"CallExpression":case"NewExpression":return r.callee!==n&&(t.isCallback=!0),t;default:return t}n=r,r=r.parent}throw new Error("unreachable")}(t);!l.isCallback||n&&s.this&&!l.isLexicalThis||s.super||s.meta||e.report({node:t,messageId:"preferArrowCallback",*fix(e){if(!l.isLexicalThis&&s.this||(n=t.params).every((e=>"Identifier"===e.type))&&n.length!==new Set(n.map((e=>e.name))).size)return;var n;if(l.isLexicalThis){const n=t.parent;if("MemberExpression"!==n.type)return;const r=n.parent,s=o.getTokenAfter(n.object,fr.isNotClosingParenToken),a=o.getLastToken(r);if(fr.isParenthesised(o,n))return;if(o.commentsExistBetween(s,a))return;yield e.removeRange([s.range[0],a.range[1]])}const r=o.getFirstToken(t,t.async?1:0),a=o.getTokenAfter(r,fr.isOpeningParenToken);o.commentsExistBetween(r,a)?(yield e.remove(r),t.id&&(yield e.remove(t.id))):yield e.removeRange([r.range[0],a.range[0]]),yield e.insertTextBefore(t.body,"=> ");let i=l.isLexicalThis?t.parent.parent:t;"ChainExpression"===i.type&&(i=i.parent),"CallExpression"===i.parent.type||"ConditionalExpression"===i.parent.type||fr.isParenthesised(o,i)||fr.isParenthesised(o,t)||(yield e.insertTextBefore(i,"("),yield e.insertTextAfter(i,")"))}})}}}};const gd=/^(?:.+?Pattern|RestElement|SpreadProperty|ExperimentalRestProperty|Property)$/u,hd=/^(?:Program|BlockStatement|SwitchCase)$/u,yd=/^(?:VariableDeclarator|AssignmentExpression)$/u;function xd(e,t){if(t.through.find((t=>t.resolved&&t.resolved.name===e)))return!0;const n=fr.getVariableByName(t,e);return null!==n&&n.defs.some((e=>"Parameter"===e.type))}function bd(e){if(!e.isWrite())return null;let t=e.identifier.parent;for(;gd.test(t.type);)t=t.parent;return yd.test(t.type)?t:null}function Ed(e){switch(e.type){case"ObjectPattern":return e.properties.some((e=>!!e&&Ed(e.argument||e.value)));case"ArrayPattern":return e.elements.some((e=>!!e&&Ed(e)));case"AssignmentPattern":return Ed(e.left);case"MemberExpression":return!0}return!1}function Sd(e,t){if(e.eslintUsed&&"global"===e.scope.type)return null;let n=null,r=!1;const o=e.references;for(let s=0;se.value)).map((e=>e.value.name)).some((t=>xd(t,e.scope))),o=Ed(n)}else if("ArrayPattern"===n.type){r=n.elements.map((e=>e&&e.name)).some((t=>xd(t,e.scope))),o=Ed(n)}if(r||o)return null}n=a}else if(a.isRead()&&null===n){if(t)return null;r=!0}}return null!==n&&n.from===e.scope&&function(e){let t=e.parent;for(;gd.test(t.type);)t=t.parent;return"VariableDeclarator"===t.type||"AssignmentExpression"===t.type&&"ExpressionStatement"===t.parent.type&&hd.test(t.parent.parent.type)}(n.identifier)?r?e.defs[0].name:n.identifier:null}function Cd(e,t,n){return!e||n(e)?null:e.type===t?e:Cd(e.parent,t,n)}var vd={meta:{type:"suggestion",docs:{description:"require `const` declarations for variables that are never reassigned after declared",category:"ECMAScript 6",recommended:!1,url:"https://eslint.org/docs/rules/prefer-const"},fixable:"code",schema:[{type:"object",properties:{destructuring:{enum:["any","all"],default:"any"},ignoreReadBeforeAssign:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{useConst:"'{{name}}' is never reassigned. Use 'const' instead."}},create(e){const t=e.options[0]||{},n=e.getSourceCode(),r="all"!==t.destructuring,o=!0===t.ignoreReadBeforeAssign,s=[];let a=0,i=null,c="";function l(t){const o=t.filter(Boolean);if(t.length&&(r||o.length===t.length)){const r=Cd(t[0],"VariableDeclaration",(e=>e.type.endsWith("Statement"))),s=null===r;if(!s&&r.declarations.length>0){const e=r.declarations[0];if(e.init){const t=e.init.parent;"VariableDeclarator"===t.type&&(t.id.name!==c&&(c=t.id.name,a=0),"ObjectPattern"===t.id.type&&t.init.name!==c&&(c=t.init.name,a=0),t.id!==i&&(i=t.id,a=0))}}let l=r&&("ForInStatement"===r.parent.type||"ForOfStatement"===r.parent.type||r.declarations.every((e=>e.init)))&&o.length===t.length;!s&&r.declarations&&1!==r.declarations.length&&r&&r.declarations&&r.declarations.length>=1&&(a+=o.length,l=l&&a===r.declarations.length),o.forEach((t=>{e.report({node:t,messageId:"useConst",data:t,fix:l?e=>{const t=n.getFirstToken(r,(e=>e.value===r.kind));return new Ra(e,n).retainRange(r.range).replaceTextRange(t.range,"const")}:null})}))}}return{"Program:exit"(){(function(e,t){const n=new Map;for(let r=0;rfunction(t,n){const r=n.init,o=e.getSourceCode();if(o.getCommentsInside(n).length>o.getCommentsInside(r.object).length)return null;let s=o.getText(r.object);return fr.getPrecedence(r.object)"SpreadElement"===e.type))||t.getCommentsInside(n).length>0)return null;const r=n.arguments[0],o=n.arguments[1],s=t.getText(r),a=t.getText(o),i=function(e){return fr.getPrecedence(e)<=Td||"AwaitExpression"===e.type||"UnaryExpression"===e.type}(r),c=function(e){return fr.getPrecedence(e)=Td&&!("BinaryExpression"===n.type&&"**"===n.operator&&n.right===e)&&!(("CallExpression"===n.type||"NewExpression"===n.type)&&n.arguments.includes(e))&&!("MemberExpression"===n.type&&n.computed&&n.property===e)&&!("ArrayExpression"===n.type))&&!fr.isParenthesised(t,e)}(n,t);let u="",p="";if(!l){if(!i){const e=t.getFirstToken(r),o=t.getTokenBefore(n);o&&o.range[1]===n.range[0]&&!fr.canTokensBeAdjacent(o,e)&&(u=" ")}if(!c){const e=t.getLastToken(o),r=t.getTokenAfter(n);r&&n.range[1]===r.range[0]&&!fr.canTokensBeAdjacent(e,r)&&(p=" ")}}const d=Id(s,i),f=Id(a,c),m=Id(`${d}**${f}`,l);return e.replaceText(n,`${u}${m}${p}`)}})}return{Program(){const t=e.getScope(),r=new Pd(t),o={Math:{pow:{[wd]:!0}}};for(const{node:e}of r.iterateGlobalReferences(o))n(e)}}}};const{CALL:Dd,CONSTRUCT:Od,ReferenceTracker:Bd,getStringIfConstant:Nd}=G.default,jd=new X.default.RegExpParser;var Ld={meta:{type:"suggestion",docs:{description:"enforce using named capture group in regular expression",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/prefer-named-capture-group"},schema:[],messages:{required:"Capture group '{{group}}' should be converted to a named or non-capturing group."}},create(e){function t(t,n,r){let o;try{o=jd.parsePattern(t,0,t.length,r)}catch{return}X.default.visitRegExpAST(o,{onCapturingGroupEnter(t){t.name||e.report({node:n,messageId:"required",data:{group:t.raw}})}})}return{Literal(e){e.regex&&t(e.regex.pattern,e,e.regex.flags.includes("u"))},Program(){const n=e.getScope(),r=new Bd(n),o={RegExp:{[Dd]:!0,[Od]:!0}};for(const{node:e}of r.iterateGlobalReferences(o)){const n=Nd(e.arguments[0]),r=Nd(e.arguments[1]);n&&t(n,e,r&&r.includes("u"))}}}}};const Rd=new Map([[2,{system:"binary",literalPrefix:"0b"}],[8,{system:"octal",literalPrefix:"0o"}],[16,{system:"hexadecimal",literalPrefix:"0x"}]]);var Md={meta:{type:"suggestion",docs:{description:"disallow `parseInt()` and `Number.parseInt()` in favor of binary, octal, and hexadecimal literals",category:"ECMAScript 6",recommended:!1,url:"https://eslint.org/docs/rules/prefer-numeric-literals"},schema:[],messages:{useLiteral:"Use {{system}} literals instead of {{functionName}}()."},fixable:"code"},create(e){const t=e.getSourceCode();return{"CallExpression[arguments.length=2]"(n){const[r,o]=n.arguments,s=fr.getStaticStringValue(r),a=o.value;if(null!==s&&fr.isStringLiteral(r)&&"Literal"===o.type&&"number"==typeof a&&Rd.has(a)&&(i=n.callee,fr.isSpecificId(i,"parseInt")||fr.isSpecificMemberAccess(i,"Number","parseInt"))){const{system:r,literalPrefix:o}=Rd.get(a);e.report({node:n,messageId:"useLiteral",data:{system:r,functionName:t.getText(n.callee)},fix(e){if(t.getCommentsInside(n).length)return null;const r=`${o}${s}`;if(+r!==parseInt(s,a))return null;const i=t.getTokenBefore(n),c=t.getTokenAfter(n);let l="",u="";return i&&i.range[1]===n.range[0]&&!fr.canTokensBeAdjacent(i,r)&&(l=" "),c&&n.range[1]===c.range[0]&&!fr.canTokensBeAdjacent(r,c)&&(u=" "),e.replaceText(n,`${l}${r}${u}`)}})}var i}}}};const{CALL:_d,ReferenceTracker:$d}=G.default,{isCommaToken:qd,isOpeningParenToken:Ud,isClosingParenToken:Vd,isParenthesised:Wd}=fr,Gd=/\s/u;function zd(e){return e.arguments.some((e=>"SpreadElement"===e.type))}function Jd(e){return"Property"===e.type&&("get"===e.kind||"set"===e.kind)}function Kd(e){return e.properties.some(Jd)}function Yd(e){return e.arguments.filter((e=>"ObjectExpression"===e.type)).some(Kd)}function Hd(e,t){switch(e.type){case"AssignmentExpression":case"ArrowFunctionExpression":case"ConditionalExpression":return!Wd(t,e);default:return!1}}function Xd(e,t,n){const r=[n.getFirstToken(e),n.getLastToken(e)];let o=n.getTokenBefore(e),s=n.getTokenAfter(e);for(;o&&s&&o.range[0]>t.range[0]&&Ud(o)&&Vd(s);)r.push(o,s),o=n.getTokenBefore(o),s=n.getTokenAfter(s);return r.sort(((e,t)=>e.range[0]-t.range[0]))}function Qd(e,t){const n=t.text;let r=e.range[0];{const n=t.getTokenBefore(e,{includeComments:!0});if(n&&"Line"===n.type)return r}for(;Gd.test(n[r-1]||"");)r-=1;return r}function Zd(e,t){const n=t.text;let r=e.range[1];for(;Gd.test(n[r]||"");)r+=1;return r}function ef(e,t){return function*(n){const r=t.getTokenAfter(e.callee,Ud),o=t.getLastToken(e);yield n.removeRange([e.range[0],r.range[0]]),!function(e,t){const n=e.parent;switch(n.type){case"VariableDeclarator":case"ArrayExpression":case"ReturnStatement":case"CallExpression":case"Property":return!1;case"AssignmentExpression":return n.left===e&&!Wd(t,e);default:return!Wd(t,e)}}(e,t)?(yield n.replaceText(r,"{"),yield n.replaceText(o,"}")):(yield n.replaceText(r,"({"),yield n.replaceText(o,"})"));for(const o of e.arguments){const e=Xd(o,r,t),s=e.shift(),a=e.pop();if("ObjectExpression"===o.type){const r=t.getLastToken(o,1),i=t.getTokenAfter(a);for(const t of e)yield n.remove(t);const c=[s.range[0],Zd(s,t)],l=[Math.max(Qd(a,t),c[1]),a.range[1]];yield n.removeRange(c),yield n.removeRange(l),(0===o.properties.length||qd(r))&&qd(i)&&(yield n.remove(i))}else Hd(o,t)?(yield n.insertTextBefore(s,"...("),yield n.insertTextAfter(a,")")):yield n.insertTextBefore(s,"...")}}}var tf={meta:{type:"suggestion",docs:{description:"disallow using Object.assign with an object literal as the first argument and prefer the use of object spread instead.",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/prefer-object-spread"},schema:[],fixable:"code",messages:{useSpreadMessage:"Use an object spread instead of `Object.assign` eg: `{ ...foo }`.",useLiteralMessage:"Use an object literal instead of `Object.assign`. eg: `{ foo: bar }`."}},create(e){const t=e.getSourceCode();return{Program(){const n=e.getScope(),r=new $d(n),o={Object:{assign:{[_d]:!0}}};for(const{node:n}of r.iterateGlobalReferences(o))if(n.arguments.length>=1&&"ObjectExpression"===n.arguments[0].type&&!zd(n)&&!(n.arguments.length>1&&Yd(n))){const r=1===n.arguments.length?"useLiteralMessage":"useSpreadMessage",o=ef(n,t);e.report({node:n,messageId:r,fix:o})}}}}},nf={meta:{type:"suggestion",docs:{description:"require using Error objects as Promise rejection reasons",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/prefer-promise-reject-errors"},fixable:null,schema:[{type:"object",properties:{allowEmptyReject:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{rejectAnError:"Expected the Promise rejection reason to be an Error."}},create(e){const t=e.options.length&&e.options[0].allowEmptyReject;function n(n){!n.arguments.length&&t||n.arguments.length&&fr.couldBeError(n.arguments[0])&&("Identifier"!==n.arguments[0].type||"undefined"!==n.arguments[0].name)||e.report({node:n,messageId:"rejectAnError"})}return{CallExpression(e){(function(e){return fr.isSpecificMemberAccess(e.callee,"Promise","reject")})(e)&&n(e)},"NewExpression:exit"(t){"Identifier"===t.callee.type&&"Promise"===t.callee.name&&t.arguments.length&&fr.isFunction(t.arguments[0])&&t.arguments[0].params.length>1&&"Identifier"===t.arguments[0].params[1].type&&e.getDeclaredVariables(t.arguments[0]).find((e=>e.name===t.arguments[0].params[1].name)).references.filter((e=>e.isRead())).filter((e=>"CallExpression"===e.identifier.parent.type&&e.identifier===e.identifier.parent.callee)).forEach((e=>n(e.identifier.parent)))}}}},rf={meta:{type:"suggestion",docs:{description:"require `Reflect` methods where applicable",category:"ECMAScript 6",recommended:!1,url:"https://eslint.org/docs/rules/prefer-reflect"},deprecated:!0,replacedBy:[],schema:[{type:"object",properties:{exceptions:{type:"array",items:{enum:["apply","call","delete","defineProperty","getOwnPropertyDescriptor","getPrototypeOf","setPrototypeOf","isExtensible","getOwnPropertyNames","preventExtensions"]},uniqueItems:!0}},additionalProperties:!1}],messages:{preferReflect:"Avoid using {{existing}}, instead use {{substitute}}."}},create(e){const t={apply:"Function.prototype.apply",call:"Function.prototype.call",defineProperty:"Object.defineProperty",getOwnPropertyDescriptor:"Object.getOwnPropertyDescriptor",getPrototypeOf:"Object.getPrototypeOf",setPrototypeOf:"Object.setPrototypeOf",isExtensible:"Object.isExtensible",getOwnPropertyNames:"Object.getOwnPropertyNames",preventExtensions:"Object.preventExtensions"},n={apply:"Reflect.apply",call:"Reflect.apply",defineProperty:"Reflect.defineProperty",getOwnPropertyDescriptor:"Reflect.getOwnPropertyDescriptor",getPrototypeOf:"Reflect.getPrototypeOf",setPrototypeOf:"Reflect.setPrototypeOf",isExtensible:"Reflect.isExtensible",getOwnPropertyNames:"Reflect.getOwnPropertyNames",preventExtensions:"Reflect.preventExtensions"},r=(e.options[0]||{}).exceptions||[];function o(t,n,r){e.report({node:t,messageId:"preferReflect",data:{existing:n,substitute:r}})}return{CallExpression(e){const s=(e.callee.property||{}).name,a="Reflect"===(e.callee.object||{}).name,i=Object.prototype.hasOwnProperty.call(n,s),c=-1!==r.indexOf(s);!i||a||c||o(e,t[s],n[s])},UnaryExpression(e){const t="delete"===e.operator,n="Identifier"===e.argument.type,s=-1!==r.indexOf("delete");!t||n||s||o(e,"the delete keyword","Reflect.deleteProperty")}}}};const{CALL:of,CONSTRUCT:sf,ReferenceTracker:af,findVariable:cf}=G.default;function lf(e){return"Literal"===e.type&&Object.prototype.hasOwnProperty.call(e,"regex")}function uf(e){return"TemplateLiteral"===e.type&&0===e.expressions.length}var pf={meta:{type:"suggestion",docs:{description:"disallow use of the `RegExp` constructor in favor of regular expression literals",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/prefer-regex-literals"},schema:[{type:"object",properties:{disallowRedundantWrapping:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{unexpectedRegExp:"Use a regular expression literal instead of the 'RegExp' constructor.",unexpectedRedundantRegExp:"Regular expression literal is unnecessarily wrapped within a 'RegExp' constructor.",unexpectedRedundantRegExpWithFlags:"Use regular expression literal with flags instead of the 'RegExp' constructor."}},create(e){const[{disallowRedundantWrapping:t=!1}={}]=e.options;function n(t){return"TaggedTemplateExpression"===t.type&&fr.isSpecificMemberAccess(t.tag,"String","raw")&&function(t){const n=e.getScope(),r=cf(n,t);return null!==r&&"global"===r.scope.type&&0===r.defs.length}(fr.skipChainExpression(t.tag).object)&&uf(t.quasi)}function r(e){return function(e){return"Literal"===e.type&&"string"==typeof e.value}(e)||uf(e)||n(e)}function o(e){const t=e.arguments;return!(1!==t.length&&2!==t.length||!t.every(r))}function s(e){const t=e.arguments;return!(1!==t.length||!lf(t[0]))||!(2!==t.length||!lf(t[0])||!r(t[1]))}return{Program(){const n=e.getScope(),r=new af(n),a={RegExp:{[of]:!0,[sf]:!0}};for(const{node:n}of r.iterateGlobalReferences(a))t&&s(n)?2===n.arguments.length?e.report({node:n,messageId:"unexpectedRedundantRegExpWithFlags"}):e.report({node:n,messageId:"unexpectedRedundantRegExp"}):o(n)&&e.report({node:n,messageId:"unexpectedRegExp"})}}}};function df(e){const t=e.identifier,n=t.parent;return!("MemberExpression"===n.type&&n.object===t&&!n.computed)}var ff={meta:{type:"suggestion",docs:{description:"require rest parameters instead of `arguments`",category:"ECMAScript 6",recommended:!1,url:"https://eslint.org/docs/rules/prefer-rest-params"},schema:[],messages:{preferRestParams:"Use the rest parameters instead of 'arguments'."}},create(e){function t(t){e.report({node:t.identifier,loc:t.identifier.loc,messageId:"preferRestParams"})}function n(){const n=function(e){const t=e.variables;for(let e=0;ee+o.slice(t.range[1],r[n+1].range[0])),"")}function o(e,n,s){if("Literal"===e.type&&"string"==typeof e.value)return`\`${e.raw.slice(1,-1).replace(/\\*(\$\{|`)/gu,(e=>e.lastIndexOf("\\")%2?`\\${e}`:e)).replace(new RegExp(`\\\\${e.raw[0]}`,"gu"),e.raw[0])}\``;if("TemplateLiteral"===e.type)return t.getText(e);if(gf(e)&&xf(e)&&bf(e)){const i=t.getFirstTokenBetween(e.left,e.right,(e=>"+"===e.value)),c=r(e.left,i),l=r(i,e.right),u="BinaryExpression"===(a=e.left).type?Ef(a.right):"TemplateLiteral"===a.type?a.expressions.length&&a.quasis.length&&a.quasis[a.quasis.length-1].range[0]===a.quasis[a.quasis.length-1].range[1]:"Literal"!==a.type||"string"!=typeof a.value,p=Ef(e.right);return u?o(e.left,n,c+l).slice(0,-1)+o(e.right,null,s).slice(1):p?o(e.left,n,null).slice(0,-1)+o(e.right,c+l,s).slice(1):`${o(e.left,n,null)}${c}+${l}${o(e.right,s,null)}`}var a;return`\`\${${n||""}${t.getText(e)}${s||""}}\``}function s(e,t){const n=hf(t.parent);return yf(n)?null:e.replaceText(n,o(n,null,null))}function a(t){if(!fr.isStringLiteral(t)||!gf(t.parent))return;const r=hf(t.parent);n[r.range[0]]||(n[r.range[0]]=!0,bf(r)&&e.report({node:r,messageId:"unexpectedStringConcatenation",fix:e=>s(e,t)}))}return{Program(){n=Object.create(null)},Literal:a,TemplateLiteral:a}}},Cf={meta:{type:"suggestion",docs:{description:"require quotes around object literal property names",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/quote-props"},schema:{anyOf:[{type:"array",items:[{enum:["always","as-needed","consistent","consistent-as-needed"]}],minItems:0,maxItems:1},{type:"array",items:[{enum:["always","as-needed","consistent","consistent-as-needed"]},{type:"object",properties:{keywords:{type:"boolean"},unnecessary:{type:"boolean"},numbers:{type:"boolean"}},additionalProperties:!1}],minItems:0,maxItems:2}]},fixable:"code",messages:{requireQuotesDueToReservedWord:"Properties should be quoted as '{{property}}' is a reserved word.",inconsistentlyQuotedProperty:"Inconsistently quoted property '{{key}}' found.",unnecessarilyQuotedProperty:"Unnecessarily quoted property '{{property}}' found.",unquotedReservedProperty:"Unquoted reserved word '{{property}}' used as key.",unquotedNumericProperty:"Unquoted number literal '{{property}}' used as key.",unquotedPropertyFound:"Unquoted property '{{property}}' found.",redundantQuoting:"Properties shouldn't be quoted as all quotes are redundant."}},create(e){const t=e.options[0],n=e.options[1]&&e.options[1].keywords,r=!e.options[1]||!1!==e.options[1].unnecessary,o=e.options[1]&&e.options[1].numbers,s=e.getSourceCode();function a(e){return io.indexOf(e)>=0}function i(e,t,n){return 1===t.length&&0===t[0].start&&t[0].end===e.length&&(["Identifier","Keyword","Null","Boolean"].indexOf(t[0].type)>=0||"Numeric"===t[0].type&&!n&&String(+t[0].value)===t[0].value)}function c(e){return"Identifier"===e.type?e.name:e.value}function l(e){return"Literal"===e.type&&"string"==typeof e.value?s.getText(e):`"${"Identifier"===e.type?e.name:e.value}"`}function u(t,r){const o=[],s=[];let u=null,p=!1;t.properties.forEach((e=>{const t=e.key;if(t&&!e.method&&!e.computed&&!e.shorthand)if("Literal"===t.type&&"string"==typeof t.value){if(o.push(e),r){let e;try{e=q.default.tokenize(t.value)}catch{return void(p=!0)}p=p||!i(t.value,e)||n&&a(e[0].value)}}else n&&r&&"Identifier"===t.type&&a(t.name)?(s.push(e),p=!0,u=t.name):s.push(e)})),r&&o.length&&!p?o.forEach((t=>{e.report({node:t,messageId:"redundantQuoting",fix:e=>e.replaceText(t.key,c(t.key))})})):s.length&&u?s.forEach((t=>{e.report({node:t,messageId:"requireQuotesDueToReservedWord",data:{property:u},fix:e=>e.replaceText(t.key,l(t.key))})})):o.length&&s.length&&s.forEach((t=>{e.report({node:t,messageId:"inconsistentlyQuotedProperty",data:{key:t.key.name||t.key.value},fix:e=>e.replaceText(t.key,l(t.key))})}))}return{Property(s){"always"!==t&&t||function(t){const n=t.key;t.method||t.computed||t.shorthand||"Literal"===n.type&&"string"==typeof n.value||e.report({node:t,messageId:"unquotedPropertyFound",data:{property:n.name||n.value},fix:e=>e.replaceText(n,l(n))})}(s),"as-needed"===t&&function(t){const s=t.key;if(!(t.method||t.computed||t.shorthand))if("Literal"===s.type&&"string"==typeof s.value){let l;try{l=q.default.tokenize(s.value)}catch{return}if(1!==l.length)return;if(a(l[0].value)&&n)return;r&&i(s.value,l,o)&&e.report({node:t,messageId:"unnecessarilyQuotedProperty",data:{property:s.value},fix:e=>e.replaceText(s,c(s))})}else n&&"Identifier"===s.type&&a(s.name)?e.report({node:t,messageId:"unquotedReservedProperty",data:{property:s.name},fix:e=>e.replaceText(s,l(s))}):o&&"Literal"===s.type&&fr.isNumericLiteral(s)&&e.report({node:t,messageId:"unquotedNumericProperty",data:{property:s.value},fix:e=>e.replaceText(s,l(s))})}(s)},ObjectExpression(e){"consistent"===t&&u(e,!1),"consistent-as-needed"===t&&u(e,!0)}}}};const vf={double:{quote:'"',alternateQuote:"'",description:"doublequote"},single:{quote:"'",alternateQuote:'"',description:"singlequote"},backtick:{quote:"`",alternateQuote:'"',description:"backtick"}},Af=new RegExp(String.raw`(^|[^\\])(\\\\)*[${Array.from(fr.LINEBREAKS).join("")}]`,"u");vf.double.convert=vf.single.convert=vf.backtick.convert=function(e){const t=this.quote,n=e[0];return t===n?e:t+e.slice(1,-1).replace(/\\(\$\{|\r\n?|\n|.)|["'`]|\$\{|(\r\n?|\n)/gu,((e,r,o)=>r===n||"`"===n&&"${"===r?r:e===t||"`"===t&&"${"===e?`\\${e}`:o&&"`"===n?"\\n":e))+t};var kf={meta:{type:"layout",docs:{description:"enforce the consistent use of either backticks, double, or single quotes",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/quotes"},fixable:"code",schema:[{enum:["single","double","backtick"]},{anyOf:[{enum:["avoid-escape"]},{type:"object",properties:{avoidEscape:{type:"boolean"},allowTemplateLiterals:{type:"boolean"}},additionalProperties:!1}]}],messages:{wrongQuotes:"Strings must use {{description}}."}},create(e){const t=e.options[0],n=vf[t||"double"],r=e.options[1],o=r&&!0===r.allowTemplateLiterals,s=e.getSourceCode();let a=r&&!0===r.avoidEscape;function i(e){return"ExpressionStatement"===e.type&&"Literal"===e.expression.type&&"string"==typeof e.expression.value}function c(e){const t=e.parent.parent;if("Program"!==t.type&&("BlockStatement"!==t.type||!fr.isFunction(t.parent)))return!1;for(let n=0;n=0),o||e.report({node:r,messageId:"wrongQuotes",data:{description:n.description},fix:e=>"backtick"===t&&fr.hasOctalOrNonOctalDecimalEscapeSequence(s)?null:e.replaceText(r,n.convert(r.raw))})}},TemplateLiteral(r){o||"backtick"===t||function(e){return"TaggedTemplateExpression"===e.parent.type&&e===e.parent.quasi||(e.expressions.length>0||!!(e.quasis.length>=1&&Af.test(e.quasis[0].value.raw)))}(r)||e.report({node:r,messageId:"wrongQuotes",data:{description:n.description},fix:e=>c(r)?null:e.replaceText(r,n.convert(s.getText(r)))})}}}};const wf=new Set(Array.from({length:35},((e,t)=>t+2)));function Pf(e){return e.defs.length>=1}var Tf={meta:{type:"suggestion",docs:{description:"enforce the consistent use of the radix argument when using `parseInt()`",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/radix"},schema:[{enum:["always","as-needed"]}],messages:{missingParameters:"Missing parameters.",redundantRadix:"Redundant radix parameter.",missingRadix:"Missing radix parameter.",invalidRadix:"Invalid radix parameter, must be an integer between 2 and 36."}},create(e){const t=e.options[0]||"always";function n(n){const r=n.arguments;switch(r.length){case 0:e.report({node:n,messageId:"missingParameters"});break;case 1:"always"===t&&e.report({node:n,messageId:"missingRadix"});break;default:"as-needed"===t&&function(e){return"Literal"===e.type&&10===e.value}(r[1])?e.report({node:n,messageId:"redundantRadix"}):function(e){return!("Literal"===e.type&&!wf.has(e.value)||"Identifier"===e.type&&"undefined"===e.name)}(r[1])||e.report({node:n,messageId:"invalidRadix"})}}return{"Program:exit"(){const t=e.getScope();let r;r=fr.getVariableByName(t,"parseInt"),r&&!Pf(r)&&r.references.forEach((e=>{const t=e.identifier;fr.isCallee(t)&&n(t.parent)})),r=fr.getVariableByName(t,"Number"),r&&!Pf(r)&&r.references.forEach((e=>{const t=e.identifier.parent,r="ChainExpression"===t.parent.type?t.parent:t;(function(e){return"MemberExpression"===e.type&&!e.computed&&"Identifier"===e.property.type&&"parseInt"===e.property.name})(t)&&fr.isCallee(r)&&n(r.parent)}))}}}};function If(e,t=new Map){for(const n of e.references)t.set(n.identifier,n);for(const n of e.childScopes)"function"!==n.type&&If(n,t);return t}class Ff{constructor(){this.info=new WeakMap}initialize(e){const t=new Set,n=new Set;for(const r of e.prevSegments){const e=this.info.get(r);e&&(e.outdatedReadVariableNames.forEach(Set.prototype.add,t),e.freshReadVariableNames.forEach(Set.prototype.add,n))}this.info.set(e,{outdatedReadVariableNames:t,freshReadVariableNames:n})}markAsRead(e,t){for(const n of e){const e=this.info.get(n);e&&(e.freshReadVariableNames.add(t),e.outdatedReadVariableNames.delete(t))}}makeOutdated(e){for(const t of e){const e=this.info.get(t);e&&(e.freshReadVariableNames.forEach(Set.prototype.add,e.outdatedReadVariableNames),e.freshReadVariableNames.clear())}}isOutdated(e,t){for(const n of e){const e=this.info.get(n);if(e&&e.outdatedReadVariableNames.has(t))return!0}return!1}}var Df={meta:{type:"problem",docs:{description:"disallow assignments that can lead to race conditions due to usage of `await` or `yield`",category:"Possible Errors",recommended:!1,url:"https://eslint.org/docs/rules/require-atomic-updates"},fixable:null,schema:[],messages:{nonAtomicUpdate:"Possible race condition: `{{value}}` might be reassigned based on an outdated value of `{{value}}`."}},create(e){const t=e.getSourceCode(),n=new Map,r=new Ff;let o=null;return{onCodePathStart(t){const n=e.getScope(),r="function"===n.type&&(n.block.async||n.block.generator);o={upper:o,codePath:t,referenceMap:r?If(n):null}},onCodePathEnd(){o=o.upper},onCodePathSegmentStart(e){r.initialize(e)},Identifier(e){const{codePath:t,referenceMap:s}=o,a=s&&s.get(e);if(!a)return;const i=a.identifier.name,c=a.resolved,l=function(e){if(e.writeExpr)return e.writeExpr;let t=e.identifier;for(;t;){const e=t.parent.type;if("AssignmentExpression"===e&&t.parent.left===t)return t.parent.right;if("MemberExpression"!==e||t.parent.object!==t)break;t=t.parent}return null}(a),u="MemberExpression"===a.identifier.parent.type;if(!a.isRead()||l&&"="===l.parent.operator||r.markAsRead(t.currentSegments,i),l&&l.parent.right===l&&!function(e,t){if(!e)return!1;if(t&&e.defs.some((e=>"Parameter"===e.type)))return!1;const n=e.scope.variableScope;return e.references.every((e=>e.from.variableScope===n))}(c,u)){let e=n.get(l);e||(e=[],n.set(l,e)),e.push(a)}},":expression:exit"(s){const{codePath:a,referenceMap:i}=o;if(!i)return;"AwaitExpression"!==s.type&&"YieldExpression"!==s.type||r.makeOutdated(a.currentSegments);const c=n.get(s);if(c){n.delete(s);for(const n of c){const o=n.identifier.name;r.isOutdated(a.currentSegments,o)&&e.report({node:s.parent,messageId:"nonAtomicUpdate",data:{value:t.getText(s.parent.left)}})}}}}}};var Of={meta:{type:"suggestion",docs:{description:"disallow async functions which have no `await` expression",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/require-await"},schema:[],messages:{missingAwait:"{{name}} has no 'await' expression."}},create(e){const t=e.getSourceCode();let n=null;function r(){n={upper:n,hasAwait:!1}}function o(r){var o;r.generator||!r.async||n.hasAwait||fr.isEmptyFunction(r)||e.report({node:r,loc:fr.getFunctionHeadLoc(r,t),messageId:"missingAwait",data:{name:(o=fr.getFunctionNameWithKind(r),o[0].toUpperCase()+o.slice(1))}}),n=n.upper}return{FunctionDeclaration:r,FunctionExpression:r,ArrowFunctionExpression:r,"FunctionDeclaration:exit":o,"FunctionExpression:exit":o,"ArrowFunctionExpression:exit":o,AwaitExpression(){n&&(n.hasAwait=!0)},ForOfStatement(e){n&&e.await&&(n.hasAwait=!0)}}}},Bf={meta:{type:"suggestion",docs:{description:"require JSDoc comments",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/require-jsdoc"},schema:[{type:"object",properties:{require:{type:"object",properties:{ClassDeclaration:{type:"boolean",default:!1},MethodDefinition:{type:"boolean",default:!1},FunctionDeclaration:{type:"boolean",default:!0},ArrowFunctionExpression:{type:"boolean",default:!1},FunctionExpression:{type:"boolean",default:!1}},additionalProperties:!1,default:{}}},additionalProperties:!1}],deprecated:!0,replacedBy:[],messages:{missingJSDocComment:"Missing JSDoc comment."}},create(e){const t=e.getSourceCode(),n=Object.assign({FunctionDeclaration:!0,MethodDefinition:!1,ClassDeclaration:!1,ArrowFunctionExpression:!1,FunctionExpression:!1},e.options[0]&&e.options[0].require);function r(n){t.getJSDocComment(n)||function(t){e.report({node:t,messageId:"missingJSDocComment"})}(n)}return{FunctionDeclaration(e){n.FunctionDeclaration&&r(e)},FunctionExpression(e){(n.MethodDefinition&&"MethodDefinition"===e.parent.type||n.FunctionExpression&&("VariableDeclarator"===e.parent.type||"Property"===e.parent.type&&e===e.parent.value))&&r(e)},ClassDeclaration(e){n.ClassDeclaration&&r(e)},ArrowFunctionExpression(e){n.ArrowFunctionExpression&&"VariableDeclarator"===e.parent.type&&r(e)}}}};const{CALL:Nf,CONSTRUCT:jf,ReferenceTracker:Lf,getStringIfConstant:Rf}=G.default;var Mf={meta:{type:"suggestion",docs:{description:"enforce the use of `u` flag on RegExp",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/require-unicode-regexp"},messages:{requireUFlag:"Use the 'u' flag."},schema:[]},create:e=>({"Literal[regex]"(t){(t.regex.flags||"").includes("u")||e.report({node:t,messageId:"requireUFlag"})},Program(){const t=e.getScope(),n=new Lf(t),r={RegExp:{[Nf]:!0,[jf]:!0}};for(const{node:o}of n.iterateGlobalReferences(r)){const n=o.arguments[1],r=Rf(n,t);n&&("string"!=typeof r||r.includes("u"))||e.report({node:o,messageId:"requireUFlag"})}}})},_f={meta:{type:"suggestion",docs:{description:"require generator functions to contain `yield`",category:"ECMAScript 6",recommended:!0,url:"https://eslint.org/docs/rules/require-yield"},schema:[],messages:{missingYield:"This generator function does not have 'yield'."}},create(e){const t=[];function n(e){e.generator&&t.push(0)}function r(n){if(!n.generator)return;0===t.pop()&&n.body.body.length>0&&e.report({node:n,messageId:"missingYield"})}return{FunctionDeclaration:n,"FunctionDeclaration:exit":r,FunctionExpression:n,"FunctionExpression:exit":r,YieldExpression(){t.length>0&&(t[t.length-1]+=1)}}}},$f={meta:{type:"layout",docs:{description:"enforce spacing between rest and spread operators and their expressions",category:"ECMAScript 6",recommended:!1,url:"https://eslint.org/docs/rules/rest-spread-spacing"},fixable:"whitespace",schema:[{enum:["always","never"]}],messages:{unexpectedWhitespace:"Unexpected whitespace after {{type}} operator.",expectedWhitespace:"Expected whitespace after {{type}} operator."}},create(e){const t=e.getSourceCode(),n="always"===e.options[0];function r(r){const o=t.getFirstToken(r),s=t.getTokenAfter(o),a=t.isSpaceBetweenTokens(o,s);let i;switch(r.type){case"SpreadElement":i="spread","ObjectExpression"===r.parent.type&&(i+=" property");break;case"RestElement":i="rest","ObjectPattern"===r.parent.type&&(i+=" property");break;case"ExperimentalSpreadProperty":i="spread property";break;case"ExperimentalRestProperty":i="rest property";break;default:return}n&&!a?e.report({node:r,loc:o.loc,messageId:"expectedWhitespace",data:{type:i},fix:e=>e.replaceTextRange([o.range[1],s.range[0]]," ")}):!n&&a&&e.report({node:r,loc:{start:o.loc.end,end:s.loc.start},messageId:"unexpectedWhitespace",data:{type:i},fix:e=>e.removeRange([o.range[1],s.range[0]])})}return{SpreadElement:r,RestElement:r,ExperimentalSpreadProperty:r,ExperimentalRestProperty:r}}},qf={meta:{type:"layout",docs:{description:"require or disallow semicolons instead of ASI",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/semi"},fixable:"code",schema:{anyOf:[{type:"array",items:[{enum:["never"]},{type:"object",properties:{beforeStatementContinuationChars:{enum:["always","any","never"]}},additionalProperties:!1}],minItems:0,maxItems:2},{type:"array",items:[{enum:["always"]},{type:"object",properties:{omitLastInOneLineBlock:{type:"boolean"}},additionalProperties:!1}],minItems:0,maxItems:2}]},messages:{missingSemi:"Missing semicolon.",extraSemi:"Extra semicolon."}},create(e){const t=/^[-[(/+`]/u,n=e.options[1],r="never"===e.options[0],o=Boolean(n&&n.omitLastInOneLineBlock),s=n&&n.beforeStatementContinuationChars||"any",a=e.getSourceCode();function i(t,n){const r=a.getLastToken(t);let o,s,i;n?(o="extraSemi",i=r.loc,s=function(e){return new Ra(e,a).retainSurroundingTokens(r).remove(r)}):(o="missingSemi",i={start:r.loc.end,end:fr.getNextLocation(a,r.loc.end)},s=function(e){return e.insertTextAfter(r,";")}),e.report({node:t,loc:i,messageId:o,fix:s})}function c(e){const t=e.type;return"DoWhileStatement"!==t&&"BreakStatement"!==t&&"ContinueStatement"!==t&&"DebuggerStatement"!==t&&"ImportDeclaration"!==t&&"ExportAllDeclaration"!==t&&("ReturnStatement"===t?Boolean(e.argument):"ExportNamedDeclaration"===t?Boolean(e.declaration):!function(e){if(!fr.isClosingBraceToken(e))return!1;const t=a.getNodeByRangeIndex(e.range[0]);return"BlockStatement"===t.type&&"ArrowFunctionExpression"===t.parent.type}(a.getLastToken(e,1)))}function l(e){return Boolean(e)&&t.test(e.value)&&"++"!==e.value&&"--"!==e.value}function u(e){return!!function(e){const t=a.getTokenAfter(e);return!t||fr.isClosingBraceToken(t)||fr.isSemicolonToken(t)}(a.getLastToken(e))||!function(e){const t=a.getLastToken(e,1),n=a.getTokenAfter(e);return!!n&&fr.isTokenOnSameLine(t,n)}(e)&&("never"===s&&!c(e)||!l(a.getTokenAfter(e)))}function p(e){const t=fr.isSemicolonToken(a.getLastToken(e));if(r)t&&u(e)?i(e,!0):!t&&"always"===s&&l(a.getTokenAfter(e))&&i(e);else{const n=o&&function(e){const t=e.parent,n=a.getTokenAfter(e);return!(!n||"}"!==n.value||!t||"BlockStatement"!==t.type||t.loc.start.line!==t.loc.end.line)}(e);t&&n?i(e,!0):t||n||i(e)}}return{VariableDeclaration:function(e){const t=e.parent;"ForStatement"===t.type&&t.init===e||/^For(?:In|Of)Statement/u.test(t.type)&&t.left===e||p(e)},ExpressionStatement:p,ReturnStatement:p,ThrowStatement:p,DoWhileStatement:p,DebuggerStatement:p,BreakStatement:p,ContinueStatement:p,ImportDeclaration:p,ExportAllDeclaration:p,ExportNamedDeclaration(e){e.declaration||p(e)},ExportDefaultDeclaration(e){/(?:Class|Function)Declaration/u.test(e.declaration.type)||p(e)}}}},Uf={meta:{type:"layout",docs:{description:"enforce consistent spacing before and after semicolons",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/semi-spacing"},fixable:"whitespace",schema:[{type:"object",properties:{before:{type:"boolean",default:!1},after:{type:"boolean",default:!0}},additionalProperties:!1}],messages:{unexpectedWhitespaceBefore:"Unexpected whitespace before semicolon.",unexpectedWhitespaceAfter:"Unexpected whitespace after semicolon.",missingWhitespaceBefore:"Missing whitespace before semicolon.",missingWhitespaceAfter:"Missing whitespace after semicolon."}},create(e){const t=e.options[0],n=e.getSourceCode();let r=!1,o=!0;function s(t,s){if(fr.isSemicolonToken(t)){if(function(e){const t=n.getTokenBefore(e);return t&&fr.isTokenOnSameLine(t,e)&&n.isSpaceBetweenTokens(t,e)}(t)){if(!r){const r=n.getTokenBefore(t),o={start:r.loc.end,end:t.loc.start};e.report({node:s,loc:o,messageId:"unexpectedWhitespaceBefore",fix:e=>e.removeRange([r.range[1],t.range[0]])})}}else if(r){const n=t.loc;e.report({node:s,loc:n,messageId:"missingWhitespaceBefore",fix:e=>e.insertTextBefore(t," ")})}if(!function(e){const t=n.getTokenBefore(e);return!(t&&fr.isTokenOnSameLine(e,t))}(t)&&!function(e){const t=n.getTokenAfter(e);return!(t&&fr.isTokenOnSameLine(e,t))}(t)&&!function(e){const t=n.getTokenAfter(e);return t&&fr.isClosingBraceToken(t)||fr.isClosingParenToken(t)}(t))if(function(e){const t=n.getTokenAfter(e);return t&&fr.isTokenOnSameLine(e,t)&&n.isSpaceBetweenTokens(e,t)}(t)){if(!o){const r=n.getTokenAfter(t),o={start:t.loc.end,end:r.loc.start};e.report({node:s,loc:o,messageId:"unexpectedWhitespaceAfter",fix:e=>e.removeRange([t.range[1],r.range[0]])})}}else if(o){const n=t.loc;e.report({node:s,loc:n,messageId:"missingWhitespaceAfter",fix:e=>e.insertTextAfter(t," ")})}}}function a(e){s(n.getLastToken(e),e)}return"object"==typeof t&&(r=t.before,o=t.after),{VariableDeclaration:a,ExpressionStatement:a,BreakStatement:a,ContinueStatement:a,DebuggerStatement:a,DoWhileStatement:a,ReturnStatement:a,ThrowStatement:a,ImportDeclaration:a,ExportNamedDeclaration:a,ExportAllDeclaration:a,ExportDefaultDeclaration:a,ForStatement(e){e.init&&s(n.getTokenAfter(e.init),e),e.test&&s(n.getTokenAfter(e.test),e)}}}};const Vf=`:matches(${["BreakStatement","ContinueStatement","DebuggerStatement","DoWhileStatement","ExportAllDeclaration","ExportDefaultDeclaration","ExportNamedDeclaration","ExpressionStatement","ImportDeclaration","ReturnStatement","ThrowStatement","VariableDeclaration"].join(",")})`;var Wf={meta:{type:"layout",docs:{description:"enforce location of semicolons",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/semi-style"},schema:[{enum:["last","first"]}],fixable:"whitespace",messages:{expectedSemiColon:"Expected this semicolon to be at {{pos}}."}},create(e){const t=e.getSourceCode(),n=e.options[0]||"last";function r(n,r){const o=t.getTokenBefore(n),s=t.getTokenAfter(n),a=!o||fr.isTokenOnSameLine(o,n),i=!s||fr.isTokenOnSameLine(n,s);("last"===r&&!a||"first"===r&&!i)&&e.report({loc:n.loc,messageId:"expectedSemiColon",data:{pos:"last"===r?"the end of the previous line":"the beginning of the next line"},fix(e){if(o&&s&&t.commentsExistBetween(o,s))return null;const a=o?o.range[1]:n.range[0],i=s?s.range[0]:n.range[1],c="last"===r?";\n":"\n;";return e.replaceTextRange([a,i],c)}})}return{[Vf](e){if("first"===n&&function(e){const t=e.parent.type;if("IfStatement"===t&&e.parent.consequent===e&&e.parent.alternate)return!0;if("DoWhileStatement"===t)return!0;const n=function(e){const t=e.type;return"BlockStatement"===t||"Program"===t?e.body:"SwitchCase"===t?e.consequent:null}(e.parent);return null!==n&&n[n.length-1]===e}(e))return;const o=t.getLastToken(e);fr.isSemicolonToken(o)&&r(o,n)},ForStatement(e){const n=e.init&&t.getTokenAfter(e.init,fr.isSemicolonToken),o=e.test&&t.getTokenAfter(e.test,fr.isSemicolonToken);n&&r(n,"last"),o&&r(o,"last")}}}},Gf={meta:{type:"suggestion",docs:{description:"enforce sorted import declarations within modules",category:"ECMAScript 6",recommended:!1,url:"https://eslint.org/docs/rules/sort-imports"},schema:[{type:"object",properties:{ignoreCase:{type:"boolean",default:!1},memberSyntaxSortOrder:{type:"array",items:{enum:["none","all","multiple","single"]},uniqueItems:!0,minItems:4,maxItems:4},ignoreDeclarationSort:{type:"boolean",default:!1},ignoreMemberSort:{type:"boolean",default:!1},allowSeparatedGroups:{type:"boolean",default:!1}},additionalProperties:!1}],fixable:"code",messages:{sortImportsAlphabetically:"Imports should be sorted alphabetically.",sortMembersAlphabetically:"Member '{{memberName}}' of the import declaration should be sorted alphabetically.",unexpectedSyntaxOrder:"Expected '{{syntaxA}}' syntax before '{{syntaxB}}' syntax."}},create(e){const t=e.options[0]||{},n=t.ignoreCase||!1,r=t.ignoreDeclarationSort||!1,o=t.ignoreMemberSort||!1,s=t.memberSyntaxSortOrder||["none","all","multiple","single"],a=t.allowSeparatedGroups||!1,i=e.getSourceCode();let c=null;function l(e){return s.indexOf(function(e){return 0===e.specifiers.length?"none":"ImportNamespaceSpecifier"===e.specifiers[0].type?"all":1===e.specifiers.length?"single":"multiple"}(e))}function u(e){return e.specifiers[0]?e.specifiers[0].local.name:null}return{ImportDeclaration(t){if(!r){if(c&&a&&(p=c,d=t,Math.max(d.loc.start.line-p.loc.end.line-1,0)>0)&&(c=null),c){const r=l(t),o=l(c);let a=u(t),i=u(c);n&&(i=i&&i.toLowerCase(),a=a&&a.toLowerCase()),r!==o?r"ImportSpecifier"===e.type)),o=n?e=>e.local.name.toLowerCase():e=>e.local.name,s=r.map(o).findIndex(((e,t,n)=>n[t-1]>e));-1!==s&&e.report({node:r[s],messageId:"sortMembersAlphabetically",data:{memberName:r[s].local.name},fix:e=>r.some((e=>i.getCommentsBefore(e).length||i.getCommentsAfter(e).length))?null:e.replaceTextRange([r[0].range[0],r[r.length-1].range[1]],r.slice().sort(((e,t)=>o(e)>o(t)?1:-1)).reduce(((e,t,n)=>{const o=n===r.length-1?"":i.getText().slice(r[n].range[1],r[n+1].range[0]);return e+i.getText(t)+o}),""))})}}}}};const zf={asc:(e,t)=>e<=t,ascI:(e,t)=>e.toLowerCase()<=t.toLowerCase(),ascN:(e,t)=>Z.default(e,t)<=0,ascIN:(e,t)=>Z.default(e.toLowerCase(),t.toLowerCase())<=0,desc:(e,t)=>zf.asc(t,e),descI:(e,t)=>zf.ascI(t,e),descN:(e,t)=>zf.ascN(t,e),descIN:(e,t)=>zf.ascIN(t,e)};var Jf={meta:{type:"suggestion",docs:{description:"require object keys to be sorted",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/sort-keys"},schema:[{enum:["asc","desc"]},{type:"object",properties:{caseSensitive:{type:"boolean",default:!0},natural:{type:"boolean",default:!1},minKeys:{type:"integer",minimum:2,default:2}},additionalProperties:!1}],messages:{sortKeys:"Expected object keys to be in {{natural}}{{insensitive}}{{order}}ending order. '{{thisName}}' should be before '{{prevName}}'."}},create(e){const t=e.options[0]||"asc",n=e.options[1],r=n&&!1===n.caseSensitive,o=n&&n.natural,s=n&&n.minKeys,a=zf[t+(r?"I":"")+(o?"N":"")];let i=null;return{ObjectExpression(e){i={upper:i,prevName:null,numKeys:e.properties.length}},"ObjectExpression:exit"(){i=i.upper},SpreadElement(e){"ObjectExpression"===e.parent.type&&(i.prevName=null)},Property(n){if("ObjectPattern"===n.parent.type)return;const c=i.prevName,l=i.numKeys,u=function(e){const t=fr.getStaticPropertyName(e);return null!==t?t:e.key.name||null}(n);null!==u&&(i.prevName=u),null===c||null===u||l"Identifier"===e.id.type)),s=t?e=>e.id.name.toLowerCase():e=>e.id.name,a=o.some((e=>null!==e.init&&"Literal"!==e.init.type));let i=!1;o.slice(1).reduce(((t,r)=>{const c=s(t);return s(r)a||i?null:e.replaceTextRange([o[0].range[0],o[o.length-1].range[1]],o.slice().sort(((e,t)=>s(e)>s(t)?1:-1)).reduce(((e,t,r)=>{const s=r===o.length-1?"":n.getText().slice(o[r].range[1],o[r+1].range[0]);return e+n.getText(t)+s}),""))}),i=!0,t):r}),o[0])}}}};function Yf(e){const t=e.parent;return"BlockStatement"===e.type&&fr.isFunction(t)&&t.body===e}var Hf={meta:{type:"layout",docs:{description:"enforce consistent spacing before blocks",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/space-before-blocks"},fixable:"whitespace",schema:[{oneOf:[{enum:["always","never"]},{type:"object",properties:{keywords:{enum:["always","never","off"]},functions:{enum:["always","never","off"]},classes:{enum:["always","never","off"]}},additionalProperties:!1}]}],messages:{unexpectedSpace:"Unexpected space before opening brace.",missingSpace:"Missing space before opening brace."}},create(e){const t=e.options[0],n=e.getSourceCode();let r=!0,o=!0,s=!0,a=!1,i=!1,c=!1;function l(t){const l=n.getTokenBefore(t);if(l&&!function(e,t){return fr.isArrowToken(e)||fr.isKeywordToken(e)&&!Yf(t)}(l,t)&&fr.isTokenOnSameLine(l,t)){const u=n.isSpaceBetweenTokens(l,t);let p,d;Yf(t)?(p=r,d=a):"ClassBody"===t.type?(p=s,d=c):(p=o,d=i),p&&!u?e.report({node:t,messageId:"missingSpace",fix:e=>e.insertTextBefore(t," ")}):d&&u&&e.report({node:t,messageId:"unexpectedSpace",fix:e=>e.removeRange([l.range[1],t.range[0]])})}}return"object"==typeof t?(r="always"===t.functions,o="always"===t.keywords,s="always"===t.classes,a="never"===t.functions,i="never"===t.keywords,c="never"===t.classes):"never"===t&&(r=!1,o=!1,s=!1,a=!0,i=!0,c=!0),{BlockStatement:l,ClassBody:l,SwitchStatement:function(e){const t=e.cases;let r;r=t.length>0?n.getTokenBefore(t[0]):n.getLastToken(e,1),l(r)}}}},Xf={meta:{type:"layout",docs:{description:"enforce consistent spacing before `function` definition opening parenthesis",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/space-before-function-paren"},fixable:"whitespace",schema:[{oneOf:[{enum:["always","never"]},{type:"object",properties:{anonymous:{enum:["always","never","ignore"]},named:{enum:["always","never","ignore"]},asyncArrow:{enum:["always","never","ignore"]}},additionalProperties:!1}]}],messages:{unexpectedSpace:"Unexpected space before function parentheses.",missingSpace:"Missing space before function parentheses."}},create(e){const t=e.getSourceCode(),n="string"==typeof e.options[0]?e.options[0]:"always",r="object"==typeof e.options[0]?e.options[0]:{};function o(o){const s=function(e){if("ArrowFunctionExpression"===e.type){if(e.async&&fr.isOpeningParenToken(t.getFirstToken(e,{skip:1})))return r.asyncArrow||n}else{if(function(e){if(e.id)return!0;const t=e.parent;return"MethodDefinition"===t.type||"Property"===t.type&&("get"===t.kind||"set"===t.kind||t.method)}(e))return r.named||n;if(!e.generator)return r.anonymous||n}return"ignore"}(o);if("ignore"===s)return;const a=t.getFirstToken(o,fr.isOpeningParenToken),i=t.getTokenBefore(a),c=t.isSpaceBetweenTokens(i,a);c&&"never"===s?e.report({node:o,loc:{start:i.loc.end,end:a.loc.start},messageId:"unexpectedSpace",fix(e){const n=t.getCommentsBefore(a);return n.some((e=>"Line"===e.type))?null:e.replaceTextRange([i.range[1],a.range[0]],n.reduce(((e,n)=>e+t.getText(n)),""))}}):c||"always"!==s||e.report({node:o,loc:a.loc,messageId:"missingSpace",fix:e=>e.insertTextAfter(i," ")})}return{ArrowFunctionExpression:o,FunctionDeclaration:o,FunctionExpression:o}}},Qf={meta:{type:"layout",docs:{description:"enforce consistent spacing inside parentheses",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/space-in-parens"},fixable:"whitespace",schema:[{enum:["always","never"]},{type:"object",properties:{exceptions:{type:"array",items:{enum:["{}","[]","()","empty"]},uniqueItems:!0}},additionalProperties:!1}],messages:{missingOpeningSpace:"There must be a space after this paren.",missingClosingSpace:"There must be a space before this paren.",rejectedOpeningSpace:"There should be no space after this paren.",rejectedClosingSpace:"There should be no space before this paren."}},create(e){const t="always"===e.options[0],n=e.options[1]&&e.options[1].exceptions||[],r={};let o;n.length&&(r.braceException=n.includes("{}"),r.bracketException=n.includes("[]"),r.parenException=n.includes("()"),r.empty=n.includes("empty"));const s=e.getSourceCode();function a(e){return o.openers.includes(e.value)}function i(e){return o.closers.includes(e.value)}return{Program:function(n){o=function(){const e=[],t=[];return r.braceException&&(e.push("{"),t.push("}")),r.bracketException&&(e.push("["),t.push("]")),r.parenException&&(e.push("("),t.push(")")),r.empty&&(e.push(")"),t.push("(")),{openers:e,closers:t}}();const c=s.tokensAndComments;c.forEach(((o,l)=>{const u=c[l-1],p=c[l+1];var d,f,m,g;(fr.isOpeningParenToken(o)||fr.isClosingParenToken(o))&&("("!==o.value||(d=o,f=p,s.isSpaceBetweenTokens(d,f)||!r.empty&&fr.isClosingParenToken(f)||(t?a(f):!a(f)))||e.report({node:n,loc:o.loc,messageId:"missingOpeningSpace",fix:e=>e.insertTextAfter(o," ")}),"("===o.value&&function(e,n){return!!fr.isTokenOnSameLine(e,n)&&"Line"!==n.type&&!!s.isSpaceBetweenTokens(e,n)&&(t?a(n):!a(n))}(o,p)&&e.report({node:n,loc:{start:o.loc.end,end:p.loc.start},messageId:"rejectedOpeningSpace",fix:e=>e.removeRange([o.range[1],p.range[0]])}),")"!==o.value||(m=u,g=o,s.isSpaceBetweenTokens(m,g)||!r.empty&&fr.isOpeningParenToken(m)||(t?i(m):!i(m)))||e.report({node:n,loc:o.loc,messageId:"missingClosingSpace",fix:e=>e.insertTextBefore(o," ")}),")"===o.value&&function(e,n){return!!fr.isTokenOnSameLine(e,n)&&!!s.isSpaceBetweenTokens(e,n)&&(t?i(e):!i(e))}(u,o)&&e.report({node:n,loc:{start:u.loc.end,end:o.loc.start},messageId:"rejectedClosingSpace",fix:e=>e.removeRange([u.range[1],o.range[0]])}))}))}}}},Zf={meta:{type:"layout",docs:{description:"require spacing around infix operators",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/space-infix-ops"},fixable:"whitespace",schema:[{type:"object",properties:{int32Hint:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{missingSpace:"Operator '{{operator}}' must be spaced."}},create(e){const t=!!e.options[0]&&!0===e.options[0].int32Hint,n=e.getSourceCode();function r(e,t,r){const o=n.getFirstTokenBetween(e,t,(e=>e.value===r)),s=n.getTokenBefore(o),a=n.getTokenAfter(o);return n.isSpaceBetweenTokens(s,o)&&n.isSpaceBetweenTokens(o,a)?null:o}function o(t,r){e.report({node:t,loc:r.loc,messageId:"missingSpace",data:{operator:r.value},fix(e){const t=n.getTokenBefore(r),o=n.getTokenAfter(r);let s="";return r.range[0]-t.range[1]==0&&(s=" "),s+=r.value,o.range[0]-r.range[1]==0&&(s+=" "),e.replaceText(r,s)}})}function s(e){const s=r(e.left.typeAnnotation?e.left.typeAnnotation:e.left,e.right,e.operator||"=");s&&(t&&n.getText(e).endsWith("|0")||o(e,s))}return{AssignmentExpression:s,AssignmentPattern:s,BinaryExpression:s,LogicalExpression:s,ConditionalExpression:function(e){const t=r(e.test,e.consequent,"?"),n=r(e.consequent,e.alternate,":");t&&o(e,t),n&&o(e,n)},VariableDeclarator:function(e){const t=e.id.typeAnnotation?e.id.typeAnnotation:e.id,n=e.init;if(n){const s=r(t,n,"=");s&&o(e,s)}}}}},em={meta:{type:"layout",docs:{description:"enforce consistent spacing before or after unary operators",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/space-unary-ops"},fixable:"whitespace",schema:[{type:"object",properties:{words:{type:"boolean",default:!0},nonwords:{type:"boolean",default:!1},overrides:{type:"object",additionalProperties:{type:"boolean"}}},additionalProperties:!1}],messages:{unexpectedBefore:"Unexpected space before unary operator '{{operator}}'.",unexpectedAfter:"Unexpected space after unary operator '{{operator}}'.",unexpectedAfterWord:"Unexpected space after unary word operator '{{word}}'.",wordOperator:"Unary word operator '{{word}}' must be followed by whitespace.",operator:"Unary operator '{{operator}}' must be followed by whitespace.",beforeUnaryExpressions:"Space is required before unary expressions '{{token}}'."}},create(e){const t=e.options[0]||{words:!0,nonwords:!1},n=e.getSourceCode();function r(e){return t.overrides&&Object.prototype.hasOwnProperty.call(t.overrides,e)}function o(e){return t.overrides[e]}function s(t,n,r,o){r.range[0]===n.range[1]&&e.report({node:t,messageId:"wordOperator",data:{word:o},fix:e=>e.insertTextAfter(n," ")})}function a(t,n,r,o){fr.canTokensBeAdjacent(n,r)&&r.range[0]>n.range[1]&&e.report({node:t,messageId:"unexpectedAfterWord",data:{word:o},fix:e=>e.removeRange([n.range[1],r.range[0]])})}function i(e,n,i,c){r(c)?o(c)?s(e,n,i,c):a(e,n,i,c):t.words?s(e,n,i,c):a(e,n,i,c)}function c(t,n,r){if(t.prefix){if(function(e){return e&&"UnaryExpression"===e.type&&"!"===e.argument.operator&&e.argument&&"UnaryExpression"===e.argument.type&&"!"===e.argument.operator}(t))return;n.range[1]===r.range[0]&&e.report({node:t,messageId:"operator",data:{operator:n.value},fix:e=>e.insertTextAfter(n," ")})}else n.range[1]===r.range[0]&&e.report({node:t,messageId:"beforeUnaryExpressions",data:{token:r.value},fix:e=>e.insertTextBefore(r," ")})}function l(t,n,r){t.prefix?r.range[0]>n.range[1]&&e.report({node:t,messageId:"unexpectedAfter",data:{operator:n.value},fix:e=>fr.canTokensBeAdjacent(n,r)?e.removeRange([n.range[1],r.range[0]]):null}):r.range[0]>n.range[1]&&e.report({node:t,messageId:"unexpectedBefore",data:{operator:r.value},fix:e=>e.removeRange([n.range[1],r.range[0]])})}function u(e){const s="UpdateExpression"!==e.type||e.prefix?n.getFirstTokens(e,2):n.getLastTokens(e,2),a=s[0],u=s[1];if(("NewExpression"===e.type||e.prefix)&&"Keyword"===a.type)return void i(e,a,u,a.value);const p=e.prefix?s[0].value:s[1].value;r(p)?o(p)?c(e,a,u):l(e,a,u):t.nonwords?c(e,a,u):l(e,a,u)}return{UnaryExpression:u,UpdateExpression:u,NewExpression:u,YieldExpression:function(e){const t=n.getFirstTokens(e,3);e.argument&&!e.delegate&&i(e,t[0],t[1],"yield")},AwaitExpression:function(e){const t=n.getFirstTokens(e,3);i(e,t[0],t[1],"await")}}}};function tm(e){return`(?:${F.default.escapeRegExp(e)})`}function nm(e){return`${tm(e)}+`}function rm(e){let t="";return 0===e.length?t+="\\s":(t+="(?:\\s|",1===e.length?t+=nm(e[0]):(t+="(?:",t+=e.map(nm).join("|"),t+=")"),t+=`(?:$|[${Array.from(fr.LINEBREAKS).join("")}]))`),t}function om(e,t){let n="^";return 1===e.length?n+=tm(e[0]):(n+="(?:",n+=e.map(tm).join("|"),n+=")"),n+="?",n+=rm(t),new RegExp(n,"u")}function sm(e){const t=`^(${e.map(tm).join("|")})?[ \t]+`;return new RegExp(t,"u")}var am={meta:{type:"suggestion",docs:{description:"enforce consistent spacing after the `//` or `/*` in a comment",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/spaced-comment"},fixable:"whitespace",schema:[{enum:["always","never"]},{type:"object",properties:{exceptions:{type:"array",items:{type:"string"}},markers:{type:"array",items:{type:"string"}},line:{type:"object",properties:{exceptions:{type:"array",items:{type:"string"}},markers:{type:"array",items:{type:"string"}}},additionalProperties:!1},block:{type:"object",properties:{exceptions:{type:"array",items:{type:"string"}},markers:{type:"array",items:{type:"string"}},balanced:{type:"boolean",default:!1}},additionalProperties:!1}},additionalProperties:!1}],messages:{unexpectedSpaceAfterMarker:"Unexpected space or tab after marker ({{refChar}}) in comment.",expectedExceptionAfter:"Expected exception block, space or tab after '{{refChar}}' in comment.",unexpectedSpaceBefore:"Unexpected space or tab before '*/' in comment.",unexpectedSpaceAfter:"Unexpected space or tab after '{{refChar}}' in comment.",expectedSpaceBefore:"Expected space or tab before '*/' in comment.",expectedSpaceAfter:"Expected space or tab after '{{refChar}}' in comment."}},create(e){const t=e.getSourceCode(),n="never"!==e.options[0],r=e.options[1]||{},o=r.block&&r.block.balanced,s=["block","line"].reduce(((e,t)=>{const s=function(e){return-1===e.indexOf("*")?e.concat("*"):e}(r[t]&&r[t].markers||r.markers||[]),a=r[t]&&r[t].exceptions||r.exceptions||[];return e[t]={beginRegex:n?om(s,a):sm(s),endRegex:o&&n?new RegExp(`${rm(a)}$`,"u"):new RegExp("[ \t]+$","u"),hasExceptions:a.length>0,captureMarker:new RegExp(`^(${s.map(tm).join("|")})`,"u"),markers:new Set(s)},e}),{});function a(t,r,o,s){const a="block"===t.type.toLowerCase()?"/*":"//";e.report({node:t,fix(e){const r=t.range[0];let s=r+2;return n?(o&&(s+=o[0].length),e.insertTextAfterRange([r,s]," ")):(s+=o[0].length,e.replaceTextRange([r,s],a+(o[1]?o[1]:"")))},messageId:r,data:{refChar:s}})}function i(t,r,o){e.report({node:t,fix(e){if(n)return e.insertTextAfterRange([t.range[0],t.range[1]-2]," ");const r=t.range[1]-2,s=r-o[0].length;return e.replaceTextRange([s,r],"")},messageId:r})}function c(e){const t=e.type.toLowerCase(),r=s[t],c="block"===t?"/*":"//";if(0===e.value.length||r.markers.has(e.value))return;const l=r.beginRegex.exec(e.value),u=r.endRegex.exec(e.value);if(n){if(!l){const t=r.captureMarker.exec(e.value),n=t?c+t[0]:c;r.hasExceptions?a(e,"expectedExceptionAfter",t,n):a(e,"expectedSpaceAfter",t,n)}o&&"block"===t&&!u&&i(e,"expectedSpaceBefore")}else l&&(l[1]?a(e,"unexpectedSpaceAfterMarker",l,l[1]):a(e,"unexpectedSpaceAfter",l,c)),o&&"block"===t&&u&&i(e,"unexpectedSpaceBefore",u)}return{Program(){t.getAllComments().filter((e=>"Shebang"!==e.type)).forEach(c)}}}};function im(e){const t=[];for(let n=0;nt.remove(e)}function i(t,n,r,o,s){t.slice(n,r).forEach((t=>{e.report({node:t,messageId:o,fix:s?a(t):null})}))}function c(e,t,n){i(e,0,e.length,t,n)}function l(e,t,n){i(e,1,e.length,t,n)}function u(){n.pop()}function p(t){const i="BlockStatement"===t.body.type?im(t.body.body):[];"function"===o?function(t,o){const s=r.length>0,i=0===n.length&&0===r.length,c=n.length>0&&n[n.length-1],u=o.length>0;u?(lm(t.params)?c?e.report({node:o[0],messageId:"unnecessary",fix:a(o[0])}):s&&e.report({node:o[0],messageId:"unnecessaryInClasses",fix:a(o[0])}):e.report({node:o[0],messageId:"nonSimpleParameterList"}),l(o,"multiple",!0)):i&&(lm(t.params)?e.report({node:t,messageId:"function"}):e.report({node:t,messageId:"wrap",data:{name:fr.getFunctionNameWithKind(t)}})),n.push(c||u)}(t,i):i.length>0&&(lm(t.params)?c(i,o,s(o)):(e.report({node:i[0],messageId:"nonSimpleParameterList"}),l(i,"multiple",!0)))}t.impliedStrict?o="implied":"safe"===o&&(o=t.globalReturn?"global":"function");const d={Program(t){const n=im(t.body);"module"===t.sourceType&&(o="module"),"global"===o?(t.body.length>0&&0===n.length&&e.report({node:t,messageId:"global"}),l(n,"multiple",!0)):c(n,o,s(o))},FunctionDeclaration:p,FunctionExpression:p,ArrowFunctionExpression:p};return"function"===o&&Object.assign(d,{ClassBody(){r.push(!0)},"ClassBody:exit"(){r.pop()},"FunctionDeclaration:exit":u,"FunctionExpression:exit":u,"ArrowFunctionExpression:exit":u}),d}},pm={meta:{type:"layout",docs:{description:"enforce spacing around colons of switch statements",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/switch-colon-spacing"},schema:[{type:"object",properties:{before:{type:"boolean",default:!1},after:{type:"boolean",default:!0}},additionalProperties:!1}],fixable:"whitespace",messages:{expectedBefore:"Expected space(s) before this colon.",expectedAfter:"Expected space(s) after this colon.",unexpectedBefore:"Unexpected space(s) before this colon.",unexpectedAfter:"Unexpected space(s) after this colon."}},create(e){const t=e.getSourceCode(),n=e.options[0]||{},r=!0===n.before,o=!1!==n.after;function s(e,n,r){return fr.isClosingBraceToken(n)||!fr.isTokenOnSameLine(e,n)||t.isSpaceBetweenTokens(e,n)===r}function a(e,n,r,o){return function(e,n){return null!==t.getFirstTokenBetween(e,n,{includeComments:!0,filter:fr.isCommentToken})}(n,r)?null:o?e.insertTextAfter(n," "):e.removeRange([n.range[1],r.range[0]])}return{SwitchCase(n){const i=function(e){return e.test?t.getTokenAfter(e.test,fr.isColonToken):t.getFirstToken(e,1)}(n),c=t.getTokenBefore(i),l=t.getTokenAfter(i);s(c,i,r)||e.report({node:n,loc:i.loc,messageId:r?"expectedBefore":"unexpectedBefore",fix:e=>a(e,c,i,r)}),s(i,l,o)||e.report({node:n,loc:i.loc,messageId:o?"expectedAfter":"unexpectedAfter",fix:e=>a(e,i,l,o)})}}}},dm={meta:{type:"suggestion",docs:{description:"require symbol descriptions",category:"ECMAScript 6",recommended:!1,url:"https://eslint.org/docs/rules/symbol-description"},fixable:null,schema:[],messages:{expected:"Expected Symbol to have a description."}},create:e=>({"Program:exit"(){const t=e.getScope(),n=fr.getVariableByName(t,"Symbol");n&&0===n.defs.length&&n.references.forEach((t=>{const n=t.identifier;fr.isCallee(n)&&function(t){0===t.arguments.length&&e.report({node:t,messageId:"expected"})}(n.parent)}))}})},fm={meta:{type:"layout",docs:{description:"require or disallow spacing around embedded expressions of template strings",category:"ECMAScript 6",recommended:!1,url:"https://eslint.org/docs/rules/template-curly-spacing"},fixable:"whitespace",schema:[{enum:["always","never"]}],messages:{expectedBefore:"Expected space(s) before '}'.",expectedAfter:"Expected space(s) after '${'.",unexpectedBefore:"Unexpected space(s) before '}'.",unexpectedAfter:"Unexpected space(s) after '${'."}},create(e){const t=e.getSourceCode(),n="always"===e.options[0];return{TemplateElement(r){const o=t.getFirstToken(r);!function(r){if(!r.value.startsWith("}"))return;const o=t.getTokenBefore(r,{includeComments:!0}),s=t.isSpaceBetween(o,r);fr.isTokenOnSameLine(o,r)&&(n&&!s&&e.report({loc:{start:r.loc.start,end:{line:r.loc.start.line,column:r.loc.start.column+1}},messageId:"expectedBefore",fix:e=>e.insertTextBefore(r," ")}),!n&&s&&e.report({loc:{start:o.loc.end,end:r.loc.start},messageId:"unexpectedBefore",fix:e=>e.removeRange([o.range[1],r.range[0]])}))}(o),function(r){if(!r.value.endsWith("${"))return;const o=t.getTokenAfter(r,{includeComments:!0}),s=t.isSpaceBetween(r,o);fr.isTokenOnSameLine(r,o)&&(n&&!s&&e.report({loc:{start:{line:r.loc.end.line,column:r.loc.end.column-2},end:r.loc.end},messageId:"expectedAfter",fix:e=>e.insertTextAfter(r," ")}),!n&&s&&e.report({loc:{start:r.loc.end,end:o.loc.start},messageId:"unexpectedAfter",fix:e=>e.removeRange([r.range[1],o.range[0]])}))}(o)}}}},mm={meta:{type:"layout",docs:{description:"require or disallow spacing between template tags and their literals",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/template-tag-spacing"},fixable:"whitespace",schema:[{enum:["always","never"]}],messages:{unexpected:"Unexpected space between template tag and template literal.",missing:"Missing space between template tag and template literal."}},create(e){const t="always"!==e.options[0],n=e.getSourceCode();return{TaggedTemplateExpression:function(r){const o=n.getTokenBefore(r.quasi),s=n.getFirstToken(r.quasi),a=n.isSpaceBetweenTokens(o,s);t&&a?e.report({node:r,loc:{start:o.loc.end,end:s.loc.start},messageId:"unexpected",fix(e){const t=n.getCommentsBefore(r.quasi);return t.some((e=>"Line"===e.type))?null:e.replaceTextRange([o.range[1],s.range[0]],t.reduce(((e,t)=>e+n.getText(t)),""))}}):t||a||e.report({node:r,loc:{start:r.loc.start,end:s.loc.start},messageId:"missing",fix:e=>e.insertTextAfter(o," ")})}}}},gm={meta:{type:"layout",docs:{description:"require or disallow Unicode byte order mark (BOM)",category:"Stylistic Issues",recommended:!1,url:"https://eslint.org/docs/rules/unicode-bom"},fixable:"whitespace",schema:[{enum:["always","never"]}],messages:{expected:"Expected Unicode BOM (Byte Order Mark).",unexpected:"Unexpected Unicode BOM (Byte Order Mark)."}},create:e=>({Program:function(t){const n=e.getSourceCode(),r={column:0,line:1},o=e.options[0]||"never";n.hasBOM||"always"!==o?n.hasBOM&&"never"===o&&e.report({node:t,loc:r,messageId:"unexpected",fix:e=>e.removeRange([-1,0])}):e.report({node:t,loc:r,messageId:"expected",fix:e=>e.insertTextBeforeRange([0,1],"\ufeff")})}})};function hm(e){return Boolean(e)&&"Identifier"===e.type&&"NaN"===e.name}var ym={meta:{type:"problem",docs:{description:"require calls to `isNaN()` when checking for `NaN`",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/use-isnan"},schema:[{type:"object",properties:{enforceForSwitchCase:{type:"boolean",default:!0},enforceForIndexOf:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{comparisonWithNaN:"Use the isNaN function to compare with NaN.",switchNaN:"'switch(NaN)' can never match a case clause. Use Number.isNaN instead of the switch.",caseNaN:"'case NaN' can never match. Use Number.isNaN before the switch.",indexOfNaN:"Array prototype method '{{ methodName }}' cannot find NaN."}},create(e){const t=!e.options[0]||e.options[0].enforceForSwitchCase,n=e.options[0]&&e.options[0].enforceForIndexOf;const r={BinaryExpression:function(t){/^(?:[<>]|[!=]=)=?$/u.test(t.operator)&&(hm(t.left)||hm(t.right))&&e.report({node:t,messageId:"comparisonWithNaN"})}};return t&&(r.SwitchStatement=function(t){hm(t.discriminant)&&e.report({node:t,messageId:"switchNaN"});for(const n of t.cases)hm(n.test)&&e.report({node:n,messageId:"caseNaN"})}),n&&(r.CallExpression=function(t){const n=fr.skipChainExpression(t.callee);if("MemberExpression"===n.type){const r=fr.getStaticPropertyName(n);"indexOf"!==r&&"lastIndexOf"!==r||1!==t.arguments.length||!hm(t.arguments[0])||e.report({node:t,messageId:"indexOfNaN",data:{methodName:r}})}}),r}},xm={meta:{type:"suggestion",docs:{description:"enforce valid JSDoc comments",category:"Possible Errors",recommended:!1,url:"https://eslint.org/docs/rules/valid-jsdoc"},schema:[{type:"object",properties:{prefer:{type:"object",additionalProperties:{type:"string"}},preferType:{type:"object",additionalProperties:{type:"string"}},requireReturn:{type:"boolean",default:!0},requireParamDescription:{type:"boolean",default:!0},requireReturnDescription:{type:"boolean",default:!0},matchDescription:{type:"string"},requireReturnType:{type:"boolean",default:!0},requireParamType:{type:"boolean",default:!0}},additionalProperties:!1}],fixable:"code",messages:{unexpectedTag:"Unexpected @{{title}} tag; function has no return statement.",expected:"Expected JSDoc for '{{name}}' but found '{{jsdocName}}'.",use:"Use @{{name}} instead.",useType:"Use '{{expectedTypeName}}' instead of '{{currentTypeName}}'.",syntaxError:"JSDoc syntax error.",missingBrace:"JSDoc type missing brace.",missingParamDesc:"Missing JSDoc parameter description for '{{name}}'.",missingParamType:"Missing JSDoc parameter type for '{{name}}'.",missingReturnType:"Missing JSDoc return type.",missingReturnDesc:"Missing JSDoc return description.",missingReturn:"Missing JSDoc @{{returns}} for function.",missingParam:"Missing JSDoc for parameter '{{name}}'.",duplicateParam:"Duplicate JSDoc parameter '{{name}}'.",unsatisfiedDesc:"JSDoc description does not satisfy the regex pattern."},deprecated:!0,replacedBy:[]},create(e){const t=e.options[0]||{},n=t.prefer||{},r=e.getSourceCode(),o=!1!==t.requireReturn,s=!1!==t.requireParamDescription,a=!1!==t.requireReturnDescription,i=!1!==t.requireReturnType,c=!1!==t.requireParamType,l=t.preferType||{},u=0!==Object.keys(l).length,p=[];function d(e){return"ClassExpression"===e.type||"ClassDeclaration"===e.type}function f(e){p.push({returnPresent:"ArrowFunctionExpression"===e.type&&"BlockStatement"!==e.body.type||d(e)||e.async})}function m(e){return null===e.type||"void"===e.type.name||"UndefinedLiteral"===e.type.type}function g(e){let t;return e.name?t=e:e.expression&&(t=e.expression),{currentType:t,expectedTypeName:t&&l[t.name]}}function h(e,t){return{start:r.getLocFromIndex(e.range[0]+2+t.range[0]),end:r.getLocFromIndex(e.range[0]+2+t.range[1])}}function y(t,n){if(!n||!function(e){return"UndefinedLiteral"!==e&&"NullLiteral"!==e&&"NullableLiteral"!==e&&"FunctionType"!==e&&"AllLiteral"!==e}(n.type))return;const r=[];let o=[];switch(n.type){case"TypeApplication":o="UnionType"===n.applications[0].type?n.applications[0].elements:n.applications,r.push(g(n));break;case"RecordType":o=n.fields;break;case"UnionType":case"ArrayType":o=n.elements;break;case"FieldType":n.value&&r.push(g(n.value));break;default:r.push(g(n))}o.forEach(y.bind(null,t)),r.forEach((n=>{n.expectedTypeName&&n.expectedTypeName!==n.currentType.name&&e.report({node:t,messageId:"useType",loc:h(t,n.currentType),data:{currentTypeName:n.currentType.name,expectedTypeName:n.expectedTypeName},fix:e=>e.replaceTextRange(n.currentType.range.map((e=>t.range[0]+2+e)),n.expectedTypeName)})}))}function x(l){const f=r.getJSDocComment(l),g=p.pop(),x=Object.create(null),b=[];let E,S=!1,C=!1,v=!1,A=!1,k=!1;if(f){let r;try{r=ee.default.parse(f.value,{strict:!0,unwrap:!0,sloppy:!0,range:!0})}catch(t){return void(/braces/iu.test(t.message)?e.report({node:f,messageId:"missingBrace"}):e.report({node:f,messageId:"syntaxError"}))}r.tags.forEach((t=>{switch(t.title.toLowerCase()){case"param":case"arg":case"argument":b.push(t);break;case"return":case"returns":S=!0,E=t;break;case"constructor":case"class":C=!0;break;case"override":case"inheritdoc":A=!0;break;case"abstract":case"virtual":k=!0;break;case"interface":v=!0}if(Object.prototype.hasOwnProperty.call(n,t.title)&&t.title!==n[t.title]){const r=h(f,t);e.report({node:f,messageId:"use",loc:{start:r.start,end:{line:r.start.line,column:r.start.column+`@${t.title}`.length}},data:{name:n[t.title]},fix:e=>e.replaceTextRange([f.range[0]+t.range[0]+3,f.range[0]+t.range[0]+t.title.length+3],n[t.title])})}u&&t.type&&y(f,t.type)})),b.forEach((t=>{c&&!t.type&&e.report({node:f,messageId:"missingParamType",loc:h(f,t),data:{name:t.name}}),!t.description&&s&&e.report({node:f,messageId:"missingParamDesc",loc:h(f,t),data:{name:t.name}}),x[t.name]?e.report({node:f,messageId:"duplicateParam",loc:h(f,t),data:{name:t.name}}):-1===t.name.indexOf(".")&&(x[t.name]=t)})),S&&(o||g.returnPresent||null!==E.type&&m(E)||k?(i&&!E.type&&e.report({node:f,messageId:"missingReturnType"}),m(E)||E.description||!a||e.report({node:f,messageId:"missingReturnDesc"})):e.report({node:f,messageId:"unexpectedTag",loc:h(f,E),data:{title:E.title}})),A||S||C||v||"get"===l.parent.kind||"constructor"===l.parent.kind||"set"===l.parent.kind||d(l)||(o||g.returnPresent&&!l.async)&&e.report({node:f,messageId:"missingReturn",data:{returns:n.returns||"returns"}});const p=Object.keys(x);if(l.params&&l.params.forEach(((t,n)=>{const r="AssignmentPattern"===t.type?t.left:t;if("Identifier"===r.type){const t=r.name;p[n]&&t!==p[n]?e.report({node:f,messageId:"expected",loc:h(f,x[p[n]]),data:{name:t,jsdocName:p[n]}}):x[t]||A||e.report({node:f,messageId:"missingParam",data:{name:t}})}})),t.matchDescription){new RegExp(t.matchDescription,"u").test(r.description)||e.report({node:f,messageId:"unsatisfiedDesc"})}}}return{ArrowFunctionExpression:f,FunctionExpression:f,FunctionDeclaration:f,ClassExpression:f,ClassDeclaration:f,"ArrowFunctionExpression:exit":x,"FunctionExpression:exit":x,"FunctionDeclaration:exit":x,"ClassExpression:exit":x,"ClassDeclaration:exit":x,ReturnStatement:function(e){const t=p[p.length-1];t&&null!==e.argument&&(t.returnPresent=!0)}}}},bm={meta:{type:"problem",docs:{description:"enforce comparing `typeof` expressions against valid strings",category:"Possible Errors",recommended:!0,url:"https://eslint.org/docs/rules/valid-typeof"},schema:[{type:"object",properties:{requireStringLiterals:{type:"boolean",default:!1}},additionalProperties:!1}],messages:{invalidValue:"Invalid typeof comparison value.",notString:"Typeof comparisons should be to string literals."}},create(e){const t=["symbol","undefined","object","boolean","number","string","function","bigint"],n=["==","===","!=","!=="],r=e.options[0]&&e.options[0].requireStringLiterals;function o(e){return"UnaryExpression"===e.type&&"typeof"===e.operator}return{UnaryExpression(s){if(o(s)){const a=e.getAncestors().pop();if("BinaryExpression"===a.type&&-1!==n.indexOf(a.operator)){const n=a.left===s?a.right:a.left;if("Literal"===n.type||"TemplateLiteral"===n.type&&!n.expressions.length){const r="Literal"===n.type?n.value:n.quasis[0].value.cooked;-1===t.indexOf(r)&&e.report({node:n,messageId:"invalidValue"})}else r&&!o(n)&&e.report({node:n,messageId:"notString"})}}}}}},Em={meta:{type:"suggestion",docs:{description:"require `var` declarations be placed at the top of their containing scope",category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/vars-on-top"},schema:[],messages:{top:"All 'var' declarations must be at the top of the function scope."}},create(e){function t(e){return"ExpressionStatement"===e.type&&"Literal"===e.expression.type&&"string"==typeof e.expression.value}function n(e){return"ImportDeclaration"===e.type||"ImportSpecifier"===e.type||"ImportDefaultSpecifier"===e.type||"ImportNamespaceSpecifier"===e.type}function r(e){return"VariableDeclaration"===e.type||"ExportNamedDeclaration"===e.type&&e.declaration&&"VariableDeclaration"===e.declaration.type}function o(e,o){const s=o.length;let a=0;for(;ae.replaceText(n,`(${t.getText(n)})`)})}}}}},vm={meta:{type:"layout",docs:{description:"require or disallow spacing around the `*` in `yield*` expressions",category:"ECMAScript 6",recommended:!1,url:"https://eslint.org/docs/rules/yield-star-spacing"},fixable:"whitespace",schema:[{oneOf:[{enum:["before","after","both","neither"]},{type:"object",properties:{before:{type:"boolean"},after:{type:"boolean"}},additionalProperties:!1}]}],messages:{missingBefore:"Missing space before *.",missingAfter:"Missing space after *.",unexpectedBefore:"Unexpected space before *.",unexpectedAfter:"Unexpected space after *."}},create(e){const t=e.getSourceCode(),n=(r=e.options[0])&&"string"!=typeof r?r:{before:{before:!0,after:!1},after:{before:!1,after:!0},both:{before:!0,after:!0},neither:{before:!1,after:!1}}[r||"after"];var r;function o(r,o,s){if(t.isSpaceBetweenTokens(o,s)!==n[r]){const t="*"===o.value,a=n[r],i=t?o:s;let c="";c=a?"before"===r?"missingBefore":"missingAfter":"before"===r?"unexpectedBefore":"unexpectedAfter",e.report({node:i,messageId:c,fix:e=>a?t?e.insertTextAfter(i," "):e.insertTextBefore(i," "):e.removeRange([o.range[1],s.range[0]])})}}return{YieldExpression:function(e){if(!e.delegate)return;const n=t.getFirstTokens(e,3),r=n[0],s=n[1],a=n[2];o("before",r,s),o("after",s,a)}}}};function Am(e){return["<","<="].indexOf(e)>=0}function km(e){return"UnaryExpression"===e.type&&"-"===e.operator&&e.prefix&&fr.isNumericLiteral(e.argument)}function wm(e){return"TemplateLiteral"===e.type&&0===e.expressions.length}function Pm(e){return km(e)||wm(e)}function Tm(e){return"Literal"===e.type?e:km(e)?{type:"Literal",value:-e.argument.value,raw:`-${e.argument.value}`}:wm(e)?{type:"Literal",value:e.quasis[0].value.cooked,raw:e.quasis[0].value.raw}:null}var Im={meta:{type:"suggestion",docs:{description:'require or disallow "Yoda" conditions',category:"Best Practices",recommended:!1,url:"https://eslint.org/docs/rules/yoda"},schema:[{enum:["always","never"]},{type:"object",properties:{exceptRange:{type:"boolean",default:!1},onlyEquality:{type:"boolean",default:!1}},additionalProperties:!1}],fixable:"code",messages:{expected:"Expected literal to be on the {{expectedSide}} side of {{operator}}."}},create(e){const t="always"===e.options[0],n=e.options[1]&&e.options[1].exceptRange,r=e.options[1]&&e.options[1].onlyEquality,o=e.getSourceCode();const s={"===":"===","!==":"!==","==":"==","!=":"!=","<":">",">":"<","<=":">=",">=":"<="};return{BinaryExpression(a){const i=t?a.left:a.right,c=t?a.right:a.left;var l;"Literal"!==c.type&&!Pm(c)||"Literal"===i.type||Pm(i)||(l=a.operator,!/^(==|===)$/u.test(l)&&r)||!function(e){return/^(==|===|!=|!==|<|>|<=|>=)$/u.test(e)}(a.operator)||n&&function(e){const t=e.left,n=e.right;return"LogicalExpression"===e.type&&"BinaryExpression"===t.type&&"BinaryExpression"===n.type&&Am(t.operator)&&Am(n.operator)&&(function(){if("&&"===e.operator&&fr.isSameReference(t.right,n.left)){const e=Tm(t.left),r=Tm(n.right);if(null===e&&null===r)return!1;if(null===r||null===e)return!0;if(e.value<=r.value)return!0}return!1}()||function(){if("||"===e.operator&&fr.isSameReference(t.left,n.right)){const e=Tm(t.right),r=Tm(n.left);if(null===e&&null===r)return!1;if(null===r||null===e)return!0;if(e.value<=r.value)return!0}return!1}())&&fr.isParenthesised(o,e)}(e.getAncestors().pop())||e.report({node:a,messageId:"expected",data:{operator:a.operator,expectedSide:t?"left":"right"},fix:e=>e.replaceText(a,function(e){const t=o.getFirstTokenBetween(e.left,e.right,(t=>t.value===e.operator)),n=o.getTokenBefore(t),r=o.getTokenAfter(t),a=o.getText(),i=a.slice(e.range[0],n.range[1]),c=a.slice(n.range[1],t.range[0]),l=a.slice(t.range[1],r.range[0]),u=a.slice(r.range[0],e.range[1]),p=o.getTokenBefore(e),d=o.getTokenAfter(e);let f="",m="";return p&&p.range[1]===e.range[0]&&!fr.canTokensBeAdjacent(p,r)&&(f=" "),d&&e.range[1]===d.range[0]&&!fr.canTokensBeAdjacent(n,d)&&(m=" "),f+u+c+s[t.value]+l+i+m}(a))})}}}};const{LazyLoadingRuleMap:Fm}=dr;var Dm=new Fm(Object.entries({"accessor-pairs":()=>hr,"array-bracket-newline":()=>yr,"array-bracket-spacing":()=>xr,"array-callback-return":()=>Ar,"array-element-newline":()=>kr,"arrow-body-style":()=>wr,"arrow-parens":()=>Pr,"arrow-spacing":()=>Tr,"block-scoped-var":()=>Ir,"block-spacing":()=>Fr,"brace-style":()=>Dr,"callback-return":()=>Or,camelcase:()=>Br,"capitalized-comments":()=>qr,"class-methods-use-this":()=>Ur,"comma-dangle":()=>Wr,"comma-spacing":()=>Gr,"comma-style":()=>zr,complexity:()=>Jr,"computed-property-spacing":()=>Kr,"consistent-return":()=>Hr,"consistent-this":()=>Xr,"constructor-super":()=>eo,curly:()=>to,"default-case":()=>ro,"default-case-last":()=>oo,"default-param-last":()=>so,"dot-location":()=>ao,"dot-notation":()=>uo,"eol-last":()=>po,eqeqeq:()=>fo,"for-direction":()=>mo,"func-call-spacing":()=>go,"func-name-matching":()=>xo,"func-names":()=>bo,"func-style":()=>Eo,"function-call-argument-newline":()=>So,"function-paren-newline":()=>Co,"generator-star-spacing":()=>Ao,"getter-return":()=>Po,"global-require":()=>Io,"grouped-accessor-pairs":()=>Do,"guard-for-in":()=>Oo,"handle-callback-err":()=>Bo,"id-blacklist":()=>No,"id-denylist":()=>jo,"id-length":()=>Lo,"id-match":()=>Ro,"implicit-arrow-linebreak":()=>$o,indent:()=>zo,"indent-legacy":()=>Jo,"init-declarations":()=>Ho,"jsx-quotes":()=>Qo,"key-spacing":()=>ns,"keyword-spacing":()=>fs,"line-comment-position":()=>ms,"linebreak-style":()=>gs,"lines-around-comment":()=>hs,"lines-around-directive":()=>ys,"lines-between-class-members":()=>xs,"max-classes-per-file":()=>bs,"max-depth":()=>Es,"max-len":()=>vs,"max-lines":()=>As,"max-lines-per-function":()=>ks,"max-nested-callbacks":()=>ws,"max-params":()=>Ps,"max-statements":()=>Ts,"max-statements-per-line":()=>Is,"multiline-comment-style":()=>Fs,"multiline-ternary":()=>Ds,"new-cap":()=>js,"new-parens":()=>Ls,"newline-after-var":()=>Rs,"newline-before-return":()=>Ms,"newline-per-chained-call":()=>_s,"no-alert":()=>Gs,"no-array-constructor":()=>zs,"no-async-promise-executor":()=>Js,"no-await-in-loop":()=>Hs,"no-bitwise":()=>Qs,"no-buffer-constructor":()=>Zs,"no-caller":()=>ea,"no-case-declarations":()=>ta,"no-catch-shadow":()=>na,"no-class-assign":()=>ra,"no-compare-neg-zero":()=>oa,"no-cond-assign":()=>ia,"no-confusing-arrow":()=>ca,"no-console":()=>la,"no-const-assign":()=>ua,"no-constant-condition":()=>pa,"no-constructor-return":()=>da,"no-continue":()=>fa,"no-control-regex":()=>ha,"no-debugger":()=>ya,"no-delete-var":()=>xa,"no-div-regex":()=>ba,"no-dupe-args":()=>Ea,"no-dupe-class-members":()=>Sa,"no-dupe-else-if":()=>wa,"no-dupe-keys":()=>Fa,"no-duplicate-case":()=>Da,"no-duplicate-imports":()=>La,"no-else-return":()=>Ma,"no-empty":()=>_a,"no-empty-character-class":()=>qa,"no-empty-function":()=>Ua,"no-empty-pattern":()=>Va,"no-eq-null":()=>Wa,"no-eval":()=>Ja,"no-ex-assign":()=>Ka,"no-extend-native":()=>Ya,"no-extra-bind":()=>Xa,"no-extra-boolean-cast":()=>Za,"no-extra-label":()=>ei,"no-extra-parens":()=>ni,"no-extra-semi":()=>ri,"no-fallthrough":()=>ai,"no-floating-decimal":()=>ii,"no-func-assign":()=>ci,"no-global-assign":()=>li,"no-implicit-coercion":()=>mi,"no-implicit-globals":()=>gi,"no-implied-eval":()=>yi,"no-import-assign":()=>vi,"no-inline-comments":()=>Ai,"no-inner-declarations":()=>Pi,"no-invalid-regexp":()=>Fi,"no-invalid-this":()=>Di,"no-irregular-whitespace":()=>Li,"no-iterator":()=>Mi,"no-label-var":()=>_i,"no-labels":()=>$i,"no-lone-blocks":()=>qi,"no-lonely-if":()=>Ui,"no-loop-func":()=>Gi,"no-loss-of-precision":()=>zi,"no-magic-numbers":()=>Ki,"no-misleading-character-class":()=>cc,"no-mixed-operators":()=>xc,"no-mixed-requires":()=>bc,"no-mixed-spaces-and-tabs":()=>Ec,"no-multi-assign":()=>Sc,"no-multi-spaces":()=>Cc,"no-multi-str":()=>vc,"no-multiple-empty-lines":()=>Ac,"no-native-reassign":()=>kc,"no-negated-condition":()=>wc,"no-negated-in-lhs":()=>Pc,"no-nested-ternary":()=>Tc,"no-new":()=>Ic,"no-new-func":()=>Fc,"no-new-object":()=>Dc,"no-new-require":()=>Oc,"no-new-symbol":()=>Bc,"no-new-wrappers":()=>Nc,"no-nonoctal-decimal-escape":()=>Rc,"no-obj-calls":()=>Wc,"no-octal":()=>Gc,"no-octal-escape":()=>zc,"no-param-reassign":()=>Kc,"no-path-concat":()=>Yc,"no-plusplus":()=>Xc,"no-process-env":()=>Qc,"no-process-exit":()=>Zc,"no-promise-executor-return":()=>rl,"no-proto":()=>sl,"no-prototype-builtins":()=>al,"no-redeclare":()=>il,"no-regex-spaces":()=>pl,"no-restricted-exports":()=>dl,"no-restricted-globals":()=>fl,"no-restricted-imports":()=>gl,"no-restricted-modules":()=>yl,"no-restricted-properties":()=>xl,"no-restricted-syntax":()=>bl,"no-return-assign":()=>Sl,"no-return-await":()=>Cl,"no-script-url":()=>vl,"no-self-assign":()=>wl,"no-self-compare":()=>Pl,"no-sequences":()=>Il,"no-setter-return":()=>Bl,"no-shadow":()=>Nl,"no-shadow-restricted-names":()=>Ll,"no-spaced-func":()=>Rl,"no-sparse-arrays":()=>Ml,"no-sync":()=>_l,"no-tabs":()=>Ul,"no-template-curly-in-string":()=>Vl,"no-ternary":()=>Wl,"no-this-before-super":()=>Gl,"no-throw-literal":()=>zl,"no-trailing-spaces":()=>Jl,"no-undef":()=>Kl,"no-undef-init":()=>Yl,"no-undefined":()=>Hl,"no-underscore-dangle":()=>Xl,"no-unexpected-multiline":()=>Ql,"no-unmodified-loop-condition":()=>uu,"no-unneeded-ternary":()=>mu,"no-unreachable":()=>xu,"no-unreachable-loop":()=>Eu,"no-unsafe-finally":()=>Au,"no-unsafe-negation":()=>ku,"no-unsafe-optional-chaining":()=>Fu,"no-unused-expressions":()=>Bu,"no-unused-labels":()=>Nu,"no-unused-vars":()=>ju,"no-use-before-define":()=>_u,"no-useless-backreference":()=>Hu,"no-useless-call":()=>Xu,"no-useless-catch":()=>Qu,"no-useless-computed-key":()=>Zu,"no-useless-concat":()=>np,"no-useless-constructor":()=>ip,"no-useless-escape":()=>dp,"no-useless-rename":()=>fp,"no-useless-return":()=>hp,"no-var":()=>Ap,"no-void":()=>kp,"no-warning-comments":()=>Pp,"no-whitespace-before-property":()=>Tp,"no-with":()=>Ip,"nonblock-statement-body-position":()=>Dp,"object-curly-newline":()=>Np,"object-curly-spacing":()=>jp,"object-property-newline":()=>Lp,"object-shorthand":()=>Vp,"one-var":()=>Wp,"one-var-declaration-per-line":()=>Gp,"operator-assignment":()=>Kp,"operator-linebreak":()=>Yp,"padded-blocks":()=>Hp,"padding-line-between-statements":()=>fd,"prefer-arrow-callback":()=>md,"prefer-const":()=>vd,"prefer-destructuring":()=>kd,"prefer-exponentiation-operator":()=>Fd,"prefer-named-capture-group":()=>Ld,"prefer-numeric-literals":()=>Md,"prefer-object-spread":()=>tf,"prefer-promise-reject-errors":()=>nf,"prefer-reflect":()=>rf,"prefer-regex-literals":()=>pf,"prefer-rest-params":()=>ff,"prefer-spread":()=>mf,"prefer-template":()=>Sf,"quote-props":()=>Cf,quotes:()=>kf,radix:()=>Tf,"require-atomic-updates":()=>Df,"require-await":()=>Of,"require-jsdoc":()=>Bf,"require-unicode-regexp":()=>Mf,"require-yield":()=>_f,"rest-spread-spacing":()=>$f,semi:()=>qf,"semi-spacing":()=>Uf,"semi-style":()=>Wf,"sort-imports":()=>Gf,"sort-keys":()=>Jf,"sort-vars":()=>Kf,"space-before-blocks":()=>Hf,"space-before-function-paren":()=>Xf,"space-in-parens":()=>Qf,"space-infix-ops":()=>Zf,"space-unary-ops":()=>em,"spaced-comment":()=>am,strict:()=>um,"switch-colon-spacing":()=>pm,"symbol-description":()=>dm,"template-curly-spacing":()=>fm,"template-tag-spacing":()=>mm,"unicode-bom":()=>gm,"use-isnan":()=>ym,"valid-jsdoc":()=>xm,"valid-typeof":()=>bm,"vars-on-top":()=>Em,"wrap-iife":()=>Sm,"wrap-regex":()=>Cm,"yield-star-spacing":()=>vm,yoda:()=>Im}));class Om{constructor(){this._rules=Object.create(null)}define(e,t){var n;this._rules[e]="function"==typeof(n=t)?Object.assign({create:n},n):n}get(e){return"string"==typeof this._rules[e]&&this.define(e,ce(this._rules[e])),this._rules[e]?this._rules[e]:Dm.has(e)?Dm.get(e):null}*[Symbol.iterator](){yield*Dm;for(const e of Object.keys(this._rules))yield[e,this.get(e)]}}var Bm=Om;const Nm=M.default("eslint:source-code-fixer");function jm(e,t){return e.fix.range[0]-t.fix.range[0]||e.fix.range[1]-t.fix.range[1]}function Lm(e,t){return e.line-t.line||e.column-t.column}function Rm(){Object.freeze(this)}Rm.applyFixes=function(e,t,n){if(Nm("Applying fixes"),!1===n)return Nm("shouldFix parameter was false, not attempting fixes"),{fixed:!1,messages:t,output:e};const r=[],o=[],s=e.startsWith("\ufeff")?"\ufeff":"",a=s?e.slice(1):e;let i=Number.NEGATIVE_INFINITY,c=s;function l(e){const t=e.fix,n=t.range[0],o=t.range[1];return i>=n||n>o?(r.push(e),!1):((n<0&&o>=0||0===n&&t.text.startsWith("\ufeff"))&&(c=""),c+=a.slice(Math.max(0,i),Math.max(0,n)),c+=t.text,i=o,!0)}if(t.forEach((e=>{Object.prototype.hasOwnProperty.call(e,"fix")?o.push(e):r.push(e)})),o.length){Nm("Found fixes to apply");let e=!1;for(const t of o.sort(jm))"function"!=typeof n||n(t)?(l(t),e=!0):r.push(t);return c+=a.slice(Math.max(0,i)),{fixed:e,messages:r.sort(Lm),output:c}}return Nm("No fixes to apply"),{fixed:!1,messages:t,output:s+a}};var Mm=Rm;function _m(e,t,n){return new Array(t-e.length+1).join(n||" ")+e}const $m=!!process.env.TIMING,qm=["Rule","Time (ms)","Relative"],Um=[function(e,t,n){return e+new Array(t-e.length+1).join(n||" ")},_m,_m];function Vm(){if("string"!=typeof process.env.TIMING)return 10;if("all"===process.env.TIMING.toLowerCase())return Number.POSITIVE_INFINITY;const e=Number.parseInt(process.env.TIMING,10);return e>10?e:10}var Wm=function(){const e=Object.create(null);return $m&&process.on("exit",(()=>{!function(e){let t=0;const n=Object.keys(e).map((n=>{const r=e[n];return t+=r,[n,r]})).sort(((e,t)=>t[1]-e[1])).slice(0,Vm());n.forEach((e=>{e.push(`${(100*e[1]/t).toFixed(1)}%`),e[1]=e[1].toFixed(3)})),n.unshift(qm);const r=[];n.forEach((e=>{const t=e.length;for(let n=0;nr[n])&&(r[n]=t)}}));const o=n.map((e=>e.map(((e,t)=>Um[t](e,r[t]))).join(" | ")));o.splice(1,0,r.map(((e,t)=>{const n=0!==t&&t!==r.length-1?2:1;return Um[t](":",e+n,"-")})).join("|")),console.log(o.join("\n"))}(e)})),{time:function(t,n){return void 0===e[t]&&(e[t]=0),function(...r){let o=process.hrtime();n(...r),o=process.hrtime(o),e[t]+=1e3*o[0]+o[1]/1e6}},enabled:$m,getListSize:Vm}}(),Gm={rules:{"generator-star":["generator-star-spacing"],"global-strict":["strict"],"no-arrow-condition":["no-confusing-arrow","no-constant-condition"],"no-comma-dangle":["comma-dangle"],"no-empty-class":["no-empty-character-class"],"no-empty-label":["no-labels"],"no-extra-strict":["strict"],"no-reserved-keys":["quote-props"],"no-space-before-semi":["semi-spacing"],"no-wrap-func":["no-extra-parens"],"space-after-function-name":["space-before-function-paren"],"space-after-keywords":["keyword-spacing"],"space-before-function-parentheses":["space-before-function-paren"],"space-before-keywords":["keyword-spacing"],"space-in-brackets":["object-curly-spacing","array-bracket-spacing","computed-property-spacing"],"space-return-throw-case":["keyword-spacing"],"space-unary-word-ops":["space-unary-ops"],"spaced-line-comment":["spaced-comment"]}};const{SourceCode:zm}=mn,Jm=M.default("eslint:linter"),Km=new class{parseStringConfig(e,t){Kn("Parsing String config");const n={};return e.replace(/\s*([:,])\s*/gu,"$1").split(/\s|,+/u).forEach((e=>{if(!e)return;const[r,o=null]=e.split(":");n[r]={value:o,comment:t}})),n}parseJsonConfig(e,t){Kn("Parsing JSON config");let n={};try{if(n=J.default.parse("Object",e)||{},wt.isEverySeverityValid(n))return{success:!0,config:n}}catch{Kn("Levn parsing failed; falling back to manual parsing.")}n={};const r=e.replace(/([-a-zA-Z0-9/]+):/gu,'"$1":').replace(/(\]|[0-9])\s+(?=")/u,"$1,");try{n=JSON.parse(`{${r}}`)}catch(e){return Kn("Manual parsing failed."),{success:!1,error:{ruleId:null,fatal:!0,severity:2,message:`Failed to parse JSON from '${r}': ${e.message}`,line:t.start.line,column:t.start.column+1}}}return{success:!0,config:n}}parseListConfig(e){Kn("Parsing list config");const t={};return e.replace(/\s*,\s*/gu,",").split(/,+/u).forEach((e=>{const n=e.trim();n&&(t[n]=!0)})),t}},Ym={start:{line:1,column:0},end:{line:1,column:1}};function Hm(e){return Object.prototype.hasOwnProperty.call(Gm.rules,e)?`Rule '${e}' was removed and replaced by: ${Gm.rules[e].join(", ")}`:`Definition for rule '${e}' was not found.`}function Xm(e){const{ruleId:t=null,loc:n=Ym,message:r=Hm(e.ruleId),severity:o=2}=e;return{ruleId:t,message:r,line:n.start.line,column:n.start.column+1,endLine:n.end.line,endColumn:n.end.column+1,severity:o,nodeType:null}}function Qm(e){return e.split(/\s-{2,}\s/u)[0].trim()}function Zm(e,t,n,r){const o={},s=Object.create(null),a={},i=[],c=[],l=new class{constructor({builtInRules:e=new Map}={}){this.builtInRules=e}getRuleOptionsSchema(e){if(!e)return null;const t=e.schema||e.meta&&e.meta.schema;return Array.isArray(t)?t.length?{type:"array",items:t,minItems:0,maxItems:t.length}:{type:"array",minItems:0,maxItems:0}:t||null}validateRuleSeverity(e){const t=Array.isArray(e)?e[0]:e,n="string"==typeof t?Mt[t.toLowerCase()]:t;if(0===n||1===n||2===n)return n;throw new Error(`\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '${V.default.inspect(t).replace(/'/gu,'"').replace(/\n/gu,"")}').\n`)}validateRuleSchema(e,t){if(!jt.has(e)){const t=this.getRuleOptionsSchema(e);t&&jt.set(e,Nt.compile(t))}const n=jt.get(e);if(n&&(n(t),n.errors))throw new Error(n.errors.map((e=>`\tValue ${JSON.stringify(e.data)} ${e.message}.\n`)).join(""))}validateRuleOptions(e,t,n,r=null){try{0!==this.validateRuleSeverity(n)&&this.validateRuleSchema(e,Array.isArray(n)?n.slice(1):[])}catch(e){const n=`Configuration for rule "${t}" is invalid:\n${e.message}`;throw"string"==typeof r?new Error(`${r}:\n\t${n}`):new Error(n)}}validateEnvironment(e,t,n=Lt){e&&Object.keys(e).forEach((e=>{if(!n(e)&&!vt.get(e))throw new Error(`${t}:\n\tEnvironment key "${e}" is unknown\n`)}))}validateRules(e,t,n=Lt){e&&Object.keys(e).forEach((r=>{const o=n(r)||this.builtInRules.get(r)||null;this.validateRuleOptions(o,r,e[r],t)}))}validateGlobals(e,t=null){e&&Object.entries(e).forEach((([e,n])=>{try{wt.normalizeConfigGlobal(n)}catch(n){throw new Error(`ESLint configuration of global '${e}' in ${t} is invalid:\n${n.message}`)}}))}validateProcessor(e,t,n){if(e&&!n(e))throw new Error(`ESLint configuration of processor in '${t}' is invalid: '${e}' was not found.`)}formatErrors(e){return e.map((e=>"additionalProperties"===e.keyword?`Unexpected top-level property "${e.dataPath.length?`${e.dataPath.slice(1)}.${e.params.additionalProperty}`:e.params.additionalProperty}"`:"type"===e.keyword?`Property "${e.dataPath.slice(1)}" is the wrong type (expected ${Array.isArray(e.schema)?e.schema.join("/"):e.schema} but got \`${JSON.stringify(e.data)}\`)`:`"${"."===e.dataPath[0]?e.dataPath.slice(1):e.dataPath}" ${e.message}. Value: ${JSON.stringify(e.data)}`)).map((e=>`\t- ${e}.\n`)).join("")}validateConfigSchema(e,t=null){if(Rt=Rt||Nt.compile(Tt),!Rt(e))throw new Error(`ESLint configuration in ${t} is invalid:\n${this.formatErrors(Rt.errors)}`);Object.hasOwnProperty.call(e,"ecmaFeatures")&&Bt(t,"ESLINT_LEGACY_ECMAFEATURES")}validate(e,t,n,r){this.validateConfigSchema(e,t),this.validateRules(e.rules,t,n),this.validateEnvironment(e.env,t,r),this.validateGlobals(e.globals,t);for(const o of e.overrides||[])this.validateRules(o.rules,t,n),this.validateEnvironment(o.env,t,r),this.validateGlobals(e.globals,t)}validateConfigArray(e){const t=Map.prototype.get.bind(e.pluginEnvironments),n=Map.prototype.get.bind(e.pluginProcessors),r=Map.prototype.get.bind(e.pluginRules);for(const o of e)_t.has(o)||(_t.add(o),this.validateEnvironment(o.env,o.name,t),this.validateGlobals(o.globals,o.name),this.validateProcessor(o.processor,o.name,n),this.validateRules(o.rules,o.name,r))}}({builtInRules:Bm});return t.comments.filter((e=>"Shebang"!==e.type)).forEach((e=>{const t=Qm(e.value),u=/^(eslint(?:-env|-enable|-disable(?:(?:-next)?-line)?)?|exported|globals?)(?:\s|$)/u.exec(t);if(!u)return;const p=u[1],d=/^eslint-disable-(next-)?line$/u.test(p);if("Line"===e.type&&!d)return;if(r){const t="Block"===e.type?`/*${p}*/`:`//${p}`;return void i.push(Xm({ruleId:null,message:`'${t}' has no effect because you have 'noInlineConfig' setting in ${r}.`,loc:e.loc,severity:1}))}if(d&&e.loc.start.line!==e.loc.end.line){const t=`${p} comment should not span multiple lines.`;return void i.push(Xm({ruleId:null,message:t,loc:e.loc}))}const f=t.slice(u.index+p.length);switch(p){case"eslint-disable":case"eslint-enable":case"eslint-disable-next-line":case"eslint-disable-line":{const t={type:p.slice("eslint-".length),loc:e.loc,value:f,ruleMapper:n},{directives:r,directiveProblems:o}=function(e){const{type:t,loc:n,value:r,ruleMapper:o}=e,s=Object.keys(Km.parseListConfig(r)),a=s.length?s:[null],i={directives:[],directiveProblems:[]};for(const e of a)null===e||null!==o(e)?i.directives.push({type:t,line:n.start.line,column:n.start.column+1,ruleId:e}):i.directiveProblems.push(Xm({ruleId:e,loc:n}));return i}(t);c.push(...r),i.push(...o);break}case"exported":Object.assign(a,Km.parseStringConfig(f,e));break;case"globals":case"global":for(const[t,{value:n}]of Object.entries(Km.parseStringConfig(f,e))){let r;try{r=wt.normalizeConfigGlobal(n)}catch(t){i.push(Xm({ruleId:null,loc:e.loc,message:t.message}));continue}s[t]?(s[t].comments.push(e),s[t].value=r):s[t]={comments:[e],value:r}}break;case"eslint":{const t=Km.parseJsonConfig(f,e.loc);t.success?Object.keys(t.config).forEach((r=>{const s=n(r),a=t.config[r];if(null!==s){try{l.validateRuleOptions(s,r,a)}catch(t){return void i.push(Xm({ruleId:r,message:t.message,loc:e.loc}))}o[r]=a}else i.push(Xm({ruleId:r,loc:e.loc}))})):i.push(t.error);break}}})),{configuredRules:o,enabledGlobals:s,exportedVariables:a,problems:i,disableDirectives:c}}const eg=/\/\*\s*eslint-env\s(.+?)\*\//gu;function tg(e){const t=e.split(O.default.sep),n=t.lastIndexOf("");return-1===n?e:t.slice(n).join(O.default.sep)}function ng(e,t,n){const r=t.ecmaFeatures||{},o=t.ecmaVersion||5;return _.default.analyze(e,{ignoreEval:!0,nodejsScope:r.globalReturn,impliedStrict:r.impliedStrict,ecmaVersion:o,sourceType:t.sourceType||"script",childVisitorKeys:n||$.default.KEYS,fallback:Vt.getKeys})}function rg(e,t){const n="Program"!==t.type;for(let r=t;r;r=r.parent){const t=e.acquire(r,n);if(t)return"function-expression-name"===t.type?t.childScopes[0]:t}return e.scopes[0]}const og={getSource:"getText",getSourceLines:"getLines",getAllComments:"getAllComments",getNodeByRangeIndex:"getNodeByRangeIndex",getComments:"getComments",getCommentsBefore:"getCommentsBefore",getCommentsAfter:"getCommentsAfter",getCommentsInside:"getCommentsInside",getJSDocComment:"getJSDocComment",getFirstToken:"getFirstToken",getFirstTokens:"getFirstTokens",getLastToken:"getLastToken",getLastTokens:"getLastTokens",getTokenAfter:"getTokenAfter",getTokenBefore:"getTokenBefore",getTokenByRangeStart:"getTokenByRangeStart",getTokens:"getTokens",getTokensAfter:"getTokensAfter",getTokensBefore:"getTokensBefore",getTokensBetween:"getTokensBetween"},sg=Object.freeze(Object.keys(og).reduce(((e,t)=>Object.assign(e,{[t](...e){return this.getSourceCode()[og[t]](...e)}})),{}));function ag(e,t,n,r,o,s,a,i,c){const l=(()=>{const e=Object.create(null);return Object.freeze({on(t,n){t in e?e[t].push(n):e[t]=[n]},emit(t,...n){t in e&&e[t].forEach((e=>e(...n)))},eventNames:()=>Object.keys(e)})})(),u=[];let p=e.ast;Vt.traverse(e.ast,{enter(e,t){e.parent=t,u.push({isEntering:!0,node:e})},leave(e){u.push({isEntering:!1,node:e})},visitorKeys:e.visitorKeys});const d=Object.freeze(Object.assign(Object.create(sg),{getAncestors:()=>function(e){const t=[];for(let n=e.parent;n;n=n.parent)t.push(n);return t.reverse()}(p),getDeclaredVariables:e.scopeManager.getDeclaredVariables.bind(e.scopeManager),getCwd:()=>c,getFilename:()=>a,getScope:()=>rg(e.scopeManager,p),getSourceCode:()=>e,markVariableAsUsed:t=>function(e,t,n,r){const o=n.ecmaFeatures&&n.ecmaFeatures.globalReturn||"module"===n.sourceType,s=rg(e,t);for(let e="global"===s.type&&o?s.childScopes[0]:s;e;e=e.upper){const t=e.variables.find((e=>e.name===r));if(t)return t.eslintUsed=!0,!0}return!1}(e.scopeManager,p,r,t),parserOptions:r,parserPath:o,parserServices:e.parserServices,settings:s})),f=[];Object.keys(t).forEach((r=>{const o=wt.getRuleSeverity(t[r]);if(0===o)return;const s=n(r);if(null===s)return void f.push(Xm({ruleId:r}));const a=s.meta&&s.meta.messages;let c=null;const u=Object.freeze(Object.assign(Object.create(d),{id:r,options:(p=t[r],Array.isArray(p)?p.slice(1):[]),report(...t){null===c&&(c=lr({ruleId:r,severity:o,sourceCode:e,messageIds:a,disableFixes:i}));const n=c(...t);if(n.fix&&s.meta&&!s.meta.fixable)throw new Error("Fixable rules should export a `meta.fixable` property.");f.push(n)}}));var p;const m=function(e,t){try{return e.create(t)}catch(e){throw e.message=`Error while loading rule '${t.id}': ${e.message}`,e}}(s,u);Object.keys(m).forEach((e=>{l.on(e,Wm.enabled?Wm.time(r,m[e]):m[e])}))}));const m="Program"===u[0].node.type?new Gn(new er(l,{visitorKeys:e.visitorKeys,fallback:Vt.getKeys})):new er(l,{visitorKeys:e.visitorKeys,fallback:Vt.getKeys});return u.forEach((e=>{p=e.node;try{e.isEntering?m.enterNode(p):m.leaveNode(p)}catch(e){throw e.currentNode=p,e}})),f}function ig(e,t){return e.lastConfigArray&&e.lastConfigArray.pluginRules.get(t)||e.ruleMap.get(t)}function cg(e){return e||("object"==typeof process?process.cwd():void 0)}const lg=new WeakMap;var ug={Linter:class{constructor({cwd:e}={}){lg.set(this,{cwd:cg(e),lastConfigArray:null,lastSourceCode:null,parserMap:new Map([["espree",q.default]]),ruleMap:new Bm}),this.version=rt.version}static get version(){return rt.version}_verifyWithoutProcessors(e,t,n){const r=lg.get(this),o=t||{},s=function(e,t){const n=!0===t.noInlineConfig,r=!1===e.allowInlineConfig,o=t.configNameOfNoInlineConfig?` (${t.configNameOfNoInlineConfig})`:"";let s=e.reportUnusedDisableDirectives;return"boolean"==typeof s&&(s=s?"error":"off"),"string"!=typeof s&&(s=t.reportUnusedDisableDirectives?"warn":"off"),{filename:tg(e.filename||""),allowInlineConfig:!r,warnInlineConfig:n&&!r?`your config${o}`:null,reportUnusedDisableDirectives:s,disableFixes:Boolean(e.disableFixes)}}(n,o);let a;"string"==typeof e?(r.lastSourceCode=null,a=e):(r.lastSourceCode=e,a=e.text);let i="espree",c=q.default;if("object"==typeof o.parser&&null!==o.parser)i=o.parser.filePath,c=o.parser.definition;else if("string"==typeof o.parser){if(!r.parserMap.has(o.parser))return[{ruleId:null,fatal:!0,severity:2,message:`Configured parser '${o.parser}' was not found.`,line:0,column:0}];i=o.parser,c=r.parserMap.get(o.parser)}const l=s.allowInlineConfig&&!s.warnInlineConfig?function(e){let t,n;for(eg.lastIndex=0;null!==(t=eg.exec(e));)n=Object.assign(n||{},Km.parseListConfig(Qm(t[1])));return n}(a):{},u=Object.assign({builtin:!0},o.env,l),p=Object.keys(u).filter((e=>u[e])).map((e=>function(e,t){return e.lastConfigArray&&e.lastConfigArray.pluginEnvironments.get(t)||vt.get(t)||null}(r,e))).filter((e=>e)),d=function(e,t,n){const r=n.filter((e=>e.parserOptions)).reduce(((e,t)=>F.default.merge(e,t.parserOptions)),{}),o=F.default.merge(r,t||{});var s;return"module"===o.sourceType&&(o.ecmaFeatures=Object.assign({},o.ecmaFeatures,{globalReturn:!1})),o.ecmaVersion=(s=o.ecmaVersion)>=2015?s-2009:s,o}(0,o.parserOptions||{},p),f=(m=o.globals||{},g=p,Object.assign({},...g.filter((e=>e.globals)).map((e=>e.globals)),m));var m,g;const h=o.settings||{};if(r.lastSourceCode)r.lastSourceCode.scopeManager||(r.lastSourceCode=new zm({text:r.lastSourceCode.text,ast:r.lastSourceCode.ast,parserServices:r.lastSourceCode.parserServices,visitorKeys:r.lastSourceCode.visitorKeys,scopeManager:ng(r.lastSourceCode.ast,d)}));else{const e=function(e,t,n,r){const o=function(e){return 65279===e.charCodeAt(0)?e.slice(1):e}(e).replace(kt.shebangPattern,((e,t)=>`//${t}`)),s=Object.assign({},n,{loc:!0,range:!0,raw:!0,tokens:!0,comment:!0,eslintVisitorKeys:!0,eslintScopeManager:!0,filePath:r});try{const n="function"==typeof t.parseForESLint?t.parseForESLint(o,s):{ast:t.parse(o,s)},r=n.ast,a=n.services||{},i=n.visitorKeys||$.default.KEYS,c=n.scopeManager||ng(r,s,i);return{success:!0,sourceCode:new zm({text:e,ast:r,parserServices:a,scopeManager:c,visitorKeys:i})}}catch(e){const t=`Parsing error: ${e.message.replace(/^line \d+:/iu,"").trim()}`;return Jm("%s\n%s",t,e.stack),{success:!1,error:{ruleId:null,fatal:!0,severity:2,message:t,line:e.lineNumber,column:e.column}}}}(a,c,d,s.filename);if(!e.success)return[e.error];r.lastSourceCode=e.sourceCode}const y=r.lastSourceCode,x=s.allowInlineConfig?Zm(s.filename,y.ast,(e=>ig(r,e)),s.warnInlineConfig):{configuredRules:{},enabledGlobals:{},exportedVariables:{},problems:[],disableDirectives:[]};!function(e,t,{exportedVariables:n,enabledGlobals:r}){for(const n of new Set([...Object.keys(t),...Object.keys(r)])){const o=void 0===t[n]?void 0:wt.normalizeConfigGlobal(t[n]),s=r[n]&&r[n].value||o,a=r[n]&&r[n].comments;if("off"===s)continue;let i=e.set.get(n);i||(i=new _.default.Variable(n,e),e.variables.push(i),e.set.set(n,i)),i.eslintImplicitGlobalSetting=o,i.eslintExplicitGlobal=void 0!==a,i.eslintExplicitGlobalComments=a,i.writeable="writable"===s}Object.keys(n).forEach((t=>{const n=e.set.get(t);n&&(n.eslintUsed=!0)})),e.through=e.through.filter((t=>{const n=t.identifier.name,r=e.set.get(n);return!r||(t.resolved=r,r.references.push(t),!1)}))}(y.scopeManager.scopes[0],f,{exportedVariables:x.exportedVariables,enabledGlobals:x.enabledGlobals});const b=Object.assign({},o.rules,x.configuredRules);let E;try{E=ag(y,b,(e=>ig(r,e)),d,i,h,s.filename,s.disableFixes,r.cwd)}catch(e){if(e.message+=`\nOccurred while linting ${s.filename}`,Jm("An error occurred while traversing"),Jm("Filename:",s.filename),e.currentNode){const{line:t}=e.currentNode.loc.start;Jm("Line:",t),e.message+=`:${t}`}throw Jm("Parser Options:",d),Jm("Parser Path:",i),Jm("Settings:",h),e}return(({directives:e,problems:t,reportUnusedDisableDirectives:n="off"})=>{const r=e.filter((e=>"disable"===e.type||"enable"===e.type)).map((e=>Object.assign({},e,{unprocessedDirective:e}))).sort(zn),o=F.default.flatMap(e,(e=>{switch(e.type){case"disable":case"enable":return[];case"disable-line":return[{type:"disable",line:e.line,column:1,ruleId:e.ruleId,unprocessedDirective:e},{type:"enable",line:e.line+1,column:0,ruleId:e.ruleId,unprocessedDirective:e}];case"disable-next-line":return[{type:"disable",line:e.line+1,column:1,ruleId:e.ruleId,unprocessedDirective:e},{type:"enable",line:e.line+2,column:0,ruleId:e.ruleId,unprocessedDirective:e}];default:throw new TypeError(`Unrecognized directive type '${e.type}'`)}})).sort(zn),s=Jn({problems:t,directives:r,reportUnusedDisableDirectives:n}),a=Jn({problems:s.problems,directives:o,reportUnusedDisableDirectives:n});return"off"!==n?a.problems.concat(s.unusedDisableDirectives).concat(a.unusedDisableDirectives).sort(zn):a.problems})({directives:x.disableDirectives,problems:E.concat(x.problems).sort(((e,t)=>e.line-t.line||e.column-t.column)),reportUnusedDisableDirectives:s.reportUnusedDisableDirectives})}verify(e,t,n){Jm("Verify");const r="string"==typeof n?{filename:n}:n||{};return t&&"function"==typeof t.extractConfig?this._verifyWithConfigArray(e,t,r):r.preprocess||r.postprocess?this._verifyWithProcessor(e,t,r):this._verifyWithoutProcessors(e,t,r)}_verifyWithConfigArray(e,t,n){Jm("With ConfigArray: %s",n.filename),lg.get(this).lastConfigArray=t;const r=t.extractConfig(n.filename),o=r.processor&&t.pluginProcessors.get(r.processor);if(o){Jm("Apply the processor: %o",r.processor);const{preprocess:s,postprocess:a,supportsAutofix:i}=o,c=n.disableFixes||!i;return this._verifyWithProcessor(e,r,{...n,disableFixes:c,postprocess:a,preprocess:s},t)}return this._verifyWithoutProcessors(e,r,n)}_verifyWithProcessor(e,t,n,r){const o=n.filename||"",s=tg(o),a=function(e){if("object"==typeof e){const{hasBOM:t,text:n}=e;return(t?"\ufeff":"")+n}return String(e)}(e),i=n.preprocess||(e=>[e]),c=n.postprocess||F.default.flatten,l=n.filterCodeBlock||(e=>e.endsWith(".js")),u=O.default.extname(o);return c(i(a,s).map(((e,s)=>{if(Jm("A code block was found: %o",e.filename||"(unnamed)"),"string"==typeof e)return this._verifyWithoutProcessors(e,t,n);const a=e.text,i=O.default.join(o,`${s}_${e.filename}`);return l(i,a)?r&&O.default.extname(i)!==u?(Jm("Resolving configuration again because the file extension was changed."),this._verifyWithConfigArray(a,r,{...n,filename:i})):this._verifyWithoutProcessors(a,t,{...n,filename:i}):(Jm("This code block was skipped."),[])})),s)}getSourceCode(){return lg.get(this).lastSourceCode}defineRule(e,t){lg.get(this).ruleMap.define(e,t)}defineRules(e){Object.getOwnPropertyNames(e).forEach((t=>{this.defineRule(t,e[t])}))}getRules(){const{lastConfigArray:e,ruleMap:t}=lg.get(this);return new Map(function*(){yield*t,e&&(yield*e.pluginRules)}())}defineParser(e,t){lg.get(this).parserMap.set(e,t)}verifyAndFix(e,t,n){let r,o=[],s=!1,a=0,i=e;const c=n&&n.filename||`${e.slice(0,10)}...`,l=!n||void 0===n.fix||n.fix;do{if(a++,Jm(`Linting code for ${c} (pass ${a})`),o=this.verify(i,t,n),Jm(`Generating fixed text for ${c} (pass ${a})`),r=Mm.applyFixes(i,o,l),1===o.length&&o[0].fatal)break;s=s||r.fixed,i=r.output}while(r.fixed&&a<10);return r.fixed&&(r.messages=this.verify(i,t,n)),r.fixed=s,r.output=i,r}},getLinterInternalSlots:e=>lg.get(e)};const{Linter:pg}=ug;var dg={Linter:pg,SourceCodeFixer:Mm,interpolate:rr};const fg={};var mg=function(e,t){const n=O.default.resolve(t,e);if(fg[n])return fg[n];const r=Object.create(null);return D.default.readdirSync(n).forEach((e=>{".js"===O.default.extname(e)&&(r[e.slice(0,-3)]=ce(O.default.join(n,e)))})),fg[n]=r,r};var gg=function(e){return te.default(e).result().toString(36)};const hg=M.default("eslint:lint-result-cache"),yg=new WeakMap,xg=process&&process.version,bg=["metadata","content"],Eg=`Cache strategy must be one of: ${bg.map((e=>`"${e}"`)).join(", ")}`;function Sg(e){return yg.has(e)||yg.set(e,gg(`${rt.version}_${xg}_${re.default(e)}`)),yg.get(e)}var Cg=class{constructor(e,t){z.default(e,"Cache file location is required"),z.default(t,"Cache strategy is required"),z.default(function(e){return-1!==bg.indexOf(e)}(t),Eg),hg(`Caching results to ${e}`);const n="content"===t;hg(`Using "${t}" strategy to detect changes`),this.fileEntryCache=ne.default.create(e,void 0,n),this.cacheFileLocation=e}getCachedLintResults(e,t){const n=this.fileEntryCache.getFileDescriptor(e),r=Sg(t),o=n.changed||n.meta.hashOfConfig!==r;return n.notFound?(hg(`File not found on the file system: ${e}`),null):o?(hg(`Cache entry not found or no longer valid: ${e}`),null):(n.meta.results&&null===n.meta.results.source&&(hg(`Rereading cached result source from filesystem: ${e}`),n.meta.results.source=D.default.readFileSync(e,"utf-8")),n.meta.results)}setCachedLintResults(e,t,n){if(n&&Object.prototype.hasOwnProperty.call(n,"output"))return;const r=this.fileEntryCache.getFileDescriptor(e);if(r&&!r.notFound){hg(`Updating cached result: ${e}`);const o=Object.assign({},n);Object.prototype.hasOwnProperty.call(o,"source")&&(o.source=null),r.meta.results=o,r.meta.hashOfConfig=Sg(t)}}reconcile(){hg(`Persisting cached results: ${this.cacheFileLocation}`),this.fileEntryCache.reconcile()}};const{Legacy:{ConfigOps:vg,naming:Ag,CascadingConfigArrayFactory:kg,IgnorePattern:wg,getUsedExtractedConfigs:Pg}}=B.default,{FileEnumerator:Tg}=bt,{Linter:Ig}=dg,Fg=M.default("eslint:cli-engine"),Dg=new Set(["problem","suggestion","layout"]),Og=new WeakMap;function Bg(e){return e.reduce(((e,t)=>(t.fatal||2===t.severity?(e.errorCount++,t.fix&&e.fixableErrorCount++):(e.warningCount++,t.fix&&e.fixableWarningCount++),e)),{errorCount:0,warningCount:0,fixableErrorCount:0,fixableWarningCount:0})}function Ng(e){return e.reduce(((e,t)=>(e.errorCount+=t.errorCount,e.warningCount+=t.warningCount,e.fixableErrorCount+=t.fixableErrorCount,e.fixableWarningCount+=t.fixableWarningCount,e)),{errorCount:0,warningCount:0,fixableErrorCount:0,fixableWarningCount:0})}function jg({text:e,cwd:t,filePath:n,config:r,fix:o,allowInlineConfig:s,reportUnusedDisableDirectives:a,fileEnumerator:i,linter:c}){const l=n||"";Fg(`Lint ${l}`);const u=""===l?O.default.join(t,l):l,{fixed:p,messages:d,output:f}=c.verifyAndFix(e,r,{allowInlineConfig:s,filename:u,fix:o,reportUnusedDisableDirectives:a,filterCodeBlock:e=>i.isTargetPath(e)}),m={filePath:l,messages:d,...Bg(d)};return p&&(m.output=f),m.errorCount+m.warningCount>0&&void 0===m.output&&(m.source=e),m}function Lg(e,t){let n;const r=e.split(O.default.sep).find((e=>/^\./u.test(e))),o=t&&O.default.relative(t,e).startsWith("node_modules");return n=r?"File ignored by default. Use a negated ignore pattern (like \"--ignore-pattern '!'\") to override.":o?"File ignored by default. Use \"--ignore-pattern '!node_modules/*'\" to override.":'File ignored because of a matching ignore pattern. Use "--no-ignore" to override.',{filePath:O.default.resolve(e),messages:[{fatal:!1,severity:1,message:n}],errorCount:0,warningCount:1,fixableErrorCount:0,fixableWarningCount:0}}function Rg(e,t){for(const n of t){const t=n.pluginRules.get(e);if(t)return t}return Dm.get(e)||null}function*Mg(e){const t=new Set,n=[].concat(...e.map(Pg));for(const r of n)for(const[n,o]of Object.entries(r.rules)){if(t.has(n))continue;if(t.add(n),!vg.getRuleSeverity(o))continue;const r=Rg(n,e);r&&r.meta&&r.meta.deprecated&&(yield{ruleId:n,replacedBy:r.meta.replacedBy||[]})}}function _g(e){return 2===e.severity}function $g(e,t,n){if(e&&!Array.isArray(e))throw new Error(`${n} must be an array.`);if(e&&e.length>0)return e.reduce(((e,n)=>{const[r,o]=n.split(":");return"__proto__"!==r&&(e[r]=void 0===o?t:"true"===o),e}),{})}function qg(e){const{ignorePattern:t,parser:n,parserOptions:r,plugins:o,rules:s}=e,a=$g(e.envs,!0,"envs"),i=$g(e.globals,!1,"globals");return void 0!==a||void 0!==i||void 0!==t&&0!==t.length||void 0!==n||void 0!==r||void 0!==o||void 0!==s?{env:a,globals:i,ignorePatterns:t,parser:n,parserOptions:r,plugins:o,rules:s}:null}function Ug(e){try{return D.default.statSync(e).isDirectory()}catch(e){if(e&&("ENOENT"===e.code||"ENOTDIR"===e.code))return!1;throw e}}class Vg{constructor(e){const t=Object.assign(Object.create(null),nt,{cwd:process.cwd()},e);void 0===t.fix&&(t.fix=!1);const n=new Map,r=function(e,t){const n=O.default.normalize(e),r=O.default.resolve(t,n),o=n.slice(-1)===O.default.sep;function s(){return O.default.join(r,`.cache_${gg(t)}`)}let a;try{a=D.default.lstatSync(r)}catch{a=null}return a?a.isDirectory()||o?s():r:o?s():r}(t.cacheLocation||t.cacheFile,t.cwd),o=new kg({additionalPluginPool:n,baseConfig:t.baseConfig||null,cliConfig:qg(t),cwd:t.cwd,ignorePath:t.ignorePath,resolvePluginsRelativeTo:t.resolvePluginsRelativeTo,rulePaths:t.rulePaths,specificConfigPath:t.configFile,useEslintrc:t.useEslintrc,builtInRules:Dm,loadRules:mg,eslintRecommendedPath:O.default.resolve(__dirname,"../../conf/eslint-recommended.js"),eslintAllPath:O.default.resolve(__dirname,"../../conf/eslint-all.js")}),s=new Tg({configArrayFactory:o,cwd:t.cwd,extensions:t.extensions,globInputPaths:t.globInputPaths,errorOnUnmatchedPattern:t.errorOnUnmatchedPattern,ignore:t.ignore}),a=t.cache?new Cg(r,t.cacheStrategy):null,i=new Ig({cwd:t.cwd}),c=[o.getConfigArrayForFile()];if(Og.set(this,{additionalPluginPool:n,cacheFilePath:r,configArrayFactory:o,defaultIgnores:wg.createDefaultIgnore(t.cwd),fileEnumerator:s,lastConfigArrays:c,lintResultCache:a,linter:i,options:t}),t.fix&&t.fixTypes&&t.fixTypes.length>0){Fg(`Using fix types ${t.fixTypes}`),function(e){for(const t of e)if(!Dg.has(t))throw new Error(`Invalid fix type "${t}" found.`)}(t.fixTypes);const e=new Set(t.fixTypes),n="function"==typeof t.fix?t.fix:()=>!0;t.fix=t=>{const r=t.ruleId&&Rg(t.ruleId,c);return r&&r.meta&&e.has(r.meta.type)&&n(t)}}}getRules(){const{lastConfigArrays:e}=Og.get(this);return new Map(function*(){yield*Dm;for(const t of e)yield*t.pluginRules}())}static getErrorResults(e){const t=[];return e.forEach((e=>{const n=e.messages.filter(_g);n.length>0&&t.push({...e,messages:n,errorCount:n.length,warningCount:0,fixableErrorCount:e.fixableErrorCount,fixableWarningCount:0})})),t}static outputFixes(e){e.results.filter((e=>Object.prototype.hasOwnProperty.call(e,"output"))).forEach((e=>{D.default.writeFileSync(e.filePath,e.output)}))}addPlugin(e,t){const{additionalPluginPool:n,configArrayFactory:r,lastConfigArrays:o}=Og.get(this);n.set(e,t),r.clearCache(),o.length=1,o[0]=r.getConfigArrayForFile()}resolveFileGlobPatterns(e){const{options:t}=Og.get(this);if(!1===t.globInputPaths)return e.filter(Boolean);const n=`/**/*.{${(t.extensions||[".js"]).map((e=>e.replace(/^\./u,""))).join(",")}}`;return e.filter(Boolean).map((e=>{const r=Ug(O.default.resolve(t.cwd,e))?e.replace(/[/\\]$/u,"")+n:e;return O.default.normalize(r).replace(/\\/gu,"/")}))}executeOnFiles(e){const{cacheFilePath:t,fileEnumerator:n,lastConfigArrays:r,lintResultCache:o,linter:s,options:{allowInlineConfig:a,cache:i,cwd:c,fix:l,reportUnusedDisableDirectives:u}}=Og.get(this),p=[],d=Date.now();if(r.length=0,!i)try{D.default.unlinkSync(t)}catch(e){const n=e&&e.code;if("ENOENT"!==n&&("EROFS"!==n||D.default.existsSync(t)))throw e}for(const{config:t,filePath:i,ignored:d}of n.iterateFiles(e)){if(d){p.push(Lg(i,c));continue}if(r.includes(t)||r.push(t),o){const e=o.getCachedLintResults(i,t);if(e){if(!(e.messages&&e.messages.length>0)||!l){Fg(`Skipping file since it hasn't changed: ${i}`),p.push(e);continue}Fg(`Reprocessing cached file to allow autofix: ${i}`)}}const e=jg({text:D.default.readFileSync(i,"utf8"),filePath:i,config:t,cwd:c,fix:l,allowInlineConfig:a,reportUnusedDisableDirectives:u,fileEnumerator:n,linter:s});p.push(e),o&&o.setCachedLintResults(i,t,e)}let f;return o&&o.reconcile(),Fg(`Linting complete in: ${Date.now()-d}ms`),{results:p,...Ng(p),get usedDeprecatedRules(){return f||(f=Array.from(Mg(r))),f}}}executeOnText(e,t,n){const{configArrayFactory:r,fileEnumerator:o,lastConfigArrays:s,linter:a,options:{allowInlineConfig:i,cwd:c,fix:l,reportUnusedDisableDirectives:u}}=Og.get(this),p=[],d=Date.now(),f=t&&O.default.resolve(c,t);if(s.length=0,f&&this.isPathIgnored(f))n&&p.push(Lg(f,c));else{const t=r.getConfigArrayForFile(f||"__placeholder__.js");s.push(t),p.push(jg({text:e,filePath:f,config:t,cwd:c,fix:l,allowInlineConfig:i,reportUnusedDisableDirectives:u,fileEnumerator:o,linter:a}))}let m;return Fg(`Linting complete in: ${Date.now()-d}ms`),{results:p,...Ng(p),get usedDeprecatedRules(){return m||(m=Array.from(Mg(s))),m}}}getConfigForFile(e){const{configArrayFactory:t,options:n}=Og.get(this),r=O.default.resolve(n.cwd,e);if(Ug(r))throw Object.assign(new Error("'filePath' should not be a directory path."),{messageTemplate:"print-config-with-directory-path"});return t.getConfigArrayForFile(r).extractConfig(r).toCompatibleObjectAsConfigFileContent()}isPathIgnored(e){const{configArrayFactory:t,defaultIgnores:n,options:{cwd:r,ignore:o}}=Og.get(this),s=O.default.resolve(r,e);if(o){return(t.getConfigArrayForFile(s).extractConfig(s).ignores||n)(s)}return n(s)}getFormatter(e){const t=e||"stylish";if("string"!=typeof t)return null;{const e=t.replace(/\\/gu,"/"),n=Og.get(this),r=n?n.options.cwd:process.cwd();let o;if(!Ag.getNamespaceFromTerm(e)&&e.indexOf("/")>-1)o=O.default.resolve(r,e);else try{const t=Ag.normalizePackageName(e,"eslint-formatter");o=st.resolve(t,O.default.join(r,"__placeholder__.js"))}catch{o=O.default.resolve(__dirname,"formatters",e)}try{return ce(o)}catch(e){throw e.message=`There was a problem loading formatter: ${o}\nError: ${e.message}`,e}}}}Vg.version=rt.version,Vg.getFormatter=Vg.prototype.getFormatter;var Wg={CLIEngine:Vg,getCLIEngineInternalSlots:e=>Og.get(e)};const{CLIEngine:Gg}=Wg;var zg={CLIEngine:Gg};const{promisify:Jg}=V.default,{CLIEngine:Kg,getCLIEngineInternalSlots:Yg}=Wg,{Legacy:{ConfigOps:{getRuleSeverity:Hg}}}=B.default,{version:Xg}=rt,Qg=Jg(D.default.writeFile),Zg=new WeakMap;function eh(e){return"string"==typeof e&&""!==e.trim()}function th(e){return Array.isArray(e)&&e.every(eh)}function nh(e){return"problem"===e||"suggestion"===e||"layout"===e}class rh extends Error{constructor(e){super(`Invalid Options:\n- ${e.join("\n- ")}`),this.code="ESLINT_INVALID_OPTIONS",Error.captureStackTrace(this,rh)}}function oh({allowInlineConfig:e=!0,baseConfig:t=null,cache:n=!1,cacheLocation:r=".eslintcache",cacheStrategy:o="metadata",cwd:s=process.cwd(),errorOnUnmatchedPattern:a=!0,extensions:i=null,fix:c=!1,fixTypes:l=null,globInputPaths:u=!0,ignore:p=!0,ignorePath:d=null,overrideConfig:f=null,overrideConfigFile:m=null,plugins:g={},reportUnusedDisableDirectives:h=null,resolvePluginsRelativeTo:y=null,rulePaths:x=[],useEslintrc:b=!0,...E}){const S=[],C=Object.keys(E);var v;if(C.length>=1&&(S.push(`Unknown options: ${C.join(", ")}`),C.includes("cacheFile")&&S.push("'cacheFile' has been removed. Please use the 'cacheLocation' option instead."),C.includes("configFile")&&S.push("'configFile' has been removed. Please use the 'overrideConfigFile' option instead."),C.includes("envs")&&S.push("'envs' has been removed. Please use the 'overrideConfig.env' option instead."),C.includes("globals")&&S.push("'globals' has been removed. Please use the 'overrideConfig.globals' option instead."),C.includes("ignorePattern")&&S.push("'ignorePattern' has been removed. Please use the 'overrideConfig.ignorePatterns' option instead."),C.includes("parser")&&S.push("'parser' has been removed. Please use the 'overrideConfig.parser' option instead."),C.includes("parserOptions")&&S.push("'parserOptions' has been removed. Please use the 'overrideConfig.parserOptions' option instead."),C.includes("rules")&&S.push("'rules' has been removed. Please use the 'overrideConfig.rules' option instead.")),"boolean"!=typeof e&&S.push("'allowInlineConfig' must be a boolean."),"object"!=typeof t&&S.push("'baseConfig' must be an object or null."),"boolean"!=typeof n&&S.push("'cache' must be a boolean."),eh(r)||S.push("'cacheLocation' must be a non-empty string."),"metadata"!==o&&"content"!==o&&S.push('\'cacheStrategy\' must be any of "metadata", "content".'),eh(s)&&O.default.isAbsolute(s)||S.push("'cwd' must be an absolute path."),"boolean"!=typeof a&&S.push("'errorOnUnmatchedPattern' must be a boolean."),th(i)||null===i||S.push("'extensions' must be an array of non-empty strings or null."),"boolean"!=typeof c&&"function"!=typeof c&&S.push("'fix' must be a boolean or a function."),null===l||(v=l,Array.isArray(v)&&v.every(nh))||S.push('\'fixTypes\' must be an array of any of "problem", "suggestion", and "layout".'),"boolean"!=typeof u&&S.push("'globInputPaths' must be a boolean."),"boolean"!=typeof p&&S.push("'ignore' must be a boolean."),eh(d)||null===d||S.push("'ignorePath' must be a non-empty string or null."),"object"!=typeof f&&S.push("'overrideConfig' must be an object or null."),eh(m)||null===m||S.push("'overrideConfigFile' must be a non-empty string or null."),"object"!=typeof g?S.push("'plugins' must be an object or null."):null!==g&&Object.keys(g).includes("")&&S.push("'plugins' must not include an empty string."),Array.isArray(g)&&S.push("'plugins' doesn't add plugins to configuration to load. Please use the 'overrideConfig.plugins' option instead."),"error"!==h&&"warn"!==h&&"off"!==h&&null!==h&&S.push('\'reportUnusedDisableDirectives\' must be any of "error", "warn", "off", and null.'),eh(y)||null===y||S.push("'resolvePluginsRelativeTo' must be a non-empty string or null."),th(x)||S.push("'rulePaths' must be an array of non-empty strings."),"boolean"!=typeof b&&S.push("'useEslintrc' must be a boolean."),S.length>0)throw new rh(S);return{allowInlineConfig:e,baseConfig:t,cache:n,cacheLocation:r,cacheStrategy:o,configFile:m,cwd:s,errorOnUnmatchedPattern:a,extensions:i,fix:c,fixTypes:l,globInputPaths:u,ignore:p,ignorePath:d,reportUnusedDisableDirectives:h,resolvePluginsRelativeTo:y,rulePaths:x,useEslintrc:b}}const sh=new WeakMap;function ah(e,{results:t}){const n={configurable:!0,enumerable:!0,get(){return function(e,t){const{configArrayFactory:n,options:{cwd:r}}=Yg(e),o=O.default.isAbsolute(t)?t:O.default.join(r,"__placeholder__.js"),s=n.getConfigArrayForFile(o),a=s.extractConfig(o);if(!sh.has(a)){const e=s.pluginRules,t=[];for(const[n,r]of Object.entries(a.rules)){if(0===Hg(r))continue;const o=e.get(n)||Dm.get(n),s=o&&o.meta;s&&s.deprecated&&t.push({ruleId:n,replacedBy:s.replacedBy||[]})}sh.set(a,Object.freeze(t))}return sh.get(a)}(e,this.filePath)}};for(const e of t)Object.defineProperty(e,"usedDeprecatedRules",n);return t}function ih(e,t){return e.filePatht.filePath?1:0}var ch={ESLint:class{constructor(e={}){const t=oh(e),n=new Kg(t),{additionalPluginPool:r,configArrayFactory:o,lastConfigArrays:s}=Yg(n);let a=!1;if(e.plugins)for(const[t,n]of Object.entries(e.plugins))r.set(t,n),a=!0;(function(e){if("object"==typeof e&&null!==e)for(const t in e)if(void 0!==e[t])return!0;return!1})(e.overrideConfig)&&(o.setOverrideConfig(e.overrideConfig),a=!0),a&&(o.clearCache(),s[0]=o.getConfigArrayForFile()),Zg.set(this,{cliEngine:n,options:t})}static get version(){return Xg}static async outputFixes(e){if(!Array.isArray(e))throw new Error("'results' must be an array");await Promise.all(e.filter((e=>{if("object"!=typeof e||null===e)throw new Error("'results' must include only objects");return"string"==typeof e.output&&O.default.isAbsolute(e.filePath)})).map((e=>Qg(e.filePath,e.output))))}static getErrorResults(e){return Kg.getErrorResults(e)}async lintFiles(e){if(!eh(e)&&!th(e))throw new Error("'patterns' must be a non-empty string or an array of non-empty strings");const{cliEngine:t}=Zg.get(this);return ah(t,t.executeOnFiles(e))}async lintText(e,t={}){if("string"!=typeof e)throw new Error("'code' must be a string");if("object"!=typeof t)throw new Error("'options' must be an object, null, or undefined");const{filePath:n,warnIgnored:r=!1,...o}=t||{};for(const e of Object.keys(o))throw new Error(`'options' must not include the unknown option '${e}'`);if(void 0!==n&&!eh(n))throw new Error("'options.filePath' must be a non-empty string or undefined");if("boolean"!=typeof r)throw new Error("'options.warnIgnored' must be a boolean or undefined");const{cliEngine:s}=Zg.get(this);return ah(s,s.executeOnText(e,n,r))}async loadFormatter(e="stylish"){if("string"!=typeof e)throw new Error("'name' must be a string");const{cliEngine:t}=Zg.get(this),n=t.getFormatter(e);if("function"!=typeof n)throw new Error(`Formatter must be a function, but got a ${typeof n}.`);return{format(e){let r=null;return e.sort(ih),n(e,{get rulesMeta(){return r||(r=function(e){return Array.from(e).reduce(((e,[t,n])=>(e[t]=n.meta,e)),{})}(t.getRules())),r}})}}}async calculateConfigForFile(e){if(!eh(e))throw new Error("'filePath' must be a non-empty string");const{cliEngine:t}=Zg.get(this);return t.getConfigForFile(e)}async isPathIgnored(e){if(!eh(e))throw new Error("'filePath' must be a non-empty string");const{cliEngine:t}=Zg.get(this);return t.isPathIgnored(e)}},getESLintPrivateMembers:e=>Zg.get(e)};const{ESLint:lh}=ch;var uh={ESLint:lh};const ph={$schema:{type:"string"},env:{type:"object"},extends:{$ref:"#/definitions/stringOrStrings"},globals:{type:"object"},overrides:{type:"array",items:{$ref:"#/definitions/overrideConfig"},additionalItems:!1},parser:{type:["string","null"]},parserOptions:{type:"object"},plugins:{type:"array"},processor:{type:"string"},rules:{type:"object"},settings:{type:"object"},noInlineConfig:{type:"boolean"},reportUnusedDisableDirectives:{type:"boolean"},ecmaFeatures:{type:"object"}};var dh={definitions:{stringOrStrings:{oneOf:[{type:"string"},{type:"array",items:{type:"string"},additionalItems:!1}]},stringOrStringsRequired:{oneOf:[{type:"string"},{type:"array",items:{type:"string"},additionalItems:!1,minItems:1}]},objectConfig:{type:"object",properties:{root:{type:"boolean"},ignorePatterns:{$ref:"#/definitions/stringOrStrings"},...ph},additionalProperties:!1},overrideConfig:{type:"object",properties:{excludedFiles:{$ref:"#/definitions/stringOrStrings"},files:{$ref:"#/definitions/stringOrStringsRequired"},...ph},required:["files"],additionalProperties:!1}},$ref:"#/definitions/objectConfig"};const fh={ESLINT_LEGACY_ECMAFEATURES:"The 'ecmaFeatures' config file property is deprecated and has no effect.",ESLINT_PERSONAL_CONFIG_LOAD:"'~/.eslintrc.*' config files have been deprecated. Please use a config file per project or the '--config' option.",ESLINT_PERSONAL_CONFIG_SUPPRESS:"'~/.eslintrc.*' config files have been deprecated. Please remove it or add 'root:true' to the config files in your projects in order to avoid loading '~/.eslintrc.*' accidentally."};var mh={emitDeprecationWarning:F.default.memoize(((e,t)=>{const n=O.default.relative(process.cwd(),e),r=fh[t];process.emitWarning(`${r} (found in "${n}")`,"DeprecationWarning",t)}),((...e)=>JSON.stringify(e)))},gh=(e={})=>{const t=new W.default({meta:!1,useDefaults:!0,validateSchema:!1,missingRefs:"ignore",verbose:!0,schemaId:"auto",...e});return t.addMetaSchema(Ot),t._opts.defaultMeta=Ot.id,t};const{emitDeprecationWarning:hh}=mh,yh=gh(),xh=new WeakMap,bh=Function.prototype;let Eh;const Sh={error:2,warn:1,off:0};function Ch(e){if(!e)return null;const t=e.schema||e.meta&&e.meta.schema;return Array.isArray(t)?t.length?{type:"array",items:t,minItems:0,maxItems:t.length}:{type:"array",minItems:0,maxItems:0}:t||null}function vh(e,t,n,r=null){try{0!==function(e){const t=Array.isArray(e)?e[0]:e,n="string"==typeof t?Sh[t.toLowerCase()]:t;if(0===n||1===n||2===n)return n;throw new Error(`\tSeverity should be one of the following: 0 = off, 1 = warn, 2 = error (you passed '${V.default.inspect(t).replace(/'/gu,'"').replace(/\n/gu,"")}').\n`)}(n)&&function(e,t){if(!xh.has(e)){const t=Ch(e);t&&xh.set(e,yh.compile(t))}const n=xh.get(e);if(n&&(n(t),n.errors))throw new Error(n.errors.map((e=>`\tValue ${JSON.stringify(e.data)} ${e.message}.\n`)).join(""))}(e,Array.isArray(n)?n.slice(1):[])}catch(e){const n=`Configuration for rule "${t}" is invalid:\n${e.message}`;throw"string"==typeof r?new Error(`${r}:\n\t${n}`):new Error(n)}}function Ah(e,t,n=bh){e&&Object.keys(e).forEach((e=>{if(!(n(e)||vt.get(e)||null)){throw new Error(`${t}:\n\tEnvironment key "${e}" is unknown\n`)}}))}function kh(e,t,n=bh){e&&Object.keys(e).forEach((r=>{vh(n(r)||Dm.get(r)||null,r,e[r],t)}))}function wh(e,t=null){e&&Object.entries(e).forEach((([e,n])=>{try{wt.normalizeConfigGlobal(n)}catch(n){throw new Error(`ESLint configuration of global '${e}' in ${t} is invalid:\n${n.message}`)}}))}function Ph(e,t,n){if(e&&!n(e))throw new Error(`ESLint configuration of processor in '${t}' is invalid: '${e}' was not found.`)}function Th(e,t=null){if(Eh=Eh||yh.compile(dh),!Eh(e))throw new Error(`ESLint configuration in ${t} is invalid:\n${n=Eh.errors,n.map((e=>"additionalProperties"===e.keyword?`Unexpected top-level property "${e.dataPath.length?`${e.dataPath.slice(1)}.${e.params.additionalProperty}`:e.params.additionalProperty}"`:"type"===e.keyword?`Property "${e.dataPath.slice(1)}" is the wrong type (expected ${Array.isArray(e.schema)?e.schema.join("/"):e.schema} but got \`${JSON.stringify(e.data)}\`)`:`"${"."===e.dataPath[0]?e.dataPath.slice(1):e.dataPath}" ${e.message}. Value: ${JSON.stringify(e.data)}`)).map((e=>`\t- ${e}.\n`)).join("")}`);var n;Object.hasOwnProperty.call(e,"ecmaFeatures")&&hh(t,"ESLINT_LEGACY_ECMAFEATURES")}const Ih=new WeakSet;var Fh={getRuleOptionsSchema:Ch,validate:function(e,t,n,r){Th(e,t),kh(e.rules,t,n),Ah(e.env,t,r),wh(e.globals,t);for(const o of e.overrides||[])kh(o.rules,t,n),Ah(o.env,t,r),wh(e.globals,t)},validateConfigArray:function(e){const t=Map.prototype.get.bind(e.pluginEnvironments),n=Map.prototype.get.bind(e.pluginProcessors),r=Map.prototype.get.bind(e.pluginRules);for(const o of e)Ih.has(o)||(Ih.add(o),Ah(o.env,o.name,t),wh(o.globals,o.name),Ph(o.processor,o.name,n),kh(o.rules,o.name,r))},validateConfigSchema:Th,validateRuleOptions:vh};const{getRuleOptionsSchema:Dh,validate:Oh}=Fh,{Linter:Bh,SourceCodeFixer:Nh,interpolate:jh}=dg,Lh=gh({strictDefaults:!0}),Rh=require.resolve("espree"),Mh={rules:{}};let _h={rules:{}};const $h=["code","filename","options","errors","output"],qh=new Set(["message","messageId","data","type","line","column","endLine","endColumn","suggestions"]),Uh=`[${[...qh].map((e=>`'${e}'`)).join(", ")}]`,Vh=new Set(["desc","messageId","data","output"]),Wh=`[${[...Vh].map((e=>`'${e}'`)).join(", ")}]`,Gh=Function.call.bind(Object.hasOwnProperty);function zh(e){if("object"==typeof e&&null!==e){if(Array.isArray(e))return e.map(zh);const t={};for(const n in e)"parent"!==n&&Gh(e,n)&&(t[n]=zh(e[n]));return t}return e}function Jh(e){if("object"==typeof e&&null!==e){if(Array.isArray(e))e.forEach(Jh);else for(const t in e)"parent"!==t&&Gh(e,t)&&Jh(e[t]);Object.freeze(e)}}function Kh(e){return e.replace(/[\u0000-\u0009\u000b-\u001a]/gu,(e=>`\\u${e.codePointAt(0).toString(16).padStart(4,"0")}`))}function Yh(e,t){Object.defineProperties(t,{start:{get(){throw new Error(`Use ${e}.range[0] instead of ${e}.start`)},configurable:!0,enumerable:!1},end:{get(){throw new Error(`Use ${e}.range[1] instead of ${e}.end`)},configurable:!0,enumerable:!1}})}function Hh(e,t){Vt.traverse(e,{visitorKeys:t,enter:Yh.bind(null,"node")}),e.tokens.forEach(Yh.bind(null,"token")),e.comments.forEach(Yh.bind(null,"token"))}const Xh=Symbol("describe"),Qh=Symbol("it");function Zh(e,t){try{return t.call(this)}catch(e){throw e instanceof z.default.AssertionError&&(e.message+=` (${V.default.inspect(e.actual)} ${e.operator} ${V.default.inspect(e.expected)})`),e}}function ey(e,t){return t.call(this)}class ty{constructor(e){this.testerConfig=F.default.merge(F.default.cloneDeep(_h),e,{rules:{"rule-tester/validate-ast":"error"}}),this.rules={},this.linter=new Bh}static setDefaultConfig(e){if("object"!=typeof e)throw new TypeError("RuleTester.setDefaultConfig: config must be an object");_h=e,_h.rules=_h.rules||{}}static getDefaultConfig(){return _h}static resetDefaultConfig(){_h=F.default.cloneDeep(Mh)}static get describe(){return this[Xh]||("function"==typeof describe?describe:ey)}static set describe(e){this[Xh]=e}static get it(){return this[Qh]||("function"==typeof it?it:Zh)}static set it(e){this[Qh]=e}defineRule(e,t){this.rules[e]=t}run(e,t,n){const r=this.testerConfig,o=[],s=this.linter;if(!n||"object"!=typeof n)throw new TypeError(`Test Scenarios for rule ${e} : Could not find test scenario object`);if(["valid","invalid"].forEach((e=>{n[e]||o.push(`Could not find any ${e} test scenarios`)})),o.length>0)throw new Error([`Test Scenarios for rule ${e} is invalid:`].concat(o).join("\n"));function a(n){let o,a,i,c,l,u=F.default.cloneDeep(r);if("string"==typeof n)o=n;else{o=n.code;const e=F.default.omit(n,$h);u=F.default.merge(u,e)}n.filename&&(a=n.filename),Gh(n,"options")?(z.default(Array.isArray(n.options),"options must be an array"),u.rules[e]=[1].concat(n.options)):u.rules[e]=1;const p=Dh(t);if(s.defineRule("rule-tester/validate-ast",(()=>({Program(e){c=zh(e)},"Program:exit"(e){l=e}}))),"string"==typeof u.parser?z.default(O.default.isAbsolute(u.parser),"Parsers provided as strings to RuleTester must be absolute paths"):u.parser=Rh,s.defineParser(u.parser,function(e){return"function"==typeof e.parseForESLint?{parseForESLint(...t){const n=e.parseForESLint(...t);return Hh(n.ast,n.visitorKeys),n}}:{parse(...t){const n=e.parse(...t);return Hh(n),n}}}(ce(u.parser))),p){if(Lh.validateSchema(p),Lh.errors){const t=Lh.errors.map((e=>`\t${"."===e.dataPath[0]?e.dataPath.slice(1):e.dataPath}: ${e.message}`)).join("\n");throw new Error([`Schema for rule ${e} is invalid:`,t])}try{Lh.compile(p)}catch(t){throw new Error(`Schema for rule ${e} is invalid: ${t.message}`)}}Oh(u,"rule-tester",(n=>n===e?t:null));const d=s.verify(o,u,a),f=d.find((e=>e.fatal));if(z.default(!f,`A fatal parsing error occurred: ${f&&f.message}`),d.some((e=>e.fix))){i=Nh.applyFixes(o,d).output;const e=s.verify(i,u,a).find((e=>e.fatal));z.default(!e,["A fatal parsing error occurred in autofix.",`Error: ${e&&e.message}`,"Autofix output:",i].join("\n"))}else i=o;return{messages:d,output:i,beforeAST:c,afterAST:zh(l)}}function i(e,t){F.default.isEqual(e,t)||z.default.fail("Rule should not modify AST.")}function c(e,t){t instanceof RegExp?z.default.ok(t.test(e),`Expected '${e}' to match ${t}`):z.default.strictEqual(e,t)}s.defineRule(e,Object.assign({},t,{create:e=>(Jh(e.options),Jh(e.settings),Jh(e.parserOptions),("function"==typeof t?t:t.create)(e))})),s.defineRules(this.rules),ty.describe(e,(()=>{ty.describe("valid",(()=>{n.valid.forEach((e=>{ty.it(Kh("object"==typeof e?e.code:e),(()=>{!function(e){const t=a(e),n=t.messages;z.default.strictEqual(n.length,0,V.default.format("Should have no errors but had %d: %s",n.length,V.default.inspect(n))),i(t.beforeAST,t.afterAST)}(e)}))}))})),ty.describe("invalid",(()=>{n.invalid.forEach((n=>{ty.it(Kh(n.code),(()=>{!function(n){z.default.ok(n.errors||0===n.errors,`Did not specify errors for an invalid test of ${e}`),Array.isArray(n.errors)&&0===n.errors.length&&z.default.fail("Invalid cases must have at least one error");const r=Gh(t,"meta")&&Gh(t.meta,"messages"),o=r?`[${Object.keys(t.meta.messages).map((e=>`'${e}'`)).join(", ")}]`:null,s=a(n),l=s.messages;if("number"==typeof n.errors)0===n.errors&&z.default.fail("Invalid cases must have 'error' value greater than 0"),z.default.strictEqual(l.length,n.errors,V.default.format("Should have %d error%s but had %d: %s",n.errors,1===n.errors?"":"s",l.length,V.default.inspect(l)));else{z.default.strictEqual(l.length,n.errors.length,V.default.format("Should have %d error%s but had %d: %s",n.errors.length,1===n.errors.length?"":"s",l.length,V.default.inspect(l)));const s=l.some((t=>t.ruleId===e));for(let e=0,a=n.errors.length;e{z.default.ok(qh.has(e),`Invalid error property name '${e}'. Expected one of ${Uh}.`)})),Gh(a,"message"))z.default.ok(!Gh(a,"messageId"),"Error should not specify both 'message' and a 'messageId'."),z.default.ok(!Gh(a,"data"),"Error should not specify both 'data' and 'message'."),c(i.message,a.message);else if(Gh(a,"messageId")&&(z.default.ok(r,"Error can not use 'messageId' if rule under test doesn't define 'meta.messages'."),Gh(t.meta.messages,a.messageId)||z.default(!1,`Invalid messageId '${a.messageId}'. Expected one of ${o}.`),z.default.strictEqual(i.messageId,a.messageId,`messageId '${i.messageId}' does not match expected messageId '${a.messageId}'.`),Gh(a,"data"))){const e=t.meta.messages[a.messageId],n=jh(e,a.data);z.default.strictEqual(i.message,n,`Hydrated message "${n}" does not match "${i.message}"`)}z.default.ok(!Gh(a,"data")||Gh(a,"messageId"),"Error must specify 'messageId' if 'data' is used."),a.type&&z.default.strictEqual(i.nodeType,a.type,`Error type should be ${a.type}, found ${i.nodeType}`),Gh(a,"line")&&z.default.strictEqual(i.line,a.line,`Error line should be ${a.line}`),Gh(a,"column")&&z.default.strictEqual(i.column,a.column,`Error column should be ${a.column}`),Gh(a,"endLine")&&z.default.strictEqual(i.endLine,a.endLine,`Error endLine should be ${a.endLine}`),Gh(a,"endColumn")&&z.default.strictEqual(i.endColumn,a.endColumn,`Error endColumn should be ${a.endColumn}`),Gh(a,"suggestions")&&(!a.suggestions||Array.isArray(a.suggestions)&&0===a.suggestions.length?Array.isArray(i.suggestions)&&i.suggestions.length>0&&z.default.fail(`Error should have no suggestions on error with message: "${i.message}"`):(z.default.strictEqual(Array.isArray(i.suggestions),!0,`Error should have an array of suggestions. Instead received "${i.suggestions}" on error with message: "${i.message}"`),z.default.strictEqual(i.suggestions.length,a.suggestions.length,`Error should have ${a.suggestions.length} suggestions. Instead found ${i.suggestions.length} suggestions`),a.suggestions.forEach(((e,s)=>{z.default.ok("object"==typeof e&&null!==e,"Test suggestion in 'suggestions' array must be an object."),Object.keys(e).forEach((e=>{z.default.ok(Vh.has(e),`Invalid suggestion property name '${e}'. Expected one of ${Wh}.`)}));const a=i.suggestions[s],c=`Error Suggestion at index ${s} :`;if(Gh(e,"desc")&&(z.default.ok(!Gh(e,"data"),`${c} Test should not specify both 'desc' and 'data'.`),z.default.strictEqual(a.desc,e.desc,`${c} desc should be "${e.desc}" but got "${a.desc}" instead.`)),Gh(e,"messageId")){if(z.default.ok(r,`${c} Test can not use 'messageId' if rule under test doesn't define 'meta.messages'.`),z.default.ok(Gh(t.meta.messages,e.messageId),`${c} Test has invalid messageId '${e.messageId}', the rule under test allows only one of ${o}.`),z.default.strictEqual(a.messageId,e.messageId,`${c} messageId should be '${e.messageId}' but got '${a.messageId}' instead.`),Gh(e,"data")){const n=t.meta.messages[e.messageId],r=jh(n,e.data);z.default.strictEqual(a.desc,r,`${c} Hydrated test desc "${r}" does not match received desc "${a.desc}".`)}}else z.default.ok(!Gh(e,"data"),`${c} Test must specify 'messageId' if 'data' is used.`);if(Gh(e,"output")){const t=Nh.applyFixes(n.code,[a]).output;z.default.strictEqual(t,e.output,`Expected the applied suggestion fix to match the test suggestion output for suggestion at index: ${s} on error with message: "${i.message}"`)}}))))}else z.default.fail(`Error should be a string, object, or RegExp, but found (${V.default.inspect(i)})`)}}Gh(n,"output")?null===n.output?z.default.strictEqual(s.output,n.code,"Expected no autofixes to be suggested"):z.default.strictEqual(s.output,n.output,"Output is incorrect."):z.default.strictEqual(s.output,n.code,"The rule fixed the code. Please add 'output' property."),s.output!==n.code&&z.default.ok(Gh(t,"meta"),"Fixable rules should export a `meta.fixable` property."),i(s.beforeAST,s.afterAST)}(n)}))}))}))}))}}ty[Xh]=ty[Qh]=null;var ny={RuleTester:ty},ry=ie((function(e){const{CLIEngine:t}=zg,{ESLint:n}=uh,{Linter:r}=dg,{RuleTester:o}=ny,{SourceCode:s}=mn;e.exports={Linter:r,CLIEngine:t,ESLint:n,RuleTester:o,SourceCode:s};let a=null;Object.defineProperty(e.exports,"linter",{enumerable:!1,get:()=>(a||(a=new r),a)})})),oy=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n,r=(n=Ze)&&n.__esModule?n:{default:n};const o=/^\s*([\s\S]*?)<\/caption>/u,s=(e,t)=>(e.match(new RegExp((e=>e.replace(/[.*+?^${}()|[\]\\]/gu,"\\$&"))(t),"gu"))||[]).length,a={"eol-last":0,"import/no-unresolved":0,"import/unambiguous":0,"jsdoc/require-file-overview":0,"jsdoc/require-jsdoc":0,"no-console":0,"no-multiple-empty-lines":0,"no-undef":0,"no-unused-vars":0,"node/no-missing-import":0,"node/no-missing-require":0,"padded-blocks":0},i={...a,"no-new":"off","no-unused-expressions":"off",quotes:["error","double"],semi:["error","never"],strict:"off"},c=e=>{const t=s(e,"\n");return[t,t?e.slice(e.lastIndexOf("\n")+1).length:e.length]};var l=(0,r.default)((({report:e,utils:t,context:n,globalState:r})=>{r.has("checkExamples-matchingFileName")||r.set("checkExamples-matchingFileName",new Map);const l=r.get("checkExamples-matchingFileName"),u=n.options[0]||{};let{exampleCodeRegex:p=null,rejectExampleCodeRegex:d=null}=u;const{checkDefaults:f=!1,checkParams:m=!1,checkProperties:g=!1,noDefaultExampleRules:h=!1,checkEslintrc:y=!0,matchingFileName:x=null,matchingFileNameDefaults:b=null,matchingFileNameParams:E=null,matchingFileNameProperties:S=null,paddedIndent:C=0,baseConfig:v={},configFile:A,allowInlineConfig:k=!0,reportUnusedDisableDirectives:w=!0,captionRequired:P=!1}=u,T=[],I=h?void 0:a,F=h?void 0:i;p&&(p=t.getRegexFromString(p)),d&&(d=t.getRegexFromString(d));const D=({filename:t,defaultFileName:n,rules:r=F,lines:o=0,cols:s=0,skipInit:a,source:i,targetTagName:c,sources:u=[],tag:p={line:0}})=>{a||u.push({nonJSPrefacingCols:s,nonJSPrefacingLines:o,string:i});u.forEach((function({nonJSPrefacingCols:o,nonJSPrefacingLines:s,string:a}){const i={allowInlineConfig:k,baseConfig:v,configFile:A,reportUnusedDisableDirectives:w,rulePaths:T,rules:r,useEslintrc:y},u=JSON.stringify(i),d=C?a.replace(new RegExp(`(^|\n) {${C}}(?!$)`,"gu"),"\n"):a,f=t?"a"+u+t:"b"+u+n,m=t||n;let g;if(l.has(f))g=l.get(f);else{const e=new ry.CLIEngine(i);let n;(t||y)&&(n=e.getConfigForFile(m)),g=new ry.CLIEngine({allowInlineConfig:k,baseConfig:{...v,...n},configFile:A,reportUnusedDisableDirectives:w,rulePaths:T,rules:r,useEslintrc:!1}),l.set(f,g)}const{results:[{messages:h}]}=g.executeOnText(d);"line"in p||(p.line=p.source[0].number);const x=p.line+s;h.forEach((({message:t,line:n,column:r,severity:s,ruleId:a})=>{e("@"+c+" "+(2===s?"error":"warning")+(a?" ("+a+")":"")+": "+t,null,{column:1+(n<=1?o+1:1)+r,line:x+n+-1})}))}))},O=(e,t="md/*.js")=>{let r;if(!e){const e=n.getFilename();r="string"==typeof e&&e.includes(".")?e.replace(/\..*?$/,`.${t}`):`dummy.${t}`}return{defaultFileName:r,filename:e}};if(f){const e=O(b,"jsdoc-defaults");t.forEachPreferredTag("default",((t,n)=>{t.description.trim()&&D({source:`(${t.description})`,targetTagName:n,...e})}))}if(m){const e=O(E,"jsdoc-params");t.forEachPreferredTag("param",((t,n)=>{t.default&&t.default.trim()&&D({source:`(${t.default})`,targetTagName:n,...e})}))}if(g){const e=O(S,"jsdoc-properties");t.forEachPreferredTag("property",((t,n)=>{t.default&&t.default.trim()&&D({source:`(${t.default})`,targetTagName:n,...e})}))}const B=t.getPreferredTagName({tagName:"example"});if(!t.hasTag(B))return;const N=O(x);t.forEachPreferredTag("example",((t,n)=>{let r=t.source[0].tokens.postTag.slice(1)+t.description;const a=r.match(o);!P||a&&a[1].trim()||e("Caption is expected for examples.",null,t),r=r.replace(o,"");const[i,l]=a?c(a[0]):[0,0];if(p&&!p.test(r)||d&&d.test(r))return;const u=[];let f=!1;if(p){let e,t=0,n=0,o=0,a=0;for(p.lastIndex=0;null!==(e=p.exec(r));){const{index:i,0:l,1:d}=e,f=r.slice(o,i),[m,g]=c(f);let h,y;if(d){const e=l.indexOf(d);h=l.slice(0,e),y=s(h,"\n")}else h="",y=0;if(n+=a+m+y,y){t+=h.slice(h.lastIndexOf("\n")+1).length}else t+=g+h.length;const x=d||l;if(u.push({nonJSPrefacingCols:t,nonJSPrefacingLines:n,string:x}),o=p.lastIndex,a=s(x,"\n"),!p.global)break}f=!0}D({cols:l,lines:i,rules:I,skipInit:f,source:r,sources:u,tag:t,targetTagName:n,...N})}))}),{iterateAllJsdocs:!0,meta:{docs:{description:"Ensures that (JavaScript) examples within JSDoc adhere to ESLint rules.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-examples"},schema:[{additionalProperties:!1,properties:{allowInlineConfig:{default:!0,type:"boolean"},baseConfig:{type:"object"},captionRequired:{default:!1,type:"boolean"},checkDefaults:{default:!1,type:"boolean"},checkEslintrc:{default:!0,type:"boolean"},checkParams:{default:!1,type:"boolean"},checkProperties:{default:!1,type:"boolean"},configFile:{type:"string"},exampleCodeRegex:{type:"string"},matchingFileName:{type:"string"},matchingFileNameDefaults:{type:"string"},matchingFileNameParams:{type:"string"},matchingFileNameProperties:{type:"string"},noDefaultExampleRules:{default:!1,type:"boolean"},paddedIndent:{default:0,type:"integer"},rejectExampleCodeRegex:{type:"string"},reportUnusedDisableDirectives:{default:!0,type:"boolean"}},type:"object"}],type:"suggestion"}});t.default=l,e.exports=t.default})),sy=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n,r=(n=Ze)&&n.__esModule?n:{default:n};var o=(0,r.default)((({sourceCode:e,jsdocNode:t,report:n,context:r})=>{const o=r.options[0]||{},{excludeTags:s=["example"]}=o,a=new RegExp(/^(?:\/?\**|[ \t]*)\*[ \t]{2}/gmu),i=e.getText(t).replace(/([ \t]+\*)[ \t]```[^\n]*?([\w|\W]*?\n)(?=[ \t]*\*(?:[ \t]*(?:```|@)|\/))/gu,((e,t,n)=>new Array(n.match(/\n/gu).length+1).join(t+"\n")));const c=s.length?((e,t)=>{const n=new RegExp(`([ \\t]+\\*)[ \\t]@(?:${t.join("|")})(?=[ \\n])([\\w|\\W]*?\\n)(?=[ \\t]*\\*(?:[ \\t]*@|\\/))`,"gu");return e.replace(n,((e,t,n)=>new Array(n.match(/\n/gu).length+1).join(t+"\n")))})(i,s):i;if(a.test(c)){n("There must be no indentation.",null,{line:(c.slice(0,a.lastIndex).match(/\n/gu)||[]).length})}}),{iterateAllJsdocs:!0,meta:{docs:{description:"Reports invalid padding inside JSDoc blocks.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-indentation"},schema:[{additionalProperties:!1,properties:{excludeTags:{items:{pattern:"^\\S+$",type:"string"},type:"array"}},type:"object"}],type:"layout"}});t.default=o,e.exports=t.default})),ay=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n,r=(n=Ze)&&n.__esModule?n:{default:n};const{flow:o,align:s,indent:a}=Je.transforms;var i=(0,r.default)((({indent:e,jsdoc:t,jsdocNode:n,report:r,context:i,utils:c})=>{const{tags:l=["param","arg","argument","property","prop","returns","return"]}=i.options[1]||{};if("always"===i.options[0]){if(!n.value.includes("\n"))return;return void(({indent:e,jsdoc:t,jsdocNode:n,report:r,utils:i})=>{const c=o(s(),a(e.length))(t),l="/*"+n.value+"*/",u=i.stringify(c).trimStart();l!==u&&r("Expected JSDoc block lines to be aligned.",(e=>e.replaceText(n,u)))})({indent:e,jsdoc:t,jsdocNode:n,report:r,utils:c})}c.getPresentTags(l).forEach((e=>{((e,t)=>{let n,r;e.tagMightHaveNamepath(t.tag)?(n=["postDelimiter","postTag","postType","postName"],r=["tag","type","name","description"]):(n=["postDelimiter","postTag","postType"],r=["tag","type","description"]);const{tokens:o}=t.source[0],s=(e,t)=>{const s=e+1;return n.slice(s).some(((e,n)=>{const a=r[s+n],i=o[e];return t&&t(!i,a),i}))};if(!n.some(((e,t)=>{const n=r[t],a=o[n],i=o[e];return i.length>1||i&&!a&&s(t)})))return;e.reportJSDoc("Expected JSDoc block lines to not be aligned.",t,(()=>{n.forEach(((e,t)=>{const n=r[t];o[n]?(o[e]=" ",s(t,((e,t)=>{e&&(o[t]="")}))):o[e]=""})),e.setTag(t,o)}),!0)})(c,e)}))}),{iterateAllJsdocs:!0,meta:{docs:{description:"Reports invalid alignment of JSDoc block lines.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-line-alignment"},fixable:"whitespace",schema:[{enum:["always","never"],type:"string"},{additionalProperties:!1,properties:{tags:{items:{type:"string"},type:"array"}},type:"object"}],type:"layout"}});t.default=i,e.exports=t.default})),iy=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n,r=(n=Ze)&&n.__esModule?n:{default:n};var o=(0,r.default)((({context:e,jsdoc:t,jsdocNode:n,report:r,utils:o})=>{const{allowExtraTrailingParamDocs:s,checkDestructured:a=!0,checkRestProperty:i=!1,checkTypesPattern:c="/^(?:[oO]bject|[aA]rray|PlainObject|Generic(?:Object|Array))$/",enableFixer:l=!1,useDefaultObjectProperties:u=!1,disableExtraPropertyReporting:p=!1}=e.options[0]||{},d=o.getRegexFromString(c),f=o.getJsdocTagsDeep("param");if(!f.length)return;const m=o.getFunctionParameterNames(u),g=o.getPreferredTagName({tagName:"param"});!((e,t,n,r,o,s,a,i,c,l,u,p)=>{const d=Object.entries(c.tags).filter((([,t])=>t.tag===e)),f=d.filter((([,e])=>!e.name.includes(".")));let m=0;return d.some((([,c],l)=>{let g;const h=d.find((([e,t],n)=>(g=e,t.name===c.name&&n!==l)));if(h)return u.reportJSDoc(`Duplicate @${e} "${c.name}"`,h[1],a?()=>{u.removeTag(g)}:null),!0;if(c.name.includes("."))return m++,!1;const y=i[l-m];if(!y)return!t&&(p(`@${e} "${c.name}" does not match an existing function parameter.`,null,c),!0);if(Array.isArray(y)){if(!n)return!1;if(c.type&&-1===c.type.search(o))return!1;const[t,{names:a,hasPropertyRest:i,rests:l,annotationParamName:f}]=y;if(void 0!==f){const t=c.name.trim();t!==f&&p(`@${e} "${t}" does not match parameter name "${f}"`,null,c)}const m=void 0===t?c.name.trim():t,g=a.map((e=>`${m}.${e}`)),h=d.map((([,e])=>e.name.trim())),x=d.map((([,e])=>e.type)),b=[],E=[];g.forEach(((e,t)=>{if(E.some((t=>e.startsWith(t))))return;const n=h.findIndex((t=>u.comparePaths(e)(t)));if(-1===n){if(!r&&l[t])return;b.push(e)}else-1===x[n].search(o)&&""!==x[n]&&E.push(e)}));const S=b.length;if(S&&b.forEach((t=>{p(`Missing @${e} "${t}"`,null,c)})),!i||r){const t=[];if(h.forEach(((e,n)=>{!e.startsWith(c.name.trim()+".")||g.some(u.comparePaths(e))||u.comparePaths(e)(c.name)||s&&!a.some((t=>t.split(".").length>=e.split(".").length-1))||t.push([e,d[n][1]])})),t.length)return t.forEach((([t,n])=>{p(`@${e} "${t}" does not exist on ${c.name}`,null,n)})),!0}return S}let x;if("object"==typeof y){const{name:e}=y;x=e}else x=y;if(x!==c.name.trim()){const t=f.map((([,{name:e}])=>e.trim())),n=i.map(((e,n)=>{var r;return null!=e&&null!==(r=e[1])&&void 0!==r&&r.names?t[n]:e})).join(", ");return p(`Expected @${e} names to be "${n}". Got "${t.join(", ")}".`,null,c),!0}return!1}))})(g,s,a,i,d,p,l,m,t,0,o,r)&&a&&((e,t,n,r,o)=>{let s;n.some((({name:t,idx:n})=>{if(t.includes(".")){if(!s)return o(`@${e} path declaration ("${t}") appears before any real parameter.`,null,r.tags[n]),!0;let a=t.slice(0,t.indexOf("."));if(a.endsWith("[]")&&(a=a.slice(0,-2)),a!==s)return o(`@${e} path declaration ("${t}") root node name ("${a}") does not match previous real parameter name ("${s}").`,null,r.tags[n]),!0}else s=t;return!1}))})(g,0,f,t,r)}),{meta:{docs:{description:"Ensures that parameter names in JSDoc match those in the function declaration.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-param-names"},fixable:"code",schema:[{additionalProperties:!1,properties:{allowExtraTrailingParamDocs:{type:"boolean"},checkDestructured:{type:"boolean"},checkRestProperty:{type:"boolean"},checkTypesPattern:{type:"string"},disableExtraPropertyReporting:{type:"boolean"},enableFixer:{type:"boolean"},useDefaultObjectProperties:{type:"boolean"}},type:"object"}],type:"suggestion"}});t.default=o,e.exports=t.default})),cy=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n,r=(n=Ze)&&n.__esModule?n:{default:n};var o=(0,r.default)((({context:e,jsdoc:t,jsdocNode:n,report:r,utils:o})=>{const{enableFixer:s=!1}=e.options[0]||{},a=o.getJsdocTagsDeep("property");if(!a.length)return;const i=o.getPreferredTagName({tagName:"property"});((e,t,n,r,o)=>{const s=Object.entries(n.tags).filter((([,t])=>t.tag===e));return s.some((([,n],r)=>{let a;const i=s.find((([e,t],o)=>(a=e,t.name===n.name&&o!==r)));return!!i&&(o.reportJSDoc(`Duplicate @${e} "${n.name}"`,i[1],t?()=>{o.removeTag(a)}:null),!0)}))})(i,s,t,0,o)||((e,t,n,r)=>{let o;t.some((({name:t,idx:s})=>{if(t.includes(".")){if(!o)return r(`@${e} path declaration ("${t}") appears before any real property.`,null,n.tags[s]),!0;let a=t.slice(0,t.indexOf("."));if(a.endsWith("[]")&&(a=a.slice(0,-2)),a!==o)return r(`@${e} path declaration ("${t}") root node name ("${a}") does not match previous real property name ("${o}").`,null,n.tags[s]),!0}else o=t;return!1}))})(i,a,t,r)}),{iterateAllJsdocs:!0,meta:{docs:{description:"Ensures that property names in JSDoc are not duplicated on the same block and that nested properties have defined roots.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-property-names"},fixable:"code",schema:[{additionalProperties:!1,properties:{enableFixer:{type:"boolean"}},type:"object"}],type:"suggestion"}});t.default=o,e.exports=t.default})),ly=ie((function(e,t){var n;Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=(0,((n=Ze)&&n.__esModule?n:{default:n}).default)((({jsdoc:e,report:t,settings:n})=>{const{mode:r}=n;if("jsdoc"===r||"typescript"===r)for(const n of e.tags)if("="===n.type.slice(-1)){t("Syntax should not be Google Closure Compiler style.",null,n);break}}),{iterateAllJsdocs:!0,meta:{docs:{description:"Reports against syntax not valid for the mode (e.g., Google Closure Compiler in non-Closure mode).",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-syntax"},type:"suggestion"}});t.default=r,e.exports=t.default})),uy=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=o(F.default),r=o(Ze);function o(e){return e&&e.__esModule?e:{default:e}}const s=new Set(["jsx","jsxFrag","jsxImportSource","jsxRuntime"]);var a=(0,r.default)((({sourceCode:e,jsdoc:t,report:r,utils:o,context:a,settings:i,jsdocNode:c})=>{const{definedTags:l=[],jsxTags:u}=a.options[0]||{};let p=[];const{tagNamePreference:d,structuredTags:f}=i,m=Object.keys(f),g=Object.keys(d);g.length&&(p=Object.values(d).map((e=>"string"==typeof e?e:e?("object"!=typeof e&&o.reportSettings("Invalid `settings.jsdoc.tagNamePreference`. Values must be falsy, a string, or an object."),e.replacement):void 0)).filter((e=>e))),t.tags.forEach((t=>{const a=t.tag;if(!u||!s.has(a))if(o.isValidTag(a,[...l,...p,...g,...m])){let s,i=o.getPreferredTagName({allowObjectReturn:!0,defaultMessage:`Blacklisted tag found (\`@${a}\`)`,tagName:a});if(!i)return;"object"==typeof i&&({message:s,replacement:i}=i),s||(s=`Invalid JSDoc tag (preference). Replace "${a}" JSDoc tag with "${i}".`),i!==a&&r(s,(t=>{const r=e.getText(c).replace(new RegExp(`@${n.default.escapeRegExp(a)}\\b`,"u"),`@${i}`);return t.replaceText(c,r)}),t)}else r(`Invalid JSDoc tag name "${a}".`,null,t)}))}),{iterateAllJsdocs:!0,meta:{docs:{description:"Reports invalid block tag names.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-tag-names"},fixable:"code",schema:[{additionalProperties:!1,properties:{definedTags:{items:{type:"string"},type:"array"},jsxTags:{type:"boolean"}},type:"object"}],type:"suggestion"}});t.default=a,e.exports=t.default}));var py={GenericTypeSyntax:{ANGLE_BRACKET:"ANGLE_BRACKET",ANGLE_BRACKET_WITH_DOT:"ANGLE_BRACKET_WITH_DOT",SQUARE_BRACKET:"SQUARE_BRACKET"},VariadicTypeSyntax:{PREFIX_DOTS:"PREFIX_DOTS",SUFFIX_DOTS:"SUFFIX_DOTS",ONLY_DOTS:"ONLY_DOTS"},OptionalTypeSyntax:{PREFIX_EQUALS_SIGN:"PREFIX_EQUALS_SIGN",SUFFIX_EQUALS_SIGN:"SUFFIX_EQUALS_SIGN",SUFFIX_KEY_QUESTION_MARK:"SUFFIX_KEY_QUESTION_MARK"},NullableTypeSyntax:{PREFIX_QUESTION_MARK:"PREFIX_QUESTION_MARK",SUFFIX_QUESTION_MARK:"SUFFIX_QUESTION_MARK"},NotNullableTypeSyntax:{PREFIX_BANG:"PREFIX_BANG",SUFFIX_BANG:"SUFFIX_BANG"}};var dy={NAME:"NAME",MEMBER:"MEMBER",UNION:"UNION",INTERSECTION:"INTERSECTION",VARIADIC:"VARIADIC",RECORD:"RECORD",RECORD_ENTRY:"RECORD_ENTRY",TUPLE:"TUPLE",GENERIC:"GENERIC",MODULE:"MODULE",OPTIONAL:"OPTIONAL",NULLABLE:"NULLABLE",NOT_NULLABLE:"NOT_NULLABLE",FUNCTION:"FUNCTION",ARROW:"ARROW",NAMED_PARAMETER:"NAMED_PARAMETER",ANY:"ANY",UNKNOWN:"UNKNOWN",INNER_MEMBER:"INNER_MEMBER",INSTANCE_MEMBER:"INSTANCE_MEMBER",STRING_VALUE:"STRING_VALUE",NUMBER_VALUE:"NUMBER_VALUE",EXTERNAL:"EXTERNAL",FILE_PATH:"FILE_PATH",PARENTHESIS:"PARENTHESIS",TYPE_QUERY:"TYPE_QUERY",KEY_QUERY:"KEY_QUERY",IMPORT:"IMPORT"};function fy(e,t,n,r){this.message=e,this.expected=t,this.found=n,this.location=r,this.name="SyntaxError","function"==typeof Error.captureStackTrace&&Error.captureStackTrace(this,fy)}!function(e,t){function n(){this.constructor=e}n.prototype=t.prototype,e.prototype=new n}(fy,Error),fy.buildMessage=function(e,t){var n={literal:function(e){return'"'+o(e.text)+'"'},class:function(e){var t,n="";for(t=0;t0){for(t=1,r=1;t",!1),Oe=et("[",!1),Be=et("]",!1),Ne="new",je=et("new",!1),Le=et("=>",!1),Re="...",Me=et("...",!1),_e="function",$e=et("function",!1),qe="this",Ue=et("this",!1),Ve=et("{",!1),We=et("}",!1),Ge=";",ze=et(";",!1),Je="readonly",Ke=et("readonly",!1),Ye=0,He=[{line:1,column:1}],Xe=0,Qe=[],Ze={};if("startRule"in t){if(!(t.startRule in o))throw new Error("Can't start parsing from rule \""+t.startRule+'".');s=o[t.startRule]}function et(e,t){return{type:"literal",text:e,ignoreCase:t}}function tt(e,t,n){return{type:"class",parts:e,inverted:t,ignoreCase:n}}function nt(t){var n,r=He[t];if(r)return r;for(n=t-1;!He[n];)n--;for(r={line:(r=He[n]).line,column:r.column};nXe&&(Xe=Ye,Qe=[]),Qe.push(e))}function st(){var e,t,n=82*Ye+0,o=Ze[n];return o?(Ye=o.nextPos,o.result):(e=Ye,it()!==r?((t=Ht())===r&&(t=kt())===r&&(t=vt())===r&&(t=Pt())===r&&(t=Rt())===r&&(t=jt())===r&&(t=Wt())===r&&(t=Jt())===r&&(t=Mt())===r&&(t=_t())===r&&(t=Ft())===r&&(t=Dt())===r&&(t=gt())===r&&(t=Yt())===r&&(t=Et())===r&&(t=xt())===r&&(t=bt()),t!==r&&it()!==r?e=t:(Ye=e,e=r)):(Ye=e,e=r),Ze[n]={nextPos:Ye,result:e},e)}function at(){var t,n,o,s=82*Ye+1,d=Ze[s];return d?(Ye=d.nextPos,d.result):(a.test(e.charAt(Ye))?(t=e.charAt(Ye),Ye++):(t=r,ot(i)),t===r&&(t=Ye,c.test(e.charAt(Ye))?(n=e.charAt(Ye),Ye++):(n=r,ot(l)),n===r&&(n=null),n!==r?(u.test(e.charAt(Ye))?(o=e.charAt(Ye),Ye++):(o=r,ot(p)),o!==r?t=n=[n,o]:(Ye=t,t=r)):(Ye=t,t=r)),Ze[s]={nextPos:Ye,result:t},t)}function it(){var e,t,n=82*Ye+2,o=Ze[n];if(o)return Ye=o.nextPos,o.result;for(e=[],t=at();t!==r;)e.push(t),t=at();return Ze[n]={nextPos:Ye,result:e},e}function ct(){var e,t,n=82*Ye+3,o=Ze[n];if(o)return Ye=o.nextPos,o.result;if(e=[],(t=at())!==r)for(;t!==r;)e.push(t),t=at();else e=r;return Ze[n]={nextPos:Ye,result:e},e}function lt(){var t,n,o,s,a,i=82*Ye+4,c=Ze[i];if(c)return Ye=c.nextPos,c.result;if(t=Ye,n=Ye,d.test(e.charAt(Ye))?(o=e.charAt(Ye),Ye++):(o=r,ot(f)),o!==r){for(s=[],m.test(e.charAt(Ye))?(a=e.charAt(Ye),Ye++):(a=r,ot(g));a!==r;)s.push(a),m.test(e.charAt(Ye))?(a=e.charAt(Ye),Ye++):(a=r,ot(g));s!==r?n=o=[o,s]:(Ye=n,n=r)}else Ye=n,n=r;return t=n!==r?e.substring(t,Ye):n,Ze[i]={nextPos:Ye,result:t},t}function ut(){var t,n,o,s,a,i,c,l,u,p,d,f=82*Ye+5,m=Ze[f];if(m)return Ye=m.nextPos,m.result;if(t=Ye,(n=Yt())===r&&(n=function(){var t,n,o,s,a,i=82*Ye+38,c=Ze[i];if(c)return Ye=c.nextPos,c.result;t=Ye,e.substr(Ye,6)===ye?(n=ye,Ye+=6):(n=r,ot(xe));n!==r&&it()!==r?(40===e.charCodeAt(Ye)?(o=be,Ye++):(o=r,ot(Ee)),o!==r&&it()!==r&&(s=St())!==r&&it()!==r?(41===e.charCodeAt(Ye)?(a=Se,Ye++):(a=r,ot(Ce)),a!==r?t=n=function(e,t){return{type:on.IMPORT,path:t}}(0,s):(Ye=t,t=r)):(Ye=t,t=r)):(Ye=t,t=r);return Ze[i]={nextPos:Ye,result:t},t}())===r&&(n=pt()),n!==r){for(o=[],s=Ye,(a=it())!==r&&(i=ft())!==r&&(c=it())!==r?(e.substr(Ye,6)===h?(l=h,Ye+=6):(l=r,ot(y)),l===r&&(l=null),l!==r&&(u=it())!==r&&(p=dt())!==r?s=a=[a,i,c,l,u,p]:(Ye=s,s=r)):(Ye=s,s=r);s!==r;)o.push(s),s=Ye,(a=it())!==r&&(i=ft())!==r&&(c=it())!==r?(e.substr(Ye,6)===h?(l=h,Ye+=6):(l=r,ot(y)),l===r&&(l=null),l!==r&&(u=it())!==r&&(p=dt())!==r?s=a=[a,i,c,l,u,p]:(Ye=s,s=r)):(Ye=s,s=r);o!==r?(d=n,t=n=o.reduce((function(e,t){const n=t[1],r=t[3],o=t[5],{quoteStyle:s,name:a}=o;switch(n){case sn.MEMBER:return{type:on.MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};case sn.INSTANCE_MEMBER:return{type:on.INSTANCE_MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};case sn.INNER_MEMBER:return{type:on.INNER_MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};default:throw new Error('Unexpected operator type: "'+n+'"')}}),d)):(Ye=t,t=r)}else Ye=t,t=r;return Ze[f]={nextPos:Ye,result:t},t}function pt(){var t,n,o,s,a,i,c=82*Ye+6,l=Ze[c];if(l)return Ye=l.nextPos,l.result;if(Ye,n=Ye,o=Ye,d.test(e.charAt(Ye))?(s=e.charAt(Ye),Ye++):(s=r,ot(f)),s!==r){for(a=[],x.test(e.charAt(Ye))?(i=e.charAt(Ye),Ye++):(i=r,ot(b));i!==r;)a.push(i),x.test(e.charAt(Ye))?(i=e.charAt(Ye),Ye++):(i=r,ot(b));a!==r?o=s=[s,a]:(Ye=o,o=r)}else Ye=o,o=r;return(n=o!==r?e.substring(n,Ye):o)!==r&&(n=function(e){return{type:on.NAME,name:e}}(n)),t=n,Ze[c]={nextPos:Ye,result:t},t}function dt(){var t,n,o,s,a,i,c,l=82*Ye+7,u=Ze[l];if(u)return Ye=u.nextPos,u.result;if(t=Ye,39===e.charCodeAt(Ye)?(n=E,Ye++):(n=r,ot(S)),n!==r){for(o=Ye,s=[],C.test(e.charAt(Ye))?(a=e.charAt(Ye),Ye++):(a=r,ot(v)),a===r&&(a=Ye,92===e.charCodeAt(Ye)?(i=A,Ye++):(i=r,ot(k)),i!==r?(e.length>Ye?(c=e.charAt(Ye),Ye++):(c=r,ot(w)),c!==r?a=i=[i,c]:(Ye=a,a=r)):(Ye=a,a=r));a!==r;)s.push(a),C.test(e.charAt(Ye))?(a=e.charAt(Ye),Ye++):(a=r,ot(v)),a===r&&(a=Ye,92===e.charCodeAt(Ye)?(i=A,Ye++):(i=r,ot(k)),i!==r?(e.length>Ye?(c=e.charAt(Ye),Ye++):(c=r,ot(w)),c!==r?a=i=[i,c]:(Ye=a,a=r)):(Ye=a,a=r));(o=s!==r?e.substring(o,Ye):s)!==r?(39===e.charCodeAt(Ye)?(s=E,Ye++):(s=r,ot(S)),s!==r?t=n=function(e){return{quoteStyle:"single",name:e.replace(/\\'/g,"'").replace(/\\\\/gu,"\\")}}(o):(Ye=t,t=r)):(Ye=t,t=r)}else Ye=t,t=r;if(t===r){if(t=Ye,34===e.charCodeAt(Ye)?(n=P,Ye++):(n=r,ot(T)),n!==r){for(o=Ye,s=[],I.test(e.charAt(Ye))?(a=e.charAt(Ye),Ye++):(a=r,ot(F)),a===r&&(a=Ye,92===e.charCodeAt(Ye)?(i=A,Ye++):(i=r,ot(k)),i!==r?(e.length>Ye?(c=e.charAt(Ye),Ye++):(c=r,ot(w)),c!==r?a=i=[i,c]:(Ye=a,a=r)):(Ye=a,a=r));a!==r;)s.push(a),I.test(e.charAt(Ye))?(a=e.charAt(Ye),Ye++):(a=r,ot(F)),a===r&&(a=Ye,92===e.charCodeAt(Ye)?(i=A,Ye++):(i=r,ot(k)),i!==r?(e.length>Ye?(c=e.charAt(Ye),Ye++):(c=r,ot(w)),c!==r?a=i=[i,c]:(Ye=a,a=r)):(Ye=a,a=r));(o=s!==r?e.substring(o,Ye):s)!==r?(34===e.charCodeAt(Ye)?(s=P,Ye++):(s=r,ot(T)),s!==r?t=n=function(e){return{quoteStyle:"double",name:e.replace(/\\"/gu,'"').replace(/\\\\/gu,"\\")}}(o):(Ye=t,t=r)):(Ye=t,t=r)}else Ye=t,t=r;t===r&&(t=Ye,(n=lt())!==r&&(n=function(e){return{quoteStyle:"none",name:e}}(n)),t=n)}return Ze[l]={nextPos:Ye,result:t},t}function ft(){var t,n=82*Ye+8,o=Ze[n];return o?(Ye=o.nextPos,o.result):((t=function(){var t,n,o=82*Ye+10,s=Ze[o];if(s)return Ye=s.nextPos,s.result;t=Ye,46===e.charCodeAt(Ye)?(n=D,Ye++):(n=r,ot(O));n!==r&&(n=sn.MEMBER);return t=n,Ze[o]={nextPos:Ye,result:t},t}())===r&&(t=function(){var t,n,o=82*Ye+12,s=Ze[o];if(s)return Ye=s.nextPos,s.result;t=Ye,35===e.charCodeAt(Ye)?(n="#",Ye++):(n=r,ot(N));n!==r&&(n=sn.INSTANCE_MEMBER);return t=n,Ze[o]={nextPos:Ye,result:t},t}())===r&&(t=function(){var t,n,o=82*Ye+11,s=Ze[o];if(s)return Ye=s.nextPos,s.result;t=Ye,126===e.charCodeAt(Ye)?(n="~",Ye++):(n=r,ot(B));n!==r&&(n=sn.INNER_MEMBER);return t=n,Ze[o]={nextPos:Ye,result:t},t}()),Ze[n]={nextPos:Ye,result:t},t)}function mt(){var t,n,o,s,a,i,c,l,u,p=82*Ye+9,d=Ze[p];if(d)return Ye=d.nextPos,d.result;if(t=Ye,(n=pt())!==r){for(o=[],s=Ye,(a=it())!==r?(46===e.charCodeAt(Ye)?(i=D,Ye++):(i=r,ot(O)),i!==r&&(c=it())!==r&&(l=pt())!==r?s=a=[a,i,c,l]:(Ye=s,s=r)):(Ye=s,s=r);s!==r;)o.push(s),s=Ye,(a=it())!==r?(46===e.charCodeAt(Ye)?(i=D,Ye++):(i=r,ot(O)),i!==r&&(c=it())!==r&&(l=pt())!==r?s=a=[a,i,c,l]:(Ye=s,s=r)):(Ye=s,s=r);o!==r?(u=n,t=n=o.reduce((function(e,t){return{type:on.MEMBER,owner:e,name:t[3]}}),u)):(Ye=t,t=r)}else Ye=t,t=r;return Ze[p]={nextPos:Ye,result:t},t}function gt(){var e,t=82*Ye+13,n=Ze[t];return n?(Ye=n.nextPos,n.result):((e=ht())===r&&(e=yt())===r&&(e=ut()),Ze[t]={nextPos:Ye,result:e},e)}function ht(){var t,n,o,s,a,i,c,l,u,p,d,f,m,g=82*Ye+14,x=Ze[g];if(x)return Ye=x.nextPos,x.result;if(t=Ye,e.substr(Ye,8)===j?(n=j,Ye+=8):(n=r,ot(L)),n!==r)if(it()!==r)if(58===e.charCodeAt(Ye)?(o=R,Ye++):(o=r,ot(M)),o!==r)if(it()!==r)if((s=dt())!==r){for(a=[],i=Ye,(c=it())!==r&&(l=ft())!==r&&(u=it())!==r?(e.substr(Ye,6)===h?(p=h,Ye+=6):(p=r,ot(y)),p===r&&(p=null),p!==r&&(d=it())!==r&&(f=dt())!==r?i=c=[c,l,u,p,d,f]:(Ye=i,i=r)):(Ye=i,i=r);i!==r;)a.push(i),i=Ye,(c=it())!==r&&(l=ft())!==r&&(u=it())!==r?(e.substr(Ye,6)===h?(p=h,Ye+=6):(p=r,ot(y)),p===r&&(p=null),p!==r&&(d=it())!==r&&(f=dt())!==r?i=c=[c,l,u,p,d,f]:(Ye=i,i=r)):(Ye=i,i=r);a!==r?(m=s,t=n=a.reduce((function(e,t){const n=t[1],r=t[3],o=t[5],{quoteStyle:s,name:a}=o;switch(n){case sn.MEMBER:return{type:on.MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};case sn.INSTANCE_MEMBER:return{type:on.INSTANCE_MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};case sn.INNER_MEMBER:return{type:on.INNER_MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};default:throw new Error('Unexpected operator type: "'+n+'"')}}),Object.assign({type:on.EXTERNAL},m))):(Ye=t,t=r)}else Ye=t,t=r;else Ye=t,t=r;else Ye=t,t=r;else Ye=t,t=r;else Ye=t,t=r;return Ze[g]={nextPos:Ye,result:t},t}function yt(){var t,n,o,s,a,i=82*Ye+15,c=Ze[i];return c?(Ye=c.nextPos,c.result):(t=Ye,e.substr(Ye,6)===_?(n=_,Ye+=6):(n=r,ot($)),n!==r&&it()!==r?(58===e.charCodeAt(Ye)?(o=R,Ye++):(o=r,ot(M)),o!==r&&it()!==r&&(s=function(){var t,n,o,s,a,i,c,l,u,p,d=82*Ye+16,f=Ze[d];if(f)return Ye=f.nextPos,f.result;if(t=Ye,(n=function(){var t,n,o,s,a,i,c,l=82*Ye+17,u=Ze[l];if(u)return Ye=u.nextPos,u.result;t=Ye,39===e.charCodeAt(Ye)?(n=E,Ye++):(n=r,ot(S));if(n!==r){for(o=Ye,s=[],C.test(e.charAt(Ye))?(a=e.charAt(Ye),Ye++):(a=r,ot(v)),a===r&&(a=Ye,92===e.charCodeAt(Ye)?(i=A,Ye++):(i=r,ot(k)),i!==r?(e.length>Ye?(c=e.charAt(Ye),Ye++):(c=r,ot(w)),c!==r?a=i=[i,c]:(Ye=a,a=r)):(Ye=a,a=r));a!==r;)s.push(a),C.test(e.charAt(Ye))?(a=e.charAt(Ye),Ye++):(a=r,ot(v)),a===r&&(a=Ye,92===e.charCodeAt(Ye)?(i=A,Ye++):(i=r,ot(k)),i!==r?(e.length>Ye?(c=e.charAt(Ye),Ye++):(c=r,ot(w)),c!==r?a=i=[i,c]:(Ye=a,a=r)):(Ye=a,a=r));(o=s!==r?e.substring(o,Ye):s)!==r?(39===e.charCodeAt(Ye)?(s=E,Ye++):(s=r,ot(S)),s!==r?t=n=function(e){return{quoteStyle:"single",type:on.FILE_PATH,path:e.replace(/\\'/g,"'").replace(/\\\\/gu,"\\")}}(o):(Ye=t,t=r)):(Ye=t,t=r)}else Ye=t,t=r;if(t===r){if(t=Ye,34===e.charCodeAt(Ye)?(n=P,Ye++):(n=r,ot(T)),n!==r){for(o=Ye,s=[],I.test(e.charAt(Ye))?(a=e.charAt(Ye),Ye++):(a=r,ot(F)),a===r&&(a=Ye,92===e.charCodeAt(Ye)?(i=A,Ye++):(i=r,ot(k)),i!==r?(e.length>Ye?(c=e.charAt(Ye),Ye++):(c=r,ot(w)),c!==r?a=i=[i,c]:(Ye=a,a=r)):(Ye=a,a=r));a!==r;)s.push(a),I.test(e.charAt(Ye))?(a=e.charAt(Ye),Ye++):(a=r,ot(F)),a===r&&(a=Ye,92===e.charCodeAt(Ye)?(i=A,Ye++):(i=r,ot(k)),i!==r?(e.length>Ye?(c=e.charAt(Ye),Ye++):(c=r,ot(w)),c!==r?a=i=[i,c]:(Ye=a,a=r)):(Ye=a,a=r));(o=s!==r?e.substring(o,Ye):s)!==r?(34===e.charCodeAt(Ye)?(s=P,Ye++):(s=r,ot(T)),s!==r?t=n=function(e){return{quoteStyle:"double",type:on.FILE_PATH,path:e.replace(/\\"/gu,'"').replace(/\\\\/gu,"\\")}}(o):(Ye=t,t=r)):(Ye=t,t=r)}else Ye=t,t=r;if(t===r){if(t=Ye,n=Ye,o=[],q.test(e.charAt(Ye))?(s=e.charAt(Ye),Ye++):(s=r,ot(U)),s!==r)for(;s!==r;)o.push(s),q.test(e.charAt(Ye))?(s=e.charAt(Ye),Ye++):(s=r,ot(U));else o=r;(n=o!==r?e.substring(n,Ye):o)!==r&&(n=function(e){return{quoteStyle:"none",type:on.FILE_PATH,path:e}}(n)),t=n}}return Ze[l]={nextPos:Ye,result:t},t}())!==r){for(o=[],s=Ye,(a=it())!==r&&(i=ft())!==r&&(c=it())!==r?(e.substr(Ye,6)===h?(l=h,Ye+=6):(l=r,ot(y)),l===r&&(l=null),l!==r&&(u=it())!==r&&(p=dt())!==r?s=a=[a,i,c,l,u,p]:(Ye=s,s=r)):(Ye=s,s=r);s!==r;)o.push(s),s=Ye,(a=it())!==r&&(i=ft())!==r&&(c=it())!==r?(e.substr(Ye,6)===h?(l=h,Ye+=6):(l=r,ot(y)),l===r&&(l=null),l!==r&&(u=it())!==r&&(p=dt())!==r?s=a=[a,i,c,l,u,p]:(Ye=s,s=r)):(Ye=s,s=r);o!==r?(m=n,t=n=o.reduce((function(e,t){const n=t[1],r=t[3],o=t[5],{quoteStyle:s,name:a}=o;switch(n){case sn.MEMBER:return{type:on.MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};case sn.INSTANCE_MEMBER:return{type:on.INSTANCE_MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};case sn.INNER_MEMBER:return{type:on.INNER_MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};default:throw new Error('Unexpected operator type: "'+n+'"')}}),m)):(Ye=t,t=r)}else Ye=t,t=r;var m;return Ze[d]={nextPos:Ye,result:t},t}())!==r?(a=s,t=n={type:on.MODULE,value:a}):(Ye=t,t=r)):(Ye=t,t=r),Ze[i]={nextPos:Ye,result:t},t)}function xt(){var t,n,o=82*Ye+18,s=Ze[o];return s?(Ye=s.nextPos,s.result):(Ye,42===e.charCodeAt(Ye)?(n="*",Ye++):(n=r,ot(V)),n!==r&&(n={type:on.ANY}),t=n,Ze[o]={nextPos:Ye,result:t},t)}function bt(){var t,n,o=82*Ye+19,s=Ze[o];return s?(Ye=s.nextPos,s.result):(Ye,63===e.charCodeAt(Ye)?(n=W,Ye++):(n=r,ot(G)),n!==r&&(n={type:on.UNKNOWN}),t=n,Ze[o]={nextPos:Ye,result:t},t)}function Et(){var t,n=82*Ye+20,o=Ze[n];return o?(Ye=o.nextPos,o.result):((t=St())===r&&(t=function(){var t,n,o=82*Ye+22,s=Ze[o];if(s)return Ye=s.nextPos,s.result;t=Ye,(n=function(){var t,n,o,s,a,i,c=82*Ye+25,l=Ze[c];if(l)return Ye=l.nextPos,l.result;t=Ye,n=Ye,45===e.charCodeAt(Ye)?(o=J,Ye++):(o=r,ot(K));o===r&&(o=null);if(o!==r)if(e.substr(Ye,2)===Q?(s=Q,Ye+=2):(s=r,ot(Z)),s!==r){if(a=[],ee.test(e.charAt(Ye))?(i=e.charAt(Ye),Ye++):(i=r,ot(te)),i!==r)for(;i!==r;)a.push(i),ee.test(e.charAt(Ye))?(i=e.charAt(Ye),Ye++):(i=r,ot(te));else a=r;a!==r?n=o=[o,s,a]:(Ye=n,n=r)}else Ye=n,n=r;else Ye=n,n=r;t=n!==r?e.substring(t,Ye):n;return Ze[c]={nextPos:Ye,result:t},t}())===r&&(n=function(){var t,n,o,s,a,i,c=82*Ye+26,l=Ze[c];if(l)return Ye=l.nextPos,l.result;t=Ye,n=Ye,45===e.charCodeAt(Ye)?(o=J,Ye++):(o=r,ot(K));o===r&&(o=null);if(o!==r)if(e.substr(Ye,2)===ne?(s=ne,Ye+=2):(s=r,ot(re)),s!==r){if(a=[],oe.test(e.charAt(Ye))?(i=e.charAt(Ye),Ye++):(i=r,ot(se)),i!==r)for(;i!==r;)a.push(i),oe.test(e.charAt(Ye))?(i=e.charAt(Ye),Ye++):(i=r,ot(se));else a=r;a!==r?n=o=[o,s,a]:(Ye=n,n=r)}else Ye=n,n=r;else Ye=n,n=r;t=n!==r?e.substring(t,Ye):n;return Ze[c]={nextPos:Ye,result:t},t}())===r&&(n=function(){var t,n,o,s,a,i,c=82*Ye+27,l=Ze[c];if(l)return Ye=l.nextPos,l.result;t=Ye,n=Ye,45===e.charCodeAt(Ye)?(o=J,Ye++):(o=r,ot(K));o===r&&(o=null);if(o!==r)if(e.substr(Ye,2)===ae?(s=ae,Ye+=2):(s=r,ot(ie)),s!==r){if(a=[],ce.test(e.charAt(Ye))?(i=e.charAt(Ye),Ye++):(i=r,ot(le)),i!==r)for(;i!==r;)a.push(i),ce.test(e.charAt(Ye))?(i=e.charAt(Ye),Ye++):(i=r,ot(le));else a=r;a!==r?n=o=[o,s,a]:(Ye=n,n=r)}else Ye=n,n=r;else Ye=n,n=r;t=n!==r?e.substring(t,Ye):n;return Ze[c]={nextPos:Ye,result:t},t}())===r&&(n=function(){var t,n,o,s,a=82*Ye+23,i=Ze[a];if(i)return Ye=i.nextPos,i.result;t=Ye,n=Ye,43===e.charCodeAt(Ye)?(o="+",Ye++):(o=r,ot(z));o===r&&(45===e.charCodeAt(Ye)?(o=J,Ye++):(o=r,ot(K)));o===r&&(o=null);o!==r&&(s=Ct())!==r?n=o=[o,s]:(Ye=n,n=r);t=n!==r?e.substring(t,Ye):n;return Ze[a]={nextPos:Ye,result:t},t}());n!==r&&(a=n,n={type:on.NUMBER_VALUE,number:a});var a;return t=n,Ze[o]={nextPos:Ye,result:t},t}()),Ze[n]={nextPos:Ye,result:t},t)}function St(){var t,n,o,s,a,i,c,l,u=82*Ye+21,p=Ze[u];if(p)return Ye=p.nextPos,p.result;if(t=Ye,34===e.charCodeAt(Ye)?(n=P,Ye++):(n=r,ot(T)),n!==r){for(o=Ye,s=[],I.test(e.charAt(Ye))?(a=e.charAt(Ye),Ye++):(a=r,ot(F)),a===r&&(a=Ye,92===e.charCodeAt(Ye)?(i=A,Ye++):(i=r,ot(k)),i!==r?(e.length>Ye?(c=e.charAt(Ye),Ye++):(c=r,ot(w)),c!==r?a=i=[i,c]:(Ye=a,a=r)):(Ye=a,a=r));a!==r;)s.push(a),I.test(e.charAt(Ye))?(a=e.charAt(Ye),Ye++):(a=r,ot(F)),a===r&&(a=Ye,92===e.charCodeAt(Ye)?(i=A,Ye++):(i=r,ot(k)),i!==r?(e.length>Ye?(c=e.charAt(Ye),Ye++):(c=r,ot(w)),c!==r?a=i=[i,c]:(Ye=a,a=r)):(Ye=a,a=r));(o=s!==r?e.substring(o,Ye):s)!==r?(34===e.charCodeAt(Ye)?(s=P,Ye++):(s=r,ot(T)),s!==r?(l=o,t=n={type:on.STRING_VALUE,quoteStyle:"double",string:l.replace(/\\"/gu,'"').replace(/\\\\/gu,"\\")}):(Ye=t,t=r)):(Ye=t,t=r)}else Ye=t,t=r;if(t===r)if(t=Ye,39===e.charCodeAt(Ye)?(n=E,Ye++):(n=r,ot(S)),n!==r){for(o=Ye,s=[],C.test(e.charAt(Ye))?(a=e.charAt(Ye),Ye++):(a=r,ot(v)),a===r&&(a=Ye,92===e.charCodeAt(Ye)?(i=A,Ye++):(i=r,ot(k)),i!==r?(e.length>Ye?(c=e.charAt(Ye),Ye++):(c=r,ot(w)),c!==r?a=i=[i,c]:(Ye=a,a=r)):(Ye=a,a=r));a!==r;)s.push(a),C.test(e.charAt(Ye))?(a=e.charAt(Ye),Ye++):(a=r,ot(v)),a===r&&(a=Ye,92===e.charCodeAt(Ye)?(i=A,Ye++):(i=r,ot(k)),i!==r?(e.length>Ye?(c=e.charAt(Ye),Ye++):(c=r,ot(w)),c!==r?a=i=[i,c]:(Ye=a,a=r)):(Ye=a,a=r));(o=s!==r?e.substring(o,Ye):s)!==r?(39===e.charCodeAt(Ye)?(s=E,Ye++):(s=r,ot(S)),s!==r?t=n=function(e){return{type:on.STRING_VALUE,quoteStyle:"single",string:e.replace(/\\'/g,"'").replace(/\\\\/gu,"\\")}}(o):(Ye=t,t=r)):(Ye=t,t=r)}else Ye=t,t=r;return Ze[u]={nextPos:Ye,result:t},t}function Ct(){var t,n,o,s,a,i,c,l,u=82*Ye+24,p=Ze[u];if(p)return Ye=p.nextPos,p.result;if(t=Ye,n=Ye,o=Ye,s=[],Y.test(e.charAt(Ye))?(a=e.charAt(Ye),Ye++):(a=r,ot(H)),a!==r)for(;a!==r;)s.push(a),Y.test(e.charAt(Ye))?(a=e.charAt(Ye),Ye++):(a=r,ot(H));else s=r;if(s!==r){if(a=Ye,46===e.charCodeAt(Ye)?(i=D,Ye++):(i=r,ot(O)),i!==r){if(c=[],Y.test(e.charAt(Ye))?(l=e.charAt(Ye),Ye++):(l=r,ot(H)),l!==r)for(;l!==r;)c.push(l),Y.test(e.charAt(Ye))?(l=e.charAt(Ye),Ye++):(l=r,ot(H));else c=r;c!==r?a=i=[i,c]:(Ye=a,a=r)}else Ye=a,a=r;a===r&&(a=null),a!==r?o=s=[s,a]:(Ye=o,o=r)}else Ye=o,o=r;if(o===r)if(o=Ye,46===e.charCodeAt(Ye)?(s=D,Ye++):(s=r,ot(O)),s!==r){if(a=[],Y.test(e.charAt(Ye))?(i=e.charAt(Ye),Ye++):(i=r,ot(H)),i!==r)for(;i!==r;)a.push(i),Y.test(e.charAt(Ye))?(i=e.charAt(Ye),Ye++):(i=r,ot(H));else a=r;a!==r?o=s=[s,a]:(Ye=o,o=r)}else Ye=o,o=r;if(o!==r){if(s=Ye,101===e.charCodeAt(Ye)?(a="e",Ye++):(a=r,ot(X)),a!==r)if(43===e.charCodeAt(Ye)?(i="+",Ye++):(i=r,ot(z)),i===r&&(45===e.charCodeAt(Ye)?(i=J,Ye++):(i=r,ot(K))),i===r&&(i=null),i!==r){if(c=[],Y.test(e.charAt(Ye))?(l=e.charAt(Ye),Ye++):(l=r,ot(H)),l!==r)for(;l!==r;)c.push(l),Y.test(e.charAt(Ye))?(l=e.charAt(Ye),Ye++):(l=r,ot(H));else c=r;c!==r?s=a=[a,i,c]:(Ye=s,s=r)}else Ye=s,s=r;else Ye=s,s=r;s===r&&(s=null),s!==r?n=o=[o,s]:(Ye=n,n=r)}else Ye=n,n=r;return t=n!==r?e.substring(t,Ye):n,Ze[u]={nextPos:Ye,result:t},t}function vt(){var t,n,o,s,a,i,c=82*Ye+28,l=Ze[c];return l?(Ye=l.nextPos,l.result):(t=Ye,(n=At())!==r&&it()!==r?(38===e.charCodeAt(Ye)?(o="&",Ye++):(o=r,ot(ue)),o!==r&&it()!==r?((s=vt())===r&&(s=At()),s!==r?(a=n,i=s,t=n={type:on.INTERSECTION,left:a,right:i}):(Ye=t,t=r)):(Ye=t,t=r)):(Ye=t,t=r),Ze[c]={nextPos:Ye,result:t},t)}function At(){var e,t=82*Ye+29,n=Ze[t];return n?(Ye=n.nextPos,n.result):((e=Pt())===r&&(e=Wt())===r&&(e=Jt())===r&&(e=Mt())===r&&(e=_t())===r&&(e=Yt())===r&&(e=Ft())===r&&(e=Dt())===r&&(e=jt())===r&&(e=Rt())===r&&(e=gt())===r&&(e=Et())===r&&(e=xt())===r&&(e=bt()),Ze[t]={nextPos:Ye,result:e},e)}function kt(){var t,n,o,s,a,i,c=82*Ye+30,l=Ze[c];return l?(Ye=l.nextPos,l.result):(t=Ye,(n=wt())!==r&&it()!==r?(124===e.charCodeAt(Ye)?(o="|",Ye++):(o=r,ot(pe)),o!==r&&it()!==r?((s=kt())===r&&(s=wt()),s!==r?(a=n,i=s,t=n={type:on.UNION,left:a,right:i}):(Ye=t,t=r)):(Ye=t,t=r)):(Ye=t,t=r),Ze[c]={nextPos:Ye,result:t},t)}function wt(){var e,t=82*Ye+31,n=Ze[t];return n?(Ye=n.nextPos,n.result):((e=Pt())===r&&(e=Wt())===r&&(e=Jt())===r&&(e=Mt())===r&&(e=_t())===r&&(e=Yt())===r&&(e=Ft())===r&&(e=Dt())===r&&(e=jt())===r&&(e=Rt())===r&&(e=gt())===r&&(e=Et())===r&&(e=xt())===r&&(e=bt()),Ze[t]={nextPos:Ye,result:e},e)}function Pt(){var t,n=82*Ye+32,o=Ze[n];return o?(Ye=o.nextPos,o.result):((t=function(){var t,n=82*Ye+42,o=Ze[n];if(o)return Ye=o.nextPos,o.result;(t=function(){var t,n,o,s=82*Ye+46,a=Ze[s];if(a)return Ye=a.nextPos,a.result;t=Ye,(n=Bt())===r&&(n=Nt())===r&&(n=Ot());n!==r&&it()!==r?(61===e.charCodeAt(Ye)?(o="=",Ye++):(o=r,ot(ke)),o!==r?(i=n,t=n={type:on.OPTIONAL,value:i,meta:{syntax:tn.SUFFIX_EQUALS_SIGN}}):(Ye=t,t=r)):(Ye=t,t=r);var i;return Ze[s]={nextPos:Ye,result:t},t}())===r&&(t=Bt())===r&&(t=Nt());return Ze[n]={nextPos:Ye,result:t},t}())===r&&(t=Tt()),Ze[n]={nextPos:Ye,result:t},t)}function Tt(){var t,n=82*Ye+33,o=Ze[n];return o?(Ye=o.nextPos,o.result):((t=function(){var t,n,o,s=82*Ye+41,a=Ze[s];if(a)return Ye=a.nextPos,a.result;t=Ye,61===e.charCodeAt(Ye)?(n=Ae,Ye++):(n=r,ot(ke));n!==r&&it()!==r&&(o=It())!==r?(i=o,t=n={type:on.OPTIONAL,value:i,meta:{syntax:tn.PREFIX_EQUALS_SIGN}}):(Ye=t,t=r);var i;return Ze[s]={nextPos:Ye,result:t},t}())===r&&(t=function(){var t,n,o,s=82*Ye+40,a=Ze[s];if(a)return Ye=a.nextPos,a.result;t=Ye,33===e.charCodeAt(Ye)?(n="!",Ye++):(n=r,ot(ve));n!==r&&it()!==r&&(o=It())!==r?(i=o,t=n={type:on.NOT_NULLABLE,value:i,meta:{syntax:rn.PREFIX_BANG}}):(Ye=t,t=r);var i;return Ze[s]={nextPos:Ye,result:t},t}())===r&&(t=function(){var t,n,o,s=82*Ye+39,a=Ze[s];if(a)return Ye=a.nextPos,a.result;t=Ye,63===e.charCodeAt(Ye)?(n=W,Ye++):(n=r,ot(G));n!==r&&it()!==r&&(o=It())!==r?(i=o,t=n={type:on.NULLABLE,value:i,meta:{syntax:nn.PREFIX_QUESTION_MARK}}):(Ye=t,t=r);var i;return Ze[s]={nextPos:Ye,result:t},t}()),Ze[n]={nextPos:Ye,result:t},t)}function It(){var e,t=82*Ye+34,n=Ze[t];return n?(Ye=n.nextPos,n.result):((e=jt())===r&&(e=Wt())===r&&(e=Jt())===r&&(e=Mt())===r&&(e=_t())===r&&(e=Yt())===r&&(e=gt())===r&&(e=Et())===r&&(e=xt())===r&&(e=bt()),Ze[t]={nextPos:Ye,result:e},e)}function Ft(){var t,n,o,s=82*Ye+35,a=Ze[s];return a?(Ye=a.nextPos,a.result):(t=Ye,e.substr(Ye,6)===de?(n=de,Ye+=6):(n=r,ot(fe)),n!==r&&ct()!==r&&(o=mt())!==r?t=n=function(e,t){return{type:on.TYPE_QUERY,name:t}}(0,o):(Ye=t,t=r),Ze[s]={nextPos:Ye,result:t},t)}function Dt(){var t,n,o,s,a=82*Ye+36,i=Ze[a];return i?(Ye=i.nextPos,i.result):(t=Ye,e.substr(Ye,5)===me?(n=me,Ye+=5):(n=r,ot(ge)),n!==r&&(o=ct())!==r&&(s=function(){var e,t=82*Ye+37,n=Ze[t];if(n)return Ye=n.nextPos,n.result;(e=kt())===r&&(e=vt())===r&&(e=Pt())===r&&(e=Wt())===r&&(e=Jt())===r&&(e=_t())===r&&(e=Yt())===r&&(e=Ft())===r&&(e=Dt())===r&&(e=Rt())===r&&(e=jt())===r&&(e=gt())===r&&(e=Et())===r&&(e=xt())===r&&(e=bt());return Ze[t]={nextPos:Ye,result:e},e}())!==r?t=n=he(0,s):(Ye=t,t=r),t===r&&(t=Ye,e.substr(Ye,5)===me?(n=me,Ye+=5):(n=r,ot(ge)),n!==r&&(o=Yt())!==r?t=n=he(0,o):(Ye=t,t=r)),Ze[a]={nextPos:Ye,result:t},t)}function Ot(){var e,t=82*Ye+43,n=Ze[t];return n?(Ye=n.nextPos,n.result):((e=Tt())===r&&(e=jt())===r&&(e=Wt())===r&&(e=Jt())===r&&(e=Mt())===r&&(e=_t())===r&&(e=Yt())===r&&(e=gt())===r&&(e=Et())===r&&(e=xt())===r&&(e=bt()),Ze[t]={nextPos:Ye,result:e},e)}function Bt(){var t,n,o,s,a=82*Ye+44,i=Ze[a];return i?(Ye=i.nextPos,i.result):(t=Ye,(n=Ot())!==r&&it()!==r?(63===e.charCodeAt(Ye)?(o=W,Ye++):(o=r,ot(G)),o!==r?(s=n,t=n={type:on.NULLABLE,value:s,meta:{syntax:nn.SUFFIX_QUESTION_MARK}}):(Ye=t,t=r)):(Ye=t,t=r),Ze[a]={nextPos:Ye,result:t},t)}function Nt(){var t,n,o,s,a=82*Ye+45,i=Ze[a];return i?(Ye=i.nextPos,i.result):(t=Ye,(n=Ot())!==r&&it()!==r?(33===e.charCodeAt(Ye)?(o="!",Ye++):(o=r,ot(ve)),o!==r?(s=n,t=n={type:on.NOT_NULLABLE,value:s,meta:{syntax:rn.SUFFIX_BANG}}):(Ye=t,t=r)):(Ye=t,t=r),Ze[a]={nextPos:Ye,result:t},t)}function jt(){var t,n,o,s,a,i,c,l=82*Ye+47,u=Ze[l];return u?(Ye=u.nextPos,u.result):(t=Ye,(n=function(){var e,t=82*Ye+48,n=Ze[t];if(n)return Ye=n.nextPos,n.result;(e=Yt())===r&&(e=gt())===r&&(e=Et())===r&&(e=xt())===r&&(e=bt());return Ze[t]={nextPos:Ye,result:e},e}())!==r&&it()!==r&&(o=function(){var t,n=82*Ye+51,o=Ze[n];if(o)return Ye=o.nextPos,o.result;(t=function(){var t,n,o=82*Ye+52,s=Ze[o];if(s)return Ye=s.nextPos,s.result;t=Ye,e.substr(Ye,2)===Te?(n=Te,Ye+=2):(n=r,ot(Ie));n!==r&&(n=Zt.ANGLE_BRACKET_WITH_DOT);return t=n,Ze[o]={nextPos:Ye,result:t},t}())===r&&(t=function(){var t,n,o=82*Ye+53,s=Ze[o];if(s)return Ye=s.nextPos,s.result;t=Ye,60===e.charCodeAt(Ye)?(n="<",Ye++):(n=r,ot(Fe));n!==r&&(n=Zt.ANGLE_BRACKET);return t=n,Ze[o]={nextPos:Ye,result:t},t}());return Ze[n]={nextPos:Ye,result:t},t}())!==r&&it()!==r&&(s=function(){var t,n,o,s,a,i,c,l,u=82*Ye+50,p=Ze[u];if(p)return Ye=p.nextPos,p.result;if(t=Ye,(n=Lt())!==r){for(o=[],s=Ye,(a=it())!==r?(44===e.charCodeAt(Ye)?(i=we,Ye++):(i=r,ot(Pe)),i!==r&&(c=it())!==r&&(l=Lt())!==r?s=a=[a,i,c,l]:(Ye=s,s=r)):(Ye=s,s=r);s!==r;)o.push(s),s=Ye,(a=it())!==r?(44===e.charCodeAt(Ye)?(i=we,Ye++):(i=r,ot(Pe)),i!==r&&(c=it())!==r&&(l=Lt())!==r?s=a=[a,i,c,l]:(Ye=s,s=r)):(Ye=s,s=r);o!==r?(d=n,t=n=o.reduce((function(e,t){return e.concat([t[3]])}),[d])):(Ye=t,t=r)}else Ye=t,t=r;var d;return Ze[u]={nextPos:Ye,result:t},t}())!==r&&it()!==r&&function(){var t,n=82*Ye+54,o=Ze[n];if(o)return Ye=o.nextPos,o.result;62===e.charCodeAt(Ye)?(t=">",Ye++):(t=r,ot(De));return Ze[n]={nextPos:Ye,result:t},t}()!==r?(a=n,i=o,c=s,t=n={type:on.GENERIC,subject:a,objects:c,meta:{syntax:i}}):(Ye=t,t=r),Ze[l]={nextPos:Ye,result:t},t)}function Lt(){var e,t=82*Ye+49,n=Ze[t];return n?(Ye=n.nextPos,n.result):((e=kt())===r&&(e=vt())===r&&(e=Pt())===r&&(e=Wt())===r&&(e=Jt())===r&&(e=Mt())===r&&(e=_t())===r&&(e=Yt())===r&&(e=Rt())===r&&(e=jt())===r&&(e=Ft())===r&&(e=Dt())===r&&(e=gt())===r&&(e=Et())===r&&(e=xt())===r&&(e=bt()),Ze[t]={nextPos:Ye,result:e},e)}function Rt(){var t,n,o,s,a,i,c,l,u,p=82*Ye+55,d=Ze[p];if(d)return Ye=d.nextPos,d.result;if(t=Ye,(n=function(){var e,t=82*Ye+56,n=Ze[t];if(n)return Ye=n.nextPos,n.result;(e=Pt())===r&&(e=Wt())===r&&(e=Jt())===r&&(e=Mt())===r&&(e=_t())===r&&(e=Yt())===r&&(e=jt())===r&&(e=Ft())===r&&(e=Dt())===r&&(e=gt())===r&&(e=Et())===r&&(e=xt())===r&&(e=bt());return Ze[t]={nextPos:Ye,result:e},e}())!==r){if(o=[],s=Ye,(a=it())!==r?(91===e.charCodeAt(Ye)?(i="[",Ye++):(i=r,ot(Oe)),i!==r&&(c=it())!==r?(93===e.charCodeAt(Ye)?(l="]",Ye++):(l=r,ot(Be)),l!==r?s=a=[a,i,c,l]:(Ye=s,s=r)):(Ye=s,s=r)):(Ye=s,s=r),s!==r)for(;s!==r;)o.push(s),s=Ye,(a=it())!==r?(91===e.charCodeAt(Ye)?(i="[",Ye++):(i=r,ot(Oe)),i!==r&&(c=it())!==r?(93===e.charCodeAt(Ye)?(l="]",Ye++):(l=r,ot(Be)),l!==r?s=a=[a,i,c,l]:(Ye=s,s=r)):(Ye=s,s=r)):(Ye=s,s=r);else o=r;o!==r?(u=n,t=n=o.reduce((function(e){return{type:on.GENERIC,subject:{type:on.NAME,name:"Array"},objects:[e],meta:{syntax:Zt.SQUARE_BRACKET}}}),u)):(Ye=t,t=r)}else Ye=t,t=r;return Ze[p]={nextPos:Ye,result:t},t}function Mt(){var t,n,o,s,a,i,c,l,u=82*Ye+57,p=Ze[u];return p?(Ye=p.nextPos,p.result):(t=Ye,e.substr(Ye,3)===Ne?(n=Ne,Ye+=3):(n=r,ot(je)),n===r&&(n=null),n!==r&&it()!==r&&(o=function(){var t,n,o,s,a=82*Ye+58,i=Ze[a];if(i)return Ye=i.nextPos,i.result;t=Ye,40===e.charCodeAt(Ye)?(n=be,Ye++):(n=r,ot(Ee));n!==r&&it()!==r?(41===e.charCodeAt(Ye)?(o=Se,Ye++):(o=r,ot(Ce)),o!==r?t=n=[]:(Ye=t,t=r)):(Ye=t,t=r);t===r&&(t=Ye,40===e.charCodeAt(Ye)?(n=be,Ye++):(n=r,ot(Ee)),n!==r&&it()!==r&&(o=function(){var t,n,o,s,a,i,c,l,u,p,d,f=82*Ye+59,m=Ze[f];if(m)return Ye=m.nextPos,m.result;t=Ye,n=[],o=Ye,(s=lt())!==r&&(a=it())!==r?(58===e.charCodeAt(Ye)?(i=R,Ye++):(i=r,ot(M)),i!==r&&(c=it())!==r?((l=Ut())===r&&(l=null),l!==r&&(u=it())!==r?(44===e.charCodeAt(Ye)?(p=we,Ye++):(p=r,ot(Pe)),p!==r&&(d=it())!==r?o=s=[s,a,i,c,l,u,p,d]:(Ye=o,o=r)):(Ye=o,o=r)):(Ye=o,o=r)):(Ye=o,o=r);for(;o!==r;)n.push(o),o=Ye,(s=lt())!==r&&(a=it())!==r?(58===e.charCodeAt(Ye)?(i=R,Ye++):(i=r,ot(M)),i!==r&&(c=it())!==r?((l=Ut())===r&&(l=null),l!==r&&(u=it())!==r?(44===e.charCodeAt(Ye)?(p=we,Ye++):(p=r,ot(Pe)),p!==r&&(d=it())!==r?o=s=[s,a,i,c,l,u,p,d]:(Ye=o,o=r)):(Ye=o,o=r)):(Ye=o,o=r)):(Ye=o,o=r);n!==r?((o=function(){var t,n,o,s,a,i=82*Ye+60,c=Ze[i];if(c)return Ye=c.nextPos,c.result;t=Ye,e.substr(Ye,3)===Re?(n=Re,Ye+=3):(n=r,ot(Me));n===r&&(n=null);n!==r&&it()!==r&&(o=lt())!==r&&it()!==r?(58===e.charCodeAt(Ye)?(s=R,Ye++):(s=r,ot(M)),s!==r&&it()!==r?((a=Ut())===r&&(a=null),a!==r?t=n=function(e,t,n){const r={type:on.NAMED_PARAMETER,name:t,typeName:n};return e?{type:on.VARIADIC,value:r,meta:{syntax:en.PREFIX_DOTS}}:r}(n,o,a):(Ye=t,t=r)):(Ye=t,t=r)):(Ye=t,t=r);return Ze[i]={nextPos:Ye,result:t},t}())===r&&(o=null),o!==r?(g=o,t=n=n.reduceRight((function(e,t){return[{type:on.NAMED_PARAMETER,name:t[0],typeName:t[4]}].concat(e)}),g?[g]:[])):(Ye=t,t=r)):(Ye=t,t=r);var g;return Ze[f]={nextPos:Ye,result:t},t}())!==r&&it()!==r?(41===e.charCodeAt(Ye)?(s=Se,Ye++):(s=r,ot(Ce)),s!==r?t=n=o:(Ye=t,t=r)):(Ye=t,t=r));return Ze[a]={nextPos:Ye,result:t},t}())!==r&&it()!==r?("=>"===e.substr(Ye,2)?(s="=>",Ye+=2):(s=r,ot(Le)),s!==r&&it()!==r&&(a=Vt())!==r?(i=n,c=o,l=a,t=n={type:on.ARROW,params:c,returns:l,new:i}):(Ye=t,t=r)):(Ye=t,t=r),Ze[u]={nextPos:Ye,result:t},t)}function _t(){var t,n,o,s,a,i,c,l=82*Ye+61,u=Ze[l];return u?(Ye=u.nextPos,u.result):(t=Ye,e.substr(Ye,8)===_e?(n=_e,Ye+=8):(n=r,ot($e)),n!==r&&it()!==r&&(o=function(){var t,n,o,s,a,i,c=82*Ye+62,l=Ze[c];if(l)return Ye=l.nextPos,l.result;t=Ye,40===e.charCodeAt(Ye)?(n=be,Ye++):(n=r,ot(Ee));n!==r&&it()!==r&&(o=$t())!==r&&it()!==r?(44===e.charCodeAt(Ye)?(s=we,Ye++):(s=r,ot(Pe)),s!==r&&it()!==r&&(a=qt())!==r&&it()!==r?(41===e.charCodeAt(Ye)?(i=Se,Ye++):(i=r,ot(Ce)),i!==r?t=n={params:a,modifier:o}:(Ye=t,t=r)):(Ye=t,t=r)):(Ye=t,t=r);t===r&&(t=Ye,40===e.charCodeAt(Ye)?(n=be,Ye++):(n=r,ot(Ee)),n!==r&&it()!==r&&(o=$t())!==r&&it()!==r?(41===e.charCodeAt(Ye)?(s=Se,Ye++):(s=r,ot(Ce)),s!==r?t=n=function(e){return{params:[],modifier:e}}(o):(Ye=t,t=r)):(Ye=t,t=r),t===r&&(t=Ye,40===e.charCodeAt(Ye)?(n=be,Ye++):(n=r,ot(Ee)),n!==r&&it()!==r?(41===e.charCodeAt(Ye)?(o=Se,Ye++):(o=r,ot(Ce)),o!==r?t=n={params:[],modifier:{nodeThis:null,nodeNew:null}}:(Ye=t,t=r)):(Ye=t,t=r),t===r&&(t=Ye,40===e.charCodeAt(Ye)?(n=be,Ye++):(n=r,ot(Ee)),n!==r&&it()!==r&&(o=qt())!==r&&it()!==r?(41===e.charCodeAt(Ye)?(s=Se,Ye++):(s=r,ot(Ce)),s!==r?t=n=function(e){return{params:e,modifier:{nodeThis:null,nodeNew:null}}}(o):(Ye=t,t=r)):(Ye=t,t=r))));return Ze[c]={nextPos:Ye,result:t},t}())!==r&&it()!==r?(s=Ye,58===e.charCodeAt(Ye)?(a=R,Ye++):(a=r,ot(M)),a!==r&&(i=it())!==r&&(c=Vt())!==r?s=a=[a,i,c]:(Ye=s,s=r),s===r&&(s=null),s!==r?t=n=function(e,t){const n=t?t[2]:null;return{type:on.FUNCTION,params:e.params,returns:n,this:e.modifier.nodeThis,new:e.modifier.nodeNew}}(o,s):(Ye=t,t=r)):(Ye=t,t=r),Ze[l]={nextPos:Ye,result:t},t)}function $t(){var t,n,o,s,a,i,c,l=82*Ye+63,u=Ze[l];return u?(Ye=u.nextPos,u.result):(t=Ye,n=Ye,e.substr(Ye,4)===qe?(o=qe,Ye+=4):(o=r,ot(Ue)),o!==r&&(s=it())!==r?(58===e.charCodeAt(Ye)?(a=R,Ye++):(a=r,ot(M)),a!==r&&(i=it())!==r&&(c=Ut())!==r?n=o=[o,s,a,i,c]:(Ye=n,n=r)):(Ye=n,n=r),n!==r&&(n={nodeThis:n[4],nodeNew:null}),(t=n)===r&&(t=Ye,n=Ye,e.substr(Ye,3)===Ne?(o=Ne,Ye+=3):(o=r,ot(je)),o!==r&&(s=it())!==r?(58===e.charCodeAt(Ye)?(a=R,Ye++):(a=r,ot(M)),a!==r&&(i=it())!==r&&(c=Ut())!==r?n=o=[o,s,a,i,c]:(Ye=n,n=r)):(Ye=n,n=r),n!==r&&(n={nodeThis:null,nodeNew:n[4]}),t=n),Ze[l]={nextPos:Ye,result:t},t)}function qt(){var t,n,o,s,a,i,c,l,u=82*Ye+64,p=Ze[u];if(p)return Ye=p.nextPos,p.result;for(t=Ye,n=[],o=Ye,(s=Ut())!==r&&(a=it())!==r?(44===e.charCodeAt(Ye)?(i=we,Ye++):(i=r,ot(Pe)),i!==r&&(c=it())!==r?o=s=[s,a,i,c]:(Ye=o,o=r)):(Ye=o,o=r);o!==r;)n.push(o),o=Ye,(s=Ut())!==r&&(a=it())!==r?(44===e.charCodeAt(Ye)?(i=we,Ye++):(i=r,ot(Pe)),i!==r&&(c=it())!==r?o=s=[s,a,i,c]:(Ye=o,o=r)):(Ye=o,o=r);return n!==r?((o=Ht())===r&&(o=Xt()),o===r&&(o=null),o!==r?(l=o,t=n=n.reduceRight((function(e,t){const[n]=t;return[n].concat(e)}),l?[l]:[])):(Ye=t,t=r)):(Ye=t,t=r),Ze[u]={nextPos:Ye,result:t},t}function Ut(){var e,t=82*Ye+65,n=Ze[t];return n?(Ye=n.nextPos,n.result):((e=kt())===r&&(e=vt())===r&&(e=Ft())===r&&(e=Dt())===r&&(e=Pt())===r&&(e=Wt())===r&&(e=Jt())===r&&(e=Mt())===r&&(e=_t())===r&&(e=Yt())===r&&(e=Rt())===r&&(e=jt())===r&&(e=gt())===r&&(e=Et())===r&&(e=xt())===r&&(e=bt()),Ze[t]={nextPos:Ye,result:e},e)}function Vt(){var e,t=82*Ye+66,n=Ze[t];return n?(Ye=n.nextPos,n.result):((e=Tt())===r&&(e=Wt())===r&&(e=Jt())===r&&(e=Mt())===r&&(e=_t())===r&&(e=Yt())===r&&(e=Rt())===r&&(e=Ft())===r&&(e=Dt())===r&&(e=jt())===r&&(e=gt())===r&&(e=Et())===r&&(e=xt())===r&&(e=bt()),Ze[t]={nextPos:Ye,result:e},e)}function Wt(){var t,n,o,s,d,f=82*Ye+67,m=Ze[f];return m?(Ye=m.nextPos,m.result):(t=Ye,123===e.charCodeAt(Ye)?(n="{",Ye++):(n=r,ot(Ve)),n!==r&&it()!==r?((o=function(){var t,n,o,s,d,f,m,g,h=82*Ye+68,y=Ze[h];if(y)return Ye=y.nextPos,y.result;if(t=Ye,(n=Gt())!==r){if(o=[],s=Ye,d=Ye,(f=it())!==r?(44===e.charCodeAt(Ye)?(m=we,Ye++):(m=r,ot(Pe)),m!==r?d=f=[f,m]:(Ye=d,d=r)):(Ye=d,d=r),d===r&&(d=Ye,(f=it())!==r?(59===e.charCodeAt(Ye)?(m=Ge,Ye++):(m=r,ot(ze)),m!==r?d=f=[f,m]:(Ye=d,d=r)):(Ye=d,d=r),d===r)){for(d=Ye,f=[],a.test(e.charAt(Ye))?(m=e.charAt(Ye),Ye++):(m=r,ot(i));m!==r;)f.push(m),a.test(e.charAt(Ye))?(m=e.charAt(Ye),Ye++):(m=r,ot(i));f!==r?(c.test(e.charAt(Ye))?(m=e.charAt(Ye),Ye++):(m=r,ot(l)),m===r&&(m=null),m!==r?(u.test(e.charAt(Ye))?(g=e.charAt(Ye),Ye++):(g=r,ot(p)),g!==r?d=f=[f,m,g]:(Ye=d,d=r)):(Ye=d,d=r)):(Ye=d,d=r)}for(d!==r&&(f=it())!==r&&(m=Gt())!==r?s=d=[d,f,m]:(Ye=s,s=r);s!==r;){if(o.push(s),s=Ye,d=Ye,(f=it())!==r?(44===e.charCodeAt(Ye)?(m=we,Ye++):(m=r,ot(Pe)),m!==r?d=f=[f,m]:(Ye=d,d=r)):(Ye=d,d=r),d===r&&(d=Ye,(f=it())!==r?(59===e.charCodeAt(Ye)?(m=Ge,Ye++):(m=r,ot(ze)),m!==r?d=f=[f,m]:(Ye=d,d=r)):(Ye=d,d=r),d===r)){for(d=Ye,f=[],a.test(e.charAt(Ye))?(m=e.charAt(Ye),Ye++):(m=r,ot(i));m!==r;)f.push(m),a.test(e.charAt(Ye))?(m=e.charAt(Ye),Ye++):(m=r,ot(i));f!==r?(c.test(e.charAt(Ye))?(m=e.charAt(Ye),Ye++):(m=r,ot(l)),m===r&&(m=null),m!==r?(u.test(e.charAt(Ye))?(g=e.charAt(Ye),Ye++):(g=r,ot(p)),g!==r?d=f=[f,m,g]:(Ye=d,d=r)):(Ye=d,d=r)):(Ye=d,d=r)}d!==r&&(f=it())!==r&&(m=Gt())!==r?s=d=[d,f,m]:(Ye=s,s=r)}if(o!==r){if(s=Ye,(d=it())!==r?(44===e.charCodeAt(Ye)?(f=we,Ye++):(f=r,ot(Pe)),f!==r?s=d=[d,f]:(Ye=s,s=r)):(Ye=s,s=r),s===r&&(s=Ye,(d=it())!==r?(59===e.charCodeAt(Ye)?(f=Ge,Ye++):(f=r,ot(ze)),f!==r?s=d=[d,f]:(Ye=s,s=r)):(Ye=s,s=r),s===r)){for(s=Ye,d=[],a.test(e.charAt(Ye))?(f=e.charAt(Ye),Ye++):(f=r,ot(i));f!==r;)d.push(f),a.test(e.charAt(Ye))?(f=e.charAt(Ye),Ye++):(f=r,ot(i));d!==r?(c.test(e.charAt(Ye))?(f=e.charAt(Ye),Ye++):(f=r,ot(l)),f===r&&(f=null),f!==r?(u.test(e.charAt(Ye))?(m=e.charAt(Ye),Ye++):(m=r,ot(p)),m!==r?s=d=[d,f,m]:(Ye=s,s=r)):(Ye=s,s=r)):(Ye=s,s=r)}s===r&&(s=null),s!==r?(x=n,t=n=o.reduce((function(e,t){const n=t[2];return e.concat([n])}),[x])):(Ye=t,t=r)}else Ye=t,t=r}else Ye=t,t=r;var x;return Ze[h]={nextPos:Ye,result:t},t}())===r&&(o=null),o!==r&&it()!==r?(125===e.charCodeAt(Ye)?(s="}",Ye++):(s=r,ot(We)),s!==r?(d=o,t=n={type:on.RECORD,entries:d||[]}):(Ye=t,t=r)):(Ye=t,t=r)):(Ye=t,t=r),Ze[f]={nextPos:Ye,result:t},t)}function Gt(){var t,n,o,s,a,i,c,l=82*Ye+69,u=Ze[l];return u?(Ye=u.nextPos,u.result):(t=Ye,n=Ye,e.substr(Ye,8)===Je?(o=Je,Ye+=8):(o=r,ot(Ke)),o!==r&&(s=ct())!==r?n=o=[o,s]:(Ye=n,n=r),n===r&&(n=null),n!==r&&(o=zt())!==r&&(s=it())!==r?(63===e.charCodeAt(Ye)?(a=W,Ye++):(a=r,ot(G)),a===r&&(a=null),a!==r&&it()!==r?(58===e.charCodeAt(Ye)?(i=R,Ye++):(i=r,ot(M)),i!==r&&it()!==r&&(c=function(){var e,t=82*Ye+71,n=Ze[t];if(n)return Ye=n.nextPos,n.result;(e=kt())===r&&(e=vt())===r&&(e=Pt())===r&&(e=Wt())===r&&(e=Jt())===r&&(e=Mt())===r&&(e=_t())===r&&(e=Yt())===r&&(e=Rt())===r&&(e=jt())===r&&(e=gt())===r&&(e=Et())===r&&(e=xt())===r&&(e=bt());return Ze[t]={nextPos:Ye,result:e},e}())!==r?t=n=function(e,t,n,r){const{quoteStyle:o,key:s}=t;return{type:on.RECORD_ENTRY,key:s,quoteStyle:o,value:"?"===n?{type:on.OPTIONAL,value:r,meta:{syntax:tn.SUFFIX_KEY_QUESTION_MARK}}:r,readonly:Boolean(e)}}(n,o,a,c):(Ye=t,t=r)):(Ye=t,t=r)):(Ye=t,t=r),t===r&&(t=Ye,n=Ye,e.substr(Ye,8)===Je?(o=Je,Ye+=8):(o=r,ot(Ke)),o!==r&&(s=ct())!==r?n=o=[o,s]:(Ye=n,n=r),n===r&&(n=null),n!==r&&(o=zt())!==r?t=n=function(e,t){const{quoteStyle:n,key:r}=t;return{type:on.RECORD_ENTRY,key:r,quoteStyle:n,value:null,readonly:Boolean(e)}}(n,o):(Ye=t,t=r)),Ze[l]={nextPos:Ye,result:t},t)}function zt(){var t,n,o,s,a,i,c,l=82*Ye+70,u=Ze[l];if(u)return Ye=u.nextPos,u.result;if(t=Ye,34===e.charCodeAt(Ye)?(n=P,Ye++):(n=r,ot(T)),n!==r){for(o=Ye,s=[],I.test(e.charAt(Ye))?(a=e.charAt(Ye),Ye++):(a=r,ot(F)),a===r&&(a=Ye,92===e.charCodeAt(Ye)?(i=A,Ye++):(i=r,ot(k)),i!==r?(e.length>Ye?(c=e.charAt(Ye),Ye++):(c=r,ot(w)),c!==r?a=i=[i,c]:(Ye=a,a=r)):(Ye=a,a=r));a!==r;)s.push(a),I.test(e.charAt(Ye))?(a=e.charAt(Ye),Ye++):(a=r,ot(F)),a===r&&(a=Ye,92===e.charCodeAt(Ye)?(i=A,Ye++):(i=r,ot(k)),i!==r?(e.length>Ye?(c=e.charAt(Ye),Ye++):(c=r,ot(w)),c!==r?a=i=[i,c]:(Ye=a,a=r)):(Ye=a,a=r));(o=s!==r?e.substring(o,Ye):s)!==r?(34===e.charCodeAt(Ye)?(s=P,Ye++):(s=r,ot(T)),s!==r?t=n=function(e){return{quoteStyle:"double",key:e.replace(/\\"/gu,'"').replace(/\\\\/gu,"\\")}}(o):(Ye=t,t=r)):(Ye=t,t=r)}else Ye=t,t=r;if(t===r){if(t=Ye,39===e.charCodeAt(Ye)?(n=E,Ye++):(n=r,ot(S)),n!==r){for(o=Ye,s=[],C.test(e.charAt(Ye))?(a=e.charAt(Ye),Ye++):(a=r,ot(v)),a===r&&(a=Ye,92===e.charCodeAt(Ye)?(i=A,Ye++):(i=r,ot(k)),i!==r?(e.length>Ye?(c=e.charAt(Ye),Ye++):(c=r,ot(w)),c!==r?a=i=[i,c]:(Ye=a,a=r)):(Ye=a,a=r));a!==r;)s.push(a),C.test(e.charAt(Ye))?(a=e.charAt(Ye),Ye++):(a=r,ot(v)),a===r&&(a=Ye,92===e.charCodeAt(Ye)?(i=A,Ye++):(i=r,ot(k)),i!==r?(e.length>Ye?(c=e.charAt(Ye),Ye++):(c=r,ot(w)),c!==r?a=i=[i,c]:(Ye=a,a=r)):(Ye=a,a=r));(o=s!==r?e.substring(o,Ye):s)!==r?(39===e.charCodeAt(Ye)?(s=E,Ye++):(s=r,ot(S)),s!==r?t=n=function(e){return{quoteStyle:"single",key:e.replace(/\\'/g,"'").replace(/\\\\/gu,"\\")}}(o):(Ye=t,t=r)):(Ye=t,t=r)}else Ye=t,t=r;t===r&&(t=Ye,n=Ye,(o=lt())===r&&(o=Ct()),(n=o!==r?e.substring(n,Ye):o)!==r&&(n=function(e){return{quoteStyle:"none",key:e}}(n)),t=n)}return Ze[l]={nextPos:Ye,result:t},t}function Jt(){var t,n,o,s,a,i=82*Ye+72,c=Ze[i];return c?(Ye=c.nextPos,c.result):(t=Ye,91===e.charCodeAt(Ye)?(n="[",Ye++):(n=r,ot(Oe)),n!==r&&it()!==r&&(o=function(){var t,n,o,s,a,i,c,l=82*Ye+73,u=Ze[l];if(u)return Ye=u.nextPos,u.result;t=Ye,n=[],o=Ye,(s=Kt())!==r&&(a=it())!==r?(44===e.charCodeAt(Ye)?(i=we,Ye++):(i=r,ot(Pe)),i!==r&&(c=it())!==r?o=s=[s,a,i,c]:(Ye=o,o=r)):(Ye=o,o=r);for(;o!==r;)n.push(o),o=Ye,(s=Kt())!==r&&(a=it())!==r?(44===e.charCodeAt(Ye)?(i=we,Ye++):(i=r,ot(Pe)),i!==r&&(c=it())!==r?o=s=[s,a,i,c]:(Ye=o,o=r)):(Ye=o,o=r);n!==r?((o=Ht())===r&&(o=Xt()),o===r&&(o=null),o!==r?t=n=function(e,t){return e.reduceRight(((e,t)=>{let[n]=t;return[n].concat(e)}),t?[t]:[])}(n,o):(Ye=t,t=r)):(Ye=t,t=r);return Ze[l]={nextPos:Ye,result:t},t}())!==r&&it()!==r?(93===e.charCodeAt(Ye)?(s="]",Ye++):(s=r,ot(Be)),s!==r?(a=o,t=n={type:on.TUPLE,entries:a}):(Ye=t,t=r)):(Ye=t,t=r),Ze[i]={nextPos:Ye,result:t},t)}function Kt(){var e,t=82*Ye+74,n=Ze[t];return n?(Ye=n.nextPos,n.result):((e=kt())===r&&(e=vt())===r&&(e=Pt())===r&&(e=Wt())===r&&(e=Jt())===r&&(e=Mt())===r&&(e=_t())===r&&(e=Yt())===r&&(e=Ft())===r&&(e=Dt())===r&&(e=Rt())===r&&(e=jt())===r&&(e=gt())===r&&(e=Et())===r&&(e=xt())===r&&(e=bt()),Ze[t]={nextPos:Ye,result:e},e)}function Yt(){var t,n,o,s,a,i=82*Ye+75,c=Ze[i];return c?(Ye=c.nextPos,c.result):(t=Ye,40===e.charCodeAt(Ye)?(n=be,Ye++):(n=r,ot(Ee)),n!==r&&it()!==r&&(o=function(){var e,t=82*Ye+76,n=Ze[t];if(n)return Ye=n.nextPos,n.result;(e=kt())===r&&(e=vt())===r&&(e=Pt())===r&&(e=Wt())===r&&(e=Jt())===r&&(e=Mt())===r&&(e=_t())===r&&(e=Rt())===r&&(e=Ft())===r&&(e=Dt())===r&&(e=jt())===r&&(e=gt())===r&&(e=Et())===r&&(e=xt())===r&&(e=bt());return Ze[t]={nextPos:Ye,result:e},e}())!==r&&it()!==r?(41===e.charCodeAt(Ye)?(s=Se,Ye++):(s=r,ot(Ce)),s!==r?(a=o,t=n={type:on.PARENTHESIS,value:a}):(Ye=t,t=r)):(Ye=t,t=r),Ze[i]={nextPos:Ye,result:t},t)}function Ht(){var t,n=82*Ye+77,o=Ze[n];return o?(Ye=o.nextPos,o.result):((t=function(){var t,n,o,s=82*Ye+78,a=Ze[s];if(a)return Ye=a.nextPos,a.result;t=Ye,e.substr(Ye,3)===Re?(n=Re,Ye+=3):(n=r,ot(Me));n!==r&&(o=Xt())!==r?(i=o,t=n={type:on.VARIADIC,value:i,meta:{syntax:en.PREFIX_DOTS}}):(Ye=t,t=r);var i;return Ze[s]={nextPos:Ye,result:t},t}())===r&&(t=function(){var t,n,o,s=82*Ye+79,a=Ze[s];if(a)return Ye=a.nextPos,a.result;t=Ye,(n=Xt())!==r?(e.substr(Ye,3)===Re?(o=Re,Ye+=3):(o=r,ot(Me)),o!==r?(i=n,t=n={type:on.VARIADIC,value:i,meta:{syntax:en.SUFFIX_DOTS}}):(Ye=t,t=r)):(Ye=t,t=r);var i;return Ze[s]={nextPos:Ye,result:t},t}())===r&&(t=function(){var t,n,o=82*Ye+80,s=Ze[o];if(s)return Ye=s.nextPos,s.result;t=Ye,e.substr(Ye,3)===Re?(n=Re,Ye+=3):(n=r,ot(Me));n!==r&&(n={type:on.VARIADIC,value:{type:on.ANY},meta:{syntax:en.ONLY_DOTS}});return t=n,Ze[o]={nextPos:Ye,result:t},t}()),Ze[n]={nextPos:Ye,result:t},t)}function Xt(){var e,t=82*Ye+81,n=Ze[t];return n?(Ye=n.nextPos,n.result):((e=kt())===r&&(e=vt())===r&&(e=Pt())===r&&(e=Wt())===r&&(e=Jt())===r&&(e=Mt())===r&&(e=_t())===r&&(e=Yt())===r&&(e=Ft())===r&&(e=Dt())===r&&(e=Rt())===r&&(e=jt())===r&&(e=gt())===r&&(e=Et())===r&&(e=xt())===r&&(e=bt()),Ze[t]={nextPos:Ye,result:e},e)}const Qt=py,{GenericTypeSyntax:Zt,VariadicTypeSyntax:en,OptionalTypeSyntax:tn,NullableTypeSyntax:nn,NotNullableTypeSyntax:rn}=Qt,on=dy,sn={MEMBER:"MEMBER",INNER_MEMBER:"INNER_MEMBER",INSTANCE_MEMBER:"INSTANCE_MEMBER"};if((n=s())!==r&&Ye===e.length)return n;throw n!==r&&Ye0){for(t=1,r=1;t",!1),Ee=We("[",!1),Se=We("]",!1),Ce="function",ve=We("function",!1),Ae="(",ke=We("(",!1),we=")",Pe=We(")",!1),Te="this",Ie=We("this",!1),Fe=We("new",!1),De=We("{",!1),Oe=We("}",!1),Be=";",Ne=We(";",!1),je="readonly",Le=We("readonly",!1),Re="...",Me=We("...",!1),_e=0,$e=[{line:1,column:1}],qe=0,Ue=[],Ve={};if("startRule"in t){if(!(t.startRule in o))throw new Error("Can't start parsing from rule \""+t.startRule+'".');s=o[t.startRule]}function We(e,t){return{type:"literal",text:e,ignoreCase:t}}function Ge(e,t,n){return{type:"class",parts:e,inverted:t,ignoreCase:n}}function ze(t){var n,r=$e[t];if(r)return r;for(n=t-1;!$e[n];)n--;for(r={line:(r=$e[n]).line,column:r.column};nqe&&(qe=_e,Ue=[]),Ue.push(e))}function Ye(){var e,t,n=69*_e+0,o=Ve[n];return o?(_e=o.nextPos,o.result):(e=_e,Xe()!==r?((t=It())===r&&(t=ut())===r&&(t=dt())===r&&(t=Et())===r&&(t=xt())===r&&(t=kt())===r&&(t=St())===r&&(t=rt())===r&&(t=Tt())===r&&(t=ct())===r&&(t=at())===r&&(t=it()),t!==r&&Xe()!==r?e=t:(_e=e,e=r)):(_e=e,e=r),Ve[n]={nextPos:_e,result:e},e)}function He(){var t,n,o,s=69*_e+1,d=Ve[s];return d?(_e=d.nextPos,d.result):(a.test(e.charAt(_e))?(t=e.charAt(_e),_e++):(t=r,Ke(i)),t===r&&(t=_e,c.test(e.charAt(_e))?(n=e.charAt(_e),_e++):(n=r,Ke(l)),n===r&&(n=null),n!==r?(u.test(e.charAt(_e))?(o=e.charAt(_e),_e++):(o=r,Ke(p)),o!==r?t=n=[n,o]:(_e=t,t=r)):(_e=t,t=r)),Ve[s]={nextPos:_e,result:t},t)}function Xe(){var e,t,n=69*_e+2,o=Ve[n];if(o)return _e=o.nextPos,o.result;for(e=[],t=He();t!==r;)e.push(t),t=He();return Ve[n]={nextPos:_e,result:e},e}function Qe(){var e,t,n=69*_e+3,o=Ve[n];if(o)return _e=o.nextPos,o.result;if(e=[],(t=He())!==r)for(;t!==r;)e.push(t),t=He();else e=r;return Ve[n]={nextPos:_e,result:e},e}function Ze(){var t,n,o,s,a,i=69*_e+4,c=Ve[i];if(c)return _e=c.nextPos,c.result;if(t=_e,n=_e,d.test(e.charAt(_e))?(o=e.charAt(_e),_e++):(o=r,Ke(f)),o!==r){for(s=[],m.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(g));a!==r;)s.push(a),m.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(g));s!==r?n=o=[o,s]:(_e=n,n=r)}else _e=n,n=r;return t=n!==r?e.substring(t,_e):n,Ve[i]={nextPos:_e,result:t},t}function et(){var t,n,o,s,a,i,c,l,u,p,m,g=69*_e+5,E=Ve[g];if(E)return _e=E.nextPos,E.result;if(t=_e,(n=Tt())===r&&(n=function(){var t,n,o,s,a,i,c=69*_e+6,l=Ve[c];if(l)return _e=l.nextPos,l.result;t=_e,n=_e,o=_e,d.test(e.charAt(_e))?(s=e.charAt(_e),_e++):(s=r,Ke(f));if(s!==r){for(a=[],x.test(e.charAt(_e))?(i=e.charAt(_e),_e++):(i=r,Ke(b));i!==r;)a.push(i),x.test(e.charAt(_e))?(i=e.charAt(_e),_e++):(i=r,Ke(b));a!==r?o=s=[s,a]:(_e=o,o=r)}else _e=o,o=r;n=o!==r?e.substring(n,_e):o;n!==r&&(n=function(e){return{type:Rt.NAME,name:e}}(n));return t=n,Ve[c]={nextPos:_e,result:t},t}()),n!==r){for(o=[],s=_e,(a=Xe())!==r&&(i=nt())!==r&&(c=Xe())!==r?(e.substr(_e,6)===h?(l=h,_e+=6):(l=r,Ke(y)),l===r&&(l=null),l!==r&&(u=Xe())!==r&&(p=tt())!==r?s=a=[a,i,c,l,u,p]:(_e=s,s=r)):(_e=s,s=r);s!==r;)o.push(s),s=_e,(a=Xe())!==r&&(i=nt())!==r&&(c=Xe())!==r?(e.substr(_e,6)===h?(l=h,_e+=6):(l=r,Ke(y)),l===r&&(l=null),l!==r&&(u=Xe())!==r&&(p=tt())!==r?s=a=[a,i,c,l,u,p]:(_e=s,s=r)):(_e=s,s=r);o!==r?(m=n,t=n=o.reduce((function(e,t){const n=t[1],r=t[3],o=t[5],{quoteStyle:s,name:a}=o;switch(n){case Mt.MEMBER:return{type:Rt.MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};case Mt.INSTANCE_MEMBER:return{type:Rt.INSTANCE_MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};case Mt.INNER_MEMBER:return{type:Rt.INNER_MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};default:throw new Error('Unexpected operator type: "'+n+'"')}}),m)):(_e=t,t=r)}else _e=t,t=r;return Ve[g]={nextPos:_e,result:t},t}function tt(){var t,n,o,s,a,i,c,l=69*_e+7,u=Ve[l];if(u)return _e=u.nextPos,u.result;if(t=_e,39===e.charCodeAt(_e)?(n=E,_e++):(n=r,Ke(S)),n!==r){for(o=_e,s=[],C.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(v)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));a!==r;)s.push(a),C.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(v)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));(o=s!==r?e.substring(o,_e):s)!==r?(39===e.charCodeAt(_e)?(s=E,_e++):(s=r,Ke(S)),s!==r?t=n=function(e){return{quoteStyle:"single",name:e.replace(/\\'/g,"'").replace(/\\\\/gu,"\\")}}(o):(_e=t,t=r)):(_e=t,t=r)}else _e=t,t=r;if(t===r){if(t=_e,34===e.charCodeAt(_e)?(n=P,_e++):(n=r,Ke(T)),n!==r){for(o=_e,s=[],I.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(F)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));a!==r;)s.push(a),I.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(F)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));(o=s!==r?e.substring(o,_e):s)!==r?(34===e.charCodeAt(_e)?(s=P,_e++):(s=r,Ke(T)),s!==r?t=n=function(e){return{quoteStyle:"double",name:e.replace(/\\"/gu,'"').replace(/\\\\/gu,"\\")}}(o):(_e=t,t=r)):(_e=t,t=r)}else _e=t,t=r;t===r&&(t=_e,(n=Ze())!==r&&(n=function(e){return{quoteStyle:"none",name:e}}(n)),t=n)}return Ve[l]={nextPos:_e,result:t},t}function nt(){var t,n=69*_e+8,o=Ve[n];return o?(_e=o.nextPos,o.result):((t=function(){var t,n,o=69*_e+10,s=Ve[o];if(s)return _e=s.nextPos,s.result;t=_e,46===e.charCodeAt(_e)?(n=D,_e++):(n=r,Ke(O));n!==r&&(n=Mt.MEMBER);return t=n,Ve[o]={nextPos:_e,result:t},t}())===r&&(t=function(){var t,n,o=69*_e+12,s=Ve[o];if(s)return _e=s.nextPos,s.result;t=_e,35===e.charCodeAt(_e)?(n="#",_e++):(n=r,Ke(N));n!==r&&(n=Mt.INSTANCE_MEMBER);return t=n,Ve[o]={nextPos:_e,result:t},t}())===r&&(t=function(){var t,n,o=69*_e+11,s=Ve[o];if(s)return _e=s.nextPos,s.result;t=_e,126===e.charCodeAt(_e)?(n="~",_e++):(n=r,Ke(B));n!==r&&(n=Mt.INNER_MEMBER);return t=n,Ve[o]={nextPos:_e,result:t},t}()),Ve[n]={nextPos:_e,result:t},t)}function rt(){var e,t=69*_e+13,n=Ve[t];return n?(_e=n.nextPos,n.result):((e=ot())===r&&(e=st())===r&&(e=et()),Ve[t]={nextPos:_e,result:e},e)}function ot(){var t,n,o,s,a,i,c,l,u,p,d,f,m,g=69*_e+14,x=Ve[g];if(x)return _e=x.nextPos,x.result;if(t=_e,e.substr(_e,8)===j?(n=j,_e+=8):(n=r,Ke(L)),n!==r)if(Xe()!==r)if(58===e.charCodeAt(_e)?(o=R,_e++):(o=r,Ke(M)),o!==r)if(Xe()!==r)if((s=tt())!==r){for(a=[],i=_e,(c=Xe())!==r&&(l=nt())!==r&&(u=Xe())!==r?(e.substr(_e,6)===h?(p=h,_e+=6):(p=r,Ke(y)),p===r&&(p=null),p!==r&&(d=Xe())!==r&&(f=tt())!==r?i=c=[c,l,u,p,d,f]:(_e=i,i=r)):(_e=i,i=r);i!==r;)a.push(i),i=_e,(c=Xe())!==r&&(l=nt())!==r&&(u=Xe())!==r?(e.substr(_e,6)===h?(p=h,_e+=6):(p=r,Ke(y)),p===r&&(p=null),p!==r&&(d=Xe())!==r&&(f=tt())!==r?i=c=[c,l,u,p,d,f]:(_e=i,i=r)):(_e=i,i=r);a!==r?(m=s,t=n=a.reduce((function(e,t){const n=t[1],r=t[3],o=t[5],{quoteStyle:s,name:a}=o;switch(n){case Mt.MEMBER:return{type:Rt.MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};case Mt.INSTANCE_MEMBER:return{type:Rt.INSTANCE_MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};case Mt.INNER_MEMBER:return{type:Rt.INNER_MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};default:throw new Error('Unexpected operator type: "'+n+'"')}}),Object.assign({type:Rt.EXTERNAL},m))):(_e=t,t=r)}else _e=t,t=r;else _e=t,t=r;else _e=t,t=r;else _e=t,t=r;else _e=t,t=r;return Ve[g]={nextPos:_e,result:t},t}function st(){var t,n,o,s,a,i=69*_e+15,c=Ve[i];return c?(_e=c.nextPos,c.result):(t=_e,e.substr(_e,6)===_?(n=_,_e+=6):(n=r,Ke($)),n!==r&&Xe()!==r?(58===e.charCodeAt(_e)?(o=R,_e++):(o=r,Ke(M)),o!==r&&Xe()!==r&&(s=function(){var t,n,o,s,a,i,c,l,u,p,d=69*_e+16,f=Ve[d];if(f)return _e=f.nextPos,f.result;if(t=_e,(n=function(){var t,n,o,s,a,i,c,l=69*_e+17,u=Ve[l];if(u)return _e=u.nextPos,u.result;t=_e,39===e.charCodeAt(_e)?(n=E,_e++):(n=r,Ke(S));if(n!==r){for(o=_e,s=[],C.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(v)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));a!==r;)s.push(a),C.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(v)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));(o=s!==r?e.substring(o,_e):s)!==r?(39===e.charCodeAt(_e)?(s=E,_e++):(s=r,Ke(S)),s!==r?t=n=function(e){return{quoteStyle:"single",type:Rt.FILE_PATH,path:e.replace(/\\'/g,"'").replace(/\\\\/gu,"\\")}}(o):(_e=t,t=r)):(_e=t,t=r)}else _e=t,t=r;if(t===r){if(t=_e,34===e.charCodeAt(_e)?(n=P,_e++):(n=r,Ke(T)),n!==r){for(o=_e,s=[],I.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(F)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));a!==r;)s.push(a),I.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(F)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));(o=s!==r?e.substring(o,_e):s)!==r?(34===e.charCodeAt(_e)?(s=P,_e++):(s=r,Ke(T)),s!==r?t=n=function(e){return{quoteStyle:"double",type:Rt.FILE_PATH,path:e.replace(/\\"/gu,'"').replace(/\\\\/gu,"\\")}}(o):(_e=t,t=r)):(_e=t,t=r)}else _e=t,t=r;if(t===r){if(t=_e,n=_e,o=[],q.test(e.charAt(_e))?(s=e.charAt(_e),_e++):(s=r,Ke(U)),s!==r)for(;s!==r;)o.push(s),q.test(e.charAt(_e))?(s=e.charAt(_e),_e++):(s=r,Ke(U));else o=r;(n=o!==r?e.substring(n,_e):o)!==r&&(n=function(e){return{quoteStyle:"none",type:Rt.FILE_PATH,path:e}}(n)),t=n}}return Ve[l]={nextPos:_e,result:t},t}())!==r){for(o=[],s=_e,(a=Xe())!==r&&(i=nt())!==r&&(c=Xe())!==r?(e.substr(_e,6)===h?(l=h,_e+=6):(l=r,Ke(y)),l===r&&(l=null),l!==r&&(u=Xe())!==r&&(p=tt())!==r?s=a=[a,i,c,l,u,p]:(_e=s,s=r)):(_e=s,s=r);s!==r;)o.push(s),s=_e,(a=Xe())!==r&&(i=nt())!==r&&(c=Xe())!==r?(e.substr(_e,6)===h?(l=h,_e+=6):(l=r,Ke(y)),l===r&&(l=null),l!==r&&(u=Xe())!==r&&(p=tt())!==r?s=a=[a,i,c,l,u,p]:(_e=s,s=r)):(_e=s,s=r);o!==r?(m=n,t=n=o.reduce((function(e,t){const n=t[1],r=t[3],o=t[5],{quoteStyle:s,name:a}=o;switch(n){case Mt.MEMBER:return{type:Rt.MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};case Mt.INSTANCE_MEMBER:return{type:Rt.INSTANCE_MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};case Mt.INNER_MEMBER:return{type:Rt.INNER_MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};default:throw new Error('Unexpected operator type: "'+n+'"')}}),m)):(_e=t,t=r)}else _e=t,t=r;var m;return Ve[d]={nextPos:_e,result:t},t}())!==r?(a=s,t=n={type:Rt.MODULE,value:a}):(_e=t,t=r)):(_e=t,t=r),Ve[i]={nextPos:_e,result:t},t)}function at(){var t,n,o=69*_e+18,s=Ve[o];return s?(_e=s.nextPos,s.result):(_e,42===e.charCodeAt(_e)?(n="*",_e++):(n=r,Ke(V)),n!==r&&(n={type:Rt.ANY}),t=n,Ve[o]={nextPos:_e,result:t},t)}function it(){var t,n,o=69*_e+19,s=Ve[o];return s?(_e=s.nextPos,s.result):(_e,63===e.charCodeAt(_e)?(n=W,_e++):(n=r,Ke(G)),n!==r&&(n={type:Rt.UNKNOWN}),t=n,Ve[o]={nextPos:_e,result:t},t)}function ct(){var t,n=69*_e+20,o=Ve[n];return o?(_e=o.nextPos,o.result):((t=function(){var t,n,o,s,a,i,c,l=69*_e+21,u=Ve[l];if(u)return _e=u.nextPos,u.result;t=_e,34===e.charCodeAt(_e)?(n=P,_e++):(n=r,Ke(T));if(n!==r){for(o=_e,s=[],I.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(F)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));a!==r;)s.push(a),I.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(F)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));(o=s!==r?e.substring(o,_e):s)!==r?(34===e.charCodeAt(_e)?(s=P,_e++):(s=r,Ke(T)),s!==r?(p=o,t=n={type:Rt.STRING_VALUE,quoteStyle:"double",string:p.replace(/\\"/gu,'"').replace(/\\\\/gu,"\\")}):(_e=t,t=r)):(_e=t,t=r)}else _e=t,t=r;var p;if(t===r)if(t=_e,39===e.charCodeAt(_e)?(n=E,_e++):(n=r,Ke(S)),n!==r){for(o=_e,s=[],C.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(v)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));a!==r;)s.push(a),C.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(v)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));(o=s!==r?e.substring(o,_e):s)!==r?(39===e.charCodeAt(_e)?(s=E,_e++):(s=r,Ke(S)),s!==r?t=n=function(e){return{type:Rt.STRING_VALUE,quoteStyle:"single",string:e.replace(/\\'/g,"'").replace(/\\\\/gu,"\\")}}(o):(_e=t,t=r)):(_e=t,t=r)}else _e=t,t=r;return Ve[l]={nextPos:_e,result:t},t}())===r&&(t=function(){var t,n,o=69*_e+22,s=Ve[o];if(s)return _e=s.nextPos,s.result;t=_e,(n=function(){var t,n,o,s,a,i,c=69*_e+25,l=Ve[c];if(l)return _e=l.nextPos,l.result;t=_e,n=_e,45===e.charCodeAt(_e)?(o=J,_e++):(o=r,Ke(K));o===r&&(o=null);if(o!==r)if(e.substr(_e,2)===Q?(s=Q,_e+=2):(s=r,Ke(Z)),s!==r){if(a=[],ee.test(e.charAt(_e))?(i=e.charAt(_e),_e++):(i=r,Ke(te)),i!==r)for(;i!==r;)a.push(i),ee.test(e.charAt(_e))?(i=e.charAt(_e),_e++):(i=r,Ke(te));else a=r;a!==r?n=o=[o,s,a]:(_e=n,n=r)}else _e=n,n=r;else _e=n,n=r;t=n!==r?e.substring(t,_e):n;return Ve[c]={nextPos:_e,result:t},t}())===r&&(n=function(){var t,n,o,s,a,i,c=69*_e+26,l=Ve[c];if(l)return _e=l.nextPos,l.result;t=_e,n=_e,45===e.charCodeAt(_e)?(o=J,_e++):(o=r,Ke(K));o===r&&(o=null);if(o!==r)if(e.substr(_e,2)===ne?(s=ne,_e+=2):(s=r,Ke(re)),s!==r){if(a=[],oe.test(e.charAt(_e))?(i=e.charAt(_e),_e++):(i=r,Ke(se)),i!==r)for(;i!==r;)a.push(i),oe.test(e.charAt(_e))?(i=e.charAt(_e),_e++):(i=r,Ke(se));else a=r;a!==r?n=o=[o,s,a]:(_e=n,n=r)}else _e=n,n=r;else _e=n,n=r;t=n!==r?e.substring(t,_e):n;return Ve[c]={nextPos:_e,result:t},t}())===r&&(n=function(){var t,n,o,s,a,i,c=69*_e+27,l=Ve[c];if(l)return _e=l.nextPos,l.result;t=_e,n=_e,45===e.charCodeAt(_e)?(o=J,_e++):(o=r,Ke(K));o===r&&(o=null);if(o!==r)if(e.substr(_e,2)===ae?(s=ae,_e+=2):(s=r,Ke(ie)),s!==r){if(a=[],ce.test(e.charAt(_e))?(i=e.charAt(_e),_e++):(i=r,Ke(le)),i!==r)for(;i!==r;)a.push(i),ce.test(e.charAt(_e))?(i=e.charAt(_e),_e++):(i=r,Ke(le));else a=r;a!==r?n=o=[o,s,a]:(_e=n,n=r)}else _e=n,n=r;else _e=n,n=r;t=n!==r?e.substring(t,_e):n;return Ve[c]={nextPos:_e,result:t},t}())===r&&(n=function(){var t,n,o,s,a=69*_e+23,i=Ve[a];if(i)return _e=i.nextPos,i.result;t=_e,n=_e,43===e.charCodeAt(_e)?(o="+",_e++):(o=r,Ke(z));o===r&&(45===e.charCodeAt(_e)?(o=J,_e++):(o=r,Ke(K)));o===r&&(o=null);o!==r&&(s=lt())!==r?n=o=[o,s]:(_e=n,n=r);t=n!==r?e.substring(t,_e):n;return Ve[a]={nextPos:_e,result:t},t}());n!==r&&(a=n,n={type:Rt.NUMBER_VALUE,number:a});var a;return t=n,Ve[o]={nextPos:_e,result:t},t}()),Ve[n]={nextPos:_e,result:t},t)}function lt(){var t,n,o,s,a,i,c,l,u=69*_e+24,p=Ve[u];if(p)return _e=p.nextPos,p.result;if(t=_e,n=_e,o=_e,s=[],Y.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(H)),a!==r)for(;a!==r;)s.push(a),Y.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(H));else s=r;if(s!==r){if(a=_e,46===e.charCodeAt(_e)?(i=D,_e++):(i=r,Ke(O)),i!==r){if(c=[],Y.test(e.charAt(_e))?(l=e.charAt(_e),_e++):(l=r,Ke(H)),l!==r)for(;l!==r;)c.push(l),Y.test(e.charAt(_e))?(l=e.charAt(_e),_e++):(l=r,Ke(H));else c=r;c!==r?a=i=[i,c]:(_e=a,a=r)}else _e=a,a=r;a===r&&(a=null),a!==r?o=s=[s,a]:(_e=o,o=r)}else _e=o,o=r;if(o===r)if(o=_e,46===e.charCodeAt(_e)?(s=D,_e++):(s=r,Ke(O)),s!==r){if(a=[],Y.test(e.charAt(_e))?(i=e.charAt(_e),_e++):(i=r,Ke(H)),i!==r)for(;i!==r;)a.push(i),Y.test(e.charAt(_e))?(i=e.charAt(_e),_e++):(i=r,Ke(H));else a=r;a!==r?o=s=[s,a]:(_e=o,o=r)}else _e=o,o=r;if(o!==r){if(s=_e,101===e.charCodeAt(_e)?(a="e",_e++):(a=r,Ke(X)),a!==r)if(43===e.charCodeAt(_e)?(i="+",_e++):(i=r,Ke(z)),i===r&&(45===e.charCodeAt(_e)?(i=J,_e++):(i=r,Ke(K))),i===r&&(i=null),i!==r){if(c=[],Y.test(e.charAt(_e))?(l=e.charAt(_e),_e++):(l=r,Ke(H)),l!==r)for(;l!==r;)c.push(l),Y.test(e.charAt(_e))?(l=e.charAt(_e),_e++):(l=r,Ke(H));else c=r;c!==r?s=a=[a,i,c]:(_e=s,s=r)}else _e=s,s=r;else _e=s,s=r;s===r&&(s=null),s!==r?n=o=[o,s]:(_e=n,n=r)}else _e=n,n=r;return t=n!==r?e.substring(t,_e):n,Ve[u]={nextPos:_e,result:t},t}function ut(){var t,n,o,s,a,i,c=69*_e+28,l=Ve[c];return l?(_e=l.nextPos,l.result):(t=_e,(n=pt())!==r&&Xe()!==r?(124===e.charCodeAt(_e)?(o="|",_e++):(o=r,Ke(ue)),o!==r&&Xe()!==r?((s=ut())===r&&(s=pt()),s!==r?(a=n,i=s,t=n={type:Rt.UNION,left:a,right:i}):(_e=t,t=r)):(_e=t,t=r)):(_e=t,t=r),Ve[c]={nextPos:_e,result:t},t)}function pt(){var e,t=69*_e+29,n=Ve[t];return n?(_e=n.nextPos,n.result):((e=dt())===r&&(e=kt())===r&&(e=St())===r&&(e=Tt())===r&&(e=xt())===r&&(e=Et())===r&&(e=rt())===r&&(e=ct())===r&&(e=at())===r&&(e=it()),Ve[t]={nextPos:_e,result:e},e)}function dt(){var t,n=69*_e+30,o=Ve[n];return o?(_e=o.nextPos,o.result):((t=function(){var t,n=69*_e+36,o=Ve[n];if(o)return _e=o.nextPos,o.result;(t=function(){var t,n,o,s=69*_e+40,a=Ve[s];if(a)return _e=a.nextPos,a.result;t=_e,(n=ht())===r&&(n=yt())===r&&(n=gt());n!==r&&Xe()!==r?(61===e.charCodeAt(_e)?(o="=",_e++):(o=r,Ke(fe)),o!==r?(i=n,t=n={type:Rt.OPTIONAL,value:i,meta:{syntax:Nt.SUFFIX_EQUALS_SIGN}}):(_e=t,t=r)):(_e=t,t=r);var i;return Ve[s]={nextPos:_e,result:t},t}())===r&&(t=ht())===r&&(t=yt());return Ve[n]={nextPos:_e,result:t},t}())===r&&(t=ft()),Ve[n]={nextPos:_e,result:t},t)}function ft(){var t,n=69*_e+31,o=Ve[n];return o?(_e=o.nextPos,o.result):((t=function(){var t,n,o,s=69*_e+35,a=Ve[s];if(a)return _e=a.nextPos,a.result;t=_e,61===e.charCodeAt(_e)?(n=de,_e++):(n=r,Ke(fe));n!==r&&Xe()!==r&&(o=mt())!==r?(i=o,t=n={type:Rt.OPTIONAL,value:i,meta:{syntax:Nt.PREFIX_EQUALS_SIGN}}):(_e=t,t=r);var i;return Ve[s]={nextPos:_e,result:t},t}())===r&&(t=function(){var t,n,o,s=69*_e+34,a=Ve[s];if(a)return _e=a.nextPos,a.result;t=_e,33===e.charCodeAt(_e)?(n="!",_e++):(n=r,Ke(pe));n!==r&&Xe()!==r&&(o=mt())!==r?(i=o,t=n={type:Rt.NOT_NULLABLE,value:i,meta:{syntax:Lt.PREFIX_BANG}}):(_e=t,t=r);var i;return Ve[s]={nextPos:_e,result:t},t}())===r&&(t=function(){var t,n,o,s=69*_e+33,a=Ve[s];if(a)return _e=a.nextPos,a.result;t=_e,63===e.charCodeAt(_e)?(n=W,_e++):(n=r,Ke(G));n!==r&&Xe()!==r&&(o=mt())!==r?(i=o,t=n={type:Rt.NULLABLE,value:i,meta:{syntax:jt.PREFIX_QUESTION_MARK}}):(_e=t,t=r);var i;return Ve[s]={nextPos:_e,result:t},t}()),Ve[n]={nextPos:_e,result:t},t)}function mt(){var e,t=69*_e+32,n=Ve[t];return n?(_e=n.nextPos,n.result):((e=xt())===r&&(e=kt())===r&&(e=St())===r&&(e=Tt())===r&&(e=rt())===r&&(e=ct())===r&&(e=at())===r&&(e=it()),Ve[t]={nextPos:_e,result:e},e)}function gt(){var e,t=69*_e+37,n=Ve[t];return n?(_e=n.nextPos,n.result):((e=ft())===r&&(e=xt())===r&&(e=kt())===r&&(e=St())===r&&(e=Tt())===r&&(e=rt())===r&&(e=ct())===r&&(e=at())===r&&(e=it()),Ve[t]={nextPos:_e,result:e},e)}function ht(){var t,n,o,s,a=69*_e+38,i=Ve[a];return i?(_e=i.nextPos,i.result):(t=_e,(n=gt())!==r&&Xe()!==r?(63===e.charCodeAt(_e)?(o=W,_e++):(o=r,Ke(G)),o!==r?(s=n,t=n={type:Rt.NULLABLE,value:s,meta:{syntax:jt.SUFFIX_QUESTION_MARK}}):(_e=t,t=r)):(_e=t,t=r),Ve[a]={nextPos:_e,result:t},t)}function yt(){var t,n,o,s,a=69*_e+39,i=Ve[a];return i?(_e=i.nextPos,i.result):(t=_e,(n=gt())!==r&&Xe()!==r?(33===e.charCodeAt(_e)?(o="!",_e++):(o=r,Ke(pe)),o!==r?(s=n,t=n={type:Rt.NOT_NULLABLE,value:s,meta:{syntax:Lt.SUFFIX_BANG}}):(_e=t,t=r)):(_e=t,t=r),Ve[a]={nextPos:_e,result:t},t)}function xt(){var t,n,o,s,a,i,c,l=69*_e+41,u=Ve[l];return u?(_e=u.nextPos,u.result):(t=_e,(n=function(){var e,t=69*_e+42,n=Ve[t];if(n)return _e=n.nextPos,n.result;(e=Tt())===r&&(e=rt())===r&&(e=ct())===r&&(e=at())===r&&(e=it());return Ve[t]={nextPos:_e,result:e},e}())!==r&&Xe()!==r&&(o=function(){var t,n=69*_e+45,o=Ve[n];if(o)return _e=o.nextPos,o.result;(t=function(){var t,n,o=69*_e+46,s=Ve[o];if(s)return _e=s.nextPos,s.result;t=_e,e.substr(_e,2)===he?(n=he,_e+=2):(n=r,Ke(ye));n!==r&&(n=Ot.ANGLE_BRACKET_WITH_DOT);return t=n,Ve[o]={nextPos:_e,result:t},t}())===r&&(t=function(){var t,n,o=69*_e+47,s=Ve[o];if(s)return _e=s.nextPos,s.result;t=_e,60===e.charCodeAt(_e)?(n="<",_e++):(n=r,Ke(xe));n!==r&&(n=Ot.ANGLE_BRACKET);return t=n,Ve[o]={nextPos:_e,result:t},t}());return Ve[n]={nextPos:_e,result:t},t}())!==r&&Xe()!==r&&(s=function(){var t,n,o,s,a,i,c,l,u=69*_e+44,p=Ve[u];if(p)return _e=p.nextPos,p.result;if(t=_e,(n=bt())!==r){for(o=[],s=_e,(a=Xe())!==r?(44===e.charCodeAt(_e)?(i=me,_e++):(i=r,Ke(ge)),i!==r&&(c=Xe())!==r&&(l=bt())!==r?s=a=[a,i,c,l]:(_e=s,s=r)):(_e=s,s=r);s!==r;)o.push(s),s=_e,(a=Xe())!==r?(44===e.charCodeAt(_e)?(i=me,_e++):(i=r,Ke(ge)),i!==r&&(c=Xe())!==r&&(l=bt())!==r?s=a=[a,i,c,l]:(_e=s,s=r)):(_e=s,s=r);o!==r?(d=n,t=n=o.reduce((function(e,t){return e.concat([t[3]])}),[d])):(_e=t,t=r)}else _e=t,t=r;var d;return Ve[u]={nextPos:_e,result:t},t}())!==r&&Xe()!==r&&function(){var t,n=69*_e+48,o=Ve[n];if(o)return _e=o.nextPos,o.result;62===e.charCodeAt(_e)?(t=">",_e++):(t=r,Ke(be));return Ve[n]={nextPos:_e,result:t},t}()!==r?(a=n,i=o,c=s,t=n={type:Rt.GENERIC,subject:a,objects:c,meta:{syntax:i}}):(_e=t,t=r),Ve[l]={nextPos:_e,result:t},t)}function bt(){var e,t=69*_e+43,n=Ve[t];return n?(_e=n.nextPos,n.result):((e=ut())===r&&(e=dt())===r&&(e=kt())===r&&(e=St())===r&&(e=Tt())===r&&(e=Et())===r&&(e=xt())===r&&(e=rt())===r&&(e=ct())===r&&(e=at())===r&&(e=it()),Ve[t]={nextPos:_e,result:e},e)}function Et(){var t,n,o,s,a,i,c,l,u,p=69*_e+49,d=Ve[p];if(d)return _e=d.nextPos,d.result;if(t=_e,(n=function(){var e,t=69*_e+50,n=Ve[t];if(n)return _e=n.nextPos,n.result;(e=dt())===r&&(e=kt())===r&&(e=St())===r&&(e=Tt())===r&&(e=xt())===r&&(e=rt())===r&&(e=ct())===r&&(e=at())===r&&(e=it());return Ve[t]={nextPos:_e,result:e},e}())!==r){if(o=[],s=_e,(a=Xe())!==r?(91===e.charCodeAt(_e)?(i="[",_e++):(i=r,Ke(Ee)),i!==r&&(c=Xe())!==r?(93===e.charCodeAt(_e)?(l="]",_e++):(l=r,Ke(Se)),l!==r?s=a=[a,i,c,l]:(_e=s,s=r)):(_e=s,s=r)):(_e=s,s=r),s!==r)for(;s!==r;)o.push(s),s=_e,(a=Xe())!==r?(91===e.charCodeAt(_e)?(i="[",_e++):(i=r,Ke(Ee)),i!==r&&(c=Xe())!==r?(93===e.charCodeAt(_e)?(l="]",_e++):(l=r,Ke(Se)),l!==r?s=a=[a,i,c,l]:(_e=s,s=r)):(_e=s,s=r)):(_e=s,s=r);else o=r;o!==r?(u=n,t=n=o.reduce((function(e){return{type:Rt.GENERIC,subject:{type:Rt.NAME,name:"Array"},objects:[e],meta:{syntax:Ot.SQUARE_BRACKET}}}),u)):(_e=t,t=r)}else _e=t,t=r;return Ve[p]={nextPos:_e,result:t},t}function St(){var t,n,o,s,a,i,c,l=69*_e+51,u=Ve[l];return u?(_e=u.nextPos,u.result):(t=_e,e.substr(_e,8)===Ce?(n=Ce,_e+=8):(n=r,Ke(ve)),n!==r&&Xe()!==r&&(o=function(){var t,n,o,s,a,i,c=69*_e+52,l=Ve[c];if(l)return _e=l.nextPos,l.result;t=_e,40===e.charCodeAt(_e)?(n=Ae,_e++):(n=r,Ke(ke));n!==r&&Xe()!==r&&(o=Ct())!==r&&Xe()!==r?(44===e.charCodeAt(_e)?(s=me,_e++):(s=r,Ke(ge)),s!==r&&Xe()!==r&&(a=vt())!==r&&Xe()!==r?(41===e.charCodeAt(_e)?(i=we,_e++):(i=r,Ke(Pe)),i!==r?t=n={params:a,modifier:o}:(_e=t,t=r)):(_e=t,t=r)):(_e=t,t=r);t===r&&(t=_e,40===e.charCodeAt(_e)?(n=Ae,_e++):(n=r,Ke(ke)),n!==r&&Xe()!==r&&(o=Ct())!==r&&Xe()!==r?(41===e.charCodeAt(_e)?(s=we,_e++):(s=r,Ke(Pe)),s!==r?t=n=function(e){return{params:[],modifier:e}}(o):(_e=t,t=r)):(_e=t,t=r),t===r&&(t=_e,40===e.charCodeAt(_e)?(n=Ae,_e++):(n=r,Ke(ke)),n!==r&&Xe()!==r?(41===e.charCodeAt(_e)?(o=we,_e++):(o=r,Ke(Pe)),o!==r?t=n={params:[],modifier:{nodeThis:null,nodeNew:null}}:(_e=t,t=r)):(_e=t,t=r),t===r&&(t=_e,40===e.charCodeAt(_e)?(n=Ae,_e++):(n=r,Ke(ke)),n!==r&&Xe()!==r&&(o=vt())!==r&&Xe()!==r?(41===e.charCodeAt(_e)?(s=we,_e++):(s=r,Ke(Pe)),s!==r?t=n=function(e){return{params:e,modifier:{nodeThis:null,nodeNew:null}}}(o):(_e=t,t=r)):(_e=t,t=r))));return Ve[c]={nextPos:_e,result:t},t}())!==r&&Xe()!==r?(s=_e,58===e.charCodeAt(_e)?(a=R,_e++):(a=r,Ke(M)),a!==r&&(i=Xe())!==r&&(c=function(){var e,t=69*_e+56,n=Ve[t];if(n)return _e=n.nextPos,n.result;(e=ft())===r&&(e=kt())===r&&(e=St())===r&&(e=Tt())===r&&(e=Et())===r&&(e=xt())===r&&(e=rt())===r&&(e=ct())===r&&(e=at())===r&&(e=it());return Ve[t]={nextPos:_e,result:e},e}())!==r?s=a=[a,i,c]:(_e=s,s=r),s===r&&(s=null),s!==r?t=n=function(e,t){const n=t?t[2]:null;return{type:Rt.FUNCTION,params:e.params,returns:n,this:e.modifier.nodeThis,new:e.modifier.nodeNew}}(o,s):(_e=t,t=r)):(_e=t,t=r),Ve[l]={nextPos:_e,result:t},t)}function Ct(){var t,n,o,s,a,i,c,l=69*_e+53,u=Ve[l];return u?(_e=u.nextPos,u.result):(t=_e,n=_e,e.substr(_e,4)===Te?(o=Te,_e+=4):(o=r,Ke(Ie)),o!==r&&(s=Xe())!==r?(58===e.charCodeAt(_e)?(a=R,_e++):(a=r,Ke(M)),a!==r&&(i=Xe())!==r&&(c=At())!==r?n=o=[o,s,a,i,c]:(_e=n,n=r)):(_e=n,n=r),n!==r&&(n={nodeThis:n[4],nodeNew:null}),(t=n)===r&&(t=_e,n=_e,"new"===e.substr(_e,3)?(o="new",_e+=3):(o=r,Ke(Fe)),o!==r&&(s=Xe())!==r?(58===e.charCodeAt(_e)?(a=R,_e++):(a=r,Ke(M)),a!==r&&(i=Xe())!==r&&(c=At())!==r?n=o=[o,s,a,i,c]:(_e=n,n=r)):(_e=n,n=r),n!==r&&(n={nodeThis:null,nodeNew:n[4]}),t=n),Ve[l]={nextPos:_e,result:t},t)}function vt(){var t,n,o,s,a,i,c,l,u=69*_e+54,p=Ve[u];if(p)return _e=p.nextPos,p.result;for(t=_e,n=[],o=_e,(s=At())!==r&&(a=Xe())!==r?(44===e.charCodeAt(_e)?(i=me,_e++):(i=r,Ke(ge)),i!==r&&(c=Xe())!==r?o=s=[s,a,i,c]:(_e=o,o=r)):(_e=o,o=r);o!==r;)n.push(o),o=_e,(s=At())!==r&&(a=Xe())!==r?(44===e.charCodeAt(_e)?(i=me,_e++):(i=r,Ke(ge)),i!==r&&(c=Xe())!==r?o=s=[s,a,i,c]:(_e=o,o=r)):(_e=o,o=r);return n!==r?((o=It())===r&&(o=Ft()),o===r&&(o=null),o!==r?(l=o,t=n=n.reduceRight((function(e,t){const[n]=t;return[n].concat(e)}),l?[l]:[])):(_e=t,t=r)):(_e=t,t=r),Ve[u]={nextPos:_e,result:t},t}function At(){var e,t=69*_e+55,n=Ve[t];return n?(_e=n.nextPos,n.result):((e=ut())===r&&(e=dt())===r&&(e=kt())===r&&(e=St())===r&&(e=Tt())===r&&(e=Et())===r&&(e=xt())===r&&(e=rt())===r&&(e=ct())===r&&(e=at())===r&&(e=it()),Ve[t]={nextPos:_e,result:e},e)}function kt(){var t,n,o,s,d,f=69*_e+57,m=Ve[f];return m?(_e=m.nextPos,m.result):(t=_e,123===e.charCodeAt(_e)?(n="{",_e++):(n=r,Ke(De)),n!==r&&Xe()!==r?((o=function(){var t,n,o,s,d,f,m,g,h=69*_e+58,y=Ve[h];if(y)return _e=y.nextPos,y.result;if(t=_e,(n=wt())!==r){if(o=[],s=_e,d=_e,(f=Xe())!==r?(44===e.charCodeAt(_e)?(m=me,_e++):(m=r,Ke(ge)),m!==r?d=f=[f,m]:(_e=d,d=r)):(_e=d,d=r),d===r&&(d=_e,(f=Xe())!==r?(59===e.charCodeAt(_e)?(m=Be,_e++):(m=r,Ke(Ne)),m!==r?d=f=[f,m]:(_e=d,d=r)):(_e=d,d=r),d===r)){for(d=_e,f=[],a.test(e.charAt(_e))?(m=e.charAt(_e),_e++):(m=r,Ke(i));m!==r;)f.push(m),a.test(e.charAt(_e))?(m=e.charAt(_e),_e++):(m=r,Ke(i));f!==r?(c.test(e.charAt(_e))?(m=e.charAt(_e),_e++):(m=r,Ke(l)),m===r&&(m=null),m!==r?(u.test(e.charAt(_e))?(g=e.charAt(_e),_e++):(g=r,Ke(p)),g!==r?d=f=[f,m,g]:(_e=d,d=r)):(_e=d,d=r)):(_e=d,d=r)}for(d!==r&&(f=Xe())!==r&&(m=wt())!==r?s=d=[d,f,m]:(_e=s,s=r);s!==r;){if(o.push(s),s=_e,d=_e,(f=Xe())!==r?(44===e.charCodeAt(_e)?(m=me,_e++):(m=r,Ke(ge)),m!==r?d=f=[f,m]:(_e=d,d=r)):(_e=d,d=r),d===r&&(d=_e,(f=Xe())!==r?(59===e.charCodeAt(_e)?(m=Be,_e++):(m=r,Ke(Ne)),m!==r?d=f=[f,m]:(_e=d,d=r)):(_e=d,d=r),d===r)){for(d=_e,f=[],a.test(e.charAt(_e))?(m=e.charAt(_e),_e++):(m=r,Ke(i));m!==r;)f.push(m),a.test(e.charAt(_e))?(m=e.charAt(_e),_e++):(m=r,Ke(i));f!==r?(c.test(e.charAt(_e))?(m=e.charAt(_e),_e++):(m=r,Ke(l)),m===r&&(m=null),m!==r?(u.test(e.charAt(_e))?(g=e.charAt(_e),_e++):(g=r,Ke(p)),g!==r?d=f=[f,m,g]:(_e=d,d=r)):(_e=d,d=r)):(_e=d,d=r)}d!==r&&(f=Xe())!==r&&(m=wt())!==r?s=d=[d,f,m]:(_e=s,s=r)}if(o!==r){if(s=_e,(d=Xe())!==r?(44===e.charCodeAt(_e)?(f=me,_e++):(f=r,Ke(ge)),f!==r?s=d=[d,f]:(_e=s,s=r)):(_e=s,s=r),s===r&&(s=_e,(d=Xe())!==r?(59===e.charCodeAt(_e)?(f=Be,_e++):(f=r,Ke(Ne)),f!==r?s=d=[d,f]:(_e=s,s=r)):(_e=s,s=r),s===r)){for(s=_e,d=[],a.test(e.charAt(_e))?(f=e.charAt(_e),_e++):(f=r,Ke(i));f!==r;)d.push(f),a.test(e.charAt(_e))?(f=e.charAt(_e),_e++):(f=r,Ke(i));d!==r?(c.test(e.charAt(_e))?(f=e.charAt(_e),_e++):(f=r,Ke(l)),f===r&&(f=null),f!==r?(u.test(e.charAt(_e))?(m=e.charAt(_e),_e++):(m=r,Ke(p)),m!==r?s=d=[d,f,m]:(_e=s,s=r)):(_e=s,s=r)):(_e=s,s=r)}s===r&&(s=null),s!==r?(x=n,t=n=o.reduce((function(e,t){const n=t[2];return e.concat([n])}),[x])):(_e=t,t=r)}else _e=t,t=r}else _e=t,t=r;var x;return Ve[h]={nextPos:_e,result:t},t}())===r&&(o=null),o!==r&&Xe()!==r?(125===e.charCodeAt(_e)?(s="}",_e++):(s=r,Ke(Oe)),s!==r?(d=o,t=n={type:Rt.RECORD,entries:d||[]}):(_e=t,t=r)):(_e=t,t=r)):(_e=t,t=r),Ve[f]={nextPos:_e,result:t},t)}function wt(){var t,n,o,s,a,i,c,l=69*_e+59,u=Ve[l];return u?(_e=u.nextPos,u.result):(t=_e,n=_e,e.substr(_e,8)===je?(o=je,_e+=8):(o=r,Ke(Le)),o!==r&&(s=Qe())!==r?n=o=[o,s]:(_e=n,n=r),n===r&&(n=null),n!==r&&(o=Pt())!==r&&(s=Xe())!==r?(63===e.charCodeAt(_e)?(a=W,_e++):(a=r,Ke(G)),a===r&&(a=null),a!==r&&Xe()!==r?(58===e.charCodeAt(_e)?(i=R,_e++):(i=r,Ke(M)),i!==r&&Xe()!==r&&(c=function(){var e,t=69*_e+61,n=Ve[t];if(n)return _e=n.nextPos,n.result;(e=ut())===r&&(e=dt())===r&&(e=kt())===r&&(e=St())===r&&(e=Tt())===r&&(e=Et())===r&&(e=xt())===r&&(e=rt())===r&&(e=ct())===r&&(e=at())===r&&(e=it());return Ve[t]={nextPos:_e,result:e},e}())!==r?t=n=function(e,t,n,r){const{quoteStyle:o,key:s}=t;return{type:Rt.RECORD_ENTRY,key:s,quoteStyle:o,value:"?"===n?{type:Rt.OPTIONAL,value:r,meta:{syntax:Nt.SUFFIX_KEY_QUESTION_MARK}}:r,readonly:Boolean(e)}}(n,o,a,c):(_e=t,t=r)):(_e=t,t=r)):(_e=t,t=r),t===r&&(t=_e,n=_e,e.substr(_e,8)===je?(o=je,_e+=8):(o=r,Ke(Le)),o!==r&&(s=Qe())!==r?n=o=[o,s]:(_e=n,n=r),n===r&&(n=null),n!==r&&(o=Pt())!==r?t=n=function(e,t){const{quoteStyle:n,key:r}=t;return{type:Rt.RECORD_ENTRY,key:r,quoteStyle:n,value:null,readonly:Boolean(e)}}(n,o):(_e=t,t=r)),Ve[l]={nextPos:_e,result:t},t)}function Pt(){var t,n,o,s,a,i,c,l=69*_e+60,u=Ve[l];if(u)return _e=u.nextPos,u.result;if(t=_e,34===e.charCodeAt(_e)?(n=P,_e++):(n=r,Ke(T)),n!==r){for(o=_e,s=[],I.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(F)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));a!==r;)s.push(a),I.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(F)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));(o=s!==r?e.substring(o,_e):s)!==r?(34===e.charCodeAt(_e)?(s=P,_e++):(s=r,Ke(T)),s!==r?t=n=function(e){return{quoteStyle:"double",key:e.replace(/\\"/gu,'"').replace(/\\\\/gu,"\\")}}(o):(_e=t,t=r)):(_e=t,t=r)}else _e=t,t=r;if(t===r){if(t=_e,39===e.charCodeAt(_e)?(n=E,_e++):(n=r,Ke(S)),n!==r){for(o=_e,s=[],C.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(v)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));a!==r;)s.push(a),C.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(v)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));(o=s!==r?e.substring(o,_e):s)!==r?(39===e.charCodeAt(_e)?(s=E,_e++):(s=r,Ke(S)),s!==r?t=n=function(e){return{quoteStyle:"single",key:e.replace(/\\'/g,"'").replace(/\\\\/gu,"\\")}}(o):(_e=t,t=r)):(_e=t,t=r)}else _e=t,t=r;t===r&&(t=_e,n=_e,(o=Ze())===r&&(o=lt()),(n=o!==r?e.substring(n,_e):o)!==r&&(n=function(e){return{quoteStyle:"none",key:e}}(n)),t=n)}return Ve[l]={nextPos:_e,result:t},t}function Tt(){var t,n,o,s,a,i=69*_e+62,c=Ve[i];return c?(_e=c.nextPos,c.result):(t=_e,40===e.charCodeAt(_e)?(n=Ae,_e++):(n=r,Ke(ke)),n!==r&&Xe()!==r&&(o=function(){var e,t=69*_e+63,n=Ve[t];if(n)return _e=n.nextPos,n.result;(e=ut())===r&&(e=dt())===r&&(e=kt())===r&&(e=St())===r&&(e=Et())===r&&(e=xt())===r&&(e=rt())===r&&(e=ct())===r&&(e=at())===r&&(e=it());return Ve[t]={nextPos:_e,result:e},e}())!==r&&Xe()!==r?(41===e.charCodeAt(_e)?(s=we,_e++):(s=r,Ke(Pe)),s!==r?(a=o,t=n={type:Rt.PARENTHESIS,value:a}):(_e=t,t=r)):(_e=t,t=r),Ve[i]={nextPos:_e,result:t},t)}function It(){var t,n=69*_e+64,o=Ve[n];return o?(_e=o.nextPos,o.result):((t=function(){var t,n,o,s=69*_e+65,a=Ve[s];if(a)return _e=a.nextPos,a.result;t=_e,e.substr(_e,3)===Re?(n=Re,_e+=3):(n=r,Ke(Me));n!==r&&(o=Ft())!==r?(i=o,t=n={type:Rt.VARIADIC,value:i,meta:{syntax:Bt.PREFIX_DOTS}}):(_e=t,t=r);var i;return Ve[s]={nextPos:_e,result:t},t}())===r&&(t=function(){var t,n,o,s=69*_e+66,a=Ve[s];if(a)return _e=a.nextPos,a.result;t=_e,(n=Ft())!==r?(e.substr(_e,3)===Re?(o=Re,_e+=3):(o=r,Ke(Me)),o!==r?(i=n,t=n={type:Rt.VARIADIC,value:i,meta:{syntax:Bt.SUFFIX_DOTS}}):(_e=t,t=r)):(_e=t,t=r);var i;return Ve[s]={nextPos:_e,result:t},t}())===r&&(t=function(){var t,n,o=69*_e+67,s=Ve[o];if(s)return _e=s.nextPos,s.result;t=_e,e.substr(_e,3)===Re?(n=Re,_e+=3):(n=r,Ke(Me));n!==r&&(n={type:Rt.VARIADIC,value:{type:Rt.ANY},meta:{syntax:Bt.ONLY_DOTS}});return t=n,Ve[o]={nextPos:_e,result:t},t}()),Ve[n]={nextPos:_e,result:t},t)}function Ft(){var e,t=69*_e+68,n=Ve[t];return n?(_e=n.nextPos,n.result):((e=ut())===r&&(e=dt())===r&&(e=kt())===r&&(e=St())===r&&(e=Tt())===r&&(e=Et())===r&&(e=xt())===r&&(e=rt())===r&&(e=ct())===r&&(e=at())===r&&(e=it()),Ve[t]={nextPos:_e,result:e},e)}const Dt=py,{GenericTypeSyntax:Ot,VariadicTypeSyntax:Bt,OptionalTypeSyntax:Nt,NullableTypeSyntax:jt,NotNullableTypeSyntax:Lt}=Dt,Rt=dy,Mt={MEMBER:"MEMBER",INNER_MEMBER:"INNER_MEMBER",INSTANCE_MEMBER:"INSTANCE_MEMBER"};if((n=s())!==r&&_e===e.length)return n;throw n!==r&&_e0){for(t=1,r=1;t",!1),Ce="function",ve=We("function",!1),Ae="(",ke=We("(",!1),we=")",Pe=We(")",!1),Te="this",Ie=We("this",!1),Fe=We("new",!1),De=We("{",!1),Oe=We("}",!1),Be=";",Ne=We(";",!1),je="readonly",Le=We("readonly",!1),Re="...",Me=We("...",!1),_e=0,$e=[{line:1,column:1}],qe=0,Ue=[],Ve={};if("startRule"in t){if(!(t.startRule in o))throw new Error("Can't start parsing from rule \""+t.startRule+'".');s=o[t.startRule]}function We(e,t){return{type:"literal",text:e,ignoreCase:t}}function Ge(e,t,n){return{type:"class",parts:e,inverted:t,ignoreCase:n}}function ze(t){var n,r=$e[t];if(r)return r;for(n=t-1;!$e[n];)n--;for(r={line:(r=$e[n]).line,column:r.column};nqe&&(qe=_e,Ue=[]),Ue.push(e))}function Ye(){var e,t,n=68*_e+0,o=Ve[n];return o?(_e=o.nextPos,o.result):(e=_e,Xe()!==r?((t=Dt())===r&&(t=dt())===r&&(t=mt())===r&&(t=St())===r&&(t=Pt())===r&&(t=vt())===r&&(t=yt())===r&&(t=st())===r&&(t=Ft())===r&&(t=ut())===r&&(t=ct())===r&&(t=lt()),t!==r&&Xe()!==r?e=t:(_e=e,e=r)):(_e=e,e=r),Ve[n]={nextPos:_e,result:e},e)}function He(){var t,n,o,s=68*_e+1,d=Ve[s];return d?(_e=d.nextPos,d.result):(a.test(e.charAt(_e))?(t=e.charAt(_e),_e++):(t=r,Ke(i)),t===r&&(t=_e,c.test(e.charAt(_e))?(n=e.charAt(_e),_e++):(n=r,Ke(l)),n===r&&(n=null),n!==r?(u.test(e.charAt(_e))?(o=e.charAt(_e),_e++):(o=r,Ke(p)),o!==r?t=n=[n,o]:(_e=t,t=r)):(_e=t,t=r)),Ve[s]={nextPos:_e,result:t},t)}function Xe(){var e,t,n=68*_e+2,o=Ve[n];if(o)return _e=o.nextPos,o.result;for(e=[],t=He();t!==r;)e.push(t),t=He();return Ve[n]={nextPos:_e,result:e},e}function Qe(){var e,t,n=68*_e+3,o=Ve[n];if(o)return _e=o.nextPos,o.result;if(e=[],(t=He())!==r)for(;t!==r;)e.push(t),t=He();else e=r;return Ve[n]={nextPos:_e,result:e},e}function Ze(){var t,n,o,s,a,i=68*_e+4,c=Ve[i];if(c)return _e=c.nextPos,c.result;if(t=_e,n=_e,d.test(e.charAt(_e))?(o=e.charAt(_e),_e++):(o=r,Ke(f)),o!==r){for(s=[],m.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(g));a!==r;)s.push(a),m.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(g));s!==r?n=o=[o,s]:(_e=n,n=r)}else _e=n,n=r;return t=n!==r?e.substring(t,_e):n,Ve[i]={nextPos:_e,result:t},t}function et(){var t,n,o,s,a,i,c,l,u,p,d,f=68*_e+5,m=Ve[f];if(m)return _e=m.nextPos,m.result;if(t=_e,(n=Ft())===r&&(n=tt()),n!==r){for(o=[],s=_e,(a=Xe())!==r&&(i=rt())!==r&&(c=Xe())!==r?(e.substr(_e,6)===h?(l=h,_e+=6):(l=r,Ke(y)),l===r&&(l=null),l!==r&&(u=Xe())!==r&&(p=nt())!==r?s=a=[a,i,c,l,u,p]:(_e=s,s=r)):(_e=s,s=r);s!==r;)o.push(s),s=_e,(a=Xe())!==r&&(i=rt())!==r&&(c=Xe())!==r?(e.substr(_e,6)===h?(l=h,_e+=6):(l=r,Ke(y)),l===r&&(l=null),l!==r&&(u=Xe())!==r&&(p=nt())!==r?s=a=[a,i,c,l,u,p]:(_e=s,s=r)):(_e=s,s=r);o!==r?(d=n,t=n=o.reduce((function(e,t){const n=t[1],r=t[3],o=t[5],{quoteStyle:s,name:a}=o;switch(n){case $t.MEMBER:return{type:_t.MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};case $t.INSTANCE_MEMBER:return{type:_t.INSTANCE_MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};case $t.INNER_MEMBER:return{type:_t.INNER_MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};default:throw new Error('Unexpected operator type: "'+n+'"')}}),d)):(_e=t,t=r)}else _e=t,t=r;return Ve[f]={nextPos:_e,result:t},t}function tt(){var t,n,o,s,a,i,c=68*_e+6,l=Ve[c];if(l)return _e=l.nextPos,l.result;if(_e,n=_e,o=_e,d.test(e.charAt(_e))?(s=e.charAt(_e),_e++):(s=r,Ke(f)),s!==r){for(a=[],x.test(e.charAt(_e))?(i=e.charAt(_e),_e++):(i=r,Ke(b));i!==r;)a.push(i),x.test(e.charAt(_e))?(i=e.charAt(_e),_e++):(i=r,Ke(b));a!==r?o=s=[s,a]:(_e=o,o=r)}else _e=o,o=r;return(n=o!==r?e.substring(n,_e):o)!==r&&(n=function(e){return{type:_t.NAME,name:e}}(n)),t=n,Ve[c]={nextPos:_e,result:t},t}function nt(){var t,n,o,s,a,i,c,l=68*_e+7,u=Ve[l];if(u)return _e=u.nextPos,u.result;if(t=_e,39===e.charCodeAt(_e)?(n=E,_e++):(n=r,Ke(S)),n!==r){for(o=_e,s=[],C.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(v)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));a!==r;)s.push(a),C.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(v)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));(o=s!==r?e.substring(o,_e):s)!==r?(39===e.charCodeAt(_e)?(s=E,_e++):(s=r,Ke(S)),s!==r?t=n=function(e){return{quoteStyle:"single",name:e.replace(/\\'/g,"'").replace(/\\\\/gu,"\\")}}(o):(_e=t,t=r)):(_e=t,t=r)}else _e=t,t=r;if(t===r){if(t=_e,34===e.charCodeAt(_e)?(n=P,_e++):(n=r,Ke(T)),n!==r){for(o=_e,s=[],I.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(F)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));a!==r;)s.push(a),I.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(F)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));(o=s!==r?e.substring(o,_e):s)!==r?(34===e.charCodeAt(_e)?(s=P,_e++):(s=r,Ke(T)),s!==r?t=n=function(e){return{quoteStyle:"double",name:e.replace(/\\"/gu,'"').replace(/\\\\/gu,"\\")}}(o):(_e=t,t=r)):(_e=t,t=r)}else _e=t,t=r;t===r&&(t=_e,(n=Ze())!==r&&(n=function(e){return{quoteStyle:"none",name:e}}(n)),t=n)}return Ve[l]={nextPos:_e,result:t},t}function rt(){var t,n=68*_e+8,o=Ve[n];return o?(_e=o.nextPos,o.result):((t=function(){var t,n,o=68*_e+10,s=Ve[o];if(s)return _e=s.nextPos,s.result;t=_e,46===e.charCodeAt(_e)?(n=D,_e++):(n=r,Ke(O));n!==r&&(n=$t.MEMBER);return t=n,Ve[o]={nextPos:_e,result:t},t}())===r&&(t=function(){var t,n,o=68*_e+12,s=Ve[o];if(s)return _e=s.nextPos,s.result;t=_e,35===e.charCodeAt(_e)?(n="#",_e++):(n=r,Ke(N));n!==r&&(n=$t.INSTANCE_MEMBER);return t=n,Ve[o]={nextPos:_e,result:t},t}())===r&&(t=function(){var t,n,o=68*_e+11,s=Ve[o];if(s)return _e=s.nextPos,s.result;t=_e,126===e.charCodeAt(_e)?(n="~",_e++):(n=r,Ke(B));n!==r&&(n=$t.INNER_MEMBER);return t=n,Ve[o]={nextPos:_e,result:t},t}()),Ve[n]={nextPos:_e,result:t},t)}function ot(){var t,n,o,s,a,i,c,l,u,p=68*_e+9,d=Ve[p];if(d)return _e=d.nextPos,d.result;if(t=_e,(n=tt())!==r){for(o=[],s=_e,(a=Xe())!==r?(46===e.charCodeAt(_e)?(i=D,_e++):(i=r,Ke(O)),i!==r&&(c=Xe())!==r&&(l=tt())!==r?s=a=[a,i,c,l]:(_e=s,s=r)):(_e=s,s=r);s!==r;)o.push(s),s=_e,(a=Xe())!==r?(46===e.charCodeAt(_e)?(i=D,_e++):(i=r,Ke(O)),i!==r&&(c=Xe())!==r&&(l=tt())!==r?s=a=[a,i,c,l]:(_e=s,s=r)):(_e=s,s=r);o!==r?(u=n,t=n=o.reduce((function(e,t){return{type:_t.MEMBER,owner:e,name:t[3]}}),u)):(_e=t,t=r)}else _e=t,t=r;return Ve[p]={nextPos:_e,result:t},t}function st(){var e,t=68*_e+13,n=Ve[t];return n?(_e=n.nextPos,n.result):((e=at())===r&&(e=it())===r&&(e=et()),Ve[t]={nextPos:_e,result:e},e)}function at(){var t,n,o,s,a,i,c,l,u,p,d,f,m,g=68*_e+14,x=Ve[g];if(x)return _e=x.nextPos,x.result;if(t=_e,e.substr(_e,8)===j?(n=j,_e+=8):(n=r,Ke(L)),n!==r)if(Xe()!==r)if(58===e.charCodeAt(_e)?(o=R,_e++):(o=r,Ke(M)),o!==r)if(Xe()!==r)if((s=nt())!==r){for(a=[],i=_e,(c=Xe())!==r&&(l=rt())!==r&&(u=Xe())!==r?(e.substr(_e,6)===h?(p=h,_e+=6):(p=r,Ke(y)),p===r&&(p=null),p!==r&&(d=Xe())!==r&&(f=nt())!==r?i=c=[c,l,u,p,d,f]:(_e=i,i=r)):(_e=i,i=r);i!==r;)a.push(i),i=_e,(c=Xe())!==r&&(l=rt())!==r&&(u=Xe())!==r?(e.substr(_e,6)===h?(p=h,_e+=6):(p=r,Ke(y)),p===r&&(p=null),p!==r&&(d=Xe())!==r&&(f=nt())!==r?i=c=[c,l,u,p,d,f]:(_e=i,i=r)):(_e=i,i=r);a!==r?(m=s,t=n=a.reduce((function(e,t){const n=t[1],r=t[3],o=t[5],{quoteStyle:s,name:a}=o;switch(n){case $t.MEMBER:return{type:_t.MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};case $t.INSTANCE_MEMBER:return{type:_t.INSTANCE_MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};case $t.INNER_MEMBER:return{type:_t.INNER_MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};default:throw new Error('Unexpected operator type: "'+n+'"')}}),Object.assign({type:_t.EXTERNAL},m))):(_e=t,t=r)}else _e=t,t=r;else _e=t,t=r;else _e=t,t=r;else _e=t,t=r;else _e=t,t=r;return Ve[g]={nextPos:_e,result:t},t}function it(){var t,n,o,s,a,i=68*_e+15,c=Ve[i];return c?(_e=c.nextPos,c.result):(t=_e,e.substr(_e,6)===_?(n=_,_e+=6):(n=r,Ke($)),n!==r&&Xe()!==r?(58===e.charCodeAt(_e)?(o=R,_e++):(o=r,Ke(M)),o!==r&&Xe()!==r&&(s=function(){var t,n,o,s,a,i,c,l,u,p,d=68*_e+16,f=Ve[d];if(f)return _e=f.nextPos,f.result;if(t=_e,(n=function(){var t,n,o,s,a,i,c,l=68*_e+17,u=Ve[l];if(u)return _e=u.nextPos,u.result;t=_e,39===e.charCodeAt(_e)?(n=E,_e++):(n=r,Ke(S));if(n!==r){for(o=_e,s=[],C.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(v)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));a!==r;)s.push(a),C.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(v)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));(o=s!==r?e.substring(o,_e):s)!==r?(39===e.charCodeAt(_e)?(s=E,_e++):(s=r,Ke(S)),s!==r?t=n=function(e){return{quoteStyle:"single",type:_t.FILE_PATH,path:e.replace(/\\'/g,"'").replace(/\\\\/gu,"\\")}}(o):(_e=t,t=r)):(_e=t,t=r)}else _e=t,t=r;if(t===r){if(t=_e,34===e.charCodeAt(_e)?(n=P,_e++):(n=r,Ke(T)),n!==r){for(o=_e,s=[],I.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(F)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));a!==r;)s.push(a),I.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(F)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));(o=s!==r?e.substring(o,_e):s)!==r?(34===e.charCodeAt(_e)?(s=P,_e++):(s=r,Ke(T)),s!==r?t=n=function(e){return{quoteStyle:"double",type:_t.FILE_PATH,path:e.replace(/\\"/gu,'"').replace(/\\\\/gu,"\\")}}(o):(_e=t,t=r)):(_e=t,t=r)}else _e=t,t=r;if(t===r){if(t=_e,n=_e,o=[],q.test(e.charAt(_e))?(s=e.charAt(_e),_e++):(s=r,Ke(U)),s!==r)for(;s!==r;)o.push(s),q.test(e.charAt(_e))?(s=e.charAt(_e),_e++):(s=r,Ke(U));else o=r;(n=o!==r?e.substring(n,_e):o)!==r&&(n=function(e){return{quoteStyle:"none",type:_t.FILE_PATH,path:e}}(n)),t=n}}return Ve[l]={nextPos:_e,result:t},t}())!==r){for(o=[],s=_e,(a=Xe())!==r&&(i=rt())!==r&&(c=Xe())!==r?(e.substr(_e,6)===h?(l=h,_e+=6):(l=r,Ke(y)),l===r&&(l=null),l!==r&&(u=Xe())!==r&&(p=nt())!==r?s=a=[a,i,c,l,u,p]:(_e=s,s=r)):(_e=s,s=r);s!==r;)o.push(s),s=_e,(a=Xe())!==r&&(i=rt())!==r&&(c=Xe())!==r?(e.substr(_e,6)===h?(l=h,_e+=6):(l=r,Ke(y)),l===r&&(l=null),l!==r&&(u=Xe())!==r&&(p=nt())!==r?s=a=[a,i,c,l,u,p]:(_e=s,s=r)):(_e=s,s=r);o!==r?(m=n,t=n=o.reduce((function(e,t){const n=t[1],r=t[3],o=t[5],{quoteStyle:s,name:a}=o;switch(n){case $t.MEMBER:return{type:_t.MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};case $t.INSTANCE_MEMBER:return{type:_t.INSTANCE_MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};case $t.INNER_MEMBER:return{type:_t.INNER_MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};default:throw new Error('Unexpected operator type: "'+n+'"')}}),m)):(_e=t,t=r)}else _e=t,t=r;var m;return Ve[d]={nextPos:_e,result:t},t}())!==r?(a=s,t=n={type:_t.MODULE,value:a}):(_e=t,t=r)):(_e=t,t=r),Ve[i]={nextPos:_e,result:t},t)}function ct(){var t,n,o=68*_e+18,s=Ve[o];return s?(_e=s.nextPos,s.result):(_e,42===e.charCodeAt(_e)?(n="*",_e++):(n=r,Ke(V)),n!==r&&(n={type:_t.ANY}),t=n,Ve[o]={nextPos:_e,result:t},t)}function lt(){var t,n,o=68*_e+19,s=Ve[o];return s?(_e=s.nextPos,s.result):(_e,63===e.charCodeAt(_e)?(n=W,_e++):(n=r,Ke(G)),n!==r&&(n={type:_t.UNKNOWN}),t=n,Ve[o]={nextPos:_e,result:t},t)}function ut(){var t,n=68*_e+20,o=Ve[n];return o?(_e=o.nextPos,o.result):((t=function(){var t,n,o,s,a,i,c,l=68*_e+21,u=Ve[l];if(u)return _e=u.nextPos,u.result;t=_e,34===e.charCodeAt(_e)?(n=P,_e++):(n=r,Ke(T));if(n!==r){for(o=_e,s=[],I.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(F)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));a!==r;)s.push(a),I.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(F)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));(o=s!==r?e.substring(o,_e):s)!==r?(34===e.charCodeAt(_e)?(s=P,_e++):(s=r,Ke(T)),s!==r?(p=o,t=n={type:_t.STRING_VALUE,quoteStyle:"double",string:p.replace(/\\"/gu,'"').replace(/\\\\/gu,"\\")}):(_e=t,t=r)):(_e=t,t=r)}else _e=t,t=r;var p;if(t===r)if(t=_e,39===e.charCodeAt(_e)?(n=E,_e++):(n=r,Ke(S)),n!==r){for(o=_e,s=[],C.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(v)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));a!==r;)s.push(a),C.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(v)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));(o=s!==r?e.substring(o,_e):s)!==r?(39===e.charCodeAt(_e)?(s=E,_e++):(s=r,Ke(S)),s!==r?t=n=function(e){return{type:_t.STRING_VALUE,quoteStyle:"single",string:e.replace(/\\'/g,"'").replace(/\\\\/gu,"\\")}}(o):(_e=t,t=r)):(_e=t,t=r)}else _e=t,t=r;return Ve[l]={nextPos:_e,result:t},t}())===r&&(t=function(){var t,n,o=68*_e+22,s=Ve[o];if(s)return _e=s.nextPos,s.result;t=_e,(n=function(){var t,n,o,s,a,i,c=68*_e+25,l=Ve[c];if(l)return _e=l.nextPos,l.result;t=_e,n=_e,45===e.charCodeAt(_e)?(o=J,_e++):(o=r,Ke(K));o===r&&(o=null);if(o!==r)if(e.substr(_e,2)===Q?(s=Q,_e+=2):(s=r,Ke(Z)),s!==r){if(a=[],ee.test(e.charAt(_e))?(i=e.charAt(_e),_e++):(i=r,Ke(te)),i!==r)for(;i!==r;)a.push(i),ee.test(e.charAt(_e))?(i=e.charAt(_e),_e++):(i=r,Ke(te));else a=r;a!==r?n=o=[o,s,a]:(_e=n,n=r)}else _e=n,n=r;else _e=n,n=r;t=n!==r?e.substring(t,_e):n;return Ve[c]={nextPos:_e,result:t},t}())===r&&(n=function(){var t,n,o,s,a,i,c=68*_e+26,l=Ve[c];if(l)return _e=l.nextPos,l.result;t=_e,n=_e,45===e.charCodeAt(_e)?(o=J,_e++):(o=r,Ke(K));o===r&&(o=null);if(o!==r)if(e.substr(_e,2)===ne?(s=ne,_e+=2):(s=r,Ke(re)),s!==r){if(a=[],oe.test(e.charAt(_e))?(i=e.charAt(_e),_e++):(i=r,Ke(se)),i!==r)for(;i!==r;)a.push(i),oe.test(e.charAt(_e))?(i=e.charAt(_e),_e++):(i=r,Ke(se));else a=r;a!==r?n=o=[o,s,a]:(_e=n,n=r)}else _e=n,n=r;else _e=n,n=r;t=n!==r?e.substring(t,_e):n;return Ve[c]={nextPos:_e,result:t},t}())===r&&(n=function(){var t,n,o,s,a,i,c=68*_e+27,l=Ve[c];if(l)return _e=l.nextPos,l.result;t=_e,n=_e,45===e.charCodeAt(_e)?(o=J,_e++):(o=r,Ke(K));o===r&&(o=null);if(o!==r)if(e.substr(_e,2)===ae?(s=ae,_e+=2):(s=r,Ke(ie)),s!==r){if(a=[],ce.test(e.charAt(_e))?(i=e.charAt(_e),_e++):(i=r,Ke(le)),i!==r)for(;i!==r;)a.push(i),ce.test(e.charAt(_e))?(i=e.charAt(_e),_e++):(i=r,Ke(le));else a=r;a!==r?n=o=[o,s,a]:(_e=n,n=r)}else _e=n,n=r;else _e=n,n=r;t=n!==r?e.substring(t,_e):n;return Ve[c]={nextPos:_e,result:t},t}())===r&&(n=function(){var t,n,o,s,a=68*_e+23,i=Ve[a];if(i)return _e=i.nextPos,i.result;t=_e,n=_e,43===e.charCodeAt(_e)?(o="+",_e++):(o=r,Ke(z));o===r&&(45===e.charCodeAt(_e)?(o=J,_e++):(o=r,Ke(K)));o===r&&(o=null);o!==r&&(s=pt())!==r?n=o=[o,s]:(_e=n,n=r);t=n!==r?e.substring(t,_e):n;return Ve[a]={nextPos:_e,result:t},t}());n!==r&&(a=n,n={type:_t.NUMBER_VALUE,number:a});var a;return t=n,Ve[o]={nextPos:_e,result:t},t}()),Ve[n]={nextPos:_e,result:t},t)}function pt(){var t,n,o,s,a,i,c,l,u=68*_e+24,p=Ve[u];if(p)return _e=p.nextPos,p.result;if(t=_e,n=_e,o=_e,s=[],Y.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(H)),a!==r)for(;a!==r;)s.push(a),Y.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(H));else s=r;if(s!==r){if(a=_e,46===e.charCodeAt(_e)?(i=D,_e++):(i=r,Ke(O)),i!==r){if(c=[],Y.test(e.charAt(_e))?(l=e.charAt(_e),_e++):(l=r,Ke(H)),l!==r)for(;l!==r;)c.push(l),Y.test(e.charAt(_e))?(l=e.charAt(_e),_e++):(l=r,Ke(H));else c=r;c!==r?a=i=[i,c]:(_e=a,a=r)}else _e=a,a=r;a===r&&(a=null),a!==r?o=s=[s,a]:(_e=o,o=r)}else _e=o,o=r;if(o===r)if(o=_e,46===e.charCodeAt(_e)?(s=D,_e++):(s=r,Ke(O)),s!==r){if(a=[],Y.test(e.charAt(_e))?(i=e.charAt(_e),_e++):(i=r,Ke(H)),i!==r)for(;i!==r;)a.push(i),Y.test(e.charAt(_e))?(i=e.charAt(_e),_e++):(i=r,Ke(H));else a=r;a!==r?o=s=[s,a]:(_e=o,o=r)}else _e=o,o=r;if(o!==r){if(s=_e,101===e.charCodeAt(_e)?(a="e",_e++):(a=r,Ke(X)),a!==r)if(43===e.charCodeAt(_e)?(i="+",_e++):(i=r,Ke(z)),i===r&&(45===e.charCodeAt(_e)?(i=J,_e++):(i=r,Ke(K))),i===r&&(i=null),i!==r){if(c=[],Y.test(e.charAt(_e))?(l=e.charAt(_e),_e++):(l=r,Ke(H)),l!==r)for(;l!==r;)c.push(l),Y.test(e.charAt(_e))?(l=e.charAt(_e),_e++):(l=r,Ke(H));else c=r;c!==r?s=a=[a,i,c]:(_e=s,s=r)}else _e=s,s=r;else _e=s,s=r;s===r&&(s=null),s!==r?n=o=[o,s]:(_e=n,n=r)}else _e=n,n=r;return t=n!==r?e.substring(t,_e):n,Ve[u]={nextPos:_e,result:t},t}function dt(){var t,n,o,s,a,i,c=68*_e+28,l=Ve[c];return l?(_e=l.nextPos,l.result):(t=_e,(n=ft())!==r&&Xe()!==r?(124===e.charCodeAt(_e)?(o="|",_e++):(o=r,Ke(ue)),o!==r&&Xe()!==r?((s=dt())===r&&(s=ft()),s!==r?(a=n,i=s,t=n={type:_t.UNION,left:a,right:i}):(_e=t,t=r)):(_e=t,t=r)):(_e=t,t=r),Ve[c]={nextPos:_e,result:t},t)}function ft(){var e,t=68*_e+29,n=Ve[t];return n?(_e=n.nextPos,n.result):((e=mt())===r&&(e=Pt())===r&&(e=vt())===r&&(e=Ft())===r&&(e=yt())===r&&(e=St())===r&&(e=st())===r&&(e=ut())===r&&(e=ct())===r&&(e=lt()),Ve[t]={nextPos:_e,result:e},e)}function mt(){var t,n=68*_e+30,o=Ve[n];return o?(_e=o.nextPos,o.result):((t=function(){var t,n=68*_e+37,o=Ve[n];if(o)return _e=o.nextPos,o.result;(t=function(){var t,n,o,s=68*_e+41,a=Ve[s];if(a)return _e=a.nextPos,a.result;t=_e,(n=bt())===r&&(n=Et())===r&&(n=xt());n!==r&&Xe()!==r?(61===e.charCodeAt(_e)?(o="=",_e++):(o=r,Ke(ge)),o!==r?(i=n,t=n={type:_t.OPTIONAL,value:i,meta:{syntax:Lt.SUFFIX_EQUALS_SIGN}}):(_e=t,t=r)):(_e=t,t=r);var i;return Ve[s]={nextPos:_e,result:t},t}())===r&&(t=bt())===r&&(t=Et());return Ve[n]={nextPos:_e,result:t},t}())===r&&(t=gt()),Ve[n]={nextPos:_e,result:t},t)}function gt(){var t,n=68*_e+31,o=Ve[n];return o?(_e=o.nextPos,o.result):((t=function(){var t,n,o,s=68*_e+36,a=Ve[s];if(a)return _e=a.nextPos,a.result;t=_e,61===e.charCodeAt(_e)?(n=me,_e++):(n=r,Ke(ge));n!==r&&Xe()!==r&&(o=ht())!==r?(i=o,t=n={type:_t.OPTIONAL,value:i,meta:{syntax:Lt.PREFIX_EQUALS_SIGN}}):(_e=t,t=r);var i;return Ve[s]={nextPos:_e,result:t},t}())===r&&(t=function(){var t,n,o,s=68*_e+35,a=Ve[s];if(a)return _e=a.nextPos,a.result;t=_e,33===e.charCodeAt(_e)?(n="!",_e++):(n=r,Ke(fe));n!==r&&Xe()!==r&&(o=ht())!==r?(i=o,t=n={type:_t.NOT_NULLABLE,value:i,meta:{syntax:Mt.PREFIX_BANG}}):(_e=t,t=r);var i;return Ve[s]={nextPos:_e,result:t},t}())===r&&(t=function(){var t,n,o,s=68*_e+34,a=Ve[s];if(a)return _e=a.nextPos,a.result;t=_e,63===e.charCodeAt(_e)?(n=W,_e++):(n=r,Ke(G));n!==r&&Xe()!==r&&(o=ht())!==r?(i=o,t=n={type:_t.NULLABLE,value:i,meta:{syntax:Rt.PREFIX_QUESTION_MARK}}):(_e=t,t=r);var i;return Ve[s]={nextPos:_e,result:t},t}()),Ve[n]={nextPos:_e,result:t},t)}function ht(){var e,t=68*_e+32,n=Ve[t];return n?(_e=n.nextPos,n.result):((e=St())===r&&(e=Pt())===r&&(e=vt())===r&&(e=Ft())===r&&(e=st())===r&&(e=ut())===r&&(e=ct())===r&&(e=lt()),Ve[t]={nextPos:_e,result:e},e)}function yt(){var t,n,o,s=68*_e+33,a=Ve[s];return a?(_e=a.nextPos,a.result):(t=_e,e.substr(_e,6)===pe?(n=pe,_e+=6):(n=r,Ke(de)),n!==r&&Qe()!==r&&(o=ot())!==r?t=n=function(e,t){return{type:_t.TYPE_QUERY,name:t}}(0,o):(_e=t,t=r),Ve[s]={nextPos:_e,result:t},t)}function xt(){var e,t=68*_e+38,n=Ve[t];return n?(_e=n.nextPos,n.result):((e=gt())===r&&(e=St())===r&&(e=Pt())===r&&(e=vt())===r&&(e=Ft())===r&&(e=st())===r&&(e=ut())===r&&(e=ct())===r&&(e=lt()),Ve[t]={nextPos:_e,result:e},e)}function bt(){var t,n,o,s,a=68*_e+39,i=Ve[a];return i?(_e=i.nextPos,i.result):(t=_e,(n=xt())!==r&&Xe()!==r?(63===e.charCodeAt(_e)?(o=W,_e++):(o=r,Ke(G)),o!==r?(s=n,t=n={type:_t.NULLABLE,value:s,meta:{syntax:Rt.SUFFIX_QUESTION_MARK}}):(_e=t,t=r)):(_e=t,t=r),Ve[a]={nextPos:_e,result:t},t)}function Et(){var t,n,o,s,a=68*_e+40,i=Ve[a];return i?(_e=i.nextPos,i.result):(t=_e,(n=xt())!==r&&Xe()!==r?(33===e.charCodeAt(_e)?(o="!",_e++):(o=r,Ke(fe)),o!==r?(s=n,t=n={type:_t.NOT_NULLABLE,value:s,meta:{syntax:Mt.SUFFIX_BANG}}):(_e=t,t=r)):(_e=t,t=r),Ve[a]={nextPos:_e,result:t},t)}function St(){var t,n,o,s,a,i,c,l=68*_e+42,u=Ve[l];return u?(_e=u.nextPos,u.result):(t=_e,(n=function(){var e,t=68*_e+43,n=Ve[t];if(n)return _e=n.nextPos,n.result;(e=Ft())===r&&(e=st())===r&&(e=ut())===r&&(e=ct())===r&&(e=lt());return Ve[t]={nextPos:_e,result:e},e}())!==r&&Xe()!==r&&(o=function(){var t,n=68*_e+46,o=Ve[n];if(o)return _e=o.nextPos,o.result;(t=function(){var t,n,o=68*_e+47,s=Ve[o];if(s)return _e=s.nextPos,s.result;t=_e,e.substr(_e,2)===xe?(n=xe,_e+=2):(n=r,Ke(be));n!==r&&(n=Nt.ANGLE_BRACKET_WITH_DOT);return t=n,Ve[o]={nextPos:_e,result:t},t}())===r&&(t=function(){var t,n,o=68*_e+48,s=Ve[o];if(s)return _e=s.nextPos,s.result;t=_e,60===e.charCodeAt(_e)?(n="<",_e++):(n=r,Ke(Ee));n!==r&&(n=Nt.ANGLE_BRACKET);return t=n,Ve[o]={nextPos:_e,result:t},t}());return Ve[n]={nextPos:_e,result:t},t}())!==r&&Xe()!==r&&(s=function(){var t,n,o,s,a,i,c,l,u=68*_e+45,p=Ve[u];if(p)return _e=p.nextPos,p.result;if(t=_e,(n=Ct())!==r){for(o=[],s=_e,(a=Xe())!==r?(44===e.charCodeAt(_e)?(i=he,_e++):(i=r,Ke(ye)),i!==r&&(c=Xe())!==r&&(l=Ct())!==r?s=a=[a,i,c,l]:(_e=s,s=r)):(_e=s,s=r);s!==r;)o.push(s),s=_e,(a=Xe())!==r?(44===e.charCodeAt(_e)?(i=he,_e++):(i=r,Ke(ye)),i!==r&&(c=Xe())!==r&&(l=Ct())!==r?s=a=[a,i,c,l]:(_e=s,s=r)):(_e=s,s=r);o!==r?(d=n,t=n=o.reduce((function(e,t){return e.concat([t[3]])}),[d])):(_e=t,t=r)}else _e=t,t=r;var d;return Ve[u]={nextPos:_e,result:t},t}())!==r&&Xe()!==r&&function(){var t,n=68*_e+49,o=Ve[n];if(o)return _e=o.nextPos,o.result;62===e.charCodeAt(_e)?(t=">",_e++):(t=r,Ke(Se));return Ve[n]={nextPos:_e,result:t},t}()!==r?(a=n,i=o,c=s,t=n={type:_t.GENERIC,subject:a,objects:c,meta:{syntax:i}}):(_e=t,t=r),Ve[l]={nextPos:_e,result:t},t)}function Ct(){var e,t=68*_e+44,n=Ve[t];return n?(_e=n.nextPos,n.result):((e=dt())===r&&(e=mt())===r&&(e=Pt())===r&&(e=vt())===r&&(e=Ft())===r&&(e=St())===r&&(e=yt())===r&&(e=st())===r&&(e=ut())===r&&(e=ct())===r&&(e=lt()),Ve[t]={nextPos:_e,result:e},e)}function vt(){var t,n,o,s,a,i,c,l=68*_e+50,u=Ve[l];return u?(_e=u.nextPos,u.result):(t=_e,e.substr(_e,8)===Ce?(n=Ce,_e+=8):(n=r,Ke(ve)),n!==r&&Xe()!==r&&(o=function(){var t,n,o,s,a,i,c=68*_e+51,l=Ve[c];if(l)return _e=l.nextPos,l.result;t=_e,40===e.charCodeAt(_e)?(n=Ae,_e++):(n=r,Ke(ke));n!==r&&Xe()!==r&&(o=At())!==r&&Xe()!==r?(44===e.charCodeAt(_e)?(s=he,_e++):(s=r,Ke(ye)),s!==r&&Xe()!==r&&(a=kt())!==r&&Xe()!==r?(41===e.charCodeAt(_e)?(i=we,_e++):(i=r,Ke(Pe)),i!==r?t=n={params:a,modifier:o}:(_e=t,t=r)):(_e=t,t=r)):(_e=t,t=r);t===r&&(t=_e,40===e.charCodeAt(_e)?(n=Ae,_e++):(n=r,Ke(ke)),n!==r&&Xe()!==r&&(o=At())!==r&&Xe()!==r?(41===e.charCodeAt(_e)?(s=we,_e++):(s=r,Ke(Pe)),s!==r?t=n=function(e){return{params:[],modifier:e}}(o):(_e=t,t=r)):(_e=t,t=r),t===r&&(t=_e,40===e.charCodeAt(_e)?(n=Ae,_e++):(n=r,Ke(ke)),n!==r&&Xe()!==r?(41===e.charCodeAt(_e)?(o=we,_e++):(o=r,Ke(Pe)),o!==r?t=n={params:[],modifier:{nodeThis:null,nodeNew:null}}:(_e=t,t=r)):(_e=t,t=r),t===r&&(t=_e,40===e.charCodeAt(_e)?(n=Ae,_e++):(n=r,Ke(ke)),n!==r&&Xe()!==r&&(o=kt())!==r&&Xe()!==r?(41===e.charCodeAt(_e)?(s=we,_e++):(s=r,Ke(Pe)),s!==r?t=n=function(e){return{params:e,modifier:{nodeThis:null,nodeNew:null}}}(o):(_e=t,t=r)):(_e=t,t=r))));return Ve[c]={nextPos:_e,result:t},t}())!==r&&Xe()!==r?(s=_e,58===e.charCodeAt(_e)?(a=R,_e++):(a=r,Ke(M)),a!==r&&(i=Xe())!==r&&(c=function(){var e,t=68*_e+55,n=Ve[t];if(n)return _e=n.nextPos,n.result;(e=gt())===r&&(e=Pt())===r&&(e=vt())===r&&(e=Ft())===r&&(e=yt())===r&&(e=St())===r&&(e=st())===r&&(e=ut())===r&&(e=ct())===r&&(e=lt());return Ve[t]={nextPos:_e,result:e},e}())!==r?s=a=[a,i,c]:(_e=s,s=r),s===r&&(s=null),s!==r?t=n=function(e,t){const n=t?t[2]:null;return{type:_t.FUNCTION,params:e.params,returns:n,this:e.modifier.nodeThis,new:e.modifier.nodeNew}}(o,s):(_e=t,t=r)):(_e=t,t=r),Ve[l]={nextPos:_e,result:t},t)}function At(){var t,n,o,s,a,i,c,l=68*_e+52,u=Ve[l];return u?(_e=u.nextPos,u.result):(t=_e,n=_e,e.substr(_e,4)===Te?(o=Te,_e+=4):(o=r,Ke(Ie)),o!==r&&(s=Xe())!==r?(58===e.charCodeAt(_e)?(a=R,_e++):(a=r,Ke(M)),a!==r&&(i=Xe())!==r&&(c=wt())!==r?n=o=[o,s,a,i,c]:(_e=n,n=r)):(_e=n,n=r),n!==r&&(n={nodeThis:n[4],nodeNew:null}),(t=n)===r&&(t=_e,n=_e,"new"===e.substr(_e,3)?(o="new",_e+=3):(o=r,Ke(Fe)),o!==r&&(s=Xe())!==r?(58===e.charCodeAt(_e)?(a=R,_e++):(a=r,Ke(M)),a!==r&&(i=Xe())!==r&&(c=wt())!==r?n=o=[o,s,a,i,c]:(_e=n,n=r)):(_e=n,n=r),n!==r&&(n={nodeThis:null,nodeNew:n[4]}),t=n),Ve[l]={nextPos:_e,result:t},t)}function kt(){var t,n,o,s,a,i,c,l,u=68*_e+53,p=Ve[u];if(p)return _e=p.nextPos,p.result;for(t=_e,n=[],o=_e,(s=wt())!==r&&(a=Xe())!==r?(44===e.charCodeAt(_e)?(i=he,_e++):(i=r,Ke(ye)),i!==r&&(c=Xe())!==r?o=s=[s,a,i,c]:(_e=o,o=r)):(_e=o,o=r);o!==r;)n.push(o),o=_e,(s=wt())!==r&&(a=Xe())!==r?(44===e.charCodeAt(_e)?(i=he,_e++):(i=r,Ke(ye)),i!==r&&(c=Xe())!==r?o=s=[s,a,i,c]:(_e=o,o=r)):(_e=o,o=r);return n!==r?((o=Dt())===r&&(o=Ot()),o===r&&(o=null),o!==r?(l=o,t=n=n.reduceRight((function(e,t){const[n]=t;return[n].concat(e)}),l?[l]:[])):(_e=t,t=r)):(_e=t,t=r),Ve[u]={nextPos:_e,result:t},t}function wt(){var e,t=68*_e+54,n=Ve[t];return n?(_e=n.nextPos,n.result):((e=dt())===r&&(e=yt())===r&&(e=mt())===r&&(e=Pt())===r&&(e=vt())===r&&(e=Ft())===r&&(e=St())===r&&(e=st())===r&&(e=ut())===r&&(e=ct())===r&&(e=lt()),Ve[t]={nextPos:_e,result:e},e)}function Pt(){var t,n,o,s,d,f=68*_e+56,m=Ve[f];return m?(_e=m.nextPos,m.result):(t=_e,123===e.charCodeAt(_e)?(n="{",_e++):(n=r,Ke(De)),n!==r&&Xe()!==r?((o=function(){var t,n,o,s,d,f,m,g,h=68*_e+57,y=Ve[h];if(y)return _e=y.nextPos,y.result;if(t=_e,(n=Tt())!==r){if(o=[],s=_e,d=_e,(f=Xe())!==r?(44===e.charCodeAt(_e)?(m=he,_e++):(m=r,Ke(ye)),m!==r?d=f=[f,m]:(_e=d,d=r)):(_e=d,d=r),d===r&&(d=_e,(f=Xe())!==r?(59===e.charCodeAt(_e)?(m=Be,_e++):(m=r,Ke(Ne)),m!==r?d=f=[f,m]:(_e=d,d=r)):(_e=d,d=r),d===r)){for(d=_e,f=[],a.test(e.charAt(_e))?(m=e.charAt(_e),_e++):(m=r,Ke(i));m!==r;)f.push(m),a.test(e.charAt(_e))?(m=e.charAt(_e),_e++):(m=r,Ke(i));f!==r?(c.test(e.charAt(_e))?(m=e.charAt(_e),_e++):(m=r,Ke(l)),m===r&&(m=null),m!==r?(u.test(e.charAt(_e))?(g=e.charAt(_e),_e++):(g=r,Ke(p)),g!==r?d=f=[f,m,g]:(_e=d,d=r)):(_e=d,d=r)):(_e=d,d=r)}for(d!==r&&(f=Xe())!==r&&(m=Tt())!==r?s=d=[d,f,m]:(_e=s,s=r);s!==r;){if(o.push(s),s=_e,d=_e,(f=Xe())!==r?(44===e.charCodeAt(_e)?(m=he,_e++):(m=r,Ke(ye)),m!==r?d=f=[f,m]:(_e=d,d=r)):(_e=d,d=r),d===r&&(d=_e,(f=Xe())!==r?(59===e.charCodeAt(_e)?(m=Be,_e++):(m=r,Ke(Ne)),m!==r?d=f=[f,m]:(_e=d,d=r)):(_e=d,d=r),d===r)){for(d=_e,f=[],a.test(e.charAt(_e))?(m=e.charAt(_e),_e++):(m=r,Ke(i));m!==r;)f.push(m),a.test(e.charAt(_e))?(m=e.charAt(_e),_e++):(m=r,Ke(i));f!==r?(c.test(e.charAt(_e))?(m=e.charAt(_e),_e++):(m=r,Ke(l)),m===r&&(m=null),m!==r?(u.test(e.charAt(_e))?(g=e.charAt(_e),_e++):(g=r,Ke(p)),g!==r?d=f=[f,m,g]:(_e=d,d=r)):(_e=d,d=r)):(_e=d,d=r)}d!==r&&(f=Xe())!==r&&(m=Tt())!==r?s=d=[d,f,m]:(_e=s,s=r)}if(o!==r){if(s=_e,(d=Xe())!==r?(44===e.charCodeAt(_e)?(f=he,_e++):(f=r,Ke(ye)),f!==r?s=d=[d,f]:(_e=s,s=r)):(_e=s,s=r),s===r&&(s=_e,(d=Xe())!==r?(59===e.charCodeAt(_e)?(f=Be,_e++):(f=r,Ke(Ne)),f!==r?s=d=[d,f]:(_e=s,s=r)):(_e=s,s=r),s===r)){for(s=_e,d=[],a.test(e.charAt(_e))?(f=e.charAt(_e),_e++):(f=r,Ke(i));f!==r;)d.push(f),a.test(e.charAt(_e))?(f=e.charAt(_e),_e++):(f=r,Ke(i));d!==r?(c.test(e.charAt(_e))?(f=e.charAt(_e),_e++):(f=r,Ke(l)),f===r&&(f=null),f!==r?(u.test(e.charAt(_e))?(m=e.charAt(_e),_e++):(m=r,Ke(p)),m!==r?s=d=[d,f,m]:(_e=s,s=r)):(_e=s,s=r)):(_e=s,s=r)}s===r&&(s=null),s!==r?(x=n,t=n=o.reduce((function(e,t){const n=t[2];return e.concat([n])}),[x])):(_e=t,t=r)}else _e=t,t=r}else _e=t,t=r;var x;return Ve[h]={nextPos:_e,result:t},t}())===r&&(o=null),o!==r&&Xe()!==r?(125===e.charCodeAt(_e)?(s="}",_e++):(s=r,Ke(Oe)),s!==r?(d=o,t=n={type:_t.RECORD,entries:d||[]}):(_e=t,t=r)):(_e=t,t=r)):(_e=t,t=r),Ve[f]={nextPos:_e,result:t},t)}function Tt(){var t,n,o,s,a,i,c,l=68*_e+58,u=Ve[l];return u?(_e=u.nextPos,u.result):(t=_e,n=_e,e.substr(_e,8)===je?(o=je,_e+=8):(o=r,Ke(Le)),o!==r&&(s=Qe())!==r?n=o=[o,s]:(_e=n,n=r),n===r&&(n=null),n!==r&&(o=It())!==r&&(s=Xe())!==r?(63===e.charCodeAt(_e)?(a=W,_e++):(a=r,Ke(G)),a===r&&(a=null),a!==r&&Xe()!==r?(58===e.charCodeAt(_e)?(i=R,_e++):(i=r,Ke(M)),i!==r&&Xe()!==r&&(c=function(){var e,t=68*_e+60,n=Ve[t];if(n)return _e=n.nextPos,n.result;(e=dt())===r&&(e=mt())===r&&(e=Pt())===r&&(e=vt())===r&&(e=Ft())===r&&(e=St())===r&&(e=st())===r&&(e=ut())===r&&(e=ct())===r&&(e=lt());return Ve[t]={nextPos:_e,result:e},e}())!==r?t=n=function(e,t,n,r){const{quoteStyle:o,key:s}=t;return{type:_t.RECORD_ENTRY,key:s,quoteStyle:o,value:"?"===n?{type:_t.OPTIONAL,value:r,meta:{syntax:Lt.SUFFIX_KEY_QUESTION_MARK}}:r,readonly:Boolean(e)}}(n,o,a,c):(_e=t,t=r)):(_e=t,t=r)):(_e=t,t=r),t===r&&(t=_e,n=_e,e.substr(_e,8)===je?(o=je,_e+=8):(o=r,Ke(Le)),o!==r&&(s=Qe())!==r?n=o=[o,s]:(_e=n,n=r),n===r&&(n=null),n!==r&&(o=It())!==r?t=n=function(e,t){const{quoteStyle:n,key:r}=t;return{type:_t.RECORD_ENTRY,key:r,quoteStyle:n,value:null,readonly:Boolean(e)}}(n,o):(_e=t,t=r)),Ve[l]={nextPos:_e,result:t},t)}function It(){var t,n,o,s,a,i,c,l=68*_e+59,u=Ve[l];if(u)return _e=u.nextPos,u.result;if(t=_e,34===e.charCodeAt(_e)?(n=P,_e++):(n=r,Ke(T)),n!==r){for(o=_e,s=[],I.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(F)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));a!==r;)s.push(a),I.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(F)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));(o=s!==r?e.substring(o,_e):s)!==r?(34===e.charCodeAt(_e)?(s=P,_e++):(s=r,Ke(T)),s!==r?t=n=function(e){return{quoteStyle:"double",key:e.replace(/\\"/gu,'"').replace(/\\\\/gu,"\\")}}(o):(_e=t,t=r)):(_e=t,t=r)}else _e=t,t=r;if(t===r){if(t=_e,39===e.charCodeAt(_e)?(n=E,_e++):(n=r,Ke(S)),n!==r){for(o=_e,s=[],C.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(v)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));a!==r;)s.push(a),C.test(e.charAt(_e))?(a=e.charAt(_e),_e++):(a=r,Ke(v)),a===r&&(a=_e,92===e.charCodeAt(_e)?(i=A,_e++):(i=r,Ke(k)),i!==r?(e.length>_e?(c=e.charAt(_e),_e++):(c=r,Ke(w)),c!==r?a=i=[i,c]:(_e=a,a=r)):(_e=a,a=r));(o=s!==r?e.substring(o,_e):s)!==r?(39===e.charCodeAt(_e)?(s=E,_e++):(s=r,Ke(S)),s!==r?t=n=function(e){return{quoteStyle:"single",key:e.replace(/\\'/g,"'").replace(/\\\\/gu,"\\")}}(o):(_e=t,t=r)):(_e=t,t=r)}else _e=t,t=r;t===r&&(t=_e,n=_e,(o=Ze())===r&&(o=pt()),(n=o!==r?e.substring(n,_e):o)!==r&&(n=function(e){return{quoteStyle:"none",key:e}}(n)),t=n)}return Ve[l]={nextPos:_e,result:t},t}function Ft(){var t,n,o,s,a,i=68*_e+61,c=Ve[i];return c?(_e=c.nextPos,c.result):(t=_e,40===e.charCodeAt(_e)?(n=Ae,_e++):(n=r,Ke(ke)),n!==r&&Xe()!==r&&(o=function(){var e,t=68*_e+62,n=Ve[t];if(n)return _e=n.nextPos,n.result;(e=dt())===r&&(e=mt())===r&&(e=Pt())===r&&(e=vt())===r&&(e=yt())===r&&(e=St())===r&&(e=st())===r&&(e=ut())===r&&(e=ct())===r&&(e=lt());return Ve[t]={nextPos:_e,result:e},e}())!==r&&Xe()!==r?(41===e.charCodeAt(_e)?(s=we,_e++):(s=r,Ke(Pe)),s!==r?(a=o,t=n={type:_t.PARENTHESIS,value:a}):(_e=t,t=r)):(_e=t,t=r),Ve[i]={nextPos:_e,result:t},t)}function Dt(){var t,n=68*_e+63,o=Ve[n];return o?(_e=o.nextPos,o.result):((t=function(){var t,n,o,s=68*_e+64,a=Ve[s];if(a)return _e=a.nextPos,a.result;t=_e,e.substr(_e,3)===Re?(n=Re,_e+=3):(n=r,Ke(Me));n!==r&&(o=Ot())!==r?(i=o,t=n={type:_t.VARIADIC,value:i,meta:{syntax:jt.PREFIX_DOTS}}):(_e=t,t=r);var i;return Ve[s]={nextPos:_e,result:t},t}())===r&&(t=function(){var t,n,o,s=68*_e+65,a=Ve[s];if(a)return _e=a.nextPos,a.result;t=_e,(n=Ot())!==r?(e.substr(_e,3)===Re?(o=Re,_e+=3):(o=r,Ke(Me)),o!==r?(i=n,t=n={type:_t.VARIADIC,value:i,meta:{syntax:jt.SUFFIX_DOTS}}):(_e=t,t=r)):(_e=t,t=r);var i;return Ve[s]={nextPos:_e,result:t},t}())===r&&(t=function(){var t,n,o=68*_e+66,s=Ve[o];if(s)return _e=s.nextPos,s.result;t=_e,e.substr(_e,3)===Re?(n=Re,_e+=3):(n=r,Ke(Me));n!==r&&(n={type:_t.VARIADIC,value:{type:_t.ANY},meta:{syntax:jt.ONLY_DOTS}});return t=n,Ve[o]={nextPos:_e,result:t},t}()),Ve[n]={nextPos:_e,result:t},t)}function Ot(){var e,t=68*_e+67,n=Ve[t];return n?(_e=n.nextPos,n.result):((e=dt())===r&&(e=mt())===r&&(e=Pt())===r&&(e=vt())===r&&(e=Ft())===r&&(e=yt())===r&&(e=St())===r&&(e=st())===r&&(e=ut())===r&&(e=ct())===r&&(e=lt()),Ve[t]={nextPos:_e,result:e},e)}const Bt=py,{GenericTypeSyntax:Nt,VariadicTypeSyntax:jt,OptionalTypeSyntax:Lt,NullableTypeSyntax:Rt,NotNullableTypeSyntax:Mt}=Bt,_t=dy,$t={MEMBER:"MEMBER",INNER_MEMBER:"INNER_MEMBER",INSTANCE_MEMBER:"INSTANCE_MEMBER"};if((n=s())!==r&&_e===e.length)return n;throw n!==r&&_e0){for(t=1,r=1;t",!1),Ae=Ke("[",!1),ke=Ke("]",!1),we="new",Pe=Ke("new",!1),Te=Ke("=>",!1),Ie=":",Fe=Ke(":",!1),De="...",Oe=Ke("...",!1),Be="function",Ne=Ke("function",!1),je="this",Le=Ke("this",!1),Re=Ke("{",!1),Me=Ke("}",!1),_e=";",$e=Ke(";",!1),qe="readonly",Ue=Ke("readonly",!1),Ve=0,We=[{line:1,column:1}],Ge=0,ze=[],Je={};if("startRule"in t){if(!(t.startRule in o))throw new Error("Can't start parsing from rule \""+t.startRule+'".');s=o[t.startRule]}function Ke(e,t){return{type:"literal",text:e,ignoreCase:t}}function Ye(e,t,n){return{type:"class",parts:e,inverted:t,ignoreCase:n}}function He(t){var n,r=We[t];if(r)return r;for(n=t-1;!We[n];)n--;for(r={line:(r=We[n]).line,column:r.column};nGe&&(Ge=Ve,ze=[]),ze.push(e))}function Ze(){var e,t,n=78*Ve+0,o=Je[n];return o?(Ve=o.nextPos,o.result):(e=Ve,tt()!==r?((t=qt())===r&&(t=ht())===r&&(t=mt())===r&&(t=xt())===r&&(t=Tt())===r&&(t=wt())===r&&(t=jt())===r&&(t=Mt())===r&&(t=It())===r&&(t=Ft())===r&&(t=St())===r&&(t=Ct())===r&&(t=ot())===r&&(t=$t())===r&&(t=pt())===r&&(t=lt())===r&&(t=ut()),t!==r&&tt()!==r?e=t:(Ve=e,e=r)):(Ve=e,e=r),Je[n]={nextPos:Ve,result:e},e)}function et(){var t,n,o,s=78*Ve+1,d=Je[s];return d?(Ve=d.nextPos,d.result):(a.test(e.charAt(Ve))?(t=e.charAt(Ve),Ve++):(t=r,Qe(i)),t===r&&(t=Ve,c.test(e.charAt(Ve))?(n=e.charAt(Ve),Ve++):(n=r,Qe(l)),n===r&&(n=null),n!==r?(u.test(e.charAt(Ve))?(o=e.charAt(Ve),Ve++):(o=r,Qe(p)),o!==r?t=n=[n,o]:(Ve=t,t=r)):(Ve=t,t=r)),Je[s]={nextPos:Ve,result:t},t)}function tt(){var e,t,n=78*Ve+2,o=Je[n];if(o)return Ve=o.nextPos,o.result;for(e=[],t=et();t!==r;)e.push(t),t=et();return Je[n]={nextPos:Ve,result:e},e}function nt(){var e,t,n=78*Ve+3,o=Je[n];if(o)return Ve=o.nextPos,o.result;if(e=[],(t=et())!==r)for(;t!==r;)e.push(t),t=et();else e=r;return Je[n]={nextPos:Ve,result:e},e}function rt(){var t,n,o,s,a,i=78*Ve+4,c=Je[i];if(c)return Ve=c.nextPos,c.result;if(t=Ve,n=Ve,d.test(e.charAt(Ve))?(o=e.charAt(Ve),Ve++):(o=r,Qe(f)),o!==r){for(s=[],m.test(e.charAt(Ve))?(a=e.charAt(Ve),Ve++):(a=r,Qe(g));a!==r;)s.push(a),m.test(e.charAt(Ve))?(a=e.charAt(Ve),Ve++):(a=r,Qe(g));s!==r?n=o=[o,s]:(Ve=n,n=r)}else Ve=n,n=r;return t=n!==r?e.substring(t,Ve):n,Je[i]={nextPos:Ve,result:t},t}function ot(){var t,n,o,s,a,i,c,l,u,p,d,f=78*Ve+5,m=Je[f];if(m)return Ve=m.nextPos,m.result;if(t=Ve,(n=$t())===r&&(n=function(){var t,n,o,s,a,i=78*Ve+34,c=Je[i];if(c)return Ve=c.nextPos,c.result;t=Ve,e.substr(Ve,6)===le?(n=le,Ve+=6):(n=r,Qe(ue));n!==r&&tt()!==r?(40===e.charCodeAt(Ve)?(o=pe,Ve++):(o=r,Qe(de)),o!==r&&tt()!==r&&(s=dt())!==r&&tt()!==r?(41===e.charCodeAt(Ve)?(a=fe,Ve++):(a=r,Qe(me)),a!==r?t=n=function(e,t){return{type:Yt.IMPORT,path:t}}(0,s):(Ve=t,t=r)):(Ve=t,t=r)):(Ve=t,t=r);return Je[i]={nextPos:Ve,result:t},t}())===r&&(n=st()),n!==r){for(o=[],s=Ve,(a=tt())!==r&&(i=it())!==r&&(c=tt())!==r?(e.substr(Ve,6)===h?(l=h,Ve+=6):(l=r,Qe(y)),l===r&&(l=null),l!==r&&(u=tt())!==r&&(p=at())!==r?s=a=[a,i,c,l,u,p]:(Ve=s,s=r)):(Ve=s,s=r);s!==r;)o.push(s),s=Ve,(a=tt())!==r&&(i=it())!==r&&(c=tt())!==r?(e.substr(Ve,6)===h?(l=h,Ve+=6):(l=r,Qe(y)),l===r&&(l=null),l!==r&&(u=tt())!==r&&(p=at())!==r?s=a=[a,i,c,l,u,p]:(Ve=s,s=r)):(Ve=s,s=r);o!==r?(d=n,t=n=o.reduce((function(e,t){const n=t[1],r=t[3],o=t[5],{quoteStyle:s,name:a}=o;switch(n){case Ht.MEMBER:return{type:Yt.MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};case Ht.INSTANCE_MEMBER:return{type:Yt.INSTANCE_MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};case Ht.INNER_MEMBER:return{type:Yt.INNER_MEMBER,owner:e,name:a,quoteStyle:s,hasEventPrefix:Boolean(r)};default:throw new Error('Unexpected operator type: "'+n+'"')}}),d)):(Ve=t,t=r)}else Ve=t,t=r;return Je[f]={nextPos:Ve,result:t},t}function st(){var t,n,o,s,a,i,c=78*Ve+6,l=Je[c];if(l)return Ve=l.nextPos,l.result;if(Ve,n=Ve,o=Ve,d.test(e.charAt(Ve))?(s=e.charAt(Ve),Ve++):(s=r,Qe(f)),s!==r){for(a=[],x.test(e.charAt(Ve))?(i=e.charAt(Ve),Ve++):(i=r,Qe(b));i!==r;)a.push(i),x.test(e.charAt(Ve))?(i=e.charAt(Ve),Ve++):(i=r,Qe(b));a!==r?o=s=[s,a]:(Ve=o,o=r)}else Ve=o,o=r;return(n=o!==r?e.substring(n,Ve):o)!==r&&(n=function(e){return{type:Yt.NAME,name:e}}(n)),t=n,Je[c]={nextPos:Ve,result:t},t}function at(){var t,n,o,s,a,i,c,l=78*Ve+7,u=Je[l];if(u)return Ve=u.nextPos,u.result;if(t=Ve,39===e.charCodeAt(Ve)?(n=E,Ve++):(n=r,Qe(S)),n!==r){for(o=Ve,s=[],C.test(e.charAt(Ve))?(a=e.charAt(Ve),Ve++):(a=r,Qe(v)),a===r&&(a=Ve,92===e.charCodeAt(Ve)?(i=A,Ve++):(i=r,Qe(k)),i!==r?(e.length>Ve?(c=e.charAt(Ve),Ve++):(c=r,Qe(w)),c!==r?a=i=[i,c]:(Ve=a,a=r)):(Ve=a,a=r));a!==r;)s.push(a),C.test(e.charAt(Ve))?(a=e.charAt(Ve),Ve++):(a=r,Qe(v)),a===r&&(a=Ve,92===e.charCodeAt(Ve)?(i=A,Ve++):(i=r,Qe(k)),i!==r?(e.length>Ve?(c=e.charAt(Ve),Ve++):(c=r,Qe(w)),c!==r?a=i=[i,c]:(Ve=a,a=r)):(Ve=a,a=r));(o=s!==r?e.substring(o,Ve):s)!==r?(39===e.charCodeAt(Ve)?(s=E,Ve++):(s=r,Qe(S)),s!==r?t=n=function(e){return{quoteStyle:"single",name:e.replace(/\\'/g,"'").replace(/\\\\/gu,"\\")}}(o):(Ve=t,t=r)):(Ve=t,t=r)}else Ve=t,t=r;if(t===r){if(t=Ve,34===e.charCodeAt(Ve)?(n=P,Ve++):(n=r,Qe(T)),n!==r){for(o=Ve,s=[],I.test(e.charAt(Ve))?(a=e.charAt(Ve),Ve++):(a=r,Qe(F)),a===r&&(a=Ve,92===e.charCodeAt(Ve)?(i=A,Ve++):(i=r,Qe(k)),i!==r?(e.length>Ve?(c=e.charAt(Ve),Ve++):(c=r,Qe(w)),c!==r?a=i=[i,c]:(Ve=a,a=r)):(Ve=a,a=r));a!==r;)s.push(a),I.test(e.charAt(Ve))?(a=e.charAt(Ve),Ve++):(a=r,Qe(F)),a===r&&(a=Ve,92===e.charCodeAt(Ve)?(i=A,Ve++):(i=r,Qe(k)),i!==r?(e.length>Ve?(c=e.charAt(Ve),Ve++):(c=r,Qe(w)),c!==r?a=i=[i,c]:(Ve=a,a=r)):(Ve=a,a=r));(o=s!==r?e.substring(o,Ve):s)!==r?(34===e.charCodeAt(Ve)?(s=P,Ve++):(s=r,Qe(T)),s!==r?t=n=function(e){return{quoteStyle:"double",name:e.replace(/\\"/gu,'"').replace(/\\\\/gu,"\\")}}(o):(Ve=t,t=r)):(Ve=t,t=r)}else Ve=t,t=r;t===r&&(t=Ve,(n=rt())!==r&&(n=function(e){return{quoteStyle:"none",name:e}}(n)),t=n)}return Je[l]={nextPos:Ve,result:t},t}function it(){var t,n=78*Ve+8,o=Je[n];return o?(Ve=o.nextPos,o.result):((t=function(){var t,n,o=78*Ve+10,s=Je[o];if(s)return Ve=s.nextPos,s.result;t=Ve,46===e.charCodeAt(Ve)?(n=D,Ve++):(n=r,Qe(O));n!==r&&(n=Ht.MEMBER);return t=n,Je[o]={nextPos:Ve,result:t},t}())===r&&(t=function(){var t,n,o=78*Ve+12,s=Je[o];if(s)return Ve=s.nextPos,s.result;t=Ve,35===e.charCodeAt(Ve)?(n="#",Ve++):(n=r,Qe(N));n!==r&&(n=Ht.INSTANCE_MEMBER);return t=n,Je[o]={nextPos:Ve,result:t},t}())===r&&(t=function(){var t,n,o=78*Ve+11,s=Je[o];if(s)return Ve=s.nextPos,s.result;t=Ve,126===e.charCodeAt(Ve)?(n="~",Ve++):(n=r,Qe(B));n!==r&&(n=Ht.INNER_MEMBER);return t=n,Je[o]={nextPos:Ve,result:t},t}()),Je[n]={nextPos:Ve,result:t},t)}function ct(){var t,n,o,s,a,i,c,l,u,p=78*Ve+9,d=Je[p];if(d)return Ve=d.nextPos,d.result;if(t=Ve,(n=st())!==r){for(o=[],s=Ve,(a=tt())!==r?(46===e.charCodeAt(Ve)?(i=D,Ve++):(i=r,Qe(O)),i!==r&&(c=tt())!==r&&(l=st())!==r?s=a=[a,i,c,l]:(Ve=s,s=r)):(Ve=s,s=r);s!==r;)o.push(s),s=Ve,(a=tt())!==r?(46===e.charCodeAt(Ve)?(i=D,Ve++):(i=r,Qe(O)),i!==r&&(c=tt())!==r&&(l=st())!==r?s=a=[a,i,c,l]:(Ve=s,s=r)):(Ve=s,s=r);o!==r?(u=n,t=n=o.reduce((function(e,t){return{type:Yt.MEMBER,owner:e,name:t[3]}}),u)):(Ve=t,t=r)}else Ve=t,t=r;return Je[p]={nextPos:Ve,result:t},t}function lt(){var t,n,o=78*Ve+14,s=Je[o];return s?(Ve=s.nextPos,s.result):(Ve,42===e.charCodeAt(Ve)?(n="*",Ve++):(n=r,Qe(j)),n!==r&&(n={type:Yt.ANY}),t=n,Je[o]={nextPos:Ve,result:t},t)}function ut(){var t,n,o=78*Ve+15,s=Je[o];return s?(Ve=s.nextPos,s.result):(Ve,63===e.charCodeAt(Ve)?(n=L,Ve++):(n=r,Qe(R)),n!==r&&(n={type:Yt.UNKNOWN}),t=n,Je[o]={nextPos:Ve,result:t},t)}function pt(){var t,n=78*Ve+16,o=Je[n];return o?(Ve=o.nextPos,o.result):((t=dt())===r&&(t=function(){var t,n,o=78*Ve+18,s=Je[o];if(s)return Ve=s.nextPos,s.result;t=Ve,(n=function(){var t,n,o,s,a,i,c=78*Ve+21,l=Je[c];if(l)return Ve=l.nextPos,l.result;t=Ve,n=Ve,45===e.charCodeAt(Ve)?(o=_,Ve++):(o=r,Qe($));o===r&&(o=null);if(o!==r)if(e.substr(Ve,2)===W?(s=W,Ve+=2):(s=r,Qe(G)),s!==r){if(a=[],z.test(e.charAt(Ve))?(i=e.charAt(Ve),Ve++):(i=r,Qe(J)),i!==r)for(;i!==r;)a.push(i),z.test(e.charAt(Ve))?(i=e.charAt(Ve),Ve++):(i=r,Qe(J));else a=r;a!==r?n=o=[o,s,a]:(Ve=n,n=r)}else Ve=n,n=r;else Ve=n,n=r;t=n!==r?e.substring(t,Ve):n;return Je[c]={nextPos:Ve,result:t},t}())===r&&(n=function(){var t,n,o,s,a,i,c=78*Ve+22,l=Je[c];if(l)return Ve=l.nextPos,l.result;t=Ve,n=Ve,45===e.charCodeAt(Ve)?(o=_,Ve++):(o=r,Qe($));o===r&&(o=null);if(o!==r)if(e.substr(Ve,2)===K?(s=K,Ve+=2):(s=r,Qe(Y)),s!==r){if(a=[],H.test(e.charAt(Ve))?(i=e.charAt(Ve),Ve++):(i=r,Qe(X)),i!==r)for(;i!==r;)a.push(i),H.test(e.charAt(Ve))?(i=e.charAt(Ve),Ve++):(i=r,Qe(X));else a=r;a!==r?n=o=[o,s,a]:(Ve=n,n=r)}else Ve=n,n=r;else Ve=n,n=r;t=n!==r?e.substring(t,Ve):n;return Je[c]={nextPos:Ve,result:t},t}())===r&&(n=function(){var t,n,o,s,a,i,c=78*Ve+23,l=Je[c];if(l)return Ve=l.nextPos,l.result;t=Ve,n=Ve,45===e.charCodeAt(Ve)?(o=_,Ve++):(o=r,Qe($));o===r&&(o=null);if(o!==r)if(e.substr(Ve,2)===Q?(s=Q,Ve+=2):(s=r,Qe(Z)),s!==r){if(a=[],ee.test(e.charAt(Ve))?(i=e.charAt(Ve),Ve++):(i=r,Qe(te)),i!==r)for(;i!==r;)a.push(i),ee.test(e.charAt(Ve))?(i=e.charAt(Ve),Ve++):(i=r,Qe(te));else a=r;a!==r?n=o=[o,s,a]:(Ve=n,n=r)}else Ve=n,n=r;else Ve=n,n=r;t=n!==r?e.substring(t,Ve):n;return Je[c]={nextPos:Ve,result:t},t}())===r&&(n=function(){var t,n,o,s,a=78*Ve+19,i=Je[a];if(i)return Ve=i.nextPos,i.result;t=Ve,n=Ve,43===e.charCodeAt(Ve)?(o="+",Ve++):(o=r,Qe(M));o===r&&(45===e.charCodeAt(Ve)?(o=_,Ve++):(o=r,Qe($)));o===r&&(o=null);o!==r&&(s=ft())!==r?n=o=[o,s]:(Ve=n,n=r);t=n!==r?e.substring(t,Ve):n;return Je[a]={nextPos:Ve,result:t},t}());n!==r&&(a=n,n={type:Yt.NUMBER_VALUE,number:a});var a;return t=n,Je[o]={nextPos:Ve,result:t},t}()),Je[n]={nextPos:Ve,result:t},t)}function dt(){var t,n,o,s,a,i,c,l,u=78*Ve+17,p=Je[u];if(p)return Ve=p.nextPos,p.result;if(t=Ve,34===e.charCodeAt(Ve)?(n=P,Ve++):(n=r,Qe(T)),n!==r){for(o=Ve,s=[],I.test(e.charAt(Ve))?(a=e.charAt(Ve),Ve++):(a=r,Qe(F)),a===r&&(a=Ve,92===e.charCodeAt(Ve)?(i=A,Ve++):(i=r,Qe(k)),i!==r?(e.length>Ve?(c=e.charAt(Ve),Ve++):(c=r,Qe(w)),c!==r?a=i=[i,c]:(Ve=a,a=r)):(Ve=a,a=r));a!==r;)s.push(a),I.test(e.charAt(Ve))?(a=e.charAt(Ve),Ve++):(a=r,Qe(F)),a===r&&(a=Ve,92===e.charCodeAt(Ve)?(i=A,Ve++):(i=r,Qe(k)),i!==r?(e.length>Ve?(c=e.charAt(Ve),Ve++):(c=r,Qe(w)),c!==r?a=i=[i,c]:(Ve=a,a=r)):(Ve=a,a=r));(o=s!==r?e.substring(o,Ve):s)!==r?(34===e.charCodeAt(Ve)?(s=P,Ve++):(s=r,Qe(T)),s!==r?(l=o,t=n={type:Yt.STRING_VALUE,quoteStyle:"double",string:l.replace(/\\"/gu,'"').replace(/\\\\/gu,"\\")}):(Ve=t,t=r)):(Ve=t,t=r)}else Ve=t,t=r;if(t===r)if(t=Ve,39===e.charCodeAt(Ve)?(n=E,Ve++):(n=r,Qe(S)),n!==r){for(o=Ve,s=[],C.test(e.charAt(Ve))?(a=e.charAt(Ve),Ve++):(a=r,Qe(v)),a===r&&(a=Ve,92===e.charCodeAt(Ve)?(i=A,Ve++):(i=r,Qe(k)),i!==r?(e.length>Ve?(c=e.charAt(Ve),Ve++):(c=r,Qe(w)),c!==r?a=i=[i,c]:(Ve=a,a=r)):(Ve=a,a=r));a!==r;)s.push(a),C.test(e.charAt(Ve))?(a=e.charAt(Ve),Ve++):(a=r,Qe(v)),a===r&&(a=Ve,92===e.charCodeAt(Ve)?(i=A,Ve++):(i=r,Qe(k)),i!==r?(e.length>Ve?(c=e.charAt(Ve),Ve++):(c=r,Qe(w)),c!==r?a=i=[i,c]:(Ve=a,a=r)):(Ve=a,a=r));(o=s!==r?e.substring(o,Ve):s)!==r?(39===e.charCodeAt(Ve)?(s=E,Ve++):(s=r,Qe(S)),s!==r?t=n=function(e){return{type:Yt.STRING_VALUE,quoteStyle:"single",string:e.replace(/\\'/g,"'").replace(/\\\\/gu,"\\")}}(o):(Ve=t,t=r)):(Ve=t,t=r)}else Ve=t,t=r;return Je[u]={nextPos:Ve,result:t},t}function ft(){var t,n,o,s,a,i,c,l,u=78*Ve+20,p=Je[u];if(p)return Ve=p.nextPos,p.result;if(t=Ve,n=Ve,o=Ve,s=[],q.test(e.charAt(Ve))?(a=e.charAt(Ve),Ve++):(a=r,Qe(U)),a!==r)for(;a!==r;)s.push(a),q.test(e.charAt(Ve))?(a=e.charAt(Ve),Ve++):(a=r,Qe(U));else s=r;if(s!==r){if(a=Ve,46===e.charCodeAt(Ve)?(i=D,Ve++):(i=r,Qe(O)),i!==r){if(c=[],q.test(e.charAt(Ve))?(l=e.charAt(Ve),Ve++):(l=r,Qe(U)),l!==r)for(;l!==r;)c.push(l),q.test(e.charAt(Ve))?(l=e.charAt(Ve),Ve++):(l=r,Qe(U));else c=r;c!==r?a=i=[i,c]:(Ve=a,a=r)}else Ve=a,a=r;a===r&&(a=null),a!==r?o=s=[s,a]:(Ve=o,o=r)}else Ve=o,o=r;if(o===r)if(o=Ve,46===e.charCodeAt(Ve)?(s=D,Ve++):(s=r,Qe(O)),s!==r){if(a=[],q.test(e.charAt(Ve))?(i=e.charAt(Ve),Ve++):(i=r,Qe(U)),i!==r)for(;i!==r;)a.push(i),q.test(e.charAt(Ve))?(i=e.charAt(Ve),Ve++):(i=r,Qe(U));else a=r;a!==r?o=s=[s,a]:(Ve=o,o=r)}else Ve=o,o=r;if(o!==r){if(s=Ve,101===e.charCodeAt(Ve)?(a="e",Ve++):(a=r,Qe(V)),a!==r)if(43===e.charCodeAt(Ve)?(i="+",Ve++):(i=r,Qe(M)),i===r&&(45===e.charCodeAt(Ve)?(i=_,Ve++):(i=r,Qe($))),i===r&&(i=null),i!==r){if(c=[],q.test(e.charAt(Ve))?(l=e.charAt(Ve),Ve++):(l=r,Qe(U)),l!==r)for(;l!==r;)c.push(l),q.test(e.charAt(Ve))?(l=e.charAt(Ve),Ve++):(l=r,Qe(U));else c=r;c!==r?s=a=[a,i,c]:(Ve=s,s=r)}else Ve=s,s=r;else Ve=s,s=r;s===r&&(s=null),s!==r?n=o=[o,s]:(Ve=n,n=r)}else Ve=n,n=r;return t=n!==r?e.substring(t,Ve):n,Je[u]={nextPos:Ve,result:t},t}function mt(){var t,n,o,s,a,i,c=78*Ve+24,l=Je[c];return l?(Ve=l.nextPos,l.result):(t=Ve,(n=gt())!==r&&tt()!==r?(38===e.charCodeAt(Ve)?(o="&",Ve++):(o=r,Qe(ne)),o!==r&&tt()!==r?((s=mt())===r&&(s=gt()),s!==r?(a=n,i=s,t=n={type:Yt.INTERSECTION,left:a,right:i}):(Ve=t,t=r)):(Ve=t,t=r)):(Ve=t,t=r),Je[c]={nextPos:Ve,result:t},t)}function gt(){var e,t=78*Ve+25,n=Je[t];return n?(Ve=n.nextPos,n.result):((e=xt())===r&&(e=jt())===r&&(e=Mt())===r&&(e=It())===r&&(e=Ft())===r&&(e=$t())===r&&(e=St())===r&&(e=Ct())===r&&(e=wt())===r&&(e=Tt())===r&&(e=ot())===r&&(e=pt())===r&&(e=lt())===r&&(e=ut()),Je[t]={nextPos:Ve,result:e},e)}function ht(){var t,n,o,s,a,i,c=78*Ve+26,l=Je[c];return l?(Ve=l.nextPos,l.result):(t=Ve,(n=yt())!==r&&tt()!==r?(124===e.charCodeAt(Ve)?(o="|",Ve++):(o=r,Qe(re)),o!==r&&tt()!==r?((s=ht())===r&&(s=yt()),s!==r?(a=n,i=s,t=n={type:Yt.UNION,left:a,right:i}):(Ve=t,t=r)):(Ve=t,t=r)):(Ve=t,t=r),Je[c]={nextPos:Ve,result:t},t)}function yt(){var e,t=78*Ve+27,n=Je[t];return n?(Ve=n.nextPos,n.result):((e=xt())===r&&(e=jt())===r&&(e=Mt())===r&&(e=It())===r&&(e=Ft())===r&&(e=$t())===r&&(e=St())===r&&(e=Ct())===r&&(e=wt())===r&&(e=Tt())===r&&(e=ot())===r&&(e=pt())===r&&(e=lt())===r&&(e=ut()),Je[t]={nextPos:Ve,result:e},e)}function xt(){var t,n=78*Ve+28,o=Je[n];return o?(Ve=o.nextPos,o.result):((t=function(){var t,n=78*Ve+38,o=Je[n];if(o)return Ve=o.nextPos,o.result;(t=function(){var t,n,o,s=78*Ve+42,a=Je[s];if(a)return Ve=a.nextPos,a.result;t=Ve,(n=At())===r&&(n=kt())===r&&(n=vt());n!==r&&tt()!==r?(61===e.charCodeAt(Ve)?(o="=",Ve++):(o=r,Qe(ye)),o!==r?(i=n,t=n={type:Yt.OPTIONAL,value:i,meta:{syntax:zt.SUFFIX_EQUALS_SIGN}}):(Ve=t,t=r)):(Ve=t,t=r);var i;return Je[s]={nextPos:Ve,result:t},t}())===r&&(t=At())===r&&(t=kt());return Je[n]={nextPos:Ve,result:t},t}())===r&&(t=bt()),Je[n]={nextPos:Ve,result:t},t)}function bt(){var t,n=78*Ve+29,o=Je[n];return o?(Ve=o.nextPos,o.result):((t=function(){var t,n,o,s=78*Ve+37,a=Je[s];if(a)return Ve=a.nextPos,a.result;t=Ve,61===e.charCodeAt(Ve)?(n=he,Ve++):(n=r,Qe(ye));n!==r&&tt()!==r&&(o=Et())!==r?(i=o,t=n={type:Yt.OPTIONAL,value:i,meta:{syntax:zt.PREFIX_EQUALS_SIGN}}):(Ve=t,t=r);var i;return Je[s]={nextPos:Ve,result:t},t}())===r&&(t=function(){var t,n,o,s=78*Ve+36,a=Je[s];if(a)return Ve=a.nextPos,a.result;t=Ve,33===e.charCodeAt(Ve)?(n="!",Ve++):(n=r,Qe(ge));n!==r&&tt()!==r&&(o=Et())!==r?(i=o,t=n={type:Yt.NOT_NULLABLE,value:i,meta:{syntax:Kt.PREFIX_BANG}}):(Ve=t,t=r);var i;return Je[s]={nextPos:Ve,result:t},t}())===r&&(t=function(){var t,n,o,s=78*Ve+35,a=Je[s];if(a)return Ve=a.nextPos,a.result;t=Ve,63===e.charCodeAt(Ve)?(n=L,Ve++):(n=r,Qe(R));n!==r&&tt()!==r&&(o=Et())!==r?(i=o,t=n={type:Yt.NULLABLE,value:i,meta:{syntax:Jt.PREFIX_QUESTION_MARK}}):(Ve=t,t=r);var i;return Je[s]={nextPos:Ve,result:t},t}()),Je[n]={nextPos:Ve,result:t},t)}function Et(){var e,t=78*Ve+30,n=Je[t];return n?(Ve=n.nextPos,n.result):((e=wt())===r&&(e=jt())===r&&(e=Mt())===r&&(e=It())===r&&(e=Ft())===r&&(e=$t())===r&&(e=ot())===r&&(e=pt())===r&&(e=lt())===r&&(e=ut()),Je[t]={nextPos:Ve,result:e},e)}function St(){var t,n,o,s=78*Ve+31,a=Je[s];return a?(Ve=a.nextPos,a.result):(t=Ve,e.substr(Ve,6)===oe?(n=oe,Ve+=6):(n=r,Qe(se)),n!==r&&nt()!==r&&(o=ct())!==r?t=n=function(e,t){return{type:Yt.TYPE_QUERY,name:t}}(0,o):(Ve=t,t=r),Je[s]={nextPos:Ve,result:t},t)}function Ct(){var t,n,o,s,a=78*Ve+32,i=Je[a];return i?(Ve=i.nextPos,i.result):(t=Ve,e.substr(Ve,5)===ae?(n=ae,Ve+=5):(n=r,Qe(ie)),n!==r&&(o=nt())!==r&&(s=function(){var e,t=78*Ve+33,n=Je[t];if(n)return Ve=n.nextPos,n.result;(e=ht())===r&&(e=mt())===r&&(e=xt())===r&&(e=jt())===r&&(e=Mt())===r&&(e=Ft())===r&&(e=$t())===r&&(e=St())===r&&(e=Ct())===r&&(e=Tt())===r&&(e=wt())===r&&(e=ot())===r&&(e=pt())===r&&(e=lt())===r&&(e=ut());return Je[t]={nextPos:Ve,result:e},e}())!==r?t=n=ce(0,s):(Ve=t,t=r),t===r&&(t=Ve,e.substr(Ve,5)===ae?(n=ae,Ve+=5):(n=r,Qe(ie)),n!==r&&(o=$t())!==r?t=n=ce(0,o):(Ve=t,t=r)),Je[a]={nextPos:Ve,result:t},t)}function vt(){var e,t=78*Ve+39,n=Je[t];return n?(Ve=n.nextPos,n.result):((e=bt())===r&&(e=wt())===r&&(e=jt())===r&&(e=Mt())===r&&(e=It())===r&&(e=Ft())===r&&(e=$t())===r&&(e=ot())===r&&(e=pt())===r&&(e=lt())===r&&(e=ut()),Je[t]={nextPos:Ve,result:e},e)}function At(){var t,n,o,s,a=78*Ve+40,i=Je[a];return i?(Ve=i.nextPos,i.result):(t=Ve,(n=vt())!==r&&tt()!==r?(63===e.charCodeAt(Ve)?(o=L,Ve++):(o=r,Qe(R)),o!==r?(s=n,t=n={type:Yt.NULLABLE,value:s,meta:{syntax:Jt.SUFFIX_QUESTION_MARK}}):(Ve=t,t=r)):(Ve=t,t=r),Je[a]={nextPos:Ve,result:t},t)}function kt(){var t,n,o,s,a=78*Ve+41,i=Je[a];return i?(Ve=i.nextPos,i.result):(t=Ve,(n=vt())!==r&&tt()!==r?(33===e.charCodeAt(Ve)?(o="!",Ve++):(o=r,Qe(ge)),o!==r?(s=n,t=n={type:Yt.NOT_NULLABLE,value:s,meta:{syntax:Kt.SUFFIX_BANG}}):(Ve=t,t=r)):(Ve=t,t=r),Je[a]={nextPos:Ve,result:t},t)}function wt(){var t,n,o,s,a,i,c,l=78*Ve+43,u=Je[l];return u?(Ve=u.nextPos,u.result):(t=Ve,(n=function(){var e,t=78*Ve+44,n=Je[t];if(n)return Ve=n.nextPos,n.result;(e=$t())===r&&(e=ot())===r&&(e=pt())===r&&(e=lt())===r&&(e=ut());return Je[t]={nextPos:Ve,result:e},e}())!==r&&tt()!==r&&(o=function(){var t,n=78*Ve+47,o=Je[n];if(o)return Ve=o.nextPos,o.result;(t=function(){var t,n,o=78*Ve+48,s=Je[o];if(s)return Ve=s.nextPos,s.result;t=Ve,e.substr(Ve,2)===Ee?(n=Ee,Ve+=2):(n=r,Qe(Se));n!==r&&(n=Wt.ANGLE_BRACKET_WITH_DOT);return t=n,Je[o]={nextPos:Ve,result:t},t}())===r&&(t=function(){var t,n,o=78*Ve+49,s=Je[o];if(s)return Ve=s.nextPos,s.result;t=Ve,60===e.charCodeAt(Ve)?(n="<",Ve++):(n=r,Qe(Ce));n!==r&&(n=Wt.ANGLE_BRACKET);return t=n,Je[o]={nextPos:Ve,result:t},t}());return Je[n]={nextPos:Ve,result:t},t}())!==r&&tt()!==r&&(s=function(){var t,n,o,s,a,i,c,l,u=78*Ve+46,p=Je[u];if(p)return Ve=p.nextPos,p.result;if(t=Ve,(n=Pt())!==r){for(o=[],s=Ve,(a=tt())!==r?(44===e.charCodeAt(Ve)?(i=xe,Ve++):(i=r,Qe(be)),i!==r&&(c=tt())!==r&&(l=Pt())!==r?s=a=[a,i,c,l]:(Ve=s,s=r)):(Ve=s,s=r);s!==r;)o.push(s),s=Ve,(a=tt())!==r?(44===e.charCodeAt(Ve)?(i=xe,Ve++):(i=r,Qe(be)),i!==r&&(c=tt())!==r&&(l=Pt())!==r?s=a=[a,i,c,l]:(Ve=s,s=r)):(Ve=s,s=r);o!==r?(d=n,t=n=o.reduce((function(e,t){return e.concat([t[3]])}),[d])):(Ve=t,t=r)}else Ve=t,t=r;var d;return Je[u]={nextPos:Ve,result:t},t}())!==r&&tt()!==r&&function(){var t,n=78*Ve+50,o=Je[n];if(o)return Ve=o.nextPos,o.result;62===e.charCodeAt(Ve)?(t=">",Ve++):(t=r,Qe(ve));return Je[n]={nextPos:Ve,result:t},t}()!==r?(a=n,i=o,c=s,t=n={type:Yt.GENERIC,subject:a,objects:c,meta:{syntax:i}}):(Ve=t,t=r),Je[l]={nextPos:Ve,result:t},t)}function Pt(){var e,t=78*Ve+45,n=Je[t];return n?(Ve=n.nextPos,n.result):((e=ht())===r&&(e=mt())===r&&(e=xt())===r&&(e=jt())===r&&(e=Mt())===r&&(e=It())===r&&(e=Ft())===r&&(e=$t())===r&&(e=Tt())===r&&(e=wt())===r&&(e=St())===r&&(e=Ct())===r&&(e=ot())===r&&(e=pt())===r&&(e=lt())===r&&(e=ut()),Je[t]={nextPos:Ve,result:e},e)}function Tt(){var t,n,o,s,a,i,c,l,u,p=78*Ve+51,d=Je[p];if(d)return Ve=d.nextPos,d.result;if(t=Ve,(n=function(){var e,t=78*Ve+52,n=Je[t];if(n)return Ve=n.nextPos,n.result;(e=xt())===r&&(e=jt())===r&&(e=Mt())===r&&(e=It())===r&&(e=Ft())===r&&(e=$t())===r&&(e=wt())===r&&(e=St())===r&&(e=Ct())===r&&(e=ot())===r&&(e=pt())===r&&(e=lt())===r&&(e=ut());return Je[t]={nextPos:Ve,result:e},e}())!==r){if(o=[],s=Ve,(a=tt())!==r?(91===e.charCodeAt(Ve)?(i="[",Ve++):(i=r,Qe(Ae)),i!==r&&(c=tt())!==r?(93===e.charCodeAt(Ve)?(l="]",Ve++):(l=r,Qe(ke)),l!==r?s=a=[a,i,c,l]:(Ve=s,s=r)):(Ve=s,s=r)):(Ve=s,s=r),s!==r)for(;s!==r;)o.push(s),s=Ve,(a=tt())!==r?(91===e.charCodeAt(Ve)?(i="[",Ve++):(i=r,Qe(Ae)),i!==r&&(c=tt())!==r?(93===e.charCodeAt(Ve)?(l="]",Ve++):(l=r,Qe(ke)),l!==r?s=a=[a,i,c,l]:(Ve=s,s=r)):(Ve=s,s=r)):(Ve=s,s=r);else o=r;o!==r?(u=n,t=n=o.reduce((function(e){return{type:Yt.GENERIC,subject:{type:Yt.NAME,name:"Array"},objects:[e],meta:{syntax:Wt.SQUARE_BRACKET}}}),u)):(Ve=t,t=r)}else Ve=t,t=r;return Je[p]={nextPos:Ve,result:t},t}function It(){var t,n,o,s,a,i,c,l,u=78*Ve+53,p=Je[u];return p?(Ve=p.nextPos,p.result):(t=Ve,e.substr(Ve,3)===we?(n=we,Ve+=3):(n=r,Qe(Pe)),n===r&&(n=null),n!==r&&tt()!==r&&(o=function(){var t,n,o,s,a=78*Ve+54,i=Je[a];if(i)return Ve=i.nextPos,i.result;t=Ve,40===e.charCodeAt(Ve)?(n=pe,Ve++):(n=r,Qe(de));n!==r&&tt()!==r?(41===e.charCodeAt(Ve)?(o=fe,Ve++):(o=r,Qe(me)),o!==r?t=n=[]:(Ve=t,t=r)):(Ve=t,t=r);t===r&&(t=Ve,40===e.charCodeAt(Ve)?(n=pe,Ve++):(n=r,Qe(de)),n!==r&&tt()!==r&&(o=function(){var t,n,o,s,a,i,c,l,u,p,d,f=78*Ve+55,m=Je[f];if(m)return Ve=m.nextPos,m.result;t=Ve,n=[],o=Ve,(s=rt())!==r&&(a=tt())!==r?(58===e.charCodeAt(Ve)?(i=Ie,Ve++):(i=r,Qe(Fe)),i!==r&&(c=tt())!==r?((l=Bt())===r&&(l=null),l!==r&&(u=tt())!==r?(44===e.charCodeAt(Ve)?(p=xe,Ve++):(p=r,Qe(be)),p!==r&&(d=tt())!==r?o=s=[s,a,i,c,l,u,p,d]:(Ve=o,o=r)):(Ve=o,o=r)):(Ve=o,o=r)):(Ve=o,o=r);for(;o!==r;)n.push(o),o=Ve,(s=rt())!==r&&(a=tt())!==r?(58===e.charCodeAt(Ve)?(i=Ie,Ve++):(i=r,Qe(Fe)),i!==r&&(c=tt())!==r?((l=Bt())===r&&(l=null),l!==r&&(u=tt())!==r?(44===e.charCodeAt(Ve)?(p=xe,Ve++):(p=r,Qe(be)),p!==r&&(d=tt())!==r?o=s=[s,a,i,c,l,u,p,d]:(Ve=o,o=r)):(Ve=o,o=r)):(Ve=o,o=r)):(Ve=o,o=r);n!==r?((o=function(){var t,n,o,s,a,i=78*Ve+56,c=Je[i];if(c)return Ve=c.nextPos,c.result;t=Ve,e.substr(Ve,3)===De?(n=De,Ve+=3):(n=r,Qe(Oe));n===r&&(n=null);n!==r&&tt()!==r&&(o=rt())!==r&&tt()!==r?(58===e.charCodeAt(Ve)?(s=Ie,Ve++):(s=r,Qe(Fe)),s!==r&&tt()!==r?((a=Bt())===r&&(a=null),a!==r?t=n=function(e,t,n){const r={type:Yt.NAMED_PARAMETER,name:t,typeName:n};return e?{type:Yt.VARIADIC,value:r,meta:{syntax:Gt.PREFIX_DOTS}}:r}(n,o,a):(Ve=t,t=r)):(Ve=t,t=r)):(Ve=t,t=r);return Je[i]={nextPos:Ve,result:t},t}())===r&&(o=null),o!==r?(g=o,t=n=n.reduceRight((function(e,t){return[{type:Yt.NAMED_PARAMETER,name:t[0],typeName:t[4]}].concat(e)}),g?[g]:[])):(Ve=t,t=r)):(Ve=t,t=r);var g;return Je[f]={nextPos:Ve,result:t},t}())!==r&&tt()!==r?(41===e.charCodeAt(Ve)?(s=fe,Ve++):(s=r,Qe(me)),s!==r?t=n=o:(Ve=t,t=r)):(Ve=t,t=r));return Je[a]={nextPos:Ve,result:t},t}())!==r&&tt()!==r?("=>"===e.substr(Ve,2)?(s="=>",Ve+=2):(s=r,Qe(Te)),s!==r&&tt()!==r&&(a=Nt())!==r?(i=n,c=o,l=a,t=n={type:Yt.ARROW,params:c,returns:l,new:i}):(Ve=t,t=r)):(Ve=t,t=r),Je[u]={nextPos:Ve,result:t},t)}function Ft(){var t,n,o,s,a,i,c,l=78*Ve+57,u=Je[l];return u?(Ve=u.nextPos,u.result):(t=Ve,e.substr(Ve,8)===Be?(n=Be,Ve+=8):(n=r,Qe(Ne)),n!==r&&tt()!==r&&(o=function(){var t,n,o,s,a,i,c=78*Ve+58,l=Je[c];if(l)return Ve=l.nextPos,l.result;t=Ve,40===e.charCodeAt(Ve)?(n=pe,Ve++):(n=r,Qe(de));n!==r&&tt()!==r&&(o=Dt())!==r&&tt()!==r?(44===e.charCodeAt(Ve)?(s=xe,Ve++):(s=r,Qe(be)),s!==r&&tt()!==r&&(a=Ot())!==r&&tt()!==r?(41===e.charCodeAt(Ve)?(i=fe,Ve++):(i=r,Qe(me)),i!==r?t=n={params:a,modifier:o}:(Ve=t,t=r)):(Ve=t,t=r)):(Ve=t,t=r);t===r&&(t=Ve,40===e.charCodeAt(Ve)?(n=pe,Ve++):(n=r,Qe(de)),n!==r&&tt()!==r&&(o=Dt())!==r&&tt()!==r?(41===e.charCodeAt(Ve)?(s=fe,Ve++):(s=r,Qe(me)),s!==r?t=n=function(e){return{params:[],modifier:e}}(o):(Ve=t,t=r)):(Ve=t,t=r),t===r&&(t=Ve,40===e.charCodeAt(Ve)?(n=pe,Ve++):(n=r,Qe(de)),n!==r&&tt()!==r?(41===e.charCodeAt(Ve)?(o=fe,Ve++):(o=r,Qe(me)),o!==r?t=n={params:[],modifier:{nodeThis:null,nodeNew:null}}:(Ve=t,t=r)):(Ve=t,t=r),t===r&&(t=Ve,40===e.charCodeAt(Ve)?(n=pe,Ve++):(n=r,Qe(de)),n!==r&&tt()!==r&&(o=Ot())!==r&&tt()!==r?(41===e.charCodeAt(Ve)?(s=fe,Ve++):(s=r,Qe(me)),s!==r?t=n=function(e){return{params:e,modifier:{nodeThis:null,nodeNew:null}}}(o):(Ve=t,t=r)):(Ve=t,t=r))));return Je[c]={nextPos:Ve,result:t},t}())!==r&&tt()!==r?(s=Ve,58===e.charCodeAt(Ve)?(a=Ie,Ve++):(a=r,Qe(Fe)),a!==r&&(i=tt())!==r&&(c=Nt())!==r?s=a=[a,i,c]:(Ve=s,s=r),s===r&&(s=null),s!==r?t=n=function(e,t){const n=t?t[2]:null;return{type:Yt.FUNCTION,params:e.params,returns:n,this:e.modifier.nodeThis,new:e.modifier.nodeNew}}(o,s):(Ve=t,t=r)):(Ve=t,t=r),Je[l]={nextPos:Ve,result:t},t)}function Dt(){var t,n,o,s,a,i,c,l=78*Ve+59,u=Je[l];return u?(Ve=u.nextPos,u.result):(t=Ve,n=Ve,e.substr(Ve,4)===je?(o=je,Ve+=4):(o=r,Qe(Le)),o!==r&&(s=tt())!==r?(58===e.charCodeAt(Ve)?(a=Ie,Ve++):(a=r,Qe(Fe)),a!==r&&(i=tt())!==r&&(c=Bt())!==r?n=o=[o,s,a,i,c]:(Ve=n,n=r)):(Ve=n,n=r),n!==r&&(n={nodeThis:n[4],nodeNew:null}),(t=n)===r&&(t=Ve,n=Ve,e.substr(Ve,3)===we?(o=we,Ve+=3):(o=r,Qe(Pe)),o!==r&&(s=tt())!==r?(58===e.charCodeAt(Ve)?(a=Ie,Ve++):(a=r,Qe(Fe)),a!==r&&(i=tt())!==r&&(c=Bt())!==r?n=o=[o,s,a,i,c]:(Ve=n,n=r)):(Ve=n,n=r),n!==r&&(n={nodeThis:null,nodeNew:n[4]}),t=n),Je[l]={nextPos:Ve,result:t},t)}function Ot(){var t,n,o,s,a,i,c,l,u=78*Ve+60,p=Je[u];if(p)return Ve=p.nextPos,p.result;for(t=Ve,n=[],o=Ve,(s=Bt())!==r&&(a=tt())!==r?(44===e.charCodeAt(Ve)?(i=xe,Ve++):(i=r,Qe(be)),i!==r&&(c=tt())!==r?o=s=[s,a,i,c]:(Ve=o,o=r)):(Ve=o,o=r);o!==r;)n.push(o),o=Ve,(s=Bt())!==r&&(a=tt())!==r?(44===e.charCodeAt(Ve)?(i=xe,Ve++):(i=r,Qe(be)),i!==r&&(c=tt())!==r?o=s=[s,a,i,c]:(Ve=o,o=r)):(Ve=o,o=r);return n!==r?((o=qt())===r&&(o=Ut()),o===r&&(o=null),o!==r?(l=o,t=n=n.reduceRight((function(e,t){const[n]=t;return[n].concat(e)}),l?[l]:[])):(Ve=t,t=r)):(Ve=t,t=r),Je[u]={nextPos:Ve,result:t},t}function Bt(){var e,t=78*Ve+61,n=Je[t];return n?(Ve=n.nextPos,n.result):((e=ht())===r&&(e=mt())===r&&(e=St())===r&&(e=Ct())===r&&(e=xt())===r&&(e=jt())===r&&(e=Mt())===r&&(e=It())===r&&(e=Ft())===r&&(e=$t())===r&&(e=Tt())===r&&(e=wt())===r&&(e=ot())===r&&(e=pt())===r&&(e=lt())===r&&(e=ut()),Je[t]={nextPos:Ve,result:e},e)}function Nt(){var e,t=78*Ve+62,n=Je[t];return n?(Ve=n.nextPos,n.result):((e=bt())===r&&(e=jt())===r&&(e=Mt())===r&&(e=It())===r&&(e=Ft())===r&&(e=$t())===r&&(e=Tt())===r&&(e=St())===r&&(e=Ct())===r&&(e=wt())===r&&(e=ot())===r&&(e=pt())===r&&(e=lt())===r&&(e=ut()),Je[t]={nextPos:Ve,result:e},e)}function jt(){var t,n,o,s,d,f=78*Ve+63,m=Je[f];return m?(Ve=m.nextPos,m.result):(t=Ve,123===e.charCodeAt(Ve)?(n="{",Ve++):(n=r,Qe(Re)),n!==r&&tt()!==r?((o=function(){var t,n,o,s,d,f,m,g,h=78*Ve+64,y=Je[h];if(y)return Ve=y.nextPos,y.result;if(t=Ve,(n=Lt())!==r){if(o=[],s=Ve,d=Ve,(f=tt())!==r?(44===e.charCodeAt(Ve)?(m=xe,Ve++):(m=r,Qe(be)),m!==r?d=f=[f,m]:(Ve=d,d=r)):(Ve=d,d=r),d===r&&(d=Ve,(f=tt())!==r?(59===e.charCodeAt(Ve)?(m=_e,Ve++):(m=r,Qe($e)),m!==r?d=f=[f,m]:(Ve=d,d=r)):(Ve=d,d=r),d===r)){for(d=Ve,f=[],a.test(e.charAt(Ve))?(m=e.charAt(Ve),Ve++):(m=r,Qe(i));m!==r;)f.push(m),a.test(e.charAt(Ve))?(m=e.charAt(Ve),Ve++):(m=r,Qe(i));f!==r?(c.test(e.charAt(Ve))?(m=e.charAt(Ve),Ve++):(m=r,Qe(l)),m===r&&(m=null),m!==r?(u.test(e.charAt(Ve))?(g=e.charAt(Ve),Ve++):(g=r,Qe(p)),g!==r?d=f=[f,m,g]:(Ve=d,d=r)):(Ve=d,d=r)):(Ve=d,d=r)}for(d!==r&&(f=tt())!==r&&(m=Lt())!==r?s=d=[d,f,m]:(Ve=s,s=r);s!==r;){if(o.push(s),s=Ve,d=Ve,(f=tt())!==r?(44===e.charCodeAt(Ve)?(m=xe,Ve++):(m=r,Qe(be)),m!==r?d=f=[f,m]:(Ve=d,d=r)):(Ve=d,d=r),d===r&&(d=Ve,(f=tt())!==r?(59===e.charCodeAt(Ve)?(m=_e,Ve++):(m=r,Qe($e)),m!==r?d=f=[f,m]:(Ve=d,d=r)):(Ve=d,d=r),d===r)){for(d=Ve,f=[],a.test(e.charAt(Ve))?(m=e.charAt(Ve),Ve++):(m=r,Qe(i));m!==r;)f.push(m),a.test(e.charAt(Ve))?(m=e.charAt(Ve),Ve++):(m=r,Qe(i));f!==r?(c.test(e.charAt(Ve))?(m=e.charAt(Ve),Ve++):(m=r,Qe(l)),m===r&&(m=null),m!==r?(u.test(e.charAt(Ve))?(g=e.charAt(Ve),Ve++):(g=r,Qe(p)),g!==r?d=f=[f,m,g]:(Ve=d,d=r)):(Ve=d,d=r)):(Ve=d,d=r)}d!==r&&(f=tt())!==r&&(m=Lt())!==r?s=d=[d,f,m]:(Ve=s,s=r)}if(o!==r){if(s=Ve,(d=tt())!==r?(44===e.charCodeAt(Ve)?(f=xe,Ve++):(f=r,Qe(be)),f!==r?s=d=[d,f]:(Ve=s,s=r)):(Ve=s,s=r),s===r&&(s=Ve,(d=tt())!==r?(59===e.charCodeAt(Ve)?(f=_e,Ve++):(f=r,Qe($e)),f!==r?s=d=[d,f]:(Ve=s,s=r)):(Ve=s,s=r),s===r)){for(s=Ve,d=[],a.test(e.charAt(Ve))?(f=e.charAt(Ve),Ve++):(f=r,Qe(i));f!==r;)d.push(f),a.test(e.charAt(Ve))?(f=e.charAt(Ve),Ve++):(f=r,Qe(i));d!==r?(c.test(e.charAt(Ve))?(f=e.charAt(Ve),Ve++):(f=r,Qe(l)),f===r&&(f=null),f!==r?(u.test(e.charAt(Ve))?(m=e.charAt(Ve),Ve++):(m=r,Qe(p)),m!==r?s=d=[d,f,m]:(Ve=s,s=r)):(Ve=s,s=r)):(Ve=s,s=r)}s===r&&(s=null),s!==r?(x=n,t=n=o.reduce((function(e,t){const n=t[2];return e.concat([n])}),[x])):(Ve=t,t=r)}else Ve=t,t=r}else Ve=t,t=r;var x;return Je[h]={nextPos:Ve,result:t},t}())===r&&(o=null),o!==r&&tt()!==r?(125===e.charCodeAt(Ve)?(s="}",Ve++):(s=r,Qe(Me)),s!==r?(d=o,t=n={type:Yt.RECORD,entries:d||[]}):(Ve=t,t=r)):(Ve=t,t=r)):(Ve=t,t=r),Je[f]={nextPos:Ve,result:t},t)}function Lt(){var t,n,o,s,a,i,c,l=78*Ve+65,u=Je[l];return u?(Ve=u.nextPos,u.result):(t=Ve,n=Ve,e.substr(Ve,8)===qe?(o=qe,Ve+=8):(o=r,Qe(Ue)),o!==r&&(s=nt())!==r?n=o=[o,s]:(Ve=n,n=r),n===r&&(n=null),n!==r&&(o=Rt())!==r&&(s=tt())!==r?(63===e.charCodeAt(Ve)?(a=L,Ve++):(a=r,Qe(R)),a===r&&(a=null),a!==r&&tt()!==r?(58===e.charCodeAt(Ve)?(i=Ie,Ve++):(i=r,Qe(Fe)),i!==r&&tt()!==r&&(c=function(){var e,t=78*Ve+67,n=Je[t];if(n)return Ve=n.nextPos,n.result;(e=ht())===r&&(e=mt())===r&&(e=xt())===r&&(e=jt())===r&&(e=Mt())===r&&(e=It())===r&&(e=Ft())===r&&(e=$t())===r&&(e=Tt())===r&&(e=wt())===r&&(e=ot())===r&&(e=pt())===r&&(e=lt())===r&&(e=ut());return Je[t]={nextPos:Ve,result:e},e}())!==r?t=n=function(e,t,n,r){const{quoteStyle:o,key:s}=t;return{type:Yt.RECORD_ENTRY,key:s,quoteStyle:o,value:"?"===n?{type:Yt.OPTIONAL,value:r,meta:{syntax:zt.SUFFIX_KEY_QUESTION_MARK}}:r,readonly:Boolean(e)}}(n,o,a,c):(Ve=t,t=r)):(Ve=t,t=r)):(Ve=t,t=r),t===r&&(t=Ve,n=Ve,e.substr(Ve,8)===qe?(o=qe,Ve+=8):(o=r,Qe(Ue)),o!==r&&(s=nt())!==r?n=o=[o,s]:(Ve=n,n=r),n===r&&(n=null),n!==r&&(o=Rt())!==r?t=n=function(e,t){const{quoteStyle:n,key:r}=t;return{type:Yt.RECORD_ENTRY,key:r,quoteStyle:n,value:null,readonly:Boolean(e)}}(n,o):(Ve=t,t=r)),Je[l]={nextPos:Ve,result:t},t)}function Rt(){var t,n,o,s,a,i,c,l=78*Ve+66,u=Je[l];if(u)return Ve=u.nextPos,u.result;if(t=Ve,34===e.charCodeAt(Ve)?(n=P,Ve++):(n=r,Qe(T)),n!==r){for(o=Ve,s=[],I.test(e.charAt(Ve))?(a=e.charAt(Ve),Ve++):(a=r,Qe(F)),a===r&&(a=Ve,92===e.charCodeAt(Ve)?(i=A,Ve++):(i=r,Qe(k)),i!==r?(e.length>Ve?(c=e.charAt(Ve),Ve++):(c=r,Qe(w)),c!==r?a=i=[i,c]:(Ve=a,a=r)):(Ve=a,a=r));a!==r;)s.push(a),I.test(e.charAt(Ve))?(a=e.charAt(Ve),Ve++):(a=r,Qe(F)),a===r&&(a=Ve,92===e.charCodeAt(Ve)?(i=A,Ve++):(i=r,Qe(k)),i!==r?(e.length>Ve?(c=e.charAt(Ve),Ve++):(c=r,Qe(w)),c!==r?a=i=[i,c]:(Ve=a,a=r)):(Ve=a,a=r));(o=s!==r?e.substring(o,Ve):s)!==r?(34===e.charCodeAt(Ve)?(s=P,Ve++):(s=r,Qe(T)),s!==r?t=n=function(e){return{quoteStyle:"double",key:e.replace(/\\"/gu,'"').replace(/\\\\/gu,"\\")}}(o):(Ve=t,t=r)):(Ve=t,t=r)}else Ve=t,t=r;if(t===r){if(t=Ve,39===e.charCodeAt(Ve)?(n=E,Ve++):(n=r,Qe(S)),n!==r){for(o=Ve,s=[],C.test(e.charAt(Ve))?(a=e.charAt(Ve),Ve++):(a=r,Qe(v)),a===r&&(a=Ve,92===e.charCodeAt(Ve)?(i=A,Ve++):(i=r,Qe(k)),i!==r?(e.length>Ve?(c=e.charAt(Ve),Ve++):(c=r,Qe(w)),c!==r?a=i=[i,c]:(Ve=a,a=r)):(Ve=a,a=r));a!==r;)s.push(a),C.test(e.charAt(Ve))?(a=e.charAt(Ve),Ve++):(a=r,Qe(v)),a===r&&(a=Ve,92===e.charCodeAt(Ve)?(i=A,Ve++):(i=r,Qe(k)),i!==r?(e.length>Ve?(c=e.charAt(Ve),Ve++):(c=r,Qe(w)),c!==r?a=i=[i,c]:(Ve=a,a=r)):(Ve=a,a=r));(o=s!==r?e.substring(o,Ve):s)!==r?(39===e.charCodeAt(Ve)?(s=E,Ve++):(s=r,Qe(S)),s!==r?t=n=function(e){return{quoteStyle:"single",key:e.replace(/\\'/g,"'").replace(/\\\\/gu,"\\")}}(o):(Ve=t,t=r)):(Ve=t,t=r)}else Ve=t,t=r;t===r&&(t=Ve,n=Ve,(o=rt())===r&&(o=ft()),(n=o!==r?e.substring(n,Ve):o)!==r&&(n=function(e){return{quoteStyle:"none",key:e}}(n)),t=n)}return Je[l]={nextPos:Ve,result:t},t}function Mt(){var t,n,o,s,a,i=78*Ve+68,c=Je[i];return c?(Ve=c.nextPos,c.result):(t=Ve,91===e.charCodeAt(Ve)?(n="[",Ve++):(n=r,Qe(Ae)),n!==r&&tt()!==r&&(o=function(){var t,n,o,s,a,i,c,l=78*Ve+69,u=Je[l];if(u)return Ve=u.nextPos,u.result;t=Ve,n=[],o=Ve,(s=_t())!==r&&(a=tt())!==r?(44===e.charCodeAt(Ve)?(i=xe,Ve++):(i=r,Qe(be)),i!==r&&(c=tt())!==r?o=s=[s,a,i,c]:(Ve=o,o=r)):(Ve=o,o=r);for(;o!==r;)n.push(o),o=Ve,(s=_t())!==r&&(a=tt())!==r?(44===e.charCodeAt(Ve)?(i=xe,Ve++):(i=r,Qe(be)),i!==r&&(c=tt())!==r?o=s=[s,a,i,c]:(Ve=o,o=r)):(Ve=o,o=r);n!==r?((o=qt())===r&&(o=Ut()),o===r&&(o=null),o!==r?t=n=function(e,t){return e.reduceRight(((e,t)=>{let[n]=t;return[n].concat(e)}),t?[t]:[])}(n,o):(Ve=t,t=r)):(Ve=t,t=r);return Je[l]={nextPos:Ve,result:t},t}())!==r&&tt()!==r?(93===e.charCodeAt(Ve)?(s="]",Ve++):(s=r,Qe(ke)),s!==r?(a=o,t=n={type:Yt.TUPLE,entries:a}):(Ve=t,t=r)):(Ve=t,t=r),Je[i]={nextPos:Ve,result:t},t)}function _t(){var e,t=78*Ve+70,n=Je[t];return n?(Ve=n.nextPos,n.result):((e=ht())===r&&(e=mt())===r&&(e=xt())===r&&(e=jt())===r&&(e=Mt())===r&&(e=It())===r&&(e=Ft())===r&&(e=$t())===r&&(e=St())===r&&(e=Ct())===r&&(e=Tt())===r&&(e=wt())===r&&(e=ot())===r&&(e=pt())===r&&(e=lt())===r&&(e=ut()),Je[t]={nextPos:Ve,result:e},e)}function $t(){var t,n,o,s,a,i=78*Ve+71,c=Je[i];return c?(Ve=c.nextPos,c.result):(t=Ve,40===e.charCodeAt(Ve)?(n=pe,Ve++):(n=r,Qe(de)),n!==r&&tt()!==r&&(o=function(){var e,t=78*Ve+72,n=Je[t];if(n)return Ve=n.nextPos,n.result;(e=ht())===r&&(e=mt())===r&&(e=xt())===r&&(e=jt())===r&&(e=Mt())===r&&(e=It())===r&&(e=Ft())===r&&(e=Tt())===r&&(e=St())===r&&(e=Ct())===r&&(e=wt())===r&&(e=ot())===r&&(e=pt())===r&&(e=lt())===r&&(e=ut());return Je[t]={nextPos:Ve,result:e},e}())!==r&&tt()!==r?(41===e.charCodeAt(Ve)?(s=fe,Ve++):(s=r,Qe(me)),s!==r?(a=o,t=n={type:Yt.PARENTHESIS,value:a}):(Ve=t,t=r)):(Ve=t,t=r),Je[i]={nextPos:Ve,result:t},t)}function qt(){var t,n=78*Ve+73,o=Je[n];return o?(Ve=o.nextPos,o.result):((t=function(){var t,n,o,s=78*Ve+74,a=Je[s];if(a)return Ve=a.nextPos,a.result;t=Ve,e.substr(Ve,3)===De?(n=De,Ve+=3):(n=r,Qe(Oe));n!==r&&(o=Ut())!==r?(i=o,t=n={type:Yt.VARIADIC,value:i,meta:{syntax:Gt.PREFIX_DOTS}}):(Ve=t,t=r);var i;return Je[s]={nextPos:Ve,result:t},t}())===r&&(t=function(){var t,n,o,s=78*Ve+75,a=Je[s];if(a)return Ve=a.nextPos,a.result;t=Ve,(n=Ut())!==r?(e.substr(Ve,3)===De?(o=De,Ve+=3):(o=r,Qe(Oe)),o!==r?(i=n,t=n={type:Yt.VARIADIC,value:i,meta:{syntax:Gt.SUFFIX_DOTS}}):(Ve=t,t=r)):(Ve=t,t=r);var i;return Je[s]={nextPos:Ve,result:t},t}())===r&&(t=function(){var t,n,o=78*Ve+76,s=Je[o];if(s)return Ve=s.nextPos,s.result;t=Ve,e.substr(Ve,3)===De?(n=De,Ve+=3):(n=r,Qe(Oe));n!==r&&(n={type:Yt.VARIADIC,value:{type:Yt.ANY},meta:{syntax:Gt.ONLY_DOTS}});return t=n,Je[o]={nextPos:Ve,result:t},t}()),Je[n]={nextPos:Ve,result:t},t)}function Ut(){var e,t=78*Ve+77,n=Je[t];return n?(Ve=n.nextPos,n.result):((e=ht())===r&&(e=mt())===r&&(e=xt())===r&&(e=jt())===r&&(e=Mt())===r&&(e=It())===r&&(e=Ft())===r&&(e=$t())===r&&(e=St())===r&&(e=Ct())===r&&(e=Tt())===r&&(e=wt())===r&&(e=ot())===r&&(e=pt())===r&&(e=lt())===r&&(e=ut()),Je[t]={nextPos:Ve,result:e},e)}const Vt=py,{GenericTypeSyntax:Wt,VariadicTypeSyntax:Gt,OptionalTypeSyntax:zt,NullableTypeSyntax:Jt,NotNullableTypeSyntax:Kt}=Vt,Yt=dy,Ht={MEMBER:"MEMBER",INNER_MEMBER:"INNER_MEMBER",INSTANCE_MEMBER:"INSTANCE_MEMBER"};if((n=s())!==r&&Ve===e.length)return n;throw n!==r&&Vee.name,MEMBER:(e,t)=>jy("%s.%s%s",t(e.owner),e.hasEventPrefix?"event:":"",Ly(e.name,e.quoteStyle)),UNION:(e,t)=>jy("%s | %s",t(e.left),t(e.right)),INTERSECTION:(e,t)=>jy("%s & %s",t(e.left),t(e.right)),VARIADIC:(e,t)=>e.meta.syntax===Ny.ONLY_DOTS?"...":jy("...%s",t(e.value)),RECORD(e,t){const n=e.entries.map(t);return jy("{%s}",n.join(", "))},RECORD_ENTRY(e,t){const{readonly:n,value:r,key:o,quoteStyle:s}=e,a=n?"readonly ":"";if(!r)return a+Ly(o,s);const i=r.type===Dy&&r.meta.syntax===By.SUFFIX_KEY_QUESTION_MARK?"?":"";return jy("%s%s%s: %s",a,Ly(o,s),i,t(r))},TUPLE(e,t){const n=e.entries.map(t);return jy("[%s]",n.join(", "))},GENERIC(e,t){const n=e.objects.map(t);switch(e.meta.syntax){case"SQUARE_BRACKET":return jy("%s[]",n.join(", "));case"ANGLE_BRACKET_WITH_DOT":return jy("%s.<%s>",t(e.subject),n.join(", "))}return jy("%s<%s>",t(e.subject),n.join(", "))},MODULE:(e,t)=>jy("module:%s",t(e.value)),FILE_PATH:e=>Ly(e.path,e.quoteStyle),OPTIONAL:(e,t)=>e.meta.syntax===By.SUFFIX_KEY_QUESTION_MARK?t(e.value):jy("%s=",t(e.value)),NULLABLE:(e,t)=>jy("?%s",t(e.value)),NOT_NULLABLE:(e,t)=>jy("!%s",t(e.value)),FUNCTION(e,t){const n=e.params.map(t);return e.new&&n.unshift(jy("new: %s",t(e.new))),e.this&&n.unshift(jy("this: %s",t(e.this))),e.returns?jy("function(%s): %s",n.join(", "),t(e.returns)):jy("function(%s)",n.join(", "))},ARROW(e,t){const n=e.params.map(t);return(e.new?"new ":"")+jy("(%s) => %s",n.join(", "),t(e.returns))},NAMED_PARAMETER:(e,t)=>e.name+": "+t(e.typeName),ANY:()=>"*",UNKNOWN:()=>"?",INNER_MEMBER:(e,t)=>t(e.owner)+"~"+(e.hasEventPrefix?"event:":"")+Ly(e.name,e.quoteStyle),INSTANCE_MEMBER:(e,t)=>t(e.owner)+"#"+(e.hasEventPrefix?"event:":"")+Ly(e.name,e.quoteStyle),STRING_VALUE:e=>Ly(e.string,e.quoteStyle),NUMBER_VALUE:e=>e.number,EXTERNAL(e){const{name:t,quoteStyle:n}=e;return jy("external:%s",Ly(t,n))},PARENTHESIS:(e,t)=>jy("(%s)",t(e.value)),TYPE_QUERY:(e,t)=>jy("typeof %s",t(e.name)),KEY_QUERY:(e,t)=>e.value.type===Oy?jy("keyof%s",t(e.value)):jy("keyof %s",t(e.value)),IMPORT:(e,t)=>jy("import(%s)",t(e.path))}}var My={publish:function e(t,n){const r=n||Ry();return r[t.type](t,(function(t){return e(t,r)}))},createDefaultPublisher:Ry};const _y={NODE(e,t,n,r){e(t,n,r)},NODE_LIST(e,t,n,r){t.forEach((function(t){e(t,n,r)}))},NULLABLE_NODE(e,t,n,r){t&&e(t,n,r)}},$y={NAME:{},NAMED_PARAMETER:{typeName:_y.NULLABLE_NODE},MEMBER:{owner:_y.NODE},UNION:{left:_y.NODE,right:_y.NODE},INTERSECTION:{left:_y.NODE,right:_y.NODE},VARIADIC:{value:_y.NODE},RECORD:{entries:_y.NODE_LIST},RECORD_ENTRY:{value:_y.NULLABLE_NODE},TUPLE:{entries:_y.NODE_LIST},GENERIC:{subject:_y.NODE,objects:_y.NODE_LIST},MODULE:{value:_y.NODE},OPTIONAL:{value:_y.NODE},NULLABLE:{value:_y.NODE},NOT_NULLABLE:{value:_y.NODE},FUNCTION:{params:_y.NODE_LIST,returns:_y.NULLABLE_NODE,this:_y.NULLABLE_NODE,new:_y.NULLABLE_NODE},ARROW:{params:_y.NODE_LIST,returns:_y.NULLABLE_NODE},ANY:{},UNKNOWN:{},INNER_MEMBER:{owner:_y.NODE},INSTANCE_MEMBER:{owner:_y.NODE},STRING_VALUE:{},NUMBER_VALUE:{},EXTERNAL:{},FILE_PATH:{},PARENTHESIS:{value:_y.NODE},TYPE_QUERY:{name:_y.NODE},KEY_QUERY:{value:_y.NODE},IMPORT:{path:_y.NODE}};var qy={traverse:function e(t,n,r){n&&n(t,null,null),function(e){const t=[],n=$y[e.type];return Object.keys(n).forEach((function(r){(0,n[r])(((e,n,r)=>{t.push([e,n,r])}),e[r],r,e)})),t}(t).forEach((function([t,o,s]){e(t,n?(e,t,r)=>{n(e,t||o,r||s)}:null,r?(e,t,n)=>{r(e,t||o,n||s)}:null)})),r&&r(t,null,null)}};const{parse:Uy,JSDocTypeSyntaxError:Vy,JSDocSyntaxError:Wy,ClosureSyntaxError:Gy,TypeScriptSyntaxError:zy}=Fy,{publish:Jy,createDefaultPublisher:Ky}=My,{traverse:Yy}=qy;var Hy=Uy,Xy=Jy,Qy=Yy,Zy=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n,r=(n=Ze)&&n.__esModule?n:{default:n};const o=["undefined","null","boolean","number","bigint","string","symbol","object","Array","Function","Date","RegExp"];var s=(0,r.default)((({jsdocNode:e,sourceCode:t,report:n,utils:r,settings:s,context:a})=>{const i=r.filterTags((e=>r.tagMightHaveTypePosition(e.tag))),{preferredTypes:c,structuredTags:l,mode:u}=s,{noDefaults:p,unifyParentAndChildTypeChecks:d,exemptTagContexts:f=[]}=a.options[0]||{};i.forEach((s=>{const a=[];let i;try{i=Hy(s.type,{mode:u})}catch{return}const m=s.tag;if(Qy(i,((e,t,n)=>{const{type:s,name:i}=e;if(!["NAME","ANY"].includes(s))return;let f="ANY"===s?"*":i;const[g,h,y]=((e,t,n,r)=>{let o,s,a=t;if(Object.keys(c).length){const e="subject"===n;if(d||e){var i;const n=null==r||null===(i=r.meta)||void 0===i?void 0:i.syntax;[[".","ANGLE_BRACKET_WITH_DOT"],[".<>","ANGLE_BRACKET_WITH_DOT"],["<>","ANGLE_BRACKET"]].some((([e,r])=>(s=void 0!==(null==c?void 0:c[t+e])&&n===r,s&&(a+=e),s))),!s&&e&&[["[]","SQUARE_BRACKET"],[".","ANGLE_BRACKET_WITH_DOT"],[".<>","ANGLE_BRACKET_WITH_DOT"],["<>","ANGLE_BRACKET"]].some((([e,t])=>(s=void 0!==(null==c?void 0:c[e])&&n===t,s&&(a=e),s)))}const l=void 0!==(null==c?void 0:c[t])&&!Object.values(c).includes(t),u=e&&l&&d;s=s||u,o=s||l&&!e}return[o,a,s]})(0,f,t,n);let x,b;if(g){const e=c[h];if(f="[]"===h?h:f,e)if("string"==typeof e)x=e,a.push([f,x]);else{if("object"!=typeof e)return void r.reportSettings("Invalid `settings.jsdoc.preferredTypes`. Values must be falsy, a string, or an object.");x=null==e?void 0:e.replacement,a.push([f,x,null==e?void 0:e.message])}else a.push([f])}else if(Object.entries(l).some((([e,{type:t}])=>(b=t,e===m&&Array.isArray(b)&&!b.includes(f)))))a.push([f,b]);else if(!p&&"NAME"===s)for(const e of o)if(!("object"===e&&"typescript"===u||e.toLowerCase()!==f.toLowerCase()||e===f||c&&void 0!==(null==c?void 0:c[e]))){x=e,a.push([f,x]);break}x&&((e,t,n,r,o,s)=>{let a=t;if(n)if("[]"===t)"UNION"===s.objects[0].type&&(s.objects[0]={type:"PARENTHESIS",value:s.objects[0]}),s.meta.syntax="SQUARE_BRACKET",a="Array";else{const e=t.match(/\.(?:<>)?$/u);e?(s.meta.syntax="ANGLE_BRACKET_WITH_DOT",a=t.slice(0,-e[0].length)):t.endsWith("<>")?(s.meta.syntax="ANGLE_BRACKET",a=t.slice(0,-2)):"SQUARE_BRACKET"!==s.meta.syntax||"[]"!==r&&"Array"!==r||(s.meta.syntax="ANGLE_BRACKET")}else"ANY"===e&&(o.type="NAME");o.name=a.replace(/(?:\.|<>|\.<>|\[\])$/u,""),a||(o.name=r)})(s,x,y,f,e,n)})),a.length){const r=Xy(i);a.forEach((([o,a="",i])=>{const c=s.name?` "${s.name}"`:"";f.some((({tag:e,types:t})=>e===m&&(!0===t||t.includes(s.type))))||n(i||`Invalid JSDoc @${m}${c} type "${o}"`+(a?"; ":".")+(a?`prefer: ${JSON.stringify(a)}.`:""),a?n=>n.replaceText(e,t.getText(e).replace(`{${s.type}}`,`{${r}}`)):null,s,i?{tagName:m,tagValue:c}:null)}))}}))}),{iterateAllJsdocs:!0,meta:{docs:{description:"Reports invalid types.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-types"},fixable:"code",schema:[{additionalProperties:!1,properties:{exemptTagContexts:{items:{additionalProperties:!1,properties:{tag:{type:"string"},types:{oneOf:[{type:"boolean"},{items:{type:"string"},type:"array"}]}},type:"object"},type:"array"},noDefaults:{type:"boolean"},unifyParentAndChildTypeChecks:{type:"boolean"}},type:"object"}],type:"suggestion"}});t.default=s,e.exports=t.default})),ex=["389-exception","Autoconf-exception-2.0","Autoconf-exception-3.0","Bison-exception-2.2","Bootloader-exception","Classpath-exception-2.0","CLISP-exception-2.0","DigiRule-FOSS-exception","eCos-exception-2.0","Fawkes-Runtime-exception","FLTK-exception","Font-exception-2.0","freertos-exception-2.0","GCC-exception-2.0","GCC-exception-3.1","gnu-javamail-exception","GPL-3.0-linking-exception","GPL-3.0-linking-source-exception","GPL-CC-1.0","i2p-gpl-java-exception","Libtool-exception","Linux-syscall-note","LLVM-exception","LZMA-exception","mif-exception","Nokia-Qt-exception-1.1","OCaml-LGPL-linking-exception","OCCT-exception-1.0","OpenJDK-assembly-exception-1.0","openvpn-openssl-exception","PS-or-PDF-font-exception-20170817","Qt-GPL-exception-1.0","Qt-LGPL-exception-1.1","Qwt-exception-1.0","Swift-exception","u-boot-exception-2.0","Universal-FOSS-exception-1.0","WxWindows-exception-3.1"],tx=[].concat(["0BSD","AAL","ADSL","AFL-1.1","AFL-1.2","AFL-2.0","AFL-2.1","AFL-3.0","AGPL-1.0-only","AGPL-1.0-or-later","AGPL-3.0-only","AGPL-3.0-or-later","AMDPLPA","AML","AMPAS","ANTLR-PD","ANTLR-PD-fallback","APAFML","APL-1.0","APSL-1.0","APSL-1.1","APSL-1.2","APSL-2.0","Abstyles","Adobe-2006","Adobe-Glyph","Afmparse","Aladdin","Apache-1.0","Apache-1.1","Apache-2.0","Artistic-1.0","Artistic-1.0-Perl","Artistic-1.0-cl8","Artistic-2.0","BSD-1-Clause","BSD-2-Clause","BSD-2-Clause-Patent","BSD-2-Clause-Views","BSD-3-Clause","BSD-3-Clause-Attribution","BSD-3-Clause-Clear","BSD-3-Clause-LBNL","BSD-3-Clause-No-Nuclear-License","BSD-3-Clause-No-Nuclear-License-2014","BSD-3-Clause-No-Nuclear-Warranty","BSD-3-Clause-Open-MPI","BSD-4-Clause","BSD-4-Clause-UC","BSD-Protection","BSD-Source-Code","BSL-1.0","BUSL-1.1","Bahyph","Barr","Beerware","BitTorrent-1.0","BitTorrent-1.1","BlueOak-1.0.0","Borceux","CAL-1.0","CAL-1.0-Combined-Work-Exception","CATOSL-1.1","CC-BY-1.0","CC-BY-2.0","CC-BY-2.5","CC-BY-3.0","CC-BY-3.0-AT","CC-BY-3.0-US","CC-BY-4.0","CC-BY-NC-1.0","CC-BY-NC-2.0","CC-BY-NC-2.5","CC-BY-NC-3.0","CC-BY-NC-4.0","CC-BY-NC-ND-1.0","CC-BY-NC-ND-2.0","CC-BY-NC-ND-2.5","CC-BY-NC-ND-3.0","CC-BY-NC-ND-3.0-IGO","CC-BY-NC-ND-4.0","CC-BY-NC-SA-1.0","CC-BY-NC-SA-2.0","CC-BY-NC-SA-2.5","CC-BY-NC-SA-3.0","CC-BY-NC-SA-4.0","CC-BY-ND-1.0","CC-BY-ND-2.0","CC-BY-ND-2.5","CC-BY-ND-3.0","CC-BY-ND-4.0","CC-BY-SA-1.0","CC-BY-SA-2.0","CC-BY-SA-2.0-UK","CC-BY-SA-2.5","CC-BY-SA-3.0","CC-BY-SA-3.0-AT","CC-BY-SA-4.0","CC-PDDC","CC0-1.0","CDDL-1.0","CDDL-1.1","CDLA-Permissive-1.0","CDLA-Sharing-1.0","CECILL-1.0","CECILL-1.1","CECILL-2.0","CECILL-2.1","CECILL-B","CECILL-C","CERN-OHL-1.1","CERN-OHL-1.2","CERN-OHL-P-2.0","CERN-OHL-S-2.0","CERN-OHL-W-2.0","CNRI-Jython","CNRI-Python","CNRI-Python-GPL-Compatible","CPAL-1.0","CPL-1.0","CPOL-1.02","CUA-OPL-1.0","Caldera","ClArtistic","Condor-1.1","Crossword","CrystalStacker","Cube","D-FSL-1.0","DOC","DSDP","Dotseqn","ECL-1.0","ECL-2.0","EFL-1.0","EFL-2.0","EPICS","EPL-1.0","EPL-2.0","EUDatagrid","EUPL-1.0","EUPL-1.1","EUPL-1.2","Entessa","ErlPL-1.1","Eurosym","FSFAP","FSFUL","FSFULLR","FTL","Fair","Frameworx-1.0","FreeImage","GFDL-1.1-invariants-only","GFDL-1.1-invariants-or-later","GFDL-1.1-no-invariants-only","GFDL-1.1-no-invariants-or-later","GFDL-1.1-only","GFDL-1.1-or-later","GFDL-1.2-invariants-only","GFDL-1.2-invariants-or-later","GFDL-1.2-no-invariants-only","GFDL-1.2-no-invariants-or-later","GFDL-1.2-only","GFDL-1.2-or-later","GFDL-1.3-invariants-only","GFDL-1.3-invariants-or-later","GFDL-1.3-no-invariants-only","GFDL-1.3-no-invariants-or-later","GFDL-1.3-only","GFDL-1.3-or-later","GL2PS","GLWTPL","GPL-1.0-only","GPL-1.0-or-later","GPL-2.0-only","GPL-2.0-or-later","GPL-3.0-only","GPL-3.0-or-later","Giftware","Glide","Glulxe","HPND","HPND-sell-variant","HTMLTIDY","HaskellReport","Hippocratic-2.1","IBM-pibs","ICU","IJG","IPA","IPL-1.0","ISC","ImageMagick","Imlib2","Info-ZIP","Intel","Intel-ACPI","Interbase-1.0","JPNIC","JSON","JasPer-2.0","LAL-1.2","LAL-1.3","LGPL-2.0-only","LGPL-2.0-or-later","LGPL-2.1-only","LGPL-2.1-or-later","LGPL-3.0-only","LGPL-3.0-or-later","LGPLLR","LPL-1.0","LPL-1.02","LPPL-1.0","LPPL-1.1","LPPL-1.2","LPPL-1.3a","LPPL-1.3c","Latex2e","Leptonica","LiLiQ-P-1.1","LiLiQ-R-1.1","LiLiQ-Rplus-1.1","Libpng","Linux-OpenIB","MIT","MIT-0","MIT-CMU","MIT-advertising","MIT-enna","MIT-feh","MIT-open-group","MITNFA","MPL-1.0","MPL-1.1","MPL-2.0","MPL-2.0-no-copyleft-exception","MS-PL","MS-RL","MTLL","MakeIndex","MirOS","Motosoto","MulanPSL-1.0","MulanPSL-2.0","Multics","Mup","NASA-1.3","NBPL-1.0","NCGL-UK-2.0","NCSA","NGPL","NIST-PD","NIST-PD-fallback","NLOD-1.0","NLPL","NOSL","NPL-1.0","NPL-1.1","NPOSL-3.0","NRL","NTP","NTP-0","Naumen","Net-SNMP","NetCDF","Newsletr","Nokia","Noweb","O-UDA-1.0","OCCT-PL","OCLC-2.0","ODC-By-1.0","ODbL-1.0","OFL-1.0","OFL-1.0-RFN","OFL-1.0-no-RFN","OFL-1.1","OFL-1.1-RFN","OFL-1.1-no-RFN","OGC-1.0","OGL-Canada-2.0","OGL-UK-1.0","OGL-UK-2.0","OGL-UK-3.0","OGTSL","OLDAP-1.1","OLDAP-1.2","OLDAP-1.3","OLDAP-1.4","OLDAP-2.0","OLDAP-2.0.1","OLDAP-2.1","OLDAP-2.2","OLDAP-2.2.1","OLDAP-2.2.2","OLDAP-2.3","OLDAP-2.4","OLDAP-2.5","OLDAP-2.6","OLDAP-2.7","OLDAP-2.8","OML","OPL-1.0","OSET-PL-2.1","OSL-1.0","OSL-1.1","OSL-2.0","OSL-2.1","OSL-3.0","OpenSSL","PDDL-1.0","PHP-3.0","PHP-3.01","PSF-2.0","Parity-6.0.0","Parity-7.0.0","Plexus","PolyForm-Noncommercial-1.0.0","PolyForm-Small-Business-1.0.0","PostgreSQL","Python-2.0","QPL-1.0","Qhull","RHeCos-1.1","RPL-1.1","RPL-1.5","RPSL-1.0","RSA-MD","RSCPL","Rdisc","Ruby","SAX-PD","SCEA","SGI-B-1.0","SGI-B-1.1","SGI-B-2.0","SHL-0.5","SHL-0.51","SISSL","SISSL-1.2","SMLNJ","SMPPL","SNIA","SPL-1.0","SSH-OpenSSH","SSH-short","SSPL-1.0","SWL","Saxpath","Sendmail","Sendmail-8.23","SimPL-2.0","Sleepycat","Spencer-86","Spencer-94","Spencer-99","SugarCRM-1.1.3","TAPR-OHL-1.0","TCL","TCP-wrappers","TMate","TORQUE-1.1","TOSL","TU-Berlin-1.0","TU-Berlin-2.0","UCL-1.0","UPL-1.0","Unicode-DFS-2015","Unicode-DFS-2016","Unicode-TOU","Unlicense","VOSTROM","VSL-1.0","Vim","W3C","W3C-19980720","W3C-20150513","WTFPL","Watcom-1.0","Wsuipa","X11","XFree86-1.1","XSkat","Xerox","Xnet","YPL-1.0","YPL-1.1","ZPL-1.1","ZPL-2.0","ZPL-2.1","Zed","Zend-2.0","Zimbra-1.3","Zimbra-1.4","Zlib","blessing","bzip2-1.0.5","bzip2-1.0.6","copyleft-next-0.3.0","copyleft-next-0.3.1","curl","diffmark","dvipdfm","eGenix","etalab-2.0","gSOAP-1.3b","gnuplot","iMatix","libpng-2.0","libselinux-1.0","libtiff","mpich2","psfrag","psutils","xinetd","xpp","zlib-acknowledgement"]).concat(["AGPL-1.0","AGPL-3.0","BSD-2-Clause-FreeBSD","BSD-2-Clause-NetBSD","GFDL-1.1","GFDL-1.2","GFDL-1.3","GPL-1.0","GPL-2.0","GPL-2.0-with-GCC-exception","GPL-2.0-with-autoconf-exception","GPL-2.0-with-bison-exception","GPL-2.0-with-classpath-exception","GPL-2.0-with-font-exception","GPL-3.0","GPL-3.0-with-GCC-exception","GPL-3.0-with-autoconf-exception","LGPL-2.0","LGPL-2.1","LGPL-3.0","Nunit","StandardML-NJ","eCos-2.0","wxWindows"]),nx=function(e){var t=0;function n(){return t1&&" "===e[t-2])throw new Error("Space before `+`");return n&&{type:"OPERATOR",string:n}}()||function(){if(r("DocumentRef-"))return{type:"DOCUMENTREF",string:s()}}()||function(){if(r("LicenseRef-"))return{type:"LICENSEREF",string:s()}}()||(n=t,a=o(),-1!==tx.indexOf(a)?{type:"LICENSE",string:a}:-1!==ex.indexOf(a)?{type:"EXCEPTION",string:a}:void(t=n));var n,a}for(var i=[];n()&&(r(/[ ]*/),n());){var c=a();if(!c)throw new Error("Unexpected `"+e[t]+"` at offset "+t);i.push(c)}return i},rx=function(e){var t=0;function n(){return t{const s=o.options[0]||{},{allowedLicenses:a=null,allowedAuthors:i=null,licensePattern:c="/([^\n]*)/gu"}=s;e.forEachPreferredTag("version",((e,r)=>{const o=e.description.trim();o?n.default.valid(o)||t(`Invalid JSDoc @${r}: "${e.description}".`,null,e):t(`Missing JSDoc @${r}.`,null,e)})),e.forEachPreferredTag("since",((e,r)=>{const o=e.description.trim();o?n.default.valid(o)||t(`Invalid JSDoc @${r}: "${e.description}".`,null,e):t(`Missing JSDoc @${r}.`,null,e)})),e.forEachPreferredTag("license",((n,o)=>{const s=e.getRegexFromString(c,"g"),i=n.description.match(s),l=i&&i[1]||i[0];if(l.trim())if(a)!0===a||a.includes(l)||t(`Invalid JSDoc @${o}: "${l}"; expected one of ${a.join(", ")}.`,null,n);else try{(0,r.default)(l)}catch{t(`Invalid JSDoc @${o}: "${l}"; expected SPDX expression: https://spdx.org/licenses/.`,null,n)}else t(`Missing JSDoc @${o}.`,null,n)})),e.forEachPreferredTag("author",((e,n)=>{const r=e.description.trim();r?i&&!i.includes(r)&&t(`Invalid JSDoc @${n}: "${e.description}"; expected one of ${i.join(", ")}.`,null,e):t(`Missing JSDoc @${n}.`,null,e)}))}),{iterateAllJsdocs:!0,meta:{docs:{description:"This rule checks the values for a handful of tags: `@version`, `@since`, `@license` and `@author`.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-check-values"},schema:[{additionalProperties:!1,properties:{allowedAuthors:{items:{type:"string"},type:"array"},allowedLicenses:{anyOf:[{items:{type:"string"},type:"array"},{type:"boolean"}]},licensePattern:{type:"string"}},type:"object"}],type:"suggestion"}});t.default=s,e.exports=t.default})),ax=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n,r=(n=Ze)&&n.__esModule?n:{default:n};const o=new Set(["abstract","async","generator","global","hideconstructor","ignore","inner","instance","override","readonly","inheritDoc","internal"]),s=new Set(["package","private","protected","public","static","inheritdoc"]);var a=(0,r.default)((({settings:e,jsdoc:t,utils:n})=>{n.filterTags((({tag:r})=>o.has(r)||n.hasOptionTag(r)&&t.tags.some((({tag:e})=>e===r))||"closure"!==e.mode&&s.has(r))).forEach((e=>{if((e.name||e.description||e.type).trim()){const t=()=>{n.setTag(e)};n.reportJSDoc(`@${e.tag} should be empty.`,e,t,!0)}}))}),{checkInternal:!0,checkPrivate:!0,iterateAllJsdocs:!0,meta:{docs:{description:"Expects specific tags to be empty of any content.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-empty-tags"},fixable:"code",schema:[{additionalProperties:!1,properties:{tags:{items:{type:"string"},type:"array"}},type:"object"}],type:"suggestion"}});t.default=a,e.exports=t.default})),ix=ie((function(e,t){var n;Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=(0,((n=Ze)&&n.__esModule?n:{default:n}).default)((({report:e,utils:t})=>{if(t.isIteratingFunction()){if(t.hasATag(["class","constructor"])||t.isConstructor())return}else if(!t.isVirtualFunction())return;t.forEachPreferredTag("implements",(t=>{e("@implements used on a non-constructor function",null,t)}))}),{contextDefaults:!0,meta:{docs:{description:"Reports an issue with any non-constructor function using `@implements`.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-implements-on-classes"},schema:[{additionalProperties:!1,properties:{contexts:{items:{type:"string"},type:"array"}},type:"object"}],type:"suggestion"}});t.default=r,e.exports=t.default})),cx=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=o(F.default),r=o(Ze);function o(e){return e&&e.__esModule?e:{default:e}}var s=(0,r.default)((({jsdoc:e,report:t,context:r,utils:o})=>{const s=r.options[0]||{},a=(n,r)=>{if(!r&&!1===s.mainDescription)return;let a=s.mainDescription;if(r){const e=r.tag;a=s.tags[e]}var i,c;o.getRegexFromString((i=a,c=s.matchDescription,"string"==typeof i?i:c||"^[A-Z`\\d_][\\s\\S]*[.?!`]$")).test(n)||t("JSDoc description does not satisfy the regex pattern.",null,r||{line:e.source[0].number+1})};if(e.description){const{description:e}=o.getDescription();a(e.replace(/\s+$/,""))}if(!s.tags||!Object.keys(s.tags).length)return;const i=e=>Boolean(s.tags[e]);o.forEachPreferredTag("description",((e,t)=>{const n=(e.name+" "+e.description).trim();i(t)&&a(n,e)}),!0);const c=o.filterTags((({tag:e})=>i(e))),{tagsWithNames:l,tagsWithoutNames:u}=o.getTagsByType(c);l.some((e=>{const t=n.default.trimStart(e.description,"- ");return a(t,e)})),u.some((e=>{const t=(e.name+" "+e.description).trim();return a(t,e)}))}),{contextDefaults:!0,meta:{docs:{description:"Enforces a regular expression pattern on descriptions.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-match-description"},schema:[{additionalProperties:!1,properties:{contexts:{items:{type:"string"},type:"array"},mainDescription:{oneOf:[{format:"regex",type:"string"},{type:"boolean"}]},matchDescription:{format:"regex",type:"string"},tags:{patternProperties:{".*":{oneOf:[{format:"regex",type:"string"},{enum:[!0],type:"boolean"}]}},type:"object"}},type:"object"}],type:"suggestion"}});t.default=s,e.exports=t.default})),lx=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=r(F.default);function r(e){return e&&e.__esModule?e:{default:e}}var o=(0,r(Ze).default)((({jsdoc:e,report:t,context:r,jsdocNode:o,sourceCode:s,indent:a,utils:i})=>{let c;if(!e.description.trim()||!e.tags.length)return;c=!n.default.has(r.options,0)||"always"===r.options[0];const{description:l,lastDescriptionLine:u}=i.getDescription(),p=/\n\r?$/.test(l);if(c){if(!p){const e=s.getText(o).split("\n");t("There must be a newline after the description of the JSDoc block.",(t=>{const n=`${a} *`+(e[u].endsWith("\r")?"\r":"");return e.splice(u+1,0,n),t.replaceText(o,e.join("\n"))}),{line:u})}}else if(p){const e=s.getText(o).split("\n");t("There must be no newline after the description of the JSDoc block.",(t=>(e.splice(u,1),t.replaceText(o,e.join("\n")))),{line:u})}}),{iterateAllJsdocs:!0,meta:{docs:{description:"Enforces a consistent padding of the block description.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-newline-after-description"},fixable:"whitespace",schema:[{enum:["always","never"],type:"string"}],type:"layout"}});t.default=o,e.exports=t.default})),ux=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n,r=(n=Ze)&&n.__esModule?n:{default:n};const o=/^\/\*(?!\*)/;var s=(0,r.default)((({context:e,sourceCode:t,allComments:n,makeReport:r})=>{const[{ignore:s=["ts-check","ts-expect-error","ts-ignore","ts-nocheck"]}={}]=e.options,a=n.filter((e=>{const n=t.getText(e);if(!o.test(n))return!1;const[{tags:r={}}={}]=(0,Je.parse)(`${n.slice(0,2)}*${n.slice(2)}`);return r.length&&!r.some((({tag:e})=>s.includes(e)))}));a.length&&a.forEach((n=>{r(e,n)("Expected JSDoc-like comment to begin with two asterisks.",(e=>{const r=t.getText(n);return e.replaceText(n,r.replace("/*","/**"))}))}))}),{checkFile:!0,meta:{docs:{description:"This rule checks for multi-line-style comments which fail to meet the criteria of a jsdoc block.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-no-bad-blocks"},fixable:"code",schema:[{additionalProperties:!1,properties:{ignore:{items:{type:"string"},type:"array"}},type:"object"}],type:"layout"}});t.default=s,e.exports=t.default})),px=ie((function(e,t){var n;Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=(0,((n=Ze)&&n.__esModule?n:{default:n}).default)((({context:e,utils:t})=>{const{noOptionalParamNames:n}=e.options[0]||{};t.getPresentTags(["param","arg","argument"]).forEach((e=>{n&&e.optional?t.reportJSDoc(`Optional param names are not permitted on @${e.tag}.`,e,(()=>{t.changeTag(e,{name:e.name.replace(/([^=]*)(=.+)?/,"$1")})})):e.default&&t.reportJSDoc(`Defaults are not permitted on @${e.tag}.`,e,(()=>{t.changeTag(e,{name:e.name.replace(/([^=]*)(=.+)?/,"[$1]")})}))}));t.getPresentTags(["default","defaultvalue"]).forEach((e=>{e.description.trim()&&t.reportJSDoc(`Default values are not permitted on @${e.tag}.`,e,(()=>{t.changeTag(e,{description:"",postTag:""})}))}))}),{contextDefaults:!0,meta:{docs:{description:"This rule reports defaults being used on the relevant portion of `@param` or `@default`.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-no-defaults"},fixable:"code",schema:[{additionalProperties:!1,properties:{contexts:{items:{type:"string"},type:"array"},noOptionalParamNames:{type:"boolean"}},type:"object"}],type:"suggestion"}});t.default=r,e.exports=t.default})),dx=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n,r=(n=Ze)&&n.__esModule?n:{default:n};const o=({tokens:e})=>{e.postTag="",e.type=""};var s=(0,r.default)((({utils:e})=>{if(!e.isIteratingFunction()&&!e.isVirtualFunction())return;e.getPresentTags(["param","arg","argument","returns","return"]).forEach((t=>{t.type&&e.reportJSDoc(`Types are not permitted on @${t.tag}.`,t,(()=>{t.source.forEach(o)}))}))}),{contextDefaults:!0,meta:{docs:{description:"This rule reports types being used on `@param` or `@returns`.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-no-types"},fixable:"code",schema:[{additionalProperties:!1,properties:{contexts:{items:{type:"string"},type:"array"}},type:"object"}],type:"suggestion"}});t.default=s,e.exports=t.default})),fx=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=a(F.default),r=function(e){if(e&&e.__esModule)return e;if(null===e||"object"!=typeof e&&"function"!=typeof e)return{default:e};var t=s();if(t&&t.has(e))return t.get(e);var n={},r=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var o in e)if(Object.prototype.hasOwnProperty.call(e,o)){var a=r?Object.getOwnPropertyDescriptor(e,o):null;a&&(a.get||a.set)?Object.defineProperty(n,o,a):n[o]=e[o]}n.default=e,t&&t.set(e,n);return n}(Ze),o=a(Qe);function s(){if("function"!=typeof WeakMap)return null;var e=new WeakMap;return s=function(){return e},e}function a(e){return e&&e.__esModule?e:{default:e}}const i=["null","undefined","void","string","boolean","object","function","symbol","number","bigint","NaN","Infinity","any","*","this","true","false","Array","Object","RegExp","Date","Function"],c=e=>e&&e.replace(/(?:\.|<>|\.<>|\[\])$/u,"");var l=(0,r.default)((({context:e,node:t,report:s,settings:a,sourceCode:l,utils:u})=>{var p;const{scopeManager:d}=l,{globalScope:f}=d,{definedTypes:m=[]}=e.options[0]||{};let g=[];const{preferredTypes:h,structuredTags:y,mode:x}=a;Object.keys(h).length&&(g=Object.values(h).map((e=>"string"==typeof e?c(e):e?("object"!=typeof e&&u.reportSettings("Invalid `settings.jsdoc.preferredTypes`. Values must be falsy, a string, or an object."),c(e.replacement)):void 0)).filter((e=>e)));const b=(0,n.default)(e.getAllComments()).filter((e=>e.value.startsWith("*"))).map((e=>(0,r.parseComment)(e,""))).flatMap((e=>e.tags.filter((({tag:e})=>u.isNamepathDefiningTag(e))))).map((e=>e.name)).value(),E=[];let S=d.acquire(t);for(;S&&"Program"!==S.block.type;)E.push(S.block),S=S.upper;let C=E.length?(0,n.default)(E).flatMap((e=>{const t=(0,Ke.getJSDocComment)(l,e,a);if(!t)return[];const n=(0,r.parseComment)(t,"");return o.default.filterTags(n.tags,(e=>"template"===e.tag))})).value():u.getPresentTags("template");const v=u.getClassJsdoc();null!=v&&v.tags&&(C=C.concat(v.tags.filter((({tag:e})=>"template"===e))));const A=n.default.flatMap(C,(e=>u.parseClosureTemplateTag(e))),k="Program"===(null===(p=f.childScopes[0])||void 0===p?void 0:p.block.type),w=new Set(f.variables.map((({name:e})=>e)).concat(k?n.default.flatMap(f.childScopes,(({variables:e})=>e),[]).map((({name:e})=>e)):[]).concat(i).concat(b).concat(m).concat(g).concat("jsdoc"===a.mode?[]:A));u.filterTags((({tag:e})=>u.tagMightHaveTypePosition(e))).forEach((t=>{let n;try{n=Hy(t.type,{mode:x})}catch{return}Qy(n,(({type:n,name:r})=>{if("NAME"===n){var o;const n=null===(o=y[t.tag])||void 0===o?void 0:o.type;w.has(r)||Array.isArray(n)&&n.includes(r)?i.includes(r)||e.markVariableAsUsed(r):s(`The type '${r}' is undefined.`,null,t)}}))}))}),{iterateAllJsdocs:!0,meta:{docs:{description:"Checks that types in jsdoc comments are defined.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-no-undefined-types"},schema:[{additionalProperties:!1,properties:{definedTypes:{items:{type:"string"},type:"array"}},type:"object"}],type:"suggestion"}});t.default=l,e.exports=t.default})),mx=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=r(F.default);function r(e){return e&&e.__esModule?e:{default:e}}var o=(0,r(Ze).default)((({jsdoc:e,report:t,utils:r,context:o})=>{if(r.avoidDocs())return;const{descriptionStyle:s="body"}=o.options[0]||{};let a=r.getPreferredTagName({skipReportingBlockedTag:"tag"!==s,tagName:"description"});if(!a)return;const i="object"==typeof a&&a.blocked;i&&(a=a.tagName);const c=e=>n.default.compact(e.trim().split("\n")).length;if("tag"!==s){const{description:e}=r.getDescription();if(c(e||""))return;if("body"===s){const e=r.getPresentTags(["desc","description"]);if(e.length){const[{tag:n}]=e;t(`Remove the @${n} tag to leave a plain block description or add additional description text above the @${n} line.`)}else t("Missing JSDoc block description.");return}}const l=i?[]:n.default.filter(e.tags,{tag:a});l.length?l.forEach((e=>{c(`${e.name} ${e.description}`)||t(`Missing JSDoc @${a} description.`)})):t("any"===s?`Missing JSDoc block description or @${a} declaration.`:`Missing JSDoc @${a} declaration.`)}),{contextDefaults:!0,meta:{docs:{description:"Requires that all functions have a description.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-description"},schema:[{additionalProperties:!1,properties:{checkConstructors:{default:!0,type:"boolean"},checkGetters:{default:!0,type:"boolean"},checkSetters:{default:!0,type:"boolean"},contexts:{items:{type:"string"},type:"array"},descriptionStyle:{enum:["body","tag","any"],type:"string"},exemptedBy:{items:{type:"string"},type:"array"}},type:"object"}],type:"suggestion"}});t.default=o,e.exports=t.default})),gx=ie((function(e,t){!function(e){function t(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function n(e,t){for(var n=0;n2&&void 0!==arguments[2]?arguments[2]:e.lastIndex;return t=t||"",(e=new RegExp(e.source,(t.includes("g")||e.global?"g":"")+(t.includes("i")||e.ignoreCase?"i":"")+(t.includes("m")||e.multiline?"m":"")+(t.includes("u")||e.unicode?"u":"")+(t.includes("y")||e.sticky?"y":"")+(t.includes("s")||e.dotAll?"s":""))).lastIndex=n,e}e.RegExtras=function(){function e(n,r,o){t(this,e),this.regex=i("string"==typeof n?new RegExp(n):i(n),r||"",o)}return r(e,[{key:"forEach",value:function(e,t){for(var n,r,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,s=i(this.regex,"g"),a=0;null!==(n=s.exec(e));)r=n.splice(0,1),t.apply(o,n.concat(a++,r));return this}},{key:"some",value:function(e,t){for(var n,r,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,s=i(this.regex,"g"),a=0;null!==(n=s.exec(e));)if(r=n.splice(0,1),t.apply(o,n.concat(a++,r)))return!0;return!1}},{key:"every",value:function(e,t){for(var n,r,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,s=i(this.regex,"g"),a=0;null!==(n=s.exec(e));)if(r=n.splice(0,1),!t.apply(o,n.concat(a++,r)))return!1;return!0}},{key:"map",value:function(e,t){for(var n,r,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,s=[],a=i(this.regex,"g"),c=0;null!==(n=a.exec(e));)r=n.splice(0,1),s.push(t.apply(o,n.concat(c++,r)));return s}},{key:"filter",value:function(e,t){for(var n,r,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,s=0,a=[],c=i(this.regex,"g");null!==(n=c.exec(e));)r=n.splice(0,1),n=n.concat(s++,r),t.apply(o,n)&&a.push(r[0]);return a}},{key:"reduce",value:function(e,t,n){var r,o,s=arguments.length>3&&void 0!==arguments[3]?arguments[3]:null,a=0,c=i(this.regex,"g");for(n||null!==(r=c.exec(e))&&(o=r.splice(0,1),n=t.apply(s,[""].concat(r.concat(a++,o))));null!==(r=c.exec(e));)o=r.splice(0,1),n=t.apply(s,[n].concat(r.concat(a++,o)));return n}},{key:"reduceRight",value:function(e,t,n,r){var o,s,a,c=r,l=n,u=[],p=i(this.regex,"g");for(c=c||null;null!==(o=p.exec(e));)u.push(o);if(!(a=u.length)){if(arguments.length<3)throw new TypeError("reduce of empty matches array with no initial value");return l}return l||(o=u.splice(-1)[0],s=o.splice(0,1),l=t.apply(c,[""].concat(o.concat(a--,s)))),u.reduceRight((function(e,n){return s=n.splice(0,1),l=t.apply(c,[l].concat(n.concat(a--,s))),e}),u),l}},{key:"find",value:function(e,t){for(var n,r,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,s=0,a=i(this.regex,"g");null!==(n=a.exec(e));)if(r=n.splice(0,1),t.apply(o,n.concat(s++,r)))return r[0];return!1}},{key:"findIndex",value:function(e,t){for(var n,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,o=i(this.regex,"g"),s=0;null!==(n=o.exec(e));){var a=n.splice(0,1);if(t.apply(r,n.concat(s++,a)))return s-1}return-1}},{key:"findExec",value:function(e,t){for(var n,r=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,o=i(this.regex,"g"),s=0;null!==(n=o.exec(e));){var a=n.splice(0,1);if(t.apply(r,n.concat(s++,a)))return n}return!1}},{key:"filterExec",value:function(e,t){for(var n,r,o=arguments.length>2&&void 0!==arguments[2]?arguments[2]:null,s=0,a=[],c=i(this.regex,"g");null!==(n=c.exec(e));)r=n.splice(0,1),n.push(s++,r[0]),t.apply(o,n)&&a.push(n);return a}}]),e}();var c=e.RegExtras;e.RegExtras=function(){for(var e=arguments.length,t=new Array(e),n=0;ne[0]===e[0].toUpperCase(),i=e=>"|"===e.charAt(),c=e=>e.charAt(0).toUpperCase()+e.slice(1),l=(e,t,r,o,s,l,u)=>{if(!e)return!1;return e.split(/(?{const d=((e,t)=>{const n=e.replace(/\{[\s\S]*?\}\s*/gu,"").replace(t,""),r=(0,gx.RegExtras)(/([.?!])(?:\s+|$)/u).map(n,(e=>e));return n.split(/[.?!](?:\s+|$)/u).map(((e,t)=>/^\s*$/u.test(e)?e:`${e}${r[t]||""}`))})(e,o),f=t=>{let o=s.getText(r);if(!/[.:?!]$/u.test(e)){const t=e.split("\n").pop();o=o.replace(new RegExp(`${n.default.escapeRegExp(t)}$`,"mu"),`${t}.`)}for(const e of d.filter((e=>!/^\s*$/u.test(e)&&!a(e)&&!i(e)))){const t=e.split("\n")[0];if(l.tag){const e=new RegExp(`(@${n.default.escapeRegExp(l.tag)}.*)${n.default.escapeRegExp(t)}`,"u");o=o.replace(e,((e,n)=>n+c(t)))}else o=o.replace(new RegExp("((?:[.!?]|\\*|\\})\\s*)"+n.default.escapeRegExp(t),"u"),"$1"+c(t))}return t.replaceText(r,o)},m=(e,n,r)=>{"line"in r?r.line+=2*p:r.source[0].number+=2*p,r.column=0,t(e,n,r)};d.some((e=>!/^\s*$/u.test(e)&&!a(e)&&!i(e)))&&m("Sentence should start with an uppercase character.",f,l);const g=e.replace(o,"");return/[.!?|]\s*$/u.test(g)?!(!u||(e=>{let t;return!e.split("\n").some((e=>!(!1!==t||!/^[A-Z][a-z]/u.test(e))||(t=/[.:?!|]$/u.test(e),!1)))})(g))&&(m("A line of text is started with an uppercase character, but preceding line does not end the sentence.",null,l),!0):(m("Sentence must end with a period.",f,l),!0)}))};var u=(0,r.default)((({sourceCode:e,context:t,jsdoc:r,report:o,jsdocNode:a,utils:i})=>{const c=t.options[0]||{},{abbreviations:u=[],newlineBeforeCapsAssumesBadSentenceEnd:p=!1}=c,d=u.length?new RegExp("\\b"+u.map((e=>n.default.escapeRegExp(e.replace(/\.$/g,"")+"."))).join("|")+"(?:$|\\s)","gu"):"",{description:f}=i.getDescription();if(l(f,o,a,d,e,{line:r.source[0].number+1},p))return;i.forEachPreferredTag("description",(t=>{const n=`${t.name} ${t.description}`.trim();l(n,o,a,d,e,t,p)}),!0);const{tagsWithNames:m}=i.getTagsByType(r.tags),g=i.filterTags((({tag:e})=>s.has(e)||i.hasOptionTag(e)&&!m.some((({tag:t})=>t===e))));m.some((t=>{const r=n.default.trimStart(t.description,"- ").trimEnd();return l(r,o,a,d,e,t,p)})),g.some((t=>{const n=`${t.name} ${t.description}`.trim();return l(n,o,a,d,e,t,p)}))}),{iterateAllJsdocs:!0,meta:{docs:{description:"Requires that block description, explicit `@description`, and `@param`/`@returns` tag descriptions are written in complete sentences.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-description-complete-sentence"},fixable:"code",schema:[{additionalProperties:!1,properties:{abbreviations:{items:{type:"string"},type:"array"},newlineBeforeCapsAssumesBadSentenceEnd:{type:"boolean"},tags:{items:{type:"string"},type:"array"}},type:"object"}],type:"suggestion"}});t.default=u,e.exports=t.default})),yx=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=r(F.default);function r(e){return e&&e.__esModule?e:{default:e}}var o=(0,r(Ze).default)((({context:e,jsdoc:t,report:r,utils:o})=>{if(o.avoidDocs())return;const{exemptNoArguments:s=!1}=e.options[0]||{},a="example",i=n.default.filter(t.tags,{tag:a});if(i.length)i.forEach((e=>{n.default.compact(`${e.name} ${e.description}`.trim().split("\n")).length||r("Missing JSDoc @example description.")}));else{if(s&&o.isIteratingFunction()&&!o.hasParams())return;o.reportJSDoc("Missing JSDoc @example declaration.",null,(()=>{o.addTag(a)}))}}),{contextDefaults:!0,meta:{docs:{description:"Requires that all functions have examples.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-example"},fixable:"code",schema:[{additionalProperties:!1,properties:{checkConstructors:{default:!0,type:"boolean"},checkGetters:{default:!1,type:"boolean"},checkSetters:{default:!1,type:"boolean"},contexts:{items:{type:"string"},type:"array"},exemptedBy:{items:{type:"string"},type:"array"},exemptNoArguments:{default:!1,type:"boolean"}},type:"object"}],type:"suggestion"}});t.default=o,e.exports=t.default})),xx=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n,r=(n=Ze)&&n.__esModule?n:{default:n};const o={file:{initialCommentsOnly:!0,mustExist:!0,preventDuplicates:!0}},s=e=>{e.globalTags||(e.globalTags={},e.hasDuplicates={},e.hasTag={},e.hasNonCommentBeforeTag={})};var a=(0,r.default)((({jsdocNode:e,state:t,utils:n,context:r})=>{const{tags:a=o}=r.options[0]||{};s(t);for(const r of Object.keys(a)){const o=n.getPreferredTagName({tagName:r}),s=o&&n.hasTag(o);t.hasTag[r]=s||t.hasTag[r];const a=t.hasDuplicates[r];!1===a?t.hasDuplicates[r]=s:!a&&s&&(t.hasDuplicates[r]=!1,t.hasNonCommentBeforeTag[r]=t.hasNonComment&&t.hasNonComment{const[a,{tags:i}={}]=r.options,c=(t,r,o=a)=>{const i=!o||"always"===o;if(!t.description.trim())return;const c=/^\s*-/u.test(t.description);i?c||n(`There must be a hyphen before @${r} description.`,(n=>{const r=t.line,o=e.getText(s).split("\n"),a=t.description.split("\n")[0],i=o[r].lastIndexOf(a),c=o[r].slice(0,i)+"- "+a;o.splice(r,1,c);const l=o.join("\n");return n.replaceText(s,l)}),t):c&&n(`There must be no hyphen before @${r} description.`,(n=>{const[r]=/^\s*-\s*/u.exec(t.description),o=e.getText(s).replace(t.description,t.description.slice(r.length));return n.replaceText(s,o)}),t)};if(t.forEachPreferredTag("param",c),i){const e=Object.entries(i);e.forEach((([n,r])=>{if("*"!==n)t.forEachPreferredTag(n,((e,t)=>{c(e,t,r)}));else{const n=t.getPreferredTagName({tagName:"param"});o.tags.forEach((({tag:o})=>{o===n||e.some((([e])=>"*"!==e&&e===o))||t.forEachPreferredTag(o,((e,t)=>{c(e,t,r)}))}))}}))}}),{iterateAllJsdocs:!0,meta:{docs:{description:"Requires a hyphen before the `@param` description.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-hyphen-before-param-description"},fixable:"code",schema:[{enum:["always","never"],type:"string"},{additionalProperties:!1,properties:{tags:{anyOf:[{patternProperties:{".*":{enum:["always","never"],type:"string"}},type:"object"},{enum:["any"],type:"string"}]}},type:"object"}],type:"layout"}});t.default=r,e.exports=t.default})),Ex=ie((function(e,t){var n;Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;const r=(0,((n=M.default)&&n.__esModule?n:{default:n}).default)("requireExportJsdoc"),o=function(e){return e&&"literal"===e.type?e.value.value:null};let s=null;const a=function(e,t,n,i){const c=i||{};switch(e.type){case"Identifier":return function(e,t,n,r){if(r.simpleIdentifier){const t={props:{},type:"literal"};return t.value={value:e.name},t}const o=n||t;return o.props[e.name]?o.props[e.name]:t.props[e.name]?t.props[e.name]:null}(e,t,n,c);case"MemberExpression":{const s=a(e.object,t,n,c),i=a(e.property,t,n,{simpleIdentifier:!e.computed}),l=o(i);if(s&&l&&s.props[l]){return s.props[l]}return r(`MemberExpression: Missing property ${e.property.name}`),null}case"TSTypeAliasDeclaration":case"TSEnumDeclaration":case"TSInterfaceDeclaration":case"ClassDeclaration":case"ClassExpression":case"FunctionExpression":case"FunctionDeclaration":case"ArrowFunctionExpression":{const t={props:{}};return t.props.prototype={props:{}},t.props.prototype.type="object",t.type="object",t.value=e,t}case"AssignmentExpression":return s(e.left,t,e.right,n,c);case"ClassBody":{const t={props:{}};return e.body.forEach((e=>{t.props[e.key.name]={props:{}},t.props[e.key.name].type="object",t.props[e.key.name].value=e.value})),t.type="object",t.value=e,t}case"ObjectExpression":{const r={props:{},type:"object"};return e.properties.forEach((e=>{if(["SpreadElement","ExperimentalSpreadProperty"].includes(e.type))return;const o=a(e.value,t,n,c);o&&(r.props[e.key.name]=o)})),r}case"Literal":{const t={props:{},type:"literal"};return t.value=e,t}}return null},i=function(e,t,n,r,o){e.props[t]=n,o&&r.props.window&&r.props.window.special&&(r.props.window.props[t]=n)};s=function(e,t,n,c,l){const u=c||t;let p;switch(e.type){case"FunctionDeclaration":case"TSEnumDeclaration":case"TSInterfaceDeclaration":case"TSTypeAliasDeclaration":case"ClassDeclaration":if(e.id&&"Identifier"===e.id.type)return s(e.id,t,e,t);break;case"Identifier":if(!n)return i(u,e.name,{props:{}},t,l),u.props[e.name];{const o=a(n,t,u);if(o)return i(u,e.name,o,t,l),u.props[e.name];r("Identifier: Missing value symbol for %s",e.name)}break;case"MemberExpression":{p=a(e.object,t,u);const s=a(e.property,t,u,{simpleIdentifier:!e.computed}),c=o(s);if(p&&c)return i(p,c,a(n,t,u),t,l),p.props[c];r("MemberExpression: Missing symbol: %s",e.property.name);break}}return null};const c=function(e,t,n){switch(e.type){case"Program":e.body.forEach((e=>{c(e,t,n)}));break;case"ExpressionStatement":c(e.expression,t,n);break;case"VariableDeclaration":e.declarations.forEach((r=>{const o=s(r.id,t,null,t);n.initWindow&&"var"===e.kind&&t.props.window&&(t.props.window.props[r.id.name]=o)}));break;case"ExportNamedDeclaration":e.declaration&&c(e.declaration,t,n)}},l=function(e,t,n,r){const o=n||{};switch(e.type){case"Program":if(o.ancestorsOnly)return!1;e.body.forEach((e=>{l(e,t,o)}));break;case"ExpressionStatement":l(e.expression,t,o);break;case"AssignmentExpression":s(e.left,t,e.right);break;case"VariableDeclaration":e.declarations.forEach((n=>{const a=o.initWindow&&"var"===e.kind&&t.props.window,i=s(n.id,t,n.init,t,a);i&&r&&(i.exported=!0)}));break;case"FunctionDeclaration":"Identifier"===e.id.type&&s(e.id,t,e,t,!0);break;case"ExportDefaultDeclaration":{const n=s(e.declaration,t,e.declaration);n?n.exported=!0:e.id||(t.ANONYMOUS_DEFAULT=e.declaration);break}case"ExportNamedDeclaration":if(e.declaration)if("VariableDeclaration"===e.declaration.type)l(e.declaration,t,o,!0);else{const n=s(e.declaration,t,e.declaration);n&&(n.exported=!0)}e.specifiers.forEach((e=>{l(e,t,o)}));break;case"ExportSpecifier":{const n=a(e.local,t,t);n&&(n.exported=!0);break}case"ClassDeclaration":s(e.id,t,e.body,t);break;default:return!1}return!0},u=function(e,t,n){let r=n||[];if(!t||r.includes(t))return!1;if(r=r.slice(),r.push(t),("object"===t.type||"MethodDefinition"===t.type)&&t.value===e)return!0;const{props:o=t.body}=t;for(const t of Object.values(o||{}))if(Array.isArray(t)){if(t.some((t=>u(e,t,r))))return!0}else if(u(e,t,r))return!0;return!1},p=new Set(["ExportNamedDeclaration","ExportDefaultDeclaration"]),d=new Set(["TSPropertySignature","TSMethodSignature","ClassProperty","Method"]),f=new Set(["TSInterfaceBody","TSInterfaceDeclaration","ClassDefinition","ClassExpression","Program"]),m=function(e,t,n){return!!(n.initModuleExports&&t.props.module&&t.props.module.props.exports&&u(e,t.props.module.props.exports))||(!!(n.initWindow&&t.props.window&&u(e,t.props.window))||!(!n.esm||!function(e,t,n){if(null===e)return!1;const r=n||[],{props:o}=e;for(const e of Object.values(o))if(r.push(e),e.exported&&(t===e.value||u(t,e.value)))return!0;return!1}(t,e)))},g=function(e,t,n){return!(!e.parent||!g(e.parent,t,n))||l(e,t,n)},h=function(e,t,n){const r=n||{ancestorsOnly:!1,esm:!0,initModuleExports:!0,initWindow:!0},o={props:{}};return r.initModuleExports&&(o.props.module={props:{}},o.props.module.props.exports={props:{}},o.props.exports=o.props.module.props.exports),r.initWindow&&(o.props.window={props:{}},o.props.window.special=!0),r.ancestorsOnly?g(t,o,r):(c(e,o,r),l(e,o,r)),{globalVars:o}};var y={isUncommentedExport:function(e,t,n,r){if(n.esm){const n=function(e){let t=e;for(;t;){if(p.has(t.type))return t;t=t.parent}return!1}(e);if(n&&!(0,Ke.findJSDocComment)(n,t,r))return!0;if(function(e){if(!d.has(e.type))return!1;let t=e.parent;for(;t;){if(p.has(t.type))return t;if(!f.has(t.type))return!1;t=t.parent}return!1}(e)&&!(0,Ke.findJSDocComment)(e,t,r))return!0}const o=h(t.ast,e,n);return m(e,o.globalVars,n)},parse:h};t.default=y,e.exports=t.default})),Sx=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=s(F.default),r=s(Ex),o=s(Qe);function s(e){return e&&e.__esModule?e:{default:e}}const a={additionalProperties:!1,properties:{checkConstructors:{default:!0,type:"boolean"},checkGetters:{anyOf:[{type:"boolean"},{enum:["no-setter"],type:"string"}],default:!0},checkSetters:{anyOf:[{type:"boolean"},{enum:["no-getter"],type:"string"}],default:!0},contexts:{items:{anyOf:[{type:"string"},{additionalProperties:!1,properties:{context:{type:"string"},inlineCommentBlock:{type:"boolean"}},type:"object"}]},type:"array"},enableFixer:{default:!0,type:"boolean"},exemptEmptyConstructors:{default:!1,type:"boolean"},exemptEmptyFunctions:{default:!1,type:"boolean"},publicOnly:{oneOf:[{default:!1,type:"boolean"},{additionalProperties:!1,default:{},properties:{ancestorsOnly:{type:"boolean"},cjs:{type:"boolean"},esm:{type:"boolean"},window:{type:"boolean"}},type:"object"}]},require:{additionalProperties:!1,default:{},properties:{ArrowFunctionExpression:{default:!1,type:"boolean"},ClassDeclaration:{default:!1,type:"boolean"},ClassExpression:{default:!1,type:"boolean"},FunctionDeclaration:{default:!0,type:"boolean"},FunctionExpression:{default:!1,type:"boolean"},MethodDefinition:{default:!1,type:"boolean"}},type:"object"}},type:"object"},i=(e,t,r,o)=>n.default.has(e,`options[0][${r}][${o}]`)?e.options[0][r][o]:t.properties[o].default;var c={create(e){const t=e.getSourceCode(),n=(0,Ze.getSettings)(e);if(!n)return{};const{require:s,contexts:c,publicOnly:l,exemptEmptyFunctions:u,exemptEmptyConstructors:p,enableFixer:d}=(e=>{const{publicOnly:t,contexts:n=[],exemptEmptyConstructors:r=!0,exemptEmptyFunctions:o=!1,enableFixer:s=!0}=e.options[0]||{};return{contexts:n,enableFixer:s,exemptEmptyConstructors:r,exemptEmptyFunctions:o,publicOnly:(n=>{if(!t)return!1;const r={};return Object.keys(n.properties).forEach((t=>{const o=i(e,n,"publicOnly",t);r[t]=o})),r})(a.properties.publicOnly.oneOf[1]),require:(t=>{const n={};return Object.keys(t.properties).forEach((r=>{const o=i(e,t,"require",r);n[r]=o})),n})(a.properties.require)}})(e),f=(s,i)=>{if((0,Ke.getJSDocComment)(t,s,n))return;if(o.default.exemptSpeciaMethods({tags:[]},s,e,[a]))return;if(u&&i||p&&o.default.isConstructor(s)){if(!o.default.getFunctionParameterNames(s).length&&!o.default.hasReturnValue(s,e))return}const f=e=>{const r=0===n.minLines&&n.maxLines>=1?1:n.minLines;let a=(0,Ke.getReducedASTNode)(s,t);const i=(0,Ke.getDecorator)(a);i&&(a=i);const l=o.default.getIndent({text:t.getText(a,a.loc.start.column)}),{inlineCommentBlock:u}=c.find((({context:e})=>e===s.type))||{},p=(u?"/** ":`/**\n${l}*\n${l}`)+`*/${"\n".repeat(r)}${l.slice(0,-1)}`;return e.insertTextBefore(a,p)},m=()=>{const t={end:s.loc.start+1,start:s.loc.start};e.report({fix:d?f:null,loc:t,messageId:"missingJsDoc",node:s})};if(l){var g,h,y,x;const e={ancestorsOnly:Boolean(null!==(g=null==l?void 0:l.ancestorsOnly)&&void 0!==g&&g),esm:Boolean(null===(h=null==l?void 0:l.esm)||void 0===h||h),initModuleExports:Boolean(null===(y=null==l?void 0:l.cjs)||void 0===y||y),initWindow:Boolean(null!==(x=null==l?void 0:l.window)&&void 0!==x&&x)};r.default.isUncommentedExport(s,t,e,n)&&m()}else m()},m=e=>s[e]||c.some((t=>"object"==typeof t?t.context===e:t===e));return{...o.default.getContextObject(o.default.enforcedContexts(e,[]),f),ArrowFunctionExpression(e){m("ArrowFunctionExpression")&&(["VariableDeclarator","AssignmentExpression","ExportDefaultDeclaration"].includes(e.parent.type)||["Property","ObjectProperty","ClassProperty"].includes(e.parent.type)&&e===e.parent.value)&&f(e,!0)},ClassDeclaration(e){m("ClassDeclaration")&&f(e)},ClassExpression(e){m("ClassExpression")&&f(e)},FunctionDeclaration(e){m("FunctionDeclaration")&&f(e,!0)},FunctionExpression(e){(m("MethodDefinition")&&"MethodDefinition"===e.parent.type||m("FunctionExpression")&&(["VariableDeclarator","AssignmentExpression","ExportDefaultDeclaration"].includes(e.parent.type)||["Property","ObjectProperty","ClassProperty"].includes(e.parent.type)&&e===e.parent.value))&&f(e,!0)}}},meta:{docs:{category:"Stylistic Issues",description:"Require JSDoc comments",recommended:"true",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-jsdoc"},fixable:"code",messages:{missingJsDoc:"Missing JSDoc comment."},schema:[a],type:"suggestion"}};t.default=c,e.exports=t.default})),Cx=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=o(F.default),r=o(Ze);function o(e){return e&&e.__esModule?e:{default:e}}const s=(e,t)=>{let n,r=t;const o=e.length<=1;if(o){n=`${e[0]}${r++}`}else n=e.shift();return[n,o,()=>s(e,r)]};var a=(0,r.default)((({jsdoc:e,utils:t,context:r})=>{const o=t.getPreferredTagName({tagName:"param"});if(!o)return;const a=t.getJsdocTagsDeep(o),i=a.filter((e=>!e.name.includes("."))).map(((e,t)=>({...e,idx:t})));if(t.avoidDocs())return;if(t.hasTag("type"))return;const{autoIncrementBase:c=0,checkRestProperty:l=!1,checkDestructured:u=!0,checkDestructuredRoots:p=!0,checkTypesPattern:d="/^(?:[oO]bject|[aA]rray|PlainObject|Generic(?:Object|Array))$/",enableFixer:f=!0,enableRootFixer:m=!0,enableRestElementFixer:g=!0,unnamedRootBase:h=["root"],useDefaultObjectProperties:y=!1}=r.options[0]||{},x=t.getRegexFromString(d),b=[],E=t.getFunctionParameterNames(y),S=t.flattenRoots(E).names,C={},v=e=>C[t.dropPathSegmentQuotes(String(e))];S.forEach(((e,n)=>{((e,n)=>{C[t.dropPathSegmentQuotes(String(e))]=n})(e,n)}));let[A,k,w]=s([...h],c);E.forEach(((e,r)=>{let o,s,c;if(Array.isArray(e)){const s=i[r]||a[r];let c;if(e[0])c=e[0];else if(s&&s.name){if(c=s.name,s.type&&-1===s.type.search(x))return}else c=A,o=k,[A,k,w]=w();const{hasRestElement:d,hasPropertyRest:f,rests:m,names:h}=e[1],y=[];if(!g&&d)return;if(!p)return;h.forEach(((r,s)=>{if(!a.find((({name:e})=>e===c))&&!b.find((({functionParameterName:e})=>e===c))){const e=a.findIndex((({name:e})=>!e));e>-1?b.push({functionParameterIdx:e,functionParameterName:c,inc:o,remove:!0}):b.push({functionParameterIdx:(i=c,n.default.has(C,t.dropPathSegmentQuotes(String(i)))?v(c):v(r)),functionParameterName:c,inc:o})}var i;if(!u)return;if(!l&&m[s])return;const p=`${c}.${r}`,g=a.find((({name:e,type:n})=>t.comparePaths(e)(p)&&-1===n.search(x)&&""!==n));void 0!==g&&y.push(g.name),y.find((e=>p.startsWith(e)))||a&&!a.find((({name:e})=>t.comparePaths(e)(p)))&&b.push({functionParameterIdx:v(e[0]?p:r),functionParameterName:p,inc:o,type:d&&!f?"{...any}":void 0})}))}else{if("object"==typeof e){if(!g&&e.restElement)return;s=e.name,c="{...any}"}else s=e;a&&!a.find((({name:e})=>e===s))&&b.push({functionParameterIdx:v(s),functionParameterName:s,inc:o,type:c})}}));const P=({functionParameterIdx:t,functionParameterName:n,remove:r,inc:s,type:a})=>{if(s&&!m)return;const i=(t,r,s)=>{const i={number:r+1,tokens:{delimiter:"*",description:"",end:"",name:n,newAdd:!0,postDelimiter:" ",postName:"",postTag:" ",postType:a?" ":"",start:e.source[r].tokens.start,tag:`@${o}`,type:null!=a?a:""}};e.tags.splice(t,s,{name:n,newAdd:!0,source:[i],tag:o,type:null!=a?a:""});const c=e.source[0].number;e.source.splice(r,s,i),e.source.slice(r).forEach(((e,t)=>{e.number=c+r+t}))},c=e.source.findIndex((({tokens:{tag:e,end:t}})=>e||t));if(r)i(t,c+t,1);else{const n=((e,t)=>{const n=E.slice(t||0),r=e.findIndex((({name:e,newAdd:t})=>!t&&n.some((t=>Array.isArray(t)?t[1].names.includes(e):"object"==typeof t?e===t.name:e===t)))),s=r>-1?e.slice(0,r):e.filter((({tag:e})=>e===o));let a=0;return s.forEach((({source:e})=>{e.forEach((({tokens:{end:e}})=>{e||a++}))})),a})(e.tags,t);i(n,c+n,0)}},T=()=>{b.forEach((e=>{P(e)}))};b.forEach((({functionParameterName:e})=>{t.reportJSDoc(`Missing JSDoc @${o} "${e}" declaration.`,null,f?T:null)}))}),{contextDefaults:!0,meta:{docs:{description:"Requires that all function parameters are documented.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-param"},fixable:"code",schema:[{additionalProperties:!1,properties:{autoIncrementBase:{default:0,type:"integer"},checkConstructors:{default:!0,type:"boolean"},checkDestructured:{default:!0,type:"boolean"},checkDestructuredRoots:{default:!0,type:"boolean"},checkGetters:{default:!1,type:"boolean"},checkRestProperty:{default:!1,type:"boolean"},checkSetters:{default:!1,type:"boolean"},checkTypesPattern:{type:"string"},contexts:{items:{type:"string"},type:"array"},enableFixer:{type:"boolean"},enableRestElementFixer:{type:"boolean"},enableRootFixer:{type:"boolean"},exemptedBy:{items:{type:"string"},type:"array"},unnamedRootBase:{items:{type:"string"},type:"array"},useDefaultObjectProperties:{type:"boolean"}},type:"object"}],type:"suggestion"}});t.default=a,e.exports=t.default})),vx=ie((function(e,t){var n;Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=(0,((n=Ze)&&n.__esModule?n:{default:n}).default)((({report:e,utils:t})=>{t.forEachPreferredTag("param",((t,n)=>{t.description.trim()||e(`Missing JSDoc @${n} "${t.name}" description.`,null,t)}))}),{contextDefaults:!0,meta:{docs:{description:"Requires that each `@param` tag has a `description` value.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-param-description"},schema:[{additionalProperties:!1,properties:{contexts:{items:{type:"string"},type:"array"}},type:"object"}],type:"suggestion"}});t.default=r,e.exports=t.default})),Ax=ie((function(e,t){var n;Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=(0,((n=Ze)&&n.__esModule?n:{default:n}).default)((({report:e,utils:t})=>{t.forEachPreferredTag("param",((t,n)=>{t.tag&&""===t.name&&e(`There must be an identifier after @${n} ${""===t.type?"type":"tag"}.`,null,t)}))}),{contextDefaults:!0,meta:{docs:{description:"Requires that all function parameters have names.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-param-name"},schema:[{additionalProperties:!1,properties:{contexts:{items:{type:"string"},type:"array"}},type:"object"}],type:"suggestion"}});t.default=r,e.exports=t.default})),kx=ie((function(e,t){var n;Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=(0,((n=Ze)&&n.__esModule?n:{default:n}).default)((({report:e,utils:t})=>{t.forEachPreferredTag("param",((t,n)=>{t.type||e(`Missing JSDoc @${n} "${t.name}" type.`,null,t)}))}),{contextDefaults:!0,meta:{docs:{description:"Requires that each `@param` tag has a `type` value.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-param-type"},schema:[{additionalProperties:!1,properties:{contexts:{items:{type:"string"},type:"array"}},type:"object"}],type:"suggestion"}});t.default=r,e.exports=t.default})),wx=ie((function(e,t){var n;Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=(0,((n=Ze)&&n.__esModule?n:{default:n}).default)((({utils:e})=>{const t=e.filterTags((({tag:e})=>["typedef","namespace"].includes(e)));if(!t.length)return;const n=e.getPreferredTagName({tagName:"property"});e.hasATag([n])||t.forEach((t=>{["object","Object","PlainObject"].includes(t.type)&&e.reportJSDoc(`Missing JSDoc @${n}.`,null,(()=>{e.addTag(n)}))}))}),{iterateAllJsdocs:!0,meta:{docs:{description:"Requires that all `@typedef` and `@namespace` tags have `@property` when their type is a plain `object`, `Object`, or `PlainObject`.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-property"},fixable:"code",type:"suggestion"}});t.default=r,e.exports=t.default})),Px=ie((function(e,t){var n;Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=(0,((n=Ze)&&n.__esModule?n:{default:n}).default)((({report:e,utils:t})=>{t.forEachPreferredTag("property",((t,n)=>{t.description.trim()||e(`Missing JSDoc @${n} "${t.name}" description.`,null,t)}))}),{iterateAllJsdocs:!0,meta:{docs:{description:"Requires that each `@property` tag has a `description` value.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-property-description"},type:"suggestion"}});t.default=r,e.exports=t.default})),Tx=ie((function(e,t){var n;Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=(0,((n=Ze)&&n.__esModule?n:{default:n}).default)((({report:e,utils:t})=>{t.forEachPreferredTag("property",((t,n)=>{t.tag&&""===t.name&&e(`There must be an identifier after @${n} ${""===t.type?"type":"tag"}.`,null,t)}))}),{iterateAllJsdocs:!0,meta:{docs:{description:"Requires that all function `@property` tags have names.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-property-name"},type:"suggestion"}});t.default=r,e.exports=t.default})),Ix=ie((function(e,t){var n;Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=(0,((n=Ze)&&n.__esModule?n:{default:n}).default)((({report:e,utils:t})=>{t.forEachPreferredTag("property",((t,n)=>{t.type||e(`Missing JSDoc @${n} "${t.name}" type.`,null,t)}))}),{iterateAllJsdocs:!0,meta:{docs:{description:"Requires that each `@property` tag has a `type` value.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-property-type"},type:"suggestion"}});t.default=r,e.exports=t.default})),Fx=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n,r=(n=Ze)&&n.__esModule?n:{default:n};var o=(0,r.default)((({report:e,utils:t,context:n})=>{const{forceRequireReturn:r=!1,forceReturnsWithAsync:o=!1}=n.options[0]||{};if((e=>e.hasATag(["abstract","virtual","class","constructor","type","interface"])||e.avoidDocs())(t))return;const s=t.getPreferredTagName({tagName:"returns"});if(!s)return;const a=t.getTags(s);a.length>1&&e(`Found more than one @${s} declaration.`);const i=t.isIteratingFunction(),[c]=a,l=null==c;(()=>{if(!l)return!1;if(r&&(i||t.isVirtualFunction()))return!0;const e=!i&&t.hasTag("async")||i&&t.isAsync();return!(!o||!e)||i&&t.hasValueOrExecutorHasNonEmptyResolveValue(o)})()&&e(`Missing JSDoc @${s} declaration.`)}),{contextDefaults:!0,meta:{docs:{description:"Requires returns are documented.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-returns"},schema:[{additionalProperties:!1,properties:{checkConstructors:{default:!1,type:"boolean"},checkGetters:{default:!0,type:"boolean"},contexts:{items:{type:"string"},type:"array"},exemptedBy:{items:{type:"string"},type:"array"},forceRequireReturn:{default:!1,type:"boolean"},forceReturnsWithAsync:{default:!1,type:"boolean"}},type:"object"}],type:"suggestion"}});t.default=o,e.exports=t.default})),Dx=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n,r=(n=Ze)&&n.__esModule?n:{default:n};var o=(0,r.default)((({context:e,report:t,settings:n,utils:r})=>{const{exemptAsync:o=!0,reportMissingReturnForUndefinedTypes:s=!1}=e.options[0]||{};if(((e,t)=>{const n=["abstract","virtual","class","constructor","interface"];return"closure"===t.mode&&n.push("record"),e.hasATag(n)||e.isConstructor()||e.classHasTag("interface")||"closure"===t.mode&&e.classHasTag("record")})(r,n))return;if(o&&r.isAsync())return;const a=r.getPreferredTagName({tagName:"returns"});if(!a)return;const i=r.getTags(a);0!==i.length&&(i.length>1?t(`Found more than one @${a} declaration.`):!s&&!r.hasDefinedTypeTag(i[0])||r.hasValueOrExecutorHasNonEmptyResolveValue(o)||t(`JSDoc @${a} declaration present but return expression not available in function.`))}),{meta:{docs:{description:"Requires a return statement in function body if a `@returns` tag is specified in jsdoc comment.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-returns-check"},schema:[{additionalProperties:!1,properties:{exemptAsync:{default:!0,type:"boolean"},reportMissingReturnForUndefinedTypes:{default:!1,type:"boolean"}},type:"object"}],type:"suggestion"}});t.default=o,e.exports=t.default})),Ox=ie((function(e,t){var n;Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=(0,((n=Ze)&&n.__esModule?n:{default:n}).default)((({report:e,utils:t})=>{t.forEachPreferredTag("returns",((t,n)=>{const r=t.type&&t.type.trim();["void","undefined","Promise","Promise"].includes(r)||t.description.trim()||e(`Missing JSDoc @${n} description.`,null,t)}))}),{contextDefaults:!0,meta:{docs:{description:"Requires that the `@returns` tag has a `description` value.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-returns-description"},schema:[{additionalProperties:!1,properties:{contexts:{items:{type:"string"},type:"array"}},type:"object"}],type:"suggestion"}});t.default=r,e.exports=t.default})),Bx=ie((function(e,t){var n;Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var r=(0,((n=Ze)&&n.__esModule?n:{default:n}).default)((({report:e,utils:t})=>{t.forEachPreferredTag("returns",((t,n)=>{t.type||e(`Missing JSDoc @${n} type.`,null,t)}))}),{contextDefaults:!0,meta:{docs:{description:"Requires that `@returns` tag has `type` value.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-returns-type"},schema:[{additionalProperties:!1,properties:{contexts:{items:{type:"string"},type:"array"}},type:"object"}],type:"suggestion"}});t.default=r,e.exports=t.default})),Nx=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n,r=(n=Ze)&&n.__esModule?n:{default:n};var o=(0,r.default)((({report:e,utils:t})=>{if((e=>e.hasATag(["abstract","virtual","type"])||e.avoidDocs())(t))return;const n=t.getPreferredTagName({tagName:"throws"});if(!n)return;const r=t.getTags(n),o=t.isIteratingFunction(),[s]=r;!!(null==s)&&o&&t.hasThrowValue()&&e(`Missing JSDoc @${n} declaration.`)}),{contextDefaults:!0,meta:{docs:{url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-returns"},schema:[{additionalProperties:!1,properties:{contexts:{items:{type:"string"},type:"array"},exemptedBy:{items:{type:"string"},type:"array"}},type:"object"}],type:"suggestion"}});t.default=o,e.exports=t.default})),jx=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n,r=(n=Ze)&&n.__esModule?n:{default:n};const o=(e,t,n)=>{const r=e.getPreferredTagName({tagName:n});if(!r)return[];const o=e.getTags(r);o.length>1&&t(`Found more than one @${r} declaration.`);const[s]=o;return[r,null==s]};var s=(0,r.default)((({report:e,utils:t,context:n})=>{const{next:r=!1,nextWithGeneratorTag:s=!1,forceRequireNext:a=!1,forceRequireYields:i=!1,withGeneratorTag:c=!0}=n.options[0]||{};if((e=>e.hasATag(["abstract","virtual","class","constructor","type","interface"])||e.avoidDocs())(t))return;const l=t.isIteratingFunction(),[u,p]=o(t,e,"yields");if(u){(()=>!!p&&(!!(c&&t.hasTag("generator")||i&&l&&t.isGenerator())||l&&t.isGenerator()&&t.hasYieldValue()))()&&e(`Missing JSDoc @${u} declaration.`)}if(r||s||a){const[n,i]=o(t,e,"next");if(!n)return;(()=>!!i&&(!(!s||!t.hasTag("generator"))||!(!r&&!a||!l||!t.isGenerator())&&(a||t.hasYieldReturnValue())))()&&e(`Missing JSDoc @${n} declaration.`)}}),{contextDefaults:!0,meta:{docs:{description:"Requires yields are documented.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-yields"},schema:[{additionalProperties:!1,properties:{contexts:{items:{type:"string"},type:"array"},exemptedBy:{items:{type:"string"},type:"array"},forceRequireNext:{default:!1,type:"boolean"},forceRequireYields:{default:!1,type:"boolean"},next:{default:!1,type:"boolean"},nextWithGeneratorTag:{default:!1,type:"boolean"},withGeneratorTag:{default:!0,type:"boolean"}},type:"object"}],type:"suggestion"}});t.default=s,e.exports=t.default})),Lx=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n,r=(n=Ze)&&n.__esModule?n:{default:n};const o=(e,t,n)=>{const r=e.getPreferredTagName({tagName:n});if(!r)return[];const o=e.getTags(r);return 0===o.length?[]:o.length>1?(t(`Found more than one @${r} declaration.`),[]):[r,o[0]]};var s=(0,r.default)((({context:e,report:t,settings:n,utils:r})=>{if(((e,t)=>{const n=["abstract","virtual","class","constructor","interface"];return"closure"===t.mode&&n.push("record"),e.hasATag(n)||e.isConstructor()||e.classHasTag("interface")||"closure"===t.mode&&e.classHasTag("record")})(r,n))return;const{next:s=!1,checkGeneratorsOnly:a=!1}=e.options[0]||{},[i,c]=o(r,t,"yields");if(i){(()=>!(!a||r.isGenerator())||r.hasDefinedTypeTag(c)&&!r.hasYieldValue())()&&t(`JSDoc @${i} declaration present but yield expression not available in function.`)}if(s){const[e,n]=o(r,t,"next");if(e){(()=>!(!a||r.isGenerator())||r.hasDefinedTypeTag(n)&&!r.hasYieldReturnValue())()&&t(`JSDoc @${e} declaration present but yield expression with return value not available in function.`)}}}),{meta:{docs:{description:"Requires a yield statement in function body if a `@yields` tag is specified in jsdoc comment.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-require-yields-check"},schema:[{additionalProperties:!1,properties:{checkGeneratorsOnly:{default:!1,type:"boolean"},contexts:{items:{type:"string"},type:"array"},exemptedBy:{items:{type:"string"},type:"array"},next:{default:!1,type:"boolean"}},type:"object"}],type:"suggestion"}});t.default=s,e.exports=t.default})),Rx=ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n,r=(n=Ze)&&n.__esModule?n:{default:n};const o=/as\s+/u;var s=(0,r.default)((({jsdoc:e,report:t,utils:n,context:r,settings:s})=>{const{allowEmptyNamepaths:a=!1}=r.options[0]||{},{mode:i}=s,c=e=>{try{return Hy(e,{mode:i}),!0}catch{}return!1};e.tags.forEach((e=>{const r=function(n,r){if(c(n))return!0;let o=!1;if(r)switch(r){case"module":n.startsWith("module:")||(o=c(`module:${n}`));break;case"memberof":case"memberof!":{const e=n.slice(-1);["#",".","~"].includes(e)&&(o=c(n.slice(0,-1)));break}case"borrows":{const e=n.charAt();["#",".","~"].includes(e)&&(o=c(n.slice(1)))}}return!!o||(t(`Syntax error in namepath: ${n}`,null,e),!1)};if("borrows"===e.tag){const n=e.description.replace(o,"").trim();if(!o.test(e.description)||!n)return void t(`@borrows must have an "as" expression. Found "${e.description}"`,null,e);if(r(n,"borrows")){const t=e.name;r(t)}return}const s=["jsdoc","typescript","closure","permissive"].filter((e=>e!==i)).map((e=>n.getTagStructureForMode(e))),l=n.tagMightHaveNamePosition(e.tag,s);if(!0!==l&&e.name){const n=!1===l?"":` in "${i}" mode`;return void t(`@${e.tag} should not have a name${n}.`,null,e)}const u=n.tagMightHaveTypePosition(e.tag,s);if(!0!==u&&e.type){const n=!1===u?"":` in "${i}" mode`;return void t(`@${e.tag} should not have a bracketed type${n}.`,null,e)}const p=n.tagMustHaveNamePosition(e.tag,s);if(!(!1===p||e.name||a||["param","arg","argument","property","prop"].includes(e.tag)||"see"===e.tag&&e.description.includes("{@link"))){const n=!0===p?"":` in "${i}" mode`;return void t(`Tag @${e.tag} must have a name/namepath${n}.`,null,e)}const d=n.tagMustHaveTypePosition(e.tag,s);if(!1!==d&&!e.type){const n=!0===d?"":` in "${i}" mode`;return void t(`Tag @${e.tag} must have a type${n}.`,null,e)}const f=n.tagMissingRequiredTypeOrNamepath(e,s);if(!1!==f&&!a){const n=!0===f?"":` in "${i}" mode`;return void t(`Tag @${e.tag} must have either a type or namepath${n}.`,null,e)}!0===u&&Boolean(e.type)&&function(n){try{Hy(n,{mode:i})}catch{return t(`Syntax error in type: ${n}`,null,e),!1}}(e.type);(!1!==p||n.tagMightHaveNamepath(e.tag))&&Boolean(e.name)&&("jsdoc"!==i&&"template"===e.tag?n.parseClosureTemplateTag(e).forEach((e=>{r(e)})):r(e.name,e.tag))}))}),{iterateAllJsdocs:!0,meta:{docs:{description:"Requires all types to be valid JSDoc or Closure compiler types without syntax errors.",url:"https://github.com/gajus/eslint-plugin-jsdoc#eslint-plugin-jsdoc-rules-valid-types"},schema:[{additionalProperies:!1,properties:{allowEmptyNamepaths:{default:!1,type:"boolean"}},type:"object"}],type:"suggestion"}});t.default=s,e.exports=t.default})),Mx=ae(ie((function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=void 0;var n=V(et),r=V(tt),o=V(oy),s=V(sy),a=V(ay),i=V(iy),c=V(cy),l=V(ly),u=V(uy),p=V(Zy),d=V(sx),f=V(ax),m=V(ix),g=V(cx),h=V(lx),y=V(ux),x=V(px),b=V(dx),E=V(fx),S=V(mx),C=V(hx),v=V(yx),A=V(xx),k=V(bx),w=V(Sx),P=V(Cx),T=V(vx),I=V(Ax),F=V(kx),D=V(wx),O=V(Px),B=V(Tx),N=V(Ix),j=V(Fx),L=V(Dx),R=V(Ox),M=V(Bx),_=V(Nx),$=V(jx),q=V(Lx),U=V(Rx);function V(e){return e&&e.__esModule?e:{default:e}}var W={configs:{recommended:{plugins:["jsdoc"],rules:{"jsdoc/check-access":"warn","jsdoc/check-alignment":"warn","jsdoc/check-examples":"off","jsdoc/check-indentation":"off","jsdoc/check-line-alignment":"off","jsdoc/check-param-names":"warn","jsdoc/check-property-names":"warn","jsdoc/check-syntax":"off","jsdoc/check-tag-names":"warn","jsdoc/check-types":"warn","jsdoc/check-values":"warn","jsdoc/empty-tags":"warn","jsdoc/implements-on-classes":"warn","jsdoc/match-description":"off","jsdoc/newline-after-description":"warn","jsdoc/no-bad-blocks":"off","jsdoc/no-defaults":"off","jsdoc/no-types":"off","jsdoc/no-undefined-types":"warn","jsdoc/require-description":"off","jsdoc/require-description-complete-sentence":"off","jsdoc/require-example":"off","jsdoc/require-file-overview":"off","jsdoc/require-hyphen-before-param-description":"off","jsdoc/require-jsdoc":"warn","jsdoc/require-param":"warn","jsdoc/require-param-description":"warn","jsdoc/require-param-name":"warn","jsdoc/require-param-type":"warn","jsdoc/require-property":"warn","jsdoc/require-property-description":"warn","jsdoc/require-property-name":"warn","jsdoc/require-property-type":"warn","jsdoc/require-returns":"warn","jsdoc/require-returns-check":"warn","jsdoc/require-returns-description":"warn","jsdoc/require-returns-type":"warn","jsdoc/require-throws":"off","jsdoc/require-yields":"warn","jsdoc/require-yields-check":"warn","jsdoc/valid-types":"warn"}}},rules:{"check-access":n.default,"check-alignment":r.default,"check-examples":o.default,"check-indentation":s.default,"check-line-alignment":a.default,"check-param-names":i.default,"check-property-names":c.default,"check-syntax":l.default,"check-tag-names":u.default,"check-types":p.default,"check-values":d.default,"empty-tags":f.default,"implements-on-classes":m.default,"match-description":g.default,"newline-after-description":h.default,"no-bad-blocks":y.default,"no-defaults":x.default,"no-types":b.default,"no-undefined-types":E.default,"require-description":S.default,"require-description-complete-sentence":C.default,"require-example":v.default,"require-file-overview":A.default,"require-hyphen-before-param-description":k.default,"require-jsdoc":w.default,"require-param":P.default,"require-param-description":T.default,"require-param-name":I.default,"require-param-type":F.default,"require-property":D.default,"require-property-description":O.default,"require-property-name":B.default,"require-property-type":N.default,"require-returns":j.default,"require-returns-check":L.default,"require-returns-description":R.default,"require-returns-type":M.default,"require-throws":_.default,"require-yields":$.default,"require-yields-check":q.default,"valid-types":U.default}};t.default=W,e.exports=t.default})));module.exports=Mx; \ No newline at end of file diff --git a/tools/node_modules/eslint/node_modules/eslint-plugin-markdown/index.js b/tools/node_modules/eslint/node_modules/eslint-plugin-markdown/index.js index d6d8d38daa961e..ce968149796dfd 100644 --- a/tools/node_modules/eslint/node_modules/eslint-plugin-markdown/index.js +++ b/tools/node_modules/eslint/node_modules/eslint-plugin-markdown/index.js @@ -1,11965 +1,13 @@ -'use strict'; - -var path = require('path'); -var require$$0$1 = require('util'); - -function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } - -var path__default = /*#__PURE__*/_interopDefaultLegacy(path); -var require$$0__default = /*#__PURE__*/_interopDefaultLegacy(require$$0$1); - -var hasOwn = Object.prototype.hasOwnProperty; -var toStr = Object.prototype.toString; -var defineProperty = Object.defineProperty; -var gOPD = Object.getOwnPropertyDescriptor; - -var isArray = function isArray(arr) { - if (typeof Array.isArray === 'function') { - return Array.isArray(arr); - } - - return toStr.call(arr) === '[object Array]'; -}; - -var isPlainObject = function isPlainObject(obj) { - if (!obj || toStr.call(obj) !== '[object Object]') { - return false; - } - - var hasOwnConstructor = hasOwn.call(obj, 'constructor'); - var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf'); - // Not own constructor property must be Object - if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) { - return false; - } - - // Own properties are enumerated firstly, so to speed up, - // if last one is own, then all properties are own. - var key; - for (key in obj) { /**/ } - - return typeof key === 'undefined' || hasOwn.call(obj, key); -}; - -// If name is '__proto__', and Object.defineProperty is available, define __proto__ as an own property on target -var setProperty = function setProperty(target, options) { - if (defineProperty && options.name === '__proto__') { - defineProperty(target, options.name, { - enumerable: true, - configurable: true, - value: options.newValue, - writable: true - }); - } else { - target[options.name] = options.newValue; - } -}; - -// Return undefined instead of __proto__ if '__proto__' is not an own property -var getProperty = function getProperty(obj, name) { - if (name === '__proto__') { - if (!hasOwn.call(obj, name)) { - return void 0; - } else if (gOPD) { - // In early versions of node, obj['__proto__'] is buggy when obj has - // __proto__ as an own property. Object.getOwnPropertyDescriptor() works. - return gOPD(obj, name).value; - } - } - - return obj[name]; -}; - -var extend$1 = function extend() { - var options, name, src, copy, copyIsArray, clone; - var target = arguments[0]; - var i = 1; - var length = arguments.length; - var deep = false; - - // Handle a deep copy situation - if (typeof target === 'boolean') { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - if (target == null || (typeof target !== 'object' && typeof target !== 'function')) { - target = {}; - } - - for (; i < length; ++i) { - options = arguments[i]; - // Only deal with non-null/undefined values - if (options != null) { - // Extend the base object - for (name in options) { - src = getProperty(target, name); - copy = getProperty(options, name); - - // Prevent never-ending loop - if (target !== copy) { - // Recurse if we're merging plain objects or arrays - if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) { - if (copyIsArray) { - copyIsArray = false; - clone = src && isArray(src) ? src : []; - } else { - clone = src && isPlainObject(src) ? src : {}; - } - - // Never move original objects, clone them - setProperty(target, { name: name, newValue: extend(deep, clone, copy) }); - - // Don't bring in undefined values - } else if (typeof copy !== 'undefined') { - setProperty(target, { name: name, newValue: copy }); - } - } - } - } - } - - // Return the modified object - return target; -}; - -var bail_1 = bail; - -function bail(err) { - if (err) { - throw err - } -} - -var own$5 = {}.hasOwnProperty; - -var unistUtilStringifyPosition = stringify; - -function stringify(value) { - /* Nothing. */ - if (!value || typeof value !== 'object') { - return null - } - - /* Node. */ - if (own$5.call(value, 'position') || own$5.call(value, 'type')) { - return position(value.position) - } - - /* Position. */ - if (own$5.call(value, 'start') || own$5.call(value, 'end')) { - return position(value) - } - - /* Point. */ - if (own$5.call(value, 'line') || own$5.call(value, 'column')) { - return point(value) - } - - /* ? */ - return null -} - -function point(point) { - if (!point || typeof point !== 'object') { - point = {}; - } - - return index(point.line) + ':' + index(point.column) -} - -function position(pos) { - if (!pos || typeof pos !== 'object') { - pos = {}; - } - - return point(pos.start) + '-' + point(pos.end) -} - -function index(value) { - return value && typeof value === 'number' ? value : 1 -} - -var vfileMessage = VMessage; - -// Inherit from `Error#`. -function VMessagePrototype() {} -VMessagePrototype.prototype = Error.prototype; -VMessage.prototype = new VMessagePrototype(); - -// Message properties. -var proto$3 = VMessage.prototype; - -proto$3.file = ''; -proto$3.name = ''; -proto$3.reason = ''; -proto$3.message = ''; -proto$3.stack = ''; -proto$3.fatal = null; -proto$3.column = null; -proto$3.line = null; - -// Construct a new VMessage. -// -// Note: We cannot invoke `Error` on the created context, as that adds readonly -// `line` and `column` attributes on Safari 9, thus throwing and failing the -// data. -function VMessage(reason, position, origin) { - var parts; - var range; - var location; - - if (typeof position === 'string') { - origin = position; - position = null; - } - - parts = parseOrigin(origin); - range = unistUtilStringifyPosition(position) || '1:1'; - - location = { - start: {line: null, column: null}, - end: {line: null, column: null} - }; - - // Node. - if (position && position.position) { - position = position.position; - } - - if (position) { - // Position. - if (position.start) { - location = position; - position = position.start; - } else { - // Point. - location.start = position; - } - } - - if (reason.stack) { - this.stack = reason.stack; - reason = reason.message; - } - - this.message = reason; - this.name = range; - this.reason = reason; - this.line = position ? position.line : null; - this.column = position ? position.column : null; - this.location = location; - this.source = parts[0]; - this.ruleId = parts[1]; -} - -function parseOrigin(origin) { - var result = [null, null]; - var index; - - if (typeof origin === 'string') { - index = origin.indexOf(':'); - - if (index === -1) { - result[1] = origin; - } else { - result[0] = origin.slice(0, index); - result[1] = origin.slice(index + 1); - } - } - - return result -} - -function replaceExt(npath, ext) { - if (typeof npath !== 'string') { - return npath; - } - - if (npath.length === 0) { - return npath; - } - - var nFileName = path__default['default'].basename(npath, path__default['default'].extname(npath)) + ext; - return path__default['default'].join(path__default['default'].dirname(npath), nFileName); -} - -var replaceExt_1 = replaceExt; - +"use strict";var r=require("path"),e=require("util");function t(r){return r&&"object"==typeof r&&"default"in r?r:{default:r}}var n=t(r),o=t(e),i=Object.prototype.hasOwnProperty,a=Object.prototype.toString,c=Object.defineProperty,l=Object.getOwnPropertyDescriptor,s=function(r){return"function"==typeof Array.isArray?Array.isArray(r):"[object Array]"===a.call(r)},u=function(r){if(!r||"[object Object]"!==a.call(r))return!1;var e,t=i.call(r,"constructor"),n=r.constructor&&r.constructor.prototype&&i.call(r.constructor.prototype,"isPrototypeOf");if(r.constructor&&!t&&!n)return!1;for(e in r);return void 0===e||i.call(r,e)},f=function(r,e){c&&"__proto__"===e.name?c(r,e.name,{enumerable:!0,configurable:!0,value:e.newValue,writable:!0}):r[e.name]=e.newValue},p=function(r,e){if("__proto__"===e){if(!i.call(r,e))return;if(l)return l(r,e).value}return r[e]},h=function r(){var e,t,n,o,i,a,c=arguments[0],l=1,h=arguments.length,d=!1;for("boolean"==typeof c&&(d=c,c=arguments[1]||{},l=2),(null==c||"object"!=typeof c&&"function"!=typeof c)&&(c={});l * @license MIT - */ -// The _isBuffer check is for Safari 5-7 support, because it's missing -// Object.prototype.constructor. Remove this eventually -var isBuffer_1 = function (obj) { - return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer) -}; - -function isBuffer (obj) { - return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) -} - -// For Node v0.10 support. Remove this eventually. -function isSlowBuffer (obj) { - return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0)) -} - -var core = VFile; - -var own$4 = {}.hasOwnProperty; -var proto$2 = VFile.prototype; - -proto$2.toString = toString$2; - -/* Order of setting (least specific to most), we need this because - * otherwise `{stem: 'a', path: '~/b.js'}` would throw, as a path - * is needed before a stem can be set. */ -var order$1 = [ - 'history', - 'path', - 'basename', - 'stem', - 'extname', - 'dirname' -]; - -/* Construct a new file. */ -function VFile(options) { - var prop; - var index; - var length; - - if (!options) { - options = {}; - } else if (typeof options === 'string' || isBuffer_1(options)) { - options = {contents: options}; - } else if ('message' in options && 'messages' in options) { - return options; - } - - if (!(this instanceof VFile)) { - return new VFile(options); - } - - this.data = {}; - this.messages = []; - this.history = []; - this.cwd = process.cwd(); - - /* Set path related properties in the correct order. */ - index = -1; - length = order$1.length; - - while (++index < length) { - prop = order$1[index]; - - if (own$4.call(options, prop)) { - this[prop] = options[prop]; - } - } - - /* Set non-path related properties. */ - for (prop in options) { - if (order$1.indexOf(prop) === -1) { - this[prop] = options[prop]; - } - } -} - -/* Access full path (`~/index.min.js`). */ -Object.defineProperty(proto$2, 'path', { - get: function () { - return this.history[this.history.length - 1]; - }, - set: function (path) { - assertNonEmpty(path, 'path'); - - if (path !== this.path) { - this.history.push(path); - } - } -}); - -/* Access parent path (`~`). */ -Object.defineProperty(proto$2, 'dirname', { - get: function () { - return typeof this.path === 'string' ? path__default['default'].dirname(this.path) : undefined; - }, - set: function (dirname) { - assertPath(this.path, 'dirname'); - this.path = path__default['default'].join(dirname || '', this.basename); - } -}); - -/* Access basename (`index.min.js`). */ -Object.defineProperty(proto$2, 'basename', { - get: function () { - return typeof this.path === 'string' ? path__default['default'].basename(this.path) : undefined; - }, - set: function (basename) { - assertNonEmpty(basename, 'basename'); - assertPart(basename, 'basename'); - this.path = path__default['default'].join(this.dirname || '', basename); - } -}); - -/* Access extname (`.js`). */ -Object.defineProperty(proto$2, 'extname', { - get: function () { - return typeof this.path === 'string' ? path__default['default'].extname(this.path) : undefined; - }, - set: function (extname) { - var ext = extname || ''; - - assertPart(ext, 'extname'); - assertPath(this.path, 'extname'); - - if (ext) { - if (ext.charAt(0) !== '.') { - throw new Error('`extname` must start with `.`'); - } - - if (ext.indexOf('.', 1) !== -1) { - throw new Error('`extname` cannot contain multiple dots'); - } - } - - this.path = replaceExt_1(this.path, ext); - } -}); - -/* Access stem (`index.min`). */ -Object.defineProperty(proto$2, 'stem', { - get: function () { - return typeof this.path === 'string' ? path__default['default'].basename(this.path, this.extname) : undefined; - }, - set: function (stem) { - assertNonEmpty(stem, 'stem'); - assertPart(stem, 'stem'); - this.path = path__default['default'].join(this.dirname || '', stem + (this.extname || '')); - } -}); - -/* Get the value of the file. */ -function toString$2(encoding) { - var value = this.contents || ''; - return isBuffer_1(value) ? value.toString(encoding) : String(value); -} - -/* Assert that `part` is not a path (i.e., does - * not contain `path.sep`). */ -function assertPart(part, name) { - if (part.indexOf(path__default['default'].sep) !== -1) { - throw new Error('`' + name + '` cannot be a path: did not expect `' + path__default['default'].sep + '`'); - } -} - -/* Assert that `part` is not empty. */ -function assertNonEmpty(part, name) { - if (!part) { - throw new Error('`' + name + '` cannot be empty'); - } -} - -/* Assert `path` exists. */ -function assertPath(path, name) { - if (!path) { - throw new Error('Setting `' + name + '` requires `path` to be set too'); - } -} - -var vfile = core; - -var proto$1 = core.prototype; - -proto$1.message = message; -proto$1.info = info; -proto$1.fail = fail; - -/* Slight backwards compatibility. Remove in the future. */ -proto$1.warn = message; - -/* Create a message with `reason` at `position`. - * When an error is passed in as `reason`, copies the stack. */ -function message(reason, position, origin) { - var filePath = this.path; - var message = new vfileMessage(reason, position, origin); - - if (filePath) { - message.name = filePath + ':' + message.name; - message.file = filePath; - } - - message.fatal = false; - - this.messages.push(message); - - return message; -} - -/* Fail. Creates a vmessage, associates it with the file, - * and throws it. */ -function fail() { - var message = this.message.apply(this, arguments); - - message.fatal = true; - - throw message; -} - -/* Info. Creates a vmessage, associates it with the file, - * and marks the fatality as null. */ -function info() { - var message = this.message.apply(this, arguments); - - message.fatal = null; - - return message; -} - -var slice$2 = [].slice; - -var wrap_1 = wrap; - -// Wrap `fn`. -// Can be sync or async; return a promise, receive a completion handler, return -// new values and errors. -function wrap(fn, callback) { - var invoked; - - return wrapped - - function wrapped() { - var params = slice$2.call(arguments, 0); - var callback = fn.length > params.length; - var result; - - if (callback) { - params.push(done); - } - - try { - result = fn.apply(null, params); - } catch (error) { - // Well, this is quite the pickle. - // `fn` received a callback and invoked it (thus continuing the pipeline), - // but later also threw an error. - // We’re not about to restart the pipeline again, so the only thing left - // to do is to throw the thing instead. - if (callback && invoked) { - throw error - } - - return done(error) - } - - if (!callback) { - if (result && typeof result.then === 'function') { - result.then(then, done); - } else if (result instanceof Error) { - done(result); - } else { - then(result); - } - } - } - - // Invoke `next`, only once. - function done() { - if (!invoked) { - invoked = true; - - callback.apply(null, arguments); - } - } - - // Invoke `done` with one value. - // Tracks if an error is passed, too. - function then(value) { - done(null, value); - } -} - -var trough_1 = trough; - -trough.wrap = wrap_1; - -var slice$1 = [].slice; - -// Create new middleware. -function trough() { - var fns = []; - var middleware = {}; - - middleware.run = run; - middleware.use = use; - - return middleware - - // Run `fns`. Last argument must be a completion handler. - function run() { - var index = -1; - var input = slice$1.call(arguments, 0, -1); - var done = arguments[arguments.length - 1]; - - if (typeof done !== 'function') { - throw new Error('Expected function as last argument, not ' + done) - } - - next.apply(null, [null].concat(input)); - - // Run the next `fn`, if any. - function next(err) { - var fn = fns[++index]; - var params = slice$1.call(arguments, 0); - var values = params.slice(1); - var length = input.length; - var pos = -1; - - if (err) { - done(err); - return - } - - // Copy non-nully input into values. - while (++pos < length) { - if (values[pos] === null || values[pos] === undefined) { - values[pos] = input[pos]; - } - } - - input = values; - - // Next or done. - if (fn) { - wrap_1(fn, next).apply(null, input); - } else { - done.apply(null, [null].concat(input)); - } - } - } - - // Add `fn` to the list. - function use(fn) { - if (typeof fn !== 'function') { - throw new Error('Expected `fn` to be a function, not ' + fn) - } - - fns.push(fn); - - return middleware - } -} - -var toString$1 = Object.prototype.toString; - -var xIsString = isString; - -function isString(obj) { - return toString$1.call(obj) === "[object String]" -} - -var toString = Object.prototype.toString; - -var isPlainObj = function (x) { - var prototype; - return toString.call(x) === '[object Object]' && (prototype = Object.getPrototypeOf(x), prototype === null || prototype === Object.getPrototypeOf({})); -}; - -/* Dependencies. */ - - - - - - - -/* Expose a frozen processor. */ -var unified_1 = unified().freeze(); - -var slice = [].slice; -var own$3 = {}.hasOwnProperty; - -/* Process pipeline. */ -var pipeline = trough_1() - .use(pipelineParse) - .use(pipelineRun) - .use(pipelineStringify); - -function pipelineParse(p, ctx) { - ctx.tree = p.parse(ctx.file); -} - -function pipelineRun(p, ctx, next) { - p.run(ctx.tree, ctx.file, done); - - function done(err, tree, file) { - if (err) { - next(err); - } else { - ctx.tree = tree; - ctx.file = file; - next(); - } - } -} - -function pipelineStringify(p, ctx) { - ctx.file.contents = p.stringify(ctx.tree, ctx.file); -} - -/* Function to create the first processor. */ -function unified() { - var attachers = []; - var transformers = trough_1(); - var namespace = {}; - var frozen = false; - var freezeIndex = -1; - - /* Data management. */ - processor.data = data; - - /* Lock. */ - processor.freeze = freeze; - - /* Plug-ins. */ - processor.attachers = attachers; - processor.use = use; - - /* API. */ - processor.parse = parse; - processor.stringify = stringify; - processor.run = run; - processor.runSync = runSync; - processor.process = process; - processor.processSync = processSync; - - /* Expose. */ - return processor - - /* Create a new processor based on the processor - * in the current scope. */ - function processor() { - var destination = unified(); - var length = attachers.length; - var index = -1; - - while (++index < length) { - destination.use.apply(null, attachers[index]); - } - - destination.data(extend$1(true, {}, namespace)); - - return destination - } - - /* Freeze: used to signal a processor that has finished - * configuration. - * - * For example, take unified itself. It’s frozen. - * Plug-ins should not be added to it. Rather, it should - * be extended, by invoking it, before modifying it. - * - * In essence, always invoke this when exporting a - * processor. */ - function freeze() { - var values; - var plugin; - var options; - var transformer; - - if (frozen) { - return processor - } - - while (++freezeIndex < attachers.length) { - values = attachers[freezeIndex]; - plugin = values[0]; - options = values[1]; - transformer = null; - - if (options === false) { - continue - } - - if (options === true) { - values[1] = undefined; - } - - transformer = plugin.apply(processor, values.slice(1)); - - if (typeof transformer === 'function') { - transformers.use(transformer); - } - } - - frozen = true; - freezeIndex = Infinity; - - return processor - } - - /* Data management. - * Getter / setter for processor-specific informtion. */ - function data(key, value) { - if (xIsString(key)) { - /* Set `key`. */ - if (arguments.length === 2) { - assertUnfrozen('data', frozen); - - namespace[key] = value; - - return processor - } - - /* Get `key`. */ - return (own$3.call(namespace, key) && namespace[key]) || null - } - - /* Set space. */ - if (key) { - assertUnfrozen('data', frozen); - namespace = key; - return processor - } - - /* Get space. */ - return namespace - } - - /* Plug-in management. - * - * Pass it: - * * an attacher and options, - * * a preset, - * * a list of presets, attachers, and arguments (list - * of attachers and options). */ - function use(value) { - var settings; - - assertUnfrozen('use', frozen); - - if (value === null || value === undefined) ; else if (typeof value === 'function') { - addPlugin.apply(null, arguments); - } else if (typeof value === 'object') { - if ('length' in value) { - addList(value); - } else { - addPreset(value); - } - } else { - throw new Error('Expected usable value, not `' + value + '`') - } - - if (settings) { - namespace.settings = extend$1(namespace.settings || {}, settings); - } - - return processor - - function addPreset(result) { - addList(result.plugins); - - if (result.settings) { - settings = extend$1(settings || {}, result.settings); - } - } - - function add(value) { - if (typeof value === 'function') { - addPlugin(value); - } else if (typeof value === 'object') { - if ('length' in value) { - addPlugin.apply(null, value); - } else { - addPreset(value); - } - } else { - throw new Error('Expected usable value, not `' + value + '`') - } - } - - function addList(plugins) { - var length; - var index; - - if (plugins === null || plugins === undefined) ; else if (typeof plugins === 'object' && 'length' in plugins) { - length = plugins.length; - index = -1; - - while (++index < length) { - add(plugins[index]); - } - } else { - throw new Error('Expected a list of plugins, not `' + plugins + '`') - } - } - - function addPlugin(plugin, value) { - var entry = find(plugin); - - if (entry) { - if (isPlainObj(entry[1]) && isPlainObj(value)) { - value = extend$1(entry[1], value); - } - - entry[1] = value; - } else { - attachers.push(slice.call(arguments)); - } - } - } - - function find(plugin) { - var length = attachers.length; - var index = -1; - var entry; - - while (++index < length) { - entry = attachers[index]; - - if (entry[0] === plugin) { - return entry - } - } - } - - /* Parse a file (in string or VFile representation) - * into a Unist node using the `Parser` on the - * processor. */ - function parse(doc) { - var file = vfile(doc); - var Parser; - - freeze(); - Parser = processor.Parser; - assertParser('parse', Parser); - - if (newable(Parser)) { - return new Parser(String(file), file).parse() - } - - return Parser(String(file), file) // eslint-disable-line new-cap - } - - /* Run transforms on a Unist node representation of a file - * (in string or VFile representation), async. */ - function run(node, file, cb) { - assertNode(node); - freeze(); - - if (!cb && typeof file === 'function') { - cb = file; - file = null; - } - - if (!cb) { - return new Promise(executor) - } - - executor(null, cb); - - function executor(resolve, reject) { - transformers.run(node, vfile(file), done); - - function done(err, tree, file) { - tree = tree || node; - if (err) { - reject(err); - } else if (resolve) { - resolve(tree); - } else { - cb(null, tree, file); - } - } - } - } - - /* Run transforms on a Unist node representation of a file - * (in string or VFile representation), sync. */ - function runSync(node, file) { - var complete = false; - var result; - - run(node, file, done); - - assertDone('runSync', 'run', complete); - - return result - - function done(err, tree) { - complete = true; - bail_1(err); - result = tree; - } - } - - /* Stringify a Unist node representation of a file - * (in string or VFile representation) into a string - * using the `Compiler` on the processor. */ - function stringify(node, doc) { - var file = vfile(doc); - var Compiler; - - freeze(); - Compiler = processor.Compiler; - assertCompiler('stringify', Compiler); - assertNode(node); - - if (newable(Compiler)) { - return new Compiler(node, file).compile() - } - - return Compiler(node, file) // eslint-disable-line new-cap - } - - /* Parse a file (in string or VFile representation) - * into a Unist node using the `Parser` on the processor, - * then run transforms on that node, and compile the - * resulting node using the `Compiler` on the processor, - * and store that result on the VFile. */ - function process(doc, cb) { - freeze(); - assertParser('process', processor.Parser); - assertCompiler('process', processor.Compiler); - - if (!cb) { - return new Promise(executor) - } - - executor(null, cb); - - function executor(resolve, reject) { - var file = vfile(doc); - - pipeline.run(processor, {file: file}, done); - - function done(err) { - if (err) { - reject(err); - } else if (resolve) { - resolve(file); - } else { - cb(null, file); - } - } - } - } - - /* Process the given document (in string or VFile - * representation), sync. */ - function processSync(doc) { - var complete = false; - var file; - - freeze(); - assertParser('processSync', processor.Parser); - assertCompiler('processSync', processor.Compiler); - file = vfile(doc); - - process(file, done); - - assertDone('processSync', 'process', complete); - - return file - - function done(err) { - complete = true; - bail_1(err); - } - } -} - -/* Check if `func` is a constructor. */ -function newable(value) { - return typeof value === 'function' && keys$1(value.prototype) -} - -/* Check if `value` is an object with keys. */ -function keys$1(value) { - var key; - for (key in value) { - return true - } - return false -} - -/* Assert a parser is available. */ -function assertParser(name, Parser) { - if (typeof Parser !== 'function') { - throw new Error('Cannot `' + name + '` without `Parser`') - } -} - -/* Assert a compiler is available. */ -function assertCompiler(name, Compiler) { - if (typeof Compiler !== 'function') { - throw new Error('Cannot `' + name + '` without `Compiler`') - } -} - -/* Assert the processor is not frozen. */ -function assertUnfrozen(name, frozen) { - if (frozen) { - throw new Error( - [ - 'Cannot invoke `' + name + '` on a frozen processor.\nCreate a new ', - 'processor first, by invoking it: use `processor()` instead of ', - '`processor`.' - ].join('') - ) - } -} - -/* Assert `node` is a Unist node. */ -function assertNode(node) { - if (!node || !xIsString(node.type)) { - throw new Error('Expected node, got `' + node + '`') - } -} - -/* Assert that `complete` is `true`. */ -function assertDone(name, asyncName, complete) { - if (!complete) { - throw new Error( - '`' + name + '` finished async. Use `' + asyncName + '` instead' - ) - } -} - -var immutable = extend; - -var hasOwnProperty = Object.prototype.hasOwnProperty; - -function extend() { - var target = {}; - - for (var i = 0; i < arguments.length; i++) { - var source = arguments[i]; - - for (var key in source) { - if (hasOwnProperty.call(source, key)) { - target[key] = source[key]; - } - } - } - - return target -} - -function createCommonjsModule(fn) { - var module = { exports: {} }; - return fn(module, module.exports), module.exports; -} - -var inherits_browser = createCommonjsModule(function (module) { -if (typeof Object.create === 'function') { - // implementation from standard node.js 'util' module - module.exports = function inherits(ctor, superCtor) { - if (superCtor) { - ctor.super_ = superCtor; - ctor.prototype = Object.create(superCtor.prototype, { - constructor: { - value: ctor, - enumerable: false, - writable: true, - configurable: true - } - }); - } - }; -} else { - // old school shim for old browsers - module.exports = function inherits(ctor, superCtor) { - if (superCtor) { - ctor.super_ = superCtor; - var TempCtor = function () {}; - TempCtor.prototype = superCtor.prototype; - ctor.prototype = new TempCtor(); - ctor.prototype.constructor = ctor; - } - }; -} -}); - -var inherits = createCommonjsModule(function (module) { -try { - var util = require$$0__default['default']; - /* istanbul ignore next */ - if (typeof util.inherits !== 'function') throw ''; - module.exports = util.inherits; -} catch (e) { - /* istanbul ignore next */ - module.exports = inherits_browser; -} -}); - -var unherit_1 = unherit; - -// Create a custom constructor which can be modified without affecting the -// original class. -function unherit(Super) { - var result; - var key; - var value; - - inherits(Of, Super); - inherits(From, Of); - - // Clone values. - result = Of.prototype; - - for (key in result) { - value = result[key]; - - if (value && typeof value === 'object') { - result[key] = 'concat' in value ? value.concat() : immutable(value); - } - } - - return Of - - // Constructor accepting a single argument, which itself is an `arguments` - // object. - function From(parameters) { - return Super.apply(this, parameters) - } - - // Constructor accepting variadic arguments. - function Of() { - if (!(this instanceof Of)) { - return new From(arguments) - } - - return Super.apply(this, arguments) - } -} - -var stateToggle = factory$4; - -// Construct a state `toggler`: a function which inverses `property` in context -// based on its current value. -// The by `toggler` returned function restores that value. -function factory$4(key, state, ctx) { - return enter - - function enter() { - var context = ctx || this; - var current = context[key]; - - context[key] = !state; - - return exit - - function exit() { - context[key] = current; - } - } -} - -var vfileLocation = factory$3; - -function factory$3(file) { - var contents = indices(String(file)); - - return { - toPosition: offsetToPositionFactory(contents), - toOffset: positionToOffsetFactory(contents) - } -} - -// Factory to get the line and column-based `position` for `offset` in the bound -// indices. -function offsetToPositionFactory(indices) { - return offsetToPosition - - // Get the line and column-based `position` for `offset` in the bound indices. - function offsetToPosition(offset) { - var index = -1; - var length = indices.length; - - if (offset < 0) { - return {} - } - - while (++index < length) { - if (indices[index] > offset) { - return { - line: index + 1, - column: offset - (indices[index - 1] || 0) + 1, - offset: offset - } - } - } - - return {} - } -} - -// Factory to get the `offset` for a line and column-based `position` in the -// bound indices. -function positionToOffsetFactory(indices) { - return positionToOffset - - // Get the `offset` for a line and column-based `position` in the bound - // indices. - function positionToOffset(position) { - var line = position && position.line; - var column = position && position.column; - - if (!isNaN(line) && !isNaN(column) && line - 1 in indices) { - return (indices[line - 2] || 0) + column - 1 || 0 - } - - return -1 - } -} - -// Get indices of line-breaks in `value`. -function indices(value) { - var result = []; - var index = value.indexOf('\n'); - - while (index !== -1) { - result.push(index + 1); - index = value.indexOf('\n', index + 1); - } - - result.push(value.length + 1); - - return result -} - -var _unescape = factory$2; - -/* Factory to de-escape a value, based on a list at `key` - * in `ctx`. */ -function factory$2(ctx, key) { - return unescape; - - /* De-escape a string using the expression at `key` - * in `ctx`. */ - function unescape(value) { - var prev = 0; - var index = value.indexOf('\\'); - var escape = ctx[key]; - var queue = []; - var character; - - while (index !== -1) { - queue.push(value.slice(prev, index)); - prev = index + 1; - character = value.charAt(prev); - - /* If the following character is not a valid escape, - * add the slash. */ - if (!character || escape.indexOf(character) === -1) { - queue.push('\\'); - } - - index = value.indexOf('\\', prev); - } - - queue.push(value.slice(prev)); - - return queue.join(''); - } -} - -var AElig$1 = "Æ"; -var AMP$1 = "&"; -var Aacute$1 = "Á"; -var Acirc$1 = "Â"; -var Agrave$1 = "À"; -var Aring$1 = "Å"; -var Atilde$1 = "Ã"; -var Auml$1 = "Ä"; -var COPY$1 = "©"; -var Ccedil$1 = "Ç"; -var ETH$1 = "Ð"; -var Eacute$1 = "É"; -var Ecirc$1 = "Ê"; -var Egrave$1 = "È"; -var Euml$1 = "Ë"; -var GT$1 = ">"; -var Iacute$1 = "Í"; -var Icirc$1 = "Î"; -var Igrave$1 = "Ì"; -var Iuml$1 = "Ï"; -var LT$1 = "<"; -var Ntilde$1 = "Ñ"; -var Oacute$1 = "Ó"; -var Ocirc$1 = "Ô"; -var Ograve$1 = "Ò"; -var Oslash$1 = "Ø"; -var Otilde$1 = "Õ"; -var Ouml$1 = "Ö"; -var QUOT$1 = "\""; -var REG$1 = "®"; -var THORN$1 = "Þ"; -var Uacute$1 = "Ú"; -var Ucirc$1 = "Û"; -var Ugrave$1 = "Ù"; -var Uuml$1 = "Ü"; -var Yacute$1 = "Ý"; -var aacute$1 = "á"; -var acirc$1 = "â"; -var acute$1 = "´"; -var aelig$1 = "æ"; -var agrave$1 = "à"; -var amp$1 = "&"; -var aring$1 = "å"; -var atilde$1 = "ã"; -var auml$1 = "ä"; -var brvbar$1 = "¦"; -var ccedil$1 = "ç"; -var cedil$1 = "¸"; -var cent$1 = "¢"; -var copy$1 = "©"; -var curren$1 = "¤"; -var deg$1 = "°"; -var divide$1 = "÷"; -var eacute$1 = "é"; -var ecirc$1 = "ê"; -var egrave$1 = "è"; -var eth$1 = "ð"; -var euml$1 = "ë"; -var frac12$1 = "½"; -var frac14$1 = "¼"; -var frac34$1 = "¾"; -var gt$1 = ">"; -var iacute$1 = "í"; -var icirc$1 = "î"; -var iexcl$1 = "¡"; -var igrave$1 = "ì"; -var iquest$1 = "¿"; -var iuml$1 = "ï"; -var laquo$1 = "«"; -var lt$1 = "<"; -var macr$1 = "¯"; -var micro$1 = "µ"; -var middot$1 = "·"; -var nbsp$1 = " "; -var not$1 = "¬"; -var ntilde$1 = "ñ"; -var oacute$1 = "ó"; -var ocirc$1 = "ô"; -var ograve$1 = "ò"; -var ordf$1 = "ª"; -var ordm$1 = "º"; -var oslash$1 = "ø"; -var otilde$1 = "õ"; -var ouml$1 = "ö"; -var para$1 = "¶"; -var plusmn$1 = "±"; -var pound$1 = "£"; -var quot$1 = "\""; -var raquo$1 = "»"; -var reg$1 = "®"; -var sect$1 = "§"; -var shy$1 = "­"; -var sup1$1 = "¹"; -var sup2$1 = "²"; -var sup3$1 = "³"; -var szlig$1 = "ß"; -var thorn$1 = "þ"; -var times$1 = "×"; -var uacute$1 = "ú"; -var ucirc$1 = "û"; -var ugrave$1 = "ù"; -var uml$1 = "¨"; -var uuml$1 = "ü"; -var yacute$1 = "ý"; -var yen$1 = "¥"; -var yuml$1 = "ÿ"; -var legacy = { - AElig: AElig$1, - AMP: AMP$1, - Aacute: Aacute$1, - Acirc: Acirc$1, - Agrave: Agrave$1, - Aring: Aring$1, - Atilde: Atilde$1, - Auml: Auml$1, - COPY: COPY$1, - Ccedil: Ccedil$1, - ETH: ETH$1, - Eacute: Eacute$1, - Ecirc: Ecirc$1, - Egrave: Egrave$1, - Euml: Euml$1, - GT: GT$1, - Iacute: Iacute$1, - Icirc: Icirc$1, - Igrave: Igrave$1, - Iuml: Iuml$1, - LT: LT$1, - Ntilde: Ntilde$1, - Oacute: Oacute$1, - Ocirc: Ocirc$1, - Ograve: Ograve$1, - Oslash: Oslash$1, - Otilde: Otilde$1, - Ouml: Ouml$1, - QUOT: QUOT$1, - REG: REG$1, - THORN: THORN$1, - Uacute: Uacute$1, - Ucirc: Ucirc$1, - Ugrave: Ugrave$1, - Uuml: Uuml$1, - Yacute: Yacute$1, - aacute: aacute$1, - acirc: acirc$1, - acute: acute$1, - aelig: aelig$1, - agrave: agrave$1, - amp: amp$1, - aring: aring$1, - atilde: atilde$1, - auml: auml$1, - brvbar: brvbar$1, - ccedil: ccedil$1, - cedil: cedil$1, - cent: cent$1, - copy: copy$1, - curren: curren$1, - deg: deg$1, - divide: divide$1, - eacute: eacute$1, - ecirc: ecirc$1, - egrave: egrave$1, - eth: eth$1, - euml: euml$1, - frac12: frac12$1, - frac14: frac14$1, - frac34: frac34$1, - gt: gt$1, - iacute: iacute$1, - icirc: icirc$1, - iexcl: iexcl$1, - igrave: igrave$1, - iquest: iquest$1, - iuml: iuml$1, - laquo: laquo$1, - lt: lt$1, - macr: macr$1, - micro: micro$1, - middot: middot$1, - nbsp: nbsp$1, - not: not$1, - ntilde: ntilde$1, - oacute: oacute$1, - ocirc: ocirc$1, - ograve: ograve$1, - ordf: ordf$1, - ordm: ordm$1, - oslash: oslash$1, - otilde: otilde$1, - ouml: ouml$1, - para: para$1, - plusmn: plusmn$1, - pound: pound$1, - quot: quot$1, - raquo: raquo$1, - reg: reg$1, - sect: sect$1, - shy: shy$1, - sup1: sup1$1, - sup2: sup2$1, - sup3: sup3$1, - szlig: szlig$1, - thorn: thorn$1, - times: times$1, - uacute: uacute$1, - ucirc: ucirc$1, - ugrave: ugrave$1, - uml: uml$1, - uuml: uuml$1, - yacute: yacute$1, - yen: yen$1, - yuml: yuml$1 -}; - -var invalid = { - "0": "�", - "128": "€", - "130": "‚", - "131": "ƒ", - "132": "„", - "133": "…", - "134": "†", - "135": "‡", - "136": "ˆ", - "137": "‰", - "138": "Š", - "139": "‹", - "140": "Œ", - "142": "Ž", - "145": "‘", - "146": "’", - "147": "“", - "148": "”", - "149": "•", - "150": "–", - "151": "—", - "152": "˜", - "153": "™", - "154": "š", - "155": "›", - "156": "œ", - "158": "ž", - "159": "Ÿ" -}; - -var isDecimal = decimal; - -// Check if the given character code, or the character code at the first -// character, is decimal. -function decimal(character) { - var code = typeof character === 'string' ? character.charCodeAt(0) : character; - - return code >= 48 && code <= 57 /* 0-9 */ -} - -var isHexadecimal = hexadecimal; - -// Check if the given character code, or the character code at the first -// character, is hexadecimal. -function hexadecimal(character) { - var code = typeof character === 'string' ? character.charCodeAt(0) : character; - - return ( - (code >= 97 /* a */ && code <= 102) /* z */ || - (code >= 65 /* A */ && code <= 70) /* Z */ || - (code >= 48 /* A */ && code <= 57) /* Z */ - ) -} - -var isAlphabetical = alphabetical; - -// Check if the given character code, or the character code at the first -// character, is alphabetical. -function alphabetical(character) { - var code = typeof character === 'string' ? character.charCodeAt(0) : character; - - return ( - (code >= 97 && code <= 122) /* a-z */ || - (code >= 65 && code <= 90) /* A-Z */ - ) -} - -var isAlphanumerical = alphanumerical; - -// Check if the given character code, or the character code at the first -// character, is alphanumerical. -function alphanumerical(character) { - return isAlphabetical(character) || isDecimal(character) -} - -var AEli = "Æ"; -var AElig = "Æ"; -var AM = "&"; -var AMP = "&"; -var Aacut = "Á"; -var Aacute = "Á"; -var Abreve = "Ă"; -var Acir = "Â"; -var Acirc = "Â"; -var Acy = "А"; -var Afr = "𝔄"; -var Agrav = "À"; -var Agrave = "À"; -var Alpha = "Α"; -var Amacr = "Ā"; -var And = "⩓"; -var Aogon = "Ą"; -var Aopf = "𝔸"; -var ApplyFunction = "⁡"; -var Arin = "Å"; -var Aring = "Å"; -var Ascr = "𝒜"; -var Assign = "≔"; -var Atild = "Ã"; -var Atilde = "Ã"; -var Aum = "Ä"; -var Auml = "Ä"; -var Backslash = "∖"; -var Barv = "⫧"; -var Barwed = "⌆"; -var Bcy = "Б"; -var Because = "∵"; -var Bernoullis = "ℬ"; -var Beta = "Β"; -var Bfr = "𝔅"; -var Bopf = "𝔹"; -var Breve = "˘"; -var Bscr = "ℬ"; -var Bumpeq = "≎"; -var CHcy = "Ч"; -var COP = "©"; -var COPY = "©"; -var Cacute = "Ć"; -var Cap = "⋒"; -var CapitalDifferentialD = "ⅅ"; -var Cayleys = "ℭ"; -var Ccaron = "Č"; -var Ccedi = "Ç"; -var Ccedil = "Ç"; -var Ccirc = "Ĉ"; -var Cconint = "∰"; -var Cdot = "Ċ"; -var Cedilla = "¸"; -var CenterDot = "·"; -var Cfr = "ℭ"; -var Chi = "Χ"; -var CircleDot = "⊙"; -var CircleMinus = "⊖"; -var CirclePlus = "⊕"; -var CircleTimes = "⊗"; -var ClockwiseContourIntegral = "∲"; -var CloseCurlyDoubleQuote = "”"; -var CloseCurlyQuote = "’"; -var Colon = "∷"; -var Colone = "⩴"; -var Congruent = "≡"; -var Conint = "∯"; -var ContourIntegral = "∮"; -var Copf = "ℂ"; -var Coproduct = "∐"; -var CounterClockwiseContourIntegral = "∳"; -var Cross = "⨯"; -var Cscr = "𝒞"; -var Cup = "⋓"; -var CupCap = "≍"; -var DD = "ⅅ"; -var DDotrahd = "⤑"; -var DJcy = "Ђ"; -var DScy = "Ѕ"; -var DZcy = "Џ"; -var Dagger = "‡"; -var Darr = "↡"; -var Dashv = "⫤"; -var Dcaron = "Ď"; -var Dcy = "Д"; -var Del = "∇"; -var Delta = "Δ"; -var Dfr = "𝔇"; -var DiacriticalAcute = "´"; -var DiacriticalDot = "˙"; -var DiacriticalDoubleAcute = "˝"; -var DiacriticalGrave = "`"; -var DiacriticalTilde = "˜"; -var Diamond = "⋄"; -var DifferentialD = "ⅆ"; -var Dopf = "𝔻"; -var Dot = "¨"; -var DotDot = "⃜"; -var DotEqual = "≐"; -var DoubleContourIntegral = "∯"; -var DoubleDot = "¨"; -var DoubleDownArrow = "⇓"; -var DoubleLeftArrow = "⇐"; -var DoubleLeftRightArrow = "⇔"; -var DoubleLeftTee = "⫤"; -var DoubleLongLeftArrow = "⟸"; -var DoubleLongLeftRightArrow = "⟺"; -var DoubleLongRightArrow = "⟹"; -var DoubleRightArrow = "⇒"; -var DoubleRightTee = "⊨"; -var DoubleUpArrow = "⇑"; -var DoubleUpDownArrow = "⇕"; -var DoubleVerticalBar = "∥"; -var DownArrow = "↓"; -var DownArrowBar = "⤓"; -var DownArrowUpArrow = "⇵"; -var DownBreve = "̑"; -var DownLeftRightVector = "⥐"; -var DownLeftTeeVector = "⥞"; -var DownLeftVector = "↽"; -var DownLeftVectorBar = "⥖"; -var DownRightTeeVector = "⥟"; -var DownRightVector = "⇁"; -var DownRightVectorBar = "⥗"; -var DownTee = "⊤"; -var DownTeeArrow = "↧"; -var Downarrow = "⇓"; -var Dscr = "𝒟"; -var Dstrok = "Đ"; -var ENG = "Ŋ"; -var ET = "Ð"; -var ETH = "Ð"; -var Eacut = "É"; -var Eacute = "É"; -var Ecaron = "Ě"; -var Ecir = "Ê"; -var Ecirc = "Ê"; -var Ecy = "Э"; -var Edot = "Ė"; -var Efr = "𝔈"; -var Egrav = "È"; -var Egrave = "È"; -var Element = "∈"; -var Emacr = "Ē"; -var EmptySmallSquare = "◻"; -var EmptyVerySmallSquare = "▫"; -var Eogon = "Ę"; -var Eopf = "𝔼"; -var Epsilon = "Ε"; -var Equal = "⩵"; -var EqualTilde = "≂"; -var Equilibrium = "⇌"; -var Escr = "ℰ"; -var Esim = "⩳"; -var Eta = "Η"; -var Eum = "Ë"; -var Euml = "Ë"; -var Exists = "∃"; -var ExponentialE = "ⅇ"; -var Fcy = "Ф"; -var Ffr = "𝔉"; -var FilledSmallSquare = "◼"; -var FilledVerySmallSquare = "▪"; -var Fopf = "𝔽"; -var ForAll = "∀"; -var Fouriertrf = "ℱ"; -var Fscr = "ℱ"; -var GJcy = "Ѓ"; -var G = ">"; -var GT = ">"; -var Gamma = "Γ"; -var Gammad = "Ϝ"; -var Gbreve = "Ğ"; -var Gcedil = "Ģ"; -var Gcirc = "Ĝ"; -var Gcy = "Г"; -var Gdot = "Ġ"; -var Gfr = "𝔊"; -var Gg = "⋙"; -var Gopf = "𝔾"; -var GreaterEqual = "≥"; -var GreaterEqualLess = "⋛"; -var GreaterFullEqual = "≧"; -var GreaterGreater = "⪢"; -var GreaterLess = "≷"; -var GreaterSlantEqual = "⩾"; -var GreaterTilde = "≳"; -var Gscr = "𝒢"; -var Gt = "≫"; -var HARDcy = "Ъ"; -var Hacek = "ˇ"; -var Hat = "^"; -var Hcirc = "Ĥ"; -var Hfr = "ℌ"; -var HilbertSpace = "ℋ"; -var Hopf = "ℍ"; -var HorizontalLine = "─"; -var Hscr = "ℋ"; -var Hstrok = "Ħ"; -var HumpDownHump = "≎"; -var HumpEqual = "≏"; -var IEcy = "Е"; -var IJlig = "IJ"; -var IOcy = "Ё"; -var Iacut = "Í"; -var Iacute = "Í"; -var Icir = "Î"; -var Icirc = "Î"; -var Icy = "И"; -var Idot = "İ"; -var Ifr = "ℑ"; -var Igrav = "Ì"; -var Igrave = "Ì"; -var Im = "ℑ"; -var Imacr = "Ī"; -var ImaginaryI = "ⅈ"; -var Implies = "⇒"; -var Int = "∬"; -var Integral = "∫"; -var Intersection = "⋂"; -var InvisibleComma = "⁣"; -var InvisibleTimes = "⁢"; -var Iogon = "Į"; -var Iopf = "𝕀"; -var Iota = "Ι"; -var Iscr = "ℐ"; -var Itilde = "Ĩ"; -var Iukcy = "І"; -var Ium = "Ï"; -var Iuml = "Ï"; -var Jcirc = "Ĵ"; -var Jcy = "Й"; -var Jfr = "𝔍"; -var Jopf = "𝕁"; -var Jscr = "𝒥"; -var Jsercy = "Ј"; -var Jukcy = "Є"; -var KHcy = "Х"; -var KJcy = "Ќ"; -var Kappa = "Κ"; -var Kcedil = "Ķ"; -var Kcy = "К"; -var Kfr = "𝔎"; -var Kopf = "𝕂"; -var Kscr = "𝒦"; -var LJcy = "Љ"; -var L = "<"; -var LT = "<"; -var Lacute = "Ĺ"; -var Lambda = "Λ"; -var Lang = "⟪"; -var Laplacetrf = "ℒ"; -var Larr = "↞"; -var Lcaron = "Ľ"; -var Lcedil = "Ļ"; -var Lcy = "Л"; -var LeftAngleBracket = "⟨"; -var LeftArrow = "←"; -var LeftArrowBar = "⇤"; -var LeftArrowRightArrow = "⇆"; -var LeftCeiling = "⌈"; -var LeftDoubleBracket = "⟦"; -var LeftDownTeeVector = "⥡"; -var LeftDownVector = "⇃"; -var LeftDownVectorBar = "⥙"; -var LeftFloor = "⌊"; -var LeftRightArrow = "↔"; -var LeftRightVector = "⥎"; -var LeftTee = "⊣"; -var LeftTeeArrow = "↤"; -var LeftTeeVector = "⥚"; -var LeftTriangle = "⊲"; -var LeftTriangleBar = "⧏"; -var LeftTriangleEqual = "⊴"; -var LeftUpDownVector = "⥑"; -var LeftUpTeeVector = "⥠"; -var LeftUpVector = "↿"; -var LeftUpVectorBar = "⥘"; -var LeftVector = "↼"; -var LeftVectorBar = "⥒"; -var Leftarrow = "⇐"; -var Leftrightarrow = "⇔"; -var LessEqualGreater = "⋚"; -var LessFullEqual = "≦"; -var LessGreater = "≶"; -var LessLess = "⪡"; -var LessSlantEqual = "⩽"; -var LessTilde = "≲"; -var Lfr = "𝔏"; -var Ll = "⋘"; -var Lleftarrow = "⇚"; -var Lmidot = "Ŀ"; -var LongLeftArrow = "⟵"; -var LongLeftRightArrow = "⟷"; -var LongRightArrow = "⟶"; -var Longleftarrow = "⟸"; -var Longleftrightarrow = "⟺"; -var Longrightarrow = "⟹"; -var Lopf = "𝕃"; -var LowerLeftArrow = "↙"; -var LowerRightArrow = "↘"; -var Lscr = "ℒ"; -var Lsh = "↰"; -var Lstrok = "Ł"; -var Lt = "≪"; -var Mcy = "М"; -var MediumSpace = " "; -var Mellintrf = "ℳ"; -var Mfr = "𝔐"; -var MinusPlus = "∓"; -var Mopf = "𝕄"; -var Mscr = "ℳ"; -var Mu = "Μ"; -var NJcy = "Њ"; -var Nacute = "Ń"; -var Ncaron = "Ň"; -var Ncedil = "Ņ"; -var Ncy = "Н"; -var NegativeMediumSpace = "​"; -var NegativeThickSpace = "​"; -var NegativeThinSpace = "​"; -var NegativeVeryThinSpace = "​"; -var NestedGreaterGreater = "≫"; -var NestedLessLess = "≪"; -var NewLine = "\n"; -var Nfr = "𝔑"; -var NoBreak = "⁠"; -var NonBreakingSpace = " "; -var Nopf = "ℕ"; -var Not = "⫬"; -var NotCongruent = "≢"; -var NotCupCap = "≭"; -var NotDoubleVerticalBar = "∦"; -var NotElement = "∉"; -var NotEqual = "≠"; -var NotEqualTilde = "≂̸"; -var NotExists = "∄"; -var NotGreater = "≯"; -var NotGreaterEqual = "≱"; -var NotGreaterFullEqual = "≧̸"; -var NotGreaterGreater = "≫̸"; -var NotGreaterLess = "≹"; -var NotGreaterSlantEqual = "⩾̸"; -var NotGreaterTilde = "≵"; -var NotHumpDownHump = "≎̸"; -var NotHumpEqual = "≏̸"; -var NotLeftTriangle = "⋪"; -var NotLeftTriangleBar = "⧏̸"; -var NotLeftTriangleEqual = "⋬"; -var NotLess = "≮"; -var NotLessEqual = "≰"; -var NotLessGreater = "≸"; -var NotLessLess = "≪̸"; -var NotLessSlantEqual = "⩽̸"; -var NotLessTilde = "≴"; -var NotNestedGreaterGreater = "⪢̸"; -var NotNestedLessLess = "⪡̸"; -var NotPrecedes = "⊀"; -var NotPrecedesEqual = "⪯̸"; -var NotPrecedesSlantEqual = "⋠"; -var NotReverseElement = "∌"; -var NotRightTriangle = "⋫"; -var NotRightTriangleBar = "⧐̸"; -var NotRightTriangleEqual = "⋭"; -var NotSquareSubset = "⊏̸"; -var NotSquareSubsetEqual = "⋢"; -var NotSquareSuperset = "⊐̸"; -var NotSquareSupersetEqual = "⋣"; -var NotSubset = "⊂⃒"; -var NotSubsetEqual = "⊈"; -var NotSucceeds = "⊁"; -var NotSucceedsEqual = "⪰̸"; -var NotSucceedsSlantEqual = "⋡"; -var NotSucceedsTilde = "≿̸"; -var NotSuperset = "⊃⃒"; -var NotSupersetEqual = "⊉"; -var NotTilde = "≁"; -var NotTildeEqual = "≄"; -var NotTildeFullEqual = "≇"; -var NotTildeTilde = "≉"; -var NotVerticalBar = "∤"; -var Nscr = "𝒩"; -var Ntild = "Ñ"; -var Ntilde = "Ñ"; -var Nu = "Ν"; -var OElig = "Œ"; -var Oacut = "Ó"; -var Oacute = "Ó"; -var Ocir = "Ô"; -var Ocirc = "Ô"; -var Ocy = "О"; -var Odblac = "Ő"; -var Ofr = "𝔒"; -var Ograv = "Ò"; -var Ograve = "Ò"; -var Omacr = "Ō"; -var Omega = "Ω"; -var Omicron = "Ο"; -var Oopf = "𝕆"; -var OpenCurlyDoubleQuote = "“"; -var OpenCurlyQuote = "‘"; -var Or = "⩔"; -var Oscr = "𝒪"; -var Oslas = "Ø"; -var Oslash = "Ø"; -var Otild = "Õ"; -var Otilde = "Õ"; -var Otimes = "⨷"; -var Oum = "Ö"; -var Ouml = "Ö"; -var OverBar = "‾"; -var OverBrace = "⏞"; -var OverBracket = "⎴"; -var OverParenthesis = "⏜"; -var PartialD = "∂"; -var Pcy = "П"; -var Pfr = "𝔓"; -var Phi = "Φ"; -var Pi = "Π"; -var PlusMinus = "±"; -var Poincareplane = "ℌ"; -var Popf = "ℙ"; -var Pr = "⪻"; -var Precedes = "≺"; -var PrecedesEqual = "⪯"; -var PrecedesSlantEqual = "≼"; -var PrecedesTilde = "≾"; -var Prime = "″"; -var Product = "∏"; -var Proportion = "∷"; -var Proportional = "∝"; -var Pscr = "𝒫"; -var Psi = "Ψ"; -var QUO = "\""; -var QUOT = "\""; -var Qfr = "𝔔"; -var Qopf = "ℚ"; -var Qscr = "𝒬"; -var RBarr = "⤐"; -var RE = "®"; -var REG = "®"; -var Racute = "Ŕ"; -var Rang = "⟫"; -var Rarr = "↠"; -var Rarrtl = "⤖"; -var Rcaron = "Ř"; -var Rcedil = "Ŗ"; -var Rcy = "Р"; -var Re = "ℜ"; -var ReverseElement = "∋"; -var ReverseEquilibrium = "⇋"; -var ReverseUpEquilibrium = "⥯"; -var Rfr = "ℜ"; -var Rho = "Ρ"; -var RightAngleBracket = "⟩"; -var RightArrow = "→"; -var RightArrowBar = "⇥"; -var RightArrowLeftArrow = "⇄"; -var RightCeiling = "⌉"; -var RightDoubleBracket = "⟧"; -var RightDownTeeVector = "⥝"; -var RightDownVector = "⇂"; -var RightDownVectorBar = "⥕"; -var RightFloor = "⌋"; -var RightTee = "⊢"; -var RightTeeArrow = "↦"; -var RightTeeVector = "⥛"; -var RightTriangle = "⊳"; -var RightTriangleBar = "⧐"; -var RightTriangleEqual = "⊵"; -var RightUpDownVector = "⥏"; -var RightUpTeeVector = "⥜"; -var RightUpVector = "↾"; -var RightUpVectorBar = "⥔"; -var RightVector = "⇀"; -var RightVectorBar = "⥓"; -var Rightarrow = "⇒"; -var Ropf = "ℝ"; -var RoundImplies = "⥰"; -var Rrightarrow = "⇛"; -var Rscr = "ℛ"; -var Rsh = "↱"; -var RuleDelayed = "⧴"; -var SHCHcy = "Щ"; -var SHcy = "Ш"; -var SOFTcy = "Ь"; -var Sacute = "Ś"; -var Sc = "⪼"; -var Scaron = "Š"; -var Scedil = "Ş"; -var Scirc = "Ŝ"; -var Scy = "С"; -var Sfr = "𝔖"; -var ShortDownArrow = "↓"; -var ShortLeftArrow = "←"; -var ShortRightArrow = "→"; -var ShortUpArrow = "↑"; -var Sigma = "Σ"; -var SmallCircle = "∘"; -var Sopf = "𝕊"; -var Sqrt = "√"; -var Square = "□"; -var SquareIntersection = "⊓"; -var SquareSubset = "⊏"; -var SquareSubsetEqual = "⊑"; -var SquareSuperset = "⊐"; -var SquareSupersetEqual = "⊒"; -var SquareUnion = "⊔"; -var Sscr = "𝒮"; -var Star = "⋆"; -var Sub = "⋐"; -var Subset = "⋐"; -var SubsetEqual = "⊆"; -var Succeeds = "≻"; -var SucceedsEqual = "⪰"; -var SucceedsSlantEqual = "≽"; -var SucceedsTilde = "≿"; -var SuchThat = "∋"; -var Sum = "∑"; -var Sup = "⋑"; -var Superset = "⊃"; -var SupersetEqual = "⊇"; -var Supset = "⋑"; -var THOR = "Þ"; -var THORN = "Þ"; -var TRADE = "™"; -var TSHcy = "Ћ"; -var TScy = "Ц"; -var Tab = "\t"; -var Tau = "Τ"; -var Tcaron = "Ť"; -var Tcedil = "Ţ"; -var Tcy = "Т"; -var Tfr = "𝔗"; -var Therefore = "∴"; -var Theta = "Θ"; -var ThickSpace = "  "; -var ThinSpace = " "; -var Tilde = "∼"; -var TildeEqual = "≃"; -var TildeFullEqual = "≅"; -var TildeTilde = "≈"; -var Topf = "𝕋"; -var TripleDot = "⃛"; -var Tscr = "𝒯"; -var Tstrok = "Ŧ"; -var Uacut = "Ú"; -var Uacute = "Ú"; -var Uarr = "↟"; -var Uarrocir = "⥉"; -var Ubrcy = "Ў"; -var Ubreve = "Ŭ"; -var Ucir = "Û"; -var Ucirc = "Û"; -var Ucy = "У"; -var Udblac = "Ű"; -var Ufr = "𝔘"; -var Ugrav = "Ù"; -var Ugrave = "Ù"; -var Umacr = "Ū"; -var UnderBar = "_"; -var UnderBrace = "⏟"; -var UnderBracket = "⎵"; -var UnderParenthesis = "⏝"; -var Union = "⋃"; -var UnionPlus = "⊎"; -var Uogon = "Ų"; -var Uopf = "𝕌"; -var UpArrow = "↑"; -var UpArrowBar = "⤒"; -var UpArrowDownArrow = "⇅"; -var UpDownArrow = "↕"; -var UpEquilibrium = "⥮"; -var UpTee = "⊥"; -var UpTeeArrow = "↥"; -var Uparrow = "⇑"; -var Updownarrow = "⇕"; -var UpperLeftArrow = "↖"; -var UpperRightArrow = "↗"; -var Upsi = "ϒ"; -var Upsilon = "Υ"; -var Uring = "Ů"; -var Uscr = "𝒰"; -var Utilde = "Ũ"; -var Uum = "Ü"; -var Uuml = "Ü"; -var VDash = "⊫"; -var Vbar = "⫫"; -var Vcy = "В"; -var Vdash = "⊩"; -var Vdashl = "⫦"; -var Vee = "⋁"; -var Verbar = "‖"; -var Vert = "‖"; -var VerticalBar = "∣"; -var VerticalLine = "|"; -var VerticalSeparator = "❘"; -var VerticalTilde = "≀"; -var VeryThinSpace = " "; -var Vfr = "𝔙"; -var Vopf = "𝕍"; -var Vscr = "𝒱"; -var Vvdash = "⊪"; -var Wcirc = "Ŵ"; -var Wedge = "⋀"; -var Wfr = "𝔚"; -var Wopf = "𝕎"; -var Wscr = "𝒲"; -var Xfr = "𝔛"; -var Xi = "Ξ"; -var Xopf = "𝕏"; -var Xscr = "𝒳"; -var YAcy = "Я"; -var YIcy = "Ї"; -var YUcy = "Ю"; -var Yacut = "Ý"; -var Yacute = "Ý"; -var Ycirc = "Ŷ"; -var Ycy = "Ы"; -var Yfr = "𝔜"; -var Yopf = "𝕐"; -var Yscr = "𝒴"; -var Yuml = "Ÿ"; -var ZHcy = "Ж"; -var Zacute = "Ź"; -var Zcaron = "Ž"; -var Zcy = "З"; -var Zdot = "Ż"; -var ZeroWidthSpace = "​"; -var Zeta = "Ζ"; -var Zfr = "ℨ"; -var Zopf = "ℤ"; -var Zscr = "𝒵"; -var aacut = "á"; -var aacute = "á"; -var abreve = "ă"; -var ac = "∾"; -var acE = "∾̳"; -var acd = "∿"; -var acir = "â"; -var acirc = "â"; -var acut = "´"; -var acute = "´"; -var acy = "а"; -var aeli = "æ"; -var aelig = "æ"; -var af = "⁡"; -var afr = "𝔞"; -var agrav = "à"; -var agrave = "à"; -var alefsym = "ℵ"; -var aleph = "ℵ"; -var alpha = "α"; -var amacr = "ā"; -var amalg = "⨿"; -var am = "&"; -var amp = "&"; -var and = "∧"; -var andand = "⩕"; -var andd = "⩜"; -var andslope = "⩘"; -var andv = "⩚"; -var ang = "∠"; -var ange = "⦤"; -var angle = "∠"; -var angmsd = "∡"; -var angmsdaa = "⦨"; -var angmsdab = "⦩"; -var angmsdac = "⦪"; -var angmsdad = "⦫"; -var angmsdae = "⦬"; -var angmsdaf = "⦭"; -var angmsdag = "⦮"; -var angmsdah = "⦯"; -var angrt = "∟"; -var angrtvb = "⊾"; -var angrtvbd = "⦝"; -var angsph = "∢"; -var angst = "Å"; -var angzarr = "⍼"; -var aogon = "ą"; -var aopf = "𝕒"; -var ap = "≈"; -var apE = "⩰"; -var apacir = "⩯"; -var ape = "≊"; -var apid = "≋"; -var apos = "'"; -var approx = "≈"; -var approxeq = "≊"; -var arin = "å"; -var aring = "å"; -var ascr = "𝒶"; -var ast = "*"; -var asymp = "≈"; -var asympeq = "≍"; -var atild = "ã"; -var atilde = "ã"; -var aum = "ä"; -var auml = "ä"; -var awconint = "∳"; -var awint = "⨑"; -var bNot = "⫭"; -var backcong = "≌"; -var backepsilon = "϶"; -var backprime = "‵"; -var backsim = "∽"; -var backsimeq = "⋍"; -var barvee = "⊽"; -var barwed = "⌅"; -var barwedge = "⌅"; -var bbrk = "⎵"; -var bbrktbrk = "⎶"; -var bcong = "≌"; -var bcy = "б"; -var bdquo = "„"; -var becaus = "∵"; -var because = "∵"; -var bemptyv = "⦰"; -var bepsi = "϶"; -var bernou = "ℬ"; -var beta = "β"; -var beth = "ℶ"; -var between = "≬"; -var bfr = "𝔟"; -var bigcap = "⋂"; -var bigcirc = "◯"; -var bigcup = "⋃"; -var bigodot = "⨀"; -var bigoplus = "⨁"; -var bigotimes = "⨂"; -var bigsqcup = "⨆"; -var bigstar = "★"; -var bigtriangledown = "▽"; -var bigtriangleup = "△"; -var biguplus = "⨄"; -var bigvee = "⋁"; -var bigwedge = "⋀"; -var bkarow = "⤍"; -var blacklozenge = "⧫"; -var blacksquare = "▪"; -var blacktriangle = "▴"; -var blacktriangledown = "▾"; -var blacktriangleleft = "◂"; -var blacktriangleright = "▸"; -var blank = "␣"; -var blk12 = "▒"; -var blk14 = "░"; -var blk34 = "▓"; -var block = "█"; -var bne = "=⃥"; -var bnequiv = "≡⃥"; -var bnot = "⌐"; -var bopf = "𝕓"; -var bot = "⊥"; -var bottom = "⊥"; -var bowtie = "⋈"; -var boxDL = "╗"; -var boxDR = "╔"; -var boxDl = "╖"; -var boxDr = "╓"; -var boxH = "═"; -var boxHD = "╦"; -var boxHU = "╩"; -var boxHd = "╤"; -var boxHu = "╧"; -var boxUL = "╝"; -var boxUR = "╚"; -var boxUl = "╜"; -var boxUr = "╙"; -var boxV = "║"; -var boxVH = "╬"; -var boxVL = "╣"; -var boxVR = "╠"; -var boxVh = "╫"; -var boxVl = "╢"; -var boxVr = "╟"; -var boxbox = "⧉"; -var boxdL = "╕"; -var boxdR = "╒"; -var boxdl = "┐"; -var boxdr = "┌"; -var boxh = "─"; -var boxhD = "╥"; -var boxhU = "╨"; -var boxhd = "┬"; -var boxhu = "┴"; -var boxminus = "⊟"; -var boxplus = "⊞"; -var boxtimes = "⊠"; -var boxuL = "╛"; -var boxuR = "╘"; -var boxul = "┘"; -var boxur = "└"; -var boxv = "│"; -var boxvH = "╪"; -var boxvL = "╡"; -var boxvR = "╞"; -var boxvh = "┼"; -var boxvl = "┤"; -var boxvr = "├"; -var bprime = "‵"; -var breve = "˘"; -var brvba = "¦"; -var brvbar = "¦"; -var bscr = "𝒷"; -var bsemi = "⁏"; -var bsim = "∽"; -var bsime = "⋍"; -var bsol = "\\"; -var bsolb = "⧅"; -var bsolhsub = "⟈"; -var bull = "•"; -var bullet = "•"; -var bump = "≎"; -var bumpE = "⪮"; -var bumpe = "≏"; -var bumpeq = "≏"; -var cacute = "ć"; -var cap = "∩"; -var capand = "⩄"; -var capbrcup = "⩉"; -var capcap = "⩋"; -var capcup = "⩇"; -var capdot = "⩀"; -var caps = "∩︀"; -var caret = "⁁"; -var caron = "ˇ"; -var ccaps = "⩍"; -var ccaron = "č"; -var ccedi = "ç"; -var ccedil = "ç"; -var ccirc = "ĉ"; -var ccups = "⩌"; -var ccupssm = "⩐"; -var cdot = "ċ"; -var cedi = "¸"; -var cedil = "¸"; -var cemptyv = "⦲"; -var cen = "¢"; -var cent = "¢"; -var centerdot = "·"; -var cfr = "𝔠"; -var chcy = "ч"; -var check = "✓"; -var checkmark = "✓"; -var chi = "χ"; -var cir = "○"; -var cirE = "⧃"; -var circ = "ˆ"; -var circeq = "≗"; -var circlearrowleft = "↺"; -var circlearrowright = "↻"; -var circledR = "®"; -var circledS = "Ⓢ"; -var circledast = "⊛"; -var circledcirc = "⊚"; -var circleddash = "⊝"; -var cire = "≗"; -var cirfnint = "⨐"; -var cirmid = "⫯"; -var cirscir = "⧂"; -var clubs = "♣"; -var clubsuit = "♣"; -var colon = ":"; -var colone = "≔"; -var coloneq = "≔"; -var comma = ","; -var commat = "@"; -var comp = "∁"; -var compfn = "∘"; -var complement = "∁"; -var complexes = "ℂ"; -var cong = "≅"; -var congdot = "⩭"; -var conint = "∮"; -var copf = "𝕔"; -var coprod = "∐"; -var cop = "©"; -var copy = "©"; -var copysr = "℗"; -var crarr = "↵"; -var cross = "✗"; -var cscr = "𝒸"; -var csub = "⫏"; -var csube = "⫑"; -var csup = "⫐"; -var csupe = "⫒"; -var ctdot = "⋯"; -var cudarrl = "⤸"; -var cudarrr = "⤵"; -var cuepr = "⋞"; -var cuesc = "⋟"; -var cularr = "↶"; -var cularrp = "⤽"; -var cup = "∪"; -var cupbrcap = "⩈"; -var cupcap = "⩆"; -var cupcup = "⩊"; -var cupdot = "⊍"; -var cupor = "⩅"; -var cups = "∪︀"; -var curarr = "↷"; -var curarrm = "⤼"; -var curlyeqprec = "⋞"; -var curlyeqsucc = "⋟"; -var curlyvee = "⋎"; -var curlywedge = "⋏"; -var curre = "¤"; -var curren = "¤"; -var curvearrowleft = "↶"; -var curvearrowright = "↷"; -var cuvee = "⋎"; -var cuwed = "⋏"; -var cwconint = "∲"; -var cwint = "∱"; -var cylcty = "⌭"; -var dArr = "⇓"; -var dHar = "⥥"; -var dagger = "†"; -var daleth = "ℸ"; -var darr = "↓"; -var dash = "‐"; -var dashv = "⊣"; -var dbkarow = "⤏"; -var dblac = "˝"; -var dcaron = "ď"; -var dcy = "д"; -var dd = "ⅆ"; -var ddagger = "‡"; -var ddarr = "⇊"; -var ddotseq = "⩷"; -var de = "°"; -var deg = "°"; -var delta = "δ"; -var demptyv = "⦱"; -var dfisht = "⥿"; -var dfr = "𝔡"; -var dharl = "⇃"; -var dharr = "⇂"; -var diam = "⋄"; -var diamond = "⋄"; -var diamondsuit = "♦"; -var diams = "♦"; -var die = "¨"; -var digamma = "ϝ"; -var disin = "⋲"; -var div = "÷"; -var divid = "÷"; -var divide = "÷"; -var divideontimes = "⋇"; -var divonx = "⋇"; -var djcy = "ђ"; -var dlcorn = "⌞"; -var dlcrop = "⌍"; -var dollar = "$"; -var dopf = "𝕕"; -var dot = "˙"; -var doteq = "≐"; -var doteqdot = "≑"; -var dotminus = "∸"; -var dotplus = "∔"; -var dotsquare = "⊡"; -var doublebarwedge = "⌆"; -var downarrow = "↓"; -var downdownarrows = "⇊"; -var downharpoonleft = "⇃"; -var downharpoonright = "⇂"; -var drbkarow = "⤐"; -var drcorn = "⌟"; -var drcrop = "⌌"; -var dscr = "𝒹"; -var dscy = "ѕ"; -var dsol = "⧶"; -var dstrok = "đ"; -var dtdot = "⋱"; -var dtri = "▿"; -var dtrif = "▾"; -var duarr = "⇵"; -var duhar = "⥯"; -var dwangle = "⦦"; -var dzcy = "џ"; -var dzigrarr = "⟿"; -var eDDot = "⩷"; -var eDot = "≑"; -var eacut = "é"; -var eacute = "é"; -var easter = "⩮"; -var ecaron = "ě"; -var ecir = "ê"; -var ecirc = "ê"; -var ecolon = "≕"; -var ecy = "э"; -var edot = "ė"; -var ee = "ⅇ"; -var efDot = "≒"; -var efr = "𝔢"; -var eg = "⪚"; -var egrav = "è"; -var egrave = "è"; -var egs = "⪖"; -var egsdot = "⪘"; -var el = "⪙"; -var elinters = "⏧"; -var ell = "ℓ"; -var els = "⪕"; -var elsdot = "⪗"; -var emacr = "ē"; -var empty = "∅"; -var emptyset = "∅"; -var emptyv = "∅"; -var emsp13 = " "; -var emsp14 = " "; -var emsp = " "; -var eng = "ŋ"; -var ensp = " "; -var eogon = "ę"; -var eopf = "𝕖"; -var epar = "⋕"; -var eparsl = "⧣"; -var eplus = "⩱"; -var epsi = "ε"; -var epsilon = "ε"; -var epsiv = "ϵ"; -var eqcirc = "≖"; -var eqcolon = "≕"; -var eqsim = "≂"; -var eqslantgtr = "⪖"; -var eqslantless = "⪕"; -var equals = "="; -var equest = "≟"; -var equiv = "≡"; -var equivDD = "⩸"; -var eqvparsl = "⧥"; -var erDot = "≓"; -var erarr = "⥱"; -var escr = "ℯ"; -var esdot = "≐"; -var esim = "≂"; -var eta = "η"; -var et = "ð"; -var eth = "ð"; -var eum = "ë"; -var euml = "ë"; -var euro = "€"; -var excl = "!"; -var exist = "∃"; -var expectation = "ℰ"; -var exponentiale = "ⅇ"; -var fallingdotseq = "≒"; -var fcy = "ф"; -var female = "♀"; -var ffilig = "ffi"; -var fflig = "ff"; -var ffllig = "ffl"; -var ffr = "𝔣"; -var filig = "fi"; -var fjlig = "fj"; -var flat = "♭"; -var fllig = "fl"; -var fltns = "▱"; -var fnof = "ƒ"; -var fopf = "𝕗"; -var forall = "∀"; -var fork = "⋔"; -var forkv = "⫙"; -var fpartint = "⨍"; -var frac1 = "¼"; -var frac12 = "½"; -var frac13 = "⅓"; -var frac14 = "¼"; -var frac15 = "⅕"; -var frac16 = "⅙"; -var frac18 = "⅛"; -var frac23 = "⅔"; -var frac25 = "⅖"; -var frac3 = "¾"; -var frac34 = "¾"; -var frac35 = "⅗"; -var frac38 = "⅜"; -var frac45 = "⅘"; -var frac56 = "⅚"; -var frac58 = "⅝"; -var frac78 = "⅞"; -var frasl = "⁄"; -var frown = "⌢"; -var fscr = "𝒻"; -var gE = "≧"; -var gEl = "⪌"; -var gacute = "ǵ"; -var gamma = "γ"; -var gammad = "ϝ"; -var gap = "⪆"; -var gbreve = "ğ"; -var gcirc = "ĝ"; -var gcy = "г"; -var gdot = "ġ"; -var ge = "≥"; -var gel = "⋛"; -var geq = "≥"; -var geqq = "≧"; -var geqslant = "⩾"; -var ges = "⩾"; -var gescc = "⪩"; -var gesdot = "⪀"; -var gesdoto = "⪂"; -var gesdotol = "⪄"; -var gesl = "⋛︀"; -var gesles = "⪔"; -var gfr = "𝔤"; -var gg = "≫"; -var ggg = "⋙"; -var gimel = "ℷ"; -var gjcy = "ѓ"; -var gl = "≷"; -var glE = "⪒"; -var gla = "⪥"; -var glj = "⪤"; -var gnE = "≩"; -var gnap = "⪊"; -var gnapprox = "⪊"; -var gne = "⪈"; -var gneq = "⪈"; -var gneqq = "≩"; -var gnsim = "⋧"; -var gopf = "𝕘"; -var grave = "`"; -var gscr = "ℊ"; -var gsim = "≳"; -var gsime = "⪎"; -var gsiml = "⪐"; -var g = ">"; -var gt = ">"; -var gtcc = "⪧"; -var gtcir = "⩺"; -var gtdot = "⋗"; -var gtlPar = "⦕"; -var gtquest = "⩼"; -var gtrapprox = "⪆"; -var gtrarr = "⥸"; -var gtrdot = "⋗"; -var gtreqless = "⋛"; -var gtreqqless = "⪌"; -var gtrless = "≷"; -var gtrsim = "≳"; -var gvertneqq = "≩︀"; -var gvnE = "≩︀"; -var hArr = "⇔"; -var hairsp = " "; -var half = "½"; -var hamilt = "ℋ"; -var hardcy = "ъ"; -var harr = "↔"; -var harrcir = "⥈"; -var harrw = "↭"; -var hbar = "ℏ"; -var hcirc = "ĥ"; -var hearts = "♥"; -var heartsuit = "♥"; -var hellip = "…"; -var hercon = "⊹"; -var hfr = "𝔥"; -var hksearow = "⤥"; -var hkswarow = "⤦"; -var hoarr = "⇿"; -var homtht = "∻"; -var hookleftarrow = "↩"; -var hookrightarrow = "↪"; -var hopf = "𝕙"; -var horbar = "―"; -var hscr = "𝒽"; -var hslash = "ℏ"; -var hstrok = "ħ"; -var hybull = "⁃"; -var hyphen = "‐"; -var iacut = "í"; -var iacute = "í"; -var ic = "⁣"; -var icir = "î"; -var icirc = "î"; -var icy = "и"; -var iecy = "е"; -var iexc = "¡"; -var iexcl = "¡"; -var iff = "⇔"; -var ifr = "𝔦"; -var igrav = "ì"; -var igrave = "ì"; -var ii = "ⅈ"; -var iiiint = "⨌"; -var iiint = "∭"; -var iinfin = "⧜"; -var iiota = "℩"; -var ijlig = "ij"; -var imacr = "ī"; -var image = "ℑ"; -var imagline = "ℐ"; -var imagpart = "ℑ"; -var imath = "ı"; -var imof = "⊷"; -var imped = "Ƶ"; -var incare = "℅"; -var infin = "∞"; -var infintie = "⧝"; -var inodot = "ı"; -var int = "∫"; -var intcal = "⊺"; -var integers = "ℤ"; -var intercal = "⊺"; -var intlarhk = "⨗"; -var intprod = "⨼"; -var iocy = "ё"; -var iogon = "į"; -var iopf = "𝕚"; -var iota = "ι"; -var iprod = "⨼"; -var iques = "¿"; -var iquest = "¿"; -var iscr = "𝒾"; -var isin = "∈"; -var isinE = "⋹"; -var isindot = "⋵"; -var isins = "⋴"; -var isinsv = "⋳"; -var isinv = "∈"; -var it = "⁢"; -var itilde = "ĩ"; -var iukcy = "і"; -var ium = "ï"; -var iuml = "ï"; -var jcirc = "ĵ"; -var jcy = "й"; -var jfr = "𝔧"; -var jmath = "ȷ"; -var jopf = "𝕛"; -var jscr = "𝒿"; -var jsercy = "ј"; -var jukcy = "є"; -var kappa = "κ"; -var kappav = "ϰ"; -var kcedil = "ķ"; -var kcy = "к"; -var kfr = "𝔨"; -var kgreen = "ĸ"; -var khcy = "х"; -var kjcy = "ќ"; -var kopf = "𝕜"; -var kscr = "𝓀"; -var lAarr = "⇚"; -var lArr = "⇐"; -var lAtail = "⤛"; -var lBarr = "⤎"; -var lE = "≦"; -var lEg = "⪋"; -var lHar = "⥢"; -var lacute = "ĺ"; -var laemptyv = "⦴"; -var lagran = "ℒ"; -var lambda = "λ"; -var lang = "⟨"; -var langd = "⦑"; -var langle = "⟨"; -var lap = "⪅"; -var laqu = "«"; -var laquo = "«"; -var larr = "←"; -var larrb = "⇤"; -var larrbfs = "⤟"; -var larrfs = "⤝"; -var larrhk = "↩"; -var larrlp = "↫"; -var larrpl = "⤹"; -var larrsim = "⥳"; -var larrtl = "↢"; -var lat = "⪫"; -var latail = "⤙"; -var late = "⪭"; -var lates = "⪭︀"; -var lbarr = "⤌"; -var lbbrk = "❲"; -var lbrace = "{"; -var lbrack = "["; -var lbrke = "⦋"; -var lbrksld = "⦏"; -var lbrkslu = "⦍"; -var lcaron = "ľ"; -var lcedil = "ļ"; -var lceil = "⌈"; -var lcub = "{"; -var lcy = "л"; -var ldca = "⤶"; -var ldquo = "“"; -var ldquor = "„"; -var ldrdhar = "⥧"; -var ldrushar = "⥋"; -var ldsh = "↲"; -var le = "≤"; -var leftarrow = "←"; -var leftarrowtail = "↢"; -var leftharpoondown = "↽"; -var leftharpoonup = "↼"; -var leftleftarrows = "⇇"; -var leftrightarrow = "↔"; -var leftrightarrows = "⇆"; -var leftrightharpoons = "⇋"; -var leftrightsquigarrow = "↭"; -var leftthreetimes = "⋋"; -var leg = "⋚"; -var leq = "≤"; -var leqq = "≦"; -var leqslant = "⩽"; -var les = "⩽"; -var lescc = "⪨"; -var lesdot = "⩿"; -var lesdoto = "⪁"; -var lesdotor = "⪃"; -var lesg = "⋚︀"; -var lesges = "⪓"; -var lessapprox = "⪅"; -var lessdot = "⋖"; -var lesseqgtr = "⋚"; -var lesseqqgtr = "⪋"; -var lessgtr = "≶"; -var lesssim = "≲"; -var lfisht = "⥼"; -var lfloor = "⌊"; -var lfr = "𝔩"; -var lg = "≶"; -var lgE = "⪑"; -var lhard = "↽"; -var lharu = "↼"; -var lharul = "⥪"; -var lhblk = "▄"; -var ljcy = "љ"; -var ll = "≪"; -var llarr = "⇇"; -var llcorner = "⌞"; -var llhard = "⥫"; -var lltri = "◺"; -var lmidot = "ŀ"; -var lmoust = "⎰"; -var lmoustache = "⎰"; -var lnE = "≨"; -var lnap = "⪉"; -var lnapprox = "⪉"; -var lne = "⪇"; -var lneq = "⪇"; -var lneqq = "≨"; -var lnsim = "⋦"; -var loang = "⟬"; -var loarr = "⇽"; -var lobrk = "⟦"; -var longleftarrow = "⟵"; -var longleftrightarrow = "⟷"; -var longmapsto = "⟼"; -var longrightarrow = "⟶"; -var looparrowleft = "↫"; -var looparrowright = "↬"; -var lopar = "⦅"; -var lopf = "𝕝"; -var loplus = "⨭"; -var lotimes = "⨴"; -var lowast = "∗"; -var lowbar = "_"; -var loz = "◊"; -var lozenge = "◊"; -var lozf = "⧫"; -var lpar = "("; -var lparlt = "⦓"; -var lrarr = "⇆"; -var lrcorner = "⌟"; -var lrhar = "⇋"; -var lrhard = "⥭"; -var lrm = "‎"; -var lrtri = "⊿"; -var lsaquo = "‹"; -var lscr = "𝓁"; -var lsh = "↰"; -var lsim = "≲"; -var lsime = "⪍"; -var lsimg = "⪏"; -var lsqb = "["; -var lsquo = "‘"; -var lsquor = "‚"; -var lstrok = "ł"; -var l = "<"; -var lt = "<"; -var ltcc = "⪦"; -var ltcir = "⩹"; -var ltdot = "⋖"; -var lthree = "⋋"; -var ltimes = "⋉"; -var ltlarr = "⥶"; -var ltquest = "⩻"; -var ltrPar = "⦖"; -var ltri = "◃"; -var ltrie = "⊴"; -var ltrif = "◂"; -var lurdshar = "⥊"; -var luruhar = "⥦"; -var lvertneqq = "≨︀"; -var lvnE = "≨︀"; -var mDDot = "∺"; -var mac = "¯"; -var macr = "¯"; -var male = "♂"; -var malt = "✠"; -var maltese = "✠"; -var map = "↦"; -var mapsto = "↦"; -var mapstodown = "↧"; -var mapstoleft = "↤"; -var mapstoup = "↥"; -var marker = "▮"; -var mcomma = "⨩"; -var mcy = "м"; -var mdash = "—"; -var measuredangle = "∡"; -var mfr = "𝔪"; -var mho = "℧"; -var micr = "µ"; -var micro = "µ"; -var mid = "∣"; -var midast = "*"; -var midcir = "⫰"; -var middo = "·"; -var middot = "·"; -var minus = "−"; -var minusb = "⊟"; -var minusd = "∸"; -var minusdu = "⨪"; -var mlcp = "⫛"; -var mldr = "…"; -var mnplus = "∓"; -var models = "⊧"; -var mopf = "𝕞"; -var mp = "∓"; -var mscr = "𝓂"; -var mstpos = "∾"; -var mu = "μ"; -var multimap = "⊸"; -var mumap = "⊸"; -var nGg = "⋙̸"; -var nGt = "≫⃒"; -var nGtv = "≫̸"; -var nLeftarrow = "⇍"; -var nLeftrightarrow = "⇎"; -var nLl = "⋘̸"; -var nLt = "≪⃒"; -var nLtv = "≪̸"; -var nRightarrow = "⇏"; -var nVDash = "⊯"; -var nVdash = "⊮"; -var nabla = "∇"; -var nacute = "ń"; -var nang = "∠⃒"; -var nap = "≉"; -var napE = "⩰̸"; -var napid = "≋̸"; -var napos = "ʼn"; -var napprox = "≉"; -var natur = "♮"; -var natural = "♮"; -var naturals = "ℕ"; -var nbs = " "; -var nbsp = " "; -var nbump = "≎̸"; -var nbumpe = "≏̸"; -var ncap = "⩃"; -var ncaron = "ň"; -var ncedil = "ņ"; -var ncong = "≇"; -var ncongdot = "⩭̸"; -var ncup = "⩂"; -var ncy = "н"; -var ndash = "–"; -var ne = "≠"; -var neArr = "⇗"; -var nearhk = "⤤"; -var nearr = "↗"; -var nearrow = "↗"; -var nedot = "≐̸"; -var nequiv = "≢"; -var nesear = "⤨"; -var nesim = "≂̸"; -var nexist = "∄"; -var nexists = "∄"; -var nfr = "𝔫"; -var ngE = "≧̸"; -var nge = "≱"; -var ngeq = "≱"; -var ngeqq = "≧̸"; -var ngeqslant = "⩾̸"; -var nges = "⩾̸"; -var ngsim = "≵"; -var ngt = "≯"; -var ngtr = "≯"; -var nhArr = "⇎"; -var nharr = "↮"; -var nhpar = "⫲"; -var ni = "∋"; -var nis = "⋼"; -var nisd = "⋺"; -var niv = "∋"; -var njcy = "њ"; -var nlArr = "⇍"; -var nlE = "≦̸"; -var nlarr = "↚"; -var nldr = "‥"; -var nle = "≰"; -var nleftarrow = "↚"; -var nleftrightarrow = "↮"; -var nleq = "≰"; -var nleqq = "≦̸"; -var nleqslant = "⩽̸"; -var nles = "⩽̸"; -var nless = "≮"; -var nlsim = "≴"; -var nlt = "≮"; -var nltri = "⋪"; -var nltrie = "⋬"; -var nmid = "∤"; -var nopf = "𝕟"; -var no = "¬"; -var not = "¬"; -var notin = "∉"; -var notinE = "⋹̸"; -var notindot = "⋵̸"; -var notinva = "∉"; -var notinvb = "⋷"; -var notinvc = "⋶"; -var notni = "∌"; -var notniva = "∌"; -var notnivb = "⋾"; -var notnivc = "⋽"; -var npar = "∦"; -var nparallel = "∦"; -var nparsl = "⫽⃥"; -var npart = "∂̸"; -var npolint = "⨔"; -var npr = "⊀"; -var nprcue = "⋠"; -var npre = "⪯̸"; -var nprec = "⊀"; -var npreceq = "⪯̸"; -var nrArr = "⇏"; -var nrarr = "↛"; -var nrarrc = "⤳̸"; -var nrarrw = "↝̸"; -var nrightarrow = "↛"; -var nrtri = "⋫"; -var nrtrie = "⋭"; -var nsc = "⊁"; -var nsccue = "⋡"; -var nsce = "⪰̸"; -var nscr = "𝓃"; -var nshortmid = "∤"; -var nshortparallel = "∦"; -var nsim = "≁"; -var nsime = "≄"; -var nsimeq = "≄"; -var nsmid = "∤"; -var nspar = "∦"; -var nsqsube = "⋢"; -var nsqsupe = "⋣"; -var nsub = "⊄"; -var nsubE = "⫅̸"; -var nsube = "⊈"; -var nsubset = "⊂⃒"; -var nsubseteq = "⊈"; -var nsubseteqq = "⫅̸"; -var nsucc = "⊁"; -var nsucceq = "⪰̸"; -var nsup = "⊅"; -var nsupE = "⫆̸"; -var nsupe = "⊉"; -var nsupset = "⊃⃒"; -var nsupseteq = "⊉"; -var nsupseteqq = "⫆̸"; -var ntgl = "≹"; -var ntild = "ñ"; -var ntilde = "ñ"; -var ntlg = "≸"; -var ntriangleleft = "⋪"; -var ntrianglelefteq = "⋬"; -var ntriangleright = "⋫"; -var ntrianglerighteq = "⋭"; -var nu = "ν"; -var num = "#"; -var numero = "№"; -var numsp = " "; -var nvDash = "⊭"; -var nvHarr = "⤄"; -var nvap = "≍⃒"; -var nvdash = "⊬"; -var nvge = "≥⃒"; -var nvgt = ">⃒"; -var nvinfin = "⧞"; -var nvlArr = "⤂"; -var nvle = "≤⃒"; -var nvlt = "<⃒"; -var nvltrie = "⊴⃒"; -var nvrArr = "⤃"; -var nvrtrie = "⊵⃒"; -var nvsim = "∼⃒"; -var nwArr = "⇖"; -var nwarhk = "⤣"; -var nwarr = "↖"; -var nwarrow = "↖"; -var nwnear = "⤧"; -var oS = "Ⓢ"; -var oacut = "ó"; -var oacute = "ó"; -var oast = "⊛"; -var ocir = "ô"; -var ocirc = "ô"; -var ocy = "о"; -var odash = "⊝"; -var odblac = "ő"; -var odiv = "⨸"; -var odot = "⊙"; -var odsold = "⦼"; -var oelig = "œ"; -var ofcir = "⦿"; -var ofr = "𝔬"; -var ogon = "˛"; -var ograv = "ò"; -var ograve = "ò"; -var ogt = "⧁"; -var ohbar = "⦵"; -var ohm = "Ω"; -var oint = "∮"; -var olarr = "↺"; -var olcir = "⦾"; -var olcross = "⦻"; -var oline = "‾"; -var olt = "⧀"; -var omacr = "ō"; -var omega = "ω"; -var omicron = "ο"; -var omid = "⦶"; -var ominus = "⊖"; -var oopf = "𝕠"; -var opar = "⦷"; -var operp = "⦹"; -var oplus = "⊕"; -var or = "∨"; -var orarr = "↻"; -var ord = "º"; -var order = "ℴ"; -var orderof = "ℴ"; -var ordf = "ª"; -var ordm = "º"; -var origof = "⊶"; -var oror = "⩖"; -var orslope = "⩗"; -var orv = "⩛"; -var oscr = "ℴ"; -var oslas = "ø"; -var oslash = "ø"; -var osol = "⊘"; -var otild = "õ"; -var otilde = "õ"; -var otimes = "⊗"; -var otimesas = "⨶"; -var oum = "ö"; -var ouml = "ö"; -var ovbar = "⌽"; -var par = "¶"; -var para = "¶"; -var parallel = "∥"; -var parsim = "⫳"; -var parsl = "⫽"; -var part = "∂"; -var pcy = "п"; -var percnt = "%"; -var period = "."; -var permil = "‰"; -var perp = "⊥"; -var pertenk = "‱"; -var pfr = "𝔭"; -var phi = "φ"; -var phiv = "ϕ"; -var phmmat = "ℳ"; -var phone = "☎"; -var pi = "π"; -var pitchfork = "⋔"; -var piv = "ϖ"; -var planck = "ℏ"; -var planckh = "ℎ"; -var plankv = "ℏ"; -var plus = "+"; -var plusacir = "⨣"; -var plusb = "⊞"; -var pluscir = "⨢"; -var plusdo = "∔"; -var plusdu = "⨥"; -var pluse = "⩲"; -var plusm = "±"; -var plusmn = "±"; -var plussim = "⨦"; -var plustwo = "⨧"; -var pm = "±"; -var pointint = "⨕"; -var popf = "𝕡"; -var poun = "£"; -var pound = "£"; -var pr = "≺"; -var prE = "⪳"; -var prap = "⪷"; -var prcue = "≼"; -var pre = "⪯"; -var prec = "≺"; -var precapprox = "⪷"; -var preccurlyeq = "≼"; -var preceq = "⪯"; -var precnapprox = "⪹"; -var precneqq = "⪵"; -var precnsim = "⋨"; -var precsim = "≾"; -var prime = "′"; -var primes = "ℙ"; -var prnE = "⪵"; -var prnap = "⪹"; -var prnsim = "⋨"; -var prod = "∏"; -var profalar = "⌮"; -var profline = "⌒"; -var profsurf = "⌓"; -var prop = "∝"; -var propto = "∝"; -var prsim = "≾"; -var prurel = "⊰"; -var pscr = "𝓅"; -var psi = "ψ"; -var puncsp = " "; -var qfr = "𝔮"; -var qint = "⨌"; -var qopf = "𝕢"; -var qprime = "⁗"; -var qscr = "𝓆"; -var quaternions = "ℍ"; -var quatint = "⨖"; -var quest = "?"; -var questeq = "≟"; -var quo = "\""; -var quot = "\""; -var rAarr = "⇛"; -var rArr = "⇒"; -var rAtail = "⤜"; -var rBarr = "⤏"; -var rHar = "⥤"; -var race = "∽̱"; -var racute = "ŕ"; -var radic = "√"; -var raemptyv = "⦳"; -var rang = "⟩"; -var rangd = "⦒"; -var range = "⦥"; -var rangle = "⟩"; -var raqu = "»"; -var raquo = "»"; -var rarr = "→"; -var rarrap = "⥵"; -var rarrb = "⇥"; -var rarrbfs = "⤠"; -var rarrc = "⤳"; -var rarrfs = "⤞"; -var rarrhk = "↪"; -var rarrlp = "↬"; -var rarrpl = "⥅"; -var rarrsim = "⥴"; -var rarrtl = "↣"; -var rarrw = "↝"; -var ratail = "⤚"; -var ratio = "∶"; -var rationals = "ℚ"; -var rbarr = "⤍"; -var rbbrk = "❳"; -var rbrace = "}"; -var rbrack = "]"; -var rbrke = "⦌"; -var rbrksld = "⦎"; -var rbrkslu = "⦐"; -var rcaron = "ř"; -var rcedil = "ŗ"; -var rceil = "⌉"; -var rcub = "}"; -var rcy = "р"; -var rdca = "⤷"; -var rdldhar = "⥩"; -var rdquo = "”"; -var rdquor = "”"; -var rdsh = "↳"; -var real = "ℜ"; -var realine = "ℛ"; -var realpart = "ℜ"; -var reals = "ℝ"; -var rect = "▭"; -var re$2 = "®"; -var reg = "®"; -var rfisht = "⥽"; -var rfloor = "⌋"; -var rfr = "𝔯"; -var rhard = "⇁"; -var rharu = "⇀"; -var rharul = "⥬"; -var rho = "ρ"; -var rhov = "ϱ"; -var rightarrow = "→"; -var rightarrowtail = "↣"; -var rightharpoondown = "⇁"; -var rightharpoonup = "⇀"; -var rightleftarrows = "⇄"; -var rightleftharpoons = "⇌"; -var rightrightarrows = "⇉"; -var rightsquigarrow = "↝"; -var rightthreetimes = "⋌"; -var ring = "˚"; -var risingdotseq = "≓"; -var rlarr = "⇄"; -var rlhar = "⇌"; -var rlm = "‏"; -var rmoust = "⎱"; -var rmoustache = "⎱"; -var rnmid = "⫮"; -var roang = "⟭"; -var roarr = "⇾"; -var robrk = "⟧"; -var ropar = "⦆"; -var ropf = "𝕣"; -var roplus = "⨮"; -var rotimes = "⨵"; -var rpar = ")"; -var rpargt = "⦔"; -var rppolint = "⨒"; -var rrarr = "⇉"; -var rsaquo = "›"; -var rscr = "𝓇"; -var rsh = "↱"; -var rsqb = "]"; -var rsquo = "’"; -var rsquor = "’"; -var rthree = "⋌"; -var rtimes = "⋊"; -var rtri = "▹"; -var rtrie = "⊵"; -var rtrif = "▸"; -var rtriltri = "⧎"; -var ruluhar = "⥨"; -var rx = "℞"; -var sacute = "ś"; -var sbquo = "‚"; -var sc = "≻"; -var scE = "⪴"; -var scap = "⪸"; -var scaron = "š"; -var sccue = "≽"; -var sce = "⪰"; -var scedil = "ş"; -var scirc = "ŝ"; -var scnE = "⪶"; -var scnap = "⪺"; -var scnsim = "⋩"; -var scpolint = "⨓"; -var scsim = "≿"; -var scy = "с"; -var sdot = "⋅"; -var sdotb = "⊡"; -var sdote = "⩦"; -var seArr = "⇘"; -var searhk = "⤥"; -var searr = "↘"; -var searrow = "↘"; -var sec = "§"; -var sect = "§"; -var semi = ";"; -var seswar = "⤩"; -var setminus = "∖"; -var setmn = "∖"; -var sext = "✶"; -var sfr = "𝔰"; -var sfrown = "⌢"; -var sharp = "♯"; -var shchcy = "щ"; -var shcy = "ш"; -var shortmid = "∣"; -var shortparallel = "∥"; -var sh = "­"; -var shy = "­"; -var sigma = "σ"; -var sigmaf = "ς"; -var sigmav = "ς"; -var sim = "∼"; -var simdot = "⩪"; -var sime = "≃"; -var simeq = "≃"; -var simg = "⪞"; -var simgE = "⪠"; -var siml = "⪝"; -var simlE = "⪟"; -var simne = "≆"; -var simplus = "⨤"; -var simrarr = "⥲"; -var slarr = "←"; -var smallsetminus = "∖"; -var smashp = "⨳"; -var smeparsl = "⧤"; -var smid = "∣"; -var smile = "⌣"; -var smt = "⪪"; -var smte = "⪬"; -var smtes = "⪬︀"; -var softcy = "ь"; -var sol = "/"; -var solb = "⧄"; -var solbar = "⌿"; -var sopf = "𝕤"; -var spades = "♠"; -var spadesuit = "♠"; -var spar = "∥"; -var sqcap = "⊓"; -var sqcaps = "⊓︀"; -var sqcup = "⊔"; -var sqcups = "⊔︀"; -var sqsub = "⊏"; -var sqsube = "⊑"; -var sqsubset = "⊏"; -var sqsubseteq = "⊑"; -var sqsup = "⊐"; -var sqsupe = "⊒"; -var sqsupset = "⊐"; -var sqsupseteq = "⊒"; -var squ = "□"; -var square = "□"; -var squarf = "▪"; -var squf = "▪"; -var srarr = "→"; -var sscr = "𝓈"; -var ssetmn = "∖"; -var ssmile = "⌣"; -var sstarf = "⋆"; -var star = "☆"; -var starf = "★"; -var straightepsilon = "ϵ"; -var straightphi = "ϕ"; -var strns = "¯"; -var sub = "⊂"; -var subE = "⫅"; -var subdot = "⪽"; -var sube = "⊆"; -var subedot = "⫃"; -var submult = "⫁"; -var subnE = "⫋"; -var subne = "⊊"; -var subplus = "⪿"; -var subrarr = "⥹"; -var subset = "⊂"; -var subseteq = "⊆"; -var subseteqq = "⫅"; -var subsetneq = "⊊"; -var subsetneqq = "⫋"; -var subsim = "⫇"; -var subsub = "⫕"; -var subsup = "⫓"; -var succ = "≻"; -var succapprox = "⪸"; -var succcurlyeq = "≽"; -var succeq = "⪰"; -var succnapprox = "⪺"; -var succneqq = "⪶"; -var succnsim = "⋩"; -var succsim = "≿"; -var sum = "∑"; -var sung = "♪"; -var sup = "⊃"; -var sup1 = "¹"; -var sup2 = "²"; -var sup3 = "³"; -var supE = "⫆"; -var supdot = "⪾"; -var supdsub = "⫘"; -var supe = "⊇"; -var supedot = "⫄"; -var suphsol = "⟉"; -var suphsub = "⫗"; -var suplarr = "⥻"; -var supmult = "⫂"; -var supnE = "⫌"; -var supne = "⊋"; -var supplus = "⫀"; -var supset = "⊃"; -var supseteq = "⊇"; -var supseteqq = "⫆"; -var supsetneq = "⊋"; -var supsetneqq = "⫌"; -var supsim = "⫈"; -var supsub = "⫔"; -var supsup = "⫖"; -var swArr = "⇙"; -var swarhk = "⤦"; -var swarr = "↙"; -var swarrow = "↙"; -var swnwar = "⤪"; -var szli = "ß"; -var szlig = "ß"; -var target = "⌖"; -var tau = "τ"; -var tbrk = "⎴"; -var tcaron = "ť"; -var tcedil = "ţ"; -var tcy = "т"; -var tdot = "⃛"; -var telrec = "⌕"; -var tfr = "𝔱"; -var there4 = "∴"; -var therefore = "∴"; -var theta = "θ"; -var thetasym = "ϑ"; -var thetav = "ϑ"; -var thickapprox = "≈"; -var thicksim = "∼"; -var thinsp = " "; -var thkap = "≈"; -var thksim = "∼"; -var thor = "þ"; -var thorn = "þ"; -var tilde = "˜"; -var time = "×"; -var times = "×"; -var timesb = "⊠"; -var timesbar = "⨱"; -var timesd = "⨰"; -var tint = "∭"; -var toea = "⤨"; -var top = "⊤"; -var topbot = "⌶"; -var topcir = "⫱"; -var topf = "𝕥"; -var topfork = "⫚"; -var tosa = "⤩"; -var tprime = "‴"; -var trade = "™"; -var triangle = "▵"; -var triangledown = "▿"; -var triangleleft = "◃"; -var trianglelefteq = "⊴"; -var triangleq = "≜"; -var triangleright = "▹"; -var trianglerighteq = "⊵"; -var tridot = "◬"; -var trie = "≜"; -var triminus = "⨺"; -var triplus = "⨹"; -var trisb = "⧍"; -var tritime = "⨻"; -var trpezium = "⏢"; -var tscr = "𝓉"; -var tscy = "ц"; -var tshcy = "ћ"; -var tstrok = "ŧ"; -var twixt = "≬"; -var twoheadleftarrow = "↞"; -var twoheadrightarrow = "↠"; -var uArr = "⇑"; -var uHar = "⥣"; -var uacut = "ú"; -var uacute = "ú"; -var uarr = "↑"; -var ubrcy = "ў"; -var ubreve = "ŭ"; -var ucir = "û"; -var ucirc = "û"; -var ucy = "у"; -var udarr = "⇅"; -var udblac = "ű"; -var udhar = "⥮"; -var ufisht = "⥾"; -var ufr = "𝔲"; -var ugrav = "ù"; -var ugrave = "ù"; -var uharl = "↿"; -var uharr = "↾"; -var uhblk = "▀"; -var ulcorn = "⌜"; -var ulcorner = "⌜"; -var ulcrop = "⌏"; -var ultri = "◸"; -var umacr = "ū"; -var um = "¨"; -var uml = "¨"; -var uogon = "ų"; -var uopf = "𝕦"; -var uparrow = "↑"; -var updownarrow = "↕"; -var upharpoonleft = "↿"; -var upharpoonright = "↾"; -var uplus = "⊎"; -var upsi = "υ"; -var upsih = "ϒ"; -var upsilon = "υ"; -var upuparrows = "⇈"; -var urcorn = "⌝"; -var urcorner = "⌝"; -var urcrop = "⌎"; -var uring = "ů"; -var urtri = "◹"; -var uscr = "𝓊"; -var utdot = "⋰"; -var utilde = "ũ"; -var utri = "▵"; -var utrif = "▴"; -var uuarr = "⇈"; -var uum = "ü"; -var uuml = "ü"; -var uwangle = "⦧"; -var vArr = "⇕"; -var vBar = "⫨"; -var vBarv = "⫩"; -var vDash = "⊨"; -var vangrt = "⦜"; -var varepsilon = "ϵ"; -var varkappa = "ϰ"; -var varnothing = "∅"; -var varphi = "ϕ"; -var varpi = "ϖ"; -var varpropto = "∝"; -var varr = "↕"; -var varrho = "ϱ"; -var varsigma = "ς"; -var varsubsetneq = "⊊︀"; -var varsubsetneqq = "⫋︀"; -var varsupsetneq = "⊋︀"; -var varsupsetneqq = "⫌︀"; -var vartheta = "ϑ"; -var vartriangleleft = "⊲"; -var vartriangleright = "⊳"; -var vcy = "в"; -var vdash = "⊢"; -var vee = "∨"; -var veebar = "⊻"; -var veeeq = "≚"; -var vellip = "⋮"; -var verbar = "|"; -var vert = "|"; -var vfr = "𝔳"; -var vltri = "⊲"; -var vnsub = "⊂⃒"; -var vnsup = "⊃⃒"; -var vopf = "𝕧"; -var vprop = "∝"; -var vrtri = "⊳"; -var vscr = "𝓋"; -var vsubnE = "⫋︀"; -var vsubne = "⊊︀"; -var vsupnE = "⫌︀"; -var vsupne = "⊋︀"; -var vzigzag = "⦚"; -var wcirc = "ŵ"; -var wedbar = "⩟"; -var wedge = "∧"; -var wedgeq = "≙"; -var weierp = "℘"; -var wfr = "𝔴"; -var wopf = "𝕨"; -var wp = "℘"; -var wr = "≀"; -var wreath = "≀"; -var wscr = "𝓌"; -var xcap = "⋂"; -var xcirc = "◯"; -var xcup = "⋃"; -var xdtri = "▽"; -var xfr = "𝔵"; -var xhArr = "⟺"; -var xharr = "⟷"; -var xi = "ξ"; -var xlArr = "⟸"; -var xlarr = "⟵"; -var xmap = "⟼"; -var xnis = "⋻"; -var xodot = "⨀"; -var xopf = "𝕩"; -var xoplus = "⨁"; -var xotime = "⨂"; -var xrArr = "⟹"; -var xrarr = "⟶"; -var xscr = "𝓍"; -var xsqcup = "⨆"; -var xuplus = "⨄"; -var xutri = "△"; -var xvee = "⋁"; -var xwedge = "⋀"; -var yacut = "ý"; -var yacute = "ý"; -var yacy = "я"; -var ycirc = "ŷ"; -var ycy = "ы"; -var ye = "¥"; -var yen = "¥"; -var yfr = "𝔶"; -var yicy = "ї"; -var yopf = "𝕪"; -var yscr = "𝓎"; -var yucy = "ю"; -var yum = "ÿ"; -var yuml = "ÿ"; -var zacute = "ź"; -var zcaron = "ž"; -var zcy = "з"; -var zdot = "ż"; -var zeetrf = "ℨ"; -var zeta = "ζ"; -var zfr = "𝔷"; -var zhcy = "ж"; -var zigrarr = "⇝"; -var zopf = "𝕫"; -var zscr = "𝓏"; -var zwj = "‍"; -var zwnj = "‌"; -var characterEntities = { - AEli: AEli, - AElig: AElig, - AM: AM, - AMP: AMP, - Aacut: Aacut, - Aacute: Aacute, - Abreve: Abreve, - Acir: Acir, - Acirc: Acirc, - Acy: Acy, - Afr: Afr, - Agrav: Agrav, - Agrave: Agrave, - Alpha: Alpha, - Amacr: Amacr, - And: And, - Aogon: Aogon, - Aopf: Aopf, - ApplyFunction: ApplyFunction, - Arin: Arin, - Aring: Aring, - Ascr: Ascr, - Assign: Assign, - Atild: Atild, - Atilde: Atilde, - Aum: Aum, - Auml: Auml, - Backslash: Backslash, - Barv: Barv, - Barwed: Barwed, - Bcy: Bcy, - Because: Because, - Bernoullis: Bernoullis, - Beta: Beta, - Bfr: Bfr, - Bopf: Bopf, - Breve: Breve, - Bscr: Bscr, - Bumpeq: Bumpeq, - CHcy: CHcy, - COP: COP, - COPY: COPY, - Cacute: Cacute, - Cap: Cap, - CapitalDifferentialD: CapitalDifferentialD, - Cayleys: Cayleys, - Ccaron: Ccaron, - Ccedi: Ccedi, - Ccedil: Ccedil, - Ccirc: Ccirc, - Cconint: Cconint, - Cdot: Cdot, - Cedilla: Cedilla, - CenterDot: CenterDot, - Cfr: Cfr, - Chi: Chi, - CircleDot: CircleDot, - CircleMinus: CircleMinus, - CirclePlus: CirclePlus, - CircleTimes: CircleTimes, - ClockwiseContourIntegral: ClockwiseContourIntegral, - CloseCurlyDoubleQuote: CloseCurlyDoubleQuote, - CloseCurlyQuote: CloseCurlyQuote, - Colon: Colon, - Colone: Colone, - Congruent: Congruent, - Conint: Conint, - ContourIntegral: ContourIntegral, - Copf: Copf, - Coproduct: Coproduct, - CounterClockwiseContourIntegral: CounterClockwiseContourIntegral, - Cross: Cross, - Cscr: Cscr, - Cup: Cup, - CupCap: CupCap, - DD: DD, - DDotrahd: DDotrahd, - DJcy: DJcy, - DScy: DScy, - DZcy: DZcy, - Dagger: Dagger, - Darr: Darr, - Dashv: Dashv, - Dcaron: Dcaron, - Dcy: Dcy, - Del: Del, - Delta: Delta, - Dfr: Dfr, - DiacriticalAcute: DiacriticalAcute, - DiacriticalDot: DiacriticalDot, - DiacriticalDoubleAcute: DiacriticalDoubleAcute, - DiacriticalGrave: DiacriticalGrave, - DiacriticalTilde: DiacriticalTilde, - Diamond: Diamond, - DifferentialD: DifferentialD, - Dopf: Dopf, - Dot: Dot, - DotDot: DotDot, - DotEqual: DotEqual, - DoubleContourIntegral: DoubleContourIntegral, - DoubleDot: DoubleDot, - DoubleDownArrow: DoubleDownArrow, - DoubleLeftArrow: DoubleLeftArrow, - DoubleLeftRightArrow: DoubleLeftRightArrow, - DoubleLeftTee: DoubleLeftTee, - DoubleLongLeftArrow: DoubleLongLeftArrow, - DoubleLongLeftRightArrow: DoubleLongLeftRightArrow, - DoubleLongRightArrow: DoubleLongRightArrow, - DoubleRightArrow: DoubleRightArrow, - DoubleRightTee: DoubleRightTee, - DoubleUpArrow: DoubleUpArrow, - DoubleUpDownArrow: DoubleUpDownArrow, - DoubleVerticalBar: DoubleVerticalBar, - DownArrow: DownArrow, - DownArrowBar: DownArrowBar, - DownArrowUpArrow: DownArrowUpArrow, - DownBreve: DownBreve, - DownLeftRightVector: DownLeftRightVector, - DownLeftTeeVector: DownLeftTeeVector, - DownLeftVector: DownLeftVector, - DownLeftVectorBar: DownLeftVectorBar, - DownRightTeeVector: DownRightTeeVector, - DownRightVector: DownRightVector, - DownRightVectorBar: DownRightVectorBar, - DownTee: DownTee, - DownTeeArrow: DownTeeArrow, - Downarrow: Downarrow, - Dscr: Dscr, - Dstrok: Dstrok, - ENG: ENG, - ET: ET, - ETH: ETH, - Eacut: Eacut, - Eacute: Eacute, - Ecaron: Ecaron, - Ecir: Ecir, - Ecirc: Ecirc, - Ecy: Ecy, - Edot: Edot, - Efr: Efr, - Egrav: Egrav, - Egrave: Egrave, - Element: Element, - Emacr: Emacr, - EmptySmallSquare: EmptySmallSquare, - EmptyVerySmallSquare: EmptyVerySmallSquare, - Eogon: Eogon, - Eopf: Eopf, - Epsilon: Epsilon, - Equal: Equal, - EqualTilde: EqualTilde, - Equilibrium: Equilibrium, - Escr: Escr, - Esim: Esim, - Eta: Eta, - Eum: Eum, - Euml: Euml, - Exists: Exists, - ExponentialE: ExponentialE, - Fcy: Fcy, - Ffr: Ffr, - FilledSmallSquare: FilledSmallSquare, - FilledVerySmallSquare: FilledVerySmallSquare, - Fopf: Fopf, - ForAll: ForAll, - Fouriertrf: Fouriertrf, - Fscr: Fscr, - GJcy: GJcy, - G: G, - GT: GT, - Gamma: Gamma, - Gammad: Gammad, - Gbreve: Gbreve, - Gcedil: Gcedil, - Gcirc: Gcirc, - Gcy: Gcy, - Gdot: Gdot, - Gfr: Gfr, - Gg: Gg, - Gopf: Gopf, - GreaterEqual: GreaterEqual, - GreaterEqualLess: GreaterEqualLess, - GreaterFullEqual: GreaterFullEqual, - GreaterGreater: GreaterGreater, - GreaterLess: GreaterLess, - GreaterSlantEqual: GreaterSlantEqual, - GreaterTilde: GreaterTilde, - Gscr: Gscr, - Gt: Gt, - HARDcy: HARDcy, - Hacek: Hacek, - Hat: Hat, - Hcirc: Hcirc, - Hfr: Hfr, - HilbertSpace: HilbertSpace, - Hopf: Hopf, - HorizontalLine: HorizontalLine, - Hscr: Hscr, - Hstrok: Hstrok, - HumpDownHump: HumpDownHump, - HumpEqual: HumpEqual, - IEcy: IEcy, - IJlig: IJlig, - IOcy: IOcy, - Iacut: Iacut, - Iacute: Iacute, - Icir: Icir, - Icirc: Icirc, - Icy: Icy, - Idot: Idot, - Ifr: Ifr, - Igrav: Igrav, - Igrave: Igrave, - Im: Im, - Imacr: Imacr, - ImaginaryI: ImaginaryI, - Implies: Implies, - Int: Int, - Integral: Integral, - Intersection: Intersection, - InvisibleComma: InvisibleComma, - InvisibleTimes: InvisibleTimes, - Iogon: Iogon, - Iopf: Iopf, - Iota: Iota, - Iscr: Iscr, - Itilde: Itilde, - Iukcy: Iukcy, - Ium: Ium, - Iuml: Iuml, - Jcirc: Jcirc, - Jcy: Jcy, - Jfr: Jfr, - Jopf: Jopf, - Jscr: Jscr, - Jsercy: Jsercy, - Jukcy: Jukcy, - KHcy: KHcy, - KJcy: KJcy, - Kappa: Kappa, - Kcedil: Kcedil, - Kcy: Kcy, - Kfr: Kfr, - Kopf: Kopf, - Kscr: Kscr, - LJcy: LJcy, - L: L, - LT: LT, - Lacute: Lacute, - Lambda: Lambda, - Lang: Lang, - Laplacetrf: Laplacetrf, - Larr: Larr, - Lcaron: Lcaron, - Lcedil: Lcedil, - Lcy: Lcy, - LeftAngleBracket: LeftAngleBracket, - LeftArrow: LeftArrow, - LeftArrowBar: LeftArrowBar, - LeftArrowRightArrow: LeftArrowRightArrow, - LeftCeiling: LeftCeiling, - LeftDoubleBracket: LeftDoubleBracket, - LeftDownTeeVector: LeftDownTeeVector, - LeftDownVector: LeftDownVector, - LeftDownVectorBar: LeftDownVectorBar, - LeftFloor: LeftFloor, - LeftRightArrow: LeftRightArrow, - LeftRightVector: LeftRightVector, - LeftTee: LeftTee, - LeftTeeArrow: LeftTeeArrow, - LeftTeeVector: LeftTeeVector, - LeftTriangle: LeftTriangle, - LeftTriangleBar: LeftTriangleBar, - LeftTriangleEqual: LeftTriangleEqual, - LeftUpDownVector: LeftUpDownVector, - LeftUpTeeVector: LeftUpTeeVector, - LeftUpVector: LeftUpVector, - LeftUpVectorBar: LeftUpVectorBar, - LeftVector: LeftVector, - LeftVectorBar: LeftVectorBar, - Leftarrow: Leftarrow, - Leftrightarrow: Leftrightarrow, - LessEqualGreater: LessEqualGreater, - LessFullEqual: LessFullEqual, - LessGreater: LessGreater, - LessLess: LessLess, - LessSlantEqual: LessSlantEqual, - LessTilde: LessTilde, - Lfr: Lfr, - Ll: Ll, - Lleftarrow: Lleftarrow, - Lmidot: Lmidot, - LongLeftArrow: LongLeftArrow, - LongLeftRightArrow: LongLeftRightArrow, - LongRightArrow: LongRightArrow, - Longleftarrow: Longleftarrow, - Longleftrightarrow: Longleftrightarrow, - Longrightarrow: Longrightarrow, - Lopf: Lopf, - LowerLeftArrow: LowerLeftArrow, - LowerRightArrow: LowerRightArrow, - Lscr: Lscr, - Lsh: Lsh, - Lstrok: Lstrok, - Lt: Lt, - "Map": "⤅", - Mcy: Mcy, - MediumSpace: MediumSpace, - Mellintrf: Mellintrf, - Mfr: Mfr, - MinusPlus: MinusPlus, - Mopf: Mopf, - Mscr: Mscr, - Mu: Mu, - NJcy: NJcy, - Nacute: Nacute, - Ncaron: Ncaron, - Ncedil: Ncedil, - Ncy: Ncy, - NegativeMediumSpace: NegativeMediumSpace, - NegativeThickSpace: NegativeThickSpace, - NegativeThinSpace: NegativeThinSpace, - NegativeVeryThinSpace: NegativeVeryThinSpace, - NestedGreaterGreater: NestedGreaterGreater, - NestedLessLess: NestedLessLess, - NewLine: NewLine, - Nfr: Nfr, - NoBreak: NoBreak, - NonBreakingSpace: NonBreakingSpace, - Nopf: Nopf, - Not: Not, - NotCongruent: NotCongruent, - NotCupCap: NotCupCap, - NotDoubleVerticalBar: NotDoubleVerticalBar, - NotElement: NotElement, - NotEqual: NotEqual, - NotEqualTilde: NotEqualTilde, - NotExists: NotExists, - NotGreater: NotGreater, - NotGreaterEqual: NotGreaterEqual, - NotGreaterFullEqual: NotGreaterFullEqual, - NotGreaterGreater: NotGreaterGreater, - NotGreaterLess: NotGreaterLess, - NotGreaterSlantEqual: NotGreaterSlantEqual, - NotGreaterTilde: NotGreaterTilde, - NotHumpDownHump: NotHumpDownHump, - NotHumpEqual: NotHumpEqual, - NotLeftTriangle: NotLeftTriangle, - NotLeftTriangleBar: NotLeftTriangleBar, - NotLeftTriangleEqual: NotLeftTriangleEqual, - NotLess: NotLess, - NotLessEqual: NotLessEqual, - NotLessGreater: NotLessGreater, - NotLessLess: NotLessLess, - NotLessSlantEqual: NotLessSlantEqual, - NotLessTilde: NotLessTilde, - NotNestedGreaterGreater: NotNestedGreaterGreater, - NotNestedLessLess: NotNestedLessLess, - NotPrecedes: NotPrecedes, - NotPrecedesEqual: NotPrecedesEqual, - NotPrecedesSlantEqual: NotPrecedesSlantEqual, - NotReverseElement: NotReverseElement, - NotRightTriangle: NotRightTriangle, - NotRightTriangleBar: NotRightTriangleBar, - NotRightTriangleEqual: NotRightTriangleEqual, - NotSquareSubset: NotSquareSubset, - NotSquareSubsetEqual: NotSquareSubsetEqual, - NotSquareSuperset: NotSquareSuperset, - NotSquareSupersetEqual: NotSquareSupersetEqual, - NotSubset: NotSubset, - NotSubsetEqual: NotSubsetEqual, - NotSucceeds: NotSucceeds, - NotSucceedsEqual: NotSucceedsEqual, - NotSucceedsSlantEqual: NotSucceedsSlantEqual, - NotSucceedsTilde: NotSucceedsTilde, - NotSuperset: NotSuperset, - NotSupersetEqual: NotSupersetEqual, - NotTilde: NotTilde, - NotTildeEqual: NotTildeEqual, - NotTildeFullEqual: NotTildeFullEqual, - NotTildeTilde: NotTildeTilde, - NotVerticalBar: NotVerticalBar, - Nscr: Nscr, - Ntild: Ntild, - Ntilde: Ntilde, - Nu: Nu, - OElig: OElig, - Oacut: Oacut, - Oacute: Oacute, - Ocir: Ocir, - Ocirc: Ocirc, - Ocy: Ocy, - Odblac: Odblac, - Ofr: Ofr, - Ograv: Ograv, - Ograve: Ograve, - Omacr: Omacr, - Omega: Omega, - Omicron: Omicron, - Oopf: Oopf, - OpenCurlyDoubleQuote: OpenCurlyDoubleQuote, - OpenCurlyQuote: OpenCurlyQuote, - Or: Or, - Oscr: Oscr, - Oslas: Oslas, - Oslash: Oslash, - Otild: Otild, - Otilde: Otilde, - Otimes: Otimes, - Oum: Oum, - Ouml: Ouml, - OverBar: OverBar, - OverBrace: OverBrace, - OverBracket: OverBracket, - OverParenthesis: OverParenthesis, - PartialD: PartialD, - Pcy: Pcy, - Pfr: Pfr, - Phi: Phi, - Pi: Pi, - PlusMinus: PlusMinus, - Poincareplane: Poincareplane, - Popf: Popf, - Pr: Pr, - Precedes: Precedes, - PrecedesEqual: PrecedesEqual, - PrecedesSlantEqual: PrecedesSlantEqual, - PrecedesTilde: PrecedesTilde, - Prime: Prime, - Product: Product, - Proportion: Proportion, - Proportional: Proportional, - Pscr: Pscr, - Psi: Psi, - QUO: QUO, - QUOT: QUOT, - Qfr: Qfr, - Qopf: Qopf, - Qscr: Qscr, - RBarr: RBarr, - RE: RE, - REG: REG, - Racute: Racute, - Rang: Rang, - Rarr: Rarr, - Rarrtl: Rarrtl, - Rcaron: Rcaron, - Rcedil: Rcedil, - Rcy: Rcy, - Re: Re, - ReverseElement: ReverseElement, - ReverseEquilibrium: ReverseEquilibrium, - ReverseUpEquilibrium: ReverseUpEquilibrium, - Rfr: Rfr, - Rho: Rho, - RightAngleBracket: RightAngleBracket, - RightArrow: RightArrow, - RightArrowBar: RightArrowBar, - RightArrowLeftArrow: RightArrowLeftArrow, - RightCeiling: RightCeiling, - RightDoubleBracket: RightDoubleBracket, - RightDownTeeVector: RightDownTeeVector, - RightDownVector: RightDownVector, - RightDownVectorBar: RightDownVectorBar, - RightFloor: RightFloor, - RightTee: RightTee, - RightTeeArrow: RightTeeArrow, - RightTeeVector: RightTeeVector, - RightTriangle: RightTriangle, - RightTriangleBar: RightTriangleBar, - RightTriangleEqual: RightTriangleEqual, - RightUpDownVector: RightUpDownVector, - RightUpTeeVector: RightUpTeeVector, - RightUpVector: RightUpVector, - RightUpVectorBar: RightUpVectorBar, - RightVector: RightVector, - RightVectorBar: RightVectorBar, - Rightarrow: Rightarrow, - Ropf: Ropf, - RoundImplies: RoundImplies, - Rrightarrow: Rrightarrow, - Rscr: Rscr, - Rsh: Rsh, - RuleDelayed: RuleDelayed, - SHCHcy: SHCHcy, - SHcy: SHcy, - SOFTcy: SOFTcy, - Sacute: Sacute, - Sc: Sc, - Scaron: Scaron, - Scedil: Scedil, - Scirc: Scirc, - Scy: Scy, - Sfr: Sfr, - ShortDownArrow: ShortDownArrow, - ShortLeftArrow: ShortLeftArrow, - ShortRightArrow: ShortRightArrow, - ShortUpArrow: ShortUpArrow, - Sigma: Sigma, - SmallCircle: SmallCircle, - Sopf: Sopf, - Sqrt: Sqrt, - Square: Square, - SquareIntersection: SquareIntersection, - SquareSubset: SquareSubset, - SquareSubsetEqual: SquareSubsetEqual, - SquareSuperset: SquareSuperset, - SquareSupersetEqual: SquareSupersetEqual, - SquareUnion: SquareUnion, - Sscr: Sscr, - Star: Star, - Sub: Sub, - Subset: Subset, - SubsetEqual: SubsetEqual, - Succeeds: Succeeds, - SucceedsEqual: SucceedsEqual, - SucceedsSlantEqual: SucceedsSlantEqual, - SucceedsTilde: SucceedsTilde, - SuchThat: SuchThat, - Sum: Sum, - Sup: Sup, - Superset: Superset, - SupersetEqual: SupersetEqual, - Supset: Supset, - THOR: THOR, - THORN: THORN, - TRADE: TRADE, - TSHcy: TSHcy, - TScy: TScy, - Tab: Tab, - Tau: Tau, - Tcaron: Tcaron, - Tcedil: Tcedil, - Tcy: Tcy, - Tfr: Tfr, - Therefore: Therefore, - Theta: Theta, - ThickSpace: ThickSpace, - ThinSpace: ThinSpace, - Tilde: Tilde, - TildeEqual: TildeEqual, - TildeFullEqual: TildeFullEqual, - TildeTilde: TildeTilde, - Topf: Topf, - TripleDot: TripleDot, - Tscr: Tscr, - Tstrok: Tstrok, - Uacut: Uacut, - Uacute: Uacute, - Uarr: Uarr, - Uarrocir: Uarrocir, - Ubrcy: Ubrcy, - Ubreve: Ubreve, - Ucir: Ucir, - Ucirc: Ucirc, - Ucy: Ucy, - Udblac: Udblac, - Ufr: Ufr, - Ugrav: Ugrav, - Ugrave: Ugrave, - Umacr: Umacr, - UnderBar: UnderBar, - UnderBrace: UnderBrace, - UnderBracket: UnderBracket, - UnderParenthesis: UnderParenthesis, - Union: Union, - UnionPlus: UnionPlus, - Uogon: Uogon, - Uopf: Uopf, - UpArrow: UpArrow, - UpArrowBar: UpArrowBar, - UpArrowDownArrow: UpArrowDownArrow, - UpDownArrow: UpDownArrow, - UpEquilibrium: UpEquilibrium, - UpTee: UpTee, - UpTeeArrow: UpTeeArrow, - Uparrow: Uparrow, - Updownarrow: Updownarrow, - UpperLeftArrow: UpperLeftArrow, - UpperRightArrow: UpperRightArrow, - Upsi: Upsi, - Upsilon: Upsilon, - Uring: Uring, - Uscr: Uscr, - Utilde: Utilde, - Uum: Uum, - Uuml: Uuml, - VDash: VDash, - Vbar: Vbar, - Vcy: Vcy, - Vdash: Vdash, - Vdashl: Vdashl, - Vee: Vee, - Verbar: Verbar, - Vert: Vert, - VerticalBar: VerticalBar, - VerticalLine: VerticalLine, - VerticalSeparator: VerticalSeparator, - VerticalTilde: VerticalTilde, - VeryThinSpace: VeryThinSpace, - Vfr: Vfr, - Vopf: Vopf, - Vscr: Vscr, - Vvdash: Vvdash, - Wcirc: Wcirc, - Wedge: Wedge, - Wfr: Wfr, - Wopf: Wopf, - Wscr: Wscr, - Xfr: Xfr, - Xi: Xi, - Xopf: Xopf, - Xscr: Xscr, - YAcy: YAcy, - YIcy: YIcy, - YUcy: YUcy, - Yacut: Yacut, - Yacute: Yacute, - Ycirc: Ycirc, - Ycy: Ycy, - Yfr: Yfr, - Yopf: Yopf, - Yscr: Yscr, - Yuml: Yuml, - ZHcy: ZHcy, - Zacute: Zacute, - Zcaron: Zcaron, - Zcy: Zcy, - Zdot: Zdot, - ZeroWidthSpace: ZeroWidthSpace, - Zeta: Zeta, - Zfr: Zfr, - Zopf: Zopf, - Zscr: Zscr, - aacut: aacut, - aacute: aacute, - abreve: abreve, - ac: ac, - acE: acE, - acd: acd, - acir: acir, - acirc: acirc, - acut: acut, - acute: acute, - acy: acy, - aeli: aeli, - aelig: aelig, - af: af, - afr: afr, - agrav: agrav, - agrave: agrave, - alefsym: alefsym, - aleph: aleph, - alpha: alpha, - amacr: amacr, - amalg: amalg, - am: am, - amp: amp, - and: and, - andand: andand, - andd: andd, - andslope: andslope, - andv: andv, - ang: ang, - ange: ange, - angle: angle, - angmsd: angmsd, - angmsdaa: angmsdaa, - angmsdab: angmsdab, - angmsdac: angmsdac, - angmsdad: angmsdad, - angmsdae: angmsdae, - angmsdaf: angmsdaf, - angmsdag: angmsdag, - angmsdah: angmsdah, - angrt: angrt, - angrtvb: angrtvb, - angrtvbd: angrtvbd, - angsph: angsph, - angst: angst, - angzarr: angzarr, - aogon: aogon, - aopf: aopf, - ap: ap, - apE: apE, - apacir: apacir, - ape: ape, - apid: apid, - apos: apos, - approx: approx, - approxeq: approxeq, - arin: arin, - aring: aring, - ascr: ascr, - ast: ast, - asymp: asymp, - asympeq: asympeq, - atild: atild, - atilde: atilde, - aum: aum, - auml: auml, - awconint: awconint, - awint: awint, - bNot: bNot, - backcong: backcong, - backepsilon: backepsilon, - backprime: backprime, - backsim: backsim, - backsimeq: backsimeq, - barvee: barvee, - barwed: barwed, - barwedge: barwedge, - bbrk: bbrk, - bbrktbrk: bbrktbrk, - bcong: bcong, - bcy: bcy, - bdquo: bdquo, - becaus: becaus, - because: because, - bemptyv: bemptyv, - bepsi: bepsi, - bernou: bernou, - beta: beta, - beth: beth, - between: between, - bfr: bfr, - bigcap: bigcap, - bigcirc: bigcirc, - bigcup: bigcup, - bigodot: bigodot, - bigoplus: bigoplus, - bigotimes: bigotimes, - bigsqcup: bigsqcup, - bigstar: bigstar, - bigtriangledown: bigtriangledown, - bigtriangleup: bigtriangleup, - biguplus: biguplus, - bigvee: bigvee, - bigwedge: bigwedge, - bkarow: bkarow, - blacklozenge: blacklozenge, - blacksquare: blacksquare, - blacktriangle: blacktriangle, - blacktriangledown: blacktriangledown, - blacktriangleleft: blacktriangleleft, - blacktriangleright: blacktriangleright, - blank: blank, - blk12: blk12, - blk14: blk14, - blk34: blk34, - block: block, - bne: bne, - bnequiv: bnequiv, - bnot: bnot, - bopf: bopf, - bot: bot, - bottom: bottom, - bowtie: bowtie, - boxDL: boxDL, - boxDR: boxDR, - boxDl: boxDl, - boxDr: boxDr, - boxH: boxH, - boxHD: boxHD, - boxHU: boxHU, - boxHd: boxHd, - boxHu: boxHu, - boxUL: boxUL, - boxUR: boxUR, - boxUl: boxUl, - boxUr: boxUr, - boxV: boxV, - boxVH: boxVH, - boxVL: boxVL, - boxVR: boxVR, - boxVh: boxVh, - boxVl: boxVl, - boxVr: boxVr, - boxbox: boxbox, - boxdL: boxdL, - boxdR: boxdR, - boxdl: boxdl, - boxdr: boxdr, - boxh: boxh, - boxhD: boxhD, - boxhU: boxhU, - boxhd: boxhd, - boxhu: boxhu, - boxminus: boxminus, - boxplus: boxplus, - boxtimes: boxtimes, - boxuL: boxuL, - boxuR: boxuR, - boxul: boxul, - boxur: boxur, - boxv: boxv, - boxvH: boxvH, - boxvL: boxvL, - boxvR: boxvR, - boxvh: boxvh, - boxvl: boxvl, - boxvr: boxvr, - bprime: bprime, - breve: breve, - brvba: brvba, - brvbar: brvbar, - bscr: bscr, - bsemi: bsemi, - bsim: bsim, - bsime: bsime, - bsol: bsol, - bsolb: bsolb, - bsolhsub: bsolhsub, - bull: bull, - bullet: bullet, - bump: bump, - bumpE: bumpE, - bumpe: bumpe, - bumpeq: bumpeq, - cacute: cacute, - cap: cap, - capand: capand, - capbrcup: capbrcup, - capcap: capcap, - capcup: capcup, - capdot: capdot, - caps: caps, - caret: caret, - caron: caron, - ccaps: ccaps, - ccaron: ccaron, - ccedi: ccedi, - ccedil: ccedil, - ccirc: ccirc, - ccups: ccups, - ccupssm: ccupssm, - cdot: cdot, - cedi: cedi, - cedil: cedil, - cemptyv: cemptyv, - cen: cen, - cent: cent, - centerdot: centerdot, - cfr: cfr, - chcy: chcy, - check: check, - checkmark: checkmark, - chi: chi, - cir: cir, - cirE: cirE, - circ: circ, - circeq: circeq, - circlearrowleft: circlearrowleft, - circlearrowright: circlearrowright, - circledR: circledR, - circledS: circledS, - circledast: circledast, - circledcirc: circledcirc, - circleddash: circleddash, - cire: cire, - cirfnint: cirfnint, - cirmid: cirmid, - cirscir: cirscir, - clubs: clubs, - clubsuit: clubsuit, - colon: colon, - colone: colone, - coloneq: coloneq, - comma: comma, - commat: commat, - comp: comp, - compfn: compfn, - complement: complement, - complexes: complexes, - cong: cong, - congdot: congdot, - conint: conint, - copf: copf, - coprod: coprod, - cop: cop, - copy: copy, - copysr: copysr, - crarr: crarr, - cross: cross, - cscr: cscr, - csub: csub, - csube: csube, - csup: csup, - csupe: csupe, - ctdot: ctdot, - cudarrl: cudarrl, - cudarrr: cudarrr, - cuepr: cuepr, - cuesc: cuesc, - cularr: cularr, - cularrp: cularrp, - cup: cup, - cupbrcap: cupbrcap, - cupcap: cupcap, - cupcup: cupcup, - cupdot: cupdot, - cupor: cupor, - cups: cups, - curarr: curarr, - curarrm: curarrm, - curlyeqprec: curlyeqprec, - curlyeqsucc: curlyeqsucc, - curlyvee: curlyvee, - curlywedge: curlywedge, - curre: curre, - curren: curren, - curvearrowleft: curvearrowleft, - curvearrowright: curvearrowright, - cuvee: cuvee, - cuwed: cuwed, - cwconint: cwconint, - cwint: cwint, - cylcty: cylcty, - dArr: dArr, - dHar: dHar, - dagger: dagger, - daleth: daleth, - darr: darr, - dash: dash, - dashv: dashv, - dbkarow: dbkarow, - dblac: dblac, - dcaron: dcaron, - dcy: dcy, - dd: dd, - ddagger: ddagger, - ddarr: ddarr, - ddotseq: ddotseq, - de: de, - deg: deg, - delta: delta, - demptyv: demptyv, - dfisht: dfisht, - dfr: dfr, - dharl: dharl, - dharr: dharr, - diam: diam, - diamond: diamond, - diamondsuit: diamondsuit, - diams: diams, - die: die, - digamma: digamma, - disin: disin, - div: div, - divid: divid, - divide: divide, - divideontimes: divideontimes, - divonx: divonx, - djcy: djcy, - dlcorn: dlcorn, - dlcrop: dlcrop, - dollar: dollar, - dopf: dopf, - dot: dot, - doteq: doteq, - doteqdot: doteqdot, - dotminus: dotminus, - dotplus: dotplus, - dotsquare: dotsquare, - doublebarwedge: doublebarwedge, - downarrow: downarrow, - downdownarrows: downdownarrows, - downharpoonleft: downharpoonleft, - downharpoonright: downharpoonright, - drbkarow: drbkarow, - drcorn: drcorn, - drcrop: drcrop, - dscr: dscr, - dscy: dscy, - dsol: dsol, - dstrok: dstrok, - dtdot: dtdot, - dtri: dtri, - dtrif: dtrif, - duarr: duarr, - duhar: duhar, - dwangle: dwangle, - dzcy: dzcy, - dzigrarr: dzigrarr, - eDDot: eDDot, - eDot: eDot, - eacut: eacut, - eacute: eacute, - easter: easter, - ecaron: ecaron, - ecir: ecir, - ecirc: ecirc, - ecolon: ecolon, - ecy: ecy, - edot: edot, - ee: ee, - efDot: efDot, - efr: efr, - eg: eg, - egrav: egrav, - egrave: egrave, - egs: egs, - egsdot: egsdot, - el: el, - elinters: elinters, - ell: ell, - els: els, - elsdot: elsdot, - emacr: emacr, - empty: empty, - emptyset: emptyset, - emptyv: emptyv, - emsp13: emsp13, - emsp14: emsp14, - emsp: emsp, - eng: eng, - ensp: ensp, - eogon: eogon, - eopf: eopf, - epar: epar, - eparsl: eparsl, - eplus: eplus, - epsi: epsi, - epsilon: epsilon, - epsiv: epsiv, - eqcirc: eqcirc, - eqcolon: eqcolon, - eqsim: eqsim, - eqslantgtr: eqslantgtr, - eqslantless: eqslantless, - equals: equals, - equest: equest, - equiv: equiv, - equivDD: equivDD, - eqvparsl: eqvparsl, - erDot: erDot, - erarr: erarr, - escr: escr, - esdot: esdot, - esim: esim, - eta: eta, - et: et, - eth: eth, - eum: eum, - euml: euml, - euro: euro, - excl: excl, - exist: exist, - expectation: expectation, - exponentiale: exponentiale, - fallingdotseq: fallingdotseq, - fcy: fcy, - female: female, - ffilig: ffilig, - fflig: fflig, - ffllig: ffllig, - ffr: ffr, - filig: filig, - fjlig: fjlig, - flat: flat, - fllig: fllig, - fltns: fltns, - fnof: fnof, - fopf: fopf, - forall: forall, - fork: fork, - forkv: forkv, - fpartint: fpartint, - frac1: frac1, - frac12: frac12, - frac13: frac13, - frac14: frac14, - frac15: frac15, - frac16: frac16, - frac18: frac18, - frac23: frac23, - frac25: frac25, - frac3: frac3, - frac34: frac34, - frac35: frac35, - frac38: frac38, - frac45: frac45, - frac56: frac56, - frac58: frac58, - frac78: frac78, - frasl: frasl, - frown: frown, - fscr: fscr, - gE: gE, - gEl: gEl, - gacute: gacute, - gamma: gamma, - gammad: gammad, - gap: gap, - gbreve: gbreve, - gcirc: gcirc, - gcy: gcy, - gdot: gdot, - ge: ge, - gel: gel, - geq: geq, - geqq: geqq, - geqslant: geqslant, - ges: ges, - gescc: gescc, - gesdot: gesdot, - gesdoto: gesdoto, - gesdotol: gesdotol, - gesl: gesl, - gesles: gesles, - gfr: gfr, - gg: gg, - ggg: ggg, - gimel: gimel, - gjcy: gjcy, - gl: gl, - glE: glE, - gla: gla, - glj: glj, - gnE: gnE, - gnap: gnap, - gnapprox: gnapprox, - gne: gne, - gneq: gneq, - gneqq: gneqq, - gnsim: gnsim, - gopf: gopf, - grave: grave, - gscr: gscr, - gsim: gsim, - gsime: gsime, - gsiml: gsiml, - g: g, - gt: gt, - gtcc: gtcc, - gtcir: gtcir, - gtdot: gtdot, - gtlPar: gtlPar, - gtquest: gtquest, - gtrapprox: gtrapprox, - gtrarr: gtrarr, - gtrdot: gtrdot, - gtreqless: gtreqless, - gtreqqless: gtreqqless, - gtrless: gtrless, - gtrsim: gtrsim, - gvertneqq: gvertneqq, - gvnE: gvnE, - hArr: hArr, - hairsp: hairsp, - half: half, - hamilt: hamilt, - hardcy: hardcy, - harr: harr, - harrcir: harrcir, - harrw: harrw, - hbar: hbar, - hcirc: hcirc, - hearts: hearts, - heartsuit: heartsuit, - hellip: hellip, - hercon: hercon, - hfr: hfr, - hksearow: hksearow, - hkswarow: hkswarow, - hoarr: hoarr, - homtht: homtht, - hookleftarrow: hookleftarrow, - hookrightarrow: hookrightarrow, - hopf: hopf, - horbar: horbar, - hscr: hscr, - hslash: hslash, - hstrok: hstrok, - hybull: hybull, - hyphen: hyphen, - iacut: iacut, - iacute: iacute, - ic: ic, - icir: icir, - icirc: icirc, - icy: icy, - iecy: iecy, - iexc: iexc, - iexcl: iexcl, - iff: iff, - ifr: ifr, - igrav: igrav, - igrave: igrave, - ii: ii, - iiiint: iiiint, - iiint: iiint, - iinfin: iinfin, - iiota: iiota, - ijlig: ijlig, - imacr: imacr, - image: image, - imagline: imagline, - imagpart: imagpart, - imath: imath, - imof: imof, - imped: imped, - "in": "∈", - incare: incare, - infin: infin, - infintie: infintie, - inodot: inodot, - int: int, - intcal: intcal, - integers: integers, - intercal: intercal, - intlarhk: intlarhk, - intprod: intprod, - iocy: iocy, - iogon: iogon, - iopf: iopf, - iota: iota, - iprod: iprod, - iques: iques, - iquest: iquest, - iscr: iscr, - isin: isin, - isinE: isinE, - isindot: isindot, - isins: isins, - isinsv: isinsv, - isinv: isinv, - it: it, - itilde: itilde, - iukcy: iukcy, - ium: ium, - iuml: iuml, - jcirc: jcirc, - jcy: jcy, - jfr: jfr, - jmath: jmath, - jopf: jopf, - jscr: jscr, - jsercy: jsercy, - jukcy: jukcy, - kappa: kappa, - kappav: kappav, - kcedil: kcedil, - kcy: kcy, - kfr: kfr, - kgreen: kgreen, - khcy: khcy, - kjcy: kjcy, - kopf: kopf, - kscr: kscr, - lAarr: lAarr, - lArr: lArr, - lAtail: lAtail, - lBarr: lBarr, - lE: lE, - lEg: lEg, - lHar: lHar, - lacute: lacute, - laemptyv: laemptyv, - lagran: lagran, - lambda: lambda, - lang: lang, - langd: langd, - langle: langle, - lap: lap, - laqu: laqu, - laquo: laquo, - larr: larr, - larrb: larrb, - larrbfs: larrbfs, - larrfs: larrfs, - larrhk: larrhk, - larrlp: larrlp, - larrpl: larrpl, - larrsim: larrsim, - larrtl: larrtl, - lat: lat, - latail: latail, - late: late, - lates: lates, - lbarr: lbarr, - lbbrk: lbbrk, - lbrace: lbrace, - lbrack: lbrack, - lbrke: lbrke, - lbrksld: lbrksld, - lbrkslu: lbrkslu, - lcaron: lcaron, - lcedil: lcedil, - lceil: lceil, - lcub: lcub, - lcy: lcy, - ldca: ldca, - ldquo: ldquo, - ldquor: ldquor, - ldrdhar: ldrdhar, - ldrushar: ldrushar, - ldsh: ldsh, - le: le, - leftarrow: leftarrow, - leftarrowtail: leftarrowtail, - leftharpoondown: leftharpoondown, - leftharpoonup: leftharpoonup, - leftleftarrows: leftleftarrows, - leftrightarrow: leftrightarrow, - leftrightarrows: leftrightarrows, - leftrightharpoons: leftrightharpoons, - leftrightsquigarrow: leftrightsquigarrow, - leftthreetimes: leftthreetimes, - leg: leg, - leq: leq, - leqq: leqq, - leqslant: leqslant, - les: les, - lescc: lescc, - lesdot: lesdot, - lesdoto: lesdoto, - lesdotor: lesdotor, - lesg: lesg, - lesges: lesges, - lessapprox: lessapprox, - lessdot: lessdot, - lesseqgtr: lesseqgtr, - lesseqqgtr: lesseqqgtr, - lessgtr: lessgtr, - lesssim: lesssim, - lfisht: lfisht, - lfloor: lfloor, - lfr: lfr, - lg: lg, - lgE: lgE, - lhard: lhard, - lharu: lharu, - lharul: lharul, - lhblk: lhblk, - ljcy: ljcy, - ll: ll, - llarr: llarr, - llcorner: llcorner, - llhard: llhard, - lltri: lltri, - lmidot: lmidot, - lmoust: lmoust, - lmoustache: lmoustache, - lnE: lnE, - lnap: lnap, - lnapprox: lnapprox, - lne: lne, - lneq: lneq, - lneqq: lneqq, - lnsim: lnsim, - loang: loang, - loarr: loarr, - lobrk: lobrk, - longleftarrow: longleftarrow, - longleftrightarrow: longleftrightarrow, - longmapsto: longmapsto, - longrightarrow: longrightarrow, - looparrowleft: looparrowleft, - looparrowright: looparrowright, - lopar: lopar, - lopf: lopf, - loplus: loplus, - lotimes: lotimes, - lowast: lowast, - lowbar: lowbar, - loz: loz, - lozenge: lozenge, - lozf: lozf, - lpar: lpar, - lparlt: lparlt, - lrarr: lrarr, - lrcorner: lrcorner, - lrhar: lrhar, - lrhard: lrhard, - lrm: lrm, - lrtri: lrtri, - lsaquo: lsaquo, - lscr: lscr, - lsh: lsh, - lsim: lsim, - lsime: lsime, - lsimg: lsimg, - lsqb: lsqb, - lsquo: lsquo, - lsquor: lsquor, - lstrok: lstrok, - l: l, - lt: lt, - ltcc: ltcc, - ltcir: ltcir, - ltdot: ltdot, - lthree: lthree, - ltimes: ltimes, - ltlarr: ltlarr, - ltquest: ltquest, - ltrPar: ltrPar, - ltri: ltri, - ltrie: ltrie, - ltrif: ltrif, - lurdshar: lurdshar, - luruhar: luruhar, - lvertneqq: lvertneqq, - lvnE: lvnE, - mDDot: mDDot, - mac: mac, - macr: macr, - male: male, - malt: malt, - maltese: maltese, - map: map, - mapsto: mapsto, - mapstodown: mapstodown, - mapstoleft: mapstoleft, - mapstoup: mapstoup, - marker: marker, - mcomma: mcomma, - mcy: mcy, - mdash: mdash, - measuredangle: measuredangle, - mfr: mfr, - mho: mho, - micr: micr, - micro: micro, - mid: mid, - midast: midast, - midcir: midcir, - middo: middo, - middot: middot, - minus: minus, - minusb: minusb, - minusd: minusd, - minusdu: minusdu, - mlcp: mlcp, - mldr: mldr, - mnplus: mnplus, - models: models, - mopf: mopf, - mp: mp, - mscr: mscr, - mstpos: mstpos, - mu: mu, - multimap: multimap, - mumap: mumap, - nGg: nGg, - nGt: nGt, - nGtv: nGtv, - nLeftarrow: nLeftarrow, - nLeftrightarrow: nLeftrightarrow, - nLl: nLl, - nLt: nLt, - nLtv: nLtv, - nRightarrow: nRightarrow, - nVDash: nVDash, - nVdash: nVdash, - nabla: nabla, - nacute: nacute, - nang: nang, - nap: nap, - napE: napE, - napid: napid, - napos: napos, - napprox: napprox, - natur: natur, - natural: natural, - naturals: naturals, - nbs: nbs, - nbsp: nbsp, - nbump: nbump, - nbumpe: nbumpe, - ncap: ncap, - ncaron: ncaron, - ncedil: ncedil, - ncong: ncong, - ncongdot: ncongdot, - ncup: ncup, - ncy: ncy, - ndash: ndash, - ne: ne, - neArr: neArr, - nearhk: nearhk, - nearr: nearr, - nearrow: nearrow, - nedot: nedot, - nequiv: nequiv, - nesear: nesear, - nesim: nesim, - nexist: nexist, - nexists: nexists, - nfr: nfr, - ngE: ngE, - nge: nge, - ngeq: ngeq, - ngeqq: ngeqq, - ngeqslant: ngeqslant, - nges: nges, - ngsim: ngsim, - ngt: ngt, - ngtr: ngtr, - nhArr: nhArr, - nharr: nharr, - nhpar: nhpar, - ni: ni, - nis: nis, - nisd: nisd, - niv: niv, - njcy: njcy, - nlArr: nlArr, - nlE: nlE, - nlarr: nlarr, - nldr: nldr, - nle: nle, - nleftarrow: nleftarrow, - nleftrightarrow: nleftrightarrow, - nleq: nleq, - nleqq: nleqq, - nleqslant: nleqslant, - nles: nles, - nless: nless, - nlsim: nlsim, - nlt: nlt, - nltri: nltri, - nltrie: nltrie, - nmid: nmid, - nopf: nopf, - no: no, - not: not, - notin: notin, - notinE: notinE, - notindot: notindot, - notinva: notinva, - notinvb: notinvb, - notinvc: notinvc, - notni: notni, - notniva: notniva, - notnivb: notnivb, - notnivc: notnivc, - npar: npar, - nparallel: nparallel, - nparsl: nparsl, - npart: npart, - npolint: npolint, - npr: npr, - nprcue: nprcue, - npre: npre, - nprec: nprec, - npreceq: npreceq, - nrArr: nrArr, - nrarr: nrarr, - nrarrc: nrarrc, - nrarrw: nrarrw, - nrightarrow: nrightarrow, - nrtri: nrtri, - nrtrie: nrtrie, - nsc: nsc, - nsccue: nsccue, - nsce: nsce, - nscr: nscr, - nshortmid: nshortmid, - nshortparallel: nshortparallel, - nsim: nsim, - nsime: nsime, - nsimeq: nsimeq, - nsmid: nsmid, - nspar: nspar, - nsqsube: nsqsube, - nsqsupe: nsqsupe, - nsub: nsub, - nsubE: nsubE, - nsube: nsube, - nsubset: nsubset, - nsubseteq: nsubseteq, - nsubseteqq: nsubseteqq, - nsucc: nsucc, - nsucceq: nsucceq, - nsup: nsup, - nsupE: nsupE, - nsupe: nsupe, - nsupset: nsupset, - nsupseteq: nsupseteq, - nsupseteqq: nsupseteqq, - ntgl: ntgl, - ntild: ntild, - ntilde: ntilde, - ntlg: ntlg, - ntriangleleft: ntriangleleft, - ntrianglelefteq: ntrianglelefteq, - ntriangleright: ntriangleright, - ntrianglerighteq: ntrianglerighteq, - nu: nu, - num: num, - numero: numero, - numsp: numsp, - nvDash: nvDash, - nvHarr: nvHarr, - nvap: nvap, - nvdash: nvdash, - nvge: nvge, - nvgt: nvgt, - nvinfin: nvinfin, - nvlArr: nvlArr, - nvle: nvle, - nvlt: nvlt, - nvltrie: nvltrie, - nvrArr: nvrArr, - nvrtrie: nvrtrie, - nvsim: nvsim, - nwArr: nwArr, - nwarhk: nwarhk, - nwarr: nwarr, - nwarrow: nwarrow, - nwnear: nwnear, - oS: oS, - oacut: oacut, - oacute: oacute, - oast: oast, - ocir: ocir, - ocirc: ocirc, - ocy: ocy, - odash: odash, - odblac: odblac, - odiv: odiv, - odot: odot, - odsold: odsold, - oelig: oelig, - ofcir: ofcir, - ofr: ofr, - ogon: ogon, - ograv: ograv, - ograve: ograve, - ogt: ogt, - ohbar: ohbar, - ohm: ohm, - oint: oint, - olarr: olarr, - olcir: olcir, - olcross: olcross, - oline: oline, - olt: olt, - omacr: omacr, - omega: omega, - omicron: omicron, - omid: omid, - ominus: ominus, - oopf: oopf, - opar: opar, - operp: operp, - oplus: oplus, - or: or, - orarr: orarr, - ord: ord, - order: order, - orderof: orderof, - ordf: ordf, - ordm: ordm, - origof: origof, - oror: oror, - orslope: orslope, - orv: orv, - oscr: oscr, - oslas: oslas, - oslash: oslash, - osol: osol, - otild: otild, - otilde: otilde, - otimes: otimes, - otimesas: otimesas, - oum: oum, - ouml: ouml, - ovbar: ovbar, - par: par, - para: para, - parallel: parallel, - parsim: parsim, - parsl: parsl, - part: part, - pcy: pcy, - percnt: percnt, - period: period, - permil: permil, - perp: perp, - pertenk: pertenk, - pfr: pfr, - phi: phi, - phiv: phiv, - phmmat: phmmat, - phone: phone, - pi: pi, - pitchfork: pitchfork, - piv: piv, - planck: planck, - planckh: planckh, - plankv: plankv, - plus: plus, - plusacir: plusacir, - plusb: plusb, - pluscir: pluscir, - plusdo: plusdo, - plusdu: plusdu, - pluse: pluse, - plusm: plusm, - plusmn: plusmn, - plussim: plussim, - plustwo: plustwo, - pm: pm, - pointint: pointint, - popf: popf, - poun: poun, - pound: pound, - pr: pr, - prE: prE, - prap: prap, - prcue: prcue, - pre: pre, - prec: prec, - precapprox: precapprox, - preccurlyeq: preccurlyeq, - preceq: preceq, - precnapprox: precnapprox, - precneqq: precneqq, - precnsim: precnsim, - precsim: precsim, - prime: prime, - primes: primes, - prnE: prnE, - prnap: prnap, - prnsim: prnsim, - prod: prod, - profalar: profalar, - profline: profline, - profsurf: profsurf, - prop: prop, - propto: propto, - prsim: prsim, - prurel: prurel, - pscr: pscr, - psi: psi, - puncsp: puncsp, - qfr: qfr, - qint: qint, - qopf: qopf, - qprime: qprime, - qscr: qscr, - quaternions: quaternions, - quatint: quatint, - quest: quest, - questeq: questeq, - quo: quo, - quot: quot, - rAarr: rAarr, - rArr: rArr, - rAtail: rAtail, - rBarr: rBarr, - rHar: rHar, - race: race, - racute: racute, - radic: radic, - raemptyv: raemptyv, - rang: rang, - rangd: rangd, - range: range, - rangle: rangle, - raqu: raqu, - raquo: raquo, - rarr: rarr, - rarrap: rarrap, - rarrb: rarrb, - rarrbfs: rarrbfs, - rarrc: rarrc, - rarrfs: rarrfs, - rarrhk: rarrhk, - rarrlp: rarrlp, - rarrpl: rarrpl, - rarrsim: rarrsim, - rarrtl: rarrtl, - rarrw: rarrw, - ratail: ratail, - ratio: ratio, - rationals: rationals, - rbarr: rbarr, - rbbrk: rbbrk, - rbrace: rbrace, - rbrack: rbrack, - rbrke: rbrke, - rbrksld: rbrksld, - rbrkslu: rbrkslu, - rcaron: rcaron, - rcedil: rcedil, - rceil: rceil, - rcub: rcub, - rcy: rcy, - rdca: rdca, - rdldhar: rdldhar, - rdquo: rdquo, - rdquor: rdquor, - rdsh: rdsh, - real: real, - realine: realine, - realpart: realpart, - reals: reals, - rect: rect, - re: re$2, - reg: reg, - rfisht: rfisht, - rfloor: rfloor, - rfr: rfr, - rhard: rhard, - rharu: rharu, - rharul: rharul, - rho: rho, - rhov: rhov, - rightarrow: rightarrow, - rightarrowtail: rightarrowtail, - rightharpoondown: rightharpoondown, - rightharpoonup: rightharpoonup, - rightleftarrows: rightleftarrows, - rightleftharpoons: rightleftharpoons, - rightrightarrows: rightrightarrows, - rightsquigarrow: rightsquigarrow, - rightthreetimes: rightthreetimes, - ring: ring, - risingdotseq: risingdotseq, - rlarr: rlarr, - rlhar: rlhar, - rlm: rlm, - rmoust: rmoust, - rmoustache: rmoustache, - rnmid: rnmid, - roang: roang, - roarr: roarr, - robrk: robrk, - ropar: ropar, - ropf: ropf, - roplus: roplus, - rotimes: rotimes, - rpar: rpar, - rpargt: rpargt, - rppolint: rppolint, - rrarr: rrarr, - rsaquo: rsaquo, - rscr: rscr, - rsh: rsh, - rsqb: rsqb, - rsquo: rsquo, - rsquor: rsquor, - rthree: rthree, - rtimes: rtimes, - rtri: rtri, - rtrie: rtrie, - rtrif: rtrif, - rtriltri: rtriltri, - ruluhar: ruluhar, - rx: rx, - sacute: sacute, - sbquo: sbquo, - sc: sc, - scE: scE, - scap: scap, - scaron: scaron, - sccue: sccue, - sce: sce, - scedil: scedil, - scirc: scirc, - scnE: scnE, - scnap: scnap, - scnsim: scnsim, - scpolint: scpolint, - scsim: scsim, - scy: scy, - sdot: sdot, - sdotb: sdotb, - sdote: sdote, - seArr: seArr, - searhk: searhk, - searr: searr, - searrow: searrow, - sec: sec, - sect: sect, - semi: semi, - seswar: seswar, - setminus: setminus, - setmn: setmn, - sext: sext, - sfr: sfr, - sfrown: sfrown, - sharp: sharp, - shchcy: shchcy, - shcy: shcy, - shortmid: shortmid, - shortparallel: shortparallel, - sh: sh, - shy: shy, - sigma: sigma, - sigmaf: sigmaf, - sigmav: sigmav, - sim: sim, - simdot: simdot, - sime: sime, - simeq: simeq, - simg: simg, - simgE: simgE, - siml: siml, - simlE: simlE, - simne: simne, - simplus: simplus, - simrarr: simrarr, - slarr: slarr, - smallsetminus: smallsetminus, - smashp: smashp, - smeparsl: smeparsl, - smid: smid, - smile: smile, - smt: smt, - smte: smte, - smtes: smtes, - softcy: softcy, - sol: sol, - solb: solb, - solbar: solbar, - sopf: sopf, - spades: spades, - spadesuit: spadesuit, - spar: spar, - sqcap: sqcap, - sqcaps: sqcaps, - sqcup: sqcup, - sqcups: sqcups, - sqsub: sqsub, - sqsube: sqsube, - sqsubset: sqsubset, - sqsubseteq: sqsubseteq, - sqsup: sqsup, - sqsupe: sqsupe, - sqsupset: sqsupset, - sqsupseteq: sqsupseteq, - squ: squ, - square: square, - squarf: squarf, - squf: squf, - srarr: srarr, - sscr: sscr, - ssetmn: ssetmn, - ssmile: ssmile, - sstarf: sstarf, - star: star, - starf: starf, - straightepsilon: straightepsilon, - straightphi: straightphi, - strns: strns, - sub: sub, - subE: subE, - subdot: subdot, - sube: sube, - subedot: subedot, - submult: submult, - subnE: subnE, - subne: subne, - subplus: subplus, - subrarr: subrarr, - subset: subset, - subseteq: subseteq, - subseteqq: subseteqq, - subsetneq: subsetneq, - subsetneqq: subsetneqq, - subsim: subsim, - subsub: subsub, - subsup: subsup, - succ: succ, - succapprox: succapprox, - succcurlyeq: succcurlyeq, - succeq: succeq, - succnapprox: succnapprox, - succneqq: succneqq, - succnsim: succnsim, - succsim: succsim, - sum: sum, - sung: sung, - sup: sup, - sup1: sup1, - sup2: sup2, - sup3: sup3, - supE: supE, - supdot: supdot, - supdsub: supdsub, - supe: supe, - supedot: supedot, - suphsol: suphsol, - suphsub: suphsub, - suplarr: suplarr, - supmult: supmult, - supnE: supnE, - supne: supne, - supplus: supplus, - supset: supset, - supseteq: supseteq, - supseteqq: supseteqq, - supsetneq: supsetneq, - supsetneqq: supsetneqq, - supsim: supsim, - supsub: supsub, - supsup: supsup, - swArr: swArr, - swarhk: swarhk, - swarr: swarr, - swarrow: swarrow, - swnwar: swnwar, - szli: szli, - szlig: szlig, - target: target, - tau: tau, - tbrk: tbrk, - tcaron: tcaron, - tcedil: tcedil, - tcy: tcy, - tdot: tdot, - telrec: telrec, - tfr: tfr, - there4: there4, - therefore: therefore, - theta: theta, - thetasym: thetasym, - thetav: thetav, - thickapprox: thickapprox, - thicksim: thicksim, - thinsp: thinsp, - thkap: thkap, - thksim: thksim, - thor: thor, - thorn: thorn, - tilde: tilde, - time: time, - times: times, - timesb: timesb, - timesbar: timesbar, - timesd: timesd, - tint: tint, - toea: toea, - top: top, - topbot: topbot, - topcir: topcir, - topf: topf, - topfork: topfork, - tosa: tosa, - tprime: tprime, - trade: trade, - triangle: triangle, - triangledown: triangledown, - triangleleft: triangleleft, - trianglelefteq: trianglelefteq, - triangleq: triangleq, - triangleright: triangleright, - trianglerighteq: trianglerighteq, - tridot: tridot, - trie: trie, - triminus: triminus, - triplus: triplus, - trisb: trisb, - tritime: tritime, - trpezium: trpezium, - tscr: tscr, - tscy: tscy, - tshcy: tshcy, - tstrok: tstrok, - twixt: twixt, - twoheadleftarrow: twoheadleftarrow, - twoheadrightarrow: twoheadrightarrow, - uArr: uArr, - uHar: uHar, - uacut: uacut, - uacute: uacute, - uarr: uarr, - ubrcy: ubrcy, - ubreve: ubreve, - ucir: ucir, - ucirc: ucirc, - ucy: ucy, - udarr: udarr, - udblac: udblac, - udhar: udhar, - ufisht: ufisht, - ufr: ufr, - ugrav: ugrav, - ugrave: ugrave, - uharl: uharl, - uharr: uharr, - uhblk: uhblk, - ulcorn: ulcorn, - ulcorner: ulcorner, - ulcrop: ulcrop, - ultri: ultri, - umacr: umacr, - um: um, - uml: uml, - uogon: uogon, - uopf: uopf, - uparrow: uparrow, - updownarrow: updownarrow, - upharpoonleft: upharpoonleft, - upharpoonright: upharpoonright, - uplus: uplus, - upsi: upsi, - upsih: upsih, - upsilon: upsilon, - upuparrows: upuparrows, - urcorn: urcorn, - urcorner: urcorner, - urcrop: urcrop, - uring: uring, - urtri: urtri, - uscr: uscr, - utdot: utdot, - utilde: utilde, - utri: utri, - utrif: utrif, - uuarr: uuarr, - uum: uum, - uuml: uuml, - uwangle: uwangle, - vArr: vArr, - vBar: vBar, - vBarv: vBarv, - vDash: vDash, - vangrt: vangrt, - varepsilon: varepsilon, - varkappa: varkappa, - varnothing: varnothing, - varphi: varphi, - varpi: varpi, - varpropto: varpropto, - varr: varr, - varrho: varrho, - varsigma: varsigma, - varsubsetneq: varsubsetneq, - varsubsetneqq: varsubsetneqq, - varsupsetneq: varsupsetneq, - varsupsetneqq: varsupsetneqq, - vartheta: vartheta, - vartriangleleft: vartriangleleft, - vartriangleright: vartriangleright, - vcy: vcy, - vdash: vdash, - vee: vee, - veebar: veebar, - veeeq: veeeq, - vellip: vellip, - verbar: verbar, - vert: vert, - vfr: vfr, - vltri: vltri, - vnsub: vnsub, - vnsup: vnsup, - vopf: vopf, - vprop: vprop, - vrtri: vrtri, - vscr: vscr, - vsubnE: vsubnE, - vsubne: vsubne, - vsupnE: vsupnE, - vsupne: vsupne, - vzigzag: vzigzag, - wcirc: wcirc, - wedbar: wedbar, - wedge: wedge, - wedgeq: wedgeq, - weierp: weierp, - wfr: wfr, - wopf: wopf, - wp: wp, - wr: wr, - wreath: wreath, - wscr: wscr, - xcap: xcap, - xcirc: xcirc, - xcup: xcup, - xdtri: xdtri, - xfr: xfr, - xhArr: xhArr, - xharr: xharr, - xi: xi, - xlArr: xlArr, - xlarr: xlarr, - xmap: xmap, - xnis: xnis, - xodot: xodot, - xopf: xopf, - xoplus: xoplus, - xotime: xotime, - xrArr: xrArr, - xrarr: xrarr, - xscr: xscr, - xsqcup: xsqcup, - xuplus: xuplus, - xutri: xutri, - xvee: xvee, - xwedge: xwedge, - yacut: yacut, - yacute: yacute, - yacy: yacy, - ycirc: ycirc, - ycy: ycy, - ye: ye, - yen: yen, - yfr: yfr, - yicy: yicy, - yopf: yopf, - yscr: yscr, - yucy: yucy, - yum: yum, - yuml: yuml, - zacute: zacute, - zcaron: zcaron, - zcy: zcy, - zdot: zdot, - zeetrf: zeetrf, - zeta: zeta, - zfr: zfr, - zhcy: zhcy, - zigrarr: zigrarr, - zopf: zopf, - zscr: zscr, - zwj: zwj, - zwnj: zwnj -}; - -var decodeEntity_1 = decodeEntity; - -var own$2 = {}.hasOwnProperty; - -function decodeEntity(characters) { - return own$2.call(characterEntities, characters) - ? characterEntities[characters] - : false -} - -var parseEntities_1 = parseEntities; - -var own$1 = {}.hasOwnProperty; -var fromCharCode = String.fromCharCode; -var noop = Function.prototype; - -// Default settings. -var defaults$2 = { - warning: null, - reference: null, - text: null, - warningContext: null, - referenceContext: null, - textContext: null, - position: {}, - additional: null, - attribute: false, - nonTerminated: true -}; - -// Characters. -var tab = 9; // '\t' -var lineFeed = 10; // '\n' -var formFeed = 12; // '\f' -var space = 32; // ' ' -var ampersand = 38; // '&' -var semicolon = 59; // ';' -var lessThan = 60; // '<' -var equalsTo = 61; // '=' -var numberSign = 35; // '#' -var uppercaseX = 88; // 'X' -var lowercaseX = 120; // 'x' -var replacementCharacter = 65533; // '�' - -// Reference types. -var name = 'named'; -var hexa = 'hexadecimal'; -var deci = 'decimal'; - -// Map of bases. -var bases = {}; - -bases[hexa] = 16; -bases[deci] = 10; - -// Map of types to tests. -// Each type of character reference accepts different characters. -// This test is used to detect whether a reference has ended (as the semicolon -// is not strictly needed). -var tests = {}; - -tests[name] = isAlphanumerical; -tests[deci] = isDecimal; -tests[hexa] = isHexadecimal; - -// Warning types. -var namedNotTerminated = 1; -var numericNotTerminated = 2; -var namedEmpty = 3; -var numericEmpty = 4; -var namedUnknown = 5; -var numericDisallowed = 6; -var numericProhibited = 7; - -// Warning messages. -var messages = {}; - -messages[namedNotTerminated] = - 'Named character references must be terminated by a semicolon'; -messages[numericNotTerminated] = - 'Numeric character references must be terminated by a semicolon'; -messages[namedEmpty] = 'Named character references cannot be empty'; -messages[numericEmpty] = 'Numeric character references cannot be empty'; -messages[namedUnknown] = 'Named character references must be known'; -messages[numericDisallowed] = - 'Numeric character references cannot be disallowed'; -messages[numericProhibited] = - 'Numeric character references cannot be outside the permissible Unicode range'; - -// Wrap to ensure clean parameters are given to `parse`. -function parseEntities(value, options) { - var settings = {}; - var option; - var key; - - if (!options) { - options = {}; - } - - for (key in defaults$2) { - option = options[key]; - settings[key] = - option === null || option === undefined ? defaults$2[key] : option; - } - - if (settings.position.indent || settings.position.start) { - settings.indent = settings.position.indent || []; - settings.position = settings.position.start; - } - - return parse$2(value, settings) -} - -// Parse entities. -// eslint-disable-next-line complexity -function parse$2(value, settings) { - var additional = settings.additional; - var nonTerminated = settings.nonTerminated; - var handleText = settings.text; - var handleReference = settings.reference; - var handleWarning = settings.warning; - var textContext = settings.textContext; - var referenceContext = settings.referenceContext; - var warningContext = settings.warningContext; - var pos = settings.position; - var indent = settings.indent || []; - var length = value.length; - var index = 0; - var lines = -1; - var column = pos.column || 1; - var line = pos.line || 1; - var queue = ''; - var result = []; - var entityCharacters; - var namedEntity; - var terminated; - var characters; - var character; - var reference; - var following; - var warning; - var reason; - var output; - var entity; - var begin; - var start; - var type; - var test; - var prev; - var next; - var diff; - var end; - - if (typeof additional === 'string') { - additional = additional.charCodeAt(0); - } - - // Cache the current point. - prev = now(); - - // Wrap `handleWarning`. - warning = handleWarning ? parseError : noop; - - // Ensure the algorithm walks over the first character and the end (inclusive). - index--; - length++; - - while (++index < length) { - // If the previous character was a newline. - if (character === lineFeed) { - column = indent[lines] || 1; - } - - character = value.charCodeAt(index); - - if (character === ampersand) { - following = value.charCodeAt(index + 1); - - // The behaviour depends on the identity of the next character. - if ( - following === tab || - following === lineFeed || - following === formFeed || - following === space || - following === ampersand || - following === lessThan || - following !== following || - (additional && following === additional) - ) { - // Not a character reference. - // No characters are consumed, and nothing is returned. - // This is not an error, either. - queue += fromCharCode(character); - column++; - - continue - } - - start = index + 1; - begin = start; - end = start; - - if (following === numberSign) { - // Numerical entity. - end = ++begin; - - // The behaviour further depends on the next character. - following = value.charCodeAt(end); - - if (following === uppercaseX || following === lowercaseX) { - // ASCII hex digits. - type = hexa; - end = ++begin; - } else { - // ASCII digits. - type = deci; - } - } else { - // Named entity. - type = name; - } - - entityCharacters = ''; - entity = ''; - characters = ''; - test = tests[type]; - end--; - - while (++end < length) { - following = value.charCodeAt(end); - - if (!test(following)) { - break - } - - characters += fromCharCode(following); - - // Check if we can match a legacy named reference. - // If so, we cache that as the last viable named reference. - // This ensures we do not need to walk backwards later. - if (type === name && own$1.call(legacy, characters)) { - entityCharacters = characters; - entity = legacy[characters]; - } - } - - terminated = value.charCodeAt(end) === semicolon; - - if (terminated) { - end++; - - namedEntity = type === name ? decodeEntity_1(characters) : false; - - if (namedEntity) { - entityCharacters = characters; - entity = namedEntity; - } - } - - diff = 1 + end - start; - - if (!terminated && !nonTerminated) ; else if (!characters) { - // An empty (possible) entity is valid, unless it’s numeric (thus an - // ampersand followed by an octothorp). - if (type !== name) { - warning(numericEmpty, diff); - } - } else if (type === name) { - // An ampersand followed by anything unknown, and not terminated, is - // invalid. - if (terminated && !entity) { - warning(namedUnknown, 1); - } else { - // If theres something after an entity name which is not known, cap - // the reference. - if (entityCharacters !== characters) { - end = begin + entityCharacters.length; - diff = 1 + end - begin; - terminated = false; - } - - // If the reference is not terminated, warn. - if (!terminated) { - reason = entityCharacters ? namedNotTerminated : namedEmpty; - - if (settings.attribute) { - following = value.charCodeAt(end); - - if (following === equalsTo) { - warning(reason, diff); - entity = null; - } else if (isAlphanumerical(following)) { - entity = null; - } else { - warning(reason, diff); - } - } else { - warning(reason, diff); - } - } - } - - reference = entity; - } else { - if (!terminated) { - // All non-terminated numeric entities are not rendered, and trigger a - // warning. - warning(numericNotTerminated, diff); - } - - // When terminated and number, parse as either hexadecimal or decimal. - reference = parseInt(characters, bases[type]); - - // Trigger a warning when the parsed number is prohibited, and replace - // with replacement character. - if (prohibited(reference)) { - warning(numericProhibited, diff); - reference = fromCharCode(replacementCharacter); - } else if (reference in invalid) { - // Trigger a warning when the parsed number is disallowed, and replace - // by an alternative. - warning(numericDisallowed, diff); - reference = invalid[reference]; - } else { - // Parse the number. - output = ''; - - // Trigger a warning when the parsed number should not be used. - if (disallowed(reference)) { - warning(numericDisallowed, diff); - } - - // Stringify the number. - if (reference > 0xffff) { - reference -= 0x10000; - output += fromCharCode((reference >>> (10 & 0x3ff)) | 0xd800); - reference = 0xdc00 | (reference & 0x3ff); - } - - reference = output + fromCharCode(reference); - } - } - - // Found it! - // First eat the queued characters as normal text, then eat an entity. - if (reference) { - flush(); - - prev = now(); - index = end - 1; - column += end - start + 1; - result.push(reference); - next = now(); - next.offset++; - - if (handleReference) { - handleReference.call( - referenceContext, - reference, - {start: prev, end: next}, - value.slice(start - 1, end) - ); - } - - prev = next; - } else { - // If we could not find a reference, queue the checked characters (as - // normal characters), and move the pointer to their end. - // This is possible because we can be certain neither newlines nor - // ampersands are included. - characters = value.slice(start - 1, end); - queue += characters; - column += characters.length; - index = end - 1; - } - } else { - // Handle anything other than an ampersand, including newlines and EOF. - if ( - character === 10 // Line feed - ) { - line++; - lines++; - column = 0; - } - - if (character === character) { - queue += fromCharCode(character); - column++; - } else { - flush(); - } - } - } - - // Return the reduced nodes, and any possible warnings. - return result.join('') - - // Get current position. - function now() { - return { - line: line, - column: column, - offset: index + (pos.offset || 0) - } - } - - // “Throw” a parse-error: a warning. - function parseError(code, offset) { - var position = now(); - - position.column += offset; - position.offset += offset; - - handleWarning.call(warningContext, messages[code], position, code); - } - - // Flush `queue` (normal text). - // Macro invoked before each entity and at the end of `value`. - // Does nothing when `queue` is empty. - function flush() { - if (queue) { - result.push(queue); - - if (handleText) { - handleText.call(textContext, queue, {start: prev, end: now()}); - } - - queue = ''; - } - } -} - -// Check if `character` is outside the permissible unicode range. -function prohibited(code) { - return (code >= 0xd800 && code <= 0xdfff) || code > 0x10ffff -} - -// Check if `character` is disallowed. -function disallowed(code) { - return ( - (code >= 0x0001 && code <= 0x0008) || - code === 0x000b || - (code >= 0x000d && code <= 0x001f) || - (code >= 0x007f && code <= 0x009f) || - (code >= 0xfdd0 && code <= 0xfdef) || - (code & 0xffff) === 0xffff || - (code & 0xffff) === 0xfffe - ) -} - -var decode = factory$1; - -/* Factory to create an entity decoder. */ -function factory$1(ctx) { - decoder.raw = decodeRaw; - - return decoder; - - /* Normalize `position` to add an `indent`. */ - function normalize(position) { - var offsets = ctx.offset; - var line = position.line; - var result = []; - - while (++line) { - if (!(line in offsets)) { - break; - } - - result.push((offsets[line] || 0) + 1); - } - - return { - start: position, - indent: result - }; - } - - /* Handle a warning. - * See https://github.com/wooorm/parse-entities - * for the warnings. */ - function handleWarning(reason, position, code) { - if (code === 3) { - return; - } - - ctx.file.message(reason, position); - } - - /* Decode `value` (at `position`) into text-nodes. */ - function decoder(value, position, handler) { - parseEntities_1(value, { - position: normalize(position), - warning: handleWarning, - text: handler, - reference: handler, - textContext: ctx, - referenceContext: ctx - }); - } - - /* Decode `value` (at `position`) into a string. */ - function decodeRaw(value, position, options) { - return parseEntities_1(value, immutable(options, { - position: normalize(position), - warning: handleWarning - })); - } -} - -var tokenizer = factory; - -var MERGEABLE_NODES = { - text: mergeText, - blockquote: mergeBlockquote -}; - -/* Check whether a node is mergeable with adjacent nodes. */ -function mergeable(node) { - var start; - var end; - - if (node.type !== 'text' || !node.position) { - return true; - } - - start = node.position.start; - end = node.position.end; - - /* Only merge nodes which occupy the same size as their - * `value`. */ - return start.line !== end.line || - end.column - start.column === node.value.length; -} - -/* Merge two text nodes: `node` into `prev`. */ -function mergeText(prev, node) { - prev.value += node.value; - - return prev; -} - -/* Merge two blockquotes: `node` into `prev`, unless in - * CommonMark mode. */ -function mergeBlockquote(prev, node) { - if (this.options.commonmark) { - return node; - } - - prev.children = prev.children.concat(node.children); - - return prev; -} - -/* Construct a tokenizer. This creates both - * `tokenizeInline` and `tokenizeBlock`. */ -function factory(type) { - return tokenize; - - /* Tokenizer for a bound `type`. */ - function tokenize(value, location) { - var self = this; - var offset = self.offset; - var tokens = []; - var methods = self[type + 'Methods']; - var tokenizers = self[type + 'Tokenizers']; - var line = location.line; - var column = location.column; - var index; - var length; - var method; - var name; - var matched; - var valueLength; - - /* Trim white space only lines. */ - if (!value) { - return tokens; - } - - /* Expose on `eat`. */ - eat.now = now; - eat.file = self.file; - - /* Sync initial offset. */ - updatePosition(''); - - /* Iterate over `value`, and iterate over all - * tokenizers. When one eats something, re-iterate - * with the remaining value. If no tokenizer eats, - * something failed (should not happen) and an - * exception is thrown. */ - while (value) { - index = -1; - length = methods.length; - matched = false; - - while (++index < length) { - name = methods[index]; - method = tokenizers[name]; - - if ( - method && - /* istanbul ignore next */ (!method.onlyAtStart || self.atStart) && - (!method.notInList || !self.inList) && - (!method.notInBlock || !self.inBlock) && - (!method.notInLink || !self.inLink) - ) { - valueLength = value.length; - - method.apply(self, [eat, value]); - - matched = valueLength !== value.length; - - if (matched) { - break; - } - } - } - - /* istanbul ignore if */ - if (!matched) { - self.file.fail(new Error('Infinite loop'), eat.now()); - } - } - - self.eof = now(); - - return tokens; - - /* Update line, column, and offset based on - * `value`. */ - function updatePosition(subvalue) { - var lastIndex = -1; - var index = subvalue.indexOf('\n'); - - while (index !== -1) { - line++; - lastIndex = index; - index = subvalue.indexOf('\n', index + 1); - } - - if (lastIndex === -1) { - column += subvalue.length; - } else { - column = subvalue.length - lastIndex; - } - - if (line in offset) { - if (lastIndex !== -1) { - column += offset[line]; - } else if (column <= offset[line]) { - column = offset[line] + 1; - } - } - } - - /* Get offset. Called before the first character is - * eaten to retrieve the range's offsets. */ - function getOffset() { - var indentation = []; - var pos = line + 1; - - /* Done. Called when the last character is - * eaten to retrieve the range’s offsets. */ - return function () { - var last = line + 1; - - while (pos < last) { - indentation.push((offset[pos] || 0) + 1); - - pos++; - } - - return indentation; - }; - } - - /* Get the current position. */ - function now() { - var pos = {line: line, column: column}; - - pos.offset = self.toOffset(pos); - - return pos; - } - - /* Store position information for a node. */ - function Position(start) { - this.start = start; - this.end = now(); - } - - /* Throw when a value is incorrectly eaten. - * This shouldn’t happen but will throw on new, - * incorrect rules. */ - function validateEat(subvalue) { - /* istanbul ignore if */ - if (value.substring(0, subvalue.length) !== subvalue) { - /* Capture stack-trace. */ - self.file.fail( - new Error( - 'Incorrectly eaten value: please report this ' + - 'warning on http://git.io/vg5Ft' - ), - now() - ); - } - } - - /* Mark position and patch `node.position`. */ - function position() { - var before = now(); - - return update; - - /* Add the position to a node. */ - function update(node, indent) { - var prev = node.position; - var start = prev ? prev.start : before; - var combined = []; - var n = prev && prev.end.line; - var l = before.line; - - node.position = new Position(start); - - /* If there was already a `position`, this - * node was merged. Fixing `start` wasn’t - * hard, but the indent is different. - * Especially because some information, the - * indent between `n` and `l` wasn’t - * tracked. Luckily, that space is - * (should be?) empty, so we can safely - * check for it now. */ - if (prev && indent && prev.indent) { - combined = prev.indent; - - if (n < l) { - while (++n < l) { - combined.push((offset[n] || 0) + 1); - } - - combined.push(before.column); - } - - indent = combined.concat(indent); - } - - node.position.indent = indent || []; - - return node; - } - } - - /* Add `node` to `parent`s children or to `tokens`. - * Performs merges where possible. */ - function add(node, parent) { - var children = parent ? parent.children : tokens; - var prev = children[children.length - 1]; - - if ( - prev && - node.type === prev.type && - node.type in MERGEABLE_NODES && - mergeable(prev) && - mergeable(node) - ) { - node = MERGEABLE_NODES[node.type].call(self, prev, node); - } - - if (node !== prev) { - children.push(node); - } - - if (self.atStart && tokens.length !== 0) { - self.exitStart(); - } - - return node; - } - - /* Remove `subvalue` from `value`. - * `subvalue` must be at the start of `value`. */ - function eat(subvalue) { - var indent = getOffset(); - var pos = position(); - var current = now(); - - validateEat(subvalue); - - apply.reset = reset; - reset.test = test; - apply.test = test; - - value = value.substring(subvalue.length); - - updatePosition(subvalue); - - indent = indent(); - - return apply; - - /* Add the given arguments, add `position` to - * the returned node, and return the node. */ - function apply(node, parent) { - return pos(add(pos(node), parent), indent); - } - - /* Functions just like apply, but resets the - * content: the line and column are reversed, - * and the eaten value is re-added. - * This is useful for nodes with a single - * type of content, such as lists and tables. - * See `apply` above for what parameters are - * expected. */ - function reset() { - var node = apply.apply(null, arguments); - - line = current.line; - column = current.column; - value = subvalue + value; - - return node; - } - - /* Test the position, after eating, and reverse - * to a not-eaten state. */ - function test() { - var result = pos({}); - - line = current.line; - column = current.column; - value = subvalue + value; - - return result.position; - } - } - } -} - -var markdownEscapes = escapes; - -var defaults$1 = [ - '\\', - '`', - '*', - '{', - '}', - '[', - ']', - '(', - ')', - '#', - '+', - '-', - '.', - '!', - '_', - '>' -]; - -var gfm = defaults$1.concat(['~', '|']); - -var commonmark = gfm.concat([ - '\n', - '"', - '$', - '%', - '&', - "'", - ',', - '/', - ':', - ';', - '<', - '=', - '?', - '@', - '^' -]); - -escapes.default = defaults$1; -escapes.gfm = gfm; -escapes.commonmark = commonmark; - -// Get markdown escapes. -function escapes(options) { - var settings = options || {}; - - if (settings.commonmark) { - return commonmark - } - - return settings.gfm ? gfm : defaults$1 -} - -var require$$0 = [ - "address", - "article", - "aside", - "base", - "basefont", - "blockquote", - "body", - "caption", - "center", - "col", - "colgroup", - "dd", - "details", - "dialog", - "dir", - "div", - "dl", - "dt", - "fieldset", - "figcaption", - "figure", - "footer", - "form", - "frame", - "frameset", - "h1", - "h2", - "h3", - "h4", - "h5", - "h6", - "head", - "header", - "hgroup", - "hr", - "html", - "iframe", - "legend", - "li", - "link", - "main", - "menu", - "menuitem", - "meta", - "nav", - "noframes", - "ol", - "optgroup", - "option", - "p", - "param", - "pre", - "section", - "source", - "title", - "summary", - "table", - "tbody", - "td", - "tfoot", - "th", - "thead", - "title", - "tr", - "track", - "ul" -]; - -var defaults = { - position: true, - gfm: true, - commonmark: false, - footnotes: false, - pedantic: false, - blocks: require$$0 -}; - -var setOptions_1 = setOptions; - -function setOptions(options) { - var self = this; - var current = self.options; - var key; - var value; - - if (options == null) { - options = {}; - } else if (typeof options === 'object') { - options = immutable(options); - } else { - throw new Error( - 'Invalid value `' + options + '` ' + - 'for setting `options`' - ); - } - - for (key in defaults) { - value = options[key]; - - if (value == null) { - value = current[key]; - } - - if ( - (key !== 'blocks' && typeof value !== 'boolean') || - (key === 'blocks' && typeof value !== 'object') - ) { - throw new Error('Invalid value `' + value + '` for setting `options.' + key + '`'); - } - - options[key] = value; - } - - self.options = options; - self.escape = markdownEscapes(options); - - return self; -} - -var convert_1 = convert; - -function convert(test) { - if (typeof test === 'string') { - return typeFactory(test) - } - - if (test === null || test === undefined) { - return ok - } - - if (typeof test === 'object') { - return ('length' in test ? anyFactory : matchesFactory)(test) - } - - if (typeof test === 'function') { - return test - } - - throw new Error('Expected function, string, or object as test') -} - -function convertAll(tests) { - var results = []; - var length = tests.length; - var index = -1; - - while (++index < length) { - results[index] = convert(tests[index]); - } - - return results -} - -// Utility assert each property in `test` is represented in `node`, and each -// values are strictly equal. -function matchesFactory(test) { - return matches - - function matches(node) { - var key; - - for (key in test) { - if (node[key] !== test[key]) { - return false - } - } - - return true - } -} - -function anyFactory(tests) { - var checks = convertAll(tests); - var length = checks.length; - - return matches - - function matches() { - var index = -1; - - while (++index < length) { - if (checks[index].apply(this, arguments)) { - return true - } - } - - return false - } -} - -// Utility to convert a string into a function which checks a given node’s type -// for said string. -function typeFactory(test) { - return type - - function type(node) { - return Boolean(node && node.type === test) - } -} - -// Utility to return true. -function ok() { - return true -} - -var unistUtilVisitParents = visitParents; - - - -var CONTINUE$1 = true; -var SKIP$1 = 'skip'; -var EXIT$1 = false; - -visitParents.CONTINUE = CONTINUE$1; -visitParents.SKIP = SKIP$1; -visitParents.EXIT = EXIT$1; - -function visitParents(tree, test, visitor, reverse) { - var is; - - if (typeof test === 'function' && typeof visitor !== 'function') { - reverse = visitor; - visitor = test; - test = null; - } - - is = convert_1(test); - - one(tree, null, []); - - // Visit a single node. - function one(node, index, parents) { - var result = []; - var subresult; - - if (!test || is(node, index, parents[parents.length - 1] || null)) { - result = toResult(visitor(node, parents)); - - if (result[0] === EXIT$1) { - return result - } - } - - if (node.children && result[0] !== SKIP$1) { - subresult = toResult(all(node.children, parents.concat(node))); - return subresult[0] === EXIT$1 ? subresult : result - } - - return result - } - - // Visit children in `parent`. - function all(children, parents) { - var min = -1; - var step = reverse ? -1 : 1; - var index = (reverse ? children.length : min) + step; - var result; - - while (index > min && index < children.length) { - result = one(children[index], index, parents); - - if (result[0] === EXIT$1) { - return result - } - - index = typeof result[1] === 'number' ? result[1] : index + step; - } - } -} - -function toResult(value) { - if (value !== null && typeof value === 'object' && 'length' in value) { - return value - } - - if (typeof value === 'number') { - return [CONTINUE$1, value] - } - - return [value] -} - -var unistUtilVisit = visit; - - - -var CONTINUE = unistUtilVisitParents.CONTINUE; -var SKIP = unistUtilVisitParents.SKIP; -var EXIT = unistUtilVisitParents.EXIT; - -visit.CONTINUE = CONTINUE; -visit.SKIP = SKIP; -visit.EXIT = EXIT; - -function visit(tree, test, visitor, reverse) { - if (typeof test === 'function' && typeof visitor !== 'function') { - reverse = visitor; - visitor = test; - test = null; - } - - unistUtilVisitParents(tree, test, overload, reverse); - - function overload(node, parents) { - var parent = parents[parents.length - 1]; - var index = parent ? parent.children.indexOf(node) : null; - return visitor(node, index, parent) - } -} - -var unistUtilRemovePosition = removePosition; - -function removePosition(node, force) { - unistUtilVisit(node, force ? hard : soft); - return node -} - -function hard(node) { - delete node.position; -} - -function soft(node) { - node.position = undefined; -} - -var parse_1 = parse$1; - -var C_NEWLINE$d = '\n'; -var EXPRESSION_LINE_BREAKS = /\r\n|\r/g; - -/* Parse the bound file. */ -function parse$1() { - var self = this; - var value = String(self.file); - var start = {line: 1, column: 1, offset: 0}; - var content = immutable(start); - var node; - - /* Clean non-unix newlines: `\r\n` and `\r` are all - * changed to `\n`. This should not affect positional - * information. */ - value = value.replace(EXPRESSION_LINE_BREAKS, C_NEWLINE$d); - - if (value.charCodeAt(0) === 0xFEFF) { - value = value.slice(1); - - content.column++; - content.offset++; - } - - node = { - type: 'root', - children: self.tokenizeBlock(value, content), - position: { - start: start, - end: self.eof || immutable(start) - } - }; - - if (!self.options.position) { - unistUtilRemovePosition(node, true); - } - - return node; -} - -var isWhitespaceCharacter = whitespace; - -var fromCode$1 = String.fromCharCode; -var re$1 = /\s/; - -// Check if the given character code, or the character code at the first -// character, is a whitespace character. -function whitespace(character) { - return re$1.test( - typeof character === 'number' ? fromCode$1(character) : character.charAt(0) - ) -} - -var newline_1 = newline; - -/* Tokenise newline. */ -function newline(eat, value, silent) { - var character = value.charAt(0); - var length; - var subvalue; - var queue; - var index; - - if (character !== '\n') { - return; - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - index = 1; - length = value.length; - subvalue = character; - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if (!isWhitespaceCharacter(character)) { - break; - } - - queue += character; - - if (character === '\n') { - subvalue += queue; - queue = ''; - } - - index++; - } - - eat(subvalue); -} - + */function L(r){return!!r.constructor&&"function"==typeof r.constructor.isBuffer&&r.constructor.isBuffer(r)}var S=C,O={}.hasOwnProperty,T=C.prototype;T.toString=function(r){var e=this.contents||"";return E(e)?e.toString(r):String(e)};var D=["history","path","basename","stem","extname","dirname"];function C(r){var e,t,n;if(r){if("string"==typeof r||E(r))r={contents:r};else if("message"in r&&"messages"in r)return r}else r={};if(!(this instanceof C))return new C(r);for(this.data={},this.messages=[],this.history=[],this.cwd=process.cwd(),t=-1,n=D.length;++ti.length;a&&i.push(n);try{e=r.apply(null,i)}catch(r){if(a&&t)throw r;return n(r)}a||(e&&"function"==typeof e.then?e.then(o,n):e instanceof Error?n(e):o(e))};function n(){t||(t=!0,e.apply(null,arguments))}function o(r){n(null,r)}};var V=G;G.wrap=P;var H=[].slice;function G(){var r=[],e={run:function(){var e=-1,t=H.call(arguments,0,-1),n=arguments[arguments.length-1];if("function"!=typeof n)throw new Error("Expected function as last argument, not "+n);function o(i){var a=r[++e],c=H.call(arguments,0),l=c.slice(1),s=t.length,u=-1;if(i)n(i);else{for(;++ue)return{line:t+1,column:e-(r[t-1]||0)+1,offset:e};return{}}}function pr(r){return function(e){var t=e&&e.line,n=e&&e.column;if(!isNaN(t)&&!isNaN(n)&&t-1 in r)return(r[t-2]||0)+n-1||0;return-1}}var hr=function(r,e){return function(t){var n,o=0,i=t.indexOf("\\"),a=r[e],c=[];for(;-1!==i;)c.push(t.slice(o,i)),o=i+1,(n=t.charAt(o))&&-1!==a.indexOf(n)||c.push("\\"),i=t.indexOf("\\",o);return c.push(t.slice(o)),c.join("")}};var dr={AElig:"Æ",AMP:"&",Aacute:"Á",Acirc:"Â",Agrave:"À",Aring:"Å",Atilde:"Ã",Auml:"Ä",COPY:"©",Ccedil:"Ç",ETH:"Ð",Eacute:"É",Ecirc:"Ê",Egrave:"È",Euml:"Ë",GT:">",Iacute:"Í",Icirc:"Î",Igrave:"Ì",Iuml:"Ï",LT:"<",Ntilde:"Ñ",Oacute:"Ó",Ocirc:"Ô",Ograve:"Ò",Oslash:"Ø",Otilde:"Õ",Ouml:"Ö",QUOT:'"',REG:"®",THORN:"Þ",Uacute:"Ú",Ucirc:"Û",Ugrave:"Ù",Uuml:"Ü",Yacute:"Ý",aacute:"á",acirc:"â",acute:"´",aelig:"æ",agrave:"à",amp:"&",aring:"å",atilde:"ã",auml:"ä",brvbar:"¦",ccedil:"ç",cedil:"¸",cent:"¢",copy:"©",curren:"¤",deg:"°",divide:"÷",eacute:"é",ecirc:"ê",egrave:"è",eth:"ð",euml:"ë",frac12:"½",frac14:"¼",frac34:"¾",gt:">",iacute:"í",icirc:"î",iexcl:"¡",igrave:"ì",iquest:"¿",iuml:"ï",laquo:"«",lt:"<",macr:"¯",micro:"µ",middot:"·",nbsp:" ",not:"¬",ntilde:"ñ",oacute:"ó",ocirc:"ô",ograve:"ò",ordf:"ª",ordm:"º",oslash:"ø",otilde:"õ",ouml:"ö",para:"¶",plusmn:"±",pound:"£",quot:'"',raquo:"»",reg:"®",sect:"§",shy:"­",sup1:"¹",sup2:"²",sup3:"³",szlig:"ß",thorn:"þ",times:"×",uacute:"ú",ucirc:"û",ugrave:"ù",uml:"¨",uuml:"ü",yacute:"ý",yen:"¥",yuml:"ÿ"},gr={0:"�",128:"€",130:"‚",131:"ƒ",132:"„",133:"…",134:"†",135:"‡",136:"ˆ",137:"‰",138:"Š",139:"‹",140:"Œ",142:"Ž",145:"‘",146:"’",147:"“",148:"”",149:"•",150:"–",151:"—",152:"˜",153:"™",154:"š",155:"›",156:"œ",158:"ž",159:"Ÿ"},mr=function(r){var e="string"==typeof r?r.charCodeAt(0):r;return e>=48&&e<=57};var br=function(r){var e="string"==typeof r?r.charCodeAt(0):r;return e>=97&&e<=102||e>=65&&e<=70||e>=48&&e<=57};var vr=function(r){var e="string"==typeof r?r.charCodeAt(0):r;return e>=97&&e<=122||e>=65&&e<=90};var yr=function(r){return vr(r)||mr(r)};var wr={AEli:"Æ",AElig:"Æ",AM:"&",AMP:"&",Aacut:"Á",Aacute:"Á",Abreve:"Ă",Acir:"Â",Acirc:"Â",Acy:"А",Afr:"𝔄",Agrav:"À",Agrave:"À",Alpha:"Α",Amacr:"Ā",And:"⩓",Aogon:"Ą",Aopf:"𝔸",ApplyFunction:"⁡",Arin:"Å",Aring:"Å",Ascr:"𝒜",Assign:"≔",Atild:"Ã",Atilde:"Ã",Aum:"Ä",Auml:"Ä",Backslash:"∖",Barv:"⫧",Barwed:"⌆",Bcy:"Б",Because:"∵",Bernoullis:"ℬ",Beta:"Β",Bfr:"𝔅",Bopf:"𝔹",Breve:"˘",Bscr:"ℬ",Bumpeq:"≎",CHcy:"Ч",COP:"©",COPY:"©",Cacute:"Ć",Cap:"⋒",CapitalDifferentialD:"ⅅ",Cayleys:"ℭ",Ccaron:"Č",Ccedi:"Ç",Ccedil:"Ç",Ccirc:"Ĉ",Cconint:"∰",Cdot:"Ċ",Cedilla:"¸",CenterDot:"·",Cfr:"ℭ",Chi:"Χ",CircleDot:"⊙",CircleMinus:"⊖",CirclePlus:"⊕",CircleTimes:"⊗",ClockwiseContourIntegral:"∲",CloseCurlyDoubleQuote:"”",CloseCurlyQuote:"’",Colon:"∷",Colone:"⩴",Congruent:"≡",Conint:"∯",ContourIntegral:"∮",Copf:"ℂ",Coproduct:"∐",CounterClockwiseContourIntegral:"∳",Cross:"⨯",Cscr:"𝒞",Cup:"⋓",CupCap:"≍",DD:"ⅅ",DDotrahd:"⤑",DJcy:"Ђ",DScy:"Ѕ",DZcy:"Џ",Dagger:"‡",Darr:"↡",Dashv:"⫤",Dcaron:"Ď",Dcy:"Д",Del:"∇",Delta:"Δ",Dfr:"𝔇",DiacriticalAcute:"´",DiacriticalDot:"˙",DiacriticalDoubleAcute:"˝",DiacriticalGrave:"`",DiacriticalTilde:"˜",Diamond:"⋄",DifferentialD:"ⅆ",Dopf:"𝔻",Dot:"¨",DotDot:"⃜",DotEqual:"≐",DoubleContourIntegral:"∯",DoubleDot:"¨",DoubleDownArrow:"⇓",DoubleLeftArrow:"⇐",DoubleLeftRightArrow:"⇔",DoubleLeftTee:"⫤",DoubleLongLeftArrow:"⟸",DoubleLongLeftRightArrow:"⟺",DoubleLongRightArrow:"⟹",DoubleRightArrow:"⇒",DoubleRightTee:"⊨",DoubleUpArrow:"⇑",DoubleUpDownArrow:"⇕",DoubleVerticalBar:"∥",DownArrow:"↓",DownArrowBar:"⤓",DownArrowUpArrow:"⇵",DownBreve:"̑",DownLeftRightVector:"⥐",DownLeftTeeVector:"⥞",DownLeftVector:"↽",DownLeftVectorBar:"⥖",DownRightTeeVector:"⥟",DownRightVector:"⇁",DownRightVectorBar:"⥗",DownTee:"⊤",DownTeeArrow:"↧",Downarrow:"⇓",Dscr:"𝒟",Dstrok:"Đ",ENG:"Ŋ",ET:"Ð",ETH:"Ð",Eacut:"É",Eacute:"É",Ecaron:"Ě",Ecir:"Ê",Ecirc:"Ê",Ecy:"Э",Edot:"Ė",Efr:"𝔈",Egrav:"È",Egrave:"È",Element:"∈",Emacr:"Ē",EmptySmallSquare:"◻",EmptyVerySmallSquare:"▫",Eogon:"Ę",Eopf:"𝔼",Epsilon:"Ε",Equal:"⩵",EqualTilde:"≂",Equilibrium:"⇌",Escr:"ℰ",Esim:"⩳",Eta:"Η",Eum:"Ë",Euml:"Ë",Exists:"∃",ExponentialE:"ⅇ",Fcy:"Ф",Ffr:"𝔉",FilledSmallSquare:"◼",FilledVerySmallSquare:"▪",Fopf:"𝔽",ForAll:"∀",Fouriertrf:"ℱ",Fscr:"ℱ",GJcy:"Ѓ",G:">",GT:">",Gamma:"Γ",Gammad:"Ϝ",Gbreve:"Ğ",Gcedil:"Ģ",Gcirc:"Ĝ",Gcy:"Г",Gdot:"Ġ",Gfr:"𝔊",Gg:"⋙",Gopf:"𝔾",GreaterEqual:"≥",GreaterEqualLess:"⋛",GreaterFullEqual:"≧",GreaterGreater:"⪢",GreaterLess:"≷",GreaterSlantEqual:"⩾",GreaterTilde:"≳",Gscr:"𝒢",Gt:"≫",HARDcy:"Ъ",Hacek:"ˇ",Hat:"^",Hcirc:"Ĥ",Hfr:"ℌ",HilbertSpace:"ℋ",Hopf:"ℍ",HorizontalLine:"─",Hscr:"ℋ",Hstrok:"Ħ",HumpDownHump:"≎",HumpEqual:"≏",IEcy:"Е",IJlig:"IJ",IOcy:"Ё",Iacut:"Í",Iacute:"Í",Icir:"Î",Icirc:"Î",Icy:"И",Idot:"İ",Ifr:"ℑ",Igrav:"Ì",Igrave:"Ì",Im:"ℑ",Imacr:"Ī",ImaginaryI:"ⅈ",Implies:"⇒",Int:"∬",Integral:"∫",Intersection:"⋂",InvisibleComma:"⁣",InvisibleTimes:"⁢",Iogon:"Į",Iopf:"𝕀",Iota:"Ι",Iscr:"ℐ",Itilde:"Ĩ",Iukcy:"І",Ium:"Ï",Iuml:"Ï",Jcirc:"Ĵ",Jcy:"Й",Jfr:"𝔍",Jopf:"𝕁",Jscr:"𝒥",Jsercy:"Ј",Jukcy:"Є",KHcy:"Х",KJcy:"Ќ",Kappa:"Κ",Kcedil:"Ķ",Kcy:"К",Kfr:"𝔎",Kopf:"𝕂",Kscr:"𝒦",LJcy:"Љ",L:"<",LT:"<",Lacute:"Ĺ",Lambda:"Λ",Lang:"⟪",Laplacetrf:"ℒ",Larr:"↞",Lcaron:"Ľ",Lcedil:"Ļ",Lcy:"Л",LeftAngleBracket:"⟨",LeftArrow:"←",LeftArrowBar:"⇤",LeftArrowRightArrow:"⇆",LeftCeiling:"⌈",LeftDoubleBracket:"⟦",LeftDownTeeVector:"⥡",LeftDownVector:"⇃",LeftDownVectorBar:"⥙",LeftFloor:"⌊",LeftRightArrow:"↔",LeftRightVector:"⥎",LeftTee:"⊣",LeftTeeArrow:"↤",LeftTeeVector:"⥚",LeftTriangle:"⊲",LeftTriangleBar:"⧏",LeftTriangleEqual:"⊴",LeftUpDownVector:"⥑",LeftUpTeeVector:"⥠",LeftUpVector:"↿",LeftUpVectorBar:"⥘",LeftVector:"↼",LeftVectorBar:"⥒",Leftarrow:"⇐",Leftrightarrow:"⇔",LessEqualGreater:"⋚",LessFullEqual:"≦",LessGreater:"≶",LessLess:"⪡",LessSlantEqual:"⩽",LessTilde:"≲",Lfr:"𝔏",Ll:"⋘",Lleftarrow:"⇚",Lmidot:"Ŀ",LongLeftArrow:"⟵",LongLeftRightArrow:"⟷",LongRightArrow:"⟶",Longleftarrow:"⟸",Longleftrightarrow:"⟺",Longrightarrow:"⟹",Lopf:"𝕃",LowerLeftArrow:"↙",LowerRightArrow:"↘",Lscr:"ℒ",Lsh:"↰",Lstrok:"Ł",Lt:"≪",Map:"⤅",Mcy:"М",MediumSpace:" ",Mellintrf:"ℳ",Mfr:"𝔐",MinusPlus:"∓",Mopf:"𝕄",Mscr:"ℳ",Mu:"Μ",NJcy:"Њ",Nacute:"Ń",Ncaron:"Ň",Ncedil:"Ņ",Ncy:"Н",NegativeMediumSpace:"​",NegativeThickSpace:"​",NegativeThinSpace:"​",NegativeVeryThinSpace:"​",NestedGreaterGreater:"≫",NestedLessLess:"≪",NewLine:"\n",Nfr:"𝔑",NoBreak:"⁠",NonBreakingSpace:" ",Nopf:"ℕ",Not:"⫬",NotCongruent:"≢",NotCupCap:"≭",NotDoubleVerticalBar:"∦",NotElement:"∉",NotEqual:"≠",NotEqualTilde:"≂̸",NotExists:"∄",NotGreater:"≯",NotGreaterEqual:"≱",NotGreaterFullEqual:"≧̸",NotGreaterGreater:"≫̸",NotGreaterLess:"≹",NotGreaterSlantEqual:"⩾̸",NotGreaterTilde:"≵",NotHumpDownHump:"≎̸",NotHumpEqual:"≏̸",NotLeftTriangle:"⋪",NotLeftTriangleBar:"⧏̸",NotLeftTriangleEqual:"⋬",NotLess:"≮",NotLessEqual:"≰",NotLessGreater:"≸",NotLessLess:"≪̸",NotLessSlantEqual:"⩽̸",NotLessTilde:"≴",NotNestedGreaterGreater:"⪢̸",NotNestedLessLess:"⪡̸",NotPrecedes:"⊀",NotPrecedesEqual:"⪯̸",NotPrecedesSlantEqual:"⋠",NotReverseElement:"∌",NotRightTriangle:"⋫",NotRightTriangleBar:"⧐̸",NotRightTriangleEqual:"⋭",NotSquareSubset:"⊏̸",NotSquareSubsetEqual:"⋢",NotSquareSuperset:"⊐̸",NotSquareSupersetEqual:"⋣",NotSubset:"⊂⃒",NotSubsetEqual:"⊈",NotSucceeds:"⊁",NotSucceedsEqual:"⪰̸",NotSucceedsSlantEqual:"⋡",NotSucceedsTilde:"≿̸",NotSuperset:"⊃⃒",NotSupersetEqual:"⊉",NotTilde:"≁",NotTildeEqual:"≄",NotTildeFullEqual:"≇",NotTildeTilde:"≉",NotVerticalBar:"∤",Nscr:"𝒩",Ntild:"Ñ",Ntilde:"Ñ",Nu:"Ν",OElig:"Œ",Oacut:"Ó",Oacute:"Ó",Ocir:"Ô",Ocirc:"Ô",Ocy:"О",Odblac:"Ő",Ofr:"𝔒",Ograv:"Ò",Ograve:"Ò",Omacr:"Ō",Omega:"Ω",Omicron:"Ο",Oopf:"𝕆",OpenCurlyDoubleQuote:"“",OpenCurlyQuote:"‘",Or:"⩔",Oscr:"𝒪",Oslas:"Ø",Oslash:"Ø",Otild:"Õ",Otilde:"Õ",Otimes:"⨷",Oum:"Ö",Ouml:"Ö",OverBar:"‾",OverBrace:"⏞",OverBracket:"⎴",OverParenthesis:"⏜",PartialD:"∂",Pcy:"П",Pfr:"𝔓",Phi:"Φ",Pi:"Π",PlusMinus:"±",Poincareplane:"ℌ",Popf:"ℙ",Pr:"⪻",Precedes:"≺",PrecedesEqual:"⪯",PrecedesSlantEqual:"≼",PrecedesTilde:"≾",Prime:"″",Product:"∏",Proportion:"∷",Proportional:"∝",Pscr:"𝒫",Psi:"Ψ",QUO:'"',QUOT:'"',Qfr:"𝔔",Qopf:"ℚ",Qscr:"𝒬",RBarr:"⤐",RE:"®",REG:"®",Racute:"Ŕ",Rang:"⟫",Rarr:"↠",Rarrtl:"⤖",Rcaron:"Ř",Rcedil:"Ŗ",Rcy:"Р",Re:"ℜ",ReverseElement:"∋",ReverseEquilibrium:"⇋",ReverseUpEquilibrium:"⥯",Rfr:"ℜ",Rho:"Ρ",RightAngleBracket:"⟩",RightArrow:"→",RightArrowBar:"⇥",RightArrowLeftArrow:"⇄",RightCeiling:"⌉",RightDoubleBracket:"⟧",RightDownTeeVector:"⥝",RightDownVector:"⇂",RightDownVectorBar:"⥕",RightFloor:"⌋",RightTee:"⊢",RightTeeArrow:"↦",RightTeeVector:"⥛",RightTriangle:"⊳",RightTriangleBar:"⧐",RightTriangleEqual:"⊵",RightUpDownVector:"⥏",RightUpTeeVector:"⥜",RightUpVector:"↾",RightUpVectorBar:"⥔",RightVector:"⇀",RightVectorBar:"⥓",Rightarrow:"⇒",Ropf:"ℝ",RoundImplies:"⥰",Rrightarrow:"⇛",Rscr:"ℛ",Rsh:"↱",RuleDelayed:"⧴",SHCHcy:"Щ",SHcy:"Ш",SOFTcy:"Ь",Sacute:"Ś",Sc:"⪼",Scaron:"Š",Scedil:"Ş",Scirc:"Ŝ",Scy:"С",Sfr:"𝔖",ShortDownArrow:"↓",ShortLeftArrow:"←",ShortRightArrow:"→",ShortUpArrow:"↑",Sigma:"Σ",SmallCircle:"∘",Sopf:"𝕊",Sqrt:"√",Square:"□",SquareIntersection:"⊓",SquareSubset:"⊏",SquareSubsetEqual:"⊑",SquareSuperset:"⊐",SquareSupersetEqual:"⊒",SquareUnion:"⊔",Sscr:"𝒮",Star:"⋆",Sub:"⋐",Subset:"⋐",SubsetEqual:"⊆",Succeeds:"≻",SucceedsEqual:"⪰",SucceedsSlantEqual:"≽",SucceedsTilde:"≿",SuchThat:"∋",Sum:"∑",Sup:"⋑",Superset:"⊃",SupersetEqual:"⊇",Supset:"⋑",THOR:"Þ",THORN:"Þ",TRADE:"™",TSHcy:"Ћ",TScy:"Ц",Tab:"\t",Tau:"Τ",Tcaron:"Ť",Tcedil:"Ţ",Tcy:"Т",Tfr:"𝔗",Therefore:"∴",Theta:"Θ",ThickSpace:"  ",ThinSpace:" ",Tilde:"∼",TildeEqual:"≃",TildeFullEqual:"≅",TildeTilde:"≈",Topf:"𝕋",TripleDot:"⃛",Tscr:"𝒯",Tstrok:"Ŧ",Uacut:"Ú",Uacute:"Ú",Uarr:"↟",Uarrocir:"⥉",Ubrcy:"Ў",Ubreve:"Ŭ",Ucir:"Û",Ucirc:"Û",Ucy:"У",Udblac:"Ű",Ufr:"𝔘",Ugrav:"Ù",Ugrave:"Ù",Umacr:"Ū",UnderBar:"_",UnderBrace:"⏟",UnderBracket:"⎵",UnderParenthesis:"⏝",Union:"⋃",UnionPlus:"⊎",Uogon:"Ų",Uopf:"𝕌",UpArrow:"↑",UpArrowBar:"⤒",UpArrowDownArrow:"⇅",UpDownArrow:"↕",UpEquilibrium:"⥮",UpTee:"⊥",UpTeeArrow:"↥",Uparrow:"⇑",Updownarrow:"⇕",UpperLeftArrow:"↖",UpperRightArrow:"↗",Upsi:"ϒ",Upsilon:"Υ",Uring:"Ů",Uscr:"𝒰",Utilde:"Ũ",Uum:"Ü",Uuml:"Ü",VDash:"⊫",Vbar:"⫫",Vcy:"В",Vdash:"⊩",Vdashl:"⫦",Vee:"⋁",Verbar:"‖",Vert:"‖",VerticalBar:"∣",VerticalLine:"|",VerticalSeparator:"❘",VerticalTilde:"≀",VeryThinSpace:" ",Vfr:"𝔙",Vopf:"𝕍",Vscr:"𝒱",Vvdash:"⊪",Wcirc:"Ŵ",Wedge:"⋀",Wfr:"𝔚",Wopf:"𝕎",Wscr:"𝒲",Xfr:"𝔛",Xi:"Ξ",Xopf:"𝕏",Xscr:"𝒳",YAcy:"Я",YIcy:"Ї",YUcy:"Ю",Yacut:"Ý",Yacute:"Ý",Ycirc:"Ŷ",Ycy:"Ы",Yfr:"𝔜",Yopf:"𝕐",Yscr:"𝒴",Yuml:"Ÿ",ZHcy:"Ж",Zacute:"Ź",Zcaron:"Ž",Zcy:"З",Zdot:"Ż",ZeroWidthSpace:"​",Zeta:"Ζ",Zfr:"ℨ",Zopf:"ℤ",Zscr:"𝒵",aacut:"á",aacute:"á",abreve:"ă",ac:"∾",acE:"∾̳",acd:"∿",acir:"â",acirc:"â",acut:"´",acute:"´",acy:"а",aeli:"æ",aelig:"æ",af:"⁡",afr:"𝔞",agrav:"à",agrave:"à",alefsym:"ℵ",aleph:"ℵ",alpha:"α",amacr:"ā",amalg:"⨿",am:"&",amp:"&",and:"∧",andand:"⩕",andd:"⩜",andslope:"⩘",andv:"⩚",ang:"∠",ange:"⦤",angle:"∠",angmsd:"∡",angmsdaa:"⦨",angmsdab:"⦩",angmsdac:"⦪",angmsdad:"⦫",angmsdae:"⦬",angmsdaf:"⦭",angmsdag:"⦮",angmsdah:"⦯",angrt:"∟",angrtvb:"⊾",angrtvbd:"⦝",angsph:"∢",angst:"Å",angzarr:"⍼",aogon:"ą",aopf:"𝕒",ap:"≈",apE:"⩰",apacir:"⩯",ape:"≊",apid:"≋",apos:"'",approx:"≈",approxeq:"≊",arin:"å",aring:"å",ascr:"𝒶",ast:"*",asymp:"≈",asympeq:"≍",atild:"ã",atilde:"ã",aum:"ä",auml:"ä",awconint:"∳",awint:"⨑",bNot:"⫭",backcong:"≌",backepsilon:"϶",backprime:"‵",backsim:"∽",backsimeq:"⋍",barvee:"⊽",barwed:"⌅",barwedge:"⌅",bbrk:"⎵",bbrktbrk:"⎶",bcong:"≌",bcy:"б",bdquo:"„",becaus:"∵",because:"∵",bemptyv:"⦰",bepsi:"϶",bernou:"ℬ",beta:"β",beth:"ℶ",between:"≬",bfr:"𝔟",bigcap:"⋂",bigcirc:"◯",bigcup:"⋃",bigodot:"⨀",bigoplus:"⨁",bigotimes:"⨂",bigsqcup:"⨆",bigstar:"★",bigtriangledown:"▽",bigtriangleup:"△",biguplus:"⨄",bigvee:"⋁",bigwedge:"⋀",bkarow:"⤍",blacklozenge:"⧫",blacksquare:"▪",blacktriangle:"▴",blacktriangledown:"▾",blacktriangleleft:"◂",blacktriangleright:"▸",blank:"␣",blk12:"▒",blk14:"░",blk34:"▓",block:"█",bne:"=⃥",bnequiv:"≡⃥",bnot:"⌐",bopf:"𝕓",bot:"⊥",bottom:"⊥",bowtie:"⋈",boxDL:"╗",boxDR:"╔",boxDl:"╖",boxDr:"╓",boxH:"═",boxHD:"╦",boxHU:"╩",boxHd:"╤",boxHu:"╧",boxUL:"╝",boxUR:"╚",boxUl:"╜",boxUr:"╙",boxV:"║",boxVH:"╬",boxVL:"╣",boxVR:"╠",boxVh:"╫",boxVl:"╢",boxVr:"╟",boxbox:"⧉",boxdL:"╕",boxdR:"╒",boxdl:"┐",boxdr:"┌",boxh:"─",boxhD:"╥",boxhU:"╨",boxhd:"┬",boxhu:"┴",boxminus:"⊟",boxplus:"⊞",boxtimes:"⊠",boxuL:"╛",boxuR:"╘",boxul:"┘",boxur:"└",boxv:"│",boxvH:"╪",boxvL:"╡",boxvR:"╞",boxvh:"┼",boxvl:"┤",boxvr:"├",bprime:"‵",breve:"˘",brvba:"¦",brvbar:"¦",bscr:"𝒷",bsemi:"⁏",bsim:"∽",bsime:"⋍",bsol:"\\",bsolb:"⧅",bsolhsub:"⟈",bull:"•",bullet:"•",bump:"≎",bumpE:"⪮",bumpe:"≏",bumpeq:"≏",cacute:"ć",cap:"∩",capand:"⩄",capbrcup:"⩉",capcap:"⩋",capcup:"⩇",capdot:"⩀",caps:"∩︀",caret:"⁁",caron:"ˇ",ccaps:"⩍",ccaron:"č",ccedi:"ç",ccedil:"ç",ccirc:"ĉ",ccups:"⩌",ccupssm:"⩐",cdot:"ċ",cedi:"¸",cedil:"¸",cemptyv:"⦲",cen:"¢",cent:"¢",centerdot:"·",cfr:"𝔠",chcy:"ч",check:"✓",checkmark:"✓",chi:"χ",cir:"○",cirE:"⧃",circ:"ˆ",circeq:"≗",circlearrowleft:"↺",circlearrowright:"↻",circledR:"®",circledS:"Ⓢ",circledast:"⊛",circledcirc:"⊚",circleddash:"⊝",cire:"≗",cirfnint:"⨐",cirmid:"⫯",cirscir:"⧂",clubs:"♣",clubsuit:"♣",colon:":",colone:"≔",coloneq:"≔",comma:",",commat:"@",comp:"∁",compfn:"∘",complement:"∁",complexes:"ℂ",cong:"≅",congdot:"⩭",conint:"∮",copf:"𝕔",coprod:"∐",cop:"©",copy:"©",copysr:"℗",crarr:"↵",cross:"✗",cscr:"𝒸",csub:"⫏",csube:"⫑",csup:"⫐",csupe:"⫒",ctdot:"⋯",cudarrl:"⤸",cudarrr:"⤵",cuepr:"⋞",cuesc:"⋟",cularr:"↶",cularrp:"⤽",cup:"∪",cupbrcap:"⩈",cupcap:"⩆",cupcup:"⩊",cupdot:"⊍",cupor:"⩅",cups:"∪︀",curarr:"↷",curarrm:"⤼",curlyeqprec:"⋞",curlyeqsucc:"⋟",curlyvee:"⋎",curlywedge:"⋏",curre:"¤",curren:"¤",curvearrowleft:"↶",curvearrowright:"↷",cuvee:"⋎",cuwed:"⋏",cwconint:"∲",cwint:"∱",cylcty:"⌭",dArr:"⇓",dHar:"⥥",dagger:"†",daleth:"ℸ",darr:"↓",dash:"‐",dashv:"⊣",dbkarow:"⤏",dblac:"˝",dcaron:"ď",dcy:"д",dd:"ⅆ",ddagger:"‡",ddarr:"⇊",ddotseq:"⩷",de:"°",deg:"°",delta:"δ",demptyv:"⦱",dfisht:"⥿",dfr:"𝔡",dharl:"⇃",dharr:"⇂",diam:"⋄",diamond:"⋄",diamondsuit:"♦",diams:"♦",die:"¨",digamma:"ϝ",disin:"⋲",div:"÷",divid:"÷",divide:"÷",divideontimes:"⋇",divonx:"⋇",djcy:"ђ",dlcorn:"⌞",dlcrop:"⌍",dollar:"$",dopf:"𝕕",dot:"˙",doteq:"≐",doteqdot:"≑",dotminus:"∸",dotplus:"∔",dotsquare:"⊡",doublebarwedge:"⌆",downarrow:"↓",downdownarrows:"⇊",downharpoonleft:"⇃",downharpoonright:"⇂",drbkarow:"⤐",drcorn:"⌟",drcrop:"⌌",dscr:"𝒹",dscy:"ѕ",dsol:"⧶",dstrok:"đ",dtdot:"⋱",dtri:"▿",dtrif:"▾",duarr:"⇵",duhar:"⥯",dwangle:"⦦",dzcy:"џ",dzigrarr:"⟿",eDDot:"⩷",eDot:"≑",eacut:"é",eacute:"é",easter:"⩮",ecaron:"ě",ecir:"ê",ecirc:"ê",ecolon:"≕",ecy:"э",edot:"ė",ee:"ⅇ",efDot:"≒",efr:"𝔢",eg:"⪚",egrav:"è",egrave:"è",egs:"⪖",egsdot:"⪘",el:"⪙",elinters:"⏧",ell:"ℓ",els:"⪕",elsdot:"⪗",emacr:"ē",empty:"∅",emptyset:"∅",emptyv:"∅",emsp13:" ",emsp14:" ",emsp:" ",eng:"ŋ",ensp:" ",eogon:"ę",eopf:"𝕖",epar:"⋕",eparsl:"⧣",eplus:"⩱",epsi:"ε",epsilon:"ε",epsiv:"ϵ",eqcirc:"≖",eqcolon:"≕",eqsim:"≂",eqslantgtr:"⪖",eqslantless:"⪕",equals:"=",equest:"≟",equiv:"≡",equivDD:"⩸",eqvparsl:"⧥",erDot:"≓",erarr:"⥱",escr:"ℯ",esdot:"≐",esim:"≂",eta:"η",et:"ð",eth:"ð",eum:"ë",euml:"ë",euro:"€",excl:"!",exist:"∃",expectation:"ℰ",exponentiale:"ⅇ",fallingdotseq:"≒",fcy:"ф",female:"♀",ffilig:"ffi",fflig:"ff",ffllig:"ffl",ffr:"𝔣",filig:"fi",fjlig:"fj",flat:"♭",fllig:"fl",fltns:"▱",fnof:"ƒ",fopf:"𝕗",forall:"∀",fork:"⋔",forkv:"⫙",fpartint:"⨍",frac1:"¼",frac12:"½",frac13:"⅓",frac14:"¼",frac15:"⅕",frac16:"⅙",frac18:"⅛",frac23:"⅔",frac25:"⅖",frac3:"¾",frac34:"¾",frac35:"⅗",frac38:"⅜",frac45:"⅘",frac56:"⅚",frac58:"⅝",frac78:"⅞",frasl:"⁄",frown:"⌢",fscr:"𝒻",gE:"≧",gEl:"⪌",gacute:"ǵ",gamma:"γ",gammad:"ϝ",gap:"⪆",gbreve:"ğ",gcirc:"ĝ",gcy:"г",gdot:"ġ",ge:"≥",gel:"⋛",geq:"≥",geqq:"≧",geqslant:"⩾",ges:"⩾",gescc:"⪩",gesdot:"⪀",gesdoto:"⪂",gesdotol:"⪄",gesl:"⋛︀",gesles:"⪔",gfr:"𝔤",gg:"≫",ggg:"⋙",gimel:"ℷ",gjcy:"ѓ",gl:"≷",glE:"⪒",gla:"⪥",glj:"⪤",gnE:"≩",gnap:"⪊",gnapprox:"⪊",gne:"⪈",gneq:"⪈",gneqq:"≩",gnsim:"⋧",gopf:"𝕘",grave:"`",gscr:"ℊ",gsim:"≳",gsime:"⪎",gsiml:"⪐",g:">",gt:">",gtcc:"⪧",gtcir:"⩺",gtdot:"⋗",gtlPar:"⦕",gtquest:"⩼",gtrapprox:"⪆",gtrarr:"⥸",gtrdot:"⋗",gtreqless:"⋛",gtreqqless:"⪌",gtrless:"≷",gtrsim:"≳",gvertneqq:"≩︀",gvnE:"≩︀",hArr:"⇔",hairsp:" ",half:"½",hamilt:"ℋ",hardcy:"ъ",harr:"↔",harrcir:"⥈",harrw:"↭",hbar:"ℏ",hcirc:"ĥ",hearts:"♥",heartsuit:"♥",hellip:"…",hercon:"⊹",hfr:"𝔥",hksearow:"⤥",hkswarow:"⤦",hoarr:"⇿",homtht:"∻",hookleftarrow:"↩",hookrightarrow:"↪",hopf:"𝕙",horbar:"―",hscr:"𝒽",hslash:"ℏ",hstrok:"ħ",hybull:"⁃",hyphen:"‐",iacut:"í",iacute:"í",ic:"⁣",icir:"î",icirc:"î",icy:"и",iecy:"е",iexc:"¡",iexcl:"¡",iff:"⇔",ifr:"𝔦",igrav:"ì",igrave:"ì",ii:"ⅈ",iiiint:"⨌",iiint:"∭",iinfin:"⧜",iiota:"℩",ijlig:"ij",imacr:"ī",image:"ℑ",imagline:"ℐ",imagpart:"ℑ",imath:"ı",imof:"⊷",imped:"Ƶ",in:"∈",incare:"℅",infin:"∞",infintie:"⧝",inodot:"ı",int:"∫",intcal:"⊺",integers:"ℤ",intercal:"⊺",intlarhk:"⨗",intprod:"⨼",iocy:"ё",iogon:"į",iopf:"𝕚",iota:"ι",iprod:"⨼",iques:"¿",iquest:"¿",iscr:"𝒾",isin:"∈",isinE:"⋹",isindot:"⋵",isins:"⋴",isinsv:"⋳",isinv:"∈",it:"⁢",itilde:"ĩ",iukcy:"і",ium:"ï",iuml:"ï",jcirc:"ĵ",jcy:"й",jfr:"𝔧",jmath:"ȷ",jopf:"𝕛",jscr:"𝒿",jsercy:"ј",jukcy:"є",kappa:"κ",kappav:"ϰ",kcedil:"ķ",kcy:"к",kfr:"𝔨",kgreen:"ĸ",khcy:"х",kjcy:"ќ",kopf:"𝕜",kscr:"𝓀",lAarr:"⇚",lArr:"⇐",lAtail:"⤛",lBarr:"⤎",lE:"≦",lEg:"⪋",lHar:"⥢",lacute:"ĺ",laemptyv:"⦴",lagran:"ℒ",lambda:"λ",lang:"⟨",langd:"⦑",langle:"⟨",lap:"⪅",laqu:"«",laquo:"«",larr:"←",larrb:"⇤",larrbfs:"⤟",larrfs:"⤝",larrhk:"↩",larrlp:"↫",larrpl:"⤹",larrsim:"⥳",larrtl:"↢",lat:"⪫",latail:"⤙",late:"⪭",lates:"⪭︀",lbarr:"⤌",lbbrk:"❲",lbrace:"{",lbrack:"[",lbrke:"⦋",lbrksld:"⦏",lbrkslu:"⦍",lcaron:"ľ",lcedil:"ļ",lceil:"⌈",lcub:"{",lcy:"л",ldca:"⤶",ldquo:"“",ldquor:"„",ldrdhar:"⥧",ldrushar:"⥋",ldsh:"↲",le:"≤",leftarrow:"←",leftarrowtail:"↢",leftharpoondown:"↽",leftharpoonup:"↼",leftleftarrows:"⇇",leftrightarrow:"↔",leftrightarrows:"⇆",leftrightharpoons:"⇋",leftrightsquigarrow:"↭",leftthreetimes:"⋋",leg:"⋚",leq:"≤",leqq:"≦",leqslant:"⩽",les:"⩽",lescc:"⪨",lesdot:"⩿",lesdoto:"⪁",lesdotor:"⪃",lesg:"⋚︀",lesges:"⪓",lessapprox:"⪅",lessdot:"⋖",lesseqgtr:"⋚",lesseqqgtr:"⪋",lessgtr:"≶",lesssim:"≲",lfisht:"⥼",lfloor:"⌊",lfr:"𝔩",lg:"≶",lgE:"⪑",lhard:"↽",lharu:"↼",lharul:"⥪",lhblk:"▄",ljcy:"љ",ll:"≪",llarr:"⇇",llcorner:"⌞",llhard:"⥫",lltri:"◺",lmidot:"ŀ",lmoust:"⎰",lmoustache:"⎰",lnE:"≨",lnap:"⪉",lnapprox:"⪉",lne:"⪇",lneq:"⪇",lneqq:"≨",lnsim:"⋦",loang:"⟬",loarr:"⇽",lobrk:"⟦",longleftarrow:"⟵",longleftrightarrow:"⟷",longmapsto:"⟼",longrightarrow:"⟶",looparrowleft:"↫",looparrowright:"↬",lopar:"⦅",lopf:"𝕝",loplus:"⨭",lotimes:"⨴",lowast:"∗",lowbar:"_",loz:"◊",lozenge:"◊",lozf:"⧫",lpar:"(",lparlt:"⦓",lrarr:"⇆",lrcorner:"⌟",lrhar:"⇋",lrhard:"⥭",lrm:"‎",lrtri:"⊿",lsaquo:"‹",lscr:"𝓁",lsh:"↰",lsim:"≲",lsime:"⪍",lsimg:"⪏",lsqb:"[",lsquo:"‘",lsquor:"‚",lstrok:"ł",l:"<",lt:"<",ltcc:"⪦",ltcir:"⩹",ltdot:"⋖",lthree:"⋋",ltimes:"⋉",ltlarr:"⥶",ltquest:"⩻",ltrPar:"⦖",ltri:"◃",ltrie:"⊴",ltrif:"◂",lurdshar:"⥊",luruhar:"⥦",lvertneqq:"≨︀",lvnE:"≨︀",mDDot:"∺",mac:"¯",macr:"¯",male:"♂",malt:"✠",maltese:"✠",map:"↦",mapsto:"↦",mapstodown:"↧",mapstoleft:"↤",mapstoup:"↥",marker:"▮",mcomma:"⨩",mcy:"м",mdash:"—",measuredangle:"∡",mfr:"𝔪",mho:"℧",micr:"µ",micro:"µ",mid:"∣",midast:"*",midcir:"⫰",middo:"·",middot:"·",minus:"−",minusb:"⊟",minusd:"∸",minusdu:"⨪",mlcp:"⫛",mldr:"…",mnplus:"∓",models:"⊧",mopf:"𝕞",mp:"∓",mscr:"𝓂",mstpos:"∾",mu:"μ",multimap:"⊸",mumap:"⊸",nGg:"⋙̸",nGt:"≫⃒",nGtv:"≫̸",nLeftarrow:"⇍",nLeftrightarrow:"⇎",nLl:"⋘̸",nLt:"≪⃒",nLtv:"≪̸",nRightarrow:"⇏",nVDash:"⊯",nVdash:"⊮",nabla:"∇",nacute:"ń",nang:"∠⃒",nap:"≉",napE:"⩰̸",napid:"≋̸",napos:"ʼn",napprox:"≉",natur:"♮",natural:"♮",naturals:"ℕ",nbs:" ",nbsp:" ",nbump:"≎̸",nbumpe:"≏̸",ncap:"⩃",ncaron:"ň",ncedil:"ņ",ncong:"≇",ncongdot:"⩭̸",ncup:"⩂",ncy:"н",ndash:"–",ne:"≠",neArr:"⇗",nearhk:"⤤",nearr:"↗",nearrow:"↗",nedot:"≐̸",nequiv:"≢",nesear:"⤨",nesim:"≂̸",nexist:"∄",nexists:"∄",nfr:"𝔫",ngE:"≧̸",nge:"≱",ngeq:"≱",ngeqq:"≧̸",ngeqslant:"⩾̸",nges:"⩾̸",ngsim:"≵",ngt:"≯",ngtr:"≯",nhArr:"⇎",nharr:"↮",nhpar:"⫲",ni:"∋",nis:"⋼",nisd:"⋺",niv:"∋",njcy:"њ",nlArr:"⇍",nlE:"≦̸",nlarr:"↚",nldr:"‥",nle:"≰",nleftarrow:"↚",nleftrightarrow:"↮",nleq:"≰",nleqq:"≦̸",nleqslant:"⩽̸",nles:"⩽̸",nless:"≮",nlsim:"≴",nlt:"≮",nltri:"⋪",nltrie:"⋬",nmid:"∤",nopf:"𝕟",no:"¬",not:"¬",notin:"∉",notinE:"⋹̸",notindot:"⋵̸",notinva:"∉",notinvb:"⋷",notinvc:"⋶",notni:"∌",notniva:"∌",notnivb:"⋾",notnivc:"⋽",npar:"∦",nparallel:"∦",nparsl:"⫽⃥",npart:"∂̸",npolint:"⨔",npr:"⊀",nprcue:"⋠",npre:"⪯̸",nprec:"⊀",npreceq:"⪯̸",nrArr:"⇏",nrarr:"↛",nrarrc:"⤳̸",nrarrw:"↝̸",nrightarrow:"↛",nrtri:"⋫",nrtrie:"⋭",nsc:"⊁",nsccue:"⋡",nsce:"⪰̸",nscr:"𝓃",nshortmid:"∤",nshortparallel:"∦",nsim:"≁",nsime:"≄",nsimeq:"≄",nsmid:"∤",nspar:"∦",nsqsube:"⋢",nsqsupe:"⋣",nsub:"⊄",nsubE:"⫅̸",nsube:"⊈",nsubset:"⊂⃒",nsubseteq:"⊈",nsubseteqq:"⫅̸",nsucc:"⊁",nsucceq:"⪰̸",nsup:"⊅",nsupE:"⫆̸",nsupe:"⊉",nsupset:"⊃⃒",nsupseteq:"⊉",nsupseteqq:"⫆̸",ntgl:"≹",ntild:"ñ",ntilde:"ñ",ntlg:"≸",ntriangleleft:"⋪",ntrianglelefteq:"⋬",ntriangleright:"⋫",ntrianglerighteq:"⋭",nu:"ν",num:"#",numero:"№",numsp:" ",nvDash:"⊭",nvHarr:"⤄",nvap:"≍⃒",nvdash:"⊬",nvge:"≥⃒",nvgt:">⃒",nvinfin:"⧞",nvlArr:"⤂",nvle:"≤⃒",nvlt:"<⃒",nvltrie:"⊴⃒",nvrArr:"⤃",nvrtrie:"⊵⃒",nvsim:"∼⃒",nwArr:"⇖",nwarhk:"⤣",nwarr:"↖",nwarrow:"↖",nwnear:"⤧",oS:"Ⓢ",oacut:"ó",oacute:"ó",oast:"⊛",ocir:"ô",ocirc:"ô",ocy:"о",odash:"⊝",odblac:"ő",odiv:"⨸",odot:"⊙",odsold:"⦼",oelig:"œ",ofcir:"⦿",ofr:"𝔬",ogon:"˛",ograv:"ò",ograve:"ò",ogt:"⧁",ohbar:"⦵",ohm:"Ω",oint:"∮",olarr:"↺",olcir:"⦾",olcross:"⦻",oline:"‾",olt:"⧀",omacr:"ō",omega:"ω",omicron:"ο",omid:"⦶",ominus:"⊖",oopf:"𝕠",opar:"⦷",operp:"⦹",oplus:"⊕",or:"∨",orarr:"↻",ord:"º",order:"ℴ",orderof:"ℴ",ordf:"ª",ordm:"º",origof:"⊶",oror:"⩖",orslope:"⩗",orv:"⩛",oscr:"ℴ",oslas:"ø",oslash:"ø",osol:"⊘",otild:"õ",otilde:"õ",otimes:"⊗",otimesas:"⨶",oum:"ö",ouml:"ö",ovbar:"⌽",par:"¶",para:"¶",parallel:"∥",parsim:"⫳",parsl:"⫽",part:"∂",pcy:"п",percnt:"%",period:".",permil:"‰",perp:"⊥",pertenk:"‱",pfr:"𝔭",phi:"φ",phiv:"ϕ",phmmat:"ℳ",phone:"☎",pi:"π",pitchfork:"⋔",piv:"ϖ",planck:"ℏ",planckh:"ℎ",plankv:"ℏ",plus:"+",plusacir:"⨣",plusb:"⊞",pluscir:"⨢",plusdo:"∔",plusdu:"⨥",pluse:"⩲",plusm:"±",plusmn:"±",plussim:"⨦",plustwo:"⨧",pm:"±",pointint:"⨕",popf:"𝕡",poun:"£",pound:"£",pr:"≺",prE:"⪳",prap:"⪷",prcue:"≼",pre:"⪯",prec:"≺",precapprox:"⪷",preccurlyeq:"≼",preceq:"⪯",precnapprox:"⪹",precneqq:"⪵",precnsim:"⋨",precsim:"≾",prime:"′",primes:"ℙ",prnE:"⪵",prnap:"⪹",prnsim:"⋨",prod:"∏",profalar:"⌮",profline:"⌒",profsurf:"⌓",prop:"∝",propto:"∝",prsim:"≾",prurel:"⊰",pscr:"𝓅",psi:"ψ",puncsp:" ",qfr:"𝔮",qint:"⨌",qopf:"𝕢",qprime:"⁗",qscr:"𝓆",quaternions:"ℍ",quatint:"⨖",quest:"?",questeq:"≟",quo:'"',quot:'"',rAarr:"⇛",rArr:"⇒",rAtail:"⤜",rBarr:"⤏",rHar:"⥤",race:"∽̱",racute:"ŕ",radic:"√",raemptyv:"⦳",rang:"⟩",rangd:"⦒",range:"⦥",rangle:"⟩",raqu:"»",raquo:"»",rarr:"→",rarrap:"⥵",rarrb:"⇥",rarrbfs:"⤠",rarrc:"⤳",rarrfs:"⤞",rarrhk:"↪",rarrlp:"↬",rarrpl:"⥅",rarrsim:"⥴",rarrtl:"↣",rarrw:"↝",ratail:"⤚",ratio:"∶",rationals:"ℚ",rbarr:"⤍",rbbrk:"❳",rbrace:"}",rbrack:"]",rbrke:"⦌",rbrksld:"⦎",rbrkslu:"⦐",rcaron:"ř",rcedil:"ŗ",rceil:"⌉",rcub:"}",rcy:"р",rdca:"⤷",rdldhar:"⥩",rdquo:"”",rdquor:"”",rdsh:"↳",real:"ℜ",realine:"ℛ",realpart:"ℜ",reals:"ℝ",rect:"▭",re:"®",reg:"®",rfisht:"⥽",rfloor:"⌋",rfr:"𝔯",rhard:"⇁",rharu:"⇀",rharul:"⥬",rho:"ρ",rhov:"ϱ",rightarrow:"→",rightarrowtail:"↣",rightharpoondown:"⇁",rightharpoonup:"⇀",rightleftarrows:"⇄",rightleftharpoons:"⇌",rightrightarrows:"⇉",rightsquigarrow:"↝",rightthreetimes:"⋌",ring:"˚",risingdotseq:"≓",rlarr:"⇄",rlhar:"⇌",rlm:"‏",rmoust:"⎱",rmoustache:"⎱",rnmid:"⫮",roang:"⟭",roarr:"⇾",robrk:"⟧",ropar:"⦆",ropf:"𝕣",roplus:"⨮",rotimes:"⨵",rpar:")",rpargt:"⦔",rppolint:"⨒",rrarr:"⇉",rsaquo:"›",rscr:"𝓇",rsh:"↱",rsqb:"]",rsquo:"’",rsquor:"’",rthree:"⋌",rtimes:"⋊",rtri:"▹",rtrie:"⊵",rtrif:"▸",rtriltri:"⧎",ruluhar:"⥨",rx:"℞",sacute:"ś",sbquo:"‚",sc:"≻",scE:"⪴",scap:"⪸",scaron:"š",sccue:"≽",sce:"⪰",scedil:"ş",scirc:"ŝ",scnE:"⪶",scnap:"⪺",scnsim:"⋩",scpolint:"⨓",scsim:"≿",scy:"с",sdot:"⋅",sdotb:"⊡",sdote:"⩦",seArr:"⇘",searhk:"⤥",searr:"↘",searrow:"↘",sec:"§",sect:"§",semi:";",seswar:"⤩",setminus:"∖",setmn:"∖",sext:"✶",sfr:"𝔰",sfrown:"⌢",sharp:"♯",shchcy:"щ",shcy:"ш",shortmid:"∣",shortparallel:"∥",sh:"­",shy:"­",sigma:"σ",sigmaf:"ς",sigmav:"ς",sim:"∼",simdot:"⩪",sime:"≃",simeq:"≃",simg:"⪞",simgE:"⪠",siml:"⪝",simlE:"⪟",simne:"≆",simplus:"⨤",simrarr:"⥲",slarr:"←",smallsetminus:"∖",smashp:"⨳",smeparsl:"⧤",smid:"∣",smile:"⌣",smt:"⪪",smte:"⪬",smtes:"⪬︀",softcy:"ь",sol:"/",solb:"⧄",solbar:"⌿",sopf:"𝕤",spades:"♠",spadesuit:"♠",spar:"∥",sqcap:"⊓",sqcaps:"⊓︀",sqcup:"⊔",sqcups:"⊔︀",sqsub:"⊏",sqsube:"⊑",sqsubset:"⊏",sqsubseteq:"⊑",sqsup:"⊐",sqsupe:"⊒",sqsupset:"⊐",sqsupseteq:"⊒",squ:"□",square:"□",squarf:"▪",squf:"▪",srarr:"→",sscr:"𝓈",ssetmn:"∖",ssmile:"⌣",sstarf:"⋆",star:"☆",starf:"★",straightepsilon:"ϵ",straightphi:"ϕ",strns:"¯",sub:"⊂",subE:"⫅",subdot:"⪽",sube:"⊆",subedot:"⫃",submult:"⫁",subnE:"⫋",subne:"⊊",subplus:"⪿",subrarr:"⥹",subset:"⊂",subseteq:"⊆",subseteqq:"⫅",subsetneq:"⊊",subsetneqq:"⫋",subsim:"⫇",subsub:"⫕",subsup:"⫓",succ:"≻",succapprox:"⪸",succcurlyeq:"≽",succeq:"⪰",succnapprox:"⪺",succneqq:"⪶",succnsim:"⋩",succsim:"≿",sum:"∑",sung:"♪",sup:"⊃",sup1:"¹",sup2:"²",sup3:"³",supE:"⫆",supdot:"⪾",supdsub:"⫘",supe:"⊇",supedot:"⫄",suphsol:"⟉",suphsub:"⫗",suplarr:"⥻",supmult:"⫂",supnE:"⫌",supne:"⊋",supplus:"⫀",supset:"⊃",supseteq:"⊇",supseteqq:"⫆",supsetneq:"⊋",supsetneqq:"⫌",supsim:"⫈",supsub:"⫔",supsup:"⫖",swArr:"⇙",swarhk:"⤦",swarr:"↙",swarrow:"↙",swnwar:"⤪",szli:"ß",szlig:"ß",target:"⌖",tau:"τ",tbrk:"⎴",tcaron:"ť",tcedil:"ţ",tcy:"т",tdot:"⃛",telrec:"⌕",tfr:"𝔱",there4:"∴",therefore:"∴",theta:"θ",thetasym:"ϑ",thetav:"ϑ",thickapprox:"≈",thicksim:"∼",thinsp:" ",thkap:"≈",thksim:"∼",thor:"þ",thorn:"þ",tilde:"˜",time:"×",times:"×",timesb:"⊠",timesbar:"⨱",timesd:"⨰",tint:"∭",toea:"⤨",top:"⊤",topbot:"⌶",topcir:"⫱",topf:"𝕥",topfork:"⫚",tosa:"⤩",tprime:"‴",trade:"™",triangle:"▵",triangledown:"▿",triangleleft:"◃",trianglelefteq:"⊴",triangleq:"≜",triangleright:"▹",trianglerighteq:"⊵",tridot:"◬",trie:"≜",triminus:"⨺",triplus:"⨹",trisb:"⧍",tritime:"⨻",trpezium:"⏢",tscr:"𝓉",tscy:"ц",tshcy:"ћ",tstrok:"ŧ",twixt:"≬",twoheadleftarrow:"↞",twoheadrightarrow:"↠",uArr:"⇑",uHar:"⥣",uacut:"ú",uacute:"ú",uarr:"↑",ubrcy:"ў",ubreve:"ŭ",ucir:"û",ucirc:"û",ucy:"у",udarr:"⇅",udblac:"ű",udhar:"⥮",ufisht:"⥾",ufr:"𝔲",ugrav:"ù",ugrave:"ù",uharl:"↿",uharr:"↾",uhblk:"▀",ulcorn:"⌜",ulcorner:"⌜",ulcrop:"⌏",ultri:"◸",umacr:"ū",um:"¨",uml:"¨",uogon:"ų",uopf:"𝕦",uparrow:"↑",updownarrow:"↕",upharpoonleft:"↿",upharpoonright:"↾",uplus:"⊎",upsi:"υ",upsih:"ϒ",upsilon:"υ",upuparrows:"⇈",urcorn:"⌝",urcorner:"⌝",urcrop:"⌎",uring:"ů",urtri:"◹",uscr:"𝓊",utdot:"⋰",utilde:"ũ",utri:"▵",utrif:"▴",uuarr:"⇈",uum:"ü",uuml:"ü",uwangle:"⦧",vArr:"⇕",vBar:"⫨",vBarv:"⫩",vDash:"⊨",vangrt:"⦜",varepsilon:"ϵ",varkappa:"ϰ",varnothing:"∅",varphi:"ϕ",varpi:"ϖ",varpropto:"∝",varr:"↕",varrho:"ϱ",varsigma:"ς",varsubsetneq:"⊊︀",varsubsetneqq:"⫋︀",varsupsetneq:"⊋︀",varsupsetneqq:"⫌︀",vartheta:"ϑ",vartriangleleft:"⊲",vartriangleright:"⊳",vcy:"в",vdash:"⊢",vee:"∨",veebar:"⊻",veeeq:"≚",vellip:"⋮",verbar:"|",vert:"|",vfr:"𝔳",vltri:"⊲",vnsub:"⊂⃒",vnsup:"⊃⃒",vopf:"𝕧",vprop:"∝",vrtri:"⊳",vscr:"𝓋",vsubnE:"⫋︀",vsubne:"⊊︀",vsupnE:"⫌︀",vsupne:"⊋︀",vzigzag:"⦚",wcirc:"ŵ",wedbar:"⩟",wedge:"∧",wedgeq:"≙",weierp:"℘",wfr:"𝔴",wopf:"𝕨",wp:"℘",wr:"≀",wreath:"≀",wscr:"𝓌",xcap:"⋂",xcirc:"◯",xcup:"⋃",xdtri:"▽",xfr:"𝔵",xhArr:"⟺",xharr:"⟷",xi:"ξ",xlArr:"⟸",xlarr:"⟵",xmap:"⟼",xnis:"⋻",xodot:"⨀",xopf:"𝕩",xoplus:"⨁",xotime:"⨂",xrArr:"⟹",xrarr:"⟶",xscr:"𝓍",xsqcup:"⨆",xuplus:"⨄",xutri:"△",xvee:"⋁",xwedge:"⋀",yacut:"ý",yacute:"ý",yacy:"я",ycirc:"ŷ",ycy:"ы",ye:"¥",yen:"¥",yfr:"𝔶",yicy:"ї",yopf:"𝕪",yscr:"𝓎",yucy:"ю",yum:"ÿ",yuml:"ÿ",zacute:"ź",zcaron:"ž",zcy:"з",zdot:"ż",zeetrf:"ℨ",zeta:"ζ",zfr:"𝔷",zhcy:"ж",zigrarr:"⇝",zopf:"𝕫",zscr:"𝓏",zwj:"‍",zwnj:"‌"},Ar=function(r){return!!kr.call(wr,r)&&wr[r]},kr={}.hasOwnProperty;var qr=function(r,e){var t,n,o={};e||(e={});for(n in Sr)t=e[n],o[n]=null==t?Sr[n]:t;(o.position.indent||o.position.start)&&(o.indent=o.position.indent||[],o.position=o.position.start);return function(r,e){var t,n,o,i,a,c,l,s,u,f,p,h,d,g,m,b,v,y,w,A=e.additional,k=e.nonTerminated,q=e.text,x=e.reference,E=e.warning,L=e.textContext,S=e.referenceContext,O=e.warningContext,T=e.position,D=e.indent||[],C=r.length,N=0,R=-1,I=T.column||1,B=T.line||1,j="",U=[];"string"==typeof A&&(A=A.charCodeAt(0));b=z(),s=E?P:Lr,N--,C++;for(;++N65535&&(f+=Er((c-=65536)>>>10|55296),c=56320|1023&c),c=f+Er(c))):g!==Or&&s(4,y)),c?(V(),b=z(),N=w-1,I+=w-d+1,U.push(c),(v=z()).offset++,x&&x.call(S,c,{start:b,end:v},r.slice(d-1,w)),b=v):(i=r.slice(d-1,w),j+=i,I+=i.length,N=w-1)}else 10===a&&(B++,R++,I=0),a==a?(j+=Er(a),I++):V();return U.join("");function z(){return{line:B,column:I,offset:N+(T.offset||0)}}function P(r,e){var t=z();t.column+=e,t.offset+=e,E.call(O,Rr[r],t,r)}function V(){j&&(U.push(j),q&&q.call(L,j,{start:b,end:z()}),j="")}}(r,o)},xr={}.hasOwnProperty,Er=String.fromCharCode,Lr=Function.prototype,Sr={warning:null,reference:null,text:null,warningContext:null,referenceContext:null,textContext:null,position:{},additional:null,attribute:!1,nonTerminated:!0},Or="named",Tr="hexadecimal",Dr="decimal",Cr={hexadecimal:16,decimal:10},Nr={};Nr.named=yr,Nr[Dr]=mr,Nr[Tr]=br;var Rr={};function Ir(r){return r>=55296&&r<=57343||r>1114111}function Br(r){return r>=1&&r<=8||11===r||r>=13&&r<=31||r>=127&&r<=159||r>=64976&&r<=65007||65535==(65535&r)||65534==(65535&r)}Rr[1]="Named character references must be terminated by a semicolon",Rr[2]="Numeric character references must be terminated by a semicolon",Rr[3]="Named character references cannot be empty",Rr[4]="Numeric character references cannot be empty",Rr[5]="Named character references must be known",Rr[6]="Numeric character references cannot be disallowed",Rr[7]="Numeric character references cannot be outside the permissible Unicode range";var jr=function(r){return n.raw=o,n;function e(e){for(var t=r.offset,n=e.line,o=[];++n&&n in t;)o.push((t[n]||0)+1);return{start:e,indent:o}}function t(e,t,n){3!==n&&r.file.message(e,t)}function n(n,o,i){qr(n,{position:e(o),warning:t,text:i,reference:i,textContext:r,referenceContext:r})}function o(r,n,o){return qr(r,nr(o,{position:e(n),warning:t}))}};var Ur=function(r){return function(e,t){var n,o,i,a,c,l=this,s=l.offset,u=[],f=l[r+"Methods"],p=l[r+"Tokenizers"],h=t.line,d=t.column;if(!e)return u;k.now=b,k.file=l.file,g("");for(;e;){for(n=-1,o=f.length,a=!1;++n"],Gr=Hr.concat(["~","|"]),Mr=Gr.concat(["\n",'"',"$","%","&","'",",","/",":",";","<","=","?","@","^"]);function _r(r){var e=r||{};return e.commonmark?Mr:e.gfm?Gr:Hr}_r.default=Hr,_r.gfm=Gr,_r.commonmark=Mr;var Fr={position:!0,gfm:!0,commonmark:!1,footnotes:!1,pedantic:!1,blocks:["address","article","aside","base","basefont","blockquote","body","caption","center","col","colgroup","dd","details","dialog","dir","div","dl","dt","fieldset","figcaption","figure","footer","form","frame","frameset","h1","h2","h3","h4","h5","h6","head","header","hgroup","hr","html","iframe","legend","li","link","main","menu","menuitem","meta","nav","noframes","ol","optgroup","option","p","param","pre","section","source","title","summary","table","tbody","td","tfoot","th","thead","title","tr","track","ul"]},Zr=function(r){var e,t,n=this,o=n.options;if(null==r)r={};else{if("object"!=typeof r)throw new Error("Invalid value `"+r+"` for setting `options`");r=nr(r)}for(e in Fr){if(null==(t=r[e])&&(t=o[e]),"blocks"!==e&&"boolean"!=typeof t||"blocks"===e&&"object"!=typeof t)throw new Error("Invalid value `"+t+"` for setting `options."+e+"`");r[e]=t}return n.options=r,n.escape=Vr(r),n};var $r=Yr;function Yr(r){if("string"==typeof r)return function(r){return e;function e(e){return Boolean(e&&e.type===r)}}(r);if(null==r)return Qr;if("object"==typeof r)return("length"in r?Kr:Jr)(r);if("function"==typeof r)return r;throw new Error("Expected function, string, or object as test")}function Jr(r){return function(e){var t;for(t in r)if(e[t]!==r[t])return!1;return!0}}function Kr(r){var e=function(r){for(var e=[],t=r.length,n=-1;++no&&c * * Copyright (c) 2014-2015, Jon Schlinkert. * Licensed under the MIT License. - */ - -/** - * Results cache - */ - -var res = ''; -var cache; - -/** - * Expose `repeat` - */ - -var repeatString = repeat; - -/** - * Repeat the given `string` the specified `number` - * of times. - * - * **Example:** - * - * ```js - * var repeat = require('repeat-string'); - * repeat('A', 5); - * //=> AAAAA - * ``` - * - * @param {String} `string` The string to repeat - * @param {Number} `number` The number of times to repeat the string - * @return {String} Repeated string - * @api public - */ - -function repeat(str, num) { - if (typeof str !== 'string') { - throw new TypeError('expected a string'); - } - - // cover common, quick use cases - if (num === 1) return str; - if (num === 2) return str + str; - - var max = str.length * num; - if (cache !== str || typeof cache === 'undefined') { - cache = str; - res = ''; - } else if (res.length >= max) { - return res.substr(0, max); - } - - while (max > res.length && num > 1) { - if (num & 1) { - res += str; - } - - num >>= 1; - str += str; - } - - res += str; - res = res.substr(0, max); - return res; -} - -var trimTrailingLines_1 = trimTrailingLines; - -// Remove final newline characters from `value`. -function trimTrailingLines(value) { - return String(value).replace(/\n+$/, '') -} - -var codeIndented = indentedCode; - -var C_NEWLINE$c = '\n'; -var C_TAB$c = '\t'; -var C_SPACE$c = ' '; - -var CODE_INDENT_COUNT$1 = 4; -var CODE_INDENT = repeatString(C_SPACE$c, CODE_INDENT_COUNT$1); - -/* Tokenise indented code. */ -function indentedCode(eat, value, silent) { - var index = -1; - var length = value.length; - var subvalue = ''; - var content = ''; - var subvalueQueue = ''; - var contentQueue = ''; - var character; - var blankQueue; - var indent; - - while (++index < length) { - character = value.charAt(index); - - if (indent) { - indent = false; - - subvalue += subvalueQueue; - content += contentQueue; - subvalueQueue = ''; - contentQueue = ''; - - if (character === C_NEWLINE$c) { - subvalueQueue = character; - contentQueue = character; - } else { - subvalue += character; - content += character; - - while (++index < length) { - character = value.charAt(index); - - if (!character || character === C_NEWLINE$c) { - contentQueue = character; - subvalueQueue = character; - break; - } - - subvalue += character; - content += character; - } - } - } else if ( - character === C_SPACE$c && - value.charAt(index + 1) === character && - value.charAt(index + 2) === character && - value.charAt(index + 3) === character - ) { - subvalueQueue += CODE_INDENT; - index += 3; - indent = true; - } else if (character === C_TAB$c) { - subvalueQueue += character; - indent = true; - } else { - blankQueue = ''; - - while (character === C_TAB$c || character === C_SPACE$c) { - blankQueue += character; - character = value.charAt(++index); - } - - if (character !== C_NEWLINE$c) { - break; - } - - subvalueQueue += blankQueue + character; - contentQueue += character; - } - } - - if (content) { - if (silent) { - return true; - } - - return eat(subvalue)({ - type: 'code', - lang: null, - value: trimTrailingLines_1(content) - }); - } -} - -var codeFenced = fencedCode; - -var C_NEWLINE$b = '\n'; -var C_TAB$b = '\t'; -var C_SPACE$b = ' '; -var C_TILDE$1 = '~'; -var C_TICK$3 = '`'; - -var MIN_FENCE_COUNT = 3; -var CODE_INDENT_COUNT = 4; - -function fencedCode(eat, value, silent) { - var self = this; - var settings = self.options; - var length = value.length + 1; - var index = 0; - var subvalue = ''; - var fenceCount; - var marker; - var character; - var flag; - var queue; - var content; - var exdentedContent; - var closing; - var exdentedClosing; - var indent; - var now; - - if (!settings.gfm) { - return; - } - - /* Eat initial spacing. */ - while (index < length) { - character = value.charAt(index); - - if (character !== C_SPACE$b && character !== C_TAB$b) { - break; - } - - subvalue += character; - index++; - } - - indent = index; - - /* Eat the fence. */ - character = value.charAt(index); - - if (character !== C_TILDE$1 && character !== C_TICK$3) { - return; - } - - index++; - marker = character; - fenceCount = 1; - subvalue += character; - - while (index < length) { - character = value.charAt(index); - - if (character !== marker) { - break; - } - - subvalue += character; - fenceCount++; - index++; - } - - if (fenceCount < MIN_FENCE_COUNT) { - return; - } - - /* Eat spacing before flag. */ - while (index < length) { - character = value.charAt(index); - - if (character !== C_SPACE$b && character !== C_TAB$b) { - break; - } - - subvalue += character; - index++; - } - - /* Eat flag. */ - flag = ''; - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if ( - character === C_NEWLINE$b || - character === C_TILDE$1 || - character === C_TICK$3 - ) { - break; - } - - if (character === C_SPACE$b || character === C_TAB$b) { - queue += character; - } else { - flag += queue + character; - queue = ''; - } - - index++; - } - - character = value.charAt(index); - - if (character && character !== C_NEWLINE$b) { - return; - } - - if (silent) { - return true; - } - - now = eat.now(); - now.column += subvalue.length; - now.offset += subvalue.length; - - subvalue += flag; - flag = self.decode.raw(self.unescape(flag), now); - - if (queue) { - subvalue += queue; - } - - queue = ''; - closing = ''; - exdentedClosing = ''; - content = ''; - exdentedContent = ''; - - /* Eat content. */ - while (index < length) { - character = value.charAt(index); - content += closing; - exdentedContent += exdentedClosing; - closing = ''; - exdentedClosing = ''; - - if (character !== C_NEWLINE$b) { - content += character; - exdentedClosing += character; - index++; - continue; - } - - /* Add the newline to `subvalue` if its the first - * character. Otherwise, add it to the `closing` - * queue. */ - if (content) { - closing += character; - exdentedClosing += character; - } else { - subvalue += character; - } - - queue = ''; - index++; - - while (index < length) { - character = value.charAt(index); - - if (character !== C_SPACE$b) { - break; - } - - queue += character; - index++; - } - - closing += queue; - exdentedClosing += queue.slice(indent); - - if (queue.length >= CODE_INDENT_COUNT) { - continue; - } - - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if (character !== marker) { - break; - } - - queue += character; - index++; - } - - closing += queue; - exdentedClosing += queue; - - if (queue.length < fenceCount) { - continue; - } - - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if (character !== C_SPACE$b && character !== C_TAB$b) { - break; - } - - closing += character; - exdentedClosing += character; - index++; - } - - if (!character || character === C_NEWLINE$b) { - break; - } - } - - subvalue += content + closing; - - return eat(subvalue)({ - type: 'code', - lang: flag || null, - value: trimTrailingLines_1(exdentedContent) - }); -} - -var trim_1 = createCommonjsModule(function (module, exports) { -exports = module.exports = trim; - -function trim(str){ - return str.replace(/^\s*|\s*$/g, ''); -} - -exports.left = function(str){ - return str.replace(/^\s*/, ''); -}; - -exports.right = function(str){ - return str.replace(/\s*$/, ''); -}; -}); - -var interrupt_1 = interrupt; - -function interrupt(interruptors, tokenizers, ctx, params) { - var bools = ['pedantic', 'commonmark']; - var count = bools.length; - var length = interruptors.length; - var index = -1; - var interruptor; - var config; - var fn; - var offset; - var bool; - var ignore; - - while (++index < length) { - interruptor = interruptors[index]; - config = interruptor[1] || {}; - fn = interruptor[0]; - offset = -1; - ignore = false; - - while (++offset < count) { - bool = bools[offset]; - - if (config[bool] !== undefined && config[bool] !== ctx.options[bool]) { - ignore = true; - break; - } - } - - if (ignore) { - continue; - } - - if (tokenizers[fn].apply(ctx, params)) { - return true; - } - } - - return false; -} - -var blockquote_1 = blockquote; - -var C_NEWLINE$a = '\n'; -var C_TAB$a = '\t'; -var C_SPACE$a = ' '; -var C_GT$3 = '>'; - -/* Tokenise a blockquote. */ -function blockquote(eat, value, silent) { - var self = this; - var offsets = self.offset; - var tokenizers = self.blockTokenizers; - var interruptors = self.interruptBlockquote; - var now = eat.now(); - var currentLine = now.line; - var length = value.length; - var values = []; - var contents = []; - var indents = []; - var add; - var index = 0; - var character; - var rest; - var nextIndex; - var content; - var line; - var startIndex; - var prefixed; - var exit; - - while (index < length) { - character = value.charAt(index); - - if (character !== C_SPACE$a && character !== C_TAB$a) { - break; - } - - index++; - } - - if (value.charAt(index) !== C_GT$3) { - return; - } - - if (silent) { - return true; - } - - index = 0; - - while (index < length) { - nextIndex = value.indexOf(C_NEWLINE$a, index); - startIndex = index; - prefixed = false; - - if (nextIndex === -1) { - nextIndex = length; - } - - while (index < length) { - character = value.charAt(index); - - if (character !== C_SPACE$a && character !== C_TAB$a) { - break; - } - - index++; - } - - if (value.charAt(index) === C_GT$3) { - index++; - prefixed = true; - - if (value.charAt(index) === C_SPACE$a) { - index++; - } - } else { - index = startIndex; - } - - content = value.slice(index, nextIndex); - - if (!prefixed && !trim_1(content)) { - index = startIndex; - break; - } - - if (!prefixed) { - rest = value.slice(index); - - /* Check if the following code contains a possible - * block. */ - if (interrupt_1(interruptors, tokenizers, self, [eat, rest, true])) { - break; - } - } - - line = startIndex === index ? content : value.slice(startIndex, nextIndex); - - indents.push(index - startIndex); - values.push(line); - contents.push(content); - - index = nextIndex + 1; - } - - index = -1; - length = indents.length; - add = eat(values.join(C_NEWLINE$a)); - - while (++index < length) { - offsets[currentLine] = (offsets[currentLine] || 0) + indents[index]; - currentLine++; - } - - exit = self.enterBlock(); - contents = self.tokenizeBlock(contents.join(C_NEWLINE$a), now); - exit(); - - return add({ - type: 'blockquote', - children: contents - }); -} - -var headingAtx = atxHeading; - -var C_NEWLINE$9 = '\n'; -var C_TAB$9 = '\t'; -var C_SPACE$9 = ' '; -var C_HASH = '#'; - -var MAX_ATX_COUNT = 6; - -function atxHeading(eat, value, silent) { - var self = this; - var settings = self.options; - var length = value.length + 1; - var index = -1; - var now = eat.now(); - var subvalue = ''; - var content = ''; - var character; - var queue; - var depth; - - /* Eat initial spacing. */ - while (++index < length) { - character = value.charAt(index); - - if (character !== C_SPACE$9 && character !== C_TAB$9) { - index--; - break; - } - - subvalue += character; - } - - /* Eat hashes. */ - depth = 0; - - while (++index <= length) { - character = value.charAt(index); - - if (character !== C_HASH) { - index--; - break; - } - - subvalue += character; - depth++; - } - - if (depth > MAX_ATX_COUNT) { - return; - } - - if ( - !depth || - (!settings.pedantic && value.charAt(index + 1) === C_HASH) - ) { - return; - } - - length = value.length + 1; - - /* Eat intermediate white-space. */ - queue = ''; - - while (++index < length) { - character = value.charAt(index); - - if (character !== C_SPACE$9 && character !== C_TAB$9) { - index--; - break; - } - - queue += character; - } - - /* Exit when not in pedantic mode without spacing. */ - if ( - !settings.pedantic && - queue.length === 0 && - character && - character !== C_NEWLINE$9 - ) { - return; - } - - if (silent) { - return true; - } - - /* Eat content. */ - subvalue += queue; - queue = ''; - content = ''; - - while (++index < length) { - character = value.charAt(index); - - if (!character || character === C_NEWLINE$9) { - break; - } - - if ( - character !== C_SPACE$9 && - character !== C_TAB$9 && - character !== C_HASH - ) { - content += queue + character; - queue = ''; - continue; - } - - while (character === C_SPACE$9 || character === C_TAB$9) { - queue += character; - character = value.charAt(++index); - } - - while (character === C_HASH) { - queue += character; - character = value.charAt(++index); - } - - while (character === C_SPACE$9 || character === C_TAB$9) { - queue += character; - character = value.charAt(++index); - } - - index--; - } - - now.column += subvalue.length; - now.offset += subvalue.length; - subvalue += content + queue; - - return eat(subvalue)({ - type: 'heading', - depth: depth, - children: self.tokenizeInline(content, now) - }); -} - -var thematicBreak_1 = thematicBreak; - -var C_NEWLINE$8 = '\n'; -var C_TAB$8 = '\t'; -var C_SPACE$8 = ' '; -var C_ASTERISK$3 = '*'; -var C_UNDERSCORE$3 = '_'; -var C_DASH$3 = '-'; - -var THEMATIC_BREAK_MARKER_COUNT = 3; - -function thematicBreak(eat, value, silent) { - var index = -1; - var length = value.length + 1; - var subvalue = ''; - var character; - var marker; - var markerCount; - var queue; - - while (++index < length) { - character = value.charAt(index); - - if (character !== C_TAB$8 && character !== C_SPACE$8) { - break; - } - - subvalue += character; - } - - if ( - character !== C_ASTERISK$3 && - character !== C_DASH$3 && - character !== C_UNDERSCORE$3 - ) { - return; - } - - marker = character; - subvalue += character; - markerCount = 1; - queue = ''; - - while (++index < length) { - character = value.charAt(index); - - if (character === marker) { - markerCount++; - subvalue += queue + marker; - queue = ''; - } else if (character === C_SPACE$8) { - queue += character; - } else if ( - markerCount >= THEMATIC_BREAK_MARKER_COUNT && - (!character || character === C_NEWLINE$8) - ) { - subvalue += queue; - - if (silent) { - return true; - } - - return eat(subvalue)({type: 'thematicBreak'}); - } else { - return; - } - } -} - -var getIndentation = indentation$1; - -/* Map of characters, and their column length, - * which can be used as indentation. */ -var characters = {' ': 1, '\t': 4}; - -/* Gets indentation information for a line. */ -function indentation$1(value) { - var index = 0; - var indent = 0; - var character = value.charAt(index); - var stops = {}; - var size; - - while (character in characters) { - size = characters[character]; - - indent += size; - - if (size > 1) { - indent = Math.floor(indent / size) * size; - } - - stops[indent] = index; - - character = value.charAt(++index); - } - - return {indent: indent, stops: stops}; -} - -var removeIndentation = indentation; - -var C_SPACE$7 = ' '; -var C_NEWLINE$7 = '\n'; -var C_TAB$7 = '\t'; - -/* Remove the minimum indent from every line in `value`. - * Supports both tab, spaced, and mixed indentation (as - * well as possible). */ -function indentation(value, maximum) { - var values = value.split(C_NEWLINE$7); - var position = values.length + 1; - var minIndent = Infinity; - var matrix = []; - var index; - var indentation; - var stops; - var padding; - - values.unshift(repeatString(C_SPACE$7, maximum) + '!'); - - while (position--) { - indentation = getIndentation(values[position]); - - matrix[position] = indentation.stops; - - if (trim_1(values[position]).length === 0) { - continue; - } - - if (indentation.indent) { - if (indentation.indent > 0 && indentation.indent < minIndent) { - minIndent = indentation.indent; - } - } else { - minIndent = Infinity; - - break; - } - } - - if (minIndent !== Infinity) { - position = values.length; - - while (position--) { - stops = matrix[position]; - index = minIndent; - - while (index && !(index in stops)) { - index--; - } - - if ( - trim_1(values[position]).length !== 0 && - minIndent && - index !== minIndent - ) { - padding = C_TAB$7; - } else { - padding = ''; - } - - values[position] = padding + values[position].slice( - index in stops ? stops[index] + 1 : 0 - ); - } - } - - values.shift(); - - return values.join(C_NEWLINE$7); -} - -/* eslint-disable max-params */ - - - - - - - - -var list_1 = list; - -var C_ASTERISK$2 = '*'; -var C_UNDERSCORE$2 = '_'; -var C_PLUS = '+'; -var C_DASH$2 = '-'; -var C_DOT = '.'; -var C_SPACE$6 = ' '; -var C_NEWLINE$6 = '\n'; -var C_TAB$6 = '\t'; -var C_PAREN_CLOSE$3 = ')'; -var C_X_LOWER = 'x'; - -var TAB_SIZE$1 = 4; -var EXPRESSION_LOOSE_LIST_ITEM = /\n\n(?!\s*$)/; -var EXPRESSION_TASK_ITEM = /^\[([ \t]|x|X)][ \t]/; -var EXPRESSION_BULLET = /^([ \t]*)([*+-]|\d+[.)])( {1,4}(?! )| |\t|$|(?=\n))([^\n]*)/; -var EXPRESSION_PEDANTIC_BULLET = /^([ \t]*)([*+-]|\d+[.)])([ \t]+)/; -var EXPRESSION_INITIAL_INDENT = /^( {1,4}|\t)?/gm; - -/* Map of characters which can be used to mark - * list-items. */ -var LIST_UNORDERED_MARKERS = {}; - -LIST_UNORDERED_MARKERS[C_ASTERISK$2] = true; -LIST_UNORDERED_MARKERS[C_PLUS] = true; -LIST_UNORDERED_MARKERS[C_DASH$2] = true; - -/* Map of characters which can be used to mark - * list-items after a digit. */ -var LIST_ORDERED_MARKERS = {}; - -LIST_ORDERED_MARKERS[C_DOT] = true; - -/* Map of characters which can be used to mark - * list-items after a digit. */ -var LIST_ORDERED_COMMONMARK_MARKERS = {}; - -LIST_ORDERED_COMMONMARK_MARKERS[C_DOT] = true; -LIST_ORDERED_COMMONMARK_MARKERS[C_PAREN_CLOSE$3] = true; - -function list(eat, value, silent) { - var self = this; - var commonmark = self.options.commonmark; - var pedantic = self.options.pedantic; - var tokenizers = self.blockTokenizers; - var interuptors = self.interruptList; - var markers; - var index = 0; - var length = value.length; - var start = null; - var size = 0; - var queue; - var ordered; - var character; - var marker; - var nextIndex; - var startIndex; - var prefixed; - var currentMarker; - var content; - var line; - var prevEmpty; - var empty; - var items; - var allLines; - var emptyLines; - var item; - var enterTop; - var exitBlockquote; - var isLoose; - var node; - var now; - var end; - var indented; - - while (index < length) { - character = value.charAt(index); - - if (character === C_TAB$6) { - size += TAB_SIZE$1 - (size % TAB_SIZE$1); - } else if (character === C_SPACE$6) { - size++; - } else { - break; - } - - index++; - } - - if (size >= TAB_SIZE$1) { - return; - } - - character = value.charAt(index); - - markers = commonmark ? - LIST_ORDERED_COMMONMARK_MARKERS : - LIST_ORDERED_MARKERS; - - if (LIST_UNORDERED_MARKERS[character] === true) { - marker = character; - ordered = false; - } else { - ordered = true; - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if (!isDecimal(character)) { - break; - } - - queue += character; - index++; - } - - character = value.charAt(index); - - if (!queue || markers[character] !== true) { - return; - } - - start = parseInt(queue, 10); - marker = character; - } - - character = value.charAt(++index); - - if (character !== C_SPACE$6 && character !== C_TAB$6) { - return; - } - - if (silent) { - return true; - } - - index = 0; - items = []; - allLines = []; - emptyLines = []; - - while (index < length) { - nextIndex = value.indexOf(C_NEWLINE$6, index); - startIndex = index; - prefixed = false; - indented = false; - - if (nextIndex === -1) { - nextIndex = length; - } - - end = index + TAB_SIZE$1; - size = 0; - - while (index < length) { - character = value.charAt(index); - - if (character === C_TAB$6) { - size += TAB_SIZE$1 - (size % TAB_SIZE$1); - } else if (character === C_SPACE$6) { - size++; - } else { - break; - } - - index++; - } - - if (size >= TAB_SIZE$1) { - indented = true; - } - - if (item && size >= item.indent) { - indented = true; - } - - character = value.charAt(index); - currentMarker = null; - - if (!indented) { - if (LIST_UNORDERED_MARKERS[character] === true) { - currentMarker = character; - index++; - size++; - } else { - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if (!isDecimal(character)) { - break; - } - - queue += character; - index++; - } - - character = value.charAt(index); - index++; - - if (queue && markers[character] === true) { - currentMarker = character; - size += queue.length + 1; - } - } - - if (currentMarker) { - character = value.charAt(index); - - if (character === C_TAB$6) { - size += TAB_SIZE$1 - (size % TAB_SIZE$1); - index++; - } else if (character === C_SPACE$6) { - end = index + TAB_SIZE$1; - - while (index < end) { - if (value.charAt(index) !== C_SPACE$6) { - break; - } - - index++; - size++; - } - - if (index === end && value.charAt(index) === C_SPACE$6) { - index -= TAB_SIZE$1 - 1; - size -= TAB_SIZE$1 - 1; - } - } else if (character !== C_NEWLINE$6 && character !== '') { - currentMarker = null; - } - } - } - - if (currentMarker) { - if (!pedantic && marker !== currentMarker) { - break; - } - - prefixed = true; - } else { - if (!commonmark && !indented && value.charAt(startIndex) === C_SPACE$6) { - indented = true; - } else if (commonmark && item) { - indented = size >= item.indent || size > TAB_SIZE$1; - } - - prefixed = false; - index = startIndex; - } - - line = value.slice(startIndex, nextIndex); - content = startIndex === index ? line : value.slice(index, nextIndex); - - if ( - currentMarker === C_ASTERISK$2 || - currentMarker === C_UNDERSCORE$2 || - currentMarker === C_DASH$2 - ) { - if (tokenizers.thematicBreak.call(self, eat, line, true)) { - break; - } - } - - prevEmpty = empty; - empty = !trim_1(content).length; - - if (indented && item) { - item.value = item.value.concat(emptyLines, line); - allLines = allLines.concat(emptyLines, line); - emptyLines = []; - } else if (prefixed) { - if (emptyLines.length !== 0) { - item.value.push(''); - item.trail = emptyLines.concat(); - } - - item = { - value: [line], - indent: size, - trail: [] - }; - - items.push(item); - allLines = allLines.concat(emptyLines, line); - emptyLines = []; - } else if (empty) { - if (prevEmpty) { - break; - } - - emptyLines.push(line); - } else { - if (prevEmpty) { - break; - } - - if (interrupt_1(interuptors, tokenizers, self, [eat, line, true])) { - break; - } - - item.value = item.value.concat(emptyLines, line); - allLines = allLines.concat(emptyLines, line); - emptyLines = []; - } - - index = nextIndex + 1; - } - - node = eat(allLines.join(C_NEWLINE$6)).reset({ - type: 'list', - ordered: ordered, - start: start, - loose: null, - children: [] - }); - - enterTop = self.enterList(); - exitBlockquote = self.enterBlock(); - isLoose = false; - index = -1; - length = items.length; - - while (++index < length) { - item = items[index].value.join(C_NEWLINE$6); - now = eat.now(); - - item = eat(item)(listItem(self, item, now), node); - - if (item.loose) { - isLoose = true; - } - - item = items[index].trail.join(C_NEWLINE$6); - - if (index !== length - 1) { - item += C_NEWLINE$6; - } - - eat(item); - } - - enterTop(); - exitBlockquote(); - - node.loose = isLoose; - - return node; -} - -function listItem(ctx, value, position) { - var offsets = ctx.offset; - var fn = ctx.options.pedantic ? pedanticListItem : normalListItem; - var checked = null; - var task; - var indent; - - value = fn.apply(null, arguments); - - if (ctx.options.gfm) { - task = value.match(EXPRESSION_TASK_ITEM); - - if (task) { - indent = task[0].length; - checked = task[1].toLowerCase() === C_X_LOWER; - offsets[position.line] += indent; - value = value.slice(indent); - } - } - - return { - type: 'listItem', - loose: EXPRESSION_LOOSE_LIST_ITEM.test(value) || - value.charAt(value.length - 1) === C_NEWLINE$6, - checked: checked, - children: ctx.tokenizeBlock(value, position) - }; -} - -/* Create a list-item using overly simple mechanics. */ -function pedanticListItem(ctx, value, position) { - var offsets = ctx.offset; - var line = position.line; - - /* Remove the list-item’s bullet. */ - value = value.replace(EXPRESSION_PEDANTIC_BULLET, replacer); - - /* The initial line was also matched by the below, so - * we reset the `line`. */ - line = position.line; - - return value.replace(EXPRESSION_INITIAL_INDENT, replacer); - - /* A simple replacer which removed all matches, - * and adds their length to `offset`. */ - function replacer($0) { - offsets[line] = (offsets[line] || 0) + $0.length; - line++; - - return ''; - } -} - -/* Create a list-item using sane mechanics. */ -function normalListItem(ctx, value, position) { - var offsets = ctx.offset; - var line = position.line; - var max; - var bullet; - var rest; - var lines; - var trimmedLines; - var index; - var length; - - /* Remove the list-item’s bullet. */ - value = value.replace(EXPRESSION_BULLET, replacer); - - lines = value.split(C_NEWLINE$6); - - trimmedLines = removeIndentation(value, getIndentation(max).indent).split(C_NEWLINE$6); - - /* We replaced the initial bullet with something - * else above, which was used to trick - * `removeIndentation` into removing some more - * characters when possible. However, that could - * result in the initial line to be stripped more - * than it should be. */ - trimmedLines[0] = rest; - - offsets[line] = (offsets[line] || 0) + bullet.length; - line++; - - index = 0; - length = lines.length; - - while (++index < length) { - offsets[line] = (offsets[line] || 0) + - lines[index].length - trimmedLines[index].length; - line++; - } - - return trimmedLines.join(C_NEWLINE$6); - - function replacer($0, $1, $2, $3, $4) { - bullet = $1 + $2 + $3; - rest = $4; - - /* Make sure that the first nine numbered list items - * can indent with an extra space. That is, when - * the bullet did not receive an extra final space. */ - if (Number($2) < 10 && bullet.length % 2 === 1) { - $2 = C_SPACE$6 + $2; - } - - max = $1 + repeatString(C_SPACE$6, $2.length) + $3; - - return max + rest; - } -} - -var headingSetext = setextHeading; - -var C_NEWLINE$5 = '\n'; -var C_TAB$5 = '\t'; -var C_SPACE$5 = ' '; -var C_EQUALS = '='; -var C_DASH$1 = '-'; - -var MAX_HEADING_INDENT = 3; - -/* Map of characters which can be used to mark setext - * headers, mapping to their corresponding depth. */ -var SETEXT_MARKERS = {}; - -SETEXT_MARKERS[C_EQUALS] = 1; -SETEXT_MARKERS[C_DASH$1] = 2; - -function setextHeading(eat, value, silent) { - var self = this; - var now = eat.now(); - var length = value.length; - var index = -1; - var subvalue = ''; - var content; - var queue; - var character; - var marker; - var depth; - - /* Eat initial indentation. */ - while (++index < length) { - character = value.charAt(index); - - if (character !== C_SPACE$5 || index >= MAX_HEADING_INDENT) { - index--; - break; - } - - subvalue += character; - } - - /* Eat content. */ - content = ''; - queue = ''; - - while (++index < length) { - character = value.charAt(index); - - if (character === C_NEWLINE$5) { - index--; - break; - } - - if (character === C_SPACE$5 || character === C_TAB$5) { - queue += character; - } else { - content += queue + character; - queue = ''; - } - } - - now.column += subvalue.length; - now.offset += subvalue.length; - subvalue += content + queue; - - /* Ensure the content is followed by a newline and a - * valid marker. */ - character = value.charAt(++index); - marker = value.charAt(++index); - - if (character !== C_NEWLINE$5 || !SETEXT_MARKERS[marker]) { - return; - } - - subvalue += character; - - /* Eat Setext-line. */ - queue = marker; - depth = SETEXT_MARKERS[marker]; - - while (++index < length) { - character = value.charAt(index); - - if (character !== marker) { - if (character !== C_NEWLINE$5) { - return; - } - - index--; - break; - } - - queue += character; - } - - if (silent) { - return true; - } - - return eat(subvalue + queue)({ - type: 'heading', - depth: depth, - children: self.tokenizeInline(content, now) - }); -} - -var attributeName = '[a-zA-Z_:][a-zA-Z0-9:._-]*'; -var unquoted = '[^"\'=<>`\\u0000-\\u0020]+'; -var singleQuoted = '\'[^\']*\''; -var doubleQuoted = '"[^"]*"'; -var attributeValue = '(?:' + unquoted + '|' + singleQuoted + '|' + doubleQuoted + ')'; -var attribute = '(?:\\s+' + attributeName + '(?:\\s*=\\s*' + attributeValue + ')?)'; -var openTag = '<[A-Za-z][A-Za-z0-9\\-]*' + attribute + '*\\s*\\/?>'; -var closeTag = '<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>'; -var comment = '|'; -var processing = '<[?].*?[?]>'; -var declaration = ']*>'; -var cdata = ''; - -var openCloseTag$1 = new RegExp('^(?:' + openTag + '|' + closeTag + ')'); - -var tag$2 = new RegExp('^(?:' + - openTag + '|' + - closeTag + '|' + - comment + '|' + - processing + '|' + - declaration + '|' + - cdata + -')'); - -var html = { - openCloseTag: openCloseTag$1, - tag: tag$2 -}; - -var openCloseTag = html.openCloseTag; - -var htmlBlock = blockHTML; - -var C_TAB$4 = '\t'; -var C_SPACE$4 = ' '; -var C_NEWLINE$4 = '\n'; -var C_LT$4 = '<'; - -function blockHTML(eat, value, silent) { - var self = this; - var blocks = self.options.blocks; - var length = value.length; - var index = 0; - var next; - var line; - var offset; - var character; - var count; - var sequence; - var subvalue; - - var sequences = [ - [/^<(script|pre|style)(?=(\s|>|$))/i, /<\/(script|pre|style)>/i, true], - [/^/, true], - [/^<\?/, /\?>/, true], - [/^/, true], - [/^/, true], - [new RegExp('^|$))', 'i'), /^$/, true], - [new RegExp(openCloseTag.source + '\\s*$'), /^$/, false] - ]; - - /* Eat initial spacing. */ - while (index < length) { - character = value.charAt(index); - - if (character !== C_TAB$4 && character !== C_SPACE$4) { - break; - } - - index++; - } - - if (value.charAt(index) !== C_LT$4) { - return; - } - - next = value.indexOf(C_NEWLINE$4, index + 1); - next = next === -1 ? length : next; - line = value.slice(index, next); - offset = -1; - count = sequences.length; - - while (++offset < count) { - if (sequences[offset][0].test(line)) { - sequence = sequences[offset]; - break; - } - } - - if (!sequence) { - return; - } - - if (silent) { - return sequence[2]; - } - - index = next; - - if (!sequence[1].test(line)) { - while (index < length) { - next = value.indexOf(C_NEWLINE$4, index + 1); - next = next === -1 ? length : next; - line = value.slice(index + 1, next); - - if (sequence[1].test(line)) { - if (line) { - index = next; - } - - break; - } - - index = next; - } - } - - subvalue = value.slice(0, index); - - return eat(subvalue)({type: 'html', value: subvalue}); -} - -var collapseWhiteSpace = collapse; - -// `collapse(' \t\nbar \nbaz\t') // ' bar baz '` -function collapse(value) { - return String(value).replace(/\s+/g, ' ') -} - -var normalize_1 = normalize; - -/* Normalize an identifier. Collapses multiple white space - * characters into a single space, and removes casing. */ -function normalize(value) { - return collapseWhiteSpace(value).toLowerCase(); -} - -var footnoteDefinition_1 = footnoteDefinition; -footnoteDefinition.notInList = true; -footnoteDefinition.notInBlock = true; - -var C_BACKSLASH$4 = '\\'; -var C_NEWLINE$3 = '\n'; -var C_TAB$3 = '\t'; -var C_SPACE$3 = ' '; -var C_BRACKET_OPEN$4 = '['; -var C_BRACKET_CLOSE$4 = ']'; -var C_CARET$1 = '^'; -var C_COLON$2 = ':'; - -var EXPRESSION_INITIAL_TAB = /^( {4}|\t)?/gm; - -function footnoteDefinition(eat, value, silent) { - var self = this; - var offsets = self.offset; - var index; - var length; - var subvalue; - var now; - var currentLine; - var content; - var queue; - var subqueue; - var character; - var identifier; - var add; - var exit; - - if (!self.options.footnotes) { - return; - } - - index = 0; - length = value.length; - subvalue = ''; - now = eat.now(); - currentLine = now.line; - - while (index < length) { - character = value.charAt(index); - - if (!isWhitespaceCharacter(character)) { - break; - } - - subvalue += character; - index++; - } - - if ( - value.charAt(index) !== C_BRACKET_OPEN$4 || - value.charAt(index + 1) !== C_CARET$1 - ) { - return; - } - - subvalue += C_BRACKET_OPEN$4 + C_CARET$1; - index = subvalue.length; - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if (character === C_BRACKET_CLOSE$4) { - break; - } else if (character === C_BACKSLASH$4) { - queue += character; - index++; - character = value.charAt(index); - } - - queue += character; - index++; - } - - if ( - !queue || - value.charAt(index) !== C_BRACKET_CLOSE$4 || - value.charAt(index + 1) !== C_COLON$2 - ) { - return; - } - - if (silent) { - return true; - } - - identifier = normalize_1(queue); - subvalue += queue + C_BRACKET_CLOSE$4 + C_COLON$2; - index = subvalue.length; - - while (index < length) { - character = value.charAt(index); - - if (character !== C_TAB$3 && character !== C_SPACE$3) { - break; - } - - subvalue += character; - index++; - } - - now.column += subvalue.length; - now.offset += subvalue.length; - queue = ''; - content = ''; - subqueue = ''; - - while (index < length) { - character = value.charAt(index); - - if (character === C_NEWLINE$3) { - subqueue = character; - index++; - - while (index < length) { - character = value.charAt(index); - - if (character !== C_NEWLINE$3) { - break; - } - - subqueue += character; - index++; - } - - queue += subqueue; - subqueue = ''; - - while (index < length) { - character = value.charAt(index); - - if (character !== C_SPACE$3) { - break; - } - - subqueue += character; - index++; - } - - if (subqueue.length === 0) { - break; - } - - queue += subqueue; - } - - if (queue) { - content += queue; - queue = ''; - } - - content += character; - index++; - } - - subvalue += content; - - content = content.replace(EXPRESSION_INITIAL_TAB, function (line) { - offsets[currentLine] = (offsets[currentLine] || 0) + line.length; - currentLine++; - - return ''; - }); - - add = eat(subvalue); - - exit = self.enterBlock(); - content = self.tokenizeBlock(content, now); - exit(); - - return add({ - type: 'footnoteDefinition', - identifier: identifier, - children: content - }); -} - -var definition_1 = definition; -definition.notInList = true; -definition.notInBlock = true; - -var C_DOUBLE_QUOTE$1 = '"'; -var C_SINGLE_QUOTE$1 = '\''; -var C_BACKSLASH$3 = '\\'; -var C_NEWLINE$2 = '\n'; -var C_TAB$2 = '\t'; -var C_SPACE$2 = ' '; -var C_BRACKET_OPEN$3 = '['; -var C_BRACKET_CLOSE$3 = ']'; -var C_PAREN_OPEN$2 = '('; -var C_PAREN_CLOSE$2 = ')'; -var C_COLON$1 = ':'; -var C_LT$3 = '<'; -var C_GT$2 = '>'; - -function definition(eat, value, silent) { - var self = this; - var commonmark = self.options.commonmark; - var index = 0; - var length = value.length; - var subvalue = ''; - var beforeURL; - var beforeTitle; - var queue; - var character; - var test; - var identifier; - var url; - var title; - - while (index < length) { - character = value.charAt(index); - - if (character !== C_SPACE$2 && character !== C_TAB$2) { - break; - } - - subvalue += character; - index++; - } - - character = value.charAt(index); - - if (character !== C_BRACKET_OPEN$3) { - return; - } - - index++; - subvalue += character; - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if (character === C_BRACKET_CLOSE$3) { - break; - } else if (character === C_BACKSLASH$3) { - queue += character; - index++; - character = value.charAt(index); - } - - queue += character; - index++; - } - - if ( - !queue || - value.charAt(index) !== C_BRACKET_CLOSE$3 || - value.charAt(index + 1) !== C_COLON$1 - ) { - return; - } - - identifier = queue; - subvalue += queue + C_BRACKET_CLOSE$3 + C_COLON$1; - index = subvalue.length; - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if ( - character !== C_TAB$2 && - character !== C_SPACE$2 && - character !== C_NEWLINE$2 - ) { - break; - } - - subvalue += character; - index++; - } - - character = value.charAt(index); - queue = ''; - beforeURL = subvalue; - - if (character === C_LT$3) { - index++; - - while (index < length) { - character = value.charAt(index); - - if (!isEnclosedURLCharacter(character)) { - break; - } - - queue += character; - index++; - } - - character = value.charAt(index); - - if (character === isEnclosedURLCharacter.delimiter) { - subvalue += C_LT$3 + queue + character; - index++; - } else { - if (commonmark) { - return; - } - - index -= queue.length + 1; - queue = ''; - } - } - - if (!queue) { - while (index < length) { - character = value.charAt(index); - - if (!isUnclosedURLCharacter(character)) { - break; - } - - queue += character; - index++; - } - - subvalue += queue; - } - - if (!queue) { - return; - } - - url = queue; - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if ( - character !== C_TAB$2 && - character !== C_SPACE$2 && - character !== C_NEWLINE$2 - ) { - break; - } - - queue += character; - index++; - } - - character = value.charAt(index); - test = null; - - if (character === C_DOUBLE_QUOTE$1) { - test = C_DOUBLE_QUOTE$1; - } else if (character === C_SINGLE_QUOTE$1) { - test = C_SINGLE_QUOTE$1; - } else if (character === C_PAREN_OPEN$2) { - test = C_PAREN_CLOSE$2; - } - - if (!test) { - queue = ''; - index = subvalue.length; - } else if (queue) { - subvalue += queue + character; - index = subvalue.length; - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if (character === test) { - break; - } - - if (character === C_NEWLINE$2) { - index++; - character = value.charAt(index); - - if (character === C_NEWLINE$2 || character === test) { - return; - } - - queue += C_NEWLINE$2; - } - - queue += character; - index++; - } - - character = value.charAt(index); - - if (character !== test) { - return; - } - - beforeTitle = subvalue; - subvalue += queue + character; - index++; - title = queue; - queue = ''; - } else { - return; - } - - while (index < length) { - character = value.charAt(index); - - if (character !== C_TAB$2 && character !== C_SPACE$2) { - break; - } - - subvalue += character; - index++; - } - - character = value.charAt(index); - - if (!character || character === C_NEWLINE$2) { - if (silent) { - return true; - } - - beforeURL = eat(beforeURL).test().end; - url = self.decode.raw(self.unescape(url), beforeURL, {nonTerminated: false}); - - if (title) { - beforeTitle = eat(beforeTitle).test().end; - title = self.decode.raw(self.unescape(title), beforeTitle); - } - - return eat(subvalue)({ - type: 'definition', - identifier: normalize_1(identifier), - title: title || null, - url: url - }); - } -} - -/* Check if `character` can be inside an enclosed URI. */ -function isEnclosedURLCharacter(character) { - return character !== C_GT$2 && - character !== C_BRACKET_OPEN$3 && - character !== C_BRACKET_CLOSE$3; -} - -isEnclosedURLCharacter.delimiter = C_GT$2; - -/* Check if `character` can be inside an unclosed URI. */ -function isUnclosedURLCharacter(character) { - return character !== C_BRACKET_OPEN$3 && - character !== C_BRACKET_CLOSE$3 && - !isWhitespaceCharacter(character); -} - -var table_1 = table; - -var C_BACKSLASH$2 = '\\'; -var C_TICK$2 = '`'; -var C_DASH = '-'; -var C_PIPE = '|'; -var C_COLON = ':'; -var C_SPACE$1 = ' '; -var C_NEWLINE$1 = '\n'; -var C_TAB$1 = '\t'; - -var MIN_TABLE_COLUMNS = 1; -var MIN_TABLE_ROWS = 2; - -var TABLE_ALIGN_LEFT = 'left'; -var TABLE_ALIGN_CENTER = 'center'; -var TABLE_ALIGN_RIGHT = 'right'; -var TABLE_ALIGN_NONE = null; - -function table(eat, value, silent) { - var self = this; - var index; - var alignments; - var alignment; - var subvalue; - var row; - var length; - var lines; - var queue; - var character; - var hasDash; - var align; - var cell; - var preamble; - var count; - var opening; - var now; - var position; - var lineCount; - var line; - var rows; - var table; - var lineIndex; - var pipeIndex; - var first; - - /* Exit when not in gfm-mode. */ - if (!self.options.gfm) { - return; - } - - /* Get the rows. - * Detecting tables soon is hard, so there are some - * checks for performance here, such as the minimum - * number of rows, and allowed characters in the - * alignment row. */ - index = 0; - lineCount = 0; - length = value.length + 1; - lines = []; - - while (index < length) { - lineIndex = value.indexOf(C_NEWLINE$1, index); - pipeIndex = value.indexOf(C_PIPE, index + 1); - - if (lineIndex === -1) { - lineIndex = value.length; - } - - if (pipeIndex === -1 || pipeIndex > lineIndex) { - if (lineCount < MIN_TABLE_ROWS) { - return; - } - - break; - } - - lines.push(value.slice(index, lineIndex)); - lineCount++; - index = lineIndex + 1; - } - - /* Parse the alignment row. */ - subvalue = lines.join(C_NEWLINE$1); - alignments = lines.splice(1, 1)[0] || []; - index = 0; - length = alignments.length; - lineCount--; - alignment = false; - align = []; - - while (index < length) { - character = alignments.charAt(index); - - if (character === C_PIPE) { - hasDash = null; - - if (alignment === false) { - if (first === false) { - return; - } - } else { - align.push(alignment); - alignment = false; - } - - first = false; - } else if (character === C_DASH) { - hasDash = true; - alignment = alignment || TABLE_ALIGN_NONE; - } else if (character === C_COLON) { - if (alignment === TABLE_ALIGN_LEFT) { - alignment = TABLE_ALIGN_CENTER; - } else if (hasDash && alignment === TABLE_ALIGN_NONE) { - alignment = TABLE_ALIGN_RIGHT; - } else { - alignment = TABLE_ALIGN_LEFT; - } - } else if (!isWhitespaceCharacter(character)) { - return; - } - - index++; - } - - if (alignment !== false) { - align.push(alignment); - } - - /* Exit when without enough columns. */ - if (align.length < MIN_TABLE_COLUMNS) { - return; - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - /* Parse the rows. */ - position = -1; - rows = []; - - table = eat(subvalue).reset({ - type: 'table', - align: align, - children: rows - }); - - while (++position < lineCount) { - line = lines[position]; - row = {type: 'tableRow', children: []}; - - /* Eat a newline character when this is not the - * first row. */ - if (position) { - eat(C_NEWLINE$1); - } - - /* Eat the row. */ - eat(line).reset(row, table); - - length = line.length + 1; - index = 0; - queue = ''; - cell = ''; - preamble = true; - count = null; - opening = null; - - while (index < length) { - character = line.charAt(index); - - if (character === C_TAB$1 || character === C_SPACE$1) { - if (cell) { - queue += character; - } else { - eat(character); - } - - index++; - continue; - } - - if (character === '' || character === C_PIPE) { - if (preamble) { - eat(character); - } else { - if (character && opening) { - queue += character; - index++; - continue; - } - - if ((cell || character) && !preamble) { - subvalue = cell; - - if (queue.length > 1) { - if (character) { - subvalue += queue.slice(0, queue.length - 1); - queue = queue.charAt(queue.length - 1); - } else { - subvalue += queue; - queue = ''; - } - } - - now = eat.now(); - - eat(subvalue)({ - type: 'tableCell', - children: self.tokenizeInline(cell, now) - }, row); - } - - eat(queue + character); - - queue = ''; - cell = ''; - } - } else { - if (queue) { - cell += queue; - queue = ''; - } - - cell += character; - - if (character === C_BACKSLASH$2 && index !== length - 2) { - cell += line.charAt(index + 1); - index++; - } - - if (character === C_TICK$2) { - count = 1; - - while (line.charAt(index + 1) === character) { - cell += character; - index++; - count++; - } - - if (!opening) { - opening = count; - } else if (count >= opening) { - opening = 0; - } - } - } - - preamble = false; - index++; - } - - /* Eat the alignment row. */ - if (!position) { - eat(C_NEWLINE$1 + alignments); - } - } - - return table; -} - -var paragraph_1 = paragraph; - -var C_NEWLINE = '\n'; -var C_TAB = '\t'; -var C_SPACE = ' '; - -var TAB_SIZE = 4; - -/* Tokenise paragraph. */ -function paragraph(eat, value, silent) { - var self = this; - var settings = self.options; - var commonmark = settings.commonmark; - var gfm = settings.gfm; - var tokenizers = self.blockTokenizers; - var interruptors = self.interruptParagraph; - var index = value.indexOf(C_NEWLINE); - var length = value.length; - var position; - var subvalue; - var character; - var size; - var now; - - while (index < length) { - /* Eat everything if there’s no following newline. */ - if (index === -1) { - index = length; - break; - } - - /* Stop if the next character is NEWLINE. */ - if (value.charAt(index + 1) === C_NEWLINE) { - break; - } - - /* In commonmark-mode, following indented lines - * are part of the paragraph. */ - if (commonmark) { - size = 0; - position = index + 1; - - while (position < length) { - character = value.charAt(position); - - if (character === C_TAB) { - size = TAB_SIZE; - break; - } else if (character === C_SPACE) { - size++; - } else { - break; - } - - position++; - } - - if (size >= TAB_SIZE) { - index = value.indexOf(C_NEWLINE, index + 1); - continue; - } - } - - subvalue = value.slice(index + 1); - - /* Check if the following code contains a possible - * block. */ - if (interrupt_1(interruptors, tokenizers, self, [eat, subvalue, true])) { - break; - } - - /* Break if the following line starts a list, when - * already in a list, or when in commonmark, or when - * in gfm mode and the bullet is *not* numeric. */ - if ( - tokenizers.list.call(self, eat, subvalue, true) && - ( - self.inList || - commonmark || - (gfm && !isDecimal(trim_1.left(subvalue).charAt(0))) - ) - ) { - break; - } - - position = index; - index = value.indexOf(C_NEWLINE, index + 1); - - if (index !== -1 && trim_1(value.slice(position, index)) === '') { - index = position; - break; - } - } - - subvalue = value.slice(0, index); - - if (trim_1(subvalue) === '') { - eat(subvalue); - - return null; - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - now = eat.now(); - subvalue = trimTrailingLines_1(subvalue); - - return eat(subvalue)({ - type: 'paragraph', - children: self.tokenizeInline(subvalue, now) - }); -} - -var _escape$1 = locate$8; - -function locate$8(value, fromIndex) { - return value.indexOf('\\', fromIndex); -} - -var _escape = escape; -escape.locator = _escape$1; - -function escape(eat, value, silent) { - var self = this; - var character; - var node; - - if (value.charAt(0) === '\\') { - character = value.charAt(1); - - if (self.escape.indexOf(character) !== -1) { - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - if (character === '\n') { - node = {type: 'break'}; - } else { - node = { - type: 'text', - value: character - }; - } - - return eat('\\' + character)(node); - } - } -} - -var tag$1 = locate$7; - -function locate$7(value, fromIndex) { - return value.indexOf('<', fromIndex); -} - -var autoLink_1 = autoLink; -autoLink.locator = tag$1; -autoLink.notInLink = true; - -var C_LT$2 = '<'; -var C_GT$1 = '>'; -var C_AT_SIGN$1 = '@'; -var C_SLASH = '/'; -var MAILTO = 'mailto:'; -var MAILTO_LENGTH = MAILTO.length; - -/* Tokenise a link. */ -function autoLink(eat, value, silent) { - var self; - var subvalue; - var length; - var index; - var queue; - var character; - var hasAtCharacter; - var link; - var now; - var content; - var tokenizers; - var exit; - - if (value.charAt(0) !== C_LT$2) { - return; - } - - self = this; - subvalue = ''; - length = value.length; - index = 0; - queue = ''; - hasAtCharacter = false; - link = ''; - - index++; - subvalue = C_LT$2; - - while (index < length) { - character = value.charAt(index); - - if ( - isWhitespaceCharacter(character) || - character === C_GT$1 || - character === C_AT_SIGN$1 || - (character === ':' && value.charAt(index + 1) === C_SLASH) - ) { - break; - } - - queue += character; - index++; - } - - if (!queue) { - return; - } - - link += queue; - queue = ''; - - character = value.charAt(index); - link += character; - index++; - - if (character === C_AT_SIGN$1) { - hasAtCharacter = true; - } else { - if ( - character !== ':' || - value.charAt(index + 1) !== C_SLASH - ) { - return; - } - - link += C_SLASH; - index++; - } - - while (index < length) { - character = value.charAt(index); - - if (isWhitespaceCharacter(character) || character === C_GT$1) { - break; - } - - queue += character; - index++; - } - - character = value.charAt(index); - - if (!queue || character !== C_GT$1) { - return; - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - link += queue; - content = link; - subvalue += link + character; - now = eat.now(); - now.column++; - now.offset++; - - if (hasAtCharacter) { - if (link.slice(0, MAILTO_LENGTH).toLowerCase() === MAILTO) { - content = content.substr(MAILTO_LENGTH); - now.column += MAILTO_LENGTH; - now.offset += MAILTO_LENGTH; - } else { - link = MAILTO + link; - } - } - - /* Temporarily remove all tokenizers except text in autolinks. */ - tokenizers = self.inlineTokenizers; - self.inlineTokenizers = {text: tokenizers.text}; - - exit = self.enterLink(); - - content = self.tokenizeInline(content, now); - - self.inlineTokenizers = tokenizers; - exit(); - - return eat(subvalue)({ - type: 'link', - title: null, - url: parseEntities_1(link, {nonTerminated: false}), - children: content - }); -} - -var url$1 = locate$6; - -var PROTOCOLS$1 = ['https://', 'http://', 'mailto:']; - -function locate$6(value, fromIndex) { - var length = PROTOCOLS$1.length; - var index = -1; - var min = -1; - var position; - - if (!this.options.gfm) { - return -1; - } - - while (++index < length) { - position = value.indexOf(PROTOCOLS$1[index], fromIndex); - - if (position !== -1 && (position < min || min === -1)) { - min = position; - } - } - - return min; -} - -var url_1 = url; -url.locator = url$1; -url.notInLink = true; - -var C_BRACKET_OPEN$2 = '['; -var C_BRACKET_CLOSE$2 = ']'; -var C_PAREN_OPEN$1 = '('; -var C_PAREN_CLOSE$1 = ')'; -var C_LT$1 = '<'; -var C_AT_SIGN = '@'; - -var HTTP_PROTOCOL = 'http://'; -var HTTPS_PROTOCOL = 'https://'; -var MAILTO_PROTOCOL = 'mailto:'; - -var PROTOCOLS = [ - HTTP_PROTOCOL, - HTTPS_PROTOCOL, - MAILTO_PROTOCOL -]; - -var PROTOCOLS_LENGTH = PROTOCOLS.length; - -function url(eat, value, silent) { - var self = this; - var subvalue; - var content; - var character; - var index; - var position; - var protocol; - var match; - var length; - var queue; - var parenCount; - var nextCharacter; - var exit; - - if (!self.options.gfm) { - return; - } - - subvalue = ''; - index = -1; - length = PROTOCOLS_LENGTH; - - while (++index < length) { - protocol = PROTOCOLS[index]; - match = value.slice(0, protocol.length); - - if (match.toLowerCase() === protocol) { - subvalue = match; - break; - } - } - - if (!subvalue) { - return; - } - - index = subvalue.length; - length = value.length; - queue = ''; - parenCount = 0; - - while (index < length) { - character = value.charAt(index); - - if (isWhitespaceCharacter(character) || character === C_LT$1) { - break; - } - - if ( - character === '.' || - character === ',' || - character === ':' || - character === ';' || - character === '"' || - character === '\'' || - character === ')' || - character === ']' - ) { - nextCharacter = value.charAt(index + 1); - - if (!nextCharacter || isWhitespaceCharacter(nextCharacter)) { - break; - } - } - - if (character === C_PAREN_OPEN$1 || character === C_BRACKET_OPEN$2) { - parenCount++; - } - - if (character === C_PAREN_CLOSE$1 || character === C_BRACKET_CLOSE$2) { - parenCount--; - - if (parenCount < 0) { - break; - } - } - - queue += character; - index++; - } - - if (!queue) { - return; - } - - subvalue += queue; - content = subvalue; - - if (protocol === MAILTO_PROTOCOL) { - position = queue.indexOf(C_AT_SIGN); - - if (position === -1 || position === length - 1) { - return; - } - - content = content.substr(MAILTO_PROTOCOL.length); - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - exit = self.enterLink(); - content = self.tokenizeInline(content, eat.now()); - exit(); - - return eat(subvalue)({ - type: 'link', - title: null, - url: parseEntities_1(subvalue, {nonTerminated: false}), - children: content - }); -} - -var tag = html.tag; - -var htmlInline = inlineHTML; -inlineHTML.locator = tag$1; - -var EXPRESSION_HTML_LINK_OPEN = /^/i; - -function inlineHTML(eat, value, silent) { - var self = this; - var length = value.length; - var character; - var subvalue; - - if (value.charAt(0) !== '<' || length < 3) { - return; - } - - character = value.charAt(1); - - if ( - !isAlphabetical(character) && - character !== '?' && - character !== '!' && - character !== '/' - ) { - return; - } - - subvalue = value.match(tag); - - if (!subvalue) { - return; - } - - /* istanbul ignore if - not used yet. */ - if (silent) { - return true; - } - - subvalue = subvalue[0]; - - if (!self.inLink && EXPRESSION_HTML_LINK_OPEN.test(subvalue)) { - self.inLink = true; - } else if (self.inLink && EXPRESSION_HTML_LINK_CLOSE.test(subvalue)) { - self.inLink = false; - } - - return eat(subvalue)({type: 'html', value: subvalue}); -} - -var link$1 = locate$5; - -function locate$5(value, fromIndex) { - var link = value.indexOf('[', fromIndex); - var image = value.indexOf('![', fromIndex); - - if (image === -1) { - return link; - } - - /* Link can never be `-1` if an image is found, so we don’t need - * to check for that :) */ - return link < image ? link : image; -} - -var link_1 = link; -link.locator = link$1; - -var own = {}.hasOwnProperty; - -var C_BACKSLASH$1 = '\\'; -var C_BRACKET_OPEN$1 = '['; -var C_BRACKET_CLOSE$1 = ']'; -var C_PAREN_OPEN = '('; -var C_PAREN_CLOSE = ')'; -var C_LT = '<'; -var C_GT = '>'; -var C_TICK$1 = '`'; -var C_DOUBLE_QUOTE = '"'; -var C_SINGLE_QUOTE = '\''; - -/* Map of characters, which can be used to mark link - * and image titles. */ -var LINK_MARKERS = {}; - -LINK_MARKERS[C_DOUBLE_QUOTE] = C_DOUBLE_QUOTE; -LINK_MARKERS[C_SINGLE_QUOTE] = C_SINGLE_QUOTE; - -/* Map of characters, which can be used to mark link - * and image titles in commonmark-mode. */ -var COMMONMARK_LINK_MARKERS = {}; - -COMMONMARK_LINK_MARKERS[C_DOUBLE_QUOTE] = C_DOUBLE_QUOTE; -COMMONMARK_LINK_MARKERS[C_SINGLE_QUOTE] = C_SINGLE_QUOTE; -COMMONMARK_LINK_MARKERS[C_PAREN_OPEN] = C_PAREN_CLOSE; - -function link(eat, value, silent) { - var self = this; - var subvalue = ''; - var index = 0; - var character = value.charAt(0); - var pedantic = self.options.pedantic; - var commonmark = self.options.commonmark; - var gfm = self.options.gfm; - var closed; - var count; - var opening; - var beforeURL; - var beforeTitle; - var subqueue; - var hasMarker; - var markers; - var isImage; - var content; - var marker; - var length; - var title; - var depth; - var queue; - var url; - var now; - var exit; - var node; - - /* Detect whether this is an image. */ - if (character === '!') { - isImage = true; - subvalue = character; - character = value.charAt(++index); - } - - /* Eat the opening. */ - if (character !== C_BRACKET_OPEN$1) { - return; - } - - /* Exit when this is a link and we’re already inside - * a link. */ - if (!isImage && self.inLink) { - return; - } - - subvalue += character; - queue = ''; - index++; - - /* Eat the content. */ - length = value.length; - now = eat.now(); - depth = 0; - - now.column += index; - now.offset += index; - - while (index < length) { - character = value.charAt(index); - subqueue = character; - - if (character === C_TICK$1) { - /* Inline-code in link content. */ - count = 1; - - while (value.charAt(index + 1) === C_TICK$1) { - subqueue += character; - index++; - count++; - } - - if (!opening) { - opening = count; - } else if (count >= opening) { - opening = 0; - } - } else if (character === C_BACKSLASH$1) { - /* Allow brackets to be escaped. */ - index++; - subqueue += value.charAt(index); - /* In GFM mode, brackets in code still count. - * In all other modes, they don’t. This empty - * block prevents the next statements are - * entered. */ - } else if ((!opening || gfm) && character === C_BRACKET_OPEN$1) { - depth++; - } else if ((!opening || gfm) && character === C_BRACKET_CLOSE$1) { - if (depth) { - depth--; - } else { - /* Allow white-space between content and - * url in GFM mode. */ - if (!pedantic) { - while (index < length) { - character = value.charAt(index + 1); - - if (!isWhitespaceCharacter(character)) { - break; - } - - subqueue += character; - index++; - } - } - - if (value.charAt(index + 1) !== C_PAREN_OPEN) { - return; - } - - subqueue += C_PAREN_OPEN; - closed = true; - index++; - - break; - } - } - - queue += subqueue; - subqueue = ''; - index++; - } - - /* Eat the content closing. */ - if (!closed) { - return; - } - - content = queue; - subvalue += queue + subqueue; - index++; - - /* Eat white-space. */ - while (index < length) { - character = value.charAt(index); - - if (!isWhitespaceCharacter(character)) { - break; - } - - subvalue += character; - index++; - } - - /* Eat the URL. */ - character = value.charAt(index); - markers = commonmark ? COMMONMARK_LINK_MARKERS : LINK_MARKERS; - queue = ''; - beforeURL = subvalue; - - if (character === C_LT) { - index++; - beforeURL += C_LT; - - while (index < length) { - character = value.charAt(index); - - if (character === C_GT) { - break; - } - - if (commonmark && character === '\n') { - return; - } - - queue += character; - index++; - } - - if (value.charAt(index) !== C_GT) { - return; - } - - subvalue += C_LT + queue + C_GT; - url = queue; - index++; - } else { - character = null; - subqueue = ''; - - while (index < length) { - character = value.charAt(index); - - if (subqueue && own.call(markers, character)) { - break; - } - - if (isWhitespaceCharacter(character)) { - if (!pedantic) { - break; - } - - subqueue += character; - } else { - if (character === C_PAREN_OPEN) { - depth++; - } else if (character === C_PAREN_CLOSE) { - if (depth === 0) { - break; - } - - depth--; - } - - queue += subqueue; - subqueue = ''; - - if (character === C_BACKSLASH$1) { - queue += C_BACKSLASH$1; - character = value.charAt(++index); - } - - queue += character; - } - - index++; - } - - subvalue += queue; - url = queue; - index = subvalue.length; - } - - /* Eat white-space. */ - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if (!isWhitespaceCharacter(character)) { - break; - } - - queue += character; - index++; - } - - character = value.charAt(index); - subvalue += queue; - - /* Eat the title. */ - if (queue && own.call(markers, character)) { - index++; - subvalue += character; - queue = ''; - marker = markers[character]; - beforeTitle = subvalue; - - /* In commonmark-mode, things are pretty easy: the - * marker cannot occur inside the title. - * - * Non-commonmark does, however, support nested - * delimiters. */ - if (commonmark) { - while (index < length) { - character = value.charAt(index); - - if (character === marker) { - break; - } - - if (character === C_BACKSLASH$1) { - queue += C_BACKSLASH$1; - character = value.charAt(++index); - } - - index++; - queue += character; - } - - character = value.charAt(index); - - if (character !== marker) { - return; - } - - title = queue; - subvalue += queue + character; - index++; - - while (index < length) { - character = value.charAt(index); - - if (!isWhitespaceCharacter(character)) { - break; - } - - subvalue += character; - index++; - } - } else { - subqueue = ''; - - while (index < length) { - character = value.charAt(index); - - if (character === marker) { - if (hasMarker) { - queue += marker + subqueue; - subqueue = ''; - } - - hasMarker = true; - } else if (!hasMarker) { - queue += character; - } else if (character === C_PAREN_CLOSE) { - subvalue += queue + marker + subqueue; - title = queue; - break; - } else if (isWhitespaceCharacter(character)) { - subqueue += character; - } else { - queue += marker + subqueue + character; - subqueue = ''; - hasMarker = false; - } - - index++; - } - } - } - - if (value.charAt(index) !== C_PAREN_CLOSE) { - return; - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - subvalue += C_PAREN_CLOSE; - - url = self.decode.raw(self.unescape(url), eat(beforeURL).test().end, {nonTerminated: false}); - - if (title) { - beforeTitle = eat(beforeTitle).test().end; - title = self.decode.raw(self.unescape(title), beforeTitle); - } - - node = { - type: isImage ? 'image' : 'link', - title: title || null, - url: url - }; - - if (isImage) { - node.alt = self.decode.raw(self.unescape(content), now) || null; - } else { - exit = self.enterLink(); - node.children = self.tokenizeInline(content, now); - exit(); - } - - return eat(subvalue)(node); -} - -var reference_1 = reference; -reference.locator = link$1; - -var T_LINK = 'link'; -var T_IMAGE = 'image'; -var T_FOOTNOTE = 'footnote'; -var REFERENCE_TYPE_SHORTCUT = 'shortcut'; -var REFERENCE_TYPE_COLLAPSED = 'collapsed'; -var REFERENCE_TYPE_FULL = 'full'; -var C_CARET = '^'; -var C_BACKSLASH = '\\'; -var C_BRACKET_OPEN = '['; -var C_BRACKET_CLOSE = ']'; - -function reference(eat, value, silent) { - var self = this; - var character = value.charAt(0); - var index = 0; - var length = value.length; - var subvalue = ''; - var intro = ''; - var type = T_LINK; - var referenceType = REFERENCE_TYPE_SHORTCUT; - var content; - var identifier; - var now; - var node; - var exit; - var queue; - var bracketed; - var depth; - - /* Check whether we’re eating an image. */ - if (character === '!') { - type = T_IMAGE; - intro = character; - character = value.charAt(++index); - } - - if (character !== C_BRACKET_OPEN) { - return; - } - - index++; - intro += character; - queue = ''; - - /* Check whether we’re eating a footnote. */ - if (self.options.footnotes && value.charAt(index) === C_CARET) { - /* Exit if `![^` is found, so the `!` will be seen as text after this, - * and we’ll enter this function again when `[^` is found. */ - if (type === T_IMAGE) { - return; - } - - intro += C_CARET; - index++; - type = T_FOOTNOTE; - } - - /* Eat the text. */ - depth = 0; - - while (index < length) { - character = value.charAt(index); - - if (character === C_BRACKET_OPEN) { - bracketed = true; - depth++; - } else if (character === C_BRACKET_CLOSE) { - if (!depth) { - break; - } - - depth--; - } - - if (character === C_BACKSLASH) { - queue += C_BACKSLASH; - character = value.charAt(++index); - } - - queue += character; - index++; - } - - subvalue = queue; - content = queue; - character = value.charAt(index); - - if (character !== C_BRACKET_CLOSE) { - return; - } - - index++; - subvalue += character; - queue = ''; - - while (index < length) { - character = value.charAt(index); - - if (!isWhitespaceCharacter(character)) { - break; - } - - queue += character; - index++; - } - - character = value.charAt(index); - - /* Inline footnotes cannot have an identifier. */ - if (type !== T_FOOTNOTE && character === C_BRACKET_OPEN) { - identifier = ''; - queue += character; - index++; - - while (index < length) { - character = value.charAt(index); - - if (character === C_BRACKET_OPEN || character === C_BRACKET_CLOSE) { - break; - } - - if (character === C_BACKSLASH) { - identifier += C_BACKSLASH; - character = value.charAt(++index); - } - - identifier += character; - index++; - } - - character = value.charAt(index); - - if (character === C_BRACKET_CLOSE) { - referenceType = identifier ? REFERENCE_TYPE_FULL : REFERENCE_TYPE_COLLAPSED; - queue += identifier + character; - index++; - } else { - identifier = ''; - } - - subvalue += queue; - queue = ''; - } else { - if (!content) { - return; - } - - identifier = content; - } - - /* Brackets cannot be inside the identifier. */ - if (referenceType !== REFERENCE_TYPE_FULL && bracketed) { - return; - } - - subvalue = intro + subvalue; - - if (type === T_LINK && self.inLink) { - return null; - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - if (type === T_FOOTNOTE && content.indexOf(' ') !== -1) { - return eat(subvalue)({ - type: 'footnote', - children: this.tokenizeInline(content, eat.now()) - }); - } - - now = eat.now(); - now.column += intro.length; - now.offset += intro.length; - identifier = referenceType === REFERENCE_TYPE_FULL ? identifier : content; - - node = { - type: type + 'Reference', - identifier: normalize_1(identifier) - }; - - if (type === T_LINK || type === T_IMAGE) { - node.referenceType = referenceType; - } - - if (type === T_LINK) { - exit = self.enterLink(); - node.children = self.tokenizeInline(content, now); - exit(); - } else if (type === T_IMAGE) { - node.alt = self.decode.raw(self.unescape(content), now) || null; - } - - return eat(subvalue)(node); -} - -var strong$1 = locate$4; - -function locate$4(value, fromIndex) { - var asterisk = value.indexOf('**', fromIndex); - var underscore = value.indexOf('__', fromIndex); - - if (underscore === -1) { - return asterisk; - } - - if (asterisk === -1) { - return underscore; - } - - return underscore < asterisk ? underscore : asterisk; -} - -var strong_1 = strong; -strong.locator = strong$1; - -var C_ASTERISK$1 = '*'; -var C_UNDERSCORE$1 = '_'; - -function strong(eat, value, silent) { - var self = this; - var index = 0; - var character = value.charAt(index); - var now; - var pedantic; - var marker; - var queue; - var subvalue; - var length; - var prev; - - if ( - (character !== C_ASTERISK$1 && character !== C_UNDERSCORE$1) || - value.charAt(++index) !== character - ) { - return; - } - - pedantic = self.options.pedantic; - marker = character; - subvalue = marker + marker; - length = value.length; - index++; - queue = ''; - character = ''; - - if (pedantic && isWhitespaceCharacter(value.charAt(index))) { - return; - } - - while (index < length) { - prev = character; - character = value.charAt(index); - - if ( - character === marker && - value.charAt(index + 1) === marker && - (!pedantic || !isWhitespaceCharacter(prev)) - ) { - character = value.charAt(index + 2); - - if (character !== marker) { - if (!trim_1(queue)) { - return; - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - now = eat.now(); - now.column += 2; - now.offset += 2; - - return eat(subvalue + queue + subvalue)({ - type: 'strong', - children: self.tokenizeInline(queue, now) - }); - } - } - - if (!pedantic && character === '\\') { - queue += character; - character = value.charAt(++index); - } - - queue += character; - index++; - } -} - -var isWordCharacter = wordCharacter; - -var fromCode = String.fromCharCode; -var re = /\w/; - -// Check if the given character code, or the character code at the first -// character, is a word character. -function wordCharacter(character) { - return re.test( - typeof character === 'number' ? fromCode(character) : character.charAt(0) - ) -} - -var emphasis$1 = locate$3; - -function locate$3(value, fromIndex) { - var asterisk = value.indexOf('*', fromIndex); - var underscore = value.indexOf('_', fromIndex); - - if (underscore === -1) { - return asterisk; - } - - if (asterisk === -1) { - return underscore; - } - - return underscore < asterisk ? underscore : asterisk; -} - -var emphasis_1 = emphasis; -emphasis.locator = emphasis$1; - -var C_ASTERISK = '*'; -var C_UNDERSCORE = '_'; - -function emphasis(eat, value, silent) { - var self = this; - var index = 0; - var character = value.charAt(index); - var now; - var pedantic; - var marker; - var queue; - var subvalue; - var length; - var prev; - - if (character !== C_ASTERISK && character !== C_UNDERSCORE) { - return; - } - - pedantic = self.options.pedantic; - subvalue = character; - marker = character; - length = value.length; - index++; - queue = ''; - character = ''; - - if (pedantic && isWhitespaceCharacter(value.charAt(index))) { - return; - } - - while (index < length) { - prev = character; - character = value.charAt(index); - - if (character === marker && (!pedantic || !isWhitespaceCharacter(prev))) { - character = value.charAt(++index); - - if (character !== marker) { - if (!trim_1(queue) || prev === marker) { - return; - } - - if (!pedantic && marker === C_UNDERSCORE && isWordCharacter(character)) { - queue += marker; - continue; - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - now = eat.now(); - now.column++; - now.offset++; - - return eat(subvalue + queue + marker)({ - type: 'emphasis', - children: self.tokenizeInline(queue, now) - }); - } - - queue += marker; - } - - if (!pedantic && character === '\\') { - queue += character; - character = value.charAt(++index); - } - - queue += character; - index++; - } -} - -var _delete$1 = locate$2; - -function locate$2(value, fromIndex) { - return value.indexOf('~~', fromIndex); -} - -var _delete = strikethrough; -strikethrough.locator = _delete$1; - -var C_TILDE = '~'; -var DOUBLE = '~~'; - -function strikethrough(eat, value, silent) { - var self = this; - var character = ''; - var previous = ''; - var preceding = ''; - var subvalue = ''; - var index; - var length; - var now; - - if ( - !self.options.gfm || - value.charAt(0) !== C_TILDE || - value.charAt(1) !== C_TILDE || - isWhitespaceCharacter(value.charAt(2)) - ) { - return; - } - - index = 1; - length = value.length; - now = eat.now(); - now.column += 2; - now.offset += 2; - - while (++index < length) { - character = value.charAt(index); - - if ( - character === C_TILDE && - previous === C_TILDE && - (!preceding || !isWhitespaceCharacter(preceding)) - ) { - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - return eat(DOUBLE + subvalue + DOUBLE)({ - type: 'delete', - children: self.tokenizeInline(subvalue, now) - }); - } - - subvalue += previous; - preceding = previous; - previous = character; - } -} - -var codeInline$1 = locate$1; - -function locate$1(value, fromIndex) { - return value.indexOf('`', fromIndex); -} - -var codeInline = inlineCode; -inlineCode.locator = codeInline$1; - -var C_TICK = '`'; - -/* Tokenise inline code. */ -function inlineCode(eat, value, silent) { - var length = value.length; - var index = 0; - var queue = ''; - var tickQueue = ''; - var contentQueue; - var subqueue; - var count; - var openingCount; - var subvalue; - var character; - var found; - var next; - - while (index < length) { - if (value.charAt(index) !== C_TICK) { - break; - } - - queue += C_TICK; - index++; - } - - if (!queue) { - return; - } - - subvalue = queue; - openingCount = index; - queue = ''; - next = value.charAt(index); - count = 0; - - while (index < length) { - character = next; - next = value.charAt(index + 1); - - if (character === C_TICK) { - count++; - tickQueue += character; - } else { - count = 0; - queue += character; - } - - if (count && next !== C_TICK) { - if (count === openingCount) { - subvalue += queue + tickQueue; - found = true; - break; - } - - queue += tickQueue; - tickQueue = ''; - } - - index++; - } - - if (!found) { - if (openingCount % 2 !== 0) { - return; - } - - queue = ''; - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - contentQueue = ''; - subqueue = ''; - length = queue.length; - index = -1; - - while (++index < length) { - character = queue.charAt(index); - - if (isWhitespaceCharacter(character)) { - subqueue += character; - continue; - } - - if (subqueue) { - if (contentQueue) { - contentQueue += subqueue; - } - - subqueue = ''; - } - - contentQueue += character; - } - - return eat(subvalue)({ - type: 'inlineCode', - value: contentQueue - }); -} - -var _break$1 = locate; - -function locate(value, fromIndex) { - var index = value.indexOf('\n', fromIndex); - - while (index > fromIndex) { - if (value.charAt(index - 1) !== ' ') { - break; - } - - index--; - } - - return index; -} - -var _break = hardBreak; -hardBreak.locator = _break$1; - -var MIN_BREAK_LENGTH = 2; - -function hardBreak(eat, value, silent) { - var length = value.length; - var index = -1; - var queue = ''; - var character; - - while (++index < length) { - character = value.charAt(index); - - if (character === '\n') { - if (index < MIN_BREAK_LENGTH) { - return; - } - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - queue += character; - - return eat(queue)({type: 'break'}); - } - - if (character !== ' ') { - return; - } - - queue += character; - } -} - -var text_1 = text; - -function text(eat, value, silent) { - var self = this; - var methods; - var tokenizers; - var index; - var length; - var subvalue; - var position; - var tokenizer; - var name; - var min; - var now; - - /* istanbul ignore if - never used (yet) */ - if (silent) { - return true; - } - - methods = self.inlineMethods; - length = methods.length; - tokenizers = self.inlineTokenizers; - index = -1; - min = value.length; - - while (++index < length) { - name = methods[index]; - - if (name === 'text' || !tokenizers[name]) { - continue; - } - - tokenizer = tokenizers[name].locator; - - if (!tokenizer) { - eat.file.fail('Missing locator: `' + name + '`'); - } - - position = tokenizer.call(self, value, 1); - - if (position !== -1 && position < min) { - min = position; - } - } - - subvalue = value.slice(0, min); - now = eat.now(); - - self.decode(subvalue, now, function (content, position, source) { - eat(source || content)({ - type: 'text', - value: content - }); - }); -} - -var parser = Parser; - -function Parser(doc, file) { - this.file = file; - this.offset = {}; - this.options = immutable(this.options); - this.setOptions({}); - - this.inList = false; - this.inBlock = false; - this.inLink = false; - this.atStart = true; - - this.toOffset = vfileLocation(file).toOffset; - this.unescape = _unescape(this, 'escape'); - this.decode = decode(this); -} - -var proto = Parser.prototype; - -/* Expose core. */ -proto.setOptions = setOptions_1; -proto.parse = parse_1; - -/* Expose `defaults`. */ -proto.options = defaults; - -/* Enter and exit helpers. */ -proto.exitStart = stateToggle('atStart', true); -proto.enterList = stateToggle('inList', false); -proto.enterLink = stateToggle('inLink', false); -proto.enterBlock = stateToggle('inBlock', false); - -/* Nodes that can interupt a paragraph: - * - * ```markdown - * A paragraph, followed by a thematic break. - * ___ - * ``` - * - * In the above example, the thematic break “interupts” - * the paragraph. */ -proto.interruptParagraph = [ - ['thematicBreak'], - ['atxHeading'], - ['fencedCode'], - ['blockquote'], - ['html'], - ['setextHeading', {commonmark: false}], - ['definition', {commonmark: false}], - ['footnote', {commonmark: false}] -]; - -/* Nodes that can interupt a list: - * - * ```markdown - * - One - * ___ - * ``` - * - * In the above example, the thematic break “interupts” - * the list. */ -proto.interruptList = [ - ['atxHeading', {pedantic: false}], - ['fencedCode', {pedantic: false}], - ['thematicBreak', {pedantic: false}], - ['definition', {commonmark: false}], - ['footnote', {commonmark: false}] -]; - -/* Nodes that can interupt a blockquote: - * - * ```markdown - * > A paragraph. - * ___ - * ``` - * - * In the above example, the thematic break “interupts” - * the blockquote. */ -proto.interruptBlockquote = [ - ['indentedCode', {commonmark: true}], - ['fencedCode', {commonmark: true}], - ['atxHeading', {commonmark: true}], - ['setextHeading', {commonmark: true}], - ['thematicBreak', {commonmark: true}], - ['html', {commonmark: true}], - ['list', {commonmark: true}], - ['definition', {commonmark: false}], - ['footnote', {commonmark: false}] -]; - -/* Handlers. */ -proto.blockTokenizers = { - newline: newline_1, - indentedCode: codeIndented, - fencedCode: codeFenced, - blockquote: blockquote_1, - atxHeading: headingAtx, - thematicBreak: thematicBreak_1, - list: list_1, - setextHeading: headingSetext, - html: htmlBlock, - footnote: footnoteDefinition_1, - definition: definition_1, - table: table_1, - paragraph: paragraph_1 -}; - -proto.inlineTokenizers = { - escape: _escape, - autoLink: autoLink_1, - url: url_1, - html: htmlInline, - link: link_1, - reference: reference_1, - strong: strong_1, - emphasis: emphasis_1, - deletion: _delete, - code: codeInline, - break: _break, - text: text_1 -}; - -/* Expose precedence. */ -proto.blockMethods = keys(proto.blockTokenizers); -proto.inlineMethods = keys(proto.inlineTokenizers); - -/* Tokenizers. */ -proto.tokenizeBlock = tokenizer('block'); -proto.tokenizeInline = tokenizer('inline'); -proto.tokenizeFactory = tokenizer; - -/* Get all keys in `value`. */ -function keys(value) { - var result = []; - var key; - - for (key in value) { - result.push(key); - } - - return result; -} - -var remarkParse = parse; -parse.Parser = parser; - -function parse(options) { - var Local = unherit_1(parser); - Local.prototype.options = immutable(Local.prototype.options, this.data('settings'), options); - this.Parser = Local; -} - -/** - * @fileoverview Processes Markdown files for consumption by ESLint. - * @author Brandon Mills - */ - - - - -const UNSATISFIABLE_RULES = [ - "eol-last", // The Markdown parser strips trailing newlines in code fences - "unicode-bom" // Code blocks will begin in the middle of Markdown files -]; -const SUPPORTS_AUTOFIX = true; - -const markdown = unified_1().use(remarkParse); - -/** - * @type {Map} - */ -const blocksCache = new Map(); - -/** - * Performs a depth-first traversal of the Markdown AST. - * @param {ASTNode} node A Markdown AST node. - * @param {{[key: string]: (node: ASTNode) => void}} callbacks A map of node types to callbacks. - * @returns {void} - */ -function traverse(node, callbacks) { - if (callbacks[node.type]) { - callbacks[node.type](node); - } else { - callbacks["*"](); - } - - if (typeof node.children !== "undefined") { - for (let i = 0; i < node.children.length; i++) { - traverse(node.children[i], callbacks); - } - } -} - -/** - * Extracts `eslint-*` or `global` comments from HTML comments if present. - * @param {string} html The text content of an HTML AST node. - * @returns {string} The comment's text without the opening and closing tags or - * an empty string if the text is not an ESLint HTML comment. - */ -function getComment(html) { - const commentStart = ""; - const regex = /^(eslint\b|global\s)/u; - - if ( - html.slice(0, commentStart.length) !== commentStart || - html.slice(-commentEnd.length) !== commentEnd - ) { - return ""; - } - - const comment = html.slice(commentStart.length, -commentEnd.length); - - if (!regex.test(comment.trim())) { - return ""; - } - - return comment; -} - -// Before a code block, blockquote characters (`>`) are also considered -// "whitespace". -const leadingWhitespaceRegex = /^[>\s]*/u; - -/** - * Gets the offset for the first column of the node's first line in the - * original source text. - * @param {ASTNode} node A Markdown code block AST node. - * @returns {number} The offset for the first column of the node's first line. - */ -function getBeginningOfLineOffset(node) { - return node.position.start.offset - node.position.start.column + 1; -} - -/** - * Gets the leading text, typically whitespace with possible blockquote chars, - * used to indent a code block. - * @param {string} text The text of the file. - * @param {ASTNode} node A Markdown code block AST node. - * @returns {string} The text from the start of the first line to the opening - * fence of the code block. - */ -function getIndentText(text, node) { - return leadingWhitespaceRegex.exec( - text.slice(getBeginningOfLineOffset(node)) - )[0]; -} - -/** - * When applying fixes, the postprocess step needs to know how to map fix ranges - * from their location in the linted JS to the original offset in the Markdown. - * Configuration comments and indentation trimming both complicate this process. - * - * Configuration comments appear in the linted JS but not in the Markdown code - * block. Fixes to configuration comments would cause undefined behavior and - * should be ignored during postprocessing. Fixes to actual code after - * configuration comments need to be mapped back to the code block after - * removing any offset due to configuration comments. - * - * Fenced code blocks can be indented by up to three spaces at the opening - * fence. Inside of a list, for example, this indent can be in addition to the - * indent already required for list item children. Leading whitespace inside - * indented code blocks is trimmed up to the level of the opening fence and does - * not appear in the linted code. Further, lines can have less leading - * whitespace than the opening fence, so not all lines are guaranteed to have - * the same column offset as the opening fence. - * - * The source code of a non-configuration-comment line in the linted JS is a - * suffix of the corresponding line in the Markdown code block. There are no - * differences within the line, so the mapping need only provide the offset - * delta at the beginning of each line. - * @param {string} text The text of the file. - * @param {ASTNode} node A Markdown code block AST node. - * @param {string[]} comments List of configuration comment strings that will be - * inserted at the beginning of the code block. - * @returns {RangeMap[]} A list of offset-based adjustments, where lookups are - * done based on the `js` key, which represents the range in the linted JS, - * and the `md` key is the offset delta that, when added to the JS range, - * returns the corresponding location in the original Markdown source. - */ -function getBlockRangeMap(text, node, comments) { - - /* - * The parser sets the fenced code block's start offset to wherever content - * should normally begin (typically the first column of the line, but more - * inside a list item, for example). The code block's opening fance may be - * further indented by up to three characters. If the code block has - * additional indenting, the opening fence's first backtick may be up to - * three whitespace characters after the start offset. - */ - const startOffset = getBeginningOfLineOffset(node); - - /* - * Extract the Markdown source to determine the leading whitespace for each - * line. - */ - const code = text.slice(startOffset, node.position.end.offset); - const lines = code.split("\n"); - - /* - * The parser trims leading whitespace from each line of code within the - * fenced code block up to the opening fence's first backtick. The first - * backtick's column is the AST node's starting column plus any additional - * indentation. - */ - const baseIndent = getIndentText(text, node).length; - - /* - * Track the length of any inserted configuration comments at the beginning - * of the linted JS and start the JS offset lookup keys at this index. - */ - const commentLength = comments.reduce((len, comment) => len + comment.length + 1, 0); - - /* - * In case there are configuration comments, initialize the map so that the - * first lookup index is always 0. If there are no configuration comments, - * the lookup index will also be 0, and the lookup should always go to the - * last range that matches, skipping this initialization entry. - */ - const rangeMap = [{ - js: 0, - md: 0 - }]; - - // Start the JS offset after any configuration comments. - let jsOffset = commentLength; - - /* - * Start the Markdown offset at the beginning of the block's first line of - * actual code. The first line of the block is always the opening fence, so - * the code begins on the second line. - */ - let mdOffset = startOffset + lines[0].length + 1; - - /* - * For each line, determine how much leading whitespace was trimmed due to - * indentation. Increase the JS lookup offset by the length of the line - * post-trimming and the Markdown offset by the total line length. - */ - for (let i = 0; i + 1 < lines.length; i++) { - const line = lines[i + 1]; - const leadingWhitespaceLength = leadingWhitespaceRegex.exec(line)[0].length; - - // The parser trims leading whitespace up to the level of the opening - // fence, so keep any additional indentation beyond that. - const trimLength = Math.min(baseIndent, leadingWhitespaceLength); - - rangeMap.push({ - js: jsOffset, - - // Advance `trimLength` character from the beginning of the Markdown - // line to the beginning of the equivalent JS line, then compute the - // delta. - md: mdOffset + trimLength - jsOffset - }); - - // Accumulate the current line in the offsets, and don't forget the - // newline. - mdOffset += line.length + 1; - jsOffset += line.length - trimLength + 1; - } - - return rangeMap; -} - -/** - * Extracts lintable code blocks from Markdown text. - * @param {string} text The text of the file. - * @param {string} filename The filename of the file - * @returns {Array<{ filename: string, text: string }>} Source code blocks to lint. - */ -function preprocess(text, filename) { - const ast = markdown.parse(text); - const blocks = []; - - blocksCache.set(filename, blocks); - - /** - * During the depth-first traversal, keep track of any sequences of HTML - * comment nodes containing `eslint-*` or `global` comments. If a code - * block immediately follows such a sequence, insert the comments at the - * top of the code block. Any non-ESLint comment or other node type breaks - * and empties the sequence. - * @type {string[]} - */ - let htmlComments = []; - - traverse(ast, { - "*"() { - htmlComments = []; - }, - code(node) { - if (node.lang) { - const comments = []; - - for (const comment of htmlComments) { - if (comment.trim() === "eslint-skip") { - htmlComments = []; - return; - } - - comments.push(`/*${comment}*/`); - } - - htmlComments = []; - - blocks.push({ - ...node, - baseIndentText: getIndentText(text, node), - comments, - rangeMap: getBlockRangeMap(text, node, comments) - }); - } - }, - html(node) { - const comment = getComment(node.value); - - if (comment) { - htmlComments.push(comment); - } else { - htmlComments = []; - } - } - }); - - return blocks.map((block, index) => ({ - filename: `${index}.${block.lang.trim().split(" ")[0]}`, - text: [ - ...block.comments, - block.value, - "" - ].join("\n") - })); -} - -/** - * Creates a map function that adjusts messages in a code block. - * @param {Block} block A code block. - * @returns {(message: Message) => Message} A function that adjusts messages in a code block. - */ -function adjustBlock(block) { - const leadingCommentLines = block.comments.reduce((count, comment) => count + comment.split("\n").length, 0); - - const blockStart = block.position.start.line; - - /** - * Adjusts ESLint messages to point to the correct location in the Markdown. - * @param {Message} message A message from ESLint. - * @returns {Message} The same message, but adjusted to the correct location. - */ - return function adjustMessage(message) { - - const lineInCode = message.line - leadingCommentLines; - - if (lineInCode < 1) { - return null; - } - - const out = { - line: lineInCode + blockStart, - column: message.column + block.position.indent[lineInCode - 1] - 1 - }; - - if (Number.isInteger(message.endLine)) { - out.endLine = message.endLine - leadingCommentLines + blockStart; - } - - const adjustedFix = {}; - - if (message.fix) { - adjustedFix.fix = { - range: message.fix.range.map(range => { - - // Advance through the block's range map to find the last - // matching range by finding the first range too far and - // then going back one. - let i = 1; - - while (i < block.rangeMap.length && block.rangeMap[i].js <= range) { - i++; - } - - // Apply the mapping delta for this range. - return range + block.rangeMap[i - 1].md; - }), - text: message.fix.text.replace(/\n/gu, `\n${block.baseIndentText}`) - }; - } - - return { ...message, ...out, ...adjustedFix }; - }; -} - -/** - * Excludes unsatisfiable rules from the list of messages. - * @param {Message} message A message from the linter. - * @returns {boolean} True if the message should be included in output. - */ -function excludeUnsatisfiableRules(message) { - return message && UNSATISFIABLE_RULES.indexOf(message.ruleId) < 0; -} - -/** - * Transforms generated messages for output. - * @param {Array} messages An array containing one array of messages - * for each code block returned from `preprocess`. - * @param {string} filename The filename of the file - * @returns {Message[]} A flattened array of messages with mapped locations. - */ -function postprocess(messages, filename) { - const blocks = blocksCache.get(filename); - - blocksCache.delete(filename); - - return [].concat(...messages.map((group, i) => { - const adjust = adjustBlock(blocks[i]); - - return group.map(adjust).filter(excludeUnsatisfiableRules); - })); -} - -var processor = { - preprocess, - postprocess, - supportsAutofix: SUPPORTS_AUTOFIX -}; - -/** - * @fileoverview Enables the processor for Markdown file extensions. - * @author Brandon Mills - */ - - - -var lib = { - configs: { - recommended: { - plugins: ["markdown"], - overrides: [ - { - files: ["*.md"], - processor: "markdown/markdown" - }, - { - files: ["**/*.md/**"], - parserOptions: { - ecmaFeatures: { - - // Adding a "use strict" directive at the top of - // every code block is tedious and distracting, so - // opt into strict mode parsing without the - // directive. - impliedStrict: true - } - }, - rules: { - - // The Markdown parser automatically trims trailing - // newlines from code blocks. - "eol-last": "off", - - // In code snippets and examples, these rules are often - // counterproductive to clarity and brevity. - "no-undef": "off", - "no-unused-expressions": "off", - "no-unused-vars": "off", - "padded-blocks": "off", - - // Adding a "use strict" directive at the top of every - // code block is tedious and distracting. The config - // opts into strict mode parsing without the directive. - strict: "off", - - // The processor will not receive a Unicode Byte Order - // Mark from the Markdown parser. - "unicode-bom": "off" - } - } - ] - } - }, - processors: { - markdown: processor - } -}; - -/** - * @fileoverview Exports the processor. - * @author Brandon Mills - */ - -var eslintPluginMarkdown = lib; - -module.exports = eslintPluginMarkdown; + */;var ge,me="",be=function(r,e){if("string"!=typeof r)throw new TypeError("expected a string");if(1===e)return r;if(2===e)return r+r;var t=r.length*e;if(ge!==r||void 0===ge)ge=r,me="";else if(me.length>=t)return me.substr(0,t);for(;t>me.length&&e>1;)1&e&&(me+=r),e>>=1,r+=r;return me=(me+=r).substr(0,t)};var ve=function(r){return String(r).replace(/\n+$/,"")};var ye=function(r,e,t){var n,o,i,a=-1,c=e.length,l="",s="",u="",f="";for(;++a=4)){for(c="";b"!==e.charAt(k))return;if(t)return!0;k=0;for(;k"===e.charAt(k)?(k++,u=!0," "===e.charAt(k)&&k++):k=s,c=e.slice(k,a),!u&&!ke(c)){k=s;break}if(!u&&(i=e.slice(k),qe(g,d,p,[r,i,!0])))break;l=s===k?c:e.slice(s,a),A.push(k-s),y.push(l),w.push(c),k=a+1}k=-1,v=A.length,n=r(y.join("\n"));for(;++k6)return;if(!i||!a.pedantic&&"#"===e.charAt(l+1))return;c=e.length+1,o="";for(;++l=3&&(!n||"\n"===n)?(s+=a,!!t||r(s)({type:"thematicBreak"})):void 0;a+=n}};var Se=function(r){var e,t=0,n=0,o=r.charAt(t),i={};for(;o in Oe;)n+=e=Oe[o],e>1&&(n=Math.floor(n/e)*e),i[n]=t,o=r.charAt(++t);return{indent:n,stops:i}},Oe={" ":1,"\t":4};var Te=function(r,e){var t,n,o,i,a=r.split("\n"),c=a.length+1,l=1/0,s=[];a.unshift(be(" ",e)+"!");for(;c--;)if(n=Se(a[c]),s[c]=n.stops,0!==ke(a[c]).length){if(!n.indent){l=1/0;break}n.indent>0&&n.indent=4)return;if(a=e.charAt(N),n=O?ze:Ue,!0===je[a])c=a,i=!1;else{for(i=!0,o="";N=4&&(L=!0),y&&B>=y.indent&&(L=!0),a=e.charAt(N),f=null,!L){if(!0===je[a])f=a,N++,B++;else{for(o="";N=y.indent||B>4):L=!0,u=!1,N=s;if(h=e.slice(s,l),p=s===N?h:e.slice(N,l),("*"===f||"_"===f||"-"===f)&&D.thematicBreak.call(S,r,h,!0))break;if(d=g,g=!ke(p).length,L&&y)y.value=y.value.concat(v,h),b=b.concat(v,h),v=[];else if(u)0!==v.length&&(y.value.push(""),y.trail=v.concat()),y={value:[h],indent:B,trail:[]},m.push(y),b=b.concat(v,h),v=[];else if(g){if(d)break;v.push(h)}else{if(d)break;if(qe(C,D,S,[r,h,!0]))break;y.value=y.value.concat(v,h),b=b.concat(v,h),v=[]}N=l+1}q=r(b.join("\n")).reset({type:"list",ordered:i,start:I,loose:null,children:[]}),w=S.enterList(),A=S.enterBlock(),k=!1,N=-1,R=m.length;for(;++N=3){u--;break}f+=i}n="",o="";for(;++u`\\u0000-\\u0020]+|'[^']*'|\"[^\"]*\"))?)*\\s*\\/?>",Fe="<\\/[A-Za-z][A-Za-z0-9\\-]*\\s*>",Ze={openCloseTag:new RegExp("^(?:"+_e+"|"+Fe+")"),tag:new RegExp("^(?:"+_e+"|"+Fe+"|\x3c!----\x3e|\x3c!--(?:-?[^>-])(?:-?[^-])*--\x3e|<[?].*?[?]>|]*>|)")},$e=Ze.openCloseTag,Ye=function(r,e,t){var n,o,i,a,c,l,s,u=this.options.blocks,f=e.length,p=0,h=[[/^<(script|pre|style)(?=(\s|>|$))/i,/<\/(script|pre|style)>/i,!0],[/^/,!0],[/^<\?/,/\?>/,!0],[/^/,!0],[/^/,!0],[new RegExp("^|$))","i"),/^$/,!0],[new RegExp($e.source+"\\s*$"),/^$/,!1]];for(;p"!==r&&"["!==r&&"]"!==r}function nt(r){return"["!==r&&"]"!==r&&!fe(r)}tt.delimiter=">";var ot=function(r,e,t){var n,o,i,a,c,l,s,u,f,p,h,d,g,m,b,v,y,w,A,k,q,x,E,L;if(!this.options.gfm)return;n=0,w=0,l=e.length+1,s=[];for(;nx){if(w<2)return;break}s.push(e.slice(n,x)),w++,n=x+1}a=s.join("\n"),o=s.splice(1,1)[0]||[],n=0,l=o.length,w--,i=!1,h=[];for(;n1&&(f?(a+=u.slice(0,u.length-1),u=u.charAt(u.length-1)):(a+=u,u="")),v=r.now(),r(a)({type:"tableCell",children:this.tokenizeInline(d,v)},c)),r(u+f),u="",d=""}else if(u&&(d+=u,u=""),d+=f,"\\"===f&&n!==l-2&&(d+=A.charAt(n+1),n++),"`"===f){for(m=1;A.charAt(n+1)===f;)d+=f,n++,m++;b?m>=b&&(b=0):b=m}g=!1,n++}else d?u+=f:r(f),n++;y||r("\n"+o)}return q};var it=function(r,e,t){var n,o,i,a,c,l=this,s=l.options,u=s.commonmark,f=s.gfm,p=l.blockTokenizers,h=l.interruptParagraph,d=e.indexOf("\n"),g=e.length;for(;d=4){d=e.indexOf("\n",d+1);continue}}if(o=e.slice(d+1),qe(h,p,l,[r,o,!0]))break;if(p.list.call(l,r,o,!0)&&(l.inList||u||f&&!mr(ke.left(o).charAt(0))))break;if(n=d,-1!==(d=e.indexOf("\n",d+1))&&""===ke(e.slice(n,d))){d=n;break}}if(o=e.slice(0,d),""===ke(o))return r(o),null;if(t)return!0;return c=r.now(),o=ve(o),r(o)({type:"paragraph",children:l.tokenizeInline(o,c)})};var at=function(r,e){return r.indexOf("\\",e)};var ct=lt;function lt(r,e,t){var n,o;if("\\"===e.charAt(0)&&(n=e.charAt(1),-1!==this.escape.indexOf(n)))return!!t||(o="\n"===n?{type:"break"}:{type:"text",value:n},r("\\"+n)(o))}lt.locator=at;var st=function(r,e){return r.indexOf("<",e)};var ut=pt;pt.locator=st,pt.notInLink=!0;var ft="mailto:".length;function pt(r,e,t){var n,o,i,a,c,l,s,u,f,p,h,d;if("<"===e.charAt(0)){for(n=this,o="",i=e.length,a=0,c="",s=!1,u="",a++,o="<";a"===l||"@"===l||":"===l&&"/"===e.charAt(a+1)));)c+=l,a++;if(c){if(u+=c,c="",u+=l=e.charAt(a),a++,"@"===l)s=!0;else{if(":"!==l||"/"!==e.charAt(a+1))return;u+="/",a++}for(;a"!==l);)c+=l,a++;if(l=e.charAt(a),c&&">"===l)return!!t||(p=u+=c,o+=u+l,(f=r.now()).column++,f.offset++,s&&("mailto:"===u.slice(0,ft).toLowerCase()?(p=p.substr(ft),f.column+=ft,f.offset+=ft):u="mailto:"+u),h=n.inlineTokenizers,n.inlineTokenizers={text:h.text},d=n.enterLink(),p=n.tokenizeInline(p,f),n.inlineTokenizers=h,d(),r(o)({type:"link",title:null,url:qr(u,{nonTerminated:!1}),children:p}))}}}var ht=function(r,e){var t,n=dt.length,o=-1,i=-1;if(!this.options.gfm)return-1;for(;++o/i;function qt(r,e,t){var n,o,i=this,a=e.length;if(!("<"!==e.charAt(0)||a<3)&&(n=e.charAt(1),(vr(n)||"?"===n||"!"===n||"/"===n)&&(o=e.match(yt))))return!!t||(o=o[0],!i.inLink&&At.test(o)?i.inLink=!0:i.inLink&&kt.test(o)&&(i.inLink=!1),r(o)({type:"html",value:o}))}var xt=function(r,e){var t=r.indexOf("[",e),n=r.indexOf("![",e);if(-1===n)return t;return t=i&&(i=0):i=o}else if("\\"===E)x++,l+=e.charAt(x);else if(i&&!O||"["!==E){if((!i||O)&&"]"===E){if(!m){if(!L)for(;x"!==(E=e.charAt(x));){if(S&&"\n"===E)return;b+=E,x++}if(">"!==e.charAt(x))return;q+="<"+b+">",v=b,x++}else{for(E=null,l="";xe&&" "===r.charAt(t-1);)t--;return t};var Yt=Jt;Jt.locator=$t;function Jt(r,e,t){for(var n,o=e.length,i=-1,a="";++i\s]*/u;function sn(r){return r.position.start.offset-r.position.start.column+1}function un(r,e){return ln.exec(r.slice(sn(e)))[0]}function fn(r,e,t){const n=sn(e),o=r.slice(n,e.position.end.offset).split("\n"),i=un(r,e).length,a=[{js:0,md:0}];let c=t.reduce(((r,e)=>r+e.length+1),0),l=n+o[0].length+1;for(let r=0;r+1({filename:`${e}.${r.lang.trim().split(" ")[0]}`,text:[...r.comments,r.value,""].join("\n")})))},postprocess:function(r,e){const t=an.get(e);return an.delete(e),[].concat(...r.map(((r,e)=>{const n=function(r){const e=r.comments.reduce(((r,e)=>r+e.split("\n").length),0),t=r.position.start.line;return function(n){const o=n.line-e;if(o<1)return null;const i={line:o+t,column:n.column+r.position.indent[o-1]-1};Number.isInteger(n.endLine)&&(i.endLine=n.endLine-e+t);const a={};return n.fix&&(a.fix={range:n.fix.range.map((e=>{let t=1;for(;t -### Draw Vertical Line - -`{function} config.drawVerticalLine` property is a function that is called for every non-content column in the table. The result of the function `{boolean}` determines whether a border is drawn. - -```js -let data, - output, - options; - -data = [ - ['0A', '0B', '0C'], - ['1A', '1B', '1C'], - ['2A', '2B', '2C'], - ['3A', '3B', '3C'], - ['4A', '4B', '4C'] -]; - -options = { - /** - * @typedef {function} drawVerticalLine - * @param {number} index - * @param {number} size - * @return {boolean} - */ - drawVerticalLine: (index, size) => { - return index === 0 || index === size; - } -}; - -output = table(data, options); - -console.log(output); - -``` - -``` -╔════════════╗ -║ 0A 0B 0C ║ -╟────────────╢ -║ 1A 1B 1C ║ -╟────────────╢ -║ 2A 2B 2C ║ -╟────────────╢ -║ 3A 3B 3C ║ -╟────────────╢ -║ 4A 4B 4C ║ -╚════════════╝ - -``` - ### Draw Horizontal Line diff --git a/tools/node_modules/eslint/node_modules/table/dist/createStream.js b/tools/node_modules/eslint/node_modules/table/dist/createStream.js index f505cf8869e12e..731f12035d0511 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/createStream.js +++ b/tools/node_modules/eslint/node_modules/table/dist/createStream.js @@ -27,13 +27,13 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de /** * @param {Array} data - * @param {streamConfig} config + * @param {object} config * @returns {Array} */ const prepareData = (data, config) => { let rows; rows = (0, _stringifyTableData.default)(data); - rows = (0, _truncateTableData.default)(rows, config); + rows = (0, _truncateTableData.default)(data, config); const rowHeightIndex = (0, _calculateRowHeightIndex.default)(rows, config); rows = (0, _mapDataUsingRowHeightIndex.default)(rows, rowHeightIndex, config); rows = (0, _alignTableData.default)(rows, config); @@ -43,7 +43,7 @@ const prepareData = (data, config) => { /** * @param {string[]} row * @param {number[]} columnWidthIndex - * @param {streamConfig} config + * @param {object} config * @returns {undefined} */ @@ -51,20 +51,20 @@ const prepareData = (data, config) => { const create = (row, columnWidthIndex, config) => { const rows = prepareData([row], config); const body = rows.map(literalRow => { - return (0, _drawRow.default)(literalRow, config); + return (0, _drawRow.default)(literalRow, config.border); }).join(''); let output; output = ''; - output += (0, _drawBorder.drawBorderTop)(columnWidthIndex, config); + output += (0, _drawBorder.drawBorderTop)(columnWidthIndex, config.border); output += body; - output += (0, _drawBorder.drawBorderBottom)(columnWidthIndex, config); + output += (0, _drawBorder.drawBorderBottom)(columnWidthIndex, config.border); output = output.trimEnd(); process.stdout.write(output); }; /** * @param {string[]} row * @param {number[]} columnWidthIndex - * @param {streamConfig} config + * @param {object} config * @returns {undefined} */ @@ -72,16 +72,16 @@ const create = (row, columnWidthIndex, config) => { const append = (row, columnWidthIndex, config) => { const rows = prepareData([row], config); const body = rows.map(literalRow => { - return (0, _drawRow.default)(literalRow, config); + return (0, _drawRow.default)(literalRow, config.border); }).join(''); let output = ''; - const bottom = (0, _drawBorder.drawBorderBottom)(columnWidthIndex, config); + const bottom = (0, _drawBorder.drawBorderBottom)(columnWidthIndex, config.border); if (bottom !== '\n') { output = '\r\u001B[K'; } - output += (0, _drawBorder.drawBorderJoin)(columnWidthIndex, config); + output += (0, _drawBorder.drawBorderJoin)(columnWidthIndex, config.border); output += body; output += bottom; output = output.trimEnd(); diff --git a/tools/node_modules/eslint/node_modules/table/dist/createStream.js.flow b/tools/node_modules/eslint/node_modules/table/dist/createStream.js.flow index 2c2f164f62adb6..747ba6a7595bd4 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/createStream.js.flow +++ b/tools/node_modules/eslint/node_modules/table/dist/createStream.js.flow @@ -14,7 +14,7 @@ import truncateTableData from './truncateTableData'; /** * @param {Array} data - * @param {streamConfig} config + * @param {object} config * @returns {Array} */ const prepareData = (data, config) => { @@ -22,7 +22,7 @@ const prepareData = (data, config) => { rows = stringifyTableData(data); - rows = truncateTableData(rows, config); + rows = truncateTableData(data, config); const rowHeightIndex = calculateRowHeightIndex(rows, config); @@ -36,23 +36,23 @@ const prepareData = (data, config) => { /** * @param {string[]} row * @param {number[]} columnWidthIndex - * @param {streamConfig} config + * @param {object} config * @returns {undefined} */ const create = (row, columnWidthIndex, config) => { const rows = prepareData([row], config); const body = rows.map((literalRow) => { - return drawRow(literalRow, config); + return drawRow(literalRow, config.border); }).join(''); let output; output = ''; - output += drawBorderTop(columnWidthIndex, config); + output += drawBorderTop(columnWidthIndex, config.border); output += body; - output += drawBorderBottom(columnWidthIndex, config); + output += drawBorderBottom(columnWidthIndex, config.border); output = output.trimEnd(); @@ -62,24 +62,24 @@ const create = (row, columnWidthIndex, config) => { /** * @param {string[]} row * @param {number[]} columnWidthIndex - * @param {streamConfig} config + * @param {object} config * @returns {undefined} */ const append = (row, columnWidthIndex, config) => { const rows = prepareData([row], config); const body = rows.map((literalRow) => { - return drawRow(literalRow, config); + return drawRow(literalRow, config.border); }).join(''); let output = ''; - const bottom = drawBorderBottom(columnWidthIndex, config); + const bottom = drawBorderBottom(columnWidthIndex, config.border); if (bottom !== '\n') { output = '\r\u001B[K'; } - output += drawBorderJoin(columnWidthIndex, config); + output += drawBorderJoin(columnWidthIndex, config.border); output += body; output += bottom; diff --git a/tools/node_modules/eslint/node_modules/table/dist/drawBorder.js b/tools/node_modules/eslint/node_modules/table/dist/drawBorder.js index d6da1fdc4991b0..965e8539d42749 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/drawBorder.js +++ b/tools/node_modules/eslint/node_modules/table/dist/drawBorder.js @@ -5,12 +5,8 @@ Object.defineProperty(exports, "__esModule", { }); exports.drawBorderTop = exports.drawBorderJoin = exports.drawBorderBottom = exports.drawBorder = void 0; -var _drawHorizontalContent = _interopRequireDefault(require("./drawHorizontalContent")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - /** - * @typedef drawBorder~border + * @typedef drawBorder~parts * @property {string} left * @property {string} right * @property {string} body @@ -19,96 +15,94 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de /** * @param {number[]} columnSizeIndex - * @param {object} config - * @param {drawBorder~border} config.border - * @param {Function} config.drawVerticalLine + * @param {drawBorder~parts} parts * @returns {string} */ -const drawBorder = (columnSizeIndex, { - border, - drawVerticalLine -}) => { +const drawBorder = (columnSizeIndex, parts) => { const columns = columnSizeIndex.map(size => { - return border.body.repeat(size); - }); - return (0, _drawHorizontalContent.default)(columns, { - drawVerticalLine, - separator: border - }); + return parts.body.repeat(size); + }).join(parts.join); + return parts.left + columns + parts.right + '\n'; }; +/** + * @typedef drawBorderTop~parts + * @property {string} topLeft + * @property {string} topRight + * @property {string} topBody + * @property {string} topJoin + */ + /** * @param {number[]} columnSizeIndex - * @param {table~config} config + * @param {drawBorderTop~parts} parts * @returns {string} */ exports.drawBorder = drawBorder; -const drawBorderTop = (columnSizeIndex, { - border, - drawVerticalLine -}) => { - const result = drawBorder(columnSizeIndex, { - border: { - body: border.topBody, - join: border.topJoin, - left: border.topLeft, - right: border.topRight - }, - drawVerticalLine +const drawBorderTop = (columnSizeIndex, parts) => { + const border = drawBorder(columnSizeIndex, { + body: parts.topBody, + join: parts.topJoin, + left: parts.topLeft, + right: parts.topRight }); - if (result === '\n') { + if (border === '\n') { return ''; } - return result; + return border; }; +/** + * @typedef drawBorderJoin~parts + * @property {string} joinLeft + * @property {string} joinRight + * @property {string} joinBody + * @property {string} joinJoin + */ + /** * @param {number[]} columnSizeIndex - * @param {table~config} config + * @param {drawBorderJoin~parts} parts * @returns {string} */ exports.drawBorderTop = drawBorderTop; -const drawBorderJoin = (columnSizeIndex, { - border, - drawVerticalLine -}) => { +const drawBorderJoin = (columnSizeIndex, parts) => { return drawBorder(columnSizeIndex, { - border: { - body: border.joinBody, - join: border.joinJoin, - left: border.joinLeft, - right: border.joinRight - }, - drawVerticalLine + body: parts.joinBody, + join: parts.joinJoin, + left: parts.joinLeft, + right: parts.joinRight }); }; +/** + * @typedef drawBorderBottom~parts + * @property {string} topLeft + * @property {string} topRight + * @property {string} topBody + * @property {string} topJoin + */ + /** * @param {number[]} columnSizeIndex - * @param {table~config} config + * @param {drawBorderBottom~parts} parts * @returns {string} */ exports.drawBorderJoin = drawBorderJoin; -const drawBorderBottom = (columnSizeIndex, { - border, - drawVerticalLine -}) => { +const drawBorderBottom = (columnSizeIndex, parts) => { return drawBorder(columnSizeIndex, { - border: { - body: border.bottomBody, - join: border.bottomJoin, - left: border.bottomLeft, - right: border.bottomRight - }, - drawVerticalLine + body: parts.bottomBody, + join: parts.bottomJoin, + left: parts.bottomLeft, + right: parts.bottomRight }); }; diff --git a/tools/node_modules/eslint/node_modules/table/dist/drawBorder.js.flow b/tools/node_modules/eslint/node_modules/table/dist/drawBorder.js.flow index fc94622efb6354..85de2475e8b294 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/drawBorder.js.flow +++ b/tools/node_modules/eslint/node_modules/table/dist/drawBorder.js.flow @@ -1,7 +1,5 @@ -import drawHorizontalContent from './drawHorizontalContent'; - /** - * @typedef drawBorder~border + * @typedef drawBorder~parts * @property {string} left * @property {string} right * @property {string} body @@ -10,74 +8,88 @@ import drawHorizontalContent from './drawHorizontalContent'; /** * @param {number[]} columnSizeIndex - * @param {object} config - * @param {drawBorder~border} config.border - * @param {Function} config.drawVerticalLine + * @param {drawBorder~parts} parts * @returns {string} */ -const drawBorder = (columnSizeIndex, {border, drawVerticalLine}) => { - const columns = columnSizeIndex.map((size) => { - return border.body.repeat(size); - }); +const drawBorder = (columnSizeIndex, parts) => { + const columns = columnSizeIndex + .map((size) => { + return parts.body.repeat(size); + }) + .join(parts.join); - return drawHorizontalContent(columns, { - drawVerticalLine, - separator: border, - }); + return parts.left + columns + parts.right + '\n'; }; +/** + * @typedef drawBorderTop~parts + * @property {string} topLeft + * @property {string} topRight + * @property {string} topBody + * @property {string} topJoin + */ + /** * @param {number[]} columnSizeIndex - * @param {table~config} config + * @param {drawBorderTop~parts} parts * @returns {string} */ -const drawBorderTop = (columnSizeIndex, {border, drawVerticalLine}) => { - const result = drawBorder(columnSizeIndex, {border: { - body: border.topBody, - join: border.topJoin, - left: border.topLeft, - right: border.topRight, - }, - drawVerticalLine}); +const drawBorderTop = (columnSizeIndex, parts) => { + const border = drawBorder(columnSizeIndex, { + body: parts.topBody, + join: parts.topJoin, + left: parts.topLeft, + right: parts.topRight, + }); - if (result === '\n') { + if (border === '\n') { return ''; } - return result; + return border; }; +/** + * @typedef drawBorderJoin~parts + * @property {string} joinLeft + * @property {string} joinRight + * @property {string} joinBody + * @property {string} joinJoin + */ + /** * @param {number[]} columnSizeIndex - * @param {table~config} config + * @param {drawBorderJoin~parts} parts * @returns {string} */ -const drawBorderJoin = (columnSizeIndex, {border, drawVerticalLine}) => { +const drawBorderJoin = (columnSizeIndex, parts) => { return drawBorder(columnSizeIndex, { - border: { - body: border.joinBody, - join: border.joinJoin, - left: border.joinLeft, - right: border.joinRight, - }, - drawVerticalLine, + body: parts.joinBody, + join: parts.joinJoin, + left: parts.joinLeft, + right: parts.joinRight, }); }; +/** + * @typedef drawBorderBottom~parts + * @property {string} topLeft + * @property {string} topRight + * @property {string} topBody + * @property {string} topJoin + */ + /** * @param {number[]} columnSizeIndex - * @param {table~config} config + * @param {drawBorderBottom~parts} parts * @returns {string} */ -const drawBorderBottom = (columnSizeIndex, {border, drawVerticalLine}) => { +const drawBorderBottom = (columnSizeIndex, parts) => { return drawBorder(columnSizeIndex, { - border: { - body: border.bottomBody, - join: border.bottomJoin, - left: border.bottomLeft, - right: border.bottomRight, - }, - drawVerticalLine, + body: parts.bottomBody, + join: parts.bottomJoin, + left: parts.bottomLeft, + right: parts.bottomRight, }); }; diff --git a/tools/node_modules/eslint/node_modules/table/dist/drawRow.js b/tools/node_modules/eslint/node_modules/table/dist/drawRow.js index 69a4a00d64aef5..432f5bce1f9cdd 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/drawRow.js +++ b/tools/node_modules/eslint/node_modules/table/dist/drawRow.js @@ -5,10 +5,6 @@ Object.defineProperty(exports, "__esModule", { }); exports.default = void 0; -var _drawHorizontalContent = _interopRequireDefault(require("./drawHorizontalContent")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - /** * @typedef {object} drawRow~border * @property {string} bodyLeft @@ -17,24 +13,12 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de */ /** - * @param {string[]} columns - * @param {object} config - * @param {border} config.border - * @param {Function} config.drawVerticalLine + * @param {number[]} columns + * @param {drawRow~border} border * @returns {string} */ -const drawRow = (columns, { - border, - drawVerticalLine -}) => { - return (0, _drawHorizontalContent.default)(columns, { - drawVerticalLine, - separator: { - join: border.bodyJoin, - left: border.bodyLeft, - right: border.bodyRight - } - }); +const drawRow = (columns, border) => { + return border.bodyLeft + columns.join(border.bodyJoin) + border.bodyRight + '\n'; }; var _default = drawRow; diff --git a/tools/node_modules/eslint/node_modules/table/dist/drawRow.js.flow b/tools/node_modules/eslint/node_modules/table/dist/drawRow.js.flow index d185e499a8008f..978eab2de19941 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/drawRow.js.flow +++ b/tools/node_modules/eslint/node_modules/table/dist/drawRow.js.flow @@ -1,5 +1,3 @@ -import drawHorizontalContent from './drawHorizontalContent'; - /** * @typedef {object} drawRow~border * @property {string} bodyLeft @@ -8,22 +6,10 @@ import drawHorizontalContent from './drawHorizontalContent'; */ /** - * @param {string[]} columns - * @param {object} config - * @param {border} config.border - * @param {Function} config.drawVerticalLine + * @param {number[]} columns + * @param {drawRow~border} border * @returns {string} */ -export default (columns, { - border, - drawVerticalLine, -}) => { - return drawHorizontalContent(columns, { - drawVerticalLine, - separator: { - join: border.bodyJoin, - left: border.bodyLeft, - right: border.bodyRight, - }, - }); +export default (columns, border) => { + return border.bodyLeft + columns.join(border.bodyJoin) + border.bodyRight + '\n'; }; diff --git a/tools/node_modules/eslint/node_modules/table/dist/drawTable.js b/tools/node_modules/eslint/node_modules/table/dist/drawTable.js index 4ae5717e26a721..4c49d0fff50de8 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/drawTable.js +++ b/tools/node_modules/eslint/node_modules/table/dist/drawTable.js @@ -12,17 +12,15 @@ var _drawRow = _interopRequireDefault(require("./drawRow")); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** - * @param {string[][]} rows + * @param {Array} rows + * @param {object} border * @param {Array} columnSizeIndex * @param {Array} rowSpanIndex - * @param {table~config} config + * @param {Function} drawHorizontalLine + * @param {boolean} singleLine * @returns {string} */ -const drawTable = (rows, columnSizeIndex, rowSpanIndex, config) => { - const { - drawHorizontalLine, - singleLine - } = config; +const drawTable = (rows, border, columnSizeIndex, rowSpanIndex, drawHorizontalLine, singleLine) => { let output; let realRowIndex; let rowHeight; @@ -31,11 +29,11 @@ const drawTable = (rows, columnSizeIndex, rowSpanIndex, config) => { output = ''; if (drawHorizontalLine(realRowIndex, rowCount)) { - output += (0, _drawBorder.drawBorderTop)(columnSizeIndex, config); + output += (0, _drawBorder.drawBorderTop)(columnSizeIndex, border); } rows.forEach((row, index0) => { - output += (0, _drawRow.default)(row, config); + output += (0, _drawRow.default)(row, border); if (!rowHeight) { rowHeight = rowSpanIndex[realRowIndex]; @@ -45,12 +43,12 @@ const drawTable = (rows, columnSizeIndex, rowSpanIndex, config) => { rowHeight--; if (!singleLine && rowHeight === 0 && index0 !== rowCount - 1 && drawHorizontalLine(realRowIndex, rowCount)) { - output += (0, _drawBorder.drawBorderJoin)(columnSizeIndex, config); + output += (0, _drawBorder.drawBorderJoin)(columnSizeIndex, border); } }); if (drawHorizontalLine(realRowIndex, rowCount)) { - output += (0, _drawBorder.drawBorderBottom)(columnSizeIndex, config); + output += (0, _drawBorder.drawBorderBottom)(columnSizeIndex, border); } return output; diff --git a/tools/node_modules/eslint/node_modules/table/dist/drawTable.js.flow b/tools/node_modules/eslint/node_modules/table/dist/drawTable.js.flow index 402649721e6977..84707caa83d04b 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/drawTable.js.flow +++ b/tools/node_modules/eslint/node_modules/table/dist/drawTable.js.flow @@ -1,26 +1,20 @@ import { - drawBorderTop, drawBorderJoin, drawBorderBottom, + drawBorderTop, + drawBorderJoin, + drawBorderBottom, } from './drawBorder'; import drawRow from './drawRow'; /** - * @param {string[][]} rows + * @param {Array} rows + * @param {object} border * @param {Array} columnSizeIndex * @param {Array} rowSpanIndex - * @param {table~config} config + * @param {Function} drawHorizontalLine + * @param {boolean} singleLine * @returns {string} */ -export default ( - rows, - columnSizeIndex, - rowSpanIndex, - config, -) => { - const { - drawHorizontalLine, - singleLine, - } = config; - +export default (rows, border, columnSizeIndex, rowSpanIndex, drawHorizontalLine, singleLine) => { let output; let realRowIndex; let rowHeight; @@ -32,11 +26,11 @@ export default ( output = ''; if (drawHorizontalLine(realRowIndex, rowCount)) { - output += drawBorderTop(columnSizeIndex, config); + output += drawBorderTop(columnSizeIndex, border); } rows.forEach((row, index0) => { - output += drawRow(row, config); + output += drawRow(row, border); if (!rowHeight) { rowHeight = rowSpanIndex[realRowIndex]; @@ -46,18 +40,13 @@ export default ( rowHeight--; - if ( - !singleLine && - rowHeight === 0 && - index0 !== rowCount - 1 && - drawHorizontalLine(realRowIndex, rowCount) - ) { - output += drawBorderJoin(columnSizeIndex, config); + if (!singleLine && rowHeight === 0 && index0 !== rowCount - 1 && drawHorizontalLine(realRowIndex, rowCount)) { + output += drawBorderJoin(columnSizeIndex, border); } }); if (drawHorizontalLine(realRowIndex, rowCount)) { - output += drawBorderBottom(columnSizeIndex, config); + output += drawBorderBottom(columnSizeIndex, border); } return output; diff --git a/tools/node_modules/eslint/node_modules/table/dist/makeConfig.js b/tools/node_modules/eslint/node_modules/table/dist/makeConfig.js index 8f210cbc0fc1cc..a80d9a06acf1c9 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/makeConfig.js +++ b/tools/node_modules/eslint/node_modules/table/dist/makeConfig.js @@ -73,22 +73,13 @@ const makeConfig = (rows, userConfig = {}) => { if (!config.drawHorizontalLine) { /** - * @returns {boolean} - */ + * @returns {boolean} + */ config.drawHorizontalLine = () => { return true; }; } - if (!config.drawVerticalLine) { - /** - * @returns {boolean} - */ - config.drawVerticalLine = () => { - return true; - }; - } - if (config.singleLine === undefined) { config.singleLine = false; } diff --git a/tools/node_modules/eslint/node_modules/table/dist/makeConfig.js.flow b/tools/node_modules/eslint/node_modules/table/dist/makeConfig.js.flow index ae03633985341e..3fcbc79c555f0b 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/makeConfig.js.flow +++ b/tools/node_modules/eslint/node_modules/table/dist/makeConfig.js.flow @@ -61,22 +61,13 @@ export default (rows, userConfig = {}) => { if (!config.drawHorizontalLine) { /** - * @returns {boolean} - */ + * @returns {boolean} + */ config.drawHorizontalLine = () => { return true; }; } - if (!config.drawVerticalLine) { - /** - * @returns {boolean} - */ - config.drawVerticalLine = () => { - return true; - }; - } - if (config.singleLine === undefined) { config.singleLine = false; } diff --git a/tools/node_modules/eslint/node_modules/table/dist/makeStreamConfig.js b/tools/node_modules/eslint/node_modules/table/dist/makeStreamConfig.js index dac43d2549735d..6ca9733dd358e2 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/makeStreamConfig.js +++ b/tools/node_modules/eslint/node_modules/table/dist/makeStreamConfig.js @@ -90,16 +90,6 @@ const makeStreamConfig = (userConfig = {}) => { config.border = makeBorder(config.border); config.columns = makeColumns(config.columnCount, config.columns, config.columnDefault); - - if (!config.drawVerticalLine) { - /** - * @returns {boolean} - */ - config.drawVerticalLine = () => { - return true; - }; - } - return config; }; diff --git a/tools/node_modules/eslint/node_modules/table/dist/makeStreamConfig.js.flow b/tools/node_modules/eslint/node_modules/table/dist/makeStreamConfig.js.flow index 1731a3eda39998..8536bf5b37a0c1 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/makeStreamConfig.js.flow +++ b/tools/node_modules/eslint/node_modules/table/dist/makeStreamConfig.js.flow @@ -79,14 +79,5 @@ export default (userConfig = {}) => { config.border = makeBorder(config.border); config.columns = makeColumns(config.columnCount, config.columns, config.columnDefault); - if (!config.drawVerticalLine) { - /** - * @returns {boolean} - */ - config.drawVerticalLine = () => { - return true; - }; - } - return config; }; diff --git a/tools/node_modules/eslint/node_modules/table/dist/schemas/config.json b/tools/node_modules/eslint/node_modules/table/dist/schemas/config.json index d82828e91604cd..10fc74ab93cfc1 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/schemas/config.json +++ b/tools/node_modules/eslint/node_modules/table/dist/schemas/config.json @@ -12,9 +12,6 @@ "columnDefault": { "$ref": "shared.json#/definitions/column" }, - "drawVerticalLine": { - "typeof": "function" - }, "drawHorizontalLine": { "typeof": "function" }, diff --git a/tools/node_modules/eslint/node_modules/table/dist/schemas/streamConfig.json b/tools/node_modules/eslint/node_modules/table/dist/schemas/streamConfig.json index 86701518877485..24dfa56282541a 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/schemas/streamConfig.json +++ b/tools/node_modules/eslint/node_modules/table/dist/schemas/streamConfig.json @@ -14,9 +14,6 @@ }, "columnCount": { "type": "number" - }, - "drawVerticalLine": { - "typeof": "function" } }, "additionalProperties": false diff --git a/tools/node_modules/eslint/node_modules/table/dist/table.js b/tools/node_modules/eslint/node_modules/table/dist/table.js index 0ae78b595cdda7..8c053d81f773b4 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/table.js +++ b/tools/node_modules/eslint/node_modules/table/dist/table.js @@ -64,17 +64,6 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de * @property {string} joinJoin */ -/** - * Used to tell whether to draw a vertical line. - * This callback is called for each non-content line of the table. - * The default behavior is to always return true. - * - * @typedef {Function} drawVerticalLine - * @param {number} index - * @param {number} size - * @returns {boolean} - */ - /** * Used to tell whether to draw a horizontal line. * This callback is called for each non-content line of the table. @@ -91,7 +80,6 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de * @property {table~border} border * @property {table~columns[]} columns Column specific configuration. * @property {table~columns} columnDefault Default values for all columns. Column specific settings overwrite the default values. - * @property {table~drawVerticalLine} drawVerticalLine * @property {table~drawHorizontalLine} drawHorizontalLine * @property {table~singleLine} singleLine Horizontal lines inside the table are not drawn. */ @@ -114,7 +102,7 @@ const table = (data, userConfig = {}) => { rows = (0, _alignTableData.default)(rows, config); rows = (0, _padTableData.default)(rows, config); const cellWidthIndex = (0, _calculateCellWidthIndex.default)(rows[0]); - return (0, _drawTable.default)(rows, cellWidthIndex, rowHeightIndex, config); + return (0, _drawTable.default)(rows, config.border, cellWidthIndex, rowHeightIndex, config.drawHorizontalLine, config.singleLine); }; var _default = table; diff --git a/tools/node_modules/eslint/node_modules/table/dist/table.js.flow b/tools/node_modules/eslint/node_modules/table/dist/table.js.flow index 887025b6b75f33..6790e8cc550f2c 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/table.js.flow +++ b/tools/node_modules/eslint/node_modules/table/dist/table.js.flow @@ -46,17 +46,6 @@ import validateTableData from './validateTableData'; * @property {string} joinJoin */ -/** - * Used to tell whether to draw a vertical line. - * This callback is called for each non-content line of the table. - * The default behavior is to always return true. - * - * @typedef {Function} drawVerticalLine - * @param {number} index - * @param {number} size - * @returns {boolean} - */ - /** * Used to tell whether to draw a horizontal line. * This callback is called for each non-content line of the table. @@ -73,7 +62,6 @@ import validateTableData from './validateTableData'; * @property {table~border} border * @property {table~columns[]} columns Column specific configuration. * @property {table~columns} columnDefault Default values for all columns. Column specific settings overwrite the default values. - * @property {table~drawVerticalLine} drawVerticalLine * @property {table~drawHorizontalLine} drawHorizontalLine * @property {table~singleLine} singleLine Horizontal lines inside the table are not drawn. */ @@ -104,5 +92,5 @@ export default (data, userConfig = {}) => { const cellWidthIndex = calculateCellWidthIndex(rows[0]); - return drawTable(rows, cellWidthIndex, rowHeightIndex, config); + return drawTable(rows, config.border, cellWidthIndex, rowHeightIndex, config.drawHorizontalLine, config.singleLine); }; diff --git a/tools/node_modules/eslint/node_modules/table/dist/validators.js b/tools/node_modules/eslint/node_modules/table/dist/validators.js index 3b2af3d84f6839..51783aa08b8595 100644 --- a/tools/node_modules/eslint/node_modules/table/dist/validators.js +++ b/tools/node_modules/eslint/node_modules/table/dist/validators.js @@ -14,9 +14,6 @@ const schema13 = { "columnDefault": { "$ref": "shared.json#/definitions/column" }, - "drawVerticalLine": { - "typeof": "function" - }, "drawHorizontalLine": { "typeof": "function" }, @@ -804,7 +801,7 @@ function validate43(data, { let errors = 0; if (data && typeof data == "object" && !Array.isArray(data)) { for (const key0 in data) { - if (!((((((key0 === "border") || (key0 === "columns")) || (key0 === "columnDefault")) || (key0 === "drawVerticalLine")) || (key0 === "drawHorizontalLine")) || (key0 === "singleLine"))) { + if (!(((((key0 === "border") || (key0 === "columns")) || (key0 === "columnDefault")) || (key0 === "drawHorizontalLine")) || (key0 === "singleLine"))) { const err0 = { instancePath, schemaPath: "#/additionalProperties", @@ -855,26 +852,9 @@ function validate43(data, { errors = vErrors.length; } } - if (data.drawVerticalLine !== undefined) { - if (typeof data.drawVerticalLine != "function") { - const err1 = { - instancePath: instancePath + "/drawVerticalLine", - schemaPath: "#/properties/drawVerticalLine/typeof", - keyword: "typeof", - params: {}, - message: "should pass \"typeof\" keyword validation" - }; - if (vErrors === null) { - vErrors = [err1]; - } else { - vErrors.push(err1); - } - errors++; - } - } if (data.drawHorizontalLine !== undefined) { if (typeof data.drawHorizontalLine != "function") { - const err2 = { + const err1 = { instancePath: instancePath + "/drawHorizontalLine", schemaPath: "#/properties/drawHorizontalLine/typeof", keyword: "typeof", @@ -882,16 +862,16 @@ function validate43(data, { message: "should pass \"typeof\" keyword validation" }; if (vErrors === null) { - vErrors = [err2]; + vErrors = [err1]; } else { - vErrors.push(err2); + vErrors.push(err1); } errors++; } } if (data.singleLine !== undefined) { if (typeof data.singleLine != "boolean") { - const err3 = { + const err2 = { instancePath: instancePath + "/singleLine", schemaPath: "#/properties/singleLine/typeof", keyword: "typeof", @@ -899,15 +879,15 @@ function validate43(data, { message: "should pass \"typeof\" keyword validation" }; if (vErrors === null) { - vErrors = [err3]; + vErrors = [err2]; } else { - vErrors.push(err3); + vErrors.push(err2); } errors++; } } } else { - const err4 = { + const err3 = { instancePath, schemaPath: "#/type", keyword: "type", @@ -917,9 +897,9 @@ function validate43(data, { message: "must be object" }; if (vErrors === null) { - vErrors = [err4]; + vErrors = [err3]; } else { - vErrors.push(err4); + vErrors.push(err3); } errors++; } @@ -943,9 +923,6 @@ const schema20 = { }, "columnCount": { "type": "number" - }, - "drawVerticalLine": { - "typeof": "function" } }, "additionalProperties": false @@ -1423,7 +1400,7 @@ function validate69(data, { let errors = 0; if (data && typeof data == "object" && !Array.isArray(data)) { for (const key0 in data) { - if (!(((((key0 === "border") || (key0 === "columns")) || (key0 === "columnDefault")) || (key0 === "columnCount")) || (key0 === "drawVerticalLine"))) { + if (!((((key0 === "border") || (key0 === "columns")) || (key0 === "columnDefault")) || (key0 === "columnCount"))) { const err0 = { instancePath, schemaPath: "#/additionalProperties", @@ -1494,25 +1471,8 @@ function validate69(data, { errors++; } } - if (data.drawVerticalLine !== undefined) { - if (typeof data.drawVerticalLine != "function") { - const err2 = { - instancePath: instancePath + "/drawVerticalLine", - schemaPath: "#/properties/drawVerticalLine/typeof", - keyword: "typeof", - params: {}, - message: "should pass \"typeof\" keyword validation" - }; - if (vErrors === null) { - vErrors = [err2]; - } else { - vErrors.push(err2); - } - errors++; - } - } } else { - const err3 = { + const err2 = { instancePath, schemaPath: "#/type", keyword: "type", @@ -1522,9 +1482,9 @@ function validate69(data, { message: "must be object" }; if (vErrors === null) { - vErrors = [err3]; + vErrors = [err2]; } else { - vErrors.push(err3); + vErrors.push(err2); } errors++; } diff --git a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/compile/validate/keyword.js b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/compile/validate/keyword.js index 47f6176b1109cf..42b2e7a33759b6 100644 --- a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/compile/validate/keyword.js +++ b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/compile/validate/keyword.js @@ -99,7 +99,7 @@ function validSchemaType(schema, schemaType, allowUndefined = false) { : typeof schema == st || (allowUndefined && typeof schema == "undefined"))); } exports.validSchemaType = validSchemaType; -function validateKeywordUsage({ schema, opts, self, errSchemaPath }, def, keyword) { +function validateKeywordUsage({ schema, opts, self }, def, keyword) { /* istanbul ignore if */ if (Array.isArray(def.keyword) ? !def.keyword.includes(keyword) : def.keyword !== keyword) { throw new Error("ajv implementation error"); @@ -111,8 +111,7 @@ function validateKeywordUsage({ schema, opts, self, errSchemaPath }, def, keywor if (def.validateSchema) { const valid = def.validateSchema(schema[keyword]); if (!valid) { - const msg = `keyword "${keyword}" value is invalid at path "${errSchemaPath}": ` + - self.errorsText(def.validateSchema.errors); + const msg = "keyword value is invalid: " + self.errorsText(def.validateSchema.errors); if (opts.validateSchema === "log") self.logger.error(msg); else diff --git a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/core.js b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/core.js index a1aae13883da38..9eba9f49d9e1e8 100644 --- a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/core.js +++ b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/core.js @@ -61,7 +61,7 @@ const deprecatedOptions = { const MAX_EXPRESSION = 200; // eslint-disable-next-line complexity function requiredOptions(o) { - var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v; + var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u; const s = o.strict; const _optz = (_a = o.code) === null || _a === void 0 ? void 0 : _a.optimize; const optimize = _optz === true || _optz === undefined ? 1 : _optz || 0; @@ -80,7 +80,6 @@ function requiredOptions(o) { addUsedSchema: (_s = o.addUsedSchema) !== null && _s !== void 0 ? _s : true, validateSchema: (_t = o.validateSchema) !== null && _t !== void 0 ? _t : true, validateFormats: (_u = o.validateFormats) !== null && _u !== void 0 ? _u : true, - unicodeRegExp: (_v = o.unicodeRegExp) !== null && _v !== void 0 ? _v : true, }; } class Ajv { diff --git a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js index 09da8547ec735b..91672bc0846023 100644 --- a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js +++ b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js @@ -50,7 +50,7 @@ const def = { definedProp = codegen_1.nil; } if (patProps.length) { - definedProp = codegen_1.or(definedProp, ...patProps.map((p) => codegen_1._ `${code_1.usePattern(cxt, p)}.test(${key})`)); + definedProp = codegen_1.or(definedProp, ...patProps.map((p) => codegen_1._ `${code_1.usePattern(gen, p)}.test(${key})`)); } return codegen_1.not(definedProp); } diff --git a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js index ff68c82e1061ec..1f2f9fe71434cf 100644 --- a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js +++ b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js @@ -45,7 +45,7 @@ const def = { } function validateProperties(pat) { gen.forIn("key", data, (key) => { - gen.if(codegen_1._ `${code_1.usePattern(cxt, pat)}.test(${key})`, () => { + gen.if(codegen_1._ `${code_1.usePattern(gen, pat)}.test(${key})`, () => { cxt.subschema({ keyword: "patternProperties", schemaProp: pat, diff --git a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/code.js b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/code.js index c6f852daf9190f..848a72c88f4c9b 100644 --- a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/code.js +++ b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/code.js @@ -65,12 +65,11 @@ function callValidateCode({ schemaCode, data, it: { gen, topSchemaRef, schemaPat return context !== codegen_1.nil ? codegen_1._ `${func}.call(${context}, ${args})` : codegen_1._ `${func}(${args})`; } exports.callValidateCode = callValidateCode; -function usePattern({ gen, it: { opts } }, pattern) { - const u = opts.unicodeRegExp ? "u" : ""; +function usePattern(gen, pattern) { return gen.scopeValue("pattern", { key: pattern, - ref: new RegExp(pattern, u), - code: codegen_1._ `new RegExp(${pattern}, ${u})`, + ref: new RegExp(pattern, "u"), + code: codegen_1._ `new RegExp(${pattern}, "u")`, }); } exports.usePattern = usePattern; diff --git a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/validation/pattern.js b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/validation/pattern.js index b0862db342257f..7bb1587d98d5b5 100644 --- a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/validation/pattern.js +++ b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/dist/vocabularies/validation/pattern.js @@ -13,10 +13,8 @@ const def = { $data: true, error, code(cxt) { - const { data, $data, schema, schemaCode, it } = cxt; - // TODO regexp should be wrapped in try/catchs - const u = it.opts.unicodeRegExp ? "u" : ""; - const regExp = $data ? codegen_1._ `(new RegExp(${schemaCode}, ${u}))` : code_1.usePattern(cxt, schema); + const { gen, data, $data, schema, schemaCode } = cxt; + const regExp = $data ? codegen_1._ `(new RegExp(${schemaCode}, "u"))` : code_1.usePattern(gen, schema); // TODO regexp should be wrapped in try/catch cxt.fail$data(codegen_1._ `!${regExp}.test(${data})`); }, }; diff --git a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/package.json b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/package.json index 22f7a782c40b27..ec9f333b117190 100644 --- a/tools/node_modules/eslint/node_modules/table/node_modules/ajv/package.json +++ b/tools/node_modules/eslint/node_modules/table/node_modules/ajv/package.json @@ -1,6 +1,6 @@ { "name": "ajv", - "version": "8.1.0", + "version": "8.0.5", "description": "Another JSON Schema Validator", "main": "dist/ajv.js", "types": "dist/ajv.d.ts", diff --git a/tools/node_modules/eslint/node_modules/table/package.json b/tools/node_modules/eslint/node_modules/table/package.json index ee6dd0beb58871..c1e2f61bacdcd4 100644 --- a/tools/node_modules/eslint/node_modules/table/package.json +++ b/tools/node_modules/eslint/node_modules/table/package.json @@ -87,5 +87,5 @@ "lint": "npm run build && eslint ./src ./test && flow", "test": "mocha --require @babel/register" }, - "version": "6.1.0" + "version": "6.0.9" } diff --git a/tools/update-eslint.sh b/tools/update-eslint.sh index 8eb180be779f77..3a181c0d6328c5 100755 --- a/tools/update-eslint.sh +++ b/tools/update-eslint.sh @@ -6,7 +6,7 @@ # script source file path to determine directories to work in. cd "$( dirname "$0" )" || exit -rm -rf node_modules/eslint node_modules/eslint-plugin-markdown +rm -rf node_modules/eslint ( mkdir eslint-tmp cd eslint-tmp || exit @@ -18,14 +18,20 @@ rm -rf node_modules/eslint node_modules/eslint-plugin-markdown "$NODE" "$NPM" init --yes + mkdir eslint-plugin-markdown eslint-plugin-jsdoc "$NODE" "$NPM" install --production --no-save --no-package-lock \ eslint@latest \ eslint-plugin-markdown@latest \ eslint-plugin-jsdoc@latest \ - rollup @rollup/plugin-node-resolve @rollup/plugin-commonjs @rollup/plugin-json + rollup @rollup/plugin-node-resolve @rollup/plugin-commonjs @rollup/plugin-json \ + terser node -p '"export default"+JSON.stringify({external:Object.keys(require("eslint/package.json").dependencies),output:{format:"cjs",exports:"default"}})' > rollup.config.mjs - "$NODE" "$NPM" exec -- rollup -c rollup.config.mjs -p '@rollup/plugin-node-resolve' -p '@rollup/plugin-commonjs' -p '@rollup/plugin-json' -f cjs --file=./eslint-plugin-markdown/index.js -- ./node_modules/eslint-plugin-markdown/index.js - "$NODE" "$NPM" exec -- rollup -c rollup.config.mjs -p '@rollup/plugin-node-resolve' -p '@rollup/plugin-commonjs' -p '@rollup/plugin-json' -f cjs --file=./eslint-plugin-jsdoc/index.js -- ./node_modules/eslint-plugin-jsdoc/dist/index.js + + "$NODE" "$NPM" exec -- rollup -c rollup.config.mjs -p '@rollup/plugin-node-resolve' -p '@rollup/plugin-commonjs' -p '@rollup/plugin-json' -- ./node_modules/eslint-plugin-markdown/index.js | \ + "$NODE" "$NPM" exec -- terser --toplevel --compress --mangle --timings -o ./eslint-plugin-markdown/index.js + + "$NODE" "$NPM" exec -- rollup -c rollup.config.mjs -p '@rollup/plugin-node-resolve' -p '@rollup/plugin-commonjs' -p '@rollup/plugin-json' -- ./node_modules/eslint-plugin-jsdoc/dist/index.js | \ + "$NODE" "$NPM" exec -- terser --toplevel --compress --mangle --timings -o ./eslint-plugin-jsdoc/index.js rm -r node_modules "$NODE" "$NPM" install --global-style --no-bin-links --production --no-package-lock eslint@latest