From 20bcf4f8506426670ba3cdb5fd6e4a89fbc755ce Mon Sep 17 00:00:00 2001 From: Alexander Kamushkin Date: Tue, 12 Sep 2023 09:31:56 +0200 Subject: [PATCH 1/4] generate rule description, metadata --- .../javascript/rules/javascript/S6757.html | 38 +++++++++++++++++++ .../javascript/rules/javascript/S6757.json | 29 ++++++++++++++ .../rules/javascript/Sonar_way_profile.json | 3 +- 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6757.html create mode 100644 sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6757.json diff --git a/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6757.html b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6757.html new file mode 100644 index 00000000000..e4fe45babce --- /dev/null +++ b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6757.html @@ -0,0 +1,38 @@ +

Why is this an issue?

+

Referring to this in React functional component would be an error because the components are just regular JavaScript functions and do +not have an object assotiated with them. The functional components receive its props as a first argument to the component function, so you can access +then directly, and it is a common style to destructure them right away.

+
+function UserProfile({firstName, lastName}){
+    return (
+        <div className="user">{firstName} {lastName}</div>
+    );
+}
+
+

React also supports legacy class-based components, where this keyword refers to the component instance object, but this style of +writing components is no longer recommended, and mixing it with functional components will lead to errors.

+
+function MyComponent(props){
+    const foo = this.props.bar; // Noncompliant: remove 'this'
+    return (
+        <div>{foo}</div>
+    );
+}
+
+

To fix the issue remove this from your functional component code (are you mixing functional and class-based component styles?)

+
+function MyComponent(props){
+    const foo = props.bar;
+    return (
+        <div>{foo}</div>
+    );
+}
+
+

Resources

+

Documentation

+ + diff --git a/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6757.json b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6757.json new file mode 100644 index 00000000000..81e4b79fc45 --- /dev/null +++ b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6757.json @@ -0,0 +1,29 @@ +{ + "title": "\"this\" should not be used in functional components", + "type": "BUG", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "5min" + }, + "tags": [ + "react" + ], + "defaultSeverity": "Major", + "ruleSpecification": "RSPEC-6757", + "sqKey": "S6757", + "scope": "All", + "quickfix": "infeasible", + "code": { + "impacts": { + "MAINTAINABILITY": "HIGH", + "RELIABILITY": "MEDIUM", + "SECURITY": "LOW" + }, + "attribute": "CONVENTIONAL" + }, + "compatibleLanguages": [ + "JAVASCRIPT", + "TYPESCRIPT" + ] +} diff --git a/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/Sonar_way_profile.json b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/Sonar_way_profile.json index 0ce7fdc6d5a..0ec1d85111c 100644 --- a/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/Sonar_way_profile.json +++ b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/Sonar_way_profile.json @@ -278,6 +278,7 @@ "S6747", "S6748", "S6749", - "S6750" + "S6750", + "S6757" ] } From 6ae6224616ea2a65a517d88ca41e82eb388e93ec Mon Sep 17 00:00:00 2001 From: Alexander Kamushkin Date: Tue, 12 Sep 2023 09:32:15 +0200 Subject: [PATCH 2/4] generate java files --- .../sonar/javascript/checks/CheckList.java | 1 + .../javascript/checks/NoThisInSfcCheck.java | 36 +++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/NoThisInSfcCheck.java diff --git a/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/CheckList.java b/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/CheckList.java index 733e4473b43..7c1546753d4 100644 --- a/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/CheckList.java +++ b/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/CheckList.java @@ -291,6 +291,7 @@ public static List> getAllChecks() { NoSelfCompareCheck.class, NoSparseArraysCheck.class, NoThisAliasCheck.class, + NoThisInSfcCheck.class, NoUndefInitCheck.class, NoUniqKeyCheck.class, NoUnknownPropertyCheck.class, diff --git a/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/NoThisInSfcCheck.java b/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/NoThisInSfcCheck.java new file mode 100644 index 00000000000..dd23b9b8323 --- /dev/null +++ b/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/NoThisInSfcCheck.java @@ -0,0 +1,36 @@ +/** + * SonarQube JavaScript Plugin + * Copyright (C) 2011-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.javascript.checks; + +import org.sonar.check.Rule; +import org.sonar.plugins.javascript.api.EslintBasedCheck; +import org.sonar.plugins.javascript.api.JavaScriptRule; +import org.sonar.plugins.javascript.api.TypeScriptRule; + +@TypeScriptRule +@JavaScriptRule +@Rule(key = "S6757") +public class NoThisInSfcCheck implements EslintBasedCheck { + + @Override + public String eslintKey() { + return "no-this-in-sfc"; + } +} From 4b0f7b16ed88a17fef3107196ccecfb1e808faea Mon Sep 17 00:00:00 2001 From: Alexander Kamushkin Date: Tue, 12 Sep 2023 11:19:25 +0200 Subject: [PATCH 3/4] update ruling issues --- .../javascript-S6757.json | 19 +++++++++++++++++++ .../react-cloud-music/javascript-S6757.json | 8 ++++++++ 2 files changed, 27 insertions(+) create mode 100644 its/ruling/src/test/expected/js/javascript-test-sources/javascript-S6757.json create mode 100644 its/ruling/src/test/expected/js/react-cloud-music/javascript-S6757.json diff --git a/its/ruling/src/test/expected/js/javascript-test-sources/javascript-S6757.json b/its/ruling/src/test/expected/js/javascript-test-sources/javascript-S6757.json new file mode 100644 index 00000000000..ff35a18b5f4 --- /dev/null +++ b/its/ruling/src/test/expected/js/javascript-test-sources/javascript-S6757.json @@ -0,0 +1,19 @@ +{ +"javascript-test-sources:src/ace/src/edit_session/bracket_match.js": [ +114, +171 +], +"javascript-test-sources:src/ace/src/editor.js": [ +2518, +2519, +2521 +], +"javascript-test-sources:src/ace/src/layer/font_metrics.js": [ +103, +111 +], +"javascript-test-sources:src/ace/src/mode/folding/mixed.js": [ +18, +20 +] +} diff --git a/its/ruling/src/test/expected/js/react-cloud-music/javascript-S6757.json b/its/ruling/src/test/expected/js/react-cloud-music/javascript-S6757.json new file mode 100644 index 00000000000..770da23a969 --- /dev/null +++ b/its/ruling/src/test/expected/js/react-cloud-music/javascript-S6757.json @@ -0,0 +1,8 @@ +{ +"react-cloud-music:src/baseUI/music-note/index.jsx": [ +47, +48, +49, +51 +] +} From 572d377f5047dbc7217e934dcfc17f72ab0cb62a Mon Sep 17 00:00:00 2001 From: Alexander Kamushkin Date: Tue, 12 Sep 2023 16:34:52 +0200 Subject: [PATCH 4/4] add true positive example --- .../test/expected/js/file-for-rules/javascript-S1172.json | 3 +++ .../test/expected/js/file-for-rules/javascript-S139.json | 3 +++ .../test/expected/js/file-for-rules/javascript-S1451.json | 3 +++ .../test/expected/js/file-for-rules/javascript-S3798.json | 3 +++ .../test/expected/js/file-for-rules/javascript-S6757.json | 5 +++++ its/sources/file-for-rules/S6757.js | 7 +++++++ 6 files changed, 24 insertions(+) create mode 100644 its/ruling/src/test/expected/js/file-for-rules/javascript-S6757.json create mode 100644 its/sources/file-for-rules/S6757.js diff --git a/its/ruling/src/test/expected/js/file-for-rules/javascript-S1172.json b/its/ruling/src/test/expected/js/file-for-rules/javascript-S1172.json index 464cc015e6f..e1474707a72 100644 --- a/its/ruling/src/test/expected/js/file-for-rules/javascript-S1172.json +++ b/its/ruling/src/test/expected/js/file-for-rules/javascript-S1172.json @@ -18,5 +18,8 @@ ], "file-for-rules:S6304.js": [ 5 +], +"file-for-rules:S6757.js": [ +2 ] } diff --git a/its/ruling/src/test/expected/js/file-for-rules/javascript-S139.json b/its/ruling/src/test/expected/js/file-for-rules/javascript-S139.json index 8b23aa9f382..2f3e09a6222 100644 --- a/its/ruling/src/test/expected/js/file-for-rules/javascript-S139.json +++ b/its/ruling/src/test/expected/js/file-for-rules/javascript-S139.json @@ -61,5 +61,8 @@ "file-for-rules:S6321.js": [ 65, 100 +], +"file-for-rules:S6757.js": [ +3 ] } diff --git a/its/ruling/src/test/expected/js/file-for-rules/javascript-S1451.json b/its/ruling/src/test/expected/js/file-for-rules/javascript-S1451.json index e619946bacf..6be4d54f9ba 100644 --- a/its/ruling/src/test/expected/js/file-for-rules/javascript-S1451.json +++ b/its/ruling/src/test/expected/js/file-for-rules/javascript-S1451.json @@ -170,6 +170,9 @@ "file-for-rules:S6746.js": [ 0 ], +"file-for-rules:S6757.js": [ +0 +], "file-for-rules:boundOrAssignedEvalOrArguments.js": [ 0 ] diff --git a/its/ruling/src/test/expected/js/file-for-rules/javascript-S3798.json b/its/ruling/src/test/expected/js/file-for-rules/javascript-S3798.json index 3b95a487693..af88de7886b 100644 --- a/its/ruling/src/test/expected/js/file-for-rules/javascript-S3798.json +++ b/its/ruling/src/test/expected/js/file-for-rules/javascript-S3798.json @@ -47,6 +47,9 @@ "file-for-rules:S6442.js": [ 3 ], +"file-for-rules:S6757.js": [ +2 +], "file-for-rules:boundOrAssignedEvalOrArguments.js": [ 2, 8 diff --git a/its/ruling/src/test/expected/js/file-for-rules/javascript-S6757.json b/its/ruling/src/test/expected/js/file-for-rules/javascript-S6757.json new file mode 100644 index 00000000000..3c1146daace --- /dev/null +++ b/its/ruling/src/test/expected/js/file-for-rules/javascript-S6757.json @@ -0,0 +1,5 @@ +{ +"file-for-rules:S6757.js": [ +3 +] +} diff --git a/its/sources/file-for-rules/S6757.js b/its/sources/file-for-rules/S6757.js new file mode 100644 index 00000000000..490ade0155d --- /dev/null +++ b/its/sources/file-for-rules/S6757.js @@ -0,0 +1,7 @@ +import React from 'react'; +function MyComponent(props){ + const foo = this.props.bar; // Noncompliant: remove 'this' + return ( +
{foo}
+ ); +}