Skip to content

Commit

Permalink
Move Regex pattern definitions to a separate file in preparation for SN
Browse files Browse the repository at this point in the history
  • Loading branch information
jchyb committed Sep 23, 2024
1 parent 15abf59 commit fb82d72
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 47 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package org.scalafmt.internal

import java.util.regex.Pattern

private[scalafmt] object RegexCompat {

@inline
val trailingSpace = Pattern.compile("\\h++$", Pattern.MULTILINE)

// "slc" stands for single-line comment
@inline
val slcLine = Pattern.compile("^/\\/\\/*+\\h*+(.*?)\\h*+$")

@inline
val slcDelim = Pattern.compile("\\h++")

// "mlc" stands for multi-line comment
@inline
val mlcHeader = Pattern.compile("^/\\*\\h*+(?:\n\\h*+[*]*+\\h*+)?")

@inline
val mlcLineDelim = Pattern.compile("\\h*+\n\\h*+[*]*+\\h*+")

@inline
val mlcParagraphEnd = Pattern.compile("[.:!?=]$")

@inline
val mlcParagraphBeg = Pattern.compile("^(?:[-*@=]|\\d++[.:])")

@inline
private val leadingAsteriskSpace = Pattern.compile("(?<=\n)\\h*+(?=[*][^*])")

@inline
val docstringLine = Pattern
.compile("^(?:\\h*+\\*)?(\\h*+)(.*?)\\h*+$", Pattern.MULTILINE)

@inline
private val emptyLines = "\\h*+(\n\\h*+\\*?\\h*+)*"

@inline
val emptyDocstring = Pattern.compile(s"^/\\*\\*$emptyLines\\*/$$")

@inline
val onelineDocstring = {
val oneline = "[^*\n\\h](?:[^\n]*[^\n\\h])?"
Pattern.compile(s"^/\\*\\*$emptyLines($oneline)$emptyLines\\*/$$")
}

@inline
val docstringLeadingSpace = Pattern.compile("^\\h++")

@inline
def compileStripMarginPattern(pipe: Char) = Pattern
.compile(s"(?<=\n)\\h*+(?=\\$pipe)")

@inline
def compileStripMarginPatternWithLineContent(pipe: Char) = Pattern
.compile(s"\n(\\h*+\\$pipe)?([^\n]*+)")

@inline
val stripMarginPattern = compileStripMarginPattern('|')

@inline
val stripMarginPatternWithLineContent =
compileStripMarginPatternWithLineContent('|')

@inline
private val leadingPipeSpace = compileStripMarginPattern('|')

@inline
private def getStripMarginPattern(pipe: Char) =
if (pipe == '|') leadingPipeSpace else compileStripMarginPattern(pipe)

@inline
def replaceAllStripMargin(
text: String,
spaces: String,
pipe: Char,
): String =
getStripMarginPattern(pipe).matcher(text).replaceAll(spaces)

@inline
def replaceAllLeadingAsterisk(
trimmed: String,
spaces: String,
): String = leadingAsteriskSpace.matcher(trimmed).replaceAll(spaces)

// Replaces baseText.split("(?={beforeText})")
@inline
def splitByBeforeTextMatching(
baseText: String,
beforeText: String,
): Array[String] = baseText.split(s"(?=$beforeText)")
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import org.scalafmt.Error
import org.scalafmt.Formatted
import org.scalafmt.Scalafmt
import org.scalafmt.config.{Case => _, _}
import org.scalafmt.internal.RegexCompat._
import org.scalafmt.rewrite.RedundantBraces
import org.scalafmt.util.LiteralOps
import org.scalafmt.util.TokenOps._
Expand Down Expand Up @@ -583,7 +584,7 @@ class FormatWriter(formatOps: FormatOps) {
}
tupleOpt.fold(text) { case (pipe, indent) =>
val spaces = getIndentation(indent)
getStripMarginPattern(pipe).matcher(text).replaceAll(spaces)
RegexCompat.replaceAllStripMargin(text, spaces, pipe)
}
}

Expand Down Expand Up @@ -794,7 +795,7 @@ class FormatWriter(formatOps: FormatOps) {
terminateMlc(curlen, lines)
} else {
val trimmed = removeTrailingWhiteSpace(text)
sb.append(leadingAsteriskSpace.matcher(trimmed).replaceAll(spaces))
sb.append(RegexCompat.replaceAllLeadingAsterisk(trimmed, spaces))
}

private def appendLineBreak(): Unit = startNewLine(spaces).append('*')
Expand Down Expand Up @@ -1905,42 +1906,12 @@ object FormatWriter {
private def getIndentation(len: Int): String =
if (len < indentations.length) indentations(len) else " " * len

private val trailingSpace = Pattern.compile("\\h++$", Pattern.MULTILINE)
private def removeTrailingWhiteSpace(str: String): String = trailingSpace
.matcher(str).replaceAll("")

private def splitAsIterator(regex: Pattern)(value: String): Iterator[String] =
regex.splitAsStream(value).iterator().asScala

// "slc" stands for single-line comment
private val slcDelim = Pattern.compile("\\h++")
// "mlc" stands for multi-line comment
private val mlcHeader = Pattern.compile("^/\\*\\h*+(?:\n\\h*+[*]*+\\h*+)?")
private val mlcLineDelim = Pattern.compile("\\h*+\n\\h*+[*]*+\\h*+")
private val mlcParagraphEnd = Pattern.compile("[.:!?=]$")
private val mlcParagraphBeg = Pattern.compile("^(?:[-*@=]|\\d++[.:])")

private val leadingAsteriskSpace = Pattern.compile("(?<=\n)\\h*+(?=[*][^*])")
private val docstringLine = Pattern
.compile("^(?:\\h*+\\*)?(\\h*+)(.*?)\\h*+$", Pattern.MULTILINE)
private val emptyLines = "\\h*+(\n\\h*+\\*?\\h*+)*"
private val emptyDocstring = Pattern.compile(s"^/\\*\\*$emptyLines\\*/$$")
private val onelineDocstring = {
val oneline = "[^*\n\\h](?:[^\n]*[^\n\\h])?"
Pattern.compile(s"^/\\*\\*$emptyLines($oneline)$emptyLines\\*/$$")
}
private val docstringLeadingSpace = Pattern.compile("^\\h++")

@inline
private def getStripMarginPattern(pipe: Char) =
if (pipe == '|') leadingPipeSpace else compileStripMarginPattern(pipe)

@inline
private def compileStripMarginPattern(pipe: Char) = Pattern
.compile(s"(?<=\n)\\h*+(?=\\$pipe)")

private val leadingPipeSpace = compileStripMarginPattern('|')

/** [[https://dotty.epfl.ch/docs/reference/other-new-features/indentation.html#the-end-marker]]
*/
private def getEndMarkerLabel(tree: Tree): String = tree match {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import org.scalafmt.util.TreeOps._
import scala.meta._
import scala.meta.tokens.Token

import java.util.regex.Pattern

import scala.annotation.tailrec

/** A partial formatting solution up to splits.length number of tokens.
Expand Down Expand Up @@ -371,16 +369,9 @@ object State {
}

@inline
private def compileStripMarginPattern(pipe: Char) = Pattern
.compile(s"\n(\\h*+\\$pipe)?([^\n]*+)")

@inline
private def getStripMarginPattern(pipe: Char) =
if (pipe == '|') pipeStripMarginPattern else compileStripMarginPattern(pipe)

private val pipeStripMarginPattern = compileStripMarginPattern('|')

private val slcLine = Pattern.compile("^/\\/\\/*+\\h*+(.*?)\\h*+$")
private def getStripMarginPatternWithLineContent(pipe: Char) =
if (pipe == '|') RegexCompat.stripMarginPatternWithLineContent
else RegexCompat.compileStripMarginPatternWithLineContent(pipe)

def getColumns(ft: FormatToken, indent: Int, column: Int)(implicit
style: ScalafmtConfig,
Expand All @@ -390,7 +381,7 @@ object State {
if (firstNL < 0) {
val syntaxLen =
if (column != 0 && ft.right.is[Token.Comment]) {
val asSlc = State.slcLine.matcher(syntax)
val asSlc = RegexCompat.slcLine.matcher(syntax)
if (asSlc.matches()) 3 + asSlc.end(1) - asSlc.start(1)
else syntax.length
} else syntax.length
Expand Down Expand Up @@ -457,7 +448,7 @@ object State {
adjustMargin: Int => Int,
firstLength: Int,
): (Int, Int) = {
val matcher = getStripMarginPattern(pipe).matcher(syntax)
val matcher = getStripMarginPatternWithLineContent(pipe).matcher(syntax)
matcher.region(firstNL, syntax.length)
if (!matcher.find()) (firstLength, firstLength)
else {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.scalafmt.cli

import org.scalafmt.config.ScalafmtConfig
import org.scalafmt.internal.RegexCompat
import org.scalafmt.sysops.AbsoluteFile
import org.scalafmt.sysops.FileOps

Expand All @@ -15,7 +16,7 @@ object FileTestOps {
*/
def string2dir(layout: String): AbsoluteFile = {
val root = AbsoluteFile(Files.createTempDirectory("root"))
layout.split("(?=\n/)").foreach { row =>
RegexCompat.splitByBeforeTextMatching(layout, "\n/").foreach { row =>
val path :: contents :: Nil = row.stripPrefix("\n").split("\n", 2).toList
val file = root / path.stripPrefix("/")
file.parent.mkdirs()
Expand Down

0 comments on commit fb82d72

Please sign in to comment.