-
Notifications
You must be signed in to change notification settings - Fork 346
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Infix should be in query sub-clauses even if contents not selected.
- Loading branch information
1 parent
0c12491
commit c085e1c
Showing
17 changed files
with
871 additions
and
106 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
140 changes: 140 additions & 0 deletions
140
quill-core/src/main/scala/io/getquill/util/Interpolator.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
package io.getquill.util | ||
|
||
import java.io.PrintStream | ||
|
||
import io.getquill.AstPrinter | ||
import io.getquill.AstPrinter.Implicits._ | ||
import io.getquill.util.Messages.TraceType | ||
|
||
import scala.collection.mutable | ||
import scala.util.matching.Regex | ||
|
||
class Interpolator( | ||
traceType: TraceType, | ||
defaultIndent: Int = 0, | ||
color: Boolean = Messages.traceColors, | ||
qprint: AstPrinter = Messages.qprint, | ||
out: PrintStream = System.out, | ||
tracesEnabled: (TraceType) => Boolean = Messages.tracesEnabled(_) | ||
) { | ||
implicit class InterpolatorExt(sc: StringContext) { | ||
def trace(elements: Any*) = new Traceable(sc, elements) | ||
} | ||
implicit class StringOps(str: String) { | ||
def fitsOnOneLine: Boolean = !str.contains("\n") | ||
def multiline(indent: Int, prefix: String): String = | ||
str.split("\n").map(elem => indent.prefix + prefix + elem).mkString("\n") | ||
} | ||
implicit class IndentOps(i: Int) { | ||
def prefix = indentOf(i) | ||
} | ||
private def indentOf(num: Int) = | ||
(0 to num).map(_ => "").mkString(" ") | ||
|
||
class Traceable(sc: StringContext, elementsSeq: Seq[Any]) { | ||
|
||
private val elementPrefix = "| " | ||
|
||
private sealed trait PrintElement | ||
private case class Str(str: String, first: Boolean) extends PrintElement | ||
private case class Elem(value: String) extends PrintElement | ||
private case object Separator extends PrintElement | ||
|
||
private def generateStringForCommand(value: Any, indent: Int) = { | ||
val objectString = qprint(value).string(color) | ||
val oneLine = objectString.fitsOnOneLine | ||
oneLine match { | ||
case true => s"${indent.prefix}> ${objectString}" | ||
case false => s"${indent.prefix}>\n${objectString.multiline(indent, elementPrefix)}" | ||
} | ||
} | ||
|
||
private def readFirst(first: String) = | ||
new Regex("%([0-9]+)(.*)").findFirstMatchIn(first) match { | ||
case Some(matches) => (matches.group(2).trim, matches.group(1).toInt) | ||
case None => (first, defaultIndent) | ||
} | ||
|
||
private def readBuffers() = { | ||
val parts = sc.parts.iterator.toList | ||
val elements = elementsSeq.toList.map(qprint(_).string(color)) | ||
|
||
val (firstStr, indent) = readFirst(parts.head) | ||
|
||
val partsIter = parts.iterator | ||
partsIter.next() // already took care of the 1st element | ||
val elementsIter = elements.iterator | ||
|
||
val sb = new mutable.ArrayBuffer[PrintElement]() | ||
sb.append(Str(firstStr.trim, true)) | ||
|
||
while (elementsIter.hasNext) { | ||
sb.append(Separator) | ||
sb.append(Elem(elementsIter.next())) | ||
val nextPart = partsIter.next().trim | ||
sb.append(Separator) | ||
sb.append(Str(nextPart, false)) | ||
} | ||
|
||
(sb.toList, indent) | ||
} | ||
|
||
def generateString() = { | ||
val (elementsRaw, indent) = readBuffers() | ||
|
||
val elements = elementsRaw.filter { | ||
case Str(value, _) => value.trim != "" | ||
case Elem(value) => value.trim != "" | ||
case _ => true | ||
} | ||
|
||
val oneLine = elements.forall { | ||
case Elem(value) => value.fitsOnOneLine | ||
case Str(value, _) => value.fitsOnOneLine | ||
case _ => true | ||
} | ||
val output = | ||
elements.map { | ||
case Str(value, true) if (oneLine) => indent.prefix + value | ||
case Str(value, false) if (oneLine) => value | ||
case Elem(value) if (oneLine) => value | ||
case Separator if (oneLine) => " " | ||
case Str(value, true) => value.multiline(indent, "") | ||
case Str(value, false) => value.multiline(indent, "|") | ||
case Elem(value) => value.multiline(indent, "| ") | ||
case Separator => "\n" | ||
} | ||
|
||
(output.mkString, indent) | ||
} | ||
|
||
private def logIfEnabled[T]() = | ||
if (tracesEnabled(traceType)) | ||
Some(generateString()) | ||
else | ||
None | ||
|
||
def andLog(): Unit = | ||
logIfEnabled.foreach(value => out.println(value._1)) | ||
|
||
def andContinue[T](command: => T) = { | ||
logIfEnabled.foreach(value => out.println(value._1)) | ||
command | ||
} | ||
|
||
def andReturn[T](command: => T) = { | ||
logIfEnabled() match { | ||
case Some((output, indent)) => | ||
// do the initial log | ||
out.println(output) | ||
// evaluate the command, this will activate any traces that were inside of it | ||
val result = command | ||
out.println(generateStringForCommand(result, indent)) | ||
|
||
result | ||
case None => | ||
command | ||
} | ||
} | ||
} | ||
} |
46 changes: 34 additions & 12 deletions
46
quill-core/src/main/scala/io/getquill/util/Messages.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.