@odg/eslint-config 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -10,6 +10,7 @@
10
10
  "Refactor",
11
11
  "Typescript",
12
12
  "Json",
13
- "Sonar"
13
+ "Sonar",
14
+ "Performance"
14
15
  ]
15
16
  }
package/README.md CHANGED
@@ -113,7 +113,7 @@
113
113
  - [Prefer Logical Operator Over Ternary](#prefer-logical-operator-over-ternary)
114
114
  - [Prefer Event Target](#prefer-event-target)
115
115
  - [Prefer Object From Entries](#prefer-object-from-entries)
116
- - [Prefer Array From.Map](#prefer-array-from-map)
116
+ - [Prefer Array From Map](#prefer-array-from-map)
117
117
  - [Prefer Array Flat](#prefer-array-flat)
118
118
  - [This Pattern](#this-pattern)
119
119
  - [Use Dot](#use-dot)
@@ -191,7 +191,7 @@
191
191
  - [No Unnecessary Type Assertion](#no-unnecessary-type-assertion)
192
192
  - [No Unsafe Call](#no-unsafe-call)
193
193
  - [No Var](#no-var)
194
- - [Operator BreakLine](#operator-break-line)
194
+ - [Operator Break-Line](#operator-break-line)
195
195
  - [Generator Function Stars](#generator-function-stars)
196
196
  - [No Unsafe Optional Chaining](#no-unsafe-optional-chaining)
197
197
  - [Array Callback](#array-callback)
@@ -202,7 +202,16 @@
202
202
  - [Comma Style](#comma-style)
203
203
  - [Object Break Line](#object-break-line)
204
204
  - [Object Curly Newline](#object-curly-newline)
205
- - [No Negative Condition](#no-negated-condition)
205
+ - [No Negative Condition](#no-negative-condition)
206
+ - [No Duplicated Branches](#no-duplicated-branches)
207
+ - [No Identical Functions](#no-identical-functions)
208
+ - [No Inverted Boolean Check](#no-inverted-boolean-check)
209
+ - [No Nested Switch](#no-nested-switch)
210
+ - [No Nested Template Literals](#no-nested-template-literals)
211
+ - [No Redundant Boolean](#no-redundant-boolean)
212
+ - [Prefer Immediate Return](#prefer-immediate-return)
213
+ - [Prefer Object Literal](#prefer-object-literal)
214
+ - [Prefer Single Boolean Return](#prefer-single-boolean-return)
206
215
  - [No Shadow](#no-shadow)
207
216
  - [Parentheses New Line](#parentheses-new-line)
208
217
  - [No Func Call Spacing](#no-func-call-spacing)
@@ -503,6 +512,16 @@
503
512
  - [Index Of Compare To Positive Number](#index-of-compare-to-positive-number)
504
513
  - [No Invariant Returns](#no-invariant-returns)
505
514
  - [Inconsistent Function Call](#inconsistent-function-call)
515
+ - [Duplicate Conditions](#duplicate-conditions)
516
+ - [No Element Overwrite](#no-element-overwrite)
517
+ - [No Empty Collection](#no-empty-collection)
518
+ - [No Extra Arguments](#no-extra-arguments)
519
+ - [No Identical Expressions](#no-identical-expressions)
520
+ - [No Ignored Return](#no-ignored-return)
521
+ - [No Use Of Empty Return Value](#no-use-of-empty-return-value)
522
+ - [No Collection Size Mischeck](#no-collection-size-mischeck)
523
+ - [No Gratuitous Expressions](#no-gratuitous-expressions)
524
+ - [No Unused Collection](#no-unused-collection)
506
525
  - [YAML / JSON](#yaml-json)
507
526
 
508
527
  ## Introduction
@@ -3799,7 +3818,7 @@ const object = pairs.reduce(
3799
3818
  const object = _.fromPairs(pairs);
3800
3819
  ```
3801
3820
 
3802
- ## Prefer Array From.Map
3821
+ ## Prefer Array From Map
3803
3822
 
3804
3823
  ----------
3805
3824
 
@@ -3989,7 +4008,7 @@ class Foo {
3989
4008
  }
3990
4009
  ```
3991
4010
 
3992
- ## Use IsNan
4011
+ ## Use Is-Nan
3993
4012
 
3994
4013
  ----------
3995
4014
 
@@ -4935,7 +4954,7 @@ var items = [,];
4935
4954
  var colors = [ "red",, "blue" ];
4936
4955
  ```
4937
4956
 
4938
- ## Valid TypeOf
4957
+ ## Valid Type-Of
4939
4958
 
4940
4959
  ----------
4941
4960
 
@@ -7026,7 +7045,7 @@ if (CONFIG.y) {
7026
7045
  console.log(y);
7027
7046
  ```
7028
7047
 
7029
- ## Operator BreakLine
7048
+ ## Operator Break-Line
7030
7049
 
7031
7050
  ----------
7032
7051
 
@@ -7700,6 +7719,351 @@ if (a !== b) {
7700
7719
  !a ? c : b
7701
7720
  ```
7702
7721
 
7722
+ ## No Duplicated Branches
7723
+
7724
+ ----------
7725
+
7726
+ Having two cases in a switch statement or two branches in an if chain with the same implementation
7727
+ is at best duplicate code, and at worst a coding error. If the same logic is truly needed for both instances,
7728
+ then in an if chain they should be combined, or for a switch, one should fall through to the other.
7729
+
7730
+ <https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-duplicated-branches.md>
7731
+
7732
+ 👍 Examples of correct code
7733
+
7734
+ ```typescript
7735
+ switch (i) {
7736
+ case 1:
7737
+ case 3:
7738
+ doFirstThing();
7739
+ doSomething();
7740
+ break;
7741
+ case 2:
7742
+ doSomethingDifferent();
7743
+ break;
7744
+ default:
7745
+ doTheRest();
7746
+ }
7747
+
7748
+ if ((a >= 0 && a < 10) || (a >= 20 && a < 50)) {
7749
+ doFirstThing();
7750
+ doTheThing();
7751
+ } else if (a >= 10 && a < 20) {
7752
+ doTheOtherThing();
7753
+ } else {
7754
+ doTheRest();
7755
+ }
7756
+
7757
+ // Or
7758
+
7759
+ switch (i) {
7760
+ case 1:
7761
+ doFirstThing();
7762
+ doSomething();
7763
+ break;
7764
+ case 2:
7765
+ doSomethingDifferent();
7766
+ break;
7767
+ case 3:
7768
+ doFirstThing();
7769
+ doThirdThing();
7770
+ break;
7771
+ default:
7772
+ doTheRest();
7773
+ }
7774
+
7775
+ if (a >= 0 && a < 10) {
7776
+ doFirstThing();
7777
+ doTheThing();
7778
+ } else if (a >= 10 && a < 20) {
7779
+ doTheOtherThing();
7780
+ } else if (a >= 20 && a < 50) {
7781
+ doFirstThing();
7782
+ doTheThirdThing();
7783
+ } else {
7784
+ doTheRest();
7785
+ }
7786
+ ```
7787
+
7788
+ 👎 Examples of incorrect code
7789
+
7790
+ ```typescript
7791
+ switch (i) {
7792
+ case 1:
7793
+ doFirstThing();
7794
+ doSomething();
7795
+ break;
7796
+ case 2:
7797
+ doSomethingDifferent();
7798
+ break;
7799
+ case 3: // Noncompliant; duplicates case 1's implementation
7800
+ doFirstThing();
7801
+ doSomething();
7802
+ break;
7803
+ default:
7804
+ doTheRest();
7805
+ }
7806
+
7807
+ if (a >= 0 && a < 10) {
7808
+ doFirstThing();
7809
+ doTheThing();
7810
+ } else if (a >= 10 && a < 20) {
7811
+ doTheOtherThing();
7812
+ } else if (a >= 20 && a < 50) {
7813
+ // Noncompliant; duplicates first condition
7814
+ doFirstThing();
7815
+ doTheThing();
7816
+ } else {
7817
+ doTheRest();
7818
+ }
7819
+ ```
7820
+
7821
+ ## No Identical Functions
7822
+
7823
+ ----------
7824
+
7825
+ When two functions have the same implementation, either it was a mistake -
7826
+ something else was intended - or the duplication was intentional, but may be confusing to maintainers.
7827
+ In the latter case, the code should be refactored.
7828
+
7829
+ <https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-identical-functions.md>
7830
+
7831
+ 👍 Examples of correct code
7832
+
7833
+ ```typescript
7834
+ function calculateCode() {
7835
+ doTheThing();
7836
+ doOtherThing();
7837
+ return code;
7838
+ }
7839
+
7840
+ function getName() {
7841
+ return calculateCode();
7842
+ }
7843
+ ```
7844
+
7845
+ 👎 Examples of incorrect code
7846
+
7847
+ ```typescript
7848
+ function calculateCode() {
7849
+ doTheThing();
7850
+ doOtherThing();
7851
+ return code;
7852
+ }
7853
+
7854
+ function getName() { // Noncompliant
7855
+ doTheThing();
7856
+ doOtherThing();
7857
+ return code;
7858
+ }
7859
+ ```
7860
+
7861
+ ## No Inverted Boolean Check
7862
+
7863
+ ----------
7864
+
7865
+ It is needlessly complex to invert the result of a boolean comparison. The opposite comparison should be made instead.
7866
+
7867
+ <https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-inverted-boolean-check.md>
7868
+
7869
+ 👍 Examples of correct code
7870
+
7871
+ ```typescript
7872
+ if (a !== 2) { ... }
7873
+ ```
7874
+
7875
+ 👎 Examples of incorrect code
7876
+
7877
+ ```typescript
7878
+ if (!(a === 2)) { ... } // Noncompliant
7879
+ ```
7880
+
7881
+ ## No Nested Switch
7882
+
7883
+ ----------
7884
+
7885
+ Nested switch structures are difficult to understand because you can easily confuse the cases of an inner switch
7886
+ as belonging to an outer statement. Therefore nested switch statements should be avoided.
7887
+
7888
+ <https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-nested-switch.md>
7889
+
7890
+ 👍 Examples of correct code
7891
+
7892
+ ```typescript
7893
+ function foo(n, m) {
7894
+ switch (n) {
7895
+ case 0:
7896
+ return bar(m);
7897
+ case 1:
7898
+ // ...
7899
+ default:
7900
+ // ...
7901
+ }
7902
+ }
7903
+
7904
+ function bar(m) {
7905
+ switch(m) {
7906
+ // ...
7907
+ }
7908
+ }
7909
+ ```
7910
+
7911
+ 👎 Examples of incorrect code
7912
+
7913
+ ```typescript
7914
+ function foo(n, m) {
7915
+ switch (n) {
7916
+ case 0:
7917
+ switch (m) { // Noncompliant; nested switch
7918
+ // ...
7919
+ }
7920
+ case 1:
7921
+ // ...
7922
+ default:
7923
+ // ...
7924
+ }
7925
+ }
7926
+ ```
7927
+
7928
+ ## No Nested Template Literals
7929
+
7930
+ ----------
7931
+
7932
+ Template literals (previously named "template strings") are an elegant way to build a string
7933
+ without using the + operator to make strings concatenation more readable.
7934
+
7935
+ <https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-nested-template-literals.md>
7936
+
7937
+ 👍 Examples of correct code
7938
+
7939
+ ```typescript
7940
+ let color = "red";
7941
+ let count = 3;
7942
+ let apples = color ? `${count} ${color}` : count;
7943
+ let message = `I have ${apples} apples`;
7944
+ ```
7945
+
7946
+ 👎 Examples of incorrect code
7947
+
7948
+ ```typescript
7949
+ let color = "red";
7950
+ let count = 3;
7951
+ let message = `I have ${color ? `${count} ${color}` : count} apples`;
7952
+ ```
7953
+
7954
+ ## No Redundant Boolean
7955
+
7956
+ ----------
7957
+
7958
+ Redundant Boolean literals should be removed from expressions to improve readability.
7959
+
7960
+ <https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-redundant-boolean.md>
7961
+
7962
+ 👍 Examples of correct code
7963
+
7964
+ ```typescript
7965
+ if (booleanMethod()) { /* ... */ }
7966
+ if (!booleanMethod()) { /* ... */ }
7967
+ if (booleanMethod()) { /* ... */ }
7968
+ doSomething(true);
7969
+ doSomething(booleanMethod());
7970
+ ```
7971
+
7972
+ 👎 Examples of incorrect code
7973
+
7974
+ ```typescript
7975
+ if (booleanMethod() == true) { /* ... */ }
7976
+ if (booleanMethod() == false) { /* ... */ }
7977
+ if (booleanMethod() || false) { /* ... */ }
7978
+ doSomething(!false);
7979
+ doSomething(booleanMethod() == true);
7980
+ ```
7981
+
7982
+ ## Prefer Immediate Return
7983
+
7984
+ ----------
7985
+
7986
+ Declaring a variable only to immediately return or throw it is a bad practice.
7987
+
7988
+ <https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/prefer-immediate-return.md>
7989
+
7990
+ 👍 Examples of correct code
7991
+
7992
+ ```typescript
7993
+ function ms(hours, minutes, seconds) {
7994
+ return ((hours * 60 + minutes) * 60 + seconds) * 1000;
7995
+ }
7996
+ ```
7997
+
7998
+ 👎 Examples of incorrect code
7999
+
8000
+ ```typescript
8001
+ function ms(hours, minutes, seconds) {
8002
+ const duration = ((hours * 60 + minutes) * 60 + seconds) * 1000;
8003
+
8004
+ return duration;
8005
+ }
8006
+ ```
8007
+
8008
+ ## Prefer Object Literal
8009
+
8010
+ ----------
8011
+
8012
+ Object literal syntax, which initializes an object's properties inside the object declaration is cleaner and clearer
8013
+ than the alternative: creating an empty object, and then giving it properties one by one.
8014
+
8015
+ <https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/prefer-object-literal.md>
8016
+
8017
+ 👍 Examples of correct code
8018
+
8019
+ ```typescript
8020
+ var person = {
8021
+ firstName: "John",
8022
+ middleInitial: "Q",
8023
+ lastName: "Public",
8024
+ };
8025
+ ```
8026
+
8027
+ 👎 Examples of incorrect code
8028
+
8029
+ ```typescript
8030
+ var person = {}; // Noncompliant
8031
+ person.firstName = "John";
8032
+ person.middleInitial = "Q";
8033
+ person.lastName = "Public";
8034
+ ```
8035
+
8036
+ ## Prefer Single Boolean Return
8037
+
8038
+ ----------
8039
+
8040
+ Return of boolean literal statements wrapped into if-then-else flow should be simplified.
8041
+
8042
+ <https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/prefer-single-boolean-return.md>
8043
+
8044
+ 👍 Examples of correct code
8045
+
8046
+ ```typescript
8047
+ return expression;
8048
+ ```
8049
+
8050
+ 👎 Examples of incorrect code
8051
+
8052
+ ```typescript
8053
+ if (expression) {
8054
+ return true;
8055
+ } else {
8056
+ return false;
8057
+ }
8058
+
8059
+ // or
8060
+
8061
+ if (expression) {
8062
+ return true;
8063
+ }
8064
+ return false;
8065
+ ```
8066
+
7703
8067
  ## No Shadow
7704
8068
 
7705
8069
  ----------
@@ -19153,6 +19517,365 @@ var my2ndNum = new getNum(); // Noncompliant. An empty object is returned, NOT
19153
19517
  var myNumObj2 = Num(); // Noncompliant. undefined is returned, NOT an object
19154
19518
  ```
19155
19519
 
19520
+ ### Duplicate Conditions
19521
+
19522
+ ----------
19523
+
19524
+ Having all branches in a switch or if chain with the same implementation is an error.
19525
+ Either a copy-paste error was made and something different should be executed
19526
+
19527
+ <https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-all-duplicated-branches.md>
19528
+
19529
+ 👍 Examples of correct code
19530
+
19531
+ ```typescript
19532
+ if (b == 0) { // Noncompliant
19533
+ doOneMoreThing();
19534
+ } else {
19535
+ doOneMoreThing();
19536
+ }
19537
+
19538
+ let a = b === 0 ? getValue() : getDefaultValue(); // Noncompliant
19539
+
19540
+ switch (i) { // Noncompliant
19541
+ case 1:
19542
+ doSomethingOne();
19543
+ break;
19544
+ case 2:
19545
+ doSomethingTwo();
19546
+ break;
19547
+ case 3:
19548
+ default:
19549
+ doSomething();
19550
+ }
19551
+
19552
+ ```
19553
+
19554
+ 👎 Examples of incorrect code
19555
+
19556
+ ```typescript
19557
+ if (b == 0) { // Noncompliant
19558
+ doOneMoreThing();
19559
+ } else {
19560
+ doSomethingElse();
19561
+ }
19562
+
19563
+ let a = b === 0 ? getValue() : getValue(); // Noncompliant
19564
+
19565
+ switch (i) { // Noncompliant
19566
+ case 1:
19567
+ doSomething();
19568
+ break;
19569
+ case 2:
19570
+ doSomething();
19571
+ break;
19572
+ case 3:
19573
+ doSomething();
19574
+ break;
19575
+ default:
19576
+ doSomething();
19577
+ }
19578
+ ```
19579
+
19580
+ ## No Element Overwrite
19581
+
19582
+ ----------
19583
+
19584
+ It is highly suspicious when a value is saved for a key or index and then unconditionally overwritten.
19585
+ Such replacements are likely in error.
19586
+
19587
+ <https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-element-overwrite.md>
19588
+
19589
+ 👍 Examples of correct code
19590
+
19591
+ ```typescript
19592
+ fruits[1] = "banana";
19593
+
19594
+ myMap.set("key", 1);
19595
+
19596
+ mySet.add(1);
19597
+ ```
19598
+
19599
+ 👎 Examples of incorrect code
19600
+
19601
+ ```typescript
19602
+ fruits[1] = "banana";
19603
+ fruits[1] = "apple"; // Noncompliant - value on index 1 is overwritten
19604
+
19605
+ myMap.set("key", 1);
19606
+ myMap.set("key", 2); // Noncompliant - value for key "key" is replaced
19607
+
19608
+ mySet.add(1);
19609
+ mySet.add(1); // Noncompliant - element is already in the set
19610
+ ```
19611
+
19612
+ ## No Empty Collection
19613
+
19614
+ ----------
19615
+
19616
+ When a collection is empty it makes no sense to access or iterate it. Doing so anyway is surely an error;
19617
+ either population was accidentally omitted or the developer doesn’t understand the situation.
19618
+
19619
+ <https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-empty-collection.md>
19620
+
19621
+ 👍 Examples of correct code
19622
+
19623
+ ```typescript
19624
+ let strings = [ ...anotherArray ];
19625
+
19626
+ if (strings.includes("foo")) {}
19627
+
19628
+ for (str of strings) {}
19629
+
19630
+ strings.forEach(str => doSomething(str));
19631
+ ```
19632
+
19633
+ 👎 Examples of incorrect code
19634
+
19635
+ ```typescript
19636
+ let strings = [];
19637
+
19638
+ if (strings.includes("foo")) {} // Noncompliant
19639
+
19640
+ for (str of strings) {} // Noncompliant
19641
+
19642
+ strings.forEach(str => doSomething(str)); // Noncompliant
19643
+ ```
19644
+
19645
+ ## No Extra Arguments
19646
+
19647
+ ----------
19648
+
19649
+ You can easily call a JavaScript function with more arguments than the function needs,
19650
+ but the extra arguments will be just ignored by function execution.
19651
+
19652
+ <https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-extra-arguments.md>
19653
+
19654
+ 👍 Examples of correct code
19655
+
19656
+ ```typescript
19657
+ function doSomething(a, b) {
19658
+ compute(arguments);
19659
+ }
19660
+
19661
+ doSomething(1, 2, 3);
19662
+
19663
+ // Or
19664
+
19665
+ function say(a, b) {
19666
+ print(a + " " + b);
19667
+ }
19668
+
19669
+ say("hello", "world");
19670
+ ```
19671
+
19672
+ 👎 Examples of incorrect code
19673
+
19674
+ ```typescript
19675
+ function say(a, b) {
19676
+ print(a + " " + b);
19677
+ }
19678
+
19679
+ say("hello", "world", "!"); // Noncompliant; last argument is not used
19680
+ ```
19681
+
19682
+ ## No Identical Expressions
19683
+
19684
+ ----------
19685
+
19686
+ Using the same value on either side of a binary operator is almost always a mistake. In the case of logical operators,
19687
+ it is either a copy/paste error and therefore a bug, or it is simply wasted code, and should be simplified.
19688
+ In the case of bitwise operators and most binary mathematical operators, having the same value on both sides of
19689
+ an operator yields predictable results, and should be simplified.
19690
+
19691
+ <https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-identical-expressions.md>
19692
+
19693
+ 👍 Examples of correct code
19694
+
19695
+ ```typescript
19696
+ if (a == b) {
19697
+ doX();
19698
+ }
19699
+ if (a > b) {
19700
+ doW();
19701
+ }
19702
+
19703
+ var j = 1; //always 1
19704
+ var k = 0; //always 0
19705
+ ```
19706
+
19707
+ 👎 Examples of incorrect code
19708
+
19709
+ ```typescript
19710
+ if (a == b && a == b) { // if the first one is true, the second one is too
19711
+ doX();
19712
+ }
19713
+ if (a > a) { // always false
19714
+ doW();
19715
+ }
19716
+
19717
+ var j = 5 / 5; //always 1
19718
+ var k = 5 - 5; //always 0
19719
+ ```
19720
+
19721
+ ## No Ignored Return
19722
+
19723
+ ----------
19724
+
19725
+ When the call to a function doesn’t have any side effects,
19726
+ what is the point of making the call if the results are ignored?
19727
+ In such case, either the function call is useless and should be dropped or the source code doesn’t behave as expected.
19728
+
19729
+ <https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-ignored-return.md>
19730
+
19731
+ 👍 Examples of correct code
19732
+
19733
+ ```typescript
19734
+ let char = 'hello'.lastIndexOf('e');
19735
+ ```
19736
+
19737
+ 👎 Examples of incorrect code
19738
+
19739
+ ```typescript
19740
+ 'hello'.lastIndexOf('e'); // Noncompliant
19741
+ ```
19742
+
19743
+ ### No Use Of Empty Return Value
19744
+
19745
+ ----------
19746
+
19747
+ If a function does not return anything, it makes no sense to use its output.
19748
+ Specifically, passing it to another function, or assigning its "result" to a variable is probably a bug because such
19749
+ functions return undefined, which is probably not what was intended.
19750
+
19751
+ <https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-use-of-empty-return-value.md>
19752
+
19753
+ 👍 Examples of correct code
19754
+
19755
+ ```typescript
19756
+ function foo() {
19757
+ console.log("Hello, World!");
19758
+ }
19759
+
19760
+ foo();
19761
+ ```
19762
+
19763
+ 👎 Examples of incorrect code
19764
+
19765
+ ```typescript
19766
+ function foo() {
19767
+ console.log("Hello, World!");
19768
+ }
19769
+
19770
+ a = foo();
19771
+ ```
19772
+
19773
+ ## No Collection Size Mischeck
19774
+
19775
+ ----------
19776
+
19777
+ The size of a collection and the length of an array are always greater than or equal to zero.
19778
+ So testing that a size or length is greater than or equal to zero doesn't make sense, since the result is always true.
19779
+ Similarly testing that it is less than zero will always return false.
19780
+ Perhaps the intent was to check the non-emptiness of the collection or array instead.
19781
+
19782
+ <https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-collection-size-mischeck.md>
19783
+
19784
+ 👍 Examples of correct code
19785
+
19786
+ ```typescript
19787
+ if (someSet.size > 0) {...}
19788
+
19789
+ if (someMap.size == 0) {...}
19790
+
19791
+ const result = someArray.length > 0;
19792
+ ```
19793
+
19794
+ 👎 Examples of incorrect code
19795
+
19796
+ ```typescript
19797
+ if (someSet.size >= 0) {...} // Noncompliant
19798
+
19799
+ if (someMap.size < 0) {...} // Noncompliant
19800
+
19801
+ const result = someArray.length >= 0; // Noncompliant
19802
+ ```
19803
+
19804
+ ## No Gratuitous Expressions
19805
+
19806
+ ----------
19807
+
19808
+ If a boolean expression doesn’t change the evaluation of the condition, then it is entirely unnecessary,
19809
+ and can be removed. If it is gratuitous because it does not match the programmer’s intent,
19810
+ then it’s a bug and the expression should be fixed.
19811
+
19812
+ <https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-gratuitous-expressions.md>
19813
+
19814
+ 👍 Examples of correct code
19815
+
19816
+ ```typescript
19817
+ if (a) {
19818
+ if (b) {
19819
+ doSomething();
19820
+ }
19821
+ }
19822
+
19823
+ // or
19824
+ if (a) {
19825
+ doSomething();
19826
+ }
19827
+ ```
19828
+
19829
+ 👎 Examples of incorrect code
19830
+
19831
+ ```typescript
19832
+ if (a) {
19833
+ if (a) { // Noncompliant
19834
+ doSomething();
19835
+ }
19836
+ }
19837
+
19838
+ // Or
19839
+
19840
+ if (a) {
19841
+ console.log("anything");
19842
+
19843
+ if (a) { // Noncompliant
19844
+ doSomething();
19845
+ }
19846
+ }
19847
+ ```
19848
+
19849
+ ### No Unused Collection
19850
+
19851
+ ----------
19852
+
19853
+ When a collection is populated but its contents are never used, then it is surely some kind of mistake.
19854
+ Either refactoring has rendered the collection moot, or an access is missing.
19855
+
19856
+ <https://github.com/SonarSource/eslint-plugin-sonarjs/blob/HEAD/docs/rules/no-unused-collection.md>
19857
+
19858
+ 👍 Examples of correct code
19859
+
19860
+ ```typescript
19861
+ function getLength(a, b, c) {
19862
+ return a.length + b.length + c.length;
19863
+ }
19864
+ ```
19865
+
19866
+ 👎 Examples of incorrect code
19867
+
19868
+ ```typescript
19869
+ function getLength(a, b, c) {
19870
+ const strings = []; // Noncompliant
19871
+ strings.push(a);
19872
+ strings.push(b);
19873
+ strings.push(c);
19874
+
19875
+ return a.length + b.length + c.length;
19876
+ }
19877
+ ```
19878
+
19156
19879
  ## Yaml Json
19157
19880
 
19158
19881
  add suport yaml and json files
package/index.js CHANGED
@@ -13,8 +13,8 @@ module.exports = {
13
13
  "no-constructor-bind",
14
14
  "anti-trojan-source",
15
15
  "sonar",
16
- "jsonc",
17
16
  "regex",
17
+ "sonarjs",
18
18
  ],
19
19
  env: {
20
20
  node: true,
@@ -27,7 +27,6 @@ module.exports = {
27
27
  "./rules/javascript/security.js",
28
28
  "./rules/javascript/performance.js",
29
29
  "./rules/javascript/possible-errors.js",
30
- "./rules/json/base.js",
31
30
  ],
32
31
  ignorePatterns: [
33
32
  "!.*",
@@ -104,6 +103,24 @@ module.exports = {
104
103
  project: [ "tsconfig.json", "@odg/tsconfig/tsconfig.json" ], // Specify it only for TypeScript files
105
104
  },
106
105
  },
106
+ {
107
+ files: [ "*.json", "*.json5", "*.jsonc", ".eslintrc", "*.code-*" ],
108
+ plugins: [
109
+ "jsonc",
110
+ ],
111
+ extends: [
112
+ "./rules/json/base.js",
113
+ ],
114
+ },
115
+ {
116
+ files: [ "package.json" ],
117
+ extends: [
118
+ "./rules/json/base.js",
119
+ ],
120
+ rules: {
121
+ "jsonc/sort-keys": [ "off" ],
122
+ },
123
+ },
107
124
  {
108
125
  files: [ "**.php" ],
109
126
  plugins: [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@odg/eslint-config",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "Linter for JavaScript And Typescript project",
5
5
  "main": "index.js",
6
6
  "author": "Dragons Gamers <https://www.linkedin.com/in/victor-alves-odgodinho>",
@@ -38,6 +38,7 @@
38
38
  "eslint-plugin-regexp": "*",
39
39
  "eslint-plugin-security": "*",
40
40
  "eslint-plugin-sonar": "*",
41
+ "eslint-plugin-sonarjs": "*",
41
42
  "eslint-plugin-unicorn": "*",
42
43
  "eslint-plugin-yml": "*",
43
44
  "toml-eslint-parser": "*"
@@ -537,5 +537,13 @@ module.exports = {
537
537
  "sonar/regex-complexity": [ "error" ], // Regex Complexidade
538
538
  "sonar/shorthand-property-grouping": [ "error" ], // Agrupe { a, b, c:1, d:2}
539
539
  "sonar/unused-named-groups": [ "error" ], // Grupos não usados de regex
540
+ "sonarjs/no-identical-functions": [ "error" ], // Não faça funções iguais
541
+ "sonarjs/no-inverted-boolean-check": [ "error" ], // Não faça funções iguais
542
+ "sonarjs/no-nested-switch": [ "error" ], // Não faça switch dentro do outro
543
+ "sonarjs/no-nested-template-literals": [ "error" ], // Não faça string Template dentro de outra
544
+ "sonarjs/no-redundant-boolean": [ "error" ], // Não faça !false ou `boolReturnFunc() || false`
545
+ "sonarjs/prefer-immediate-return": [ "error" ], // Prefira retornar imediatamente a variável
546
+ "sonarjs/prefer-object-literal": [ "error" ], // Prefira declarar dentro do objeto inicial ao invés de injetar
547
+ "sonarjs/prefer-single-boolean-return": [ "error" ], // Retorne a boolean em vez de fazer if e else
540
548
  },
541
549
  };
@@ -57,5 +57,17 @@ module.exports = {
57
57
  "sonar/no-misleading-array-reverse": [ "error" ], // Não salva array.revert variável
58
58
  "sonar/strings-comparison": [ "error" ], // Não faça comparação de string com < ou >
59
59
  "sonar/useless-string-operation": [ "error" ], // Não use função string sem salvar variável
60
+ "sonarjs/no-all-duplicated-branches": [ "error" ], // Não faça condições duplicadas
61
+ "sonarjs/no-element-overwrite": [ "error" ], // Não sobrescreva variável de forma desnecessária
62
+ "sonarjs/no-empty-collection": [ "error" ], // Não interaja com array vazios
63
+ "sonarjs/no-extra-arguments": [ "error" ], // Não passe argumentos extra
64
+ "sonarjs/no-identical-expressions": [ "error" ], // Não faça condições iguais
65
+ "sonarjs/no-ignored-return": [ "error" ], // Use retorno das funções
66
+ "sonarjs/no-use-of-empty-return-value": [ "error" ], // Não atribua void em uma variável
67
+ "sonarjs/no-collection-size-mischeck": [ "error" ], // Não atribua void em uma variável
68
+ "sonarjs/no-duplicate-string": [ "error" ], // Não permite string duplicadas
69
+ "sonarjs/no-duplicated-branches": [ "error" ], // Em vez de if else igual faça um ||
70
+ "sonarjs/no-gratuitous-expressions": [ "error" ], // Não faça a mesma condição dentro de outra
71
+ "sonarjs/no-unused-collection": [ "error" ], // Não faça array que não é usado
60
72
  },
61
73
  };
@@ -2,29 +2,18 @@ module.exports = {
2
2
  extends: [
3
3
  "plugin:jsonc/all",
4
4
  ],
5
- overrides: [
6
- {
7
- files: [ "*.json", "*.json5", "*.jsonc", ".eslintrc", "*.code-*" ],
8
- parser: require.resolve("jsonc-eslint-parser"),
9
- rules: {
10
- "jsonc/array-bracket-spacing": [ "error", "always" ],
11
- "jsonc/key-name-casing": [ "off" ],
12
- "strict": [ "off" ],
13
- "no-unused-expressions": [ "off" ],
14
- "import/unambiguous": [ "off" ],
15
- "filenames/match-regex": [ "off" ],
16
- "jsonc/object-curly-spacing": [ "error", "always" ], // Espaço declarar objeto
17
- "jsonc/object-curly-newline": [
18
- "error",
19
- { "consistent": true },
20
- ], // Força quebrar linha em todos #4 os itens objeto
21
- },
22
- },
23
- {
24
- files: [ "package.json" ],
25
- rules: {
26
- "jsonc/sort-keys": [ "off" ],
27
- },
28
- },
29
- ],
5
+ parser: require.resolve("jsonc-eslint-parser"),
6
+ rules: {
7
+ "jsonc/array-bracket-spacing": [ "error", "always" ],
8
+ "jsonc/key-name-casing": [ "off" ],
9
+ "strict": [ "off" ],
10
+ "no-unused-expressions": [ "off" ],
11
+ "import/unambiguous": [ "off" ],
12
+ "filenames/match-regex": [ "off" ],
13
+ "jsonc/object-curly-spacing": [ "error", "always" ], // Espaço declarar objeto
14
+ "jsonc/object-curly-newline": [
15
+ "error",
16
+ { "consistent": true },
17
+ ], // Força quebrar linha em todos #4 os itens objeto
18
+ },
30
19
  };
@@ -24,5 +24,7 @@ module.exports = {
24
24
  ], // Switch com typo coloque default ou todos os casos
25
25
  "brace-style": [ "off" ], // Força formatação {}
26
26
  "@typescript-eslint/brace-style": [ "error" ], // Força formatação {}
27
+ "sonarjs/no-extra-arguments": [ "off" ], // Argumentos extra ja é tratado por typescript
28
+ "sonarjs/no-use-of-empty-return-value": [ "off" ], // Não atribua void em uma variável
27
29
  },
28
30
  };