Skip to content

Commit

Permalink
New ImplicitClassPrivateParams rule scalacenter#542
Browse files Browse the repository at this point in the history
  • Loading branch information
LeonardMeyer committed Jan 17, 2018
1 parent 0019914 commit 2a5e005
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package scalafix.internal.rule

import scala.meta.quasiquotes.XtensionQuasiquoteInit
import scala.meta.{Ctor, Defn, Mod, Template, Term}
import scalafix.rule.RuleCtx
import scalafix.{Patch, Rule}

case object ImplicitClassPrivateVal
extends Rule("ImplicitClassPrivateVal") {

override def description: String =
"Add private access modifier to val parameters of implicit value classes in order to prevent public access"

override def fix(ctx: RuleCtx): Patch = {
ctx.tree.collect {
case Defn.Class(cMods, _, _, Ctor.Primary(_, _, (Term.Param(pMods, _, _, _) :: Nil) :: Nil), Template(_, init"AnyVal" :: Nil, _, _))
if cMods.exists(_.is[Mod.Implicit]) =>
val optPatch = for {
anchorMod <- pMods.find(!_.is[Mod.Annot]) if !containsPrivateOrProtected(pMods)
} yield ctx.addLeft(anchorMod, "private ")
optPatch.asPatch

}.asPatch
}

private def containsPrivateOrProtected(pMods: List[Mod]) =
pMods.exists(m => m.is[Mod.Private] || m.is[Mod.Protected])
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ object ScalafixRules {
NoFinalize,
DottyKeywords,
DottyVarArgPattern,
DisableSyntax()
DisableSyntax(),
ImplicitClassPrivateVal
)
def semantic(index: SemanticdbIndex): List[Rule] = List(
NoInfer(index, NoInferConfig.default),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
rules = ImplicitClassPrivateVal
*/
package test

object ImplicitClassPrivateVal {
implicit class XtensionVal(val int: Int) extends AnyVal {
def doubled: Int = int + int
}

implicit class XtensionFinalVal(final val int: Int) extends AnyVal {
def doubled: Int = int + int
}

implicit class XtensionAnnotatedVal(@transient val str: String) extends AnyVal {
def doubled: String = str + str
}

implicit class XtensionAnnotatedFinalVal(@transient final val str: String) extends AnyVal {
def doubled: String = str + str
}

implicit class XtensionAnnotatedProtectedVal(@transient protected val int: Int) extends AnyVal {
def doubled: Int = int + int
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package test

object ImplicitClassPrivateVal {
implicit class XtensionVal(private val int: Int) extends AnyVal {
def doubled: Int = int + int
}

implicit class XtensionFinalVal(private final val int: Int) extends AnyVal {
def doubled: Int = int + int
}

implicit class XtensionAnnotatedVal(@transient private val str: String) extends AnyVal {
def doubled: String = str + str
}

implicit class XtensionAnnotatedFinalVal(@transient private final val str: String) extends AnyVal {
def doubled: String = str + str
}

implicit class XtensionAnnotatedProtectedVal(@transient protected val int: Int) extends AnyVal {
def doubled: Int = int + int
}
}
1 change: 1 addition & 0 deletions website/src/main/resources/microsite/data/rules.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ rules:
- Disable
- DisableSyntax
- DisableUnless
- ImplicitClassPrivateVal
25 changes: 25 additions & 0 deletions website/src/main/tut/docs/rules/ImplicitClassPrivateVal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
layout: docs
title: ImplicitClassPrivateVal
---

# ImplicitClassPrivateVal

`val` fields of implicit classes are accessible as an extension.
This rule adds the `private` access modifier in such cases in order to prevent direct access.

```scala
// before
implicit class XtensionVal(val str: String) extends AnyVal {
def doubled: String = str + str
}
"message".str // compiles

// after
implicit class XtensionValFixed(private val str: String) extends AnyVal {
def doubled: String = str + str
}
"message".str // does not compile
```

This rule safely ignores all other modifiers.

0 comments on commit 2a5e005

Please sign in to comment.