Skip to content

Commit

Permalink
Fix Angular ESLint v13 (#22)
Browse files Browse the repository at this point in the history
* Fix running this rule on Angular ESLint 13.
* Fix CI.
  • Loading branch information
jerone committed Apr 17, 2024
1 parent ed457fe commit 68ed448
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 12 deletions.
1 change: 1 addition & 0 deletions .cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"jerone",
"lcov",
"postpack",
"rimraf",
"SARIF",
"Snyk",
"sonarcloud",
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v3
- uses: actions/setup-node@v4
- run: npm ci --no-fund
- run: npm run lint

Expand Down Expand Up @@ -45,18 +45,18 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Setup Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: "npm"
# Cannot use `npm ci`, because this package uses ESLint plugins,
# which conflict with the different installations below.
# Also the package-lock file is to new for npm on older NodeJS versions.
# Also the package-lock file is too new for npm on older NodeJS versions.
- name: Install packages
run: npm install rimraf typescript jest jest-junit ts-jest
run: npm install rimraf typescript jest jest-junit ts-jest semver @types/semver
- name: Install Angular ESLint ${{ matrix.angular-eslint-version[0] }}
run: |
npm install \
npm install --legacy-peer-deps \
@angular-eslint/template-parser@${{ matrix.angular-eslint-version[0] }} \
@angular-eslint/utils@${{ matrix.angular-eslint-version[0] }} \
@angular/compiler@${{ matrix.angular-eslint-version[0] }} \
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"jest-junit": "16.0.0",
"lockfile-lint": "4.12.1",
"rimraf": "5.0.1",
"semver": "7.5.4",
"semver": "7.6.0",
"ts-jest": "29.1.1",
"typescript": "5.1.6"
},
Expand Down
64 changes: 64 additions & 0 deletions src/lib/external/ensure-template-parser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// The method `ensureTemplateParser` is exported since ESLint Angular v14.4.0.
// Any version before that requires the fallback.
// See https://github.com/angular-eslint/angular-eslint/issues/888
// Copied from https://github.com/angular-eslint/angular-eslint/blob/025ad9df4006ccd482b85df93ef52a0d5ebfa29d/packages/utils/src/eslint-plugin-template/parser-services.ts#L28-L45
// Use `import { ensureTemplateParser } from "@angular-eslint/utils";` once ESLint Angular < v14.4.0 is dropped.

import type {
ParseSourceSpan,
TmplAstElement,
} from "@angular-eslint/bundled-angular-compiler";
import type { TSESLint, TSESTree } from "@typescript-eslint/utils";

export interface TemplateParserServices {
convertNodeSourceSpanToLoc: (
sourceSpan: ParseSourceSpan,
) => TSESTree.SourceLocation;
convertElementSourceSpanToLoc: (
context: Readonly<TSESLint.RuleContext<string, ReadonlyArray<unknown>>>,
node: TmplAstElement,
) => TSESTree.SourceLocation;
}

/**
* Utility for rule authors to ensure that their rule is correctly being used with @angular-eslint/template-parser
* If @angular-eslint/template-parser is not the configured parser when the function is invoked it will throw
*/
export function ensureTemplateParser(
context: Readonly<TSESLint.RuleContext<string, ReadonlyArray<unknown>>>,
): void {
try {
import("@angular-eslint/utils")
.then(({ default: utils }) => {
try {
utils.ensureTemplateParser(context);
} catch {
ensureTemplateParserFallback(context);
}
})
.catch(() => {
ensureTemplateParserFallback(context);
});
} catch {
ensureTemplateParserFallback(context);
}
}

function ensureTemplateParserFallback(
context: Readonly<TSESLint.RuleContext<string, ReadonlyArray<unknown>>>,
): void {
if (
!(context.parserServices as unknown as TemplateParserServices)
?.convertNodeSourceSpanToLoc ||
!(context.parserServices as unknown as TemplateParserServices)
?.convertElementSourceSpanToLoc
) {
/**
* The user needs to have configured "parser" in their eslint config and set it
* to @angular-eslint/template-parser
*/
throw new Error(
"You have used a rule which requires '@angular-eslint/template-parser' to be used as the 'parser' in your ESLint config.",
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import type {
TmplAstVariable,
PropertyRead,
} from "@angular-eslint/bundled-angular-compiler";
import { ensureTemplateParser } from "@angular-eslint/utils";
import type { TSESLint, TSESTree } from "@typescript-eslint/utils";
import { MESSAGE_IDS } from "../message-ids";
import type { MessageIds, AstWithParent, RuleOptions } from "../types";
import Utils from "../utils";
import { ensureTemplateParser } from "../external/ensure-template-parser";

export const RULE_NAME = "eslint-plugin-angular-template-consistent-this";

Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@
"compilerOptions": {
"sourceMap": true
},
"include": ["src", "tests"]
"include": ["src", "tests", "./typings.d.ts"]
}
8 changes: 8 additions & 0 deletions typings.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import type { TSESLint } from "@typescript-eslint/utils";

// See explanation in `./src/lib/external/ensure-template-parser.ts` why this typing is needed.
declare module "@angular-eslint/utils" {
export function ensureTemplateParser(
context: Readonly<TSESLint.RuleContext<string, ReadonlyArray<unknown>>>,
): void;
}

0 comments on commit 68ed448

Please sign in to comment.