astro-eslint-parser 0.0.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.
@@ -0,0 +1,96 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseTemplate = exports.parseForESLint = void 0;
4
+ const visitor_keys_1 = require("../visitor-keys");
5
+ const context_1 = require("../context");
6
+ const types_1 = require("@typescript-eslint/types");
7
+ const script_1 = require("./script");
8
+ const sort_1 = require("./sort");
9
+ const errors_1 = require("../errors");
10
+ const parse_1 = require("./astro-parser/parse");
11
+ const script_2 = require("../context/script");
12
+ /**
13
+ * Parse source code
14
+ */
15
+ function parseForESLint(code, options) {
16
+ const parserOptions = Object.assign({ ecmaVersion: 2020, sourceType: "module", loc: true, range: true, raw: true, tokens: true, comment: true, eslintVisitorKeys: true, eslintScopeManager: true }, (options || {}));
17
+ parserOptions.ecmaFeatures = Object.assign(Object.assign({}, (parserOptions.ecmaFeatures || {})), { jsx: true });
18
+ parserOptions.sourceType = "module";
19
+ if (parserOptions.ecmaVersion <= 5 || parserOptions.ecmaVersion == null) {
20
+ parserOptions.ecmaVersion = 2015;
21
+ }
22
+ const ctx = new context_1.Context(code, parserOptions);
23
+ const resultTemplate = parseTemplate(ctx.code, ctx);
24
+ const scriptContext = (0, script_2.processTemplate)(ctx, resultTemplate);
25
+ const resultScript = (0, script_1.parseScript)(scriptContext.script, ctx);
26
+ scriptContext.restore(resultScript);
27
+ (0, sort_1.sort)(resultScript.ast.comments);
28
+ (0, sort_1.sort)(resultScript.ast.tokens);
29
+ extractTokens(resultScript, ctx);
30
+ resultScript.services = Object.assign(resultScript.services || {}, {
31
+ isAstro: true,
32
+ getAstroAst() {
33
+ return resultTemplate.ast;
34
+ },
35
+ });
36
+ resultScript.visitorKeys = Object.assign({}, visitor_keys_1.KEYS, resultScript.visitorKeys);
37
+ ctx.remapCR(resultScript);
38
+ return resultScript;
39
+ }
40
+ exports.parseForESLint = parseForESLint;
41
+ /** Extract tokens */
42
+ function extractTokens(ast, ctx) {
43
+ if (!ast.ast.tokens) {
44
+ return;
45
+ }
46
+ const useRanges = (0, sort_1.sort)([
47
+ ...ast.ast.tokens,
48
+ ...(ast.ast.comments || []),
49
+ ]).map((t) => t.range);
50
+ let range = useRanges.shift();
51
+ for (let index = 0; index < ctx.code.length; index++) {
52
+ while (range && range[1] <= index) {
53
+ range = useRanges.shift();
54
+ }
55
+ if (range && range[0] <= index) {
56
+ index = range[1] - 1;
57
+ continue;
58
+ }
59
+ const c = ctx.code[index];
60
+ if (!c.trim()) {
61
+ continue;
62
+ }
63
+ if (isPunctuator(c)) {
64
+ ast.ast.tokens.push(ctx.buildToken(types_1.AST_TOKEN_TYPES.Punctuator, [index, index + 1]));
65
+ }
66
+ else {
67
+ // unknown
68
+ // It is may be a bug.
69
+ ast.ast.tokens.push(ctx.buildToken(types_1.AST_TOKEN_TYPES.Identifier, [index, index + 1]));
70
+ }
71
+ }
72
+ (0, sort_1.sort)(ast.ast.tokens);
73
+ /**
74
+ * Checks if the given char is punctuator
75
+ */
76
+ function isPunctuator(c) {
77
+ return /^[^\w$]$/iu.test(c);
78
+ }
79
+ }
80
+ /**
81
+ * Parse for template
82
+ */
83
+ function parseTemplate(code, ctx) {
84
+ try {
85
+ return (0, parse_1.parse)(code);
86
+ }
87
+ catch (e) {
88
+ if (typeof e.pos === "number") {
89
+ const err = new errors_1.ParseError(e.message, e.pos, ctx);
90
+ err.astroCompilerError = e;
91
+ throw err;
92
+ }
93
+ throw e;
94
+ }
95
+ }
96
+ exports.parseTemplate = parseTemplate;
@@ -0,0 +1,16 @@
1
+ import type { ESLintExtendedProgram } from ".";
2
+ /**
3
+ * The interface of a result of ESLint custom parser.
4
+ */
5
+ export declare type ESLintCustomParserResult = ESLintExtendedProgram["ast"] | ESLintExtendedProgram;
6
+ /**
7
+ * The interface of ESLint custom parsers.
8
+ */
9
+ export interface ESLintCustomParser {
10
+ parse(code: string, options: any): ESLintCustomParserResult;
11
+ parseForESLint?(code: string, options: any): ESLintCustomParserResult;
12
+ }
13
+ /** Get parser name */
14
+ export declare function getParserName(attrs: Record<string, string | undefined>, parser: any): string;
15
+ /** Get parser */
16
+ export declare function getParser(attrs: Record<string, string | undefined>, parser: any): ESLintCustomParser;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getParser = exports.getParserName = void 0;
4
+ const espree_1 = require("./espree");
5
+ /** Get parser name */
6
+ function getParserName(attrs, parser) {
7
+ if (parser) {
8
+ if (typeof parser === "string" && parser !== "espree") {
9
+ return parser;
10
+ }
11
+ else if (typeof parser === "object") {
12
+ const name = parser[attrs.lang || "js"];
13
+ if (typeof name === "string") {
14
+ return getParserName(attrs, name);
15
+ }
16
+ }
17
+ }
18
+ return "espree";
19
+ }
20
+ exports.getParserName = getParserName;
21
+ /** Get parser */
22
+ function getParser(attrs, parser) {
23
+ const name = getParserName(attrs, parser);
24
+ if (name !== "espree") {
25
+ // eslint-disable-next-line @typescript-eslint/no-require-imports -- ignore
26
+ return require(name);
27
+ }
28
+ return (0, espree_1.getEspree)();
29
+ }
30
+ exports.getParser = getParser;
@@ -0,0 +1,6 @@
1
+ import type { ESLintExtendedProgram } from ".";
2
+ import type { Context } from "../context";
3
+ /**
4
+ * Parse for script
5
+ */
6
+ export declare function parseScript(code: string, ctx: Context): ESLintExtendedProgram;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.parseScript = void 0;
7
+ const resolve_parser_1 = require("./resolve-parser");
8
+ const fs_1 = __importDefault(require("fs"));
9
+ const debug_1 = require("../debug");
10
+ /**
11
+ * Parse for script
12
+ */
13
+ function parseScript(code, ctx) {
14
+ var _a, _b, _c;
15
+ const parser = (0, resolve_parser_1.getParser)({}, ctx.parserOptions.parser);
16
+ let removeFile = null;
17
+ try {
18
+ const scriptOption = Object.assign({}, ctx.parserOptions);
19
+ if (ctx.isTypeScript() && scriptOption.filePath) {
20
+ scriptOption.filePath += ".tsx";
21
+ if (!fs_1.default.existsSync(scriptOption.filePath)) {
22
+ fs_1.default.writeFileSync(scriptOption.filePath, "/* temp for astro-eslint-parser */");
23
+ removeFile = scriptOption.filePath;
24
+ }
25
+ }
26
+ const result = (_b = (_a = parser.parseForESLint) === null || _a === void 0 ? void 0 : _a.call(parser, code, scriptOption)) !== null && _b !== void 0 ? _b : (_c = parser.parse) === null || _c === void 0 ? void 0 : _c.call(parser, code, scriptOption);
27
+ if ("ast" in result && result.ast != null) {
28
+ return result;
29
+ }
30
+ return { ast: result };
31
+ }
32
+ catch (e) {
33
+ (0, debug_1.debug)("[script] parsing error:", e.message, `@ ${JSON.stringify(code)}`);
34
+ throw e;
35
+ }
36
+ finally {
37
+ if (removeFile)
38
+ fs_1.default.unlinkSync(removeFile);
39
+ }
40
+ }
41
+ exports.parseScript = parseScript;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Sort tokens
3
+ */
4
+ export declare function sort<T extends {
5
+ range: [number, number];
6
+ }>(tokens: T[]): T[];
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.sort = void 0;
4
+ /**
5
+ * Sort tokens
6
+ */
7
+ function sort(tokens) {
8
+ return tokens.sort((a, b) => {
9
+ if (a.range[0] !== b.range[0]) {
10
+ return a.range[0] - b.range[0];
11
+ }
12
+ return a.range[1] - b.range[1];
13
+ });
14
+ }
15
+ exports.sort = sort;
@@ -0,0 +1,27 @@
1
+ import type { VisitorKeys } from "eslint-visitor-keys";
2
+ import type { TSESTree } from "@typescript-eslint/types";
3
+ import type { AstroNode } from "./ast";
4
+ /**
5
+ * Get the keys of the given node to traverse it.
6
+ * @param node The node to get.
7
+ * @returns The keys to traverse.
8
+ */
9
+ export declare function getFallbackKeys(node: any): string[];
10
+ /**
11
+ * Get the keys of the given node to traverse it.
12
+ * @param node The node to get.
13
+ * @returns The keys to traverse.
14
+ */
15
+ export declare function getKeys(node: any, visitorKeys?: VisitorKeys): string[];
16
+ /**
17
+ * Get the nodes of the given node.
18
+ * @param node The node to get.
19
+ */
20
+ export declare function getNodes(node: any, key: string): IterableIterator<AstroNode | TSESTree.Node>;
21
+ export interface Visitor<N> {
22
+ visitorKeys?: VisitorKeys;
23
+ enterNode(node: N, parent: N | null): void;
24
+ leaveNode(node: N, parent: N | null): void;
25
+ }
26
+ export declare function traverseNodes(node: AstroNode, visitor: Visitor<AstroNode | TSESTree.Node>): void;
27
+ export declare function traverseNodes(node: TSESTree.Node, visitor: Visitor<TSESTree.Node>): void;
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.traverseNodes = exports.getNodes = exports.getKeys = exports.getFallbackKeys = void 0;
4
+ const visitor_keys_1 = require("./visitor-keys");
5
+ /**
6
+ * Check that the given key should be traversed or not.
7
+ * @this {Traversable}
8
+ * @param key The key to check.
9
+ * @returns `true` if the key should be traversed.
10
+ */
11
+ function fallbackKeysFilter(key) {
12
+ let value = null;
13
+ return (key !== "comments" &&
14
+ key !== "leadingComments" &&
15
+ key !== "loc" &&
16
+ key !== "parent" &&
17
+ key !== "range" &&
18
+ key !== "tokens" &&
19
+ key !== "trailingComments" &&
20
+ (value = this[key]) !== null &&
21
+ typeof value === "object" &&
22
+ (typeof value.type === "string" || Array.isArray(value)));
23
+ }
24
+ /**
25
+ * Get the keys of the given node to traverse it.
26
+ * @param node The node to get.
27
+ * @returns The keys to traverse.
28
+ */
29
+ function getFallbackKeys(node) {
30
+ return Object.keys(node).filter(fallbackKeysFilter, node);
31
+ }
32
+ exports.getFallbackKeys = getFallbackKeys;
33
+ /**
34
+ * Get the keys of the given node to traverse it.
35
+ * @param node The node to get.
36
+ * @returns The keys to traverse.
37
+ */
38
+ function getKeys(node, visitorKeys) {
39
+ const keys = (visitorKeys || visitor_keys_1.KEYS)[node.type] || getFallbackKeys(node);
40
+ return keys.filter((key) => !getNodes(node, key).next().done);
41
+ }
42
+ exports.getKeys = getKeys;
43
+ /**
44
+ * Get the nodes of the given node.
45
+ * @param node The node to get.
46
+ */
47
+ function* getNodes(node, key) {
48
+ const child = node[key];
49
+ if (Array.isArray(child)) {
50
+ for (const c of child) {
51
+ if (isNode(c)) {
52
+ yield c;
53
+ }
54
+ }
55
+ }
56
+ else if (isNode(child)) {
57
+ yield child;
58
+ }
59
+ }
60
+ exports.getNodes = getNodes;
61
+ /**
62
+ * Check whether a given value is a node.
63
+ * @param x The value to check.
64
+ * @returns `true` if the value is a node.
65
+ */
66
+ function isNode(x) {
67
+ return x !== null && typeof x === "object" && typeof x.type === "string";
68
+ }
69
+ /**
70
+ * Traverse the given node.
71
+ * @param node The node to traverse.
72
+ * @param parent The parent node.
73
+ * @param visitor The node visitor.
74
+ */
75
+ function traverse(node, parent, visitor) {
76
+ visitor.enterNode(node, parent);
77
+ const keys = getKeys(node, visitor.visitorKeys);
78
+ for (const key of keys) {
79
+ for (const child of getNodes(node, key)) {
80
+ traverse(child, node, visitor);
81
+ }
82
+ }
83
+ visitor.leaveNode(node, parent);
84
+ }
85
+ /**
86
+ * Traverse the given AST tree.
87
+ * @param node Root node to traverse.
88
+ * @param visitor Visitor.
89
+ */
90
+ function traverseNodes(node, visitor) {
91
+ traverse(node, null, visitor);
92
+ }
93
+ exports.traverseNodes = traverseNodes;
@@ -0,0 +1,2 @@
1
+ import type { SourceCode } from "eslint";
2
+ export declare const KEYS: SourceCode.VisitorKeys;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.KEYS = void 0;
4
+ const eslint_visitor_keys_1 = require("eslint-visitor-keys");
5
+ const astroKeys = {
6
+ Program: ["body"],
7
+ AstroRootFragment: ["children"],
8
+ AstroHTMLComment: [],
9
+ AstroDoctype: [],
10
+ AstroShorthandAttribute: ["name", "value"],
11
+ AstroTemplateLiteralAttribute: ["name", "value"],
12
+ };
13
+ exports.KEYS = (0, eslint_visitor_keys_1.unionWith)(astroKeys);
package/package.json ADDED
@@ -0,0 +1,91 @@
1
+ {
2
+ "name": "astro-eslint-parser",
3
+ "version": "0.0.0",
4
+ "description": "Astro parser for ESLint",
5
+ "main": "lib/index.js",
6
+ "files": [
7
+ "lib"
8
+ ],
9
+ "engines": {
10
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
11
+ },
12
+ "scripts": {
13
+ "prebuild": "npm run -s clean",
14
+ "build": "tsc --project ./tsconfig.build.json",
15
+ "clean": "rimraf .nyc_output lib coverage",
16
+ "lint": "eslint . --ext .js,.ts,.json",
17
+ "eslint-fix": "npm run lint -- --fix",
18
+ "test": "mocha --require ts-node/register \"tests/src/**/*.ts\" --reporter dot --timeout 60000",
19
+ "cover": "nyc --reporter=lcov npm run test",
20
+ "debug": "mocha --require ts-node/register/transpile-only \"tests/src/**/*.ts\" --reporter dot --timeout 60000",
21
+ "preversion": "npm run lint && npm test",
22
+ "update-fixtures": "ts-node --transpile-only ./tools/update-fixtures.ts",
23
+ "eslint-playground": "eslint tests/fixtures --ext .astro --config .eslintrc-for-playground.js --format codeframe",
24
+ "benchmark": "ts-node --transpile-only benchmark/index.ts"
25
+ },
26
+ "repository": {
27
+ "type": "git",
28
+ "url": "git+https://github.com/ota-meshi/astro-eslint-parser.git"
29
+ },
30
+ "keywords": [
31
+ "astro",
32
+ "astrojs",
33
+ "eslint",
34
+ "parser"
35
+ ],
36
+ "author": "Yosuke Ota",
37
+ "funding": "https://github.com/sponsors/ota-meshi",
38
+ "license": "MIT",
39
+ "bugs": {
40
+ "url": "https://github.com/ota-meshi/astro-eslint-parser/issues"
41
+ },
42
+ "homepage": "https://github.com/ota-meshi/astro-eslint-parser#readme",
43
+ "dependencies": {
44
+ "@astrojs/compiler": "^0.14.2",
45
+ "debug": "^4.3.4",
46
+ "eslint-scope": "^7.0.0",
47
+ "eslint-visitor-keys": "^3.0.0",
48
+ "espree": "^9.0.0"
49
+ },
50
+ "devDependencies": {
51
+ "@ota-meshi/eslint-plugin": "^0.10.0",
52
+ "@types/benchmark": "^2.1.1",
53
+ "@types/chai": "^4.3.0",
54
+ "@types/debug": "^4.1.7",
55
+ "@types/eslint": "^8.0.0",
56
+ "@types/eslint-scope": "^3.7.0",
57
+ "@types/eslint-visitor-keys": "^1.0.0",
58
+ "@types/mocha": "^9.0.0",
59
+ "@types/node": "^16.0.0",
60
+ "@types/semver": "^7.3.9",
61
+ "@typescript-eslint/eslint-plugin": "^5.4.0",
62
+ "@typescript-eslint/parser": "^5.4.0",
63
+ "benchmark": "^2.1.4",
64
+ "chai": "^4.3.4",
65
+ "code-red": "^0.2.3",
66
+ "eslint": "^8.2.0",
67
+ "eslint-config-prettier": "^8.3.0",
68
+ "eslint-formatter-codeframe": "^7.32.1",
69
+ "eslint-plugin-eslint-comments": "^3.2.0",
70
+ "eslint-plugin-json-schema-validator": "^2.1.6",
71
+ "eslint-plugin-jsonc": "^2.0.0",
72
+ "eslint-plugin-node": "^11.1.0",
73
+ "eslint-plugin-node-dependencies": "^0.8.0",
74
+ "eslint-plugin-prettier": "^4.0.0",
75
+ "eslint-plugin-regexp": "^1.5.0",
76
+ "eslint-plugin-vue": "^8.0.3",
77
+ "estree-walker": "^3.0.0",
78
+ "locate-character": "^2.0.5",
79
+ "magic-string": "^0.26.0",
80
+ "mocha": "^9.1.3",
81
+ "mocha-chai-jest-snapshot": "^1.1.3",
82
+ "nyc": "^15.1.0",
83
+ "prettier": "^2.0.5",
84
+ "prettier-plugin-astro": "^0.0.12",
85
+ "semver": "^7.3.5",
86
+ "string-replace-loader": "^3.0.3",
87
+ "ts-node": "^10.4.0",
88
+ "typescript": "~4.6.0",
89
+ "vue-eslint-parser": "^8.0.1"
90
+ }
91
+ }