Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions .README/rules/prefer-import-tag.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# `prefer-import-tag`

Prefer `@import` tags to inline `import()` statements.

## Fixer

Creates `@import` tags if an already existing matching `@typedef` or
`@import` is not found.

## Options

{"gitdown": "options"}

|||
|---|---|
|Context|everywhere|
|Tags|`augments`, `class`, `constant`, `enum`, `implements`, `member`, `module`, `namespace`, `param`, `property`, `returns`, `throws`, `type`, `typedef`, `yields`|
|Aliases|`constructor`, `const`, `extends`, `var`, `arg`, `argument`, `prop`, `return`, `exception`, `yield`|
|Closure-only|`package`, `private`, `protected`, `public`, `static`|
|Recommended|false|
|Settings|`mode`|
|Options|`enableFixer`, `exemptTypedefs`, `outputType`|

## Failing examples

<!-- assertions-failing preferImportTag -->

## Passing examples

<!-- assertions-passing preferImportTag -->
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,7 @@ non-default-recommended fixer).
||| [no-restricted-syntax](./docs/rules/no-restricted-syntax.md#readme) | Reports when certain comment structures are present. |
|On in TS; Off in TS flavor|:wrench:| [no-types](./docs/rules/no-types.md#readme) | This rule reports types being used on `@param` or `@returns` (redundant with TypeScript). |
|:heavy_check_mark: (Off in TS; Off in TS flavor)|| [no-undefined-types](./docs/rules/no-undefined-types.md#readme) | Besides some expected built-in types, prohibits any types not specified as globals or within `@typedef`. |
||:wrench:| [prefer-import-tag](./docs/rules/prefer-import-tag.md#readme) | Prefer `@import` tags to inline `import()` statements. |
|:heavy_check_mark:|| [reject-any-type](./docs/rules/reject-any-type.md#readme) | Reports use of `any` or `*` type |
|:heavy_check_mark:|| [reject-function-type](./docs/rules/reject-function-type.md#readme) | Reports use of `Function` type |
||:wrench:| [require-asterisk-prefix](./docs/rules/require-asterisk-prefix.md#readme) | Requires that each JSDoc line starts with an `*`. |
Expand Down
305 changes: 305 additions & 0 deletions docs/rules/prefer-import-tag.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,305 @@
<a name="user-content-prefer-import-tag"></a>
<a name="prefer-import-tag"></a>
# <code>prefer-import-tag</code>

Prefer `@import` tags to inline `import()` statements.

<a name="user-content-prefer-import-tag-fixer"></a>
<a name="prefer-import-tag-fixer"></a>
## Fixer

Creates `@import` tags if an already existing matching `@typedef` or
`@import` is not found.

<a name="user-content-prefer-import-tag-options"></a>
<a name="prefer-import-tag-options"></a>
## Options

A single options object has the following properties.

<a name="user-content-prefer-import-tag-options-enablefixer"></a>
<a name="prefer-import-tag-options-enablefixer"></a>
### <code>enableFixer</code>

Whether or not to enable the fixer to add `@import` tags.
<a name="user-content-prefer-import-tag-options-exempttypedefs"></a>
<a name="prefer-import-tag-options-exempttypedefs"></a>
### <code>exemptTypedefs</code>

Whether to allow `import()` statements within `@typedef`
<a name="user-content-prefer-import-tag-options-outputtype"></a>
<a name="prefer-import-tag-options-outputtype"></a>
### <code>outputType</code>

What kind of `@import` to generate when no matching `@typedef` or `@import` is found


|||
|---|---|
|Context|everywhere|
|Tags|`augments`, `class`, `constant`, `enum`, `implements`, `member`, `module`, `namespace`, `param`, `property`, `returns`, `throws`, `type`, `typedef`, `yields`|
|Aliases|`constructor`, `const`, `extends`, `var`, `arg`, `argument`, `prop`, `return`, `exception`, `yield`|
|Closure-only|`package`, `private`, `protected`, `public`, `static`|
|Recommended|false|
|Settings|`mode`|
|Options|`enableFixer`, `exemptTypedefs`, `outputType`|

<a name="user-content-prefer-import-tag-failing-examples"></a>
<a name="prefer-import-tag-failing-examples"></a>
## Failing examples

The following patterns are considered problems:

````ts
/**
* @type {import('eslint').Rule.Node}
*/
// Message: Inline `import()` found; prefer `@import`

/**
* @type {import('eslint').Rule.Node}
*/
// Settings: {"jsdoc":{"mode":"permissive"}}
// Message: Inline `import()` found; prefer `@import`

/**
* @type {import('eslint').Rule.Node}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"enableFixer":false}]
// Message: Inline `import()` found; prefer `@import`

/**
* @type {import('eslint').Rule.Node}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"outputType":"named-import"}]
// Message: Inline `import()` found; prefer `@import`

/**
* @type {import('eslint').Rule.Node}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"outputType":"namespaced-import"}]
// Message: Inline `import()` found; prefer `@import`

/**
* @type {import('eslint').Rule['Node']}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"outputType":"named-import"}]
// Message: Inline `import()` found; prefer `@import`

/**
* @type {import('eslint').Rule['Node']}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"outputType":"namespaced-import"}]
// Message: Inline `import()` found; prefer `@import`

/** @typedef {import('eslint2').Rule.Node} RuleNode */
/**
* @type {import('eslint').Rule.Node}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"exemptTypedefs":false}]
// Message: Inline `import()` found; prefer `@import`

/**
* @type {import('eslint')}
*/
// Message: Inline `import()` found; prefer `@import`

/**
* @type {import('eslint')}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"enableFixer":false}]
// Message: Inline `import()` found; prefer `@import`

/**
* @type {import('eslint').default}
*/
// Message: Inline `import()` found; prefer `@import`

/**
* @type {import('eslint').default}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"enableFixer":false}]
// Message: Inline `import()` found; prefer `@import`

/** @import * as eslint2 from 'eslint'; */
/**
* @type {import('eslint')}
*/
// Message: Inline `import()` found; prefer `@import`

/** @import eslint2 from 'eslint'; */
/**
* @type {import('eslint').default}
*/
// Message: Inline `import()` found; prefer `@import`

/** @import eslint2 from 'eslint'; */
/**
* @type {import('eslint').default}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"enableFixer":false}]
// Message: Inline `import()` found; prefer `@import`

/** @import {Rule} from 'eslint' */
/**
* @type {import('eslint').Rule.Node}
*/
// Message: Inline `import()` found; prefer `@import`

/** @import {Rule} from 'eslint' */
/**
* @type {import('eslint').Rule.Node}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"enableFixer":false}]
// Message: Inline `import()` found; prefer `@import`

/** @import * as eslint2 from 'eslint' */
/**
* @type {import('eslint').Rule.Node}
*/
// Message: Inline `import()` found; prefer `@import`

/** @import * as eslint2 from 'eslint' */
/**
* @type {import('eslint').Rule.Node}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"enableFixer":false}]
// Message: Inline `import()` found; prefer `@import`

/** @import LinterDef2, * as LinterDef3 from "eslint" */
/**
* @type {import('eslint').Rule.Node}
*/
// Message: Inline `import()` found; prefer `@import`

/**
* @import LinterDef2, * as LinterDef3 from "eslint"
*/
/**
* @type {import('eslint').Rule.Node}
*/
// Message: Inline `import()` found; prefer `@import`

/**
* @import LinterDef2,
* * as LinterDef3 from "eslint"
*/
/**
* @type {import('eslint').Rule.Node}
*/
// Message: Inline `import()` found; prefer `@import`

/**
* @import {
* ESLint
* } from "eslint"
*/
/**
* @type {import('eslint').ESLint.Node}
*/
// Message: Inline `import()` found; prefer `@import`

/** @typedef {import('eslint').Rule} Rule */
/**
* @type {import('eslint').Rule.Node}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"exemptTypedefs":true}]
// Message: Inline `import()` found; using `@typedef`

/** @typedef {import('eslint').Rule} Rule */
/**
* @type {import('eslint').Rule.Node.Abc.Def}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"exemptTypedefs":true}]
// Message: Inline `import()` found; using `@typedef`

/** @typedef {import('eslint').Rule} Rule */
/**
* @type {import('eslint').Rule.Node.Abc['Def']}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"exemptTypedefs":true}]
// Message: Inline `import()` found; using `@typedef`

/** @typedef {import('eslint').Rule.Node} RuleNode */
/**
* @type {import('eslint').Rule.Node}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"exemptTypedefs":true}]
// Message: Inline `import()` found; using `@typedef`

/**
* @type {number|import('eslint').Rule.Node}
*/
// Message: Inline `import()` found; prefer `@import`

/** @typedef {import('eslint').Rule.Node} Rule */
/**
* @type {import('eslint').Rule}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"exemptTypedefs":true}]
// Message: Inline `import()` found; prefer `@import`

/** @typedef {import('eslint').Rule.Node} Rule */
/**
* @type {import('eslint').Rule.Abc}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"exemptTypedefs":true}]
// Message: Inline `import()` found; prefer `@import`

/** @typedef {import('eslint').Rule} Rule */
/**
* @type {import('eslint').Rule.Node.Abc.Rule}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"exemptTypedefs":true}]
// Message: Inline `import()` found; using `@typedef`

/** @typedef {import('eslint').Rule} Rule */
/**
* @type {import('eslint').Rule.Node.Abc.Rule}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"enableFixer":false,"exemptTypedefs":true}]
// Message: Inline `import()` found; using `@typedef`

/** @typedef {import('eslint').Rule.Rule} Rule */
/**
* @type {import('eslint').Abc.Rule}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"exemptTypedefs":true}]
// Message: Inline `import()` found; prefer `@import`
````



<a name="user-content-prefer-import-tag-passing-examples"></a>
<a name="prefer-import-tag-passing-examples"></a>
## Passing examples

The following patterns are not considered problems:

````ts
/** @typedef {import('eslint').Rule.Node} RuleNode */
/**
* @type {RuleNode}
*/
// "jsdoc/prefer-import-tag": ["error"|"warn", {"exemptTypedefs":true}]

/** @import {Rule} from 'eslint' */
/**
* @type {Rule.Node}
*/

/** @import * as eslint from 'eslint' */
/**
* @type {eslint.Rule.Node}
*/

/**
* @type {Rule['Node']}
*/

/**
* Silently ignores error
* @type {Rule['Node'}
*/
````

3 changes: 3 additions & 0 deletions src/index-cjs.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import noMultiAsterisks from './rules/noMultiAsterisks.js';
import noRestrictedSyntax from './rules/noRestrictedSyntax.js';
import noTypes from './rules/noTypes.js';
import noUndefinedTypes from './rules/noUndefinedTypes.js';
import preferImportTag from './rules/preferImportTag.js';
import requireAsteriskPrefix from './rules/requireAsteriskPrefix.js';
import requireDescription from './rules/requireDescription.js';
import requireDescriptionCompleteSentence from './rules/requireDescriptionCompleteSentence.js';
Expand Down Expand Up @@ -111,6 +112,7 @@ index.rules = {
'no-restricted-syntax': noRestrictedSyntax,
'no-types': noTypes,
'no-undefined-types': noUndefinedTypes,
'prefer-import-tag': preferImportTag,
'reject-any-type': buildRejectOrPreferRuleDefinition({
description: 'Reports use of `any` or `*` type',
overrideSettings: {
Expand Down Expand Up @@ -283,6 +285,7 @@ const createRecommendedRuleset = (warnOrError, flatName) => {
'jsdoc/no-restricted-syntax': 'off',
'jsdoc/no-types': 'off',
'jsdoc/no-undefined-types': warnOrError,
'jsdoc/prefer-import-tag': 'off',
'jsdoc/reject-any-type': warnOrError,
'jsdoc/reject-function-type': warnOrError,
'jsdoc/require-asterisk-prefix': 'off',
Expand Down
3 changes: 3 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ import noMultiAsterisks from './rules/noMultiAsterisks.js';
import noRestrictedSyntax from './rules/noRestrictedSyntax.js';
import noTypes from './rules/noTypes.js';
import noUndefinedTypes from './rules/noUndefinedTypes.js';
import preferImportTag from './rules/preferImportTag.js';
import requireAsteriskPrefix from './rules/requireAsteriskPrefix.js';
import requireDescription from './rules/requireDescription.js';
import requireDescriptionCompleteSentence from './rules/requireDescriptionCompleteSentence.js';
Expand Down Expand Up @@ -117,6 +118,7 @@ index.rules = {
'no-restricted-syntax': noRestrictedSyntax,
'no-types': noTypes,
'no-undefined-types': noUndefinedTypes,
'prefer-import-tag': preferImportTag,
'reject-any-type': buildRejectOrPreferRuleDefinition({
description: 'Reports use of `any` or `*` type',
overrideSettings: {
Expand Down Expand Up @@ -289,6 +291,7 @@ const createRecommendedRuleset = (warnOrError, flatName) => {
'jsdoc/no-restricted-syntax': 'off',
'jsdoc/no-types': 'off',
'jsdoc/no-undefined-types': warnOrError,
'jsdoc/prefer-import-tag': 'off',
'jsdoc/reject-any-type': warnOrError,
'jsdoc/reject-function-type': warnOrError,
'jsdoc/require-asterisk-prefix': 'off',
Expand Down
Loading
Loading