Skip to content

Commit

Permalink
Add linesIterator implementation
Browse files Browse the repository at this point in the history
`linesIterator` from Scala is not consistent for our cross-compiled
versions, so we provide an explicit implementation (copied from Scala
2.13.14 StringOps.scala).
  • Loading branch information
Armin Wiebigke committed Sep 4, 2024
1 parent daa7781 commit 24be4fb
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package sangria.renderer

import sangria.ast.AstLocation
import sangria.util.StringUtil.{escapeBlockString, escapeString}
import sangria.ast._
import sangria.util.StringUtil.{escapeBlockString, escapeString, linesIterator}

object QueryRenderer {
val Pretty: QueryRendererConfig = QueryRendererConfig(
Expand Down Expand Up @@ -477,7 +476,7 @@ object QueryRenderer {
extraIndent: Boolean = true): String =
if (node.value.trim.nonEmpty) {
val ind = if (extraIndent) indent.incForce.str else indent.strForce
val lines = escapeBlockString(node.value).linesIterator.map { line =>
val lines = linesIterator(escapeBlockString(node.value)).map { line =>
if (line.isEmpty) line // do not output lines with only whitespaces inside
else ind + line
}
Expand Down
25 changes: 25 additions & 0 deletions modules/core/src/main/scala/sangria/util/StringUtil.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package sangria.util
import sangria.since3_0_0

import java.util.Locale
import scala.collection.AbstractIterator
import scala.collection.mutable.ListBuffer

object StringUtil {
Expand Down Expand Up @@ -110,6 +111,30 @@ object StringUtil {
def charHex(ch: Char): String =
Integer.toHexString(ch).toUpperCase(Locale.ENGLISH)

// Redefine `linesIterator`, since the implementation provided by Scala is not consistent for our
// cross-compiled versions
def linesIterator(string: String): Iterator[String] = new AbstractIterator[String] {
def hasNext: Boolean = !done
def next(): String = if (done) Iterator.empty.next() else advance()

private def isLineBreak(c: Char) = c == '\r' || c == '\n'
private def isWindowsLineBreak(c1: Char, c2: Char) = c1 == '\r' && c2 == '\n'
private[this] val len = string.length
private[this] var index = 0
@`inline` private def done: Boolean = index >= len
private def advance(): String = {
val start = index
while (!done && !isLineBreak(string.charAt(index))) index += 1
val end = index
if (!done) {
val c = string.charAt(index)
index += 1
if (!done && isWindowsLineBreak(c, string.charAt(index))) index += 1
}
string.substring(start, end)
}
}

/** Produces the value of a block string from its parsed raw value, similar to Coffeescript's
* block string, Python's docstring trim or Ruby's strip_heredoc.
*
Expand Down

0 comments on commit 24be4fb

Please sign in to comment.