Skip to content

Commit 360c9fd

Browse files
committed
Add lint rule for as any and bulk ignore all existing breaks
For microsoft#269213 This adds a new eslint rule for `as any` and `<any>({... })`. We'd like to remove almost all of these, however right now the first goal is to prevent them in new code. That's why with this first PR I simply add `eslint-disable` comments for all breaks Trying to get this change in soon after branching off for release to hopefully minimize disruption during debt week work
1 parent 96aa43f commit 360c9fd

465 files changed

Lines changed: 1188 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*---------------------------------------------------------------------------------------------
2+
* Copyright (c) Microsoft Corporation. All rights reserved.
3+
* Licensed under the MIT License. See License.txt in the project root for license information.
4+
*--------------------------------------------------------------------------------------------*/
5+
6+
import * as eslint from 'eslint';
7+
import { TSESTree } from '@typescript-eslint/utils';
8+
9+
export = new class NoAnyCasts implements eslint.Rule.RuleModule {
10+
11+
create(context: eslint.Rule.RuleContext): eslint.Rule.RuleListener {
12+
return {
13+
// Detect TSTypeAssertion: <any>value
14+
'TSTypeAssertion': (node: any) => {
15+
const typeAssertion = node as TSESTree.TSTypeAssertion;
16+
if (typeAssertion.typeAnnotation.type === 'TSAnyKeyword') {
17+
context.report({
18+
node,
19+
message: `Avoid casting to 'any' type. Consider using a more specific type or type guards for better type safety.`
20+
});
21+
}
22+
},
23+
24+
// Detect TSAsExpression: value as any
25+
'TSAsExpression': (node: any) => {
26+
const asExpression = node as TSESTree.TSAsExpression;
27+
if (asExpression.typeAnnotation.type === 'TSAnyKeyword') {
28+
context.report({
29+
node,
30+
message: `Avoid casting to 'any' type. Consider using a more specific type or type guards for better type safety.`
31+
});
32+
}
33+
}
34+
};
35+
}
36+
};

.eslint-plugin-local/code-no-observable-get-in-reactive-context.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,12 @@ function checkFunctionForObservableGetCalls(
6161
if (node.type === 'CallExpression' && isObservableGetCall(node)) {
6262
// Flag .get() calls since we're always in a reactive context here
6363
context.report({
64+
// eslint-disable-next-line local/code-no-any-casts
6465
node: node as any as ESTree.Node,
6566
message: `Observable '.get()' should not be used in reactive context. Use '.read(${readerName})' instead to properly track dependencies or '.read(undefined)' to be explicit about an untracked read.`,
6667
fix: (fixer) => {
6768
const memberExpression = node.callee as TSESTree.MemberExpression;
69+
// eslint-disable-next-line local/code-no-any-casts
6870
return fixer.replaceText(node as any, `${context.getSourceCode().getText(memberExpression.object as any)}.read(undefined)`);
6971
}
7072
});
@@ -131,6 +133,7 @@ function isReactiveFunctionWithReader(callee: TSESTree.Node): boolean {
131133
function walkChildren(node: TSESTree.Node, cb: (child: TSESTree.Node) => void) {
132134
const keys = visitorKeys.KEYS[node.type] || [];
133135
for (const key of keys) {
136+
// eslint-disable-next-line local/code-no-any-casts
134137
const child = (node as any)[key];
135138
if (Array.isArray(child)) {
136139
for (const item of child) {

.eslint-plugin-local/code-no-reader-after-await.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ function checkFunctionForAwaitBeforeReader(
5959
if (awaitPositions.length > 0) {
6060
const methodName = getMethodName(node);
6161
context.report({
62+
// eslint-disable-next-line local/code-no-any-casts
6263
node: node as any as ESTree.Node,
6364
message: `Reader method '${methodName}' should not be called after 'await'. The reader becomes invalid after async operations.`
6465
});

.eslint-plugin-local/code-no-static-self-ref.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ export = new class implements eslint.Rule.RuleModule {
3333
}
3434

3535
const name = classDeclaration.id.name;
36+
// eslint-disable-next-line local/code-no-any-casts
3637
const valueText = context.sourceCode.getText(<any>propertyDefinition.value);
3738

3839
if (valueText.includes(name + '.')) {

.eslint-plugin-local/code-no-test-async-suite.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export = new class NoAsyncSuite implements eslint.Rule.RuleModule {
2020
function hasAsyncSuite(node: any) {
2121
if (isCallExpression(node) && node.arguments.length >= 2 && isFunctionExpression(node.arguments[1]) && node.arguments[1].async) {
2222
return context.report({
23+
// eslint-disable-next-line local/code-no-any-casts
2324
node: node as any,
2425
message: 'suite factory function should never be async'
2526
});

.eslint-plugin-local/code-no-unexternalized-strings.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ export = new class NoUnexternalizedStrings implements eslint.Rule.RuleModule {
8181
context.report({
8282
loc: messageNode.loc,
8383
messageId: 'badMessage',
84+
// eslint-disable-next-line local/code-no-any-casts
8485
data: { message: context.getSourceCode().getText(<any>node) }
8586
});
8687
}
@@ -128,6 +129,7 @@ export = new class NoUnexternalizedStrings implements eslint.Rule.RuleModule {
128129
// report all invalid duplicates (same key, different message)
129130
if (values.length > 1) {
130131
for (let i = 1; i < values.length; i++) {
132+
// eslint-disable-next-line local/code-no-any-casts
131133
if (context.getSourceCode().getText(<any>values[i - 1].message) !== context.getSourceCode().getText(<any>values[i].message)) {
132134
context.report({ loc: values[i].call.loc, messageId: 'duplicateKey', data: { key } });
133135
}

.eslint-plugin-local/vscode-dts-provider-naming.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ export = new class ApiProviderNaming implements eslint.Rule.RuleModule {
3232
return;
3333
}
3434

35+
// eslint-disable-next-line local/code-no-any-casts
3536
const methodName = (<any>(<TSESTree.TSMethodSignatureNonComputedName>node).key).name;
3637

3738
if (!ApiProviderNaming._providerFunctionNames.test(methodName)) {

.eslint-plugin-local/vscode-dts-vscode-in-comments.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ export = new class ApiVsCodeInComments implements eslint.Rule.RuleModule {
4040
}
4141

4242
// Types for eslint seem incorrect
43+
// eslint-disable-next-line local/code-no-any-casts
4344
const start = sourceCode.getLocFromIndex(startIndex + match.index) as any as estree.Position;
45+
// eslint-disable-next-line local/code-no-any-casts
4446
const end = sourceCode.getLocFromIndex(startIndex + match.index + match[0].length) as any as estree.Position;
4547
context.report({
4648
messageId: 'comment',

build/azure-pipelines/common/publish.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,7 @@ class ESRPReleaseService {
521521
// Release service uses hex format, not base64url :roll_eyes:
522522
x5t: getThumbprint(this.requestSigningCertificates[0], 'sha1').toString('hex'),
523523
// Release service uses a '.' separated string, not an array of strings :roll_eyes:
524+
// eslint-disable-next-line local/code-no-any-casts
524525
x5c: this.requestSigningCertificates.map(c => getCertificateBuffer(c).toString('base64url')).join('.') as any,
525526
},
526527
payload: message,

build/azure-pipelines/upload-cdn.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ async function main(): Promise<void> {
112112
const listing = new Vinyl({
113113
path: 'files.txt',
114114
contents: Buffer.from(files.join('\n')),
115+
// eslint-disable-next-line local/code-no-any-casts
115116
stat: { mode: 0o666 } as any
116117
});
117118

0 commit comments

Comments
 (0)