Skip to content

Add more Dart rules #4062

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
075b9c4
Modify rule S6582: Add Dart language
leveretka Jul 12, 2024
ba36bfe
Modify rule S6606: Add Dart language
leveretka Jul 12, 2024
888fe89
Modify rule S6207: Add Dart language
leveretka Jul 12, 2024
1f12491
Modify rule S1116: Add Dart example with empty "else"
leveretka Jul 12, 2024
468413c
Modify rule S927: Add Dart language
leveretka Jul 12, 2024
fcb5c77
Modify rule S1155: Add Dart language
leveretka Jul 12, 2024
cee2e6a
Modify rule S2933: Add Dart language
leveretka Jul 12, 2024
d26bcec
Modify rule S2971: Add Dart language
leveretka Jul 12, 2024
0cc5d2f
Modify rule S4123: Add Dart language
leveretka Jul 12, 2024
82009fd
Modify rule S120: Add Dart language
leveretka Jul 12, 2024
316505c
Modify rule S1679: Add Dart language
leveretka Jul 12, 2024
948ce4d
Fix tags and descriptions
leveretka Jul 12, 2024
bc2589a
Modify rule S2159: Add Dart language
leveretka Jul 12, 2024
b7bd409
Modify rule S3257: Add Dart language
leveretka Jul 12, 2024
6f520f8
Modify rule S6619: Add Dart language
leveretka Jul 12, 2024
d1c77d9
Modify rule S3562: Add Dart language
leveretka Jul 12, 2024
a5fc596
Fix asciidoc
leveretka Jul 12, 2024
ab4c919
Modify rule S3240: Add Dart language
leveretka Jul 12, 2024
52b85be
Modify rule S5416: Add Dart language
leveretka Jul 12, 2024
a255600
Fix "Sonar way" quality profile typo
leveretka Jul 12, 2024
994e050
Modify rule S2175: Add Dart language
leveretka Jul 12, 2024
7fae6fe
Modify rule S3962: Add Dart language
leveretka Jul 12, 2024
b0410a9
Modify rule S2471: Add Dart language
leveretka Jul 13, 2024
601cb6a
Modify rule S3512: Add Dart language
leveretka Jul 13, 2024
f0e1a61
Modify rule S2432: Add Dart language
leveretka Jul 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion rules/S1116/dart/rule.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ void f() {
}
----

[source,dart,diff-id=3,diff-type=noncompliant]
----
void f() {
if (complicated.expression.foo())
bar();
else ; // Noncompliant else is empty
buzz();
}
----

==== Compliant solution

[source,dart,diff-id=1,diff-type=compliant]
Expand All @@ -38,6 +48,17 @@ void f() {
}
----

[source,dart,diff-id=3,diff-type=compliant]
----
void f() {
if (complicated.expression.foo())
bar();
else
buzz();
}
----

== Resources

* https://dart.dev/tools/linter-rules/empty_statements[Dart Lint rule]
* https://dart.dev/tools/linter-rules/empty_statements[Dart Lint rule - empty_statements]
* https://dart.dev/tools/linter-rules/avoid_empty_else[Dart Lint rule - avoid_empty_else]
3 changes: 3 additions & 0 deletions rules/S1155/dart/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"title": "\"isEmpty\" or \"isNotEmpty\" should be used to test for emptiness"
}
36 changes: 36 additions & 0 deletions rules/S1155/dart/rule.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
== Why is this an issue?

When you call `isEmpty` or `isNotEmpty`, it clearly communicates the code's intention, which is to check if the collection is empty. Using `.length == 0` for this purpose is less direct and makes the code slightly more complex.

[source,dart,diff-id=1,diff-type=noncompliant]
----
void fun(List<int> myList) {
if (myList.length == 0) { // Noncompliant
// do something
}

if (myList.length != 0) { // Noncompliant
// do something
}

}
----


[source,dart,diff-id=1,diff-type=compliant]
----
void fun(List<int> myList) {
if (myList.isEmpty) {
// do something
}

if (myList.isNotEmpty) {
// do something
}

}
----

== Resources

* https://dart.dev/tools/linter-rules/prefer_is_empty[Dart Lint rule]
3 changes: 3 additions & 0 deletions rules/S120/dart/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{

}
17 changes: 17 additions & 0 deletions rules/S120/dart/rule.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
== Why is this an issue?

Shared naming conventions improve readability and allow teams to collaborate efficiently.
In Dart the convention is that all package names should be in lowercase with parts separated with underscore. This rule checks that all package names comply with this convention.

Noncompliant package names:

* myPackage
* My_Package

Compliant package name:

* my_package

== Resources

* https://dart.dev/tools/linter-rules/package_names[Dart Lint rule]
31 changes: 0 additions & 31 deletions rules/S1679/cfamily/metadata.json
Original file line number Diff line number Diff line change
@@ -1,34 +1,3 @@
{
"title": "The original exception object should be rethrown",
"type": "BUG",
"code": {
"impacts": {
"RELIABILITY": "MEDIUM"
},
"attribute": "EFFICIENT"
},
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [

],
"extra": {
"replacementRules": [

],
"legacyKeys": [

]
},
"defaultSeverity": "Major",
"ruleSpecification": "RSPEC-1679",
"sqKey": "S1679",
"scope": "All",
"defaultQualityProfiles": [
"Sonar way"
],
"quickfix": "unknown"
}
3 changes: 3 additions & 0 deletions rules/S1679/dart/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{

}
51 changes: 51 additions & 0 deletions rules/S1679/dart/rule.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
== Why is this an issue?

In dart `throw` is used no initiate an exception. Usually this is enough to just catch it and handle. However, there are cases when the exceptions needs to be propagated further after being caught. This allows a handling of the exception on different levels.
In such case it's recommended to use `rethrow` instead of just `throw`, to preserve the original stacktrace.

[source,dart]
----
try {
...
} catch (ex, stacktrace) {
rethrow ex; // preserves the original exception with its stacktrace
}
----

== How to fix it

The rule raises an issue when the argument of the `throw` expression is an unmodified copy of the caught exception.

=== Code examples

==== Noncompliant code example

[source,dart,diff-id=1,diff-type=noncompliant]
----
void foo() {
try {
methodThrowsException();
} catch (ex) {
// ...
throw ex; // Noncompliant
}
}
----

==== Compliant solution

[source,dart,diff-id=1,diff-type=compliant]
----
void foo() {
try {
methodThrowsException();
} catch (ex) {
// ...
rethrow ex;
}
}
----

== Resources

* https://dart.dev/tools/linter-rules/use_rethrow_when_possible[Dart Lint rule]
32 changes: 32 additions & 0 deletions rules/S1679/metadata.json
Original file line number Diff line number Diff line change
@@ -1,2 +1,34 @@
{
"title": "The original exception object should be rethrown",
"type": "BUG",
"code": {
"impacts": {
"RELIABILITY": "MEDIUM"
},
"attribute": "EFFICIENT"
},
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [

],
"extra": {
"replacementRules": [

],
"legacyKeys": [

]
},
"defaultSeverity": "Major",
"ruleSpecification": "RSPEC-1679",
"sqKey": "S1679",
"scope": "All",
"defaultQualityProfiles": [
"Sonar way"
],
"quickfix": "unknown"
}
3 changes: 3 additions & 0 deletions rules/S2159/dart/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{

}
23 changes: 23 additions & 0 deletions rules/S2159/dart/rule.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
== Why is this an issue?

Comparisons of dissimilar types will always return false. The comparison and all its dependent code can simply be removed. This includes:

* comparing an object with null
* comparing an object with an unrelated primitive (E.G. a string with an int)
* comparing unrelated types

=== Noncompliant code example

[source,dart]
----
void f() {
var a = "Hello, World!";
if (a == 42) {
print("BOOM!");
}
}
----

== Resources

* https://dart.dev/tools/linter-rules/unrelated_type_equality_checks[Dart Lint rule]
3 changes: 3 additions & 0 deletions rules/S2175/dart/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"title": "Inappropriate collection calls should not be made"
}
47 changes: 47 additions & 0 deletions rules/S2175/dart/rule.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
== Why is this an issue?

The Dart collections API has methods that allow developers to overcome type-safety restriction of the parameter, such as `Iterable.contains`. When the actual type of the object provided to these methods is not consistent with the target collection's actual type, those methods will always return `false` or `null`. This is most likely unintended and hides a design problem.

This rule raises an issue when the type of the argument of the following APIs is unrelated to the type used for the collection declaration:

* `Iterable<E>.contains`
* `List<E>.remove`
* `Map<K, V>.containsKey`
* `Map<K, V>.containsValue`
* `Map<K, V>.remove`
* `Map<K, V>.[]`
* `Queue<E>.remove`
* `Set<E>.lookup`
* `Set<E>.remove`

=== Noncompliant code example

[source,dart]
----
void foo(List<String> list, Map<Int, String> map) {

list.contains(100); // Noncompliant, list contains only Strings
list.remove(3.14); // Noncompliant

map.containsKey["a"]; // Noncompliant
map["123"]; // Noncompliant
}
----

=== Compliant solution

[source,dart]
----
void foo(List<String> list, Map<Int, String> map) {

list.contains("100");
list.remove("3.14");

map.containsValue["a"];
map[123];
}
----

== Resources

* https://dart.dev/tools/linter-rules/collection_methods_unrelated_type[Dart Lint rule]
3 changes: 3 additions & 0 deletions rules/S2432/dart/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"title": "Setters should not declare return types"
}
40 changes: 40 additions & 0 deletions rules/S2432/dart/rule.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
== Why is this an issue?

In Dart, a setter is a special type of function that is used to set the value of a property on an object. Setters are defined using the ``++set++`` keyword followed by the name of the property that the setter is associated with.

To set the property, we simply assign a value to it as if it were a regular property. The setter function is automatically called with the value that we assign to the property.

Functions declared with the ``++set++`` keyword can't return any value, so setting any return type other than `void` is a compile-time error. While this is possible to still add `void` return type it is redundant and should be omitted.

[source,dart,diff-id=1,diff-type=noncompliant]
----
class Person {
String name;
int birthYear;

Person(this.name, this.birthYear);

// Adding a calculated property age
int get age => currentYear - birthYear;
void set age(int value) => birthYear = currentYear - value; // Noncompliant
}
----

[source,dart,diff-id=1,diff-type=compliant]
----
class Person {
String name;
int birthYear;

Person(this.name, this.birthYear);

// Adding a calculated property age
int get age => currentYear - birthYear;
set age(int value) => birthYear = currentYear - value;
}
----

== Resources

* https://dart.dev/tools/linter-rules/avoid_return_types_on_setters[Dart Lint rule]
* https://dart.dev/language/methods#getters-and-setters[Getters and setters]
31 changes: 0 additions & 31 deletions rules/S2432/javascript/metadata.json
Original file line number Diff line number Diff line change
@@ -1,34 +1,3 @@
{
"title": "Setters should not return values",
"type": "BUG",
"code": {
"impacts": {
"RELIABILITY": "MEDIUM"
},
"attribute": "CLEAR"
},
"status": "ready",
"remediation": {
"func": "Constant\/Issue",
"constantCost": "5min"
},
"tags": [

],
"extra": {
"replacementRules": [

],
"legacyKeys": [

]
},
"defaultSeverity": "Major",
"ruleSpecification": "RSPEC-2432",
"sqKey": "S2432",
"scope": "Main",
"defaultQualityProfiles": [
"Sonar way"
],
"quickfix": "unknown"
}
Loading