Skip to content

Commit 48a7ca5

Browse files
committed
build: Add no-optional-chaining eslint rule
1 parent 88b23f6 commit 48a7ca5

File tree

9 files changed

+73
-1
lines changed

9 files changed

+73
-1
lines changed

packages/eslint-config-sdk/src/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,9 @@ module.exports = {
143143
},
144144
],
145145

146-
// We want to prevent async await usage in our files to prevent uncessary bundle size. Turned off in tests.
146+
// We want to prevent async await & optional chaining usage in our files to prevent uncessary bundle size. Turned off in tests.
147147
'@sentry-internal/sdk/no-async-await': 'error',
148+
'@sentry-internal/sdk/no-optional-chaining': 'error',
148149

149150
// JSDOC comments are required for classes and methods. As we have a public facing codebase, documentation,
150151
// even if it may seems excessive at times, is important to emphasize. Turned off in tests.
@@ -178,6 +179,7 @@ module.exports = {
178179
'@typescript-eslint/no-non-null-assertion': 'off',
179180
'@typescript-eslint/no-empty-function': 'off',
180181
'@sentry-internal/sdk/no-async-await': 'off',
182+
'@sentry-internal/sdk/no-optional-chaining': 'off',
181183
},
182184
},
183185
{

packages/eslint-plugin-sdk/src/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
module.exports = {
1212
rules: {
1313
'no-async-await': require('./rules/no-async-await'),
14+
'no-optional-chaining': require('./rules/no-optional-chaining'),
1415
'no-eq-empty': require('./rules/no-eq-empty'),
1516
},
1617
};
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/**
2+
* @fileoverview Rule to disallow using optional chaining - because this is transpiled into verbose code.
3+
* @author Francesco Novy
4+
*
5+
* Based on https://github.com/facebook/lexical/pull/3233
6+
*/
7+
'use strict';
8+
9+
// ------------------------------------------------------------------------------
10+
// Rule Definition
11+
// ------------------------------------------------------------------------------
12+
13+
/** @type {import('eslint').Rule.RuleModule} */
14+
module.exports = {
15+
meta: {
16+
type: 'problem',
17+
docs: {
18+
description: 'disallow usage of optional chaining',
19+
category: 'Best Practices',
20+
recommended: true,
21+
},
22+
messages: {
23+
forbidden: 'Avoid using optional chaining',
24+
},
25+
fixable: null,
26+
schema: [],
27+
},
28+
29+
create(context) {
30+
const sourceCode = context.getSourceCode();
31+
32+
/**
33+
* Checks if the given token is a `?.` token or not.
34+
* @param {Token} token The token to check.
35+
* @returns {boolean} `true` if the token is a `?.` token.
36+
*/
37+
function isQuestionDotToken(token) {
38+
return (
39+
token.value === '?.' &&
40+
(token.type === 'Punctuator' || // espree has been parsed well.
41+
// [email protected] doesn't parse "?." tokens well. Therefore, get the string from the source code and check it.
42+
sourceCode.getText(token) === '?.')
43+
);
44+
}
45+
46+
return {
47+
'CallExpression[optional=true]'(node) {
48+
context.report({
49+
messageId: 'forbidden',
50+
node: sourceCode.getTokenAfter(node.callee, isQuestionDotToken),
51+
});
52+
},
53+
'MemberExpression[optional=true]'(node) {
54+
context.report({
55+
messageId: 'forbidden',
56+
node: sourceCode.getTokenAfter(node.object, isQuestionDotToken),
57+
});
58+
},
59+
};
60+
},
61+
};

packages/nextjs/.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module.exports = {
1010
extends: ['../../.eslintrc.js'],
1111
rules: {
1212
'@sentry-internal/sdk/no-async-await': 'off',
13+
'@sentry-internal/sdk/no-optional-chaining': 'off',
1314
},
1415
overrides: [
1516
{

packages/node/.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ module.exports = {
55
extends: ['../../.eslintrc.js'],
66
rules: {
77
'@sentry-internal/sdk/no-async-await': 'off',
8+
'@sentry-internal/sdk/no-optional-chaining': 'off',
89
},
910
};

packages/opentelemetry-node/.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@ module.exports = {
55
extends: ['../../.eslintrc.js'],
66
rules: {
77
'@sentry-internal/sdk/no-async-await': 'off',
8+
'@sentry-internal/sdk/no-optional-chaining': 'off',
89
},
910
};

packages/remix/.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ module.exports = {
1010
extends: ['../../.eslintrc.js'],
1111
rules: {
1212
'@sentry-internal/sdk/no-async-await': 'off',
13+
'@sentry-internal/sdk/no-optional-chaining': 'off',
1314
},
1415
overrides: [
1516
{

packages/serverless/.eslintrc.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ module.exports = {
55
extends: ['../../.eslintrc.js'],
66
rules: {
77
'@sentry-internal/sdk/no-async-await': 'off',
8+
'@sentry-internal/sdk/no-optional-chaining': 'off',
89
},
910
overrides: [
1011
{

packages/wasm/.eslintrc.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
module.exports = {
22
extends: ['../../.eslintrc.js'],
3+
rules: {
4+
'@sentry-internal/sdk/no-optional-chaining': 'off',
5+
},
36
};

0 commit comments

Comments
 (0)