mirror of https://github.com/sbt/sbt.git
Documentation and renaming of "blankies" into somethign a bit easier to find.
* Rename SPlitExpression* to `SbtParser` denoting that is parses .sbt files * Adds a few todos * Document APIs for internal usage.
This commit is contained in:
parent
e230a17d3b
commit
009426d896
|
|
@ -8,7 +8,7 @@ import compiler.{ Eval, EvalImports }
|
|||
import complete.DefaultParsers.validID
|
||||
import Def.{ ScopedKey, Setting }
|
||||
import Scope.GlobalScope
|
||||
import sbt.internals.parser.SplitExpressionsNoBlankies
|
||||
import sbt.internals.parser.SbtParser
|
||||
|
||||
import scala.annotation.tailrec
|
||||
|
||||
|
|
@ -218,7 +218,9 @@ object EvaluateConfigurations {
|
|||
*/
|
||||
private[sbt] def splitExpressions(file: File, lines: Seq[String]): (Seq[(String, Int)], Seq[(String, LineRange)]) =
|
||||
{
|
||||
val split = SplitExpressionsNoBlankies(file, lines)
|
||||
val split = SbtParser(file, lines)
|
||||
// TODO - Look at pulling the parsed expression trees from the SbtParser and stitch them back into a different
|
||||
// scala compiler rather than re-parsing.
|
||||
(split.imports, split.settings)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -130,11 +130,18 @@ object SessionSettings {
|
|||
oldState.log.warn("Discarding " + pluralize(oldSettings.size, " session setting") + ". Use 'session save' to persist session settings.")
|
||||
}
|
||||
|
||||
@deprecated("This method will no longer be public", "0.13.7")
|
||||
def removeRanges[T](in: Seq[T], ranges: Seq[(Int, Int)]): Seq[T] = {
|
||||
val asSet = (Set.empty[Int] /: ranges) { case (s, (hi, lo)) => s ++ (hi to lo) }
|
||||
in.zipWithIndex.flatMap { case (t, index) => if (asSet(index + 1)) Nil else t :: Nil }
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes settings from the current session, by range.
|
||||
* @param s The current build state.
|
||||
* @param ranges A set of Low->High tuples for which settings to remove.
|
||||
* @return The new build state with settings removed.
|
||||
*/
|
||||
def removeSettings(s: State, ranges: Seq[(Int, Int)]): State =
|
||||
withSettings(s) { session =>
|
||||
val current = session.current
|
||||
|
|
@ -169,6 +176,7 @@ object SessionSettings {
|
|||
reapply(newSession.copy(original = newSession.mergeSettings, append = Map.empty), s)
|
||||
}
|
||||
|
||||
@deprecated("This method will no longer be publlic", "0.13.7")
|
||||
def writeSettings(pref: ProjectRef, settings: List[SessionSetting], original: Seq[Setting[_]], structure: BuildStructure): (Seq[SessionSetting], Seq[Setting[_]]) = {
|
||||
val project = Project.getProject(pref, structure).getOrElse(sys.error("Invalid project reference " + pref))
|
||||
val writeTo: File = BuildPaths.configurationSources(project.base).headOption.getOrElse(new File(project.base, "build.sbt"))
|
||||
|
|
@ -209,6 +217,7 @@ object SessionSettings {
|
|||
(newWithPos.reverse, other ++ oldShifted)
|
||||
}
|
||||
|
||||
@deprecated("This method will no longer be publlic", "0.13.7")
|
||||
def needsTrailingBlank(lines: Seq[String]) = !lines.isEmpty && !lines.takeRight(1).exists(_.trim.isEmpty)
|
||||
|
||||
/** Prints all the user-defined SessionSettings (not raw) to System.out. */
|
||||
|
|
@ -221,12 +230,14 @@ object SessionSettings {
|
|||
s
|
||||
}
|
||||
|
||||
/** Prints all the defined session settings for the current project in the given build state. */
|
||||
def printSettings(s: State): State =
|
||||
withSettings(s) { session =>
|
||||
printSettings(session.append.getOrElse(session.current, Nil))
|
||||
s
|
||||
}
|
||||
|
||||
/** Prints all the passed in session settings */
|
||||
def printSettings(settings: Seq[SessionSetting]): Unit =
|
||||
for (((_, stringRep), index) <- settings.zipWithIndex)
|
||||
println(" " + (index + 1) + ". " + stringRep.mkString("\n"))
|
||||
|
|
@ -291,7 +302,7 @@ save, save-all
|
|||
|
||||
def range: Parser[(Int, Int)] = (NatBasic ~ ('-' ~> NatBasic).?).map { case lo ~ hi => (lo, hi getOrElse lo) }
|
||||
|
||||
/** The raw implementation of the sessoin command. */
|
||||
/** The raw implementation of the session command. */
|
||||
def command(s: State) = Command.applyEffect(parser) {
|
||||
case p: Print => if (p.all) printAllSettings(s) else printSettings(s)
|
||||
case v: Save => if (v.all) saveAllSettings(s) else saveSettings(s)
|
||||
|
|
|
|||
|
|
@ -4,20 +4,56 @@ package parser
|
|||
|
||||
import java.io.File
|
||||
|
||||
import sbt.internals.parser.SplitExpressionsNoBlankies._
|
||||
import sbt.internals.parser.SbtParser._
|
||||
|
||||
import scala.annotation.tailrec
|
||||
import scala.reflect.runtime.universe._
|
||||
|
||||
private[sbt] object SplitExpressionsNoBlankies {
|
||||
private[sbt] object SbtParser {
|
||||
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]) {
|
||||
/**
|
||||
* This method soley exists to add scaladoc to members in SbtParser which
|
||||
* are defined using pattern matching.
|
||||
*/
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
* An initial parser/splitter of .sbt files.
|
||||
*
|
||||
* This class is responsible for chunking a `.sbt` file into expression ranges
|
||||
* which we can then compile using the Scala compiler.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* {{{
|
||||
* val parser = SbtParser(myFile, IO.readLines(myFile))
|
||||
* // All import statements
|
||||
* val imports = parser.imports
|
||||
* // All other statements (val x =, or raw settings)
|
||||
* val settings = parser.settings
|
||||
* }}}
|
||||
*
|
||||
* @param file The file we're parsing (may be a dummy file)
|
||||
* @param lines The parsed "lines" of the file, where each string is a line.
|
||||
*/
|
||||
private[sbt] case class SbtParser(file: File, lines: Seq[String]) extends ParsedSbtFileExpressions {
|
||||
//settingsTrees,modifiedContent needed for "session save"
|
||||
// TODO - We should look into splitting out "defintiions" vs. "settings" here instead of further string lookups, since we have the
|
||||
// parsed trees.
|
||||
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) = {
|
||||
|
|
@ -117,7 +153,7 @@ private[sbt] object MissingBracketHandler {
|
|||
case Some(index) =>
|
||||
val text = content.substring(positionEnd, index + 1)
|
||||
val textWithoutBracket = text.substring(0, text.length - 1)
|
||||
util.Try(SplitExpressionsNoBlankies(FAKE_FILE, textWithoutBracket.lines.toSeq)) match {
|
||||
util.Try(SbtParser(FAKE_FILE, textWithoutBracket.lines.toSeq)) match {
|
||||
case util.Success(_) =>
|
||||
text
|
||||
case util.Failure(th) =>
|
||||
|
|
@ -6,7 +6,7 @@ import scala.reflect.runtime.universe._
|
|||
|
||||
private[sbt] object SbtRefactorings {
|
||||
|
||||
import sbt.internals.parser.SplitExpressionsNoBlankies.{ END_OF_LINE, FAKE_FILE }
|
||||
import sbt.internals.parser.SbtParser.{ END_OF_LINE, FAKE_FILE }
|
||||
import sbt.SessionSettings.{ SessionSetting, SbtConfigFile }
|
||||
|
||||
val EMPTY_STRING = ""
|
||||
|
|
@ -23,7 +23,7 @@ private[sbt] object SbtRefactorings {
|
|||
*/
|
||||
def applySessionSettings(configFile: SbtConfigFile, commands: Seq[SessionSetting]): SbtConfigFile = {
|
||||
val (file, lines) = configFile
|
||||
val split = SplitExpressionsNoBlankies(FAKE_FILE, lines)
|
||||
val split = SbtParser(FAKE_FILE, lines)
|
||||
val recordedCommands = recordCommands(commands, split)
|
||||
val sortedRecordedCommands = recordedCommands.sortBy(_._1)(REVERSE_ORDERING_INT)
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ private[sbt] object SbtRefactorings {
|
|||
if (trimmed.isEmpty) trimmed else text
|
||||
}
|
||||
|
||||
private def recordCommands(commands: Seq[SessionSetting], split: SplitExpressionsNoBlankies) =
|
||||
private def recordCommands(commands: Seq[SessionSetting], split: SbtParser) =
|
||||
commands.flatMap {
|
||||
case (_, command) =>
|
||||
val map = toTreeStringMap(command)
|
||||
|
|
@ -56,7 +56,7 @@ private[sbt] object SbtRefactorings {
|
|||
}
|
||||
}
|
||||
|
||||
private def treesToReplacements(split: SplitExpressionsNoBlankies, name: String, command: Seq[String]) =
|
||||
private def treesToReplacements(split: SbtParser, name: String, command: Seq[String]) =
|
||||
split.settingsTrees.foldLeft(Seq.empty[(Int, String, String)]) {
|
||||
case (acc, (st, tree)) =>
|
||||
val treeName = extractSettingName(tree)
|
||||
|
|
@ -73,7 +73,7 @@ private[sbt] object SbtRefactorings {
|
|||
}
|
||||
|
||||
private def toTreeStringMap(command: Seq[String]) = {
|
||||
val split = SplitExpressionsNoBlankies(FAKE_FILE, command)
|
||||
val split = SbtParser(FAKE_FILE, command)
|
||||
val trees = split.settingsTrees
|
||||
val seq = trees.map {
|
||||
case (statement, tree) =>
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ class ErrorSpec extends AbstractSpec with ScalaCheck {
|
|||
foreach(new File(rootPath).listFiles) { file =>
|
||||
print(s"Processing ${file.getName}: ")
|
||||
val buildSbt = Source.fromFile(file).getLines().mkString("\n")
|
||||
SplitExpressionsNoBlankies(file, buildSbt.lines.toSeq) must throwA[MessageOnlyException].like {
|
||||
SbtParser(file, buildSbt.lines.toSeq) must throwA[MessageOnlyException].like {
|
||||
case exp =>
|
||||
val message = exp.getMessage
|
||||
println(s"${exp.getMessage}")
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@ abstract class AbstractSessionSettingsSpec(folder: String) extends AbstractSpec
|
|||
foreach(expectedResultAndMap(file)) {
|
||||
case (expectedResultList, commands) =>
|
||||
val resultList = SbtRefactorings.applySessionSettings((file, originalLines), commands)
|
||||
val expected = SplitExpressionsNoBlankies(file, expectedResultList)
|
||||
val result = SplitExpressionsNoBlankies(file, resultList._2)
|
||||
val expected = SbtParser(file, expectedResultList)
|
||||
val result = SbtParser(file, resultList._2)
|
||||
result.settings must_== expected.settings
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue