Workaround/document edge case where node can't be found by token

This commit is contained in:
Yury Bondarenko
2024-03-21 10:33:13 +01:00
parent 6e22b5376a
commit 568574585b
2 changed files with 66 additions and 5 deletions

View File

@@ -335,6 +335,69 @@ cy.get('ds-themeable');
cy.get('#test > ds-themeable > #nest');
`,
},
{
name: 'edge case: unable to find usage node through usage token, but import is still flagged and fixed',
code: `
import { Component } from '@angular/core';
import { Context } from '../../core/shared/context.model';
import { TestThemeableComponent } from '../test/test-themeable.component.ts';
@Component({
selector: 'ds-admin-search-page',
templateUrl: './admin-search-page.component.html',
styleUrls: ['./admin-search-page.component.scss'],
standalone: true,
imports: [
TestThemeableComponent
],
})
/**
* Component that represents a search page for administrators
*/
export class AdminSearchPageComponent {
/**
* The context of this page
*/
context: Context = Context.AdminSearch;
}
`,
errors: [
{
messageId: Message.WRONG_IMPORT,
},
{
messageId: Message.WRONG_CLASS,
},
],
output: `
import { Component } from '@angular/core';
import { Context } from '../../core/shared/context.model';
import { ThemedTestThemeableComponent } from '../test/themed-test-themeable.component.ts';
@Component({
selector: 'ds-admin-search-page',
templateUrl: './admin-search-page.component.html',
styleUrls: ['./admin-search-page.component.scss'],
standalone: true,
imports: [
ThemedTestThemeableComponent
],
})
/**
* Component that represents a search page for administrators
*/
export class AdminSearchPageComponent {
/**
* The context of this page
*/
context: Context = Context.AdminSearch;
}
`,
},
],
};

View File

@@ -54,6 +54,7 @@ export function findUsages(context: AnyRuleContext, localNode: TSESTree.Identifi
for (const token of source.ast.tokens) {
if (token.type === 'Identifier' && token.value === localNode.name && !match(token.range, localNode.range)) {
const node = source.getNodeByRangeIndex(token.range[0]);
// todo: in some cases, the resulting node can actually be the whole program (!)
if (node !== null) {
usages.push(node as TSESTree.Identifier);
}
@@ -64,12 +65,9 @@ export function findUsages(context: AnyRuleContext, localNode: TSESTree.Identifi
}
export function isPartOfTypeExpression(node: TSESTree.Identifier): boolean {
return node.parent.type.startsWith('TSType');
return node.parent?.type?.startsWith('TSType');
}
export function isPartOfClassDeclaration(node: TSESTree.Identifier): boolean {
if (node.parent === undefined) {
return false;
}
return node.parent.type === 'ClassDeclaration';
return node.parent?.type === 'ClassDeclaration';
}