Revert brackets for backward compatibility (binary compatibility), addExplicitXmlContent use pattern matching, splitFile - does not return whitespace statements

This commit is contained in:
andrzej.jozwik@gmail.com 2014-10-19 23:54:18 +02:00
parent 8c0e400c11
commit 6f9dfcce52
3 changed files with 54 additions and 48 deletions

View File

@ -23,10 +23,13 @@ private[sbt] object SbtParser {
sealed trait ParsedSbtFileExpressions {
/** The set of parsed import expressions. */
def imports: Seq[(String, Int)]
/** The set of parsed defintions and/or sbt build settings. */
def settings: Seq[(String, LineRange)]
/** The set of scala tree's for parsed definitions/settings and the underlying string representation.. */
def settingsTrees: Seq[(String, Tree)]
/** Represents the changes we had to perform to the sbt file so that XML will parse correctly. */
def modifiedContent: String
}
@ -200,7 +203,9 @@ private[sbt] object XmlContent {
private val DOUBLE_SLASH = "//"
private val CLOSE_XML_STATEMENT = ";"
private val OPEN_BRACKET = s"$OPEN_CURLY_BRACKET"
private val CLOSE_BRACKET = ")"
/**
*
@ -220,24 +225,25 @@ private[sbt] object XmlContent {
* Cut file for normal text - xml - normal text - xml ....
* @param content - content
* @param ts - import/statements
* @return (text,true) - is xml (text,false) - if normal text
* @return Seq - Right(xml,whiteSpaces) - for xml, Left(statement) - for text
*/
private def splitFile(content: String, ts: Seq[(String, Int, Int)]): Seq[(String, Boolean)] = {
val (statements, index) = ts.foldLeft((Seq.empty[(String, Boolean)], 0)) {
(accSeqIndex, el) =>
val (statement, startIndex, endIndex) = el
val (accSeq, index) = accSeqIndex
val textStatementOption = if (index >= startIndex) {
None
private def splitFile(content: String, ts: Seq[(String, Int, Int)]): Seq[Either[(String), (String, String)]] = {
val (statements, lastIndex) = ts.foldLeft((Seq.empty[Either[(String), (String, String)]], 0)) {
case ((accSeq, index), (statement, startIndex, endIndex)) =>
val toAdd = if (index >= startIndex) {
Seq(Right((statement, "")))
} else {
val s = content.substring(index, startIndex)
Some((s, false))
if (s.trim.isEmpty) {
Seq(Right((statement, s)))
} else {
Seq(Right((statement, "")), Left(s))
}
}
val newAccSeq = (statement, true) +: addOptionToCollection(accSeq, textStatementOption)
(newAccSeq, endIndex)
(toAdd ++ accSeq, endIndex)
}
val endOfFile = content.substring(index, content.length)
val withEndOfFile = (endOfFile, false) +: statements
val endOfFile = content.substring(lastIndex, content.length)
val withEndOfFile = if (endOfFile.isEmpty) statements else Left(endOfFile) +: statements
withEndOfFile.reverse
}
@ -263,6 +269,8 @@ private[sbt] object XmlContent {
}
}
private val CLOSE_XML_TAG = "/>"
/**
* Modified Opening Tag - <aaa/>
* @param offsetIndex - index
@ -271,7 +279,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)
val endIndex = content.indexOf(CLOSE_XML_TAG, offsetIndex)
if (endIndex == NOT_FOUND_INDEX) {
acc
} else {
@ -350,42 +358,40 @@ private[sbt] object XmlContent {
* @return content with xml with brackets
*/
private def addExplicitXmlContent(content: String, xmlParts: Seq[(String, Int, Int)]): String = {
val statements: Seq[(String, Boolean)] = splitFile(content, xmlParts)
val (correctedStmt, shouldAddCloseBrackets, wasXml, _) = addBracketsIfNecessary(statements)
val closeIfNecessaryCorrectedStmt =
if (shouldAddCloseBrackets && wasXml) {
correctedStmt.head +: CLOSE_XML_STATEMENT +: correctedStmt.tail
} else {
correctedStmt
}
closeIfNecessaryCorrectedStmt.reverse.mkString
}
val statements = splitFile(content, xmlParts)
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 (newShouldAddCloseBracket, newStmtAcc) = if (isXml) {
addOpenBracketIfNecessary(accStmt, shouldAddCloseBracket, prvWasXml, prvStmt)
} else if (shouldAddCloseBracket) {
(false, CLOSE_XML_STATEMENT +: accStmt)
} else {
(false, accStmt)
}
(stmt +: newStmtAcc, newShouldAddCloseBracket, isXml, stmt)
val (_, seq, lastAdd) = statements.foldLeft[(Option[Either[(String), (String, String)]], Seq[String], Boolean)]((None, Seq.empty[String], false)) {
case ((previousOption, acc, add), element) =>
val (newAcc, newAdd) = (element, previousOption) match {
case (Left(text), _) =>
val accWithClose = if (add) {
addCloseBracket(acc)
} else {
acc
}
(text +: accWithClose, false)
case (Right((xml, nonXml)), Some(Left(text))) =>
val (accWithOpen, added) = if (areBracketsNecessary(text)) {
(OPEN_BRACKET +: acc, true)
} else {
(acc, false)
}
(xml +: (nonXml +: accWithOpen), added)
case (Right((xml, nonXml)), _) =>
(xml +: (nonXml +: acc), add)
}
(Some(element), newAcc, newAdd)
}
val correctedSeq = if (lastAdd) {
addCloseBracket(seq)
} else {
seq
}
correctedSeq.reverse.mkString
}
private def addOpenBracketIfNecessary(stmtAcc: Seq[String], shouldAddCloseBracket: Boolean, prvWasXml: Boolean, prvStatement: String) =
if (prvWasXml) {
(shouldAddCloseBracket, stmtAcc)
} else {
(areBracketsNecessary(prvStatement), stmtAcc)
}
private def addCloseBracket(statements: Seq[String]) = CLOSE_BRACKET +: statements
/**
* Add to head if option is not empty

View File

@ -2,4 +2,4 @@ import sbt._
val scmpom = taskKey[xml.NodeBuffer]("Node buffer")
scmpom := <a/><b a="rt">OK</b>;
scmpom := (<a/><b a="rt">OK</b>)

View File

@ -70,4 +70,4 @@ abstract class AbstractSessionSettingsSpec(folder: String) extends AbstractSpec
class SessionSettingsSpec extends AbstractSessionSettingsSpec("session-settings")
//class SessionSettingsQuickSpec extends AbstractSessionSettingsSpec("session-settings-quick", true)
class SessionSettingsQuickSpec extends AbstractSessionSettingsSpec("session-settings-quick")