From f8ce0d2b90b8da2f4f87074e41a5158ae4ecd011 Mon Sep 17 00:00:00 2001 From: srijan-paul Date: Tue, 18 Jan 2022 16:17:46 +0530 Subject: [PATCH 1/3] docs: add jsdoc types to espree Co-authored-by: Milos Djermanovic Co-authored-by: Bryan Mishkin <698306+bmish@users.noreply.github.com> --- espree.js | 15 +++++++++++---- lib/espree.js | 39 +++++++++++++++++++++++++++++++-------- lib/features.js | 10 ++++++++++ lib/options.js | 18 +++++++++++++++++- lib/token-translator.js | 29 ++++++++++++++++++++++++++--- package.json | 8 ++++++-- tsconfig.json | 11 +++++++++++ 7 files changed, 112 insertions(+), 18 deletions(-) create mode 100644 tsconfig.json diff --git a/espree.js b/espree.js index 71e3d47d..fa664b84 100644 --- a/espree.js +++ b/espree.js @@ -63,6 +63,13 @@ import espreeVersion from "./lib/version.js"; import * as visitorKeys from "eslint-visitor-keys"; import { getLatestEcmaVersion, getSupportedEcmaVersions } from "./lib/options.js"; +/** + * @typedef {import("acorn")} acorn + * @typedef {import("./lib/options").ParserOptions} ParserOptions + * @typedef {import("./lib/token-translator").EsprimaToken} EsprimaToken + * @typedef {import("./lib/token-translator").TokenRange} TokenRange + */ + // To initialize lazily. const parsers = { @@ -101,8 +108,8 @@ const parsers = { /** * Tokenizes the given code. * @param {string} code The code to tokenize. - * @param {Object} options Options defining how to tokenize. - * @returns {Token[]} An array of tokens. + * @param {ParserOptions} [options] Options defining how to tokenize. + * @returns {EsprimaToken[]} An array of tokens. * @throws {SyntaxError} If the input code is invalid. * @private */ @@ -124,8 +131,8 @@ export function tokenize(code, options) { /** * Parses the given code. * @param {string} code The code to tokenize. - * @param {Object} options Options defining how to tokenize. - * @returns {ASTNode} The "Program" AST node. + * @param {ParserOptions} options Options defining how to tokenize. + * @returns {acorn.Node} The "Program" AST node. * @throws {SyntaxError} If the input code is invalid. */ export function parse(code, options) { diff --git a/lib/espree.js b/lib/espree.js index 786d89fa..fa99adf9 100644 --- a/lib/espree.js +++ b/lib/espree.js @@ -3,9 +3,24 @@ import TokenTranslator from "./token-translator.js"; import { normalizeOptions } from "./options.js"; +/** + * @typedef {import("acorn")} acorn + * @typedef {import("./token-translator").Range} Range + */ + const STATE = Symbol("espree's internal state"); const ESPRIMA_FINISH_NODE = Symbol("espree's esprimaFinishNode"); +/** + * @typedef {Object} EsprimaComment + * @property {"Block"|"Line"} type Type of the comment, can either be "Block" (multiline) or "Line" (single line). + * @property {string} text Contents of the comment. + * @property {number|undefined} start Start column of a comment. + * @property {number|undefined} end End column of the comment. + * @property {Range|undefined} range The [start, end] range of a comment. + * @property {acorn.Position} startLoc Start location of the comment. + * @property {acorn.Position} endLoc End location of the comment. + */ /** * Converts an Acorn comment to a Esprima comment. @@ -15,7 +30,7 @@ const ESPRIMA_FINISH_NODE = Symbol("espree's esprimaFinishNode"); * @param {int} end The index at which the comment ends. * @param {Location} startLoc The location at which the comment starts. * @param {Location} endLoc The location at which the comment ends. - * @returns {Object} The comment object. + * @returns {EsprimaComment} The comment object. * @private */ function convertAcornCommentToEsprimaComment(block, text, start, end, startLoc, endLoc) { @@ -40,7 +55,12 @@ function convertAcornCommentToEsprimaComment(block, text, start, end, startLoc, return comment; } -export default () => Parser => { +/** + * Takes an acorn Parser class and returns a new Parser extending from it. + * @param {typeof acorn.Parser} Parser A base acorn parser class. + * @returns {typeof acorn.Parser} An espree parser extending the base acorn parser. + */ +function extendAcornParser(Parser) { const tokTypes = Object.assign({}, Parser.acorn.tokTypes); if (Parser.acornJsx) { @@ -232,7 +252,7 @@ export default () => Parser => { /** * Overwrites the default raise method to throw Esprima-style errors. - * @param {int} pos The position of the error. + * @param {number} pos The position of the error. * @param {string} message The error message. * @throws {SyntaxError} A syntax error. * @returns {void} @@ -249,7 +269,7 @@ export default () => Parser => { /** * Overwrites the default raise method to throw Esprima-style errors. - * @param {int} pos The position of the error. + * @param {number} pos The position of the error. * @param {string} message The error message. * @throws {SyntaxError} A syntax error. * @returns {void} @@ -260,7 +280,7 @@ export default () => Parser => { /** * Overwrites the default unexpected method to throw Esprima-style errors. - * @param {int} pos The position of the error. + * @param {number} pos The position of the error. * @throws {SyntaxError} A syntax error. * @returns {void} */ @@ -305,8 +325,8 @@ export default () => Parser => { /** * Performs last-minute Esprima-specific compatibility checks and fixes. - * @param {ASTNode} result The node to check. - * @returns {ASTNode} The finished node. + * @param {acorn.Node} result The node to check. + * @returns {acorn.Node} The finished node. */ [ESPRIMA_FINISH_NODE](result) { @@ -325,4 +345,7 @@ export default () => Parser => { return result; } }; -}; + +} + +export default () => extendAcornParser; diff --git a/lib/features.js b/lib/features.js index 31467d28..c95d4dc6 100644 --- a/lib/features.js +++ b/lib/features.js @@ -14,6 +14,16 @@ // Public //------------------------------------------------------------------------------ +/** + * @typedef {Object} EcmaFeatures + * @property {boolean} [jsx] + * @property {boolean} [globalReturn] + * @property {boolean} [impliedStrict] + */ + +/** + * @type {EcmaFeatures} + */ export default { // React JSX parsing diff --git a/lib/options.js b/lib/options.js index 87739699..111179d0 100644 --- a/lib/options.js +++ b/lib/options.js @@ -81,9 +81,25 @@ function normalizeSourceType(sourceType = "script") { throw new Error("Invalid sourceType."); } +/** + * @typedef {import("./features").EcmaFeatures} EcmaFeatures + */ + +/** + * @typedef {Object} ParserOptions + * @property {boolean} [range] Whether to include the range information for each node. + * @property {boolean} [loc] Whether to include the location information for every node. + * @property {boolean} [comment] Whether to include an array of all comments + * @property {boolean} [tokens] Whether to include an array of all tokens + * @property {number|"latest"} [ecmaVersion] The ECMAScript version to use (between 3 and 13, or 2015 and 2022, or "latest"). + * @property {boolean} [allowReserved] Only allowed when `ecmaVersion` is set to 3. + * @property {"script"|"module"|"commonjs"} [sourceType] The kind of the source string being parsed. + * @property {EcmaFeatures} [ecmaFeatures] The additional features to enable. + */ + /** * Normalize parserOptions - * @param {Object} options the parser options to normalize + * @param {ParserOptions} options the parser options to normalize * @throws {Error} throw an error if found invalid option. * @returns {Object} normalized options */ diff --git a/lib/token-translator.js b/lib/token-translator.js index 9aa5e22e..0f08ad37 100644 --- a/lib/token-translator.js +++ b/lib/token-translator.js @@ -14,6 +14,29 @@ // Private //------------------------------------------------------------------------------ +/** + * @typedef {import("acorn")} acorn + */ + +/** + * @typedef {Object} Location + * @property {acorn.Position} start The start position. + * @property {acorn.Position} end The end position. + */ + +/** + * @typedef {[number, number]} Range + */ + +/** + * @typedef {Object} EsprimaToken + * @property {string} type The type of this token. + * @property {string} value The string content of the token. + * @property {Location|undefined} loc Location in source text. + * @property {number|undefined} start start column. + * @property {number|undefined} end end column. + * @property {Range|undefined} range [start, end] range + */ // Esprima Token Types const Token = { @@ -34,7 +57,7 @@ const Token = { /** * Converts part of a template into an Esprima token. - * @param {AcornToken[]} tokens The Acorn tokens representing the template. + * @param {acorn.Token[]} tokens The Acorn tokens representing the template. * @param {string} code The source code. * @returns {EsprimaToken} The Esprima equivalent of the template token. * @private @@ -94,7 +117,7 @@ TokenTranslator.prototype = { * Translates a single Esprima token to a single Acorn token. This may be * inaccurate due to how templates are handled differently in Esprima and * Acorn, but should be accurate for all other tokens. - * @param {AcornToken} token The Acorn token to translate. + * @param {acorn.Token} token The Acorn token to translate. * @param {Object} extra Espree extra object. * @returns {EsprimaToken} The Esprima version of the token. */ @@ -174,7 +197,7 @@ TokenTranslator.prototype = { /** * Function to call during Acorn's onToken handler. - * @param {AcornToken} token The Acorn token. + * @param {acorn.Token} token The Acorn token. * @param {Object} extra The Espree extra object. * @returns {void} */ diff --git a/package.json b/package.json index 2b21d3f8..7be2943e 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,10 @@ "files": [ "lib", "dist/espree.cjs", + "dist/espree.d.ts", "espree.js" ], + "types": "dist/espree.d.ts", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -52,7 +54,9 @@ "mocha": "^8.3.1", "npm-run-all": "^4.1.5", "rollup": "^2.41.2", - "shelljs": "^0.3.0" + "shelljs": "^0.3.0", + "typescript": "^4.5.4", + "unicode-6.3.0": "^0.7.5" }, "keywords": [ "ast", @@ -69,7 +73,7 @@ "test": "npm-run-all -p unit lint", "lint": "eslint \"*.?(c)js\" lib/ tests/lib/", "fixlint": "npm run lint -- --fix", - "build": "rollup -c rollup.config.js", + "build": "rollup -c rollup.config.js && tsc --build", "update-version": "node tools/update-version.js", "pretest": "npm run build", "prepublishOnly": "npm run update-version && npm run build", diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..e73cbb6a --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,11 @@ +{ + "include": ["lib/**/*", "espree.js"], + "compilerOptions": { + "allowJs": true, + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "dist", + "declarationMap": true, + "strict": true + } +} From 41d48d8a7f72ac4c33fffa3a37dac7c426b8201f Mon Sep 17 00:00:00 2001 From: srijan-paul Date: Tue, 18 Jan 2022 16:17:46 +0530 Subject: [PATCH 2/3] docs: add jsdoc types to espree Co-authored-by: Milos Djermanovic Co-authored-by: Bryan Mishkin <698306+bmish@users.noreply.github.com> --- espree.js | 15 +++++++++++---- lib/espree.js | 39 +++++++++++++++++++++++++++++++-------- lib/features.js | 10 ++++++++++ lib/options.js | 18 +++++++++++++++++- lib/token-translator.js | 29 ++++++++++++++++++++++++++--- package.json | 8 ++++++-- tsconfig.json | 11 +++++++++++ 7 files changed, 112 insertions(+), 18 deletions(-) create mode 100644 tsconfig.json diff --git a/espree.js b/espree.js index 71e3d47d..fa664b84 100644 --- a/espree.js +++ b/espree.js @@ -63,6 +63,13 @@ import espreeVersion from "./lib/version.js"; import * as visitorKeys from "eslint-visitor-keys"; import { getLatestEcmaVersion, getSupportedEcmaVersions } from "./lib/options.js"; +/** + * @typedef {import("acorn")} acorn + * @typedef {import("./lib/options").ParserOptions} ParserOptions + * @typedef {import("./lib/token-translator").EsprimaToken} EsprimaToken + * @typedef {import("./lib/token-translator").TokenRange} TokenRange + */ + // To initialize lazily. const parsers = { @@ -101,8 +108,8 @@ const parsers = { /** * Tokenizes the given code. * @param {string} code The code to tokenize. - * @param {Object} options Options defining how to tokenize. - * @returns {Token[]} An array of tokens. + * @param {ParserOptions} [options] Options defining how to tokenize. + * @returns {EsprimaToken[]} An array of tokens. * @throws {SyntaxError} If the input code is invalid. * @private */ @@ -124,8 +131,8 @@ export function tokenize(code, options) { /** * Parses the given code. * @param {string} code The code to tokenize. - * @param {Object} options Options defining how to tokenize. - * @returns {ASTNode} The "Program" AST node. + * @param {ParserOptions} options Options defining how to tokenize. + * @returns {acorn.Node} The "Program" AST node. * @throws {SyntaxError} If the input code is invalid. */ export function parse(code, options) { diff --git a/lib/espree.js b/lib/espree.js index 786d89fa..53a4130b 100644 --- a/lib/espree.js +++ b/lib/espree.js @@ -3,9 +3,24 @@ import TokenTranslator from "./token-translator.js"; import { normalizeOptions } from "./options.js"; +/** + * @typedef {import("acorn")} acorn + * @typedef {import("./token-translator").TokenRange} TokenRange + */ + const STATE = Symbol("espree's internal state"); const ESPRIMA_FINISH_NODE = Symbol("espree's esprimaFinishNode"); +/** + * @typedef {Object} EsprimaComment + * @property {"Block"|"Line"} type Type of the comment, can either be "Block" (multiline) or "Line" (single line). + * @property {string} text Contents of the comment. + * @property {number|undefined} start Start column of a comment. + * @property {number|undefined} end End column of the comment. + * @property {TokenRange|undefined} range The [start, end] range of a comment. + * @property {acorn.Position} startLoc Start location of the comment. + * @property {acorn.Position} endLoc End location of the comment. + */ /** * Converts an Acorn comment to a Esprima comment. @@ -15,7 +30,7 @@ const ESPRIMA_FINISH_NODE = Symbol("espree's esprimaFinishNode"); * @param {int} end The index at which the comment ends. * @param {Location} startLoc The location at which the comment starts. * @param {Location} endLoc The location at which the comment ends. - * @returns {Object} The comment object. + * @returns {EsprimaComment} The comment object. * @private */ function convertAcornCommentToEsprimaComment(block, text, start, end, startLoc, endLoc) { @@ -40,7 +55,12 @@ function convertAcornCommentToEsprimaComment(block, text, start, end, startLoc, return comment; } -export default () => Parser => { +/** + * Takes an acorn Parser class and returns a new Parser extending from it. + * @param {typeof acorn.Parser} Parser A base acorn parser class. + * @returns {typeof acorn.Parser} An espree parser extending the base acorn parser. + */ +function extendAcornParser(Parser) { const tokTypes = Object.assign({}, Parser.acorn.tokTypes); if (Parser.acornJsx) { @@ -232,7 +252,7 @@ export default () => Parser => { /** * Overwrites the default raise method to throw Esprima-style errors. - * @param {int} pos The position of the error. + * @param {number} pos The position of the error. * @param {string} message The error message. * @throws {SyntaxError} A syntax error. * @returns {void} @@ -249,7 +269,7 @@ export default () => Parser => { /** * Overwrites the default raise method to throw Esprima-style errors. - * @param {int} pos The position of the error. + * @param {number} pos The position of the error. * @param {string} message The error message. * @throws {SyntaxError} A syntax error. * @returns {void} @@ -260,7 +280,7 @@ export default () => Parser => { /** * Overwrites the default unexpected method to throw Esprima-style errors. - * @param {int} pos The position of the error. + * @param {number} pos The position of the error. * @throws {SyntaxError} A syntax error. * @returns {void} */ @@ -305,8 +325,8 @@ export default () => Parser => { /** * Performs last-minute Esprima-specific compatibility checks and fixes. - * @param {ASTNode} result The node to check. - * @returns {ASTNode} The finished node. + * @param {acorn.Node} result The node to check. + * @returns {acorn.Node} The finished node. */ [ESPRIMA_FINISH_NODE](result) { @@ -325,4 +345,7 @@ export default () => Parser => { return result; } }; -}; + +} + +export default () => extendAcornParser; diff --git a/lib/features.js b/lib/features.js index 31467d28..c95d4dc6 100644 --- a/lib/features.js +++ b/lib/features.js @@ -14,6 +14,16 @@ // Public //------------------------------------------------------------------------------ +/** + * @typedef {Object} EcmaFeatures + * @property {boolean} [jsx] + * @property {boolean} [globalReturn] + * @property {boolean} [impliedStrict] + */ + +/** + * @type {EcmaFeatures} + */ export default { // React JSX parsing diff --git a/lib/options.js b/lib/options.js index 87739699..111179d0 100644 --- a/lib/options.js +++ b/lib/options.js @@ -81,9 +81,25 @@ function normalizeSourceType(sourceType = "script") { throw new Error("Invalid sourceType."); } +/** + * @typedef {import("./features").EcmaFeatures} EcmaFeatures + */ + +/** + * @typedef {Object} ParserOptions + * @property {boolean} [range] Whether to include the range information for each node. + * @property {boolean} [loc] Whether to include the location information for every node. + * @property {boolean} [comment] Whether to include an array of all comments + * @property {boolean} [tokens] Whether to include an array of all tokens + * @property {number|"latest"} [ecmaVersion] The ECMAScript version to use (between 3 and 13, or 2015 and 2022, or "latest"). + * @property {boolean} [allowReserved] Only allowed when `ecmaVersion` is set to 3. + * @property {"script"|"module"|"commonjs"} [sourceType] The kind of the source string being parsed. + * @property {EcmaFeatures} [ecmaFeatures] The additional features to enable. + */ + /** * Normalize parserOptions - * @param {Object} options the parser options to normalize + * @param {ParserOptions} options the parser options to normalize * @throws {Error} throw an error if found invalid option. * @returns {Object} normalized options */ diff --git a/lib/token-translator.js b/lib/token-translator.js index 9aa5e22e..97b42ae1 100644 --- a/lib/token-translator.js +++ b/lib/token-translator.js @@ -14,6 +14,29 @@ // Private //------------------------------------------------------------------------------ +/** + * @typedef {import("acorn")} acorn + */ + +/** + * @typedef {Object} Location + * @property {acorn.Position} start The start position. + * @property {acorn.Position} end The end position. + */ + +/** + * @typedef {[number, number]} TokenRange + */ + +/** + * @typedef {Object} EsprimaToken + * @property {string} type The type of this token. + * @property {string} value The string content of the token. + * @property {Location|undefined} loc Location in source text. + * @property {number|undefined} start start column. + * @property {number|undefined} end end column. + * @property {TokenRange|undefined} range [start, end] range + */ // Esprima Token Types const Token = { @@ -34,7 +57,7 @@ const Token = { /** * Converts part of a template into an Esprima token. - * @param {AcornToken[]} tokens The Acorn tokens representing the template. + * @param {acorn.Token[]} tokens The Acorn tokens representing the template. * @param {string} code The source code. * @returns {EsprimaToken} The Esprima equivalent of the template token. * @private @@ -94,7 +117,7 @@ TokenTranslator.prototype = { * Translates a single Esprima token to a single Acorn token. This may be * inaccurate due to how templates are handled differently in Esprima and * Acorn, but should be accurate for all other tokens. - * @param {AcornToken} token The Acorn token to translate. + * @param {acorn.Token} token The Acorn token to translate. * @param {Object} extra Espree extra object. * @returns {EsprimaToken} The Esprima version of the token. */ @@ -174,7 +197,7 @@ TokenTranslator.prototype = { /** * Function to call during Acorn's onToken handler. - * @param {AcornToken} token The Acorn token. + * @param {acorn.Token} token The Acorn token. * @param {Object} extra The Espree extra object. * @returns {void} */ diff --git a/package.json b/package.json index 2b21d3f8..7be2943e 100644 --- a/package.json +++ b/package.json @@ -20,8 +20,10 @@ "files": [ "lib", "dist/espree.cjs", + "dist/espree.d.ts", "espree.js" ], + "types": "dist/espree.d.ts", "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -52,7 +54,9 @@ "mocha": "^8.3.1", "npm-run-all": "^4.1.5", "rollup": "^2.41.2", - "shelljs": "^0.3.0" + "shelljs": "^0.3.0", + "typescript": "^4.5.4", + "unicode-6.3.0": "^0.7.5" }, "keywords": [ "ast", @@ -69,7 +73,7 @@ "test": "npm-run-all -p unit lint", "lint": "eslint \"*.?(c)js\" lib/ tests/lib/", "fixlint": "npm run lint -- --fix", - "build": "rollup -c rollup.config.js", + "build": "rollup -c rollup.config.js && tsc --build", "update-version": "node tools/update-version.js", "pretest": "npm run build", "prepublishOnly": "npm run update-version && npm run build", diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000..e73cbb6a --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,11 @@ +{ + "include": ["lib/**/*", "espree.js"], + "compilerOptions": { + "allowJs": true, + "declaration": true, + "emitDeclarationOnly": true, + "outDir": "dist", + "declarationMap": true, + "strict": true + } +} From 63f5b6516b2b67d8feb009a1ab23f205a41bd0b1 Mon Sep 17 00:00:00 2001 From: injuly Date: Fri, 6 May 2022 10:47:36 +0530 Subject: [PATCH 3/3] fix: add missing type definition files --- espree.js | 2 +- package.json | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/espree.js b/espree.js index 749fa73e..411a9c94 100644 --- a/espree.js +++ b/espree.js @@ -68,7 +68,7 @@ import { getLatestEcmaVersion, getSupportedEcmaVersions } from "./lib/options.js * @typedef {import("./lib/options").ParserOptions} ParserOptions * @typedef {import("./lib/token-translator").EsprimaToken} EsprimaToken * @typedef {import("./lib/token-translator").Range} TokenRange - * @typedef {import("@types/estree").Program} Program + * @typedef {import("estree").Program} Program */ diff --git a/package.json b/package.json index 6273d49e..1061865b 100644 --- a/package.json +++ b/package.json @@ -12,13 +12,15 @@ "require": "./dist/espree.cjs", "default": "./dist/espree.cjs" }, - "./dist/espree.cjs" + "./dist/espree.cjs", + "./dist/lib" ], "./package.json": "./package.json" }, "version": "9.3.1", "files": [ "lib", + "dist/lib", "dist/espree.cjs", "dist/espree.d.ts", "espree.js"