-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
182 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
/* | ||
rule = ObjectFinal | ||
*/ | ||
package fix | ||
|
||
object ObjectFinalTest { | ||
final val a1: List[String] = List.empty[String] // assert: ObjectFinal | ||
final val a2 = List.empty[String] | ||
|
||
final def b1: List[String] = List.empty[String] // assert: ObjectFinal | ||
final def b2 = List.empty[String] // assert: ObjectFinal | ||
final def b3 = "a" // assert: ObjectFinal | ||
final def b4 = 123 // assert: ObjectFinal | ||
|
||
final val c1: Boolean = false | ||
final val c2: Byte = 2 | ||
final val c3: Short = 3 | ||
final val c4: Char = 'x' | ||
final val c5: Int = 5 | ||
final val c6: Long = 6L | ||
final val c7: Float = 1.5f | ||
final val c8: Double = 2.5 | ||
|
||
final val d1: scala.Boolean = false | ||
final val d2: scala.Byte = 2 | ||
final val d3: scala.Short = 3 | ||
final val d4: scala.Char = 'x' | ||
final val d5: scala.Int = 5 | ||
final val d6: scala.Long = 6L | ||
final val d7: scala.Float = 1.5f | ||
final val d8: scala.Double = 2.5 | ||
|
||
final val e1: _root_.scala.Boolean = false | ||
final val e2: _root_.scala.Byte = 2 | ||
final val e3: _root_.scala.Short = 3 | ||
final val e4: _root_.scala.Char = 'x' | ||
final val e5: _root_.scala.Int = 5 | ||
final val e6: _root_.scala.Long = 6L | ||
final val e7: _root_.scala.Float = 1.5f | ||
final val e8: _root_.scala.Double = 2.5 | ||
|
||
final val s1: String = "s" | ||
final val s2: Predef.String = "s" | ||
final val s3: scala.Predef.String = "s" | ||
final val s4: _root_.scala.Predef.String = "s" | ||
final val s5: java.lang.String = "s" | ||
final val s6: _root_.java.lang.String = "s" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
package fix | ||
|
||
import scala.meta.Defn | ||
import scala.meta.Mod | ||
import scala.meta.Pat | ||
import scala.meta.Term | ||
import scala.meta.Type | ||
import scalafix.Patch | ||
import scalafix.lint.Diagnostic | ||
import scalafix.lint.LintSeverity | ||
import scalafix.v1.SyntacticDocument | ||
import scalafix.v1.SyntacticRule | ||
|
||
object ObjectFinal { | ||
private val constantTypes: Seq[Type] = { | ||
val values = Seq( | ||
"Boolean", | ||
"Byte", | ||
"Short", | ||
"Char", | ||
"Int", | ||
"Long", | ||
"Float", | ||
"Double", | ||
).map(Type.Name.apply) | ||
|
||
Seq( | ||
values.flatMap { x => | ||
Seq( | ||
x, | ||
Type.Select( | ||
Term.Name("scala"), | ||
x, | ||
), | ||
Type.Select( | ||
Term.Select( | ||
Term.Name("_root_"), | ||
Term.Name("scala") | ||
), | ||
x | ||
) | ||
) | ||
}, { | ||
val str = Type.Name("String") | ||
|
||
Seq( | ||
str, | ||
Type.Select( | ||
Term.Name("Predef"), | ||
str, | ||
), | ||
Type.Select( | ||
Term.Select( | ||
Term.Name("scala"), | ||
Term.Name("Predef") | ||
), | ||
str | ||
), | ||
Type.Select( | ||
Term.Select( | ||
Term.Select( | ||
Term.Name("_root_"), | ||
Term.Name("scala") | ||
), | ||
Term.Name("Predef") | ||
), | ||
str | ||
), | ||
Type.Select( | ||
Term.Select( | ||
Term.Name("java"), | ||
Term.Name("lang") | ||
), | ||
str | ||
), | ||
Type.Select( | ||
Term.Select( | ||
Term.Select( | ||
Term.Name("_root_"), | ||
Term.Name("java") | ||
), | ||
Term.Name("lang") | ||
), | ||
str | ||
), | ||
) | ||
} | ||
).flatten | ||
} | ||
|
||
private object FinalMod { | ||
def unapply(values: List[Mod]): Option[Mod] = values.find(_.is[Mod.Final]) | ||
} | ||
} | ||
|
||
class ObjectFinal extends SyntacticRule("ObjectFinal") { | ||
|
||
override def fix(implicit doc: SyntacticDocument): Patch = { | ||
doc.tree.collect { case o: Defn.Object => | ||
o.templ.stats.collect { | ||
case Defn.Val( | ||
ObjectFinal.FinalMod(m), | ||
List(Pat.Var(_: Term.Name)), | ||
Some(tpe), | ||
_ | ||
) if ObjectFinal.constantTypes.forall(_.structure != tpe.structure) => | ||
Patch.lint( | ||
Diagnostic( | ||
id = "", | ||
message = | ||
"redundant final https://scala-lang.org/files/archive/spec/2.13/06-expressions.html#constant-expressions", | ||
position = m.pos, | ||
severity = LintSeverity.Warning | ||
) | ||
) | ||
case Defn.Def.After_4_7_3( | ||
ObjectFinal.FinalMod(m), | ||
_, | ||
_, | ||
_, | ||
_ | ||
) => | ||
Patch.lint( | ||
Diagnostic( | ||
id = "", | ||
message = "redundant final", | ||
position = m.pos, | ||
severity = LintSeverity.Warning | ||
) | ||
) | ||
}.asPatch | ||
}.asPatch | ||
} | ||
} |