From f82de63625ad94ee25f5b9ebd46601399297964c Mon Sep 17 00:00:00 2001 From: Brett Zamir Date: Tue, 24 Mar 2020 12:29:56 +0800 Subject: [PATCH] INCOMPLETE 1. Add tests (for desired features added to docs) -> implement 2. (apparent problem in eslint itself with our use of Program:exit): test(`no-undefined-types`): issues #507 --- .README/rules/no-undefined-types.md | 28 +++++++++++- README.md | 52 ++++++++++++++++++++++- package.json | 1 + src/rules/noUndefinedTypes.js | 50 +++++++++++++++++++++- test/rules/assertions/noUndefinedTypes.js | 38 +++++++++++++++++ 5 files changed, 166 insertions(+), 3 deletions(-) diff --git a/.README/rules/no-undefined-types.md b/.README/rules/no-undefined-types.md index e72fbbbd7..6629a7d47 100644 --- a/.README/rules/no-undefined-types.md +++ b/.README/rules/no-undefined-types.md @@ -43,12 +43,38 @@ reporting on use of that namepath elsewhere) and/or that a tag's `type` is #### Options -An option object may have the following key: +An option object may have the following keys, helping indicate types or +file sources of types: - `definedTypes` - This array can be populated to indicate other types which are automatically considered as defined (in addition to globals, etc.). Defaults to an empty array. +- `entryFiles` - Array of entry files objects indicating JavaScript or HTML + files whose `import` or `require` statements should be resolved recursively + and be analyzed for `@typedef`'s, globals, etc. (see `typeSources`) to treat + as "defined" for the purposes of this rule. Each object should have a + `file` array and with an optional `node` boolean property to indicate whether + to use the Node Resolution Algorithm (e.g., for Node.js) and/or a `cjs` + boolean property (if following `require`) properties. Set one of the `file` + items to `
`, ``, ``, or `` + to use the file referenced in the correpsonding property in `package.json`. + +- `jsdocConfig` - Object with: + - `file` string pointing to a path for a + [jsdoc config file](https://jsdoc.app/about-configuring-jsdoc.html) + which will be parsed for [input files](https://jsdoc.app/about-configuring-jsdoc.html#specifying-input-files), + including `include`, `exclude`, `includePattern`, and `excludePattern` + properties within the file as well as `opts.recurse`. See `entryFiles` + on how the (JavaScript) files will be treated (with + `sourceType: 'module'` in the jsdoc config file causing "cjs" to be + set to `false`). + +- `typeSources` - Array with `globals`, `exports`, and/or `locals` indicating + the source types that will be treated as valid types when found in the + current file or any entry files (`locals` will only apply to the + current file). Defaults to `['typedefs', 'globals', 'exports', 'locals']`. + ||| |---|---| |Context|everywhere| diff --git a/README.md b/README.md index 5e29119d5..62998430c 100644 --- a/README.md +++ b/README.md @@ -6848,12 +6848,38 @@ reporting on use of that namepath elsewhere) and/or that a tag's `type` is #### Options -An option object may have the following key: +An option object may have the following keys, helping indicate types or +file sources of types: - `definedTypes` - This array can be populated to indicate other types which are automatically considered as defined (in addition to globals, etc.). Defaults to an empty array. +- `entryFiles` - Array of entry files objects indicating JavaScript or HTML + files whose `import` or `require` statements should be resolved recursively + and be analyzed for `@typedef`'s or globals to treat as "defined" for the + purposes of this rule. Each object should have a `file` array and with an + optional `node` property to indicate whether to use the Node Resolution + Algorithm (e.g., for Node.js) and/or `cjs` (if following `require`) + properties. Set one of the `file` items to `
`, ``, + ``, or `` to use the file referenced in + the correpsonding property in `package.json`. + +- `jsdocConfig` - Object with: + - `file` string pointing to a path for a + [jsdoc config file](https://jsdoc.app/about-configuring-jsdoc.html) + which will be parsed for [input files](https://jsdoc.app/about-configuring-jsdoc.html#specifying-input-files), + including `include`, `exclude`, `includePattern`, and `excludePattern` + properties within the file as well as `opts.recurse`. See `entryFiles` + on how the (JavaScript) files will be treated (with + `sourceType: 'module'` in the jsdoc config file causing "cjs" to be + set to `false`). + +- `typeSources` - Array with `globals`, `exports`, and/or `locals` indicating + the source types that will be treated as valid types when found in the + current file or any entry files (`locals` will only apply to the + current file). + ||| |---|---| |Context|everywhere| @@ -7345,6 +7371,30 @@ function quux () {} * @type {SomeType} */ // Settings: {"jsdoc":{"structuredTags":{"namepathDefiner":{"name":"namepath-defining"}}}} + +import {myTypesA} from '../internal/file.js'; // ERROR +import {myTypesB} from '../internal/file.js'; // NO ERROR + +/** +* @typedef newType +* @property {myTypesA.someType} someProp - Some prop. +*/ + +/** +* @param {newType} arg - Arg. +*/ +function myFunctionA(arg) { + return arg; +} + +/** +* @param {myTypesB.someType} arg - Arg. +*/ +function myFunctionB(arg) { + return arg; +} + +export {myFunctionA, myFunctionB}; ```` diff --git a/package.json b/package.json index c847171b1..9a7d346e3 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "dependencies": { "comment-parser": "^0.7.6", "debug": "^4.1.1", + "es-file-traverse": "^0.1.2", "jsdoctypeparser": "^9.0.0", "lodash": "^4.17.20", "regextras": "^0.7.1", diff --git a/src/rules/noUndefinedTypes.js b/src/rules/noUndefinedTypes.js index acbbce4ff..0b5b56822 100644 --- a/src/rules/noUndefinedTypes.js +++ b/src/rules/noUndefinedTypes.js @@ -33,7 +33,17 @@ export default iterateJsdoc(({ const {scopeManager} = sourceCode; const {globalScope} = scopeManager; - const {definedTypes = []} = context.options[0] || {}; + const { + definedTypes = [], + entryFiles = [ + // {file, cjs, node} + ], + jsdocConfig: {file: jsdocConfigFile}, + typeSources = ['typedefs', 'globals', 'exports', 'locals'], + } = context.options[0] || {}; + + // eslint-disable-next-line no-console + console.log('entryFiles', entryFiles, jsdocConfigFile, typeSources); let definedPreferredTypes = []; const {preferredTypes, mode} = settings; @@ -179,6 +189,44 @@ export default iterateJsdoc(({ }, type: 'array', }, + entryFiles: { + items: { + properties: { + cjs: { + type: 'boolean', + }, + file: { + items: { + type: 'string', + }, + type: 'array', + }, + node: { + type: 'boolean', + }, + }, + require: ['file'], + type: 'object', + }, + type: 'array', + }, + jsdocConfig: { + properties: { + file: { + type: 'string', + }, + }, + type: 'object', + }, + typeSources: { + items: { + enum: [ + 'globals', 'exports', 'locals', + ], + type: 'string', + }, + type: 'array', + }, }, type: 'object', }, diff --git a/test/rules/assertions/noUndefinedTypes.js b/test/rules/assertions/noUndefinedTypes.js index c3e2a6491..6c23d74f4 100644 --- a/test/rules/assertions/noUndefinedTypes.js +++ b/test/rules/assertions/noUndefinedTypes.js @@ -897,5 +897,43 @@ export default { }, }, }, + { + code: ` + import {myTypesA} from '../internal/file.js'; // ERROR + import {myTypesB} from '../internal/file.js'; // NO ERROR + + /** + * @typedef newType + * @property {myTypesA.someType} someProp - Some prop. + */ + + /** + * @param {newType} arg - Arg. + */ + function myFunctionA(arg) { + return arg; + } + + /** + * @param {myTypesB.someType} arg - Arg. + */ + function myFunctionB(arg) { + return arg; + } + + export {myFunctionA, myFunctionB}; + `, + options: [ + { + entryFiles: [], + }, + ], + parserOptions: { + sourceType: 'module', + }, + rules: { + 'no-unused-vars': ['error'], + }, + }, ], };