-
-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: add `astro/semi` rule * Create little-kangaroos-invent.md
- Loading branch information
Showing
26 changed files
with
534 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"eslint-plugin-astro": minor | ||
--- | ||
|
||
feat: add `astro/semi` rule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
node_modules | ||
/tests/fixtures/rules/semi/**/*.astro |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
--- | ||
title: "astro/semi" | ||
description: "Require or disallow semicolons instead of ASI" | ||
--- | ||
|
||
# astro/semi | ||
|
||
> Require or disallow semicolons instead of ASI | ||
- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> **_This rule has not been released yet._** </badge> | ||
- :wrench: The `--fix` option on the [command line](https://eslint.org/docs/user-guide/command-line-interface#fixing-problems) can automatically fix some of the problems reported by this rule. | ||
|
||
## :book: Rule Details | ||
|
||
This rule enforces consistent use of semicolons. | ||
|
||
This rule extends the base ESLint's [semi] rule. The [semi] rule does not understand frontmatter fence tokens (`---`), so using the `never` option in the [semi] rule will result in a false negative. | ||
This rule supports [astro-eslint-parser]'s AST and tokens. | ||
|
||
[astro-eslint-parser]: https://github.com/ota-meshi/astro-eslint-parser | ||
|
||
Default: | ||
|
||
<ESLintCodeBlock fix> | ||
|
||
<!--eslint-skip--> | ||
|
||
```astro | ||
--- | ||
/* eslint astro/semi: ["error"] */ | ||
/* ✓ GOOD */ | ||
fn(); | ||
/* ✗ BAD */ | ||
fn() | ||
--- | ||
{() => { | ||
/* ✓ GOOD */ | ||
fn(); | ||
/* ✗ BAD */ | ||
fn() | ||
}} | ||
``` | ||
|
||
</ESLintCodeBlock> | ||
|
||
with `"never"` option: | ||
|
||
<ESLintCodeBlock fix> | ||
|
||
<!--eslint-skip--> | ||
|
||
```astro | ||
--- | ||
/* eslint astro/semi: ["error", "never"] */ | ||
/* ✓ GOOD */ | ||
fn() | ||
/* ✗ BAD */ | ||
fn(); | ||
--- | ||
{() => { | ||
/* ✓ GOOD */ | ||
fn() | ||
/* ✗ BAD */ | ||
fn(); | ||
}} | ||
``` | ||
|
||
</ESLintCodeBlock> | ||
|
||
## :wrench: Options | ||
|
||
```json | ||
{ | ||
"semi": "off", // Don't need ESLint's semi, so turn it off. | ||
"astro/semi": [ | ||
"error", | ||
"always", // or "never" | ||
{ "omitLastInOneLineBlock": true } | ||
// or { "beforeStatementContinuationChars": "any" | "always" | "never" } | ||
] | ||
} | ||
``` | ||
|
||
Same as [semi] rule option. See [here](https://eslint.org/docs/rules/semi#options) for details. | ||
|
||
## :couple: Related rules | ||
|
||
- [semi] | ||
|
||
[semi]: https://eslint.org/docs/rules/semi | ||
|
||
## :mag: Implementation | ||
|
||
- [Rule source](https://github.com/ota-meshi/eslint-plugin-astro/blob/main/src/rules/semi.ts) | ||
- [Test source](https://github.com/ota-meshi/eslint-plugin-astro/blob/main/tests/src/rules/semi.ts) | ||
- [Test fixture sources](https://github.com/ota-meshi/eslint-plugin-astro/tree/main/tests/fixtures/rules/semi) | ||
|
||
<sup>Taken with ❤️ [from ESLint core](https://eslint.org/docs/rules/semi)</sup> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import type { AST } from "astro-eslint-parser" | ||
import type { SourceCode } from "../types" | ||
import { createRule } from "../utils" | ||
import { getCoreRule, newProxy } from "../utils/eslint-core" | ||
|
||
const coreRule = getCoreRule("semi") | ||
export default createRule("semi", { | ||
meta: { | ||
docs: { | ||
description: coreRule.meta.docs.description, | ||
category: "Stylistic Issues", | ||
recommended: false, | ||
extensionRule: "semi", | ||
}, | ||
schema: coreRule.meta.schema, | ||
messages: coreRule.meta.messages, | ||
type: coreRule.meta.type, | ||
fixable: coreRule.meta.fixable, | ||
hasSuggestions: coreRule.meta.hasSuggestions, | ||
}, | ||
create(context) { | ||
if (!context.parserServices.isAstro) { | ||
return coreRule.create(context) | ||
} | ||
|
||
let sourceCodeWrapper: SourceCode | undefined | ||
|
||
return coreRule.create( | ||
newProxy(context, { | ||
getSourceCode() { | ||
if (sourceCodeWrapper) { | ||
return sourceCodeWrapper | ||
} | ||
const sourceCode = context.getSourceCode() | ||
|
||
/** Transforms token */ | ||
function transformToken( | ||
token: AST.Token | AST.Comment, | ||
): AST.Token | AST.Comment { | ||
return token.value === "---" | ||
? newProxy(token, { value: "___" }) | ||
: token | ||
} | ||
|
||
return (sourceCodeWrapper = newProxy(sourceCode, { | ||
/* eslint-disable @typescript-eslint/unbound-method -- ignore */ | ||
getFirstToken: wrapGetTokenFunction(sourceCode.getFirstToken), | ||
getFirstTokens: wrapGetTokensFunction(sourceCode.getFirstTokens), | ||
getFirstTokenBetween: wrapGetTokenFunction( | ||
sourceCode.getFirstTokenBetween, | ||
), | ||
getFirstTokensBetween: wrapGetTokensFunction( | ||
sourceCode.getFirstTokensBetween, | ||
), | ||
getLastToken: wrapGetTokenFunction(sourceCode.getLastToken), | ||
getLastTokens: wrapGetTokensFunction(sourceCode.getLastTokens), | ||
getLastTokenBetween: wrapGetTokenFunction( | ||
sourceCode.getLastTokenBetween, | ||
), | ||
getLastTokensBetween: wrapGetTokensFunction( | ||
sourceCode.getLastTokensBetween, | ||
), | ||
getTokenBefore: wrapGetTokenFunction(sourceCode.getTokenBefore), | ||
getTokensBefore: wrapGetTokensFunction(sourceCode.getTokensBefore), | ||
getTokenAfter: wrapGetTokenFunction(sourceCode.getTokenAfter), | ||
getTokensAfter: wrapGetTokensFunction(sourceCode.getTokensAfter), | ||
getTokenByRangeStart: wrapGetTokenFunction( | ||
sourceCode.getTokenByRangeStart, | ||
), | ||
getTokens: wrapGetTokensFunction(sourceCode.getTokens), | ||
getTokensBetween: wrapGetTokensFunction( | ||
sourceCode.getTokensBetween, | ||
), | ||
/* eslint-enable @typescript-eslint/unbound-method -- ignore */ | ||
})) | ||
|
||
/** Wrap token getter function */ | ||
function wrapGetTokenFunction< | ||
T extends ( | ||
this: SourceCode, | ||
...args: never[] | ||
) => AST.Token | AST.Comment | null, | ||
>(base: T): T { | ||
return function (this: SourceCode, ...args) { | ||
// eslint-disable-next-line no-invalid-this -- is valid | ||
const token = base.apply(this, args) | ||
if (!token) { | ||
return token | ||
} | ||
return transformToken(token) | ||
} as T | ||
} | ||
|
||
/** Wrap tokens getter function */ | ||
function wrapGetTokensFunction< | ||
T extends ( | ||
this: SourceCode, | ||
...args: never[] | ||
) => (AST.Token | AST.Comment)[], | ||
>(base: T): T { | ||
return function (this: SourceCode, ...args) { | ||
// eslint-disable-next-line no-invalid-this -- is valid | ||
const tokens = base.apply(this, args) | ||
return tokens.map(transformToken) | ||
} as T | ||
} | ||
}, | ||
}), | ||
) | ||
}, | ||
}) |
Oops, something went wrong.