Remove binary compatibility breakages and migrate new parser features into an internal package.

This commit is contained in:
Josh Suereth 2014-09-26 13:26:48 -04:00 committed by Eugene Yokota
parent ff466c5cd3
commit a8370880e0
19 changed files with 79 additions and 30 deletions

View File

@ -11,7 +11,7 @@ import org.apache.ivy.util.url.CredentialsStore
/** Additional information about a project module */
final case class ModuleInfo(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None, developers: Seq[Developer] = Seq()) {
def this(nameFormal: String, description: String = "", homepage: Option[URL] = None, startYear: Option[Int] = None, licenses: Seq[(String, URL)] = Nil, organizationName: String = "", organizationHomepage: Option[URL] = None, scmInfo: Option[ScmInfo] = None) =
def this(nameFormal: String, description: String, homepage: Option[URL], startYear: Option[Int], licenses: Seq[(String, URL)], organizationName: String, organizationHomepage: Option[URL], scmInfo: Option[ScmInfo]) =
this(nameFormal, description, homepage, startYear, licenses, organizationName, organizationHomepage, scmInfo, Seq())
def formally(name: String) = copy(nameFormal = name)
def describing(desc: String, home: Option[URL]) = copy(description = desc, homepage = home)

View File

@ -8,6 +8,9 @@ import compiler.{ Eval, EvalImports }
import complete.DefaultParsers.validID
import Def.{ ScopedKey, Setting }
import Scope.GlobalScope
import sbt.internals.parser.SplitExpressionsNoBlankies
import scala.annotation.tailrec
/**
* This file is responsible for compiling the .sbt files used to configure sbt builds.
@ -206,18 +209,45 @@ object EvaluateConfigurations {
}
}
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)
/**
* Splits a set of lines into (imports, expressions). That is,
* anything on the right of the tuple is a scala expression (definition or setting).
*/
def splitExpressions(file: File, lines: Seq[String]): (Seq[(String, Int)], Seq[(String, LineRange)]) =
private[sbt] def splitExpressions(file: File, lines: Seq[String]): (Seq[(String, Int)], Seq[(String, LineRange)]) =
{
val split = SplitExpressionsNoBlankies(file, lines)
(split.imports, split.settings)
}
@deprecated("This method is no longer part of the public API.", "0.13.7")
def splitExpressions(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))
}
@deprecated("This method is deprecated and no longer used.", "0.13.7")
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)
}
private[this] def splitSettingsDefinitions(lines: Seq[(String, LineRange)]): (Seq[(String, LineRange)], Seq[(String, LineRange)]) =
lines partition { case (line, range) => isDefinition(line) }
private[this] def isDefinition(line: String): Boolean =

View File

@ -1,5 +1,8 @@
package sbt
import java.io.File
import sbt.internals.parser.{ XmlContent, SplitExpressionsNoBlankies }
import scala.collection.immutable.SortedMap
import scala.reflect.runtime.universe._

View File

@ -1,29 +1,31 @@
package sbt
package internals
package parser
import java.io.File
import sbt.internals.parser.SplitExpressionsNoBlankies._
import scala.annotation.tailrec
import SplitExpressionsNoBlankies._
import scala.reflect.runtime.universe
import scala.reflect.runtime.universe._
object SplitExpressionsNoBlankies {
private[sbt] object SplitExpressionsNoBlankies {
val END_OF_LINE_CHAR = '\n'
val END_OF_LINE = String.valueOf(END_OF_LINE_CHAR)
private[sbt] val FAKE_FILE = new File("fake")
}
case class SplitExpressionsNoBlankies(file: File, lines: Seq[String]) {
private[sbt] case class SplitExpressionsNoBlankies(file: File, lines: Seq[String]) {
//settingsTrees needed for "session save"
val (imports, settings, settingsTrees) = splitExpressions(file, lines)
private def splitExpressions(file: File, lines: Seq[String]): (Seq[(String, Int)], Seq[(String, LineRange)], Seq[(String, Tree)]) = {
import scala.reflect.runtime._
import sbt.internals.parser.BugInParser._
import sbt.internals.parser.XmlContent._
import scala.tools.reflect.ToolBoxError
import scala.tools.reflect.ToolBox
import scala.compat.Platform.EOL
import BugInParser._
import XmlContent._
import scala.tools.reflect.{ ToolBox, ToolBoxError }
val mirror = universe.runtimeMirror(this.getClass.getClassLoader)
val toolbox = mirror.mkToolBox(options = "-Yrangepos")
@ -150,7 +152,7 @@ private[sbt] object BugInParser {
* <a>rr</a>)
* </pre>
*/
private object XmlContent {
private[sbt] object XmlContent {
/**
*
* @param original - file content

View File

@ -1,5 +0,0 @@
package sbt
import org.specs2.mutable._
trait AbstractSpec extends Specification with SplitExpression

View File

@ -1,5 +1,7 @@
package sbt
import sbt.internals.parser.AbstractSpec
class SessionSettingsCutExpressionSpec extends AbstractSpec {
"Cut expression " should {

View File

@ -3,6 +3,7 @@ package sbt
import java.io.{ File, FilenameFilter }
import org.specs2.matcher.MatchResult
import sbt.internals.parser.{ AbstractSpec, SplitExpressionsNoBlankies }
import scala.collection.GenTraversableOnce
import scala.collection.immutable.{ SortedMap, TreeMap }

View File

@ -0,0 +1,5 @@
package sbt.internals.parser
import org.specs2.mutable._
trait AbstractSpec extends Specification with SplitExpression

View File

@ -1,4 +1,6 @@
package sbt
package sbt.internals.parser
import sbt.EvaluateConfigurations
abstract class CheckIfParsedSpec(implicit val splitter: SplitExpressions.SplitExpression = EvaluateConfigurations.splitExpressions) extends AbstractSpec {

View File

@ -1,4 +1,4 @@
package sbt
package sbt.internals.parser
class CommentedXmlSpec extends CheckIfParsedSpec {

View File

@ -1,4 +1,6 @@
package sbt
package sbt.internals.parser
import sbt.MessageOnlyException
class EmbeddedXmlSpec extends CheckIfParsedSpec {

View File

@ -1,10 +1,9 @@
package sbt
package sbt.internals.parser
import java.io.File
import org.scalacheck.Gen._
import org.scalacheck.Prop._
import org.specs2.ScalaCheck
import sbt.{ EvaluateConfigurations, MessageOnlyException }
import scala.io.Source
@ -14,7 +13,7 @@ class ErrorSpec extends AbstractSpec with ScalaCheck {
"Parser " should {
"contains file name and line number" in {
val rootPath = getClass.getResource("").getPath + "../error-format/"
val rootPath = getClass.getClassLoader.getResource("").getPath + "/error-format/"
println(s"Reading files from: $rootPath")
foreach(new File(rootPath).listFiles) { file =>
print(s"Processing ${file.getName}: ")

View File

@ -1,7 +1,9 @@
package sbt
package sbt.internals.parser
import java.io.File
import sbt.LineRange
import scala.annotation.tailrec
object EvaluateConfigurationsOriginal {

View File

@ -1,9 +1,10 @@
package sbt
package sbt.internals.parser
import java.io.File
import org.junit.runner.RunWith
import org.specs2.runner.JUnitRunner
import sbt.EvaluateConfigurations
import scala.io.Source
@ -13,7 +14,7 @@ class NewFormatSpec extends AbstractSpec {
"New Format " should {
"Handle lines " in {
val rootPath = getClass.getResource("").getPath + "../new-format/"
val rootPath = getClass.getClassLoader.getResource("").getPath + "/new-format/"
println(s"Reading files from: $rootPath")
val allFiles = new File(rootPath).listFiles.toList
foreach(allFiles) {

View File

@ -1,7 +1,9 @@
package sbt
package sbt.internals.parser
import java.io.File
import sbt.LineRange
object SplitExpressions {
type SplitExpression = (File, Seq[String]) => (Seq[(String, Int)], Seq[(String, LineRange)])
}

View File

@ -1,4 +1,4 @@
package sbt
package sbt.internals.parser
import java.io.File

View File

@ -1,4 +1,6 @@
package sbt
package internals
package parser
import java.io.File
@ -8,7 +10,7 @@ import scala.annotation.tailrec
import scala.io.Source
import scala.tools.reflect.ToolBoxError
class SplitExpressionsFilesTest extends AbstractSplitExpressionsFilesTest("../old-format/")
class SplitExpressionsFilesTest extends AbstractSplitExpressionsFilesTest("/old-format/")
abstract class AbstractSplitExpressionsFilesTest(pathName: String) extends Specification {
@ -23,7 +25,7 @@ abstract class AbstractSplitExpressionsFilesTest(pathName: String) extends Speci
s"$getClass " should {
"split whole sbt files" in {
val rootPath = getClass.getResource("").getPath + pathName
val rootPath = getClass.getClassLoader.getResource("").getPath + pathName
println(s"Reading files from: $rootPath")
val allFiles = new File(rootPath).listFiles.toList

View File

@ -1,6 +1,7 @@
package sbt
package sbt.internals.parser
import org.specs2.mutable.Specification
import sbt.EvaluateConfigurations
class SplitExpressionsTest extends Specification with SplitExpressionsBehavior {