mirror of https://github.com/sbt/sbt.git
Split to small methods
This commit is contained in:
parent
dac3edb546
commit
97a96d5bf8
|
|
@ -4,26 +4,28 @@ package parser
|
|||
|
||||
import java.io.File
|
||||
|
||||
import SplitExpressionsNoBlankies._
|
||||
import sbt.internals.parser.SplitExpressionsNoBlankies._
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import scala.reflect.runtime.universe._
|
||||
|
||||
private[sbt] object SplitExpressionsNoBlankies {
|
||||
val END_OF_LINE_CHAR = '\n'
|
||||
val END_OF_LINE = String.valueOf(END_OF_LINE_CHAR)
|
||||
private[parser] val NOT_FOUND_INDEX = -1
|
||||
private[sbt] val FAKE_FILE = new File("fake")
|
||||
}
|
||||
|
||||
private[sbt] case class SplitExpressionsNoBlankies(file: File, lines: Seq[String]) {
|
||||
//settingsTrees needed for "session save"
|
||||
//settingsTrees,modifiedContent needed for "session save"
|
||||
val (imports, settings, settingsTrees, modifiedContent) = splitExpressions(file, lines)
|
||||
|
||||
private def splitExpressions(file: File, lines: Seq[String]): (Seq[(String, Int)], Seq[(String, LineRange)], Seq[(String, Tree)], String) = {
|
||||
import scala.reflect.runtime._
|
||||
import sbt.internals.parser.MissingBracketHandler._
|
||||
import sbt.internals.parser.XmlContent._
|
||||
|
||||
import scala.compat.Platform.EOL
|
||||
import MissingBracketHandler._
|
||||
import XmlContent._
|
||||
import scala.reflect.runtime._
|
||||
import scala.tools.reflect.{ ToolBox, ToolBoxError }
|
||||
|
||||
val mirror = universe.runtimeMirror(this.getClass.getClassLoader)
|
||||
|
|
@ -83,7 +85,7 @@ private[sbt] case class SplitExpressionsNoBlankies(file: File, lines: Seq[String
|
|||
if (t.pos.isDefined) {
|
||||
val originalStatement = modifiedContent.substring(t.pos.start, t.pos.end)
|
||||
val statement = parseStatementAgain(t, originalStatement)
|
||||
val numberLines = statement.count(c => c == END_OF_LINE_CHAR)
|
||||
val numberLines = countLines(statement)
|
||||
Some((statement, t, LineRange(t.pos.line - 1, t.pos.line + numberLines)))
|
||||
} else {
|
||||
None
|
||||
|
|
@ -91,11 +93,13 @@ private[sbt] case class SplitExpressionsNoBlankies(file: File, lines: Seq[String
|
|||
val statementsTreeLineRange = statements flatMap convertStatement
|
||||
(imports map convertImport, statementsTreeLineRange.map(t => (t._1, t._3)), statementsTreeLineRange.map(t => (t._1, t._2)), modifiedContent)
|
||||
}
|
||||
|
||||
private def countLines(statement: String) = statement.count(c => c == END_OF_LINE_CHAR)
|
||||
}
|
||||
|
||||
/**
|
||||
* Scala parser cuts last bracket -
|
||||
* @see http://stackoverflow.com/questions/25547149/scala-parser-cuts-last-bracket
|
||||
* @see https://github.com/scala/scala/pull/3991
|
||||
*/
|
||||
private[sbt] object MissingBracketHandler {
|
||||
/**
|
||||
|
|
@ -105,7 +109,7 @@ private[sbt] object MissingBracketHandler {
|
|||
* @param positionLine - number of start position line
|
||||
* @param fileName - file name
|
||||
* @param originalException - original exception
|
||||
* @return
|
||||
* @return missing text
|
||||
*/
|
||||
private[sbt] def findMissingText(content: String, positionEnd: Int, positionLine: Int, fileName: String, originalException: Throwable): String = {
|
||||
findClosingBracketIndex(content, positionEnd) match {
|
||||
|
|
@ -131,7 +135,7 @@ private[sbt] object MissingBracketHandler {
|
|||
*/
|
||||
private[sbt] def findClosingBracketIndex(content: String, from: Int): Option[Int] = {
|
||||
val index = content.indexWhere(c => c == '}' || c == ')', from)
|
||||
if (index == -1) {
|
||||
if (index == NOT_FOUND_INDEX) {
|
||||
None
|
||||
} else {
|
||||
Some(index)
|
||||
|
|
@ -152,6 +156,17 @@ private[sbt] object MissingBracketHandler {
|
|||
* </pre>
|
||||
*/
|
||||
private[sbt] object XmlContent {
|
||||
|
||||
private val OPEN_PARENTHESIS = '{'
|
||||
|
||||
private val OPEN_CURLY_BRACKET = '('
|
||||
|
||||
private val DOUBLE_SLASH = "//"
|
||||
|
||||
private val OPEN_BRACKET = s" $OPEN_CURLY_BRACKET "
|
||||
|
||||
private val CLOSE_BRACKET = " ) "
|
||||
|
||||
/**
|
||||
*
|
||||
* @param original - file content
|
||||
|
|
@ -206,7 +221,7 @@ private[sbt] object XmlContent {
|
|||
private def searchForTagName(text: String, startIndex: Int, endIndex: Int) = {
|
||||
val subs = text.substring(startIndex, endIndex)
|
||||
val spaceIndex = subs.indexWhere(c => c.isWhitespace, 1)
|
||||
if (spaceIndex == -1) {
|
||||
if (spaceIndex == NOT_FOUND_INDEX) {
|
||||
subs
|
||||
} else {
|
||||
subs.substring(0, spaceIndex)
|
||||
|
|
@ -222,7 +237,7 @@ private[sbt] object XmlContent {
|
|||
@tailrec
|
||||
private def findModifiedOpeningTags(content: String, offsetIndex: Int, acc: Seq[(String, Int, Int)]): Seq[(String, Int, Int)] = {
|
||||
val endIndex = content.indexOf("/>", offsetIndex)
|
||||
if (endIndex == -1) {
|
||||
if (endIndex == NOT_FOUND_INDEX) {
|
||||
acc
|
||||
} else {
|
||||
val xmlFragment = findModifiedOpeningTag(content, offsetIndex, endIndex)
|
||||
|
|
@ -233,7 +248,7 @@ private[sbt] object XmlContent {
|
|||
|
||||
private def findModifiedOpeningTag(content: String, offsetIndex: Int, endIndex: Int): Option[(String, Int, Int)] = {
|
||||
val startIndex = content.substring(offsetIndex, endIndex).lastIndexOf("<")
|
||||
if (startIndex == -1) {
|
||||
if (startIndex == NOT_FOUND_INDEX) {
|
||||
None
|
||||
} else {
|
||||
val tagName = searchForTagName(content, startIndex + 1 + offsetIndex, endIndex)
|
||||
|
|
@ -249,7 +264,7 @@ private[sbt] object XmlContent {
|
|||
private def searchForOpeningIndex(text: String, closeTagStartIndex: Int, tagName: String) = {
|
||||
val subs = text.substring(0, closeTagStartIndex)
|
||||
val index = subs.lastIndexOf(s"<$tagName>")
|
||||
if (index == -1) {
|
||||
if (index == NOT_FOUND_INDEX) {
|
||||
subs.lastIndexOf(s"<$tagName ")
|
||||
} else {
|
||||
index
|
||||
|
|
@ -265,11 +280,11 @@ private[sbt] object XmlContent {
|
|||
@tailrec
|
||||
private def findNotModifiedOpeningTags(content: String, current: Int, acc: Seq[(String, Int, Int)]): Seq[(String, Int, Int)] = {
|
||||
val closeTagStartIndex = content.indexOf("</", current)
|
||||
if (closeTagStartIndex == -1) {
|
||||
if (closeTagStartIndex == NOT_FOUND_INDEX) {
|
||||
acc
|
||||
} else {
|
||||
val closeTagEndIndex = content.indexOf(">", closeTagStartIndex)
|
||||
if (closeTagEndIndex == -1) {
|
||||
if (closeTagEndIndex == NOT_FOUND_INDEX) {
|
||||
findNotModifiedOpeningTags(content, closeTagStartIndex + 2, acc)
|
||||
} else {
|
||||
val xmlFragment = findNotModifiedOpeningTag(content, closeTagStartIndex, closeTagEndIndex)
|
||||
|
|
@ -301,39 +316,46 @@ private[sbt] object XmlContent {
|
|||
*/
|
||||
private def addExplicitXmlContent(content: String, xmlParts: Seq[(String, Int, Int)]): String = {
|
||||
val statements: Seq[(String, Boolean)] = splitFile(content, xmlParts)
|
||||
val (builder, addCloseBrackets, wasXml, _) = statements.foldLeft((Seq.empty[String], false, false, "")) {
|
||||
case ((bAcc, addCloseBrackets, wasXml, previous), (content, isXml)) =>
|
||||
if (content.trim.isEmpty) {
|
||||
(content +: bAcc, addCloseBrackets, wasXml, content)
|
||||
val (correctedStmt, shouldAddCloseBrackets, wasXml, _) = addBracketsIfNecessary(statements)
|
||||
val closeIfNecessaryCorrectedStmt =
|
||||
if (shouldAddCloseBrackets && wasXml) {
|
||||
correctedStmt.head +: CLOSE_BRACKET +: correctedStmt.tail
|
||||
} else {
|
||||
correctedStmt
|
||||
}
|
||||
closeIfNecessaryCorrectedStmt.reverse.mkString
|
||||
}
|
||||
|
||||
def addBracketsIfNecessary(statements: Seq[(String, Boolean)]): (Seq[String], Boolean, Boolean, String) = {
|
||||
statements.foldLeft((Seq.empty[String], false, false, "")) {
|
||||
case ((accStmt, shouldAddCloseBracket, prvWasXml, prvStmt), (stmt, isXml)) =>
|
||||
if (stmt.trim.isEmpty) {
|
||||
(stmt +: accStmt, shouldAddCloseBracket, prvWasXml, stmt)
|
||||
} else {
|
||||
val (newAddCloseBrackets, newAcc) = if (isXml) {
|
||||
if (wasXml) {
|
||||
(addCloseBrackets, bAcc)
|
||||
} else {
|
||||
if (areBracketsNecessary(previous)) {
|
||||
(true, " ( " +: bAcc)
|
||||
} else {
|
||||
(false, bAcc)
|
||||
}
|
||||
}
|
||||
} else if (addCloseBrackets) {
|
||||
(false, " ) " +: bAcc)
|
||||
val (newShouldAddCloseBracket, newStmtAcc) = if (isXml) {
|
||||
addOpenBracketIfNecessary(accStmt, shouldAddCloseBracket, prvWasXml, prvStmt)
|
||||
} else if (shouldAddCloseBracket) {
|
||||
(false, CLOSE_BRACKET +: accStmt)
|
||||
} else {
|
||||
(false, bAcc)
|
||||
(false, accStmt)
|
||||
}
|
||||
|
||||
(content +: newAcc, newAddCloseBrackets, isXml, content)
|
||||
(stmt +: newStmtAcc, newShouldAddCloseBracket, isXml, stmt)
|
||||
}
|
||||
}
|
||||
val closeIfNecessaryBuilder =
|
||||
if (addCloseBrackets && wasXml) {
|
||||
builder.head +: " ) " +: builder.tail
|
||||
} else {
|
||||
builder
|
||||
}
|
||||
closeIfNecessaryBuilder.reverse.mkString
|
||||
}
|
||||
|
||||
private def addOpenBracketIfNecessary(stmtAcc: Seq[String], shouldAddCloseBracket: Boolean, prvWasXml: Boolean, prvStatement: String) =
|
||||
if (prvWasXml) {
|
||||
(shouldAddCloseBracket, stmtAcc)
|
||||
} else {
|
||||
if (areBracketsNecessary(prvStatement)) {
|
||||
(true, OPEN_BRACKET +: stmtAcc)
|
||||
} else {
|
||||
(false, stmtAcc)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add to head if option is not empty
|
||||
* @param ts - seq
|
||||
|
|
@ -348,7 +370,7 @@ private[sbt] object XmlContent {
|
|||
val tagName = content.substring(closeTagStartIndex + 2, closeTagEndIndex)
|
||||
if (xml.Utility.isName(tagName)) {
|
||||
val openTagIndex = searchForOpeningIndex(content, closeTagStartIndex, tagName)
|
||||
if (openTagIndex == -1) {
|
||||
if (openTagIndex == NOT_FOUND_INDEX) {
|
||||
None
|
||||
} else {
|
||||
xmlFragmentOption(content, openTagIndex, closeTagEndIndex + 1)
|
||||
|
|
@ -379,13 +401,13 @@ private[sbt] object XmlContent {
|
|||
* @return are brackets necessary?
|
||||
*/
|
||||
private def areBracketsNecessary(statement: String): Boolean = {
|
||||
val doubleSlash = statement.indexOf("//")
|
||||
val doubleSlash = statement.indexOf(DOUBLE_SLASH)
|
||||
val endOfLine = statement.indexOf(END_OF_LINE)
|
||||
if (doubleSlash == -1 || (doubleSlash < endOfLine)) {
|
||||
val roundBrackets = statement.lastIndexOf("(")
|
||||
val braces = statement.lastIndexOf("{")
|
||||
if (doubleSlash == NOT_FOUND_INDEX || (doubleSlash < endOfLine)) {
|
||||
val roundBrackets = statement.lastIndexOf(OPEN_CURLY_BRACKET)
|
||||
val braces = statement.lastIndexOf(OPEN_PARENTHESIS)
|
||||
val max = roundBrackets.max(braces)
|
||||
if (max == -1) {
|
||||
if (max == NOT_FOUND_INDEX) {
|
||||
true
|
||||
} else {
|
||||
val trimmed = statement.substring(max + 1).trim
|
||||
|
|
|
|||
Loading…
Reference in New Issue