mirror of https://github.com/sbt/sbt.git
Remove binary compatibility breakages and migrate new parser features into an internal package.
This commit is contained in:
parent
ff466c5cd3
commit
a8370880e0
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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._
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
package sbt
|
||||
|
||||
import org.specs2.mutable._
|
||||
|
||||
trait AbstractSpec extends Specification with SplitExpression
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
package sbt
|
||||
|
||||
import sbt.internals.parser.AbstractSpec
|
||||
|
||||
class SessionSettingsCutExpressionSpec extends AbstractSpec {
|
||||
|
||||
"Cut expression " should {
|
||||
|
|
|
|||
|
|
@ -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 }
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
package sbt.internals.parser
|
||||
|
||||
import org.specs2.mutable._
|
||||
|
||||
trait AbstractSpec extends Specification with SplitExpression
|
||||
|
|
@ -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 {
|
||||
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package sbt
|
||||
package sbt.internals.parser
|
||||
|
||||
class CommentedXmlSpec extends CheckIfParsedSpec {
|
||||
|
||||
|
|
@ -1,4 +1,6 @@
|
|||
package sbt
|
||||
package sbt.internals.parser
|
||||
|
||||
import sbt.MessageOnlyException
|
||||
|
||||
class EmbeddedXmlSpec extends CheckIfParsedSpec {
|
||||
|
||||
|
|
@ -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}: ")
|
||||
|
|
@ -1,7 +1,9 @@
|
|||
package sbt
|
||||
package sbt.internals.parser
|
||||
|
||||
import java.io.File
|
||||
|
||||
import sbt.LineRange
|
||||
|
||||
import scala.annotation.tailrec
|
||||
|
||||
object EvaluateConfigurationsOriginal {
|
||||
|
|
@ -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) {
|
||||
|
|
@ -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)])
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
package sbt
|
||||
package sbt.internals.parser
|
||||
|
||||
import java.io.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
|
||||
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
package sbt
|
||||
package sbt.internals.parser
|
||||
|
||||
import org.specs2.mutable.Specification
|
||||
import sbt.EvaluateConfigurations
|
||||
|
||||
class SplitExpressionsTest extends Specification with SplitExpressionsBehavior {
|
||||
|
||||
Loading…
Reference in New Issue