Skip to content

Commit 16b1c9d

Browse files
authored
Add new inspection: abstract trait (#887)
* add abstract trait inspection * add to all inspections * fix readme info * change import for compiling in scala2.12 * resorct inspections in README.me, fix test
1 parent 85d47a4 commit 16b1c9d

File tree

4 files changed

+79
-2
lines changed

4 files changed

+79
-2
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,11 +157,12 @@ To suppress warnings globally for the project, use `disabledInspections` or `ove
157157

158158
### Inspections
159159

160-
There are currently 121 inspections for Scala 2, and 1 for Scala 3.
160+
There are currently 122 inspections for Scala 2, and 1 for Scala 3.
161161
An overview list is given, followed by a more detailed description of each inspection after the list (todo: finish rest of detailed descriptions)
162162

163163
| Name | Brief Description | Default Level | Scala 2 | Scala 3 |
164164
|---------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------|---------|---------|
165+
| AbstractTrait | Check if trait is abstract | Info | Yes | No |
165166
| ArrayEquals | Checks for comparison of arrays using `==` which will always return false | Info | Yes | No |
166167
| ArraysInFormat | Checks for arrays passed to String.format | Error | Yes | No |
167168
| ArraysToString | Checks for explicit toString calls on arrays | Warning | Yes | No |

src/main/scala-2/com/sksamuel/scapegoat/Inspections.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import com.sksamuel.scapegoat.inspections.option._
1616
import com.sksamuel.scapegoat.inspections.string._
1717
import com.sksamuel.scapegoat.inspections.style._
1818
import com.sksamuel.scapegoat.inspections.unneccesary._
19+
import com.sksamuel.scapegoat.inspections.traits._
1920
import com.sksamuel.scapegoat.inspections.unsafe._
2021

2122
/**
@@ -146,6 +147,7 @@ object Inspections extends App {
146147
new VarClosure,
147148
new VarCouldBeVal,
148149
new WhileTrue,
149-
new ZeroNumerator
150+
new ZeroNumerator,
151+
new AbstractTrait
150152
)
151153
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package com.sksamuel.scapegoat.inspections.traits
2+
3+
import com.sksamuel.scapegoat._
4+
5+
class AbstractTrait
6+
extends Inspection(
7+
text = "Use of abstract trait",
8+
defaultLevel = Levels.Info,
9+
description = "Traits are automatically abstract.",
10+
explanation = "The abstract modifier is used in class definitions. It is redundant for traits, and mandatory for all other classes which have incomplete members."
11+
){
12+
13+
override def inspector(ctx: InspectionContext): Inspector = {
14+
new Inspector(ctx) {
15+
override def postTyperTraverser: context.Traverser =
16+
new context.Traverser {
17+
18+
import context.global._
19+
20+
def isAbstractTrait(positions: Map[Long, Position]): Boolean = {
21+
positions.contains(Flag.TRAIT) && positions.contains(Flag.ABSTRACT)
22+
}
23+
24+
override def inspect(tree: Tree): Unit = {
25+
tree match {
26+
// I use positions, because all traits are abstract by default
27+
case ClassDef(mods, _, _, _) if isAbstractTrait(mods.positions) =>
28+
context.warn(tree.pos, self, tree.toString.take(500))
29+
case _ => continue(tree)
30+
}
31+
}
32+
}
33+
}
34+
}
35+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package com.sksamuel.scapegoat.inspections.traits
2+
3+
import com.sksamuel.scapegoat.{Inspection, InspectionTest}
4+
5+
class AbstractTraitTest extends InspectionTest {
6+
7+
override val inspections = Seq[Inspection](new AbstractTrait)
8+
9+
"abstract trait use" - {
10+
"should report warning" in {
11+
val code = "abstract trait Test { val x: Int = 1 }"
12+
13+
compileCodeSnippet(code)
14+
compiler.scapegoat.feedback.warnings.size shouldBe 1
15+
}
16+
17+
"should not report warning on sealed" in {
18+
val code = "sealed trait Test { val x: Int = 1 }"
19+
20+
compileCodeSnippet(code)
21+
compiler.scapegoat.feedback.warnings.size shouldBe 0
22+
}
23+
24+
"should not report warning on trait without modifiers" in {
25+
val code = "trait Test1 { val x: Int = 1 }"
26+
27+
compileCodeSnippet(code)
28+
compiler.scapegoat.feedback.warnings.size shouldBe 0
29+
}
30+
31+
"should not report on private trait" in {
32+
val code = "private trait Test1 { val x: Int = 1 }"
33+
34+
compileCodeSnippet(code)
35+
compiler.scapegoat.feedback.warnings.size shouldBe 0
36+
}
37+
}
38+
39+
}

0 commit comments

Comments
 (0)