@ms-cloudpack/eslint-plugin-deprecated 0.1.1 → 0.1.3

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,20 @@
1
+ /**
2
+ * Heavily modified from https://github.com/cartant/eslint-etc/blob/main/source/from-fixture.ts
3
+ * for no-deprecated rule tests.
4
+ */
5
+ import type { InvalidTestCase } from '@typescript-eslint/rule-tester';
6
+ /**
7
+ * Convert a string with marker comment to an invalid test case.
8
+ * ```
9
+ * let a: DeprecatedInterface;
10
+ * ~~~~~~~~~~~~~~~~~~~
11
+ * ```
12
+ */
13
+ export declare function createInvalidCases<MessageIds extends string, TData extends Readonly<Record<string, unknown>>>(cases: Omit<InvalidTestCase<MessageIds, never>, 'code' | 'errors'> & {
14
+ code: string;
15
+ errors: {
16
+ messageId: MessageIds;
17
+ data?: TData;
18
+ }[];
19
+ }[]): InvalidTestCase<MessageIds, never>[];
20
+ //# sourceMappingURL=createInvalidCases.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createInvalidCases.d.ts","sourceRoot":"","sources":["../../src/__fixtures__/createInvalidCases.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,gCAAgC,CAAC;AAIrF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,SAAS,MAAM,EAAE,KAAK,SAAS,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,EAC3G,KAAK,EAAE,IAAI,CAAC,eAAe,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC,GAChE;IACE,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE;QAAE,SAAS,EAAE,UAAU,CAAC;QAAC,IAAI,CAAC,EAAE,KAAK,CAAA;KAAE,EAAE,CAAC;CACnD,EAAE,GACJ,eAAe,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,CAuBtC"}
@@ -0,0 +1,32 @@
1
+ const markerRegexp = /^(?<indent>\s*)(?<marker>~+)$/;
2
+ /**
3
+ * Convert a string with marker comment to an invalid test case.
4
+ * ```
5
+ * let a: DeprecatedInterface;
6
+ * ~~~~~~~~~~~~~~~~~~~
7
+ * ```
8
+ */
9
+ export function createInvalidCases(cases) {
10
+ return cases.map(({ code, errors: partialErrors, ...testCase }) => {
11
+ const lines = [];
12
+ const errors = [];
13
+ for (const line of code.split('\n')) {
14
+ const match = line.match(markerRegexp);
15
+ if (match?.groups) {
16
+ const error = partialErrors[errors.length];
17
+ if (!error) {
18
+ throw new Error('More marker comments found than expected');
19
+ }
20
+ const column = match.groups.indent.length + 1;
21
+ const endColumn = column + match.groups.marker.length;
22
+ const lineNum = lines.length;
23
+ errors.push({ ...error, line: lineNum, column, endLine: lineNum, endColumn });
24
+ }
25
+ else {
26
+ lines.push(line);
27
+ }
28
+ }
29
+ return { code: lines.join('\n'), errors, ...testCase };
30
+ });
31
+ }
32
+ //# sourceMappingURL=createInvalidCases.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createInvalidCases.js","sourceRoot":"","sources":["../../src/__fixtures__/createInvalidCases.ts"],"names":[],"mappings":"AAMA,MAAM,YAAY,GAAG,+BAA+B,CAAC;AAErD;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAChC,KAIK;IAEL,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,GAAG,QAAQ,EAAE,EAAE,EAAE;QAChE,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAgC,EAAE,CAAC;QAE/C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YACvC,IAAI,KAAK,EAAE,MAAM,EAAE,CAAC;gBAClB,MAAM,KAAK,GAAG,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC3C,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;gBAC9D,CAAC;gBACD,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;gBAC9C,MAAM,SAAS,GAAG,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;gBACtD,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC;gBAC7B,MAAM,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,CAAC,CAAC;YAChF,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,QAAQ,EAAE,CAAC;IACzD,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["/**\n * Heavily modified from https://github.com/cartant/eslint-etc/blob/main/source/from-fixture.ts\n * for no-deprecated rule tests.\n */\nimport type { InvalidTestCase, TestCaseError } from '@typescript-eslint/rule-tester';\n\nconst markerRegexp = /^(?<indent>\\s*)(?<marker>~+)$/;\n\n/**\n * Convert a string with marker comment to an invalid test case.\n * ```\n * let a: DeprecatedInterface;\n * ~~~~~~~~~~~~~~~~~~~\n * ```\n */\nexport function createInvalidCases<MessageIds extends string, TData extends Readonly<Record<string, unknown>>>(\n cases: Omit<InvalidTestCase<MessageIds, never>, 'code' | 'errors'> &\n {\n code: string;\n errors: { messageId: MessageIds; data?: TData }[];\n }[],\n): InvalidTestCase<MessageIds, never>[] {\n return cases.map(({ code, errors: partialErrors, ...testCase }) => {\n const lines: string[] = [];\n const errors: TestCaseError<MessageIds>[] = [];\n\n for (const line of code.split('\\n')) {\n const match = line.match(markerRegexp);\n if (match?.groups) {\n const error = partialErrors[errors.length];\n if (!error) {\n throw new Error('More marker comments found than expected');\n }\n const column = match.groups.indent.length + 1;\n const endColumn = column + match.groups.marker.length;\n const lineNum = lines.length;\n errors.push({ ...error, line: lineNum, column, endLine: lineNum, endColumn });\n } else {\n lines.push(line);\n }\n }\n\n return { code: lines.join('\\n'), errors, ...testCase };\n });\n}\n"]}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Copied from https://github.com/cartant/eslint-plugin-etc/blob/main/tests/modules/deprecated.ts
3
+ * due to lack of updates for new dependency versions.
4
+ */
5
+ /** */
6
+ export interface NotDeprecatedInterface {
7
+ notDeprecatedProperty: string;
8
+ notDeprecatedMethod(): void;
9
+ }
10
+ export type NotDeprecatedType = {
11
+ notDeprecatedProperty: string;
12
+ notDeprecatedMethod(): void;
13
+ };
14
+ export declare class NotDeprecatedClass {
15
+ static notDeprecatedStaticMethod(): void;
16
+ notDeprecatedProperty: string;
17
+ get notDeprecatedGetter(): string;
18
+ set notDeprecatedSetter(value: string);
19
+ notDeprecatedMethod(): void;
20
+ }
21
+ export declare enum NotDeprecatedEnum {
22
+ NotDeprecatedMember = 1
23
+ }
24
+ export declare const notDeprecatedVariable: {};
25
+ export declare function notDeprecatedFunction(): void;
26
+ /** @deprecated Don't use this */
27
+ export interface DeprecatedInterface {
28
+ notDeprecatedProperty: string;
29
+ notDeprecatedMethod(): void;
30
+ }
31
+ /** @deprecated Don't use this */
32
+ export type DeprecatedType = {
33
+ notDeprecatedProperty: string;
34
+ notDeprecatedMethod(): void;
35
+ };
36
+ /** @deprecated Don't use this */
37
+ export declare class DeprecatedClass {
38
+ static notDeprecatedStaticMethod(): void;
39
+ notDeprecatedProperty: string;
40
+ get notDeprecatedGetter(): string;
41
+ set notDeprecatedSetter(value: string);
42
+ notDeprecatedMethod(): void;
43
+ }
44
+ /** @deprecated Don't use this */
45
+ export declare enum DeprecatedEnum {
46
+ NotDeprecatedMember = 1
47
+ }
48
+ /** @deprecated Don't use this */
49
+ export declare const deprecatedVariable: {};
50
+ /** @deprecated Don't use this */
51
+ export declare function deprecatedFunction(): void;
52
+ export interface SomeDeprecatedInterface {
53
+ /** @deprecated Don't use this */
54
+ deprecatedProperty: string;
55
+ notDeprecatedProperty: string;
56
+ /** @deprecated Don't use this */
57
+ deprecatedMethod(): void;
58
+ notDeprecatedMethod(): void;
59
+ }
60
+ export type SomeDeprecatedType = {
61
+ /** @deprecated Don't use this */
62
+ deprecatedProperty: string;
63
+ notDeprecatedProperty: string;
64
+ /** @deprecated Don't use this */
65
+ deprecatedMethod(): void;
66
+ notDeprecatedMethod(): void;
67
+ };
68
+ export declare class SomeDeprecatedClass {
69
+ /** @deprecated Don't use this */
70
+ static deprecatedStaticMethod(): void;
71
+ static notDeprecatedStaticMethod(): void;
72
+ /** @deprecated Don't use this */
73
+ deprecatedProperty: string;
74
+ notDeprecatedProperty: string;
75
+ /** @deprecated Don't use this */
76
+ get deprecatedGetter(): string;
77
+ get notDeprecatedGetter(): string;
78
+ /** @deprecated Don't use this */
79
+ set deprecatedSetter(value: string);
80
+ set notDeprecatedSetter(value: string);
81
+ /** @deprecated Don't use this */
82
+ deprecatedMethod(): void;
83
+ notDeprecatedMethod(): void;
84
+ }
85
+ export declare enum SomeDeprecatedEnum {
86
+ /** @deprecated Don't use this */
87
+ DeprecatedMember = 1,
88
+ NotDeprecatedMember = 2
89
+ }
90
+ export declare class DeprecatedSignatureClass {
91
+ static deprecatedSignatureStaticMethod(value: number): void;
92
+ /** @deprecated Don't use this */
93
+ static deprecatedSignatureStaticMethod(value: string): void;
94
+ deprecatedSignatureMethod(value: number): void;
95
+ /** @deprecated Don't use this */
96
+ deprecatedSignatureMethod(value: string): void;
97
+ }
98
+ export declare function deprecatedSignatureFunction(value: number): void;
99
+ /** @deprecated Don't use this */
100
+ export declare function deprecatedSignatureFunction(value: string): void;
101
+ export declare class DeprecatedConstructorClass {
102
+ /** @deprecated Don't use this */
103
+ constructor();
104
+ }
105
+ export declare class DeprecatedConstructorSignatureClass {
106
+ constructor(value: number);
107
+ /** @deprecated Don't use this */
108
+ constructor(value: string);
109
+ }
110
+ //# sourceMappingURL=deprecated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deprecated.d.ts","sourceRoot":"","sources":["../../src/__fixtures__/deprecated.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Copied from https://github.com/cartant/eslint-plugin-etc/blob/main/tests/modules/deprecated.ts
3
+ * due to lack of updates for new dependency versions.
4
+ */
5
+ /** */
6
+ export class NotDeprecatedClass {
7
+ static notDeprecatedStaticMethod() { }
8
+ notDeprecatedProperty = '';
9
+ get notDeprecatedGetter() {
10
+ return '';
11
+ }
12
+ set notDeprecatedSetter(value) { }
13
+ notDeprecatedMethod() { }
14
+ }
15
+ // Note: this gets an editor diagnostics error, but is correct at actual build time
16
+ // @ts-expect-error -- not valid with erasable syntax, but fine for a test fixture
17
+ export var NotDeprecatedEnum;
18
+ (function (NotDeprecatedEnum) {
19
+ NotDeprecatedEnum[NotDeprecatedEnum["NotDeprecatedMember"] = 1] = "NotDeprecatedMember";
20
+ })(NotDeprecatedEnum || (NotDeprecatedEnum = {}));
21
+ export const notDeprecatedVariable = {};
22
+ export function notDeprecatedFunction() { }
23
+ /** @deprecated Don't use this */
24
+ export class DeprecatedClass {
25
+ static notDeprecatedStaticMethod() { }
26
+ notDeprecatedProperty = '';
27
+ get notDeprecatedGetter() {
28
+ return '';
29
+ }
30
+ set notDeprecatedSetter(value) { }
31
+ notDeprecatedMethod() { }
32
+ }
33
+ /** @deprecated Don't use this */
34
+ // @ts-expect-error -- not valid with erasable syntax, but fine for a test fixture
35
+ export var DeprecatedEnum;
36
+ (function (DeprecatedEnum) {
37
+ DeprecatedEnum[DeprecatedEnum["NotDeprecatedMember"] = 1] = "NotDeprecatedMember";
38
+ })(DeprecatedEnum || (DeprecatedEnum = {}));
39
+ /** @deprecated Don't use this */
40
+ export const deprecatedVariable = {};
41
+ /** @deprecated Don't use this */
42
+ export function deprecatedFunction() { }
43
+ export class SomeDeprecatedClass {
44
+ /** @deprecated Don't use this */
45
+ static deprecatedStaticMethod() { }
46
+ static notDeprecatedStaticMethod() { }
47
+ /** @deprecated Don't use this */
48
+ deprecatedProperty = '';
49
+ notDeprecatedProperty = '';
50
+ /** @deprecated Don't use this */
51
+ get deprecatedGetter() {
52
+ return '';
53
+ }
54
+ get notDeprecatedGetter() {
55
+ return '';
56
+ }
57
+ /** @deprecated Don't use this */
58
+ set deprecatedSetter(value) { }
59
+ set notDeprecatedSetter(value) { }
60
+ /** @deprecated Don't use this */
61
+ deprecatedMethod() { }
62
+ notDeprecatedMethod() { }
63
+ }
64
+ // @ts-expect-error -- not valid with erasable syntax, but fine for a test fixture
65
+ export var SomeDeprecatedEnum;
66
+ (function (SomeDeprecatedEnum) {
67
+ /** @deprecated Don't use this */
68
+ SomeDeprecatedEnum[SomeDeprecatedEnum["DeprecatedMember"] = 1] = "DeprecatedMember";
69
+ SomeDeprecatedEnum[SomeDeprecatedEnum["NotDeprecatedMember"] = 2] = "NotDeprecatedMember";
70
+ })(SomeDeprecatedEnum || (SomeDeprecatedEnum = {}));
71
+ // Some deprecated signatures
72
+ export class DeprecatedSignatureClass {
73
+ static deprecatedSignatureStaticMethod(_value) { }
74
+ deprecatedSignatureMethod(_value) { }
75
+ }
76
+ export function deprecatedSignatureFunction(_value) { }
77
+ // Deprecated constructor
78
+ export class DeprecatedConstructorClass {
79
+ /** @deprecated Don't use this */
80
+ constructor() { }
81
+ }
82
+ export class DeprecatedConstructorSignatureClass {
83
+ constructor(_value) { }
84
+ }
85
+ //# sourceMappingURL=deprecated.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deprecated.js","sourceRoot":"","sources":["../../src/__fixtures__/deprecated.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM;AAYN,MAAM,OAAO,kBAAkB;IAC7B,MAAM,CAAC,yBAAyB,KAAU,CAAC;IAC3C,qBAAqB,GAAW,EAAE,CAAC;IACnC,IAAI,mBAAmB;QACrB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,mBAAmB,CAAC,KAAa,IAAG,CAAC;IACzC,mBAAmB,KAAU,CAAC;CAC/B;AAED,mFAAmF;AACnF,kFAAkF;AAClF,MAAM,CAAN,IAAY,iBAEX;AAFD,WAAY,iBAAiB;IAC3B,uFAAuB,CAAA;AACzB,CAAC,EAFW,iBAAiB,KAAjB,iBAAiB,QAE5B;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC;AAExC,MAAM,UAAU,qBAAqB,KAAU,CAAC;AAgBhD,iCAAiC;AACjC,MAAM,OAAO,eAAe;IAC1B,MAAM,CAAC,yBAAyB,KAAU,CAAC;IAC3C,qBAAqB,GAAW,EAAE,CAAC;IACnC,IAAI,mBAAmB;QACrB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,mBAAmB,CAAC,KAAa,IAAG,CAAC;IACzC,mBAAmB,KAAU,CAAC;CAC/B;AAED,iCAAiC;AACjC,kFAAkF;AAClF,MAAM,CAAN,IAAY,cAEX;AAFD,WAAY,cAAc;IACxB,iFAAuB,CAAA;AACzB,CAAC,EAFW,cAAc,KAAd,cAAc,QAEzB;AAED,iCAAiC;AACjC,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAErC,iCAAiC;AACjC,MAAM,UAAU,kBAAkB,KAAU,CAAC;AAsB7C,MAAM,OAAO,mBAAmB;IAC9B,iCAAiC;IACjC,MAAM,CAAC,sBAAsB,KAAU,CAAC;IACxC,MAAM,CAAC,yBAAyB,KAAU,CAAC;IAC3C,iCAAiC;IACjC,kBAAkB,GAAW,EAAE,CAAC;IAChC,qBAAqB,GAAW,EAAE,CAAC;IACnC,iCAAiC;IACjC,IAAI,gBAAgB;QAClB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,mBAAmB;QACrB,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,iCAAiC;IACjC,IAAI,gBAAgB,CAAC,KAAa,IAAG,CAAC;IACtC,IAAI,mBAAmB,CAAC,KAAa,IAAG,CAAC;IACzC,iCAAiC;IACjC,gBAAgB,KAAU,CAAC;IAC3B,mBAAmB,KAAU,CAAC;CAC/B;AAED,kFAAkF;AAClF,MAAM,CAAN,IAAY,kBAIX;AAJD,WAAY,kBAAkB;IAC5B,iCAAiC;IACjC,mFAAoB,CAAA;IACpB,yFAAuB,CAAA;AACzB,CAAC,EAJW,kBAAkB,KAAlB,kBAAkB,QAI7B;AAED,6BAA6B;AAE7B,MAAM,OAAO,wBAAwB;IAInC,MAAM,CAAC,+BAA+B,CAAC,MAAe,IAAS,CAAC;IAIhE,yBAAyB,CAAC,MAAe,IAAS,CAAC;CACpD;AAKD,MAAM,UAAU,2BAA2B,CAAC,MAAe,IAAS,CAAC;AAErE,yBAAyB;AAEzB,MAAM,OAAO,0BAA0B;IACrC,iCAAiC;IACjC,gBAAe,CAAC;CACjB;AAED,MAAM,OAAO,mCAAmC;IAI9C,YAAY,MAAe,IAAG,CAAC;CAChC","sourcesContent":["/**\n * Copied from https://github.com/cartant/eslint-plugin-etc/blob/main/tests/modules/deprecated.ts\n * due to lack of updates for new dependency versions.\n */\n/** */\n\nexport interface NotDeprecatedInterface {\n notDeprecatedProperty: string;\n notDeprecatedMethod(): void;\n}\n\nexport type NotDeprecatedType = {\n notDeprecatedProperty: string;\n notDeprecatedMethod(): void;\n};\n\nexport class NotDeprecatedClass {\n static notDeprecatedStaticMethod(): void {}\n notDeprecatedProperty: string = '';\n get notDeprecatedGetter(): string {\n return '';\n }\n set notDeprecatedSetter(value: string) {}\n notDeprecatedMethod(): void {}\n}\n\n// Note: this gets an editor diagnostics error, but is correct at actual build time\n// @ts-expect-error -- not valid with erasable syntax, but fine for a test fixture\nexport enum NotDeprecatedEnum {\n NotDeprecatedMember = 1,\n}\n\nexport const notDeprecatedVariable = {};\n\nexport function notDeprecatedFunction(): void {}\n\n// Deprecated\n\n/** @deprecated Don't use this */\nexport interface DeprecatedInterface {\n notDeprecatedProperty: string;\n notDeprecatedMethod(): void;\n}\n\n/** @deprecated Don't use this */\nexport type DeprecatedType = {\n notDeprecatedProperty: string;\n notDeprecatedMethod(): void;\n};\n\n/** @deprecated Don't use this */\nexport class DeprecatedClass {\n static notDeprecatedStaticMethod(): void {}\n notDeprecatedProperty: string = '';\n get notDeprecatedGetter(): string {\n return '';\n }\n set notDeprecatedSetter(value: string) {}\n notDeprecatedMethod(): void {}\n}\n\n/** @deprecated Don't use this */\n// @ts-expect-error -- not valid with erasable syntax, but fine for a test fixture\nexport enum DeprecatedEnum {\n NotDeprecatedMember = 1,\n}\n\n/** @deprecated Don't use this */\nexport const deprecatedVariable = {};\n\n/** @deprecated Don't use this */\nexport function deprecatedFunction(): void {}\n\n// Some proeprties/methods deprecated\n\nexport interface SomeDeprecatedInterface {\n /** @deprecated Don't use this */\n deprecatedProperty: string;\n notDeprecatedProperty: string;\n /** @deprecated Don't use this */\n deprecatedMethod(): void;\n notDeprecatedMethod(): void;\n}\n\nexport type SomeDeprecatedType = {\n /** @deprecated Don't use this */\n deprecatedProperty: string;\n notDeprecatedProperty: string;\n /** @deprecated Don't use this */\n deprecatedMethod(): void;\n notDeprecatedMethod(): void;\n};\n\nexport class SomeDeprecatedClass {\n /** @deprecated Don't use this */\n static deprecatedStaticMethod(): void {}\n static notDeprecatedStaticMethod(): void {}\n /** @deprecated Don't use this */\n deprecatedProperty: string = '';\n notDeprecatedProperty: string = '';\n /** @deprecated Don't use this */\n get deprecatedGetter(): string {\n return '';\n }\n get notDeprecatedGetter(): string {\n return '';\n }\n /** @deprecated Don't use this */\n set deprecatedSetter(value: string) {}\n set notDeprecatedSetter(value: string) {}\n /** @deprecated Don't use this */\n deprecatedMethod(): void {}\n notDeprecatedMethod(): void {}\n}\n\n// @ts-expect-error -- not valid with erasable syntax, but fine for a test fixture\nexport enum SomeDeprecatedEnum {\n /** @deprecated Don't use this */\n DeprecatedMember = 1,\n NotDeprecatedMember = 2,\n}\n\n// Some deprecated signatures\n\nexport class DeprecatedSignatureClass {\n static deprecatedSignatureStaticMethod(value: number): void;\n /** @deprecated Don't use this */\n static deprecatedSignatureStaticMethod(value: string): void;\n static deprecatedSignatureStaticMethod(_value: unknown): void {}\n deprecatedSignatureMethod(value: number): void;\n /** @deprecated Don't use this */\n deprecatedSignatureMethod(value: string): void;\n deprecatedSignatureMethod(_value: unknown): void {}\n}\n\nexport function deprecatedSignatureFunction(value: number): void;\n/** @deprecated Don't use this */\nexport function deprecatedSignatureFunction(value: string): void;\nexport function deprecatedSignatureFunction(_value: unknown): void {}\n\n// Deprecated constructor\n\nexport class DeprecatedConstructorClass {\n /** @deprecated Don't use this */\n constructor() {}\n}\n\nexport class DeprecatedConstructorSignatureClass {\n constructor(value: number);\n /** @deprecated Don't use this */\n constructor(value: string);\n constructor(_value: unknown) {}\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.d.ts","sourceRoot":"","sources":["../../src/__fixtures__/file.ts"],"names":[],"mappings":""}
@@ -1 +1,3 @@
1
+ export {};
1
2
  // placeholder for tests (must exist on disk, but contents will be virtualized)
3
+ //# sourceMappingURL=file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file.js","sourceRoot":"","sources":["../../src/__fixtures__/file.ts"],"names":[],"mappings":";AAAA,+EAA+E","sourcesContent":["// placeholder for tests (must exist on disk, but contents will be virtualized)\n"]}
package/lib/index.d.ts ADDED
@@ -0,0 +1,22 @@
1
+ import type { TSESLint } from '@typescript-eslint/utils';
2
+ declare const plugin: {
3
+ meta: {
4
+ name: string;
5
+ version: string;
6
+ namespace: string;
7
+ };
8
+ configs: {
9
+ recommended: {
10
+ rules: {
11
+ '@ms-cloudpack/no-deprecated': "error";
12
+ };
13
+ };
14
+ };
15
+ rules: {
16
+ '@ms-cloudpack/no-deprecated': TSESLint.RuleModule<"forbidden", [({
17
+ ignoredSelectors?: string[];
18
+ } | undefined)?], unknown, TSESLint.RuleListener>;
19
+ };
20
+ };
21
+ export default plugin;
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAQzD,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;CAa0B,CAAC;AAEvC,eAAe,MAAM,CAAC"}
package/lib/index.js ADDED
@@ -0,0 +1,20 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ import noDeprecated from "./rules/no-deprecated.js";
4
+ const { name, version } = JSON.parse(fs.readFileSync(path.resolve(import.meta.dirname, '../package.json'), 'utf8'));
5
+ const plugin = {
6
+ meta: { name, version, namespace: '@ms-cloudpack' },
7
+ configs: {
8
+ recommended: {
9
+ rules: {
10
+ '@ms-cloudpack/no-deprecated': 'error',
11
+ },
12
+ },
13
+ },
14
+ rules: {
15
+ '@ms-cloudpack/no-deprecated': noDeprecated,
16
+ },
17
+ // Use `satisfies` to preserve the original property names
18
+ };
19
+ export default plugin;
20
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,YAAY,MAAM,0BAA0B,CAAC;AAEpD,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC,EAAE,MAAM,CAAC,CAGjH,CAAC;AAEF,MAAM,MAAM,GAAG;IACb,IAAI,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE;IACnD,OAAO,EAAE;QACP,WAAW,EAAE;YACX,KAAK,EAAE;gBACL,6BAA6B,EAAE,OAAO;aACvC;SACF;KACF;IACD,KAAK,EAAE;QACL,6BAA6B,EAAE,YAAY;KAC5C;IACD,0DAA0D;CACtB,CAAC;AAEvC,eAAe,MAAM,CAAC","sourcesContent":["import fs from 'fs';\nimport path from 'path';\nimport type { TSESLint } from '@typescript-eslint/utils';\nimport noDeprecated from './rules/no-deprecated.ts';\n\nconst { name, version } = JSON.parse(fs.readFileSync(path.resolve(import.meta.dirname, '../package.json'), 'utf8')) as {\n name: string;\n version: string;\n};\n\nconst plugin = {\n meta: { name, version, namespace: '@ms-cloudpack' },\n configs: {\n recommended: {\n rules: {\n '@ms-cloudpack/no-deprecated': 'error',\n },\n },\n },\n rules: {\n '@ms-cloudpack/no-deprecated': noDeprecated,\n },\n // Use `satisfies` to preserve the original property names\n} satisfies TSESLint.FlatConfig.Plugin;\n\nexport default plugin;\n"]}
@@ -0,0 +1,41 @@
1
+ import type { TSESLint } from '@typescript-eslint/utils';
2
+ export type MessageIds = 'forbidden';
3
+ export type MessageData = {
4
+ name: string;
5
+ comment: string;
6
+ };
7
+ type Options = {
8
+ ignoredSelectors?: string[];
9
+ };
10
+ /**
11
+ * Copied from https://github.com/cartant/eslint-plugin-etc/blob/main/source/rules/no-deprecated.ts
12
+ * due to lack of updates for new dependency versions.
13
+ * Also added a new `ignoredSelectors` option.
14
+ *
15
+ * License for `eslint-plugin-etc` (excluding new `ignoredSelectors` option):
16
+ *
17
+ * MIT License
18
+ *
19
+ * Copyright (c) 2019-2021 Nicholas Jamieson and contributors
20
+ *
21
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
22
+ * of this software and associated documentation files (the "Software"), to deal
23
+ * in the Software without restriction, including without limitation the rights
24
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
25
+ * copies of the Software, and to permit persons to whom the Software is
26
+ * furnished to do so, subject to the following conditions:
27
+ *
28
+ * The above copyright notice and this permission notice shall be included in all
29
+ * copies or substantial portions of the Software.
30
+ *
31
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
35
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
36
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
37
+ * SOFTWARE.
38
+ */
39
+ declare const rule: TSESLint.RuleModule<MessageIds, [Options?]>;
40
+ export default rule;
41
+ //# sourceMappingURL=no-deprecated.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-deprecated.d.ts","sourceRoot":"","sources":["../../src/rules/no-deprecated.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAMzD,MAAM,MAAM,UAAU,GAAG,WAAW,CAAC;AACrC,MAAM,MAAM,WAAW,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAC5D,KAAK,OAAO,GAAG;IAAE,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC;AAI/C;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,QAAA,MAAM,IAAI,EAAE,QAAQ,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC,OAAO,CAAC,CAAC,CA2ErD,CAAC;AAEF,eAAe,IAAI,CAAC"}
@@ -0,0 +1,241 @@
1
+ import { ESLintUtils } from '@typescript-eslint/utils';
2
+ import ts from 'typescript';
3
+ import { tsquery } from '@phenomnomnominal/tsquery';
4
+ import tsutils from 'tsutils';
5
+ const deprecatedNamesByProgram = new WeakMap();
6
+ /**
7
+ * Copied from https://github.com/cartant/eslint-plugin-etc/blob/main/source/rules/no-deprecated.ts
8
+ * due to lack of updates for new dependency versions.
9
+ * Also added a new `ignoredSelectors` option.
10
+ *
11
+ * License for `eslint-plugin-etc` (excluding new `ignoredSelectors` option):
12
+ *
13
+ * MIT License
14
+ *
15
+ * Copyright (c) 2019-2021 Nicholas Jamieson and contributors
16
+ *
17
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
18
+ * of this software and associated documentation files (the "Software"), to deal
19
+ * in the Software without restriction, including without limitation the rights
20
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
21
+ * copies of the Software, and to permit persons to whom the Software is
22
+ * furnished to do so, subject to the following conditions:
23
+ *
24
+ * The above copyright notice and this permission notice shall be included in all
25
+ * copies or substantial portions of the Software.
26
+ *
27
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
30
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
31
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
32
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
33
+ * SOFTWARE.
34
+ */
35
+ const rule = {
36
+ defaultOptions: [],
37
+ meta: {
38
+ docs: {
39
+ description: 'disallow the use of deprecated APIs',
40
+ },
41
+ messages: {
42
+ forbidden: `"{{name}}" is deprecated: {{comment}}`,
43
+ },
44
+ schema: [
45
+ {
46
+ properties: {
47
+ ignoredSelectors: {
48
+ description: 'Selectors for nodes to ignore',
49
+ type: 'array',
50
+ items: { type: 'string' },
51
+ },
52
+ },
53
+ type: 'object',
54
+ },
55
+ ],
56
+ defaultOptions: [{}],
57
+ type: 'problem',
58
+ },
59
+ create: (context) => {
60
+ const [{ ignoredSelectors } = {}] = context.options;
61
+ let ignoredNodes;
62
+ const { esTreeNodeToTSNodeMap, program } = ESLintUtils.getParserServices(context);
63
+ const typeChecker = program.getTypeChecker();
64
+ let deprecatedNames = deprecatedNamesByProgram.get(program);
65
+ if (!deprecatedNames) {
66
+ deprecatedNames = findTaggedNames('deprecated', program);
67
+ deprecatedNamesByProgram.set(program, deprecatedNames);
68
+ }
69
+ return {
70
+ Identifier: (node) => {
71
+ const parentType = node.parent?.type;
72
+ if (parentType === 'ExportSpecifier' ||
73
+ parentType === 'ImportDefaultSpecifier' ||
74
+ parentType === 'ImportNamespaceSpecifier' ||
75
+ parentType === 'ImportSpecifier') {
76
+ return;
77
+ }
78
+ const identifier = esTreeNodeToTSNodeMap.get(node);
79
+ if (!deprecatedNames.has(identifier.text) || isDeclaration(identifier)) {
80
+ return;
81
+ }
82
+ // NEW: check if this node matches any ignored selectors
83
+ if (ignoredSelectors?.length) {
84
+ ignoredNodes ??= tsquery(identifier.getSourceFile(), ignoredSelectors.join(', '));
85
+ if (ignoredNodes.includes(identifier)) {
86
+ return;
87
+ }
88
+ }
89
+ const tags = getTags('deprecated', identifier, typeChecker);
90
+ for (const tag of tags) {
91
+ context.report({
92
+ data: {
93
+ comment: tag.trim().replace(/\s+/g, ' '),
94
+ name: identifier.text,
95
+ },
96
+ messageId: 'forbidden',
97
+ node,
98
+ });
99
+ }
100
+ },
101
+ };
102
+ },
103
+ };
104
+ export default rule;
105
+ function isDeclaration(identifier) {
106
+ const parent = identifier.parent;
107
+ switch (parent.kind) {
108
+ case ts.SyntaxKind.ClassDeclaration:
109
+ case ts.SyntaxKind.ClassExpression:
110
+ case ts.SyntaxKind.InterfaceDeclaration:
111
+ case ts.SyntaxKind.TypeParameter:
112
+ case ts.SyntaxKind.FunctionExpression:
113
+ case ts.SyntaxKind.FunctionDeclaration:
114
+ case ts.SyntaxKind.LabeledStatement:
115
+ case ts.SyntaxKind.JsxAttribute:
116
+ case ts.SyntaxKind.MethodDeclaration:
117
+ case ts.SyntaxKind.MethodSignature:
118
+ case ts.SyntaxKind.PropertySignature:
119
+ case ts.SyntaxKind.TypeAliasDeclaration:
120
+ case ts.SyntaxKind.GetAccessor:
121
+ case ts.SyntaxKind.SetAccessor:
122
+ case ts.SyntaxKind.EnumDeclaration:
123
+ case ts.SyntaxKind.ModuleDeclaration:
124
+ return true;
125
+ case ts.SyntaxKind.VariableDeclaration:
126
+ case ts.SyntaxKind.Parameter:
127
+ case ts.SyntaxKind.PropertyDeclaration:
128
+ case ts.SyntaxKind.EnumMember:
129
+ case ts.SyntaxKind.ImportEqualsDeclaration:
130
+ return parent.name === identifier;
131
+ case ts.SyntaxKind.PropertyAssignment:
132
+ return (parent.name === identifier &&
133
+ !tsutils.isReassignmentTarget(identifier.parent.parent));
134
+ case ts.SyntaxKind.BindingElement:
135
+ // return true for `b` in `const {a: b} = obj`
136
+ return (parent.name === identifier && parent.propertyName !== undefined);
137
+ default:
138
+ return false;
139
+ }
140
+ }
141
+ /**
142
+ * Get all identifiers with jsdoc tag `@tagName` in the program.
143
+ */
144
+ function findTaggedNames(tagName, program) {
145
+ const taggedNames = new Set();
146
+ for (const sourceFile of program.getSourceFiles()) {
147
+ if (!sourceFile.text.includes(`@${tagName}`)) {
148
+ continue;
149
+ }
150
+ const nodes = tsquery(sourceFile, `ClassDeclaration, Constructor, EnumDeclaration, EnumMember, FunctionDeclaration, GetAccessor, ` +
151
+ `InterfaceDeclaration, MethodDeclaration, MethodSignature, PropertyDeclaration, PropertySignature, ` +
152
+ `SetAccessor, TypeAliasDeclaration, VariableDeclaration`);
153
+ for (const node of nodes) {
154
+ const tags = ts.getJSDocTags(node);
155
+ if (tags.some((tag) => tag.tagName.text === tagName)) {
156
+ const name = ts.isConstructorDeclaration(node)
157
+ ? node.parent.name
158
+ : node.name;
159
+ if (name?.text) {
160
+ taggedNames.add(name.text);
161
+ }
162
+ }
163
+ }
164
+ }
165
+ return taggedNames;
166
+ }
167
+ /**
168
+ * Get the text of all tags of `node`'s type matching `tagName`.
169
+ */
170
+ function getTags(tagName, node, tc) {
171
+ const callExpression = getCallExpression(node);
172
+ if (callExpression) {
173
+ const signature = tc.getResolvedSignature(callExpression);
174
+ const tags = signature && findTags(tagName, signature.getJsDocTags());
175
+ if (tags?.length) {
176
+ return tags;
177
+ }
178
+ }
179
+ let symbol;
180
+ const parent = node.parent;
181
+ if (parent.kind === ts.SyntaxKind.BindingElement) {
182
+ symbol = tc.getTypeAtLocation(parent.parent).getProperty(node.text);
183
+ }
184
+ else if ((tsutils.isPropertyAssignment(parent) && parent.name === node) ||
185
+ (tsutils.isShorthandPropertyAssignment(parent) && parent.name === node && tsutils.isReassignmentTarget(node))) {
186
+ symbol = tc.getPropertySymbolOfDestructuringAssignment(node);
187
+ }
188
+ else {
189
+ symbol = tc.getSymbolAtLocation(node);
190
+ }
191
+ if (symbol && tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias)) {
192
+ symbol = tc.getAliasedSymbol(symbol);
193
+ }
194
+ if (!symbol ||
195
+ // if this is a CallExpression and the declaration is a function or method,
196
+ // stop here to avoid collecting JsDoc of all overload signatures
197
+ (callExpression && isFunctionOrMethod(symbol.declarations))) {
198
+ return [];
199
+ }
200
+ return findTags(tagName, symbol.getJsDocTags());
201
+ }
202
+ /**
203
+ * Get the text of all `tags` matching `tagName`.
204
+ */
205
+ function findTags(tagName, tags) {
206
+ const result = [];
207
+ for (const tag of tags) {
208
+ if (tag.name === tagName) {
209
+ const { text = '' } = tag;
210
+ if (typeof text === 'string') {
211
+ result.push(text);
212
+ }
213
+ else {
214
+ result.push(text.reduce((t, part) => t + part.text, ''));
215
+ }
216
+ }
217
+ }
218
+ return result;
219
+ }
220
+ function getCallExpression(node) {
221
+ let parent = node.parent;
222
+ if (tsutils.isPropertyAccessExpression(parent) && parent.name === node) {
223
+ parent = parent.parent;
224
+ }
225
+ return tsutils.isCallLikeExpression(parent) ? parent : undefined;
226
+ }
227
+ function isFunctionOrMethod(declarations) {
228
+ if (!declarations?.length) {
229
+ return false;
230
+ }
231
+ switch (declarations[0].kind) {
232
+ case ts.SyntaxKind.MethodDeclaration:
233
+ case ts.SyntaxKind.FunctionDeclaration:
234
+ case ts.SyntaxKind.FunctionExpression:
235
+ case ts.SyntaxKind.MethodSignature:
236
+ return true;
237
+ default:
238
+ return false;
239
+ }
240
+ }
241
+ //# sourceMappingURL=no-deprecated.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-deprecated.js","sourceRoot":"","sources":["../../src/rules/no-deprecated.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TSESLint } from '@typescript-eslint/utils';\nimport { ESLintUtils } from '@typescript-eslint/utils';\nimport ts from 'typescript';\nimport { tsquery } from '@phenomnomnominal/tsquery';\nimport tsutils from 'tsutils';\n\nexport type MessageIds = 'forbidden';\nexport type MessageData = { name: string; comment: string };\ntype Options = { ignoredSelectors?: string[] };\n\nconst deprecatedNamesByProgram = new WeakMap<ts.Program, Set<string>>();\n\n/**\n * Copied from https://github.com/cartant/eslint-plugin-etc/blob/main/source/rules/no-deprecated.ts\n * due to lack of updates for new dependency versions.\n * Also added a new `ignoredSelectors` option.\n *\n * License for `eslint-plugin-etc` (excluding new `ignoredSelectors` option):\n *\n * MIT License\n *\n * Copyright (c) 2019-2021 Nicholas Jamieson and contributors\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to deal\n * in the Software without restriction, including without limitation the rights\n * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in all\n * copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n * SOFTWARE.\n */\nconst rule: TSESLint.RuleModule<MessageIds, [Options?]> = {\n defaultOptions: [],\n meta: {\n docs: {\n description: 'disallow the use of deprecated APIs',\n },\n messages: {\n forbidden: `\"{{name}}\" is deprecated: {{comment}}`,\n },\n schema: [\n {\n properties: {\n ignoredSelectors: {\n description: 'Selectors for nodes to ignore',\n type: 'array',\n items: { type: 'string' },\n },\n },\n type: 'object',\n },\n ],\n defaultOptions: [{}],\n type: 'problem',\n },\n create: (context) => {\n const [{ ignoredSelectors } = {}] = context.options;\n let ignoredNodes: ts.Node[] | undefined;\n\n const { esTreeNodeToTSNodeMap, program } = ESLintUtils.getParserServices(context);\n const typeChecker = program.getTypeChecker();\n\n let deprecatedNames = deprecatedNamesByProgram.get(program);\n if (!deprecatedNames) {\n deprecatedNames = findTaggedNames('deprecated', program);\n deprecatedNamesByProgram.set(program, deprecatedNames);\n }\n\n return {\n Identifier: (node) => {\n const parentType = node.parent?.type;\n if (\n parentType === 'ExportSpecifier' ||\n parentType === 'ImportDefaultSpecifier' ||\n parentType === 'ImportNamespaceSpecifier' ||\n parentType === 'ImportSpecifier'\n ) {\n return;\n }\n const identifier = esTreeNodeToTSNodeMap.get(node) as ts.Identifier;\n if (!deprecatedNames.has(identifier.text) || isDeclaration(identifier)) {\n return;\n }\n\n // NEW: check if this node matches any ignored selectors\n if (ignoredSelectors?.length) {\n ignoredNodes ??= tsquery(identifier.getSourceFile(), ignoredSelectors.join(', '));\n if (ignoredNodes.includes(identifier)) {\n return;\n }\n }\n\n const tags = getTags('deprecated', identifier, typeChecker);\n for (const tag of tags) {\n context.report({\n data: {\n comment: tag.trim().replace(/\\s+/g, ' '),\n name: identifier.text,\n },\n messageId: 'forbidden',\n node,\n });\n }\n },\n };\n },\n};\n\nexport default rule;\n\nfunction isDeclaration(identifier: ts.Identifier): boolean {\n const parent = identifier.parent;\n switch (parent.kind) {\n case ts.SyntaxKind.ClassDeclaration:\n case ts.SyntaxKind.ClassExpression:\n case ts.SyntaxKind.InterfaceDeclaration:\n case ts.SyntaxKind.TypeParameter:\n case ts.SyntaxKind.FunctionExpression:\n case ts.SyntaxKind.FunctionDeclaration:\n case ts.SyntaxKind.LabeledStatement:\n case ts.SyntaxKind.JsxAttribute:\n case ts.SyntaxKind.MethodDeclaration:\n case ts.SyntaxKind.MethodSignature:\n case ts.SyntaxKind.PropertySignature:\n case ts.SyntaxKind.TypeAliasDeclaration:\n case ts.SyntaxKind.GetAccessor:\n case ts.SyntaxKind.SetAccessor:\n case ts.SyntaxKind.EnumDeclaration:\n case ts.SyntaxKind.ModuleDeclaration:\n return true;\n case ts.SyntaxKind.VariableDeclaration:\n case ts.SyntaxKind.Parameter:\n case ts.SyntaxKind.PropertyDeclaration:\n case ts.SyntaxKind.EnumMember:\n case ts.SyntaxKind.ImportEqualsDeclaration:\n return (parent as ts.NamedDeclaration).name === identifier;\n case ts.SyntaxKind.PropertyAssignment:\n return (\n (parent as ts.PropertyAssignment).name === identifier &&\n !tsutils.isReassignmentTarget(identifier.parent.parent as ts.ObjectLiteralExpression)\n );\n case ts.SyntaxKind.BindingElement:\n // return true for `b` in `const {a: b} = obj`\n return (\n (parent as ts.BindingElement).name === identifier && (parent as ts.BindingElement).propertyName !== undefined\n );\n default:\n return false;\n }\n}\n\n/**\n * Get all identifiers with jsdoc tag `@tagName` in the program.\n */\nfunction findTaggedNames(tagName: string, program: ts.Program): Set<string> {\n const taggedNames = new Set<string>();\n for (const sourceFile of program.getSourceFiles()) {\n if (!sourceFile.text.includes(`@${tagName}`)) {\n continue;\n }\n const nodes = tsquery(\n sourceFile,\n `ClassDeclaration, Constructor, EnumDeclaration, EnumMember, FunctionDeclaration, GetAccessor, ` +\n `InterfaceDeclaration, MethodDeclaration, MethodSignature, PropertyDeclaration, PropertySignature, ` +\n `SetAccessor, TypeAliasDeclaration, VariableDeclaration`,\n );\n for (const node of nodes) {\n const tags = ts.getJSDocTags(node);\n if (tags.some((tag) => tag.tagName.text === tagName)) {\n const name = ts.isConstructorDeclaration(node)\n ? node.parent.name\n : (node as ts.Node & { name?: ts.Identifier }).name;\n if (name?.text) {\n taggedNames.add(name.text);\n }\n }\n }\n }\n return taggedNames;\n}\n\n/**\n * Get the text of all tags of `node`'s type matching `tagName`.\n */\nfunction getTags(tagName: string, node: ts.Identifier, tc: ts.TypeChecker): string[] {\n const callExpression = getCallExpression(node);\n if (callExpression) {\n const signature = tc.getResolvedSignature(callExpression);\n const tags = signature && findTags(tagName, signature.getJsDocTags());\n if (tags?.length) {\n return tags;\n }\n }\n\n let symbol: ts.Symbol | undefined;\n const parent = node.parent;\n if (parent.kind === ts.SyntaxKind.BindingElement) {\n symbol = tc.getTypeAtLocation(parent.parent).getProperty(node.text);\n } else if (\n (tsutils.isPropertyAssignment(parent) && parent.name === node) ||\n (tsutils.isShorthandPropertyAssignment(parent) && parent.name === node && tsutils.isReassignmentTarget(node))\n ) {\n symbol = tc.getPropertySymbolOfDestructuringAssignment(node);\n } else {\n symbol = tc.getSymbolAtLocation(node);\n }\n\n if (symbol && tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias)) {\n symbol = tc.getAliasedSymbol(symbol);\n }\n if (\n !symbol ||\n // if this is a CallExpression and the declaration is a function or method,\n // stop here to avoid collecting JsDoc of all overload signatures\n (callExpression && isFunctionOrMethod(symbol.declarations))\n ) {\n return [];\n }\n return findTags(tagName, symbol.getJsDocTags());\n}\n\n/**\n * Get the text of all `tags` matching `tagName`.\n */\nfunction findTags(tagName: string, tags: ts.JSDocTagInfo[]): string[] {\n const result: string[] = [];\n for (const tag of tags) {\n if (tag.name === tagName) {\n const { text = '' } = tag;\n if (typeof text === 'string') {\n result.push(text);\n } else {\n result.push(text.reduce((t, part) => t + part.text, ''));\n }\n }\n }\n return result;\n}\n\nfunction getCallExpression(node: ts.Expression): ts.CallLikeExpression | undefined {\n let parent = node.parent;\n if (tsutils.isPropertyAccessExpression(parent) && parent.name === node) {\n parent = parent.parent;\n }\n return tsutils.isCallLikeExpression(parent) ? parent : undefined;\n}\n\nfunction isFunctionOrMethod(declarations: ts.Declaration[] | undefined): boolean {\n if (!declarations?.length) {\n return false;\n }\n switch (declarations[0].kind) {\n case ts.SyntaxKind.MethodDeclaration:\n case ts.SyntaxKind.FunctionDeclaration:\n case ts.SyntaxKind.FunctionExpression:\n case ts.SyntaxKind.MethodSignature:\n return true;\n default:\n return false;\n }\n}\n"]}
package/package.json CHANGED
@@ -1,10 +1,16 @@
1
1
  {
2
2
  "name": "@ms-cloudpack/eslint-plugin-deprecated",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "description": "ESLint rule banning usage of deprecated APIs",
5
5
  "license": "MIT",
6
6
  "type": "module",
7
- "exports": "./src/index.ts",
7
+ "exports": {
8
+ ".": {
9
+ "types": "./lib/index.d.ts",
10
+ "import": "./lib/index.js"
11
+ }
12
+ },
13
+ "publishConfig": {},
8
14
  "engines": {
9
15
  "node": ">=22.18.0"
10
16
  },
@@ -24,7 +30,7 @@
24
30
  "typescript-eslint": "^8.0.0"
25
31
  },
26
32
  "devDependencies": {
27
- "@ms-cloudpack/scripts": "workspace:^",
33
+ "@ms-cloudpack/scripts": "^0.0.1",
28
34
  "@typescript-eslint/parser": "^8.0.0",
29
35
  "@typescript-eslint/rule-tester": "^8.0.0",
30
36
  "eslint": "^9.0.0",
@@ -32,6 +38,7 @@
32
38
  "typescript": "~5.9.0"
33
39
  },
34
40
  "files": [
35
- "src/**/!(*.test.*)"
36
- ]
41
+ "lib/**/!(*.test.*)"
42
+ ],
43
+ "types": "./lib/index.d.ts"
37
44
  }
@@ -1,45 +0,0 @@
1
- /**
2
- * Heavily modified from https://github.com/cartant/eslint-etc/blob/main/source/from-fixture.ts
3
- * for no-deprecated rule tests.
4
- */
5
- import type { InvalidTestCase, TestCaseError } from '@typescript-eslint/rule-tester';
6
-
7
- const markerRegexp = /^(?<indent>\s*)(?<marker>~+)$/;
8
-
9
- /**
10
- * Convert a string with marker comment to an invalid test case.
11
- * ```
12
- * let a: DeprecatedInterface;
13
- * ~~~~~~~~~~~~~~~~~~~
14
- * ```
15
- */
16
- export function createInvalidCases<MessageIds extends string, TData extends Readonly<Record<string, unknown>>>(
17
- cases: Omit<InvalidTestCase<MessageIds, never>, 'code' | 'errors'> &
18
- {
19
- code: string;
20
- errors: { messageId: MessageIds; data?: TData }[];
21
- }[],
22
- ): InvalidTestCase<MessageIds, never>[] {
23
- return cases.map(({ code, errors: partialErrors, ...testCase }) => {
24
- const lines: string[] = [];
25
- const errors: TestCaseError<MessageIds>[] = [];
26
-
27
- for (const line of code.split('\n')) {
28
- const match = line.match(markerRegexp);
29
- if (match?.groups) {
30
- const error = partialErrors[errors.length];
31
- if (!error) {
32
- throw new Error('More marker comments found than expected');
33
- }
34
- const column = match.groups.indent.length + 1;
35
- const endColumn = column + match.groups.marker.length;
36
- const lineNum = lines.length;
37
- errors.push({ ...error, line: lineNum, column, endLine: lineNum, endColumn });
38
- } else {
39
- lines.push(line);
40
- }
41
- }
42
-
43
- return { code: lines.join('\n'), errors, ...testCase };
44
- });
45
- }
@@ -1,153 +0,0 @@
1
- /**
2
- * Copied from https://github.com/cartant/eslint-plugin-etc/blob/main/tests/modules/deprecated.ts
3
- * due to lack of updates for new dependency versions.
4
- */
5
- /** */
6
-
7
- export interface NotDeprecatedInterface {
8
- notDeprecatedProperty: string;
9
- notDeprecatedMethod(): void;
10
- }
11
-
12
- export type NotDeprecatedType = {
13
- notDeprecatedProperty: string;
14
- notDeprecatedMethod(): void;
15
- };
16
-
17
- export class NotDeprecatedClass {
18
- static notDeprecatedStaticMethod(): void {}
19
- notDeprecatedProperty: string = '';
20
- get notDeprecatedGetter(): string {
21
- return '';
22
- }
23
- set notDeprecatedSetter(value: string) {}
24
- notDeprecatedMethod(): void {}
25
- }
26
-
27
- // Note: this gets an editor diagnostics error, but is correct at actual build time
28
- // @ts-expect-error -- not valid with erasable syntax, but fine for a test fixture
29
- export enum NotDeprecatedEnum {
30
- NotDeprecatedMember = 1,
31
- }
32
-
33
- export const notDeprecatedVariable = {};
34
-
35
- export function notDeprecatedFunction(): void {}
36
-
37
- // Deprecated
38
-
39
- /** @deprecated Don't use this */
40
- export interface DeprecatedInterface {
41
- notDeprecatedProperty: string;
42
- notDeprecatedMethod(): void;
43
- }
44
-
45
- /** @deprecated Don't use this */
46
- export type DeprecatedType = {
47
- notDeprecatedProperty: string;
48
- notDeprecatedMethod(): void;
49
- };
50
-
51
- /** @deprecated Don't use this */
52
- export class DeprecatedClass {
53
- static notDeprecatedStaticMethod(): void {}
54
- notDeprecatedProperty: string = '';
55
- get notDeprecatedGetter(): string {
56
- return '';
57
- }
58
- set notDeprecatedSetter(value: string) {}
59
- notDeprecatedMethod(): void {}
60
- }
61
-
62
- /** @deprecated Don't use this */
63
- // @ts-expect-error -- not valid with erasable syntax, but fine for a test fixture
64
- export enum DeprecatedEnum {
65
- NotDeprecatedMember = 1,
66
- }
67
-
68
- /** @deprecated Don't use this */
69
- export const deprecatedVariable = {};
70
-
71
- /** @deprecated Don't use this */
72
- export function deprecatedFunction(): void {}
73
-
74
- // Some proeprties/methods deprecated
75
-
76
- export interface SomeDeprecatedInterface {
77
- /** @deprecated Don't use this */
78
- deprecatedProperty: string;
79
- notDeprecatedProperty: string;
80
- /** @deprecated Don't use this */
81
- deprecatedMethod(): void;
82
- notDeprecatedMethod(): void;
83
- }
84
-
85
- export type SomeDeprecatedType = {
86
- /** @deprecated Don't use this */
87
- deprecatedProperty: string;
88
- notDeprecatedProperty: string;
89
- /** @deprecated Don't use this */
90
- deprecatedMethod(): void;
91
- notDeprecatedMethod(): void;
92
- };
93
-
94
- export class SomeDeprecatedClass {
95
- /** @deprecated Don't use this */
96
- static deprecatedStaticMethod(): void {}
97
- static notDeprecatedStaticMethod(): void {}
98
- /** @deprecated Don't use this */
99
- deprecatedProperty: string = '';
100
- notDeprecatedProperty: string = '';
101
- /** @deprecated Don't use this */
102
- get deprecatedGetter(): string {
103
- return '';
104
- }
105
- get notDeprecatedGetter(): string {
106
- return '';
107
- }
108
- /** @deprecated Don't use this */
109
- set deprecatedSetter(value: string) {}
110
- set notDeprecatedSetter(value: string) {}
111
- /** @deprecated Don't use this */
112
- deprecatedMethod(): void {}
113
- notDeprecatedMethod(): void {}
114
- }
115
-
116
- // @ts-expect-error -- not valid with erasable syntax, but fine for a test fixture
117
- export enum SomeDeprecatedEnum {
118
- /** @deprecated Don't use this */
119
- DeprecatedMember = 1,
120
- NotDeprecatedMember = 2,
121
- }
122
-
123
- // Some deprecated signatures
124
-
125
- export class DeprecatedSignatureClass {
126
- static deprecatedSignatureStaticMethod(value: number): void;
127
- /** @deprecated Don't use this */
128
- static deprecatedSignatureStaticMethod(value: string): void;
129
- static deprecatedSignatureStaticMethod(_value: unknown): void {}
130
- deprecatedSignatureMethod(value: number): void;
131
- /** @deprecated Don't use this */
132
- deprecatedSignatureMethod(value: string): void;
133
- deprecatedSignatureMethod(_value: unknown): void {}
134
- }
135
-
136
- export function deprecatedSignatureFunction(value: number): void;
137
- /** @deprecated Don't use this */
138
- export function deprecatedSignatureFunction(value: string): void;
139
- export function deprecatedSignatureFunction(_value: unknown): void {}
140
-
141
- // Deprecated constructor
142
-
143
- export class DeprecatedConstructorClass {
144
- /** @deprecated Don't use this */
145
- constructor() {}
146
- }
147
-
148
- export class DeprecatedConstructorSignatureClass {
149
- constructor(value: number);
150
- /** @deprecated Don't use this */
151
- constructor(value: string);
152
- constructor(_value: unknown) {}
153
- }
@@ -1,13 +0,0 @@
1
- // tsconfig used as `project` for no-deprecated tests
2
- {
3
- "compilerOptions": {
4
- "lib": ["esnext"],
5
- "module": "esnext",
6
- "moduleResolution": "bundler",
7
- "skipLibCheck": true,
8
- "target": "esnext",
9
- // very important for test performance!
10
- "types": []
11
- },
12
- "include": ["file.ts", "deprecated.ts"]
13
- }
package/src/index.ts DELETED
@@ -1,26 +0,0 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
- import type { TSESLint } from '@typescript-eslint/utils';
4
- import noDeprecated from './rules/no-deprecated.ts';
5
-
6
- const { name, version } = JSON.parse(fs.readFileSync(path.resolve(import.meta.dirname, '../package.json'), 'utf8')) as {
7
- name: string;
8
- version: string;
9
- };
10
-
11
- const plugin = {
12
- meta: { name, version, namespace: '@ms-cloudpack' },
13
- configs: {
14
- recommended: {
15
- rules: {
16
- '@ms-cloudpack/no-deprecated': 'error',
17
- },
18
- },
19
- },
20
- rules: {
21
- '@ms-cloudpack/no-deprecated': noDeprecated,
22
- },
23
- // Use `satisfies` to preserve the original property names
24
- } satisfies TSESLint.FlatConfig.Plugin;
25
-
26
- export default plugin;
@@ -1,271 +0,0 @@
1
- import type { TSESLint } from '@typescript-eslint/utils';
2
- import { ESLintUtils } from '@typescript-eslint/utils';
3
- import ts from 'typescript';
4
- import { tsquery } from '@phenomnomnominal/tsquery';
5
- import tsutils from 'tsutils';
6
-
7
- export type MessageIds = 'forbidden';
8
- export type MessageData = { name: string; comment: string };
9
- type Options = { ignoredSelectors?: string[] };
10
-
11
- const deprecatedNamesByProgram = new WeakMap<ts.Program, Set<string>>();
12
-
13
- /**
14
- * Copied from https://github.com/cartant/eslint-plugin-etc/blob/main/source/rules/no-deprecated.ts
15
- * due to lack of updates for new dependency versions.
16
- * Also added a new `ignoredSelectors` option.
17
- *
18
- * License for `eslint-plugin-etc` (excluding new `ignoredSelectors` option):
19
- *
20
- * MIT License
21
- *
22
- * Copyright (c) 2019-2021 Nicholas Jamieson and contributors
23
- *
24
- * Permission is hereby granted, free of charge, to any person obtaining a copy
25
- * of this software and associated documentation files (the "Software"), to deal
26
- * in the Software without restriction, including without limitation the rights
27
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
28
- * copies of the Software, and to permit persons to whom the Software is
29
- * furnished to do so, subject to the following conditions:
30
- *
31
- * The above copyright notice and this permission notice shall be included in all
32
- * copies or substantial portions of the Software.
33
- *
34
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
36
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
37
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
38
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
39
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
40
- * SOFTWARE.
41
- */
42
- const rule: TSESLint.RuleModule<MessageIds, [Options?]> = {
43
- defaultOptions: [],
44
- meta: {
45
- docs: {
46
- description: 'disallow the use of deprecated APIs',
47
- },
48
- messages: {
49
- forbidden: `"{{name}}" is deprecated: {{comment}}`,
50
- },
51
- schema: [
52
- {
53
- properties: {
54
- ignoredSelectors: {
55
- description: 'Selectors for nodes to ignore',
56
- type: 'array',
57
- items: { type: 'string' },
58
- },
59
- },
60
- type: 'object',
61
- },
62
- ],
63
- defaultOptions: [{}],
64
- type: 'problem',
65
- },
66
- create: (context) => {
67
- const [{ ignoredSelectors } = {}] = context.options;
68
- let ignoredNodes: ts.Node[] | undefined;
69
-
70
- const { esTreeNodeToTSNodeMap, program } = ESLintUtils.getParserServices(context);
71
- const typeChecker = program.getTypeChecker();
72
-
73
- let deprecatedNames = deprecatedNamesByProgram.get(program);
74
- if (!deprecatedNames) {
75
- deprecatedNames = findTaggedNames('deprecated', program);
76
- deprecatedNamesByProgram.set(program, deprecatedNames);
77
- }
78
-
79
- return {
80
- Identifier: (node) => {
81
- const parentType = node.parent?.type;
82
- if (
83
- parentType === 'ExportSpecifier' ||
84
- parentType === 'ImportDefaultSpecifier' ||
85
- parentType === 'ImportNamespaceSpecifier' ||
86
- parentType === 'ImportSpecifier'
87
- ) {
88
- return;
89
- }
90
- const identifier = esTreeNodeToTSNodeMap.get(node) as ts.Identifier;
91
- if (!deprecatedNames.has(identifier.text) || isDeclaration(identifier)) {
92
- return;
93
- }
94
-
95
- // NEW: check if this node matches any ignored selectors
96
- if (ignoredSelectors?.length) {
97
- ignoredNodes ??= tsquery(identifier.getSourceFile(), ignoredSelectors.join(', '));
98
- if (ignoredNodes.includes(identifier)) {
99
- return;
100
- }
101
- }
102
-
103
- const tags = getTags('deprecated', identifier, typeChecker);
104
- for (const tag of tags) {
105
- context.report({
106
- data: {
107
- comment: tag.trim().replace(/\s+/g, ' '),
108
- name: identifier.text,
109
- },
110
- messageId: 'forbidden',
111
- node,
112
- });
113
- }
114
- },
115
- };
116
- },
117
- };
118
-
119
- export default rule;
120
-
121
- function isDeclaration(identifier: ts.Identifier): boolean {
122
- const parent = identifier.parent;
123
- switch (parent.kind) {
124
- case ts.SyntaxKind.ClassDeclaration:
125
- case ts.SyntaxKind.ClassExpression:
126
- case ts.SyntaxKind.InterfaceDeclaration:
127
- case ts.SyntaxKind.TypeParameter:
128
- case ts.SyntaxKind.FunctionExpression:
129
- case ts.SyntaxKind.FunctionDeclaration:
130
- case ts.SyntaxKind.LabeledStatement:
131
- case ts.SyntaxKind.JsxAttribute:
132
- case ts.SyntaxKind.MethodDeclaration:
133
- case ts.SyntaxKind.MethodSignature:
134
- case ts.SyntaxKind.PropertySignature:
135
- case ts.SyntaxKind.TypeAliasDeclaration:
136
- case ts.SyntaxKind.GetAccessor:
137
- case ts.SyntaxKind.SetAccessor:
138
- case ts.SyntaxKind.EnumDeclaration:
139
- case ts.SyntaxKind.ModuleDeclaration:
140
- return true;
141
- case ts.SyntaxKind.VariableDeclaration:
142
- case ts.SyntaxKind.Parameter:
143
- case ts.SyntaxKind.PropertyDeclaration:
144
- case ts.SyntaxKind.EnumMember:
145
- case ts.SyntaxKind.ImportEqualsDeclaration:
146
- return (parent as ts.NamedDeclaration).name === identifier;
147
- case ts.SyntaxKind.PropertyAssignment:
148
- return (
149
- (parent as ts.PropertyAssignment).name === identifier &&
150
- !tsutils.isReassignmentTarget(identifier.parent.parent as ts.ObjectLiteralExpression)
151
- );
152
- case ts.SyntaxKind.BindingElement:
153
- // return true for `b` in `const {a: b} = obj`
154
- return (
155
- (parent as ts.BindingElement).name === identifier && (parent as ts.BindingElement).propertyName !== undefined
156
- );
157
- default:
158
- return false;
159
- }
160
- }
161
-
162
- /**
163
- * Get all identifiers with jsdoc tag `@tagName` in the program.
164
- */
165
- function findTaggedNames(tagName: string, program: ts.Program): Set<string> {
166
- const taggedNames = new Set<string>();
167
- for (const sourceFile of program.getSourceFiles()) {
168
- if (!sourceFile.text.includes(`@${tagName}`)) {
169
- continue;
170
- }
171
- const nodes = tsquery(
172
- sourceFile,
173
- `ClassDeclaration, Constructor, EnumDeclaration, EnumMember, FunctionDeclaration, GetAccessor, ` +
174
- `InterfaceDeclaration, MethodDeclaration, MethodSignature, PropertyDeclaration, PropertySignature, ` +
175
- `SetAccessor, TypeAliasDeclaration, VariableDeclaration`,
176
- );
177
- for (const node of nodes) {
178
- const tags = ts.getJSDocTags(node);
179
- if (tags.some((tag) => tag.tagName.text === tagName)) {
180
- const name = ts.isConstructorDeclaration(node)
181
- ? node.parent.name
182
- : (node as ts.Node & { name?: ts.Identifier }).name;
183
- if (name?.text) {
184
- taggedNames.add(name.text);
185
- }
186
- }
187
- }
188
- }
189
- return taggedNames;
190
- }
191
-
192
- /**
193
- * Get the text of all tags of `node`'s type matching `tagName`.
194
- */
195
- function getTags(tagName: string, node: ts.Identifier, tc: ts.TypeChecker): string[] {
196
- const callExpression = getCallExpression(node);
197
- if (callExpression) {
198
- const signature = tc.getResolvedSignature(callExpression);
199
- const tags = signature && findTags(tagName, signature.getJsDocTags());
200
- if (tags?.length) {
201
- return tags;
202
- }
203
- }
204
-
205
- let symbol: ts.Symbol | undefined;
206
- const parent = node.parent;
207
- if (parent.kind === ts.SyntaxKind.BindingElement) {
208
- symbol = tc.getTypeAtLocation(parent.parent).getProperty(node.text);
209
- } else if (
210
- (tsutils.isPropertyAssignment(parent) && parent.name === node) ||
211
- (tsutils.isShorthandPropertyAssignment(parent) && parent.name === node && tsutils.isReassignmentTarget(node))
212
- ) {
213
- symbol = tc.getPropertySymbolOfDestructuringAssignment(node);
214
- } else {
215
- symbol = tc.getSymbolAtLocation(node);
216
- }
217
-
218
- if (symbol && tsutils.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias)) {
219
- symbol = tc.getAliasedSymbol(symbol);
220
- }
221
- if (
222
- !symbol ||
223
- // if this is a CallExpression and the declaration is a function or method,
224
- // stop here to avoid collecting JsDoc of all overload signatures
225
- (callExpression && isFunctionOrMethod(symbol.declarations))
226
- ) {
227
- return [];
228
- }
229
- return findTags(tagName, symbol.getJsDocTags());
230
- }
231
-
232
- /**
233
- * Get the text of all `tags` matching `tagName`.
234
- */
235
- function findTags(tagName: string, tags: ts.JSDocTagInfo[]): string[] {
236
- const result: string[] = [];
237
- for (const tag of tags) {
238
- if (tag.name === tagName) {
239
- const { text = '' } = tag;
240
- if (typeof text === 'string') {
241
- result.push(text);
242
- } else {
243
- result.push(text.reduce((t, part) => t + part.text, ''));
244
- }
245
- }
246
- }
247
- return result;
248
- }
249
-
250
- function getCallExpression(node: ts.Expression): ts.CallLikeExpression | undefined {
251
- let parent = node.parent;
252
- if (tsutils.isPropertyAccessExpression(parent) && parent.name === node) {
253
- parent = parent.parent;
254
- }
255
- return tsutils.isCallLikeExpression(parent) ? parent : undefined;
256
- }
257
-
258
- function isFunctionOrMethod(declarations: ts.Declaration[] | undefined): boolean {
259
- if (!declarations?.length) {
260
- return false;
261
- }
262
- switch (declarations[0].kind) {
263
- case ts.SyntaxKind.MethodDeclaration:
264
- case ts.SyntaxKind.FunctionDeclaration:
265
- case ts.SyntaxKind.FunctionExpression:
266
- case ts.SyntaxKind.MethodSignature:
267
- return true;
268
- default:
269
- return false;
270
- }
271
- }