Skip to content

Commit

Permalink
DisableSyntax add regex
Browse files Browse the repository at this point in the history
  • Loading branch information
MasseGuillaume committed Dec 10, 2017
1 parent 9016b49 commit 080c867
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ import MetaconfigPendingUpstream.XtensionConfScalafix

import scala.meta.tokens.Token

import java.util.regex.{Pattern, PatternSyntaxException}

case class DisableSyntaxConfig(
keywords: Set[DisabledKeyword] = Set(),
noSemicolons: Boolean = false,
noTabs: Boolean = false,
noXml: Boolean = false
noXml: Boolean = false,
regex: List[CustomMessage[Pattern]] = Nil
) {
implicit val reader: ConfDecoder[DisableSyntaxConfig] =
ConfDecoder.instanceF[DisableSyntaxConfig](
Expand All @@ -19,12 +22,27 @@ case class DisableSyntaxConfig(
c.getField(keywords) |@|
c.getField(noSemicolons) |@|
c.getField(noTabs) |@|
c.getField(noXml)
c.getField(noXml) |@|
c.getField(regex)
).map {
case (((a, b), c), d) =>
DisableSyntaxConfig(a, b, c, d)
case ((((a, b), c), d), e) =>
DisableSyntaxConfig(a, b, c, d, e)
})

implicit val patternReader: ConfDecoder[Pattern] = {
ConfDecoder.stringConfDecoder.flatMap(pattern =>
try {
Configured.Ok(Pattern.compile(pattern, Pattern.MULTILINE))
} catch {
case ex: PatternSyntaxException =>
Configured.NotOk(ConfError.msg(ex.getMessage))
}
)
}

implicit val customMessageReader: ConfDecoder[CustomMessage[Pattern]] =
CustomMessage.decoder(field = "pattern")

def isDisabled(keyword: String): Boolean =
keywords.contains(DisabledKeyword(keyword))
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package scalafix.internal.rule

import scala.meta._
import scala.meta.tokens.Token.Comment
import metaconfig.{Conf, Configured}
import scalafix.rule.{Rule, RuleCtx}
import scalafix.lint.LintMessage
import scalafix.lint.LintCategory
import scalafix.util.SymbolMatcher
import scalafix.internal.util.IntervalSet
import scalafix.internal.config.{DisableSyntaxConfig, Keyword}
import scalafix.syntax._

Expand All @@ -23,16 +25,33 @@ final case class DisableSyntax(
.map(DisableSyntax(_))

override def check(ctx: RuleCtx): Seq[LintMessage] = {
ctx.tree.tokens.collect {
case token @ Keyword(keyword) if config.isDisabled(keyword) =>
errorCategory.copy(id = s"keywords.$keyword").at(s"$keyword is disabled", token.pos)
case token @ Token.Semicolon() if config.noSemicolons =>
error("noSemicolons", token)
case token @ Token.Tab() if config.noTabs =>
error("noTabs", token)
case token @ Token.Xml.Start() if config.noXml =>
error("noXml", token)
}.toSeq
def pos(offset: Int): Position =
Position.Range(ctx.input, offset, offset)
val regexLintMessages = Seq.newBuilder[LintMessage]
config.regex.foreach{regex =>
val matcher = regex.value.matcher(ctx.input.chars)
val pattern = regex.value.pattern
val message = regex.message.getOrElse(s"$pattern is disabled")
while(matcher.find()) {
regexLintMessages +=
errorCategory
.copy(id = pattern)
.at(message, pos(matcher.start))
}
}
val tokensLintMessage =
ctx.tree.tokens.collect {
case token @ Keyword(keyword) if config.isDisabled(keyword) =>
errorCategory.copy(id = s"keywords.$keyword").at(s"$keyword is disabled", token.pos)
case token @ Token.Semicolon() if config.noSemicolons =>
error("noSemicolons", token)
case token @ Token.Tab() if config.noTabs =>
error("noTabs", token)
case token @ Token.Xml.Start() if config.noXml =>
error("noXml", token)
}.toSeq

tokensLintMessage ++ regexLintMessages.result()
}

private val errorCategory: LintCategory =
Expand Down
18 changes: 13 additions & 5 deletions scalafix-tests/input/src/main/scala/test/DisableSyntax.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,19 @@ DisableSyntax.keywords = [
DisableSyntax.noTabs = true
DisableSyntax.noSemicolons = true
DisableSyntax.noXml = true
DisableSyntax.regex = [
{
pattern = "[P|p]imp"
message = "Please consider a less offensive word such as Extension"
}
"Await\\.result"
]
*/
package test

import scala.concurrent._
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global

case object DisableSyntax {

Expand All @@ -31,10 +39,10 @@ case object DisableSyntax {
<a>xml</a> // assert: DisableSyntax.noXml
// assert: DisableSyntax.noTabs

// implicit class StringPimp(value: String) { // assert: DisableSyntax.regex.pimp
// def -(other: String): String = s"$value - $other"
// }
implicit class StringPimp(value: String) { // assert: DisableSyntax.[P|p]imp
def -(other: String): String = s"$value - $other"
}

// // actually 7.5 million years
// Await.result(Future(42), 75.days) // assert: DisableSyntax.regex.Await.result
// actually 7.5 million years
Await.result(Future(42), 75.days) // assert: DisableSyntax.Await\.result
}

0 comments on commit 080c867

Please sign in to comment.