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 12, 2017
1 parent 5dbdd6b commit 7930947
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 30 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,26 @@ 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,35 @@ 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
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ class IntervalSet(range: BitSet) {
}

override def toString: String = {
val intervals =
if(range.isEmpty) Nil
val intervals =
if (range.isEmpty) Nil
else {
var cur = range.head
var start = cur
val interval = List.newBuilder[(Int, Int)]
range.tail.foreach{bit =>
if(cur + 1 != bit) {
range.tail.foreach { bit =>
if (cur + 1 != bit) {
interval += ((start, cur))
start = bit
}
Expand All @@ -29,8 +29,9 @@ class IntervalSet(range: BitSet) {
interval.result()
}

val is = intervals.map{ case (start, end) =>
s"[$start, $end]"
val is = intervals.map {
case (start, end) =>
s"[$start, $end]"
}

s"""IntervalSet(${is.mkString(", ")})"""
Expand Down
20 changes: 14 additions & 6 deletions scalafix-tests/input/src/main/scala/test/DisableSyntax.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* ONLY
/*
rules = DisableSyntax
DisableSyntax.keywords = [
var
Expand All @@ -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
}
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class CliGitDiffTests() extends FunSuite with DiffAssertions {

val expected =
s"""|Running DisableSyntax
|$newCodeAbsPath:3:3: error: [DisableSyntax.keywords.var] keywords.var is disabled
|$newCodeAbsPath:3:3: error: [DisableSyntax.keywords.var] var is disabled
| var newVar = 1
| ^
|""".stripMargin
Expand Down Expand Up @@ -90,7 +90,7 @@ class CliGitDiffTests() extends FunSuite with DiffAssertions {

val expected =
s"""|Running DisableSyntax
|$oldCodeAbsPath:7:3: error: [DisableSyntax.keywords.var] keywords.var is disabled
|$oldCodeAbsPath:7:3: error: [DisableSyntax.keywords.var] var is disabled
| var newVar = 2
| ^
|""".stripMargin
Expand Down Expand Up @@ -132,7 +132,7 @@ class CliGitDiffTests() extends FunSuite with DiffAssertions {

val expected =
s"""|Running DisableSyntax
|$newCodeAbsPath:5:3: error: [DisableSyntax.keywords.var] keywords.var is disabled
|$newCodeAbsPath:5:3: error: [DisableSyntax.keywords.var] var is disabled
| var newVar = 2
| ^
|""".stripMargin
Expand Down Expand Up @@ -190,7 +190,7 @@ class CliGitDiffTests() extends FunSuite with DiffAssertions {

val expected =
s"""|Running DisableSyntax
|$newCodeAbsPath:5:3: error: [DisableSyntax.keywords.var] keywords.var is disabled
|$newCodeAbsPath:5:3: error: [DisableSyntax.keywords.var] var is disabled
| var newVar = 2
| ^
|""".stripMargin
Expand Down

0 comments on commit 7930947

Please sign in to comment.