From 68ff6774bb91192daced8310ffe93c88ea7917d7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 26 Sep 2024 13:58:07 +0000 Subject: [PATCH] Create rule S7094: Constant patterns should not be used with type literals (type_literal_in_constant_pattern) (#4323) Co-authored-by: antonioaversa --- rules/S7094/dart/metadata.json | 24 ++++++++ rules/S7094/dart/rule.adoc | 100 +++++++++++++++++++++++++++++++++ rules/S7094/metadata.json | 2 + 3 files changed, 126 insertions(+) create mode 100644 rules/S7094/dart/metadata.json create mode 100644 rules/S7094/dart/rule.adoc create mode 100644 rules/S7094/metadata.json diff --git a/rules/S7094/dart/metadata.json b/rules/S7094/dart/metadata.json new file mode 100644 index 00000000000..13dd4695f89 --- /dev/null +++ b/rules/S7094/dart/metadata.json @@ -0,0 +1,24 @@ +{ + "title": "Constant patterns should not be used with type literals", + "type": "BUG", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "1min" + }, + "tags": [ + "pitfall" + ], + "defaultSeverity": "Major", + "ruleSpecification": "RSPEC-7094", + "sqKey": "S7094", + "scope": "All", + "defaultQualityProfiles": ["Sonar way"], + "quickfix": "unknown", + "code": { + "impacts": { + "RELIABILITY": "HIGH" + }, + "attribute": "LOGICAL" + } +} diff --git a/rules/S7094/dart/rule.adoc b/rules/S7094/dart/rule.adoc new file mode 100644 index 00000000000..95c41605bd9 --- /dev/null +++ b/rules/S7094/dart/rule.adoc @@ -0,0 +1,100 @@ +https://dart.dev/language/pattern-types#constant[Constant patterns] should not be used with type literals. + +== Why is this an issue? + +Using constant patterns with type literals is most likely a mistake. + +For example, the following code + +[source,dart] +---- +bool isANumber(Object? o) { + if (o case num) { // Checks if `o` is `num`, not if it is a `num` + return true; + } + return false; +} +---- + +will always return `false` for any input *value* of type `num` (as in `isANumber(42)`), and will returns `true` only when the input is the *type* `num` (as in `isANumber(int)`). + +This is because a constant pattern compares the value of the provided constant against the value being matched, and not against its type. + +The original intent of checking whether an `Object? o` is a `num` or not, should be expressed via a https://dart.dev/language/pattern-types#variable[typed variable pattern]: + +[source,dart] +---- +bool isANumber(Object? o) { + if (o case num n) { // Checks if `o` is a `num` and assigns the cast value to n + return true; + } + return false; +} +---- + +If the intent of the code is to only check whether the input is a `num` or not, then the `n` variable is not necessary, and a value discard can be used: + +[source,dart] +---- +bool isANumber(Object? o) { + if (o case num _) { // Checks if `o` is a `num`, and discards the cast value + return true; + } + return false; +} +---- + +== How to fix it + +Convert the https://dart.dev/language/pattern-types#constant[constant pattern] to a https://dart.dev/language/pattern-types#variable[typed variable pattern] by adding a ``++_++`` (value discard) to the type. + +=== Code examples + +==== Noncompliant code example + +[source,dart,diff-id=1,diff-type=noncompliant] +---- +bool isANumber(Object? o) { + if (o case num) { + return true; + } + return false; +} +---- + +==== Compliant solution + +[source,dart,diff-id=1,diff-type=compliant] +---- +bool isANumber(Object? o) { + if (o case num _) { + return true; + } + return false; +} +---- + +== Resources + +* Dart Docs - https://dart.dev/tools/linter-rules/type_literal_in_constant_pattern[Dart Linter rule - type_literal_in_constant_pattern] +* Dart Docs - https://dart.dev/language/pattern-types[Language - Pattern types] + +ifdef::env-github,rspecator-view[] + +''' +== Implementation Specification +(visible only on this page) + +=== Message + +Use 'TypeName _' instead of a type literal. + +=== Highlighting + +The type literal: e.g. `num` in `if (o1 case num) { }`. + +''' +== Comments And Links +(visible only on this page) + +endif::env-github,rspecator-view[] diff --git a/rules/S7094/metadata.json b/rules/S7094/metadata.json new file mode 100644 index 00000000000..2c63c085104 --- /dev/null +++ b/rules/S7094/metadata.json @@ -0,0 +1,2 @@ +{ +}