Skip to content

Commit

Permalink
Added new rules
Browse files Browse the repository at this point in the history
  • Loading branch information
t1b00 committed Sep 11, 2024
1 parent 66823a7 commit 5600648
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 38 deletions.
3 changes: 1 addition & 2 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@ inThisBuild(
developers := List(Developer("t1b00", "Thibault Czarniak", "[email protected]", url("https://www.linkedin.com/in/thcz/"))),
semanticdbEnabled := true,
semanticdbVersion := scalafixSemanticdb.revision,
semanticdbOptions += "synthetics:on",
scmInfo := Some(ScmInfo(url("https://github.com/dedis/scapegoat-scalafix"), "scm:[email protected]:dedis/scapegoat-scalafix.git")),
version := "1.0",
version := "1.1.2",
versionScheme := Some("pvp")
)
)
Expand Down
150 changes: 114 additions & 36 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Scalafix rules for PoPStellar
# Scapegoat-Scalafix
## Scalafix implementation of Scapegoat linter for Scala 3

## Versions:

Expand All @@ -11,15 +12,15 @@

[version]: 1.0
## Description
This subfolder contains a set of custom linter rules developed for the Scala backend of [PopStellar](https://github.com/dedis/popstellar).
They are built on top of the [Scalafix](https://scalacenter.github.io/scalafix/) framework.
Since these rules can also be used by other projects that use Scalafix, they are published on Maven Central, for Scala 2.13 and Scala 3.
This project is a Scalafix implementation of the Scapegoat linter for Scala 3. It contains a set of rules that can be run on Scala code to detect potential issues and bad practices. The rules are based on the Scapegoat linter for Scala 2, but have been adapted to work with Scalafix and Scala 3.

For now, this project has 52 rules but more are being worked on.

## Installation

To install the rules, simply add the following to your `build.sbt` file:
```
ThisBuild / scalafixDependencies += "io.github.dedis" %% "scapegoat-scalafix" % "1.0"
ThisBuild / scalafixDependencies += "io.github.dedis" %% "scapegoat-scalafix" % "1.1.1"
```

**The rules are compatible with Scala 2.13 and Scala 3 (tested for Scala 3.3.1).**
Expand All @@ -39,22 +40,62 @@ inThisBuild(

This is necessary to enable the SemanticDB, which is required for the rules to work. Only add these lines if SemanticDB is not already enabled in the `build.sbt`.

## Rule list (not up to date with latest commits)
1. **ArraysInFormat**: Checks if arrays are used in the format method of a string.
2. **CatchNpe**: Checks if a catch block catches a NullPointerException.
3. **ComparingFloatingPointTypes**: Checks if floating point types (float or double) are compared with == or !=.
4. **EmptyInterpolatedString**: Checks if an interpolated string is empty.
5. **IllegalFormatString**: Checks for illegal format strings.
6. **ImpossibleOptionSizeCondition**: Checks if an Option is compared with a size.
7. **IncorrectlyNamedExceptions**: Checks if exceptions are named correctly (end with Exception).
8. **IncorrectNumberOfArgsToFormat**: Checks if the number of arguments in a format string matches the number of arguments in the format method.
9. **LonelySealedTrait**: Checks if a sealed trait has only one implementation.
10. **MapGetGetOrElse**: Checks if a map.get is followed by a getOrElse.
11. **NanComparison**: Checks if a floating point number (float or double) is compared with Double.NaN.
12. **OptionGet**: Checks if an Option is used with get.
13. **OptionSize**: Checks if an Option is used with size.
14. **StripMarginOnRegex**: Checks if a regex is used with stripMargin.
15. **TryGet**: Checks if a Try is used with get.
## Rule list
|Name |Description |Level |
|----------------------------|-----------------------------------------------------------------------------------------------------------------------------------------|-------|
|ArraysInFormat |Checks for arrays passed to String.format |Error |
|CatchNpe |Checks for try blocks that catch null pointer exceptions |Error |
|ComparingFloatingTypes |Checks for equality checks on floating point types |Error |
|EitherGet |Checks for use of .get on Left or Right |Error |
|EmptyInterpolatedString |Looks for interpolated strings that have no arguments |Error |
|IllegalFormatString |Looks for invalid format strings |Error |
|ImpossibleOptionSizeCondition |Checks for code like option.size > 2 which can never be true |Error |
|IncorrectNumberOfArgsToFormat |Checks for wrong number of arguments to String.format |Error |
|IncorrectlyNamedExceptions |Checks for exceptions that are not called *Exception and vice versa |Error |
|LonelySealedTrait |Checks for sealed traits which have no implementation |Error |
|MapGetAndGetOrElse |Map.get(key).getOrElse(value) can be replaced with Map.getOrElse(key,value) |Error |
|NanComparison |Checks for x == Double.NaN which will always fail |Error |
|OptionGet |Checks for Option.get |Error |
|OptionSize |Checks for Option.size |Error |
|StripMarginOnRegex |Checks for .stripMargin on regex strings that contain a pipe |Error |
|TryGet |Checks for use of Try.get |Error |
|UnsafeContains |Checks for List.contains(value) for invalid types |Error |
|UnsafeStringContains |Checks for String.contains(value) for invalid types |Error |
|UnsafeTraversableMethods |Checks unsafe traversable method usages (head, tail, init, last, reduce, reduceLeft, reduceRight, max, maxBy, min, minBy) |Error |
|AvoidSizeEqualsZero |Traversable.size can be slow for some data structure, prefer .isEmpty |Warning|
|AvoidSizeNotEqualsZero |Traversable.size can be slow for some data structure, prefer .nonEmpty |Warning|
|CatchException |Checks for try blocks that catch Exception |Warning|
|CatchExceptionImmediatelyRethrown|Checks for try-catch blocks that immediately rethrow caught exceptions. |Warning|
|CatchFatal |Checks for try blocks that catch fatal exceptions: VirtualMachineError, ThreadDeath, InterruptedException, LinkageError, ControlThrowable|Warning|
|CatchThrowable |Checks for try blocks that catch Throwable |Warning|
|CollectionIndexOnNonIndexedSeq |Checks for indexing on a Seq which is not an IndexedSeq |Warning|
|CollectionNegativeIndex |Checks for negative access on a sequence e.g. list.get(-1) |Warning|
|CollectionPromotionToAny |Checks for collection operations that promote the collection to Any |Warning|
|ComparisonWithSelf |Checks for equality checks with itself |Warning|
|ConstantIf |Checks for code where the if condition compiles to a constant |Warning|
|DuplicateImport |Checks for import statements that import the same selector |Info |
|EmptyFor |Checks for empty for loops |Warning|
|EmptyIfBlock |Checks for empty if blocks |Warning|
|EmptyMethod |Looks for empty methods |Warning|
|EmptySynchronizedBlock |Looks for empty synchronized blocks |Warning|
|EmptyTryBlock |Looks for empty try blocks |Warning|
|EmptyWhileBlock |Looks for empty while loops |Warning|
|FinalizerWithoutSuper |Checks for overriden finalizers that do not call super |Warning|
|LooksLikeInterpolatedString |Finds strings that look like they should be interpolated but are not |Warning|
|MethodReturningAny |Checks for defs that are defined or inferred to return Any |Warning|
|NullAssignment |Checks for use of null in assignments |Warning|
|NullParameter |Checks for use of null in method invocation |Warning|
|RepeatedCaseBody |Checks for case statements which have the same body |Warning|
|RepeatedIfElseBody |Checks for the main branch and the else branch of an if being the same |Warning|
|SwallowedException |Find catch blocks that don't handle caught exceptions |Warning|
|UnnecessaryConversion |Checks for unnecessary toInt on instances of Int or toString on Strings, etc. |Warning|
|UnreachableCatch |Checks for catch clauses that cannot be reached |Warning|
|UnusedMethodParameter |Checks for unused method parameters |Warning|
|VarCouldBeVal |Checks for vars that could be declared as vals |Warning|
|VariableShadowing |Checks for multiple uses of the variable name in nested scopes |Warning|
|While true |Checks for code that uses a while(true) or do {} while(true) block |Warning|
|InterpolationToString |Checks for string interpolations that have .toString in their arguments |Warning|


## Usage

Expand All @@ -66,21 +107,58 @@ sbt scalafix RuleName
You can also create a `.scalafix.conf` file and enable rules in them. Here is an example with all of the rules enabled:
```
rules = [
ArraysInFormat,
CatchNpe,
ComparingFloatingPointTypes,
EmptyInterpolatedString,
IllegalFormatString,
ImpossibleOptionSizeCondition,
IncorrectlyNamedExceptions,
IncorrectNumberOfArgsToFormat,
LonelySealedTrait,
MapGetGetOrElse,
NanComparison,
OptionGet,
OptionSize,
StripMarginOnRegex,
TryGet
ArraysInFormat,
CatchNpe,
ComparingFloatingPointTypes,
EitherGet,
EmptyInterpolatedString,
IllegalFormatString,
ImpossibleOptionSizeCondition,
IncorrectNumberOfArgsToFormat,
IncorrectlyNamedExceptions,
LonelySealedTrait,
MapGetAndGetOrElse,
NanComparison,
OptionGet,
OptionSize,
StripMarginOnRegex,
TryGet,
UnsafeContains,
UnsafeStringContains,
UnsafeTraversableMethods,
AvoidSizeEqualsZero,
AvoidSizeNotEqualsZero,
CatchException,
CatchExceptionImmediatelyRethrown,
CatchFatal,
CatchThrowable,
CollectionIndexOnNonIndexedSeq,
CollectionNegativeIndex,
CollectionPromotionToAny,
ComparisonWithSelf,
ConstantIf,
DuplicateImport,
EmptyFor,
EmptyIfBlock,
EmptyMethod,
EmptySynchronizedBlock,
EmptyTryBlock,
EmptyWhileBlock,
FinalizerWithoutSuper,
LooksLikeInterpolatedString,
MethodReturningAny,
NullAssignment,
NullParameter,
RepeatedCaseBody,
RepeatedIfElseBody,
SwallowedException,
UnnecessaryConversion,
UnreachableCatch,
UnusedMethodParameter,
VarCouldBeVal,
VariableShadowing,
WhileTrue,
InterpolationToString,
]
```

Expand Down

0 comments on commit 5600648

Please sign in to comment.