@eslint-sh/eslint-plugin 0.2.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -4
- package/dist/eslint-plugin.d.ts +95 -57
- package/dist/index.d.ts +12 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -12
- package/dist/index.js.map +1 -1
- package/dist/language/selector-classes.d.ts +6 -10
- package/dist/language/selector-classes.d.ts.map +1 -1
- package/dist/language/selector-classes.js +6 -9
- package/dist/language/selector-classes.js.map +1 -1
- package/dist/language/shell-language-options.d.ts +9 -11
- package/dist/language/shell-language-options.d.ts.map +1 -1
- package/dist/language/shell-language-options.js +7 -11
- package/dist/language/shell-language-options.js.map +1 -1
- package/dist/language/shell-language.d.ts +10 -12
- package/dist/language/shell-language.d.ts.map +1 -1
- package/dist/language/shell-language.js +45 -79
- package/dist/language/shell-language.js.map +1 -1
- package/dist/language/shell-source-code.d.ts +10 -19
- package/dist/language/shell-source-code.d.ts.map +1 -1
- package/dist/language/shell-source-code.js +165 -62
- package/dist/language/shell-source-code.js.map +1 -1
- package/dist/language/source-coordinates.d.ts +23 -0
- package/dist/language/source-coordinates.d.ts.map +1 -0
- package/dist/language/source-coordinates.js +58 -0
- package/dist/language/source-coordinates.js.map +1 -0
- package/dist/language/syntax-view.d.ts +60 -0
- package/dist/language/syntax-view.d.ts.map +1 -0
- package/dist/language/syntax-view.js +164 -0
- package/dist/language/syntax-view.js.map +1 -0
- package/dist/language/word-resolution.d.ts +11 -0
- package/dist/language/word-resolution.d.ts.map +1 -0
- package/dist/language/word-resolution.js +18 -0
- package/dist/language/word-resolution.js.map +1 -0
- package/docs/custom-rule-tutorial.md +23 -12
- package/docs/examples/eslint.config.mjs +1 -1
- package/docs/examples/{no-rm-rf-rule.js → no-rm-rf-rule.mjs} +9 -4
- package/docs/selectors.md +9 -0
- package/package.json +9 -3
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import type { ShFile, ShNode } from 'sh-ast';
|
|
2
1
|
import type { File, Language, OkParseResult, ParseResult } from '@eslint/core';
|
|
3
2
|
import { ShellSourceCode } from './shell-source-code.js';
|
|
3
|
+
import type { ShellFile, ShellNode } from './syntax-view.js';
|
|
4
4
|
import { type NormalizedShellLanguageOptions, type ShellLanguageOptions } from './shell-language-options.js';
|
|
5
5
|
/**
|
|
6
6
|
* `ShellLanguage` — the `@eslint/core` `Language` implementation for shell
|
|
7
|
-
* scripts
|
|
8
|
-
*
|
|
9
|
-
* as `languages.sh`, so consumers select it via `language: "sh/sh"`.
|
|
7
|
+
* scripts. Registered by the plugin as `languages.sh`, so consumers select
|
|
8
|
+
* it via `language: "sh/sh"`.
|
|
10
9
|
*
|
|
11
10
|
* Implements `matchesSelectorClass` (the six launch esquery selector
|
|
12
11
|
* classes — see `./selector-classes.js`), so rules and end users can write
|
|
@@ -49,23 +48,22 @@ export declare class ShellLanguage implements Language {
|
|
|
49
48
|
* needed there, but `:loop :command` is) match a whole family of node
|
|
50
49
|
* types instead of one literal type name. Delegates to
|
|
51
50
|
* `./selector-classes.js`'s `SELECTOR_CLASS_NODE_TYPES` table for the six
|
|
52
|
-
* launch classes
|
|
53
|
-
* objects"); `ancestry` is unused today because none of the six launch
|
|
51
|
+
* launch classes; `ancestry` is unused today because none of the six launch
|
|
54
52
|
* classes need ancestor context, but the parameter is accepted to match
|
|
55
53
|
* `Language.matchesSelectorClass`'s signature exactly.
|
|
56
54
|
*/
|
|
57
|
-
matchesSelectorClass(className: string, node:
|
|
55
|
+
matchesSelectorClass(className: string, node: ShellNode, _ancestry: ShellNode[]): boolean;
|
|
58
56
|
/**
|
|
59
57
|
* Parses `file.body` (guaranteed to be a `string`, since `fileType` is
|
|
60
|
-
* `"text"`)
|
|
58
|
+
* `"text"`) with one synchronous parse and its original-position snapshot,
|
|
59
|
+
* mapping the result to
|
|
61
60
|
* the `{ok: true, ast}` / `{ok: false, errors}` shape `Language.parse` is
|
|
62
61
|
* required to return. Never throws — parse failures are reported as
|
|
63
|
-
* fatal lint messages, per the `Language` contract
|
|
64
|
-
* (design/ARCHITECTURE.md, "Parse errors and dialects").
|
|
62
|
+
* fatal lint messages, per the `Language` contract.
|
|
65
63
|
*/
|
|
66
64
|
parse(file: File, context: {
|
|
67
65
|
languageOptions: ShellLanguageOptions;
|
|
68
|
-
}): ParseResult<
|
|
66
|
+
}): ParseResult<ShellFile>;
|
|
69
67
|
/**
|
|
70
68
|
* Creates the `ShellSourceCode` ESLint uses to run rules against `ast`.
|
|
71
69
|
* `context.languageOptions` is ESLint's already-normalized copy (see
|
|
@@ -77,7 +75,7 @@ export declare class ShellLanguage implements Language {
|
|
|
77
75
|
* direct construction (e.g. tests that skip the `Language` normalization
|
|
78
76
|
* step), mirroring `parse()`'s `dialect` default above.
|
|
79
77
|
*/
|
|
80
|
-
createSourceCode(file: File, parseResult: OkParseResult<
|
|
78
|
+
createSourceCode(file: File, parseResult: OkParseResult<ShellFile>, context: {
|
|
81
79
|
languageOptions: ShellLanguageOptions;
|
|
82
80
|
}): ShellSourceCode;
|
|
83
81
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell-language.d.ts","sourceRoot":"","sources":["../../src/language/shell-language.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shell-language.d.ts","sourceRoot":"","sources":["../../src/language/shell-language.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,IAAI,EAAa,QAAQ,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE1F,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7D,OAAO,EAGL,KAAK,8BAA8B,EAEnC,KAAK,oBAAoB,EAC1B,MAAM,6BAA6B,CAAC;AA+CrC;;;;;;;;;;;;;;GAcG;AACH,qBAAa,aAAc,YAAW,QAAQ;IAC5C,QAAQ,CAAC,QAAQ,EAAG,MAAM,CAAU;IACpC,QAAQ,CAAC,SAAS,EAAG,CAAC,CAAU;IAChC,QAAQ,CAAC,WAAW,EAAG,CAAC,CAAU;IAClC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAU;IACtC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAA2B;IACzE,QAAQ,CAAC,sBAAsB,EAAE,oBAAoB,CAAuB;IAE5E;;;;;;;;OAQG;IACH,uBAAuB,CAAC,eAAe,EAAE,oBAAoB,GAAG,IAAI;IAIpE;;;;;;OAMG;IACH,wBAAwB,CAAC,eAAe,EAAE,oBAAoB,GAAG,8BAA8B;IAI/F;;;;;;;;;OASG;IACH,oBAAoB,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,OAAO;IAIzF;;;;;;;OAOG;IACH,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE;QAAE,eAAe,EAAE,oBAAoB,CAAA;KAAE,GAAG,WAAW,CAAC,SAAS,CAAC;IAiB7F;;;;;;;;;;OAUG;IACH,gBAAgB,CACd,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,aAAa,CAAC,SAAS,CAAC,EACrC,OAAO,EAAE;QAAE,eAAe,EAAE,oBAAoB,CAAA;KAAE,GACjD,eAAe;CAOnB"}
|
|
@@ -1,89 +1,51 @@
|
|
|
1
|
-
|
|
1
|
+
/** Adapts upstream parsing and diagnostics to ESLint's synchronous Language contract. */
|
|
2
|
+
import { LangBash, LangBats, LangError, LangMirBSDKorn, LangPOSIX, LangZsh, ParseError, parseWithPositionsSync, } from 'sh-ast';
|
|
2
3
|
import { matchesSelectorClass as matchesShellSelectorClass } from './selector-classes.js';
|
|
3
4
|
import { ShellSourceCode } from './shell-source-code.js';
|
|
5
|
+
import { SourceCoordinates } from './source-coordinates.js';
|
|
6
|
+
import { adaptSyntaxFile, shellVisitorKeys } from './syntax-view.js';
|
|
4
7
|
import { normalizeShellLanguageOptions, validateShellLanguageOptions, } from './shell-language-options.js';
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
*/
|
|
8
|
+
/** Configuration labels map to exact upstream constants; no shell-version policy is added to parsing. */
|
|
9
|
+
const DIALECT_VARIANTS = {
|
|
10
|
+
bash: LangBash,
|
|
11
|
+
posix: LangPOSIX,
|
|
12
|
+
mksh: LangMirBSDKorn,
|
|
13
|
+
bats: LangBats,
|
|
14
|
+
zsh: LangZsh,
|
|
15
|
+
};
|
|
16
|
+
/** ESLint declares mutable visitor arrays; give it its own copy of the shared consumer relationships. */
|
|
14
17
|
const mutableShellVisitorKeys = Object.fromEntries(Object.entries(shellVisitorKeys).map(([type, keys]) => [type, [...keys]]));
|
|
15
18
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* without the filename's own characters (e.g. `.` in `b.sh`, or any
|
|
20
|
-
* sandbox-path characters) being interpreted as regex metacharacters.
|
|
21
|
-
*/
|
|
22
|
-
function escapeRegExp(value) {
|
|
23
|
-
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Strips mvdan/sh's own `<filename>:<line>:<col>: ` prefix from a
|
|
27
|
-
* `ShParseError.message`, if present. mvdan/sh's `.message` is its own
|
|
28
|
-
* formatted error string (`sh-ast`'s `parse.ts` passes
|
|
29
|
-
* `result.parseError.message` to `ShParseError` verbatim — see that file's
|
|
30
|
-
* doc comment), which already embeds the same `filename:line:col` ESLint's
|
|
31
|
-
* own fatal-message header prints from `FileError.line`/`.column` — see
|
|
32
|
-
* issue #36. Left un-stripped, ESLint's console formatter (and any other
|
|
33
|
-
* consumer that reads `message.message`) shows the position twice and
|
|
34
|
-
* exposes the sandbox-absolute `file.path` a second time inside the message
|
|
35
|
-
* body.
|
|
36
|
-
*
|
|
37
|
-
* Only strips a prefix that names *this exact* `filename` (escaped, so the
|
|
38
|
-
* filename's own characters can't be misread as regex syntax), matched
|
|
39
|
-
* against `\d+:\d+` for line/column — mvdan/sh's message uses its own raw
|
|
40
|
-
* byte column, which is not always numerically identical to
|
|
41
|
-
* `ShParseError.column` (UTF-16-converted; see `ShParseErrorInfo.column`'s
|
|
42
|
-
* doc comment). A message that doesn't start with that exact prefix (e.g.
|
|
43
|
-
* mvdan/sh changes its format, or `filename` doesn't appear verbatim) is
|
|
44
|
-
* returned unchanged rather than mangled.
|
|
19
|
+
* Strip the exact upstream filename/position prefix ESLint renders separately.
|
|
20
|
+
* Upstream formats saturated line/column components as `?`; the source byte
|
|
21
|
+
* offset can still provide an exact UTF-16 location independently of that text.
|
|
45
22
|
*/
|
|
46
23
|
function stripPositionPrefix(message, filename) {
|
|
47
|
-
const
|
|
48
|
-
return message.replace(
|
|
24
|
+
const escaped = filename.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
25
|
+
return message.replace(new RegExp(`^${escaped}:(?:\\d+|\\?):(?:\\d+|\\?):\\s*`), '');
|
|
49
26
|
}
|
|
50
|
-
/**
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
* ESLint already renders that position from `.line`/`.column` in its own
|
|
60
|
-
* fatal-message header, so embedding it again in the message body is both
|
|
61
|
-
* noisy and, for absolute `file.path` values, an unwanted disclosure of the
|
|
62
|
-
* sandbox-absolute path (issue #36).
|
|
63
|
-
*
|
|
64
|
-
* Any other error reaching here (`ShInvalidDialectError` — unreachable in
|
|
65
|
-
* practice, since `validateLanguageOptions` rejects a bad dialect before
|
|
66
|
-
* ESLint ever calls `parse()`; or `ShInternalError` — a shim contract
|
|
67
|
-
* violation) has no real source position to report, so `1:1` is used as an
|
|
68
|
-
* explicit, honest fallback for the "no position available" case — not a
|
|
69
|
-
* stand-in for an actual parse error's position.
|
|
70
|
-
*/
|
|
71
|
-
function toFileError(error) {
|
|
72
|
-
if (error instanceof ShParseError) {
|
|
27
|
+
/** Preserve actual syntax positions while converting byte offsets into this source's UTF-16 diagnostics. */
|
|
28
|
+
function toFileError(error, source) {
|
|
29
|
+
if (error instanceof ParseError || error instanceof LangError) {
|
|
30
|
+
const filename = typeof error.Filename === 'string'
|
|
31
|
+
? error.Filename
|
|
32
|
+
: new TextDecoder('utf-8', { fatal: true }).decode(error.Filename);
|
|
33
|
+
const location = error.Pos.IsValid && !error.Pos.IsRecovered
|
|
34
|
+
? new SourceCoordinates(source).fromByteOffset(error.Pos.Offset)
|
|
35
|
+
: { line: 1, column: 1 };
|
|
73
36
|
return {
|
|
74
|
-
message: stripPositionPrefix(error.message,
|
|
75
|
-
line:
|
|
76
|
-
column:
|
|
37
|
+
message: stripPositionPrefix(error.message, filename),
|
|
38
|
+
line: location.line,
|
|
39
|
+
column: location.column,
|
|
77
40
|
};
|
|
78
41
|
}
|
|
79
|
-
|
|
80
|
-
return { message, line: 1, column: 1 };
|
|
42
|
+
// Bridge/input failures carry no asserted syntax position. The fallback is an ESLint presentation policy.
|
|
43
|
+
return { message: error instanceof Error ? error.message : String(error), line: 1, column: 1 };
|
|
81
44
|
}
|
|
82
45
|
/**
|
|
83
46
|
* `ShellLanguage` — the `@eslint/core` `Language` implementation for shell
|
|
84
|
-
* scripts
|
|
85
|
-
*
|
|
86
|
-
* as `languages.sh`, so consumers select it via `language: "sh/sh"`.
|
|
47
|
+
* scripts. Registered by the plugin as `languages.sh`, so consumers select
|
|
48
|
+
* it via `language: "sh/sh"`.
|
|
87
49
|
*
|
|
88
50
|
* Implements `matchesSelectorClass` (the six launch esquery selector
|
|
89
51
|
* classes — see `./selector-classes.js`), so rules and end users can write
|
|
@@ -130,8 +92,7 @@ export class ShellLanguage {
|
|
|
130
92
|
* needed there, but `:loop :command` is) match a whole family of node
|
|
131
93
|
* types instead of one literal type name. Delegates to
|
|
132
94
|
* `./selector-classes.js`'s `SELECTOR_CLASS_NODE_TYPES` table for the six
|
|
133
|
-
* launch classes
|
|
134
|
-
* objects"); `ancestry` is unused today because none of the six launch
|
|
95
|
+
* launch classes; `ancestry` is unused today because none of the six launch
|
|
135
96
|
* classes need ancestor context, but the parameter is accepted to match
|
|
136
97
|
* `Language.matchesSelectorClass`'s signature exactly.
|
|
137
98
|
*/
|
|
@@ -140,21 +101,26 @@ export class ShellLanguage {
|
|
|
140
101
|
}
|
|
141
102
|
/**
|
|
142
103
|
* Parses `file.body` (guaranteed to be a `string`, since `fileType` is
|
|
143
|
-
* `"text"`)
|
|
104
|
+
* `"text"`) with one synchronous parse and its original-position snapshot,
|
|
105
|
+
* mapping the result to
|
|
144
106
|
* the `{ok: true, ast}` / `{ok: false, errors}` shape `Language.parse` is
|
|
145
107
|
* required to return. Never throws — parse failures are reported as
|
|
146
|
-
* fatal lint messages, per the `Language` contract
|
|
147
|
-
* (design/ARCHITECTURE.md, "Parse errors and dialects").
|
|
108
|
+
* fatal lint messages, per the `Language` contract.
|
|
148
109
|
*/
|
|
149
110
|
parse(file, context) {
|
|
150
111
|
const text = file.body;
|
|
151
112
|
const dialect = context.languageOptions.dialect ?? 'bash';
|
|
152
113
|
try {
|
|
153
|
-
const
|
|
114
|
+
const parsed = parseWithPositionsSync(text, {
|
|
115
|
+
Variant: DIALECT_VARIANTS[dialect],
|
|
116
|
+
Filename: file.path,
|
|
117
|
+
KeepComments: true,
|
|
118
|
+
});
|
|
119
|
+
const ast = adaptSyntaxFile(parsed.File, text, parsed.Positions);
|
|
154
120
|
return { ok: true, ast };
|
|
155
121
|
}
|
|
156
122
|
catch (error) {
|
|
157
|
-
return { ok: false, errors: [toFileError(error)] };
|
|
123
|
+
return { ok: false, errors: [toFileError(error, text)] };
|
|
158
124
|
}
|
|
159
125
|
}
|
|
160
126
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell-language.js","sourceRoot":"","sources":["../../src/language/shell-language.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"shell-language.js","sourceRoot":"","sources":["../../src/language/shell-language.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { TextSourceCodeBase } from '@eslint/plugin-kit';
|
|
2
|
-
import type { ShFile, ShNode,
|
|
2
|
+
import type { ShellFile as ShFile, ShellNode as ShNode, ShellComment } from './syntax-view.js';
|
|
3
3
|
import type { Directive as IDirective, FileProblem, RulesConfig, SourceLocation, TraversalStep } from '@eslint/core';
|
|
4
4
|
import type { ShellLanguageOptions } from './shell-language-options.js';
|
|
5
5
|
/**
|
|
6
6
|
* `ShellSourceCode` — the `SourceCode` object ESLint uses to work with a
|
|
7
|
-
* parsed shell file
|
|
8
|
-
* objects"). Extends `@eslint/plugin-kit`'s `TextSourceCodeBase`, which
|
|
7
|
+
* parsed shell file. Extends `@eslint/plugin-kit`'s `TextSourceCodeBase`, which
|
|
9
8
|
* already implements `getLoc`/`getRange`/`getText`/`lines` (both by reading
|
|
10
9
|
* the normalized node's own `loc`/`range` fields — see
|
|
11
|
-
*
|
|
10
|
+
* the consumer's source-view contract), `getLocFromIndex`, and
|
|
12
11
|
* `getIndexFromLoc`; this class adds the two members the base class
|
|
13
12
|
* deliberately leaves unimplemented: `traverse()` (base throws "Not
|
|
14
13
|
* implemented") and `getParent()` (base throws "Not implemented", and
|
|
@@ -20,7 +19,7 @@ import type { ShellLanguageOptions } from './shell-language-options.js';
|
|
|
20
19
|
* (`<prefix>-disable`, `<prefix>-enable`, `<prefix>-disable-line`,
|
|
21
20
|
* `<prefix>-disable-next-line`) plus whole-file inline rule config
|
|
22
21
|
* (bare `<prefix> <rule-config>`), sourced from `Comment` nodes gathered via
|
|
23
|
-
*
|
|
22
|
+
* the consumer's `walkShell()` and parsed with
|
|
24
23
|
* `@eslint/plugin-kit`'s `ConfigCommentParser` — the same building blocks
|
|
25
24
|
* `@eslint/json`'s `JSONSourceCode` uses, generalized so the `<prefix>` is
|
|
26
25
|
* configurable (default `"eslint"`; see `ShellLanguageOptions.directivePrefix`)
|
|
@@ -36,7 +35,7 @@ export declare class ShellSourceCode extends TextSourceCodeBase<{
|
|
|
36
35
|
LangOptions: ShellLanguageOptions;
|
|
37
36
|
RootNode: ShFile;
|
|
38
37
|
SyntaxElementWithLoc: ShNode;
|
|
39
|
-
ConfigNode:
|
|
38
|
+
ConfigNode: ShellComment;
|
|
40
39
|
}> {
|
|
41
40
|
#private;
|
|
42
41
|
constructor(options: {
|
|
@@ -53,17 +52,9 @@ export declare class ShellSourceCode extends TextSourceCodeBase<{
|
|
|
53
52
|
*/
|
|
54
53
|
getParent(node: ShNode): ShNode | undefined;
|
|
55
54
|
/**
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
* is what lets rule listeners use `NodeType` and `NodeType:exit` esquery
|
|
60
|
-
* selectors. Children are discovered via `sh-ast`'s generated,
|
|
61
|
-
* frozen `visitorKeys` table (per node `type`) — **not** structurally
|
|
62
|
-
* (contrast `sh-ast`'s own `walk()`, which deliberately walks
|
|
63
|
-
* structurally so its correctness never depends on that table) — because
|
|
64
|
-
* ESLint's traversal contract is defined in terms of a language's
|
|
65
|
-
* declared `visitorKeys`, and this class's whole job is to honor that
|
|
66
|
-
* contract for shell ASTs.
|
|
55
|
+
* Produces the enter/exit steps ESLint uses for selectors and ancestor lookup.
|
|
56
|
+
* Child keys describe the consumer view, including its auxiliary records.
|
|
57
|
+
* This callback protocol is ESLint's, independent of upstream syntax.Walk.
|
|
67
58
|
*/
|
|
68
59
|
traverse(): Iterable<TraversalStep>;
|
|
69
60
|
/**
|
|
@@ -74,7 +65,7 @@ export declare class ShellSourceCode extends TextSourceCodeBase<{
|
|
|
74
65
|
* effect" when `linterOptions.noInlineConfig` is set — see
|
|
75
66
|
* `eslint`'s `lib/linter/linter.js`, the `warnInlineConfig` branch).
|
|
76
67
|
*/
|
|
77
|
-
getInlineConfigNodes():
|
|
68
|
+
getInlineConfigNodes(): ShellComment[];
|
|
78
69
|
/**
|
|
79
70
|
* Returns the disable/enable directives found among
|
|
80
71
|
* {@link ShellSourceCode.getInlineConfigNodes}'s comments, recognizing all four forms —
|
|
@@ -106,7 +97,7 @@ export declare class ShellSourceCode extends TextSourceCodeBase<{
|
|
|
106
97
|
* calling this method — and `getDisableDirectives`, together, since both
|
|
107
98
|
* are gated by the same flag in `eslint`'s own `linter.js` — and instead
|
|
108
99
|
* calls `getInlineConfigNodes` to emit a "has no effect" warning per
|
|
109
|
-
* comment
|
|
100
|
+
* comment).
|
|
110
101
|
*/
|
|
111
102
|
applyInlineConfig(): {
|
|
112
103
|
configs: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shell-source-code.d.ts","sourceRoot":"","sources":["../../src/language/shell-source-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,kBAAkB,EAEnB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,
|
|
1
|
+
{"version":3,"file":"shell-source-code.d.ts","sourceRoot":"","sources":["../../src/language/shell-source-code.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,kBAAkB,EAEnB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,KAAK,EAAE,SAAS,IAAI,MAAM,EAAE,SAAS,IAAI,MAAM,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAC/F,OAAO,KAAK,EACV,SAAS,IAAI,UAAU,EAEvB,WAAW,EACX,WAAW,EACX,cAAc,EACd,aAAa,EACd,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AA+MxE;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,qBAAa,eAAgB,SAAQ,kBAAkB,CAAC;IACtD,WAAW,EAAE,oBAAoB,CAAC;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,UAAU,EAAE,YAAY,CAAC;CAC1B,CAAC;;gBAkDY,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE;IAU5E;;;;;;OAMG;IACH,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAI3C;;;;OAIG;IACH,QAAQ,IAAI,QAAQ,CAAC,aAAa,CAAC;IAuDnC;;;;;;;OAOG;IACH,oBAAoB,IAAI,YAAY,EAAE;IAOtC;;;;;;;;;;;;;;;;OAgBG;IACH,oBAAoB,IAAI;QAAE,UAAU,EAAE,UAAU,EAAE,CAAC;QAAC,QAAQ,EAAE,WAAW,EAAE,CAAA;KAAE;IA0B7E;;;;;;;;;;;OAWG;IACH,iBAAiB,IAAI;QACnB,OAAO,EAAE;YAAE,MAAM,EAAE;gBAAE,KAAK,EAAE,WAAW,CAAA;aAAE,CAAC;YAAC,GAAG,EAAE,cAAc,CAAA;SAAE,EAAE,CAAC;QACnE,QAAQ,EAAE,WAAW,EAAE,CAAC;KACzB;CAqBF"}
|