Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
target/
.idea/
.bsp
lowered.hnir
Original file line number Diff line number Diff line change
Expand Up @@ -154,19 +154,12 @@ class Formatter(cfg: FormatConfig, tokenizer: Tokenizer) {
util.trimEnd(query)
}

private def previousNonWhitespaceToken = {
var n = 1
while (previousToken(n).exists(_.tokenType == TokenTypes.WHITESPACE)) {
n += 1
}
previousToken(n)
}
private def previousNonWhitespaceToken =
tokens.take(index).reverseIterator.find(_.tokenType != TokenTypes.WHITESPACE)

private def previousToken(offset: Int): Option[Token] =
if (index - offset < 0)
private def previousToken: Option[Token] =
if (index - 1 < 0)
None
else
Some(tokens(index - offset))

private def previousToken: Option[Token] = previousToken(1)
Some(tokens(index - 1))
}
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,7 @@ private[core] class Indentation(indent: String) {
* throws away these as well.
*/
def decreaseBlockLevel(): Unit = {
indentTypes = indentTypes.dropWhile(_ == IndentTypes.INDENT_TYPE_TOP_LEVEL)
indentTypes = indentTypes.drop(1)
indentTypes = indentTypes.dropWhile(_ == IndentTypes.INDENT_TYPE_TOP_LEVEL).drop(1)
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.github.takayahilton.sqlformatter.core

import scala.annotation.tailrec

/**
* Bookkeeper for inline blocks.
* <p>
Expand All @@ -8,6 +10,8 @@ package com.github.takayahilton.sqlformatter.core
* expressions where open-parenthesis causes newline and increase of indentation.
*/
private[core] class InlineBlock {
import InlineBlock._

private[this] var level: Int = 0

/**
Expand Down Expand Up @@ -37,25 +41,27 @@ private[core] class InlineBlock {
* @return {Boolean}
*/
def isActive: Boolean = level > 0
}

private[core] object InlineBlock {
private val INLINE_MAX_LENGTH: Int = 50

// Check if this should be an inline parentheses block
// Examples are "NOW()", "COUNT(*)", "int(10)", key(`somecolumn`), DECIMAL(7,2)
private def isInlineBlock(tokens: Vector[Token], index: Int): Boolean = {
var length = 0
var level = 0
for (i <- index until tokens.size) {
val token = tokens(i)
length += token.value.length
@tailrec
def go(tokens: List[Token], length: Int, level: Int): Boolean = tokens match {
// Overran max length
if (length > InlineBlock.INLINE_MAX_LENGTH) return false
if (token.tokenType == TokenTypes.OPEN_PAREN) level += 1
else if (token.tokenType == TokenTypes.CLOSE_PAREN) {
level -= 1
if (level == 0) return true
}
if (isForbiddenToken(token)) return false
case _ if length > InlineBlock.INLINE_MAX_LENGTH => false
case Nil => false
case token :: tail if token.tokenType == TokenTypes.OPEN_PAREN =>
go(tail, length + token.value.length, level + 1)
case token :: tail if token.tokenType == TokenTypes.CLOSE_PAREN =>
level < 2 || go(tail, length + token.value.length, level - 1)
case token :: _ if isForbiddenToken(token) => false
case token :: tail => go(tail, length + token.value.length, level)
}
false
go(tokens.drop(index).toList, 0, 0)
}

// Reserved words that cause newlines, comments and semicolons
Expand All @@ -66,7 +72,3 @@ private[core] class InlineBlock {
token.value == ";"
}
}

private[core] object InlineBlock {
private val INLINE_MAX_LENGTH: Int = 50
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,16 @@ package com.github.takayahilton.sqlformatter.core
final case class Token(
tokenType: TokenTypes,
value: String,
regex: Option[String],
key: Option[String]
) {

def withKey(key: String): Token = copy(key = Some(key))

override def toString: String =
s"(type: $tokenType, value [$value]" + regex.fold(")")(r => s"regex: /$r/)")
s"(type: $tokenType, value [$value]" + ")"
}

object Token {
def apply(tokenType: TokenTypes, value: String, regex: String): Token =
new Token(tokenType, value, Some(regex), None)

def apply(tokenType: TokenTypes, value: String): Token =
new Token(tokenType, value, None, None)
new Token(tokenType, value, None)
}
Original file line number Diff line number Diff line change
Expand Up @@ -96,12 +96,11 @@ class Tokenizer(val cfg: DialectConfig) {

@scala.annotation.tailrec
def go(input: String, previousToken: Option[Token], tokens: VectorBuilder[Token]): Vector[Token] =
input match {
case "" =>
tokens.result()
case _ =>
val token = getNextToken(input, previousToken).get // if token is None, something is wrong
go(input.substring(token.value.length), Some(token), tokens += token)
if (input.isEmpty)
tokens.result()
else {
val token = getNextToken(input, previousToken).get // if token is None, something is wrong
go(input.substring(token.value.length), Some(token), tokens += token)
}

go(input, None, new VectorBuilder)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,25 @@ import java.util.regex.Pattern
package object util {
def trimEnd(s: String): String = s.replaceAll("[ |\\n|\\r]*$", "")

def escapeRegExp(s: String): String = {
val regexp = List(
"^",
"$",
"\\",
".",
"*",
"+",
"*",
"?",
"(",
")",
"[",
"]",
"{",
"}",
"|"
).map(spChr => "(\\" + spChr + ")")
.mkString("|")
private[this] val regexp = List(
"^",
"$",
"\\",
".",
"*",
"+",
"*",
"?",
"(",
")",
"[",
"]",
"{",
"}",
"|"
).map(spChr => "(\\" + spChr + ")")
.mkString("|")

def escapeRegExp(s: String): String =
Pattern.compile(regexp).matcher(s).replaceAll("\\\\$0")
}
}