Skip to content

Commit

Permalink
feat: apply runes to *.svelte.js and *.svelte.ts (#426)
Browse files Browse the repository at this point in the history
  • Loading branch information
ota-meshi authored Nov 17, 2023
1 parent 96d44b8 commit 9793cb0
Show file tree
Hide file tree
Showing 32 changed files with 9,092 additions and 451 deletions.
5 changes: 5 additions & 0 deletions .changeset/brown-cheetahs-greet.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"svelte-eslint-parser": minor
---

feat: apply runes to `*.svelte.js` and `*.svelte.ts`.
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,44 @@ module.exports = {
}
```

### Runes support

***This is an experimental feature. It may be changed or removed in minor versions without notice.***

If you install Svelte v5 the parser will be able to parse runes, and will also be able to parse `*.js` and `*.ts` files.

When using this mode in an ESLint configuration, it is recommended to set it per file pattern as below.

```json
{
"overrides": [
{
"files": ["*.svelte"],
"parser": "svelte-eslint-parser",
"parserOptions": {
"parser": "...",
...
}
},
{
"files": ["*.svelte.js"],
"parser": "svelte-eslint-parser",
"parserOptions": {
...
}
},
{
"files": ["*.svelte.ts"],
"parser": "svelte-eslint-parser",
"parserOptions": {
"parser": "...(ts parser)...",
...
}
}
]
}
```

## :computer: Editor Integrations

### Visual Studio Code
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"release": "changeset publish",
"test": "pnpm run mocha \"tests/src/**/*.ts\" --reporter dot --timeout 60000",
"ts": "node -r esbuild-register",
"update-fixtures": "pnpm i -D svelte@4 && pnpm run run-update-fixtures && git checkout package.json && pnpm i && pnpm run run-update-fixtures",
"update-fixtures": "git add package.json && pnpm i -D svelte@4 && git checkout package.json && pnpm run run-update-fixtures && pnpm i && pnpm run run-update-fixtures",
"run-update-fixtures": "pnpm run ts ./tools/update-fixtures.ts",
"version:ci": "env-cmd -e version-ci pnpm run build:meta && changeset version"
},
Expand Down
59 changes: 7 additions & 52 deletions src/context/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import fs from "fs";
import path from "path";
import type {
Comment,
Locations,
Expand All @@ -15,19 +13,13 @@ import type ESTree from "estree";
import type * as SvAST from "../parser/svelte-ast-types";
import { ScriptLetContext } from "./script-let";
import { LetDirectiveCollections } from "./let-directive-collection";
import { getParserForLang } from "../parser/resolve-parser";
import type { AttributeToken } from "../parser/html";
import { parseAttributes } from "../parser/html";
import {
isTSESLintParserObject,
maybeTSESLintParserObject,
} from "../parser/parser-object";
import { sortedLastIndex } from "../utils";

const TS_PARSER_NAMES = [
"@typescript-eslint/parser",
"typescript-eslint-parser-for-extra-files",
];
import {
isTypeScript,
type NormalizedParserOptions,
} from "../parser/parser-options";

export class ScriptsSourceCode {
private raw: string;
Expand Down Expand Up @@ -116,7 +108,7 @@ export type ContextSourceCode = {
export class Context {
public readonly code: string;

public readonly parserOptions: any;
public readonly parserOptions: NormalizedParserOptions;

// ----- Source Code ------
public readonly sourceCode: ContextSourceCode;
Expand Down Expand Up @@ -155,7 +147,7 @@ export class Context {

private readonly blocks: Block[] = [];

public constructor(code: string, parserOptions: any) {
public constructor(code: string, parserOptions: NormalizedParserOptions) {
this.code = code;
this.parserOptions = parserOptions;
this.locs = new LinesAndColumns(code);
Expand Down Expand Up @@ -287,44 +279,7 @@ export class Context {
return this.state.isTypeScript;
}
const lang = this.sourceCode.scripts.attrs.lang;
if (!lang) {
return (this.state.isTypeScript = false);
}
const parserValue = getParserForLang(
this.sourceCode.scripts.attrs,
this.parserOptions?.parser,
);
if (typeof parserValue !== "string") {
return (this.state.isTypeScript =
maybeTSESLintParserObject(parserValue) ||
isTSESLintParserObject(parserValue));
}
const parserName = parserValue;
if (TS_PARSER_NAMES.includes(parserName)) {
return (this.state.isTypeScript = true);
}
if (TS_PARSER_NAMES.some((nm) => parserName.includes(nm))) {
let targetPath = parserName;
while (targetPath) {
const pkgPath = path.join(targetPath, "package.json");
if (fs.existsSync(pkgPath)) {
try {
return (this.state.isTypeScript = TS_PARSER_NAMES.includes(
JSON.parse(fs.readFileSync(pkgPath, "utf-8"))?.name,
));
} catch {
return (this.state.isTypeScript = false);
}
}
const parent = path.dirname(targetPath);
if (targetPath === parent) {
break;
}
targetPath = parent;
}
}

return (this.state.isTypeScript = false);
return (this.state.isTypeScript = isTypeScript(this.parserOptions, lang));
}

public stripScriptCode(start: number, end: number): void {
Expand Down
3 changes: 2 additions & 1 deletion src/parser/analyze-scope.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ import { getFallbackKeys } from "../traverse";
import type { SvelteReactiveStatement, SvelteScriptElement } from "../ast";
import { addReference, addVariable } from "../scope";
import { addElementToSortedArray } from "../utils";
import type { NormalizedParserOptions } from "./parser-options";
/**
* Analyze scope
*/
export function analyzeScope(
node: ESTree.Node,
parserOptions: any = {},
parserOptions: NormalizedParserOptions,
): ScopeManager {
const ecmaVersion = parserOptions.ecmaVersion || 2020;
const ecmaFeatures = parserOptions.ecmaFeatures || {};
Expand Down
18 changes: 9 additions & 9 deletions src/parser/globals.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import { VERSION as SVELTE_VERSION } from "svelte/compiler";
import { svelteVersion } from "./svelte-version";

const globalsForSvelte4: Readonly<string[]> = [
"$$slots",
"$$props",
"$$restProps",
] as const;
export const globalsForSvelte5 = [
const globalsForSvelte4 = ["$$slots", "$$props", "$$restProps"] as const;
export const globalsForRunes = [
"$state",
"$derived",
"$effect",
"$props",
] as const;
export const globals = SVELTE_VERSION.startsWith("5")
? [...globalsForSvelte4, ...globalsForSvelte5]
const globalsForSvelte5 = [...globalsForSvelte4, ...globalsForRunes];
export const globals = svelteVersion.gte(5)
? globalsForSvelte5
: globalsForSvelte4;
export const globalsForSvelteScript = svelteVersion.gte(5)
? globalsForRunes
: [];
Loading

0 comments on commit 9793cb0

Please sign in to comment.