mirror of https://github.com/sbt/sbt.git
commit
577c555d81
|
|
@ -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,9 +203,9 @@ private[sbt] object XmlContent {
|
|||
|
||||
private val DOUBLE_SLASH = "//"
|
||||
|
||||
private val OPEN_BRACKET = s" $OPEN_CURLY_BRACKET "
|
||||
private val OPEN_BRACKET = s"$OPEN_CURLY_BRACKET"
|
||||
|
||||
private val CLOSE_BRACKET = " ) "
|
||||
private val CLOSE_BRACKET = ")"
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
@ -222,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
|
||||
}
|
||||
|
||||
|
|
@ -265,6 +269,8 @@ private[sbt] object XmlContent {
|
|||
}
|
||||
}
|
||||
|
||||
private val CLOSE_XML_TAG = "/>"
|
||||
|
||||
/**
|
||||
* Modified Opening Tag - <aaa/>
|
||||
* @param offsetIndex - index
|
||||
|
|
@ -273,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 {
|
||||
|
|
@ -352,46 +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_BRACKET +: 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_BRACKET +: 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 {
|
||||
if (areBracketsNecessary(prvStatement)) {
|
||||
(true, OPEN_BRACKET +: stmtAcc)
|
||||
} else {
|
||||
(false, stmtAcc)
|
||||
}
|
||||
}
|
||||
private def addCloseBracket(statements: Seq[String]) = CLOSE_BRACKET +: statements
|
||||
|
||||
/**
|
||||
* Add to head if option is not empty
|
||||
|
|
@ -439,8 +439,15 @@ private[sbt] object XmlContent {
|
|||
*/
|
||||
private def areBracketsNecessary(statement: String): Boolean = {
|
||||
val doubleSlash = statement.indexOf(DOUBLE_SLASH)
|
||||
val endOfLine = statement.indexOf(END_OF_LINE)
|
||||
if (doubleSlash == NOT_FOUND_INDEX || (doubleSlash < endOfLine)) {
|
||||
|
||||
if (doubleSlash != NOT_FOUND_INDEX) {
|
||||
val endOfLine = statement.indexOf(END_OF_LINE, doubleSlash)
|
||||
if (endOfLine == NOT_FOUND_INDEX) {
|
||||
false
|
||||
} else {
|
||||
areBracketsNecessary(statement.substring(endOfLine))
|
||||
}
|
||||
} else {
|
||||
val roundBrackets = statement.lastIndexOf(OPEN_CURLY_BRACKET)
|
||||
val braces = statement.lastIndexOf(OPEN_PARENTHESIS)
|
||||
val max = roundBrackets.max(braces)
|
||||
|
|
@ -450,8 +457,7 @@ private[sbt] object XmlContent {
|
|||
val trimmed = statement.substring(max + 1).trim
|
||||
trimmed.nonEmpty
|
||||
}
|
||||
} else {
|
||||
false
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
*
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
|
||||
name := "scala-stm"
|
||||
|
||||
organization := "org.scala-stm"
|
||||
|
||||
version := "0.8-SNAPSHOT"
|
||||
|
||||
scalaVersion := "2.11.2"
|
||||
|
||||
crossScalaVersions := Seq("2.11.2", "2.10.4", "2.9.3")
|
||||
|
||||
libraryDependencies += ("org.scalatest" %% "scalatest" % "[1.5,)" % "test")
|
||||
|
||||
libraryDependencies += ("junit" % "junit" % "4.5" % "test")
|
||||
|
||||
// skip exhaustive tests
|
||||
testOptions += Tests.Argument("-l", "slow")
|
||||
|
||||
// test of TxnExecutor.transformDefault must be run by itself
|
||||
parallelExecution in Test := false
|
||||
|
||||
////////////////////
|
||||
// publishing
|
||||
|
||||
pomExtra :=
|
||||
<url>http://nbronson.github.com/scala-stm/</url>
|
||||
<licenses>
|
||||
<license>
|
||||
<name>BSD</name>
|
||||
<url>https://github.com/nbronson/scala-stm/blob/master/LICENSE.txt</url>
|
||||
<distribution>repo</distribution>
|
||||
</license>
|
||||
</licenses>
|
||||
<scm>
|
||||
<connection>scm:git:git@github.com:nbronson/scala-stm.git</connection>
|
||||
<url>git@github.com:nbronson/scala-stm.git</url>
|
||||
</scm>
|
||||
<developers>
|
||||
<developer>
|
||||
<id>nbronson</id>
|
||||
<name>Nathan Bronson</name>
|
||||
<email>ngbronson@gmail.com</email>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
publishMavenStyle := true
|
||||
|
||||
publishTo <<= (version) { v: String =>
|
||||
val base = "https://oss.sonatype.org/"
|
||||
if (v.trim.endsWith("SNAPSHOT"))
|
||||
Some("snapshots" at base + "content/repositories/snapshots/")
|
||||
else
|
||||
Some("releases" at base + "service/local/staging/deploy/maven2/")
|
||||
}
|
||||
|
||||
// exclude scalatest from the Maven POM
|
||||
pomPostProcess := { xi: scala.xml.Node =>
|
||||
import scala.xml._
|
||||
val badDeps = (xi \\ "dependency") filter {
|
||||
x => (x \ "artifactId").text != "scala-library"
|
||||
} toSet
|
||||
def filt(root: Node): Node = root match {
|
||||
case x: Elem => {
|
||||
val ch = x.child filter { !badDeps(_) } map { filt(_) }
|
||||
Elem(x.prefix, x.label, x.attributes, x.scope, ch: _*)
|
||||
}
|
||||
case x => x
|
||||
}
|
||||
filt(xi)
|
||||
}
|
||||
|
||||
credentials += Credentials(Path.userHome / ".ivy2" / ".credentials")
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
import sbt._
|
||||
|
||||
val scmpom = taskKey[xml.NodeBuffer]("Node buffer")
|
||||
|
||||
scmpom := <scm>
|
||||
<url>git@github.com:mohiva/play-html-compressor.git</url>
|
||||
<connection>scm:git:git@github.com:mohiva/play-html-compressor.git</connection>
|
||||
</scm>
|
||||
<developers>
|
||||
<developer>
|
||||
<id>akkie</id>
|
||||
<name>Christian Kaps</name>
|
||||
<url>http://mohiva.com</url>
|
||||
</developer>
|
||||
</developers>
|
||||
<a></a>
|
||||
|
|
@ -0,0 +1 @@
|
|||
scmpom := <a/><b a="rt">OK</b>
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import sbt._
|
||||
|
||||
val scmpom = taskKey[xml.NodeBuffer]("Node buffer")
|
||||
|
||||
scmpom := (<a/><b a="rt">OK</b>)
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
k1 := {}
|
||||
|
||||
k2 := {}
|
||||
|
||||
k3 := {
|
||||
|
||||
|
||||
val x = "hi"
|
||||
()
|
||||
}
|
||||
|
||||
k4 := { }; k5 := ()
|
||||
|
||||
k1 <<= k1 map {_ => sys.error("k1")}
|
||||
|
||||
k4 := { val x = k4.value; () }
|
||||
|
||||
|
|
@ -1 +0,0 @@
|
|||
k4 := ()
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
k1 := {}
|
||||
|
||||
k2 := {}
|
||||
|
||||
k3 := {
|
||||
|
||||
|
||||
val x = "hi"
|
||||
()
|
||||
}
|
||||
|
||||
k4 := (); k5 := ()
|
||||
|
||||
k1 <<= k1 map {_ => sys.error("k1")}
|
||||
|
||||
|
|
@ -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>;
|
||||
|
|
@ -2,40 +2,16 @@ package sbt.internals.parser
|
|||
|
||||
import java.io.File
|
||||
|
||||
import sbt.LineRange
|
||||
import sbt.{ EvaluateConfigurations, LineRange }
|
||||
|
||||
import scala.annotation.tailrec
|
||||
|
||||
@deprecated("This class is be removed. Only for test backward compatibility", "1.0")
|
||||
object EvaluateConfigurationsOriginal {
|
||||
|
||||
private[this] def isSpace = (c: Char) => Character isWhitespace c
|
||||
private[this] def fstS(f: String => Boolean): ((String, Int)) => Boolean = { case (s, i) => f(s) }
|
||||
private[this] def firstNonSpaceIs(lit: String) = (_: String).view.dropWhile(isSpace).startsWith(lit)
|
||||
private[this] def or[A](a: A => Boolean, b: A => Boolean): A => Boolean = in => a(in) || b(in)
|
||||
|
||||
def splitExpressions(file: File, lines: Seq[String]): (Seq[(String, Int)], Seq[(String, LineRange)]) =
|
||||
{
|
||||
val blank = (_: String).forall(isSpace)
|
||||
val isImport = firstNonSpaceIs("import ")
|
||||
val comment = firstNonSpaceIs("//")
|
||||
val blankOrComment = or(blank, comment)
|
||||
val importOrBlank = fstS(or(blankOrComment, isImport))
|
||||
|
||||
val (imports, settings) = lines.zipWithIndex span importOrBlank
|
||||
(imports filterNot fstS(blankOrComment), groupedLines(settings, blank, blankOrComment))
|
||||
EvaluateConfigurations.splitExpressions(lines)
|
||||
}
|
||||
|
||||
def groupedLines(lines: Seq[(String, Int)], delimiter: String => Boolean, skipInitial: String => Boolean): Seq[(String, LineRange)] =
|
||||
{
|
||||
val fdelim = fstS(delimiter)
|
||||
@tailrec def group0(lines: Seq[(String, Int)], accum: Seq[(String, LineRange)]): Seq[(String, LineRange)] =
|
||||
if (lines.isEmpty) accum.reverse
|
||||
else {
|
||||
val start = lines dropWhile fstS(skipInitial)
|
||||
val (next, tail) = start.span { case (s, _) => !delimiter(s) }
|
||||
val grouped = if (next.isEmpty) accum else (next.map(_._1).mkString("\n"), LineRange(next.head._2, next.last._2 + 1)) +: accum
|
||||
group0(tail, grouped)
|
||||
}
|
||||
group0(lines, Nil)
|
||||
}
|
||||
}
|
||||
|
|
@ -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")
|
||||
|
|
@ -12,6 +12,8 @@ import scala.tools.reflect.ToolBoxError
|
|||
|
||||
class SplitExpressionsFilesTest extends AbstractSplitExpressionsFilesTest("/old-format/")
|
||||
|
||||
//class SplitExpressionsFilesFailedTest extends AbstractSplitExpressionsFilesTest("/fail-format/")
|
||||
|
||||
abstract class AbstractSplitExpressionsFilesTest(pathName: String) extends Specification {
|
||||
|
||||
case class SplitterComparison(oldSplitterResult: util.Try[(Seq[(String, Int)], Seq[LineRange])], newSplitterResult: util.Try[(Seq[(String, Int)], Seq[LineRange])])
|
||||
|
|
|
|||
Loading…
Reference in New Issue