From d9aadaf1e1afc387edb70d311f5c2d90fe36e089 Mon Sep 17 00:00:00 2001 From: "andrzej.jozwik@gmail.com" Date: Thu, 20 Nov 2014 23:10:03 +0100 Subject: [PATCH 1/2] Multi import in one line --- .../sbt/internals/parser/SbtParser.scala | 44 +++++++++++++++++-- main/src/test/resources/old-format/23.sbt.txt | 7 +++ 2 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 main/src/test/resources/old-format/23.sbt.txt diff --git a/main/src/main/scala/sbt/internals/parser/SbtParser.scala b/main/src/main/scala/sbt/internals/parser/SbtParser.scala index 583375f88..21ff844b7 100644 --- a/main/src/main/scala/sbt/internals/parser/SbtParser.scala +++ b/main/src/main/scala/sbt/internals/parser/SbtParser.scala @@ -114,9 +114,6 @@ private[sbt] case class SbtParser(file: File, lines: Seq[String]) extends Parsed case _ => false } - def convertImport(t: Tree): (String, Int) = - (modifiedContent.substring(t.pos.start, t.pos.end), t.pos.line - 1) - /** * See BugInParser * @param t - tree @@ -145,7 +142,46 @@ private[sbt] case class SbtParser(file: File, lines: Seq[String]) extends Parsed Some((statement, t, LineRange(position.line - 1, position.line + numberLines))) } val stmtTreeLineRange = statements flatMap convertStatement - (imports map convertImport, stmtTreeLineRange.map { case (stmt, _, lr) => (stmt, lr) }, stmtTreeLineRange.map { case (stmt, tree, _) => (stmt, tree) }, modifiedContent) + val importsLineRange = importsToLineRanges(modifiedContent, imports) + (importsLineRange, stmtTreeLineRange.map { case (stmt, _, lr) => (stmt, lr) }, stmtTreeLineRange.map { case (stmt, tree, _) => (stmt, tree) }, modifiedContent) + } + + /** + * import sbt._, Keys._,java.util._ should return ("import sbt._, Keys._,java.util._",0) + * @param modifiedContent - modifiedContent + * @param imports - trees + * @return imports per line + */ + private def importsToLineRanges(modifiedContent: String, imports: Seq[Tree]): Seq[(String, Int)] = { + val toLineRange = imports map convertImport(modifiedContent) + val groupedByLineNumber = toLineRange.groupBy { case (_, lineNumber) => lineNumber } + val mergedImports = groupedByLineNumber.map { case (l, seq) => (extractLine(modifiedContent, seq), l) } + mergedImports.toSeq.sortBy(_._2) + } + + /** + * + * @param modifiedContent - modifiedContent + * @param t - tree + * @return ((start,end),lineNumber) + */ + private def convertImport(modifiedContent: String)(t: Tree): ((Int, Int), Int) = { + val lineNumber = t.pos.line - 1 + ((t.pos.start, t.pos.end), lineNumber) + } + + /** + * Search for min begin index and max end index + * @param modifiedContent - modifiedContent + * @param importsInOneLine - imports in line + * @return - text + */ + private def extractLine(modifiedContent: String, importsInOneLine: Seq[((Int, Int), Int)]): String = { + val (begin, end) = importsInOneLine.foldLeft((Int.MaxValue, Int.MinValue)) { + case ((min, max), ((start, end), _)) => + (min.min(start), max.max(end)) + } + modifiedContent.substring(begin, end) } private def countLines(statement: String) = statement.count(c => c == END_OF_LINE_CHAR) diff --git a/main/src/test/resources/old-format/23.sbt.txt b/main/src/test/resources/old-format/23.sbt.txt new file mode 100644 index 000000000..0bdd2de41 --- /dev/null +++ b/main/src/test/resources/old-format/23.sbt.txt @@ -0,0 +1,7 @@ +import sbt._, Keys._,java.util._ +import a._ +import c._ +import d._ +import g._,h._ + +scalaVersion := "2.11.4" \ No newline at end of file From ce75c5a9b0672613003e5c89be531553f057ab22 Mon Sep 17 00:00:00 2001 From: "andrzej.jozwik@gmail.com" Date: Fri, 21 Nov 2014 09:11:09 +0100 Subject: [PATCH 2/2] For backward compatibility - do not used duplicated imports --- main/src/main/scala/sbt/internals/parser/SbtParser.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/main/src/main/scala/sbt/internals/parser/SbtParser.scala b/main/src/main/scala/sbt/internals/parser/SbtParser.scala index 21ff844b7..c80721f3f 100644 --- a/main/src/main/scala/sbt/internals/parser/SbtParser.scala +++ b/main/src/main/scala/sbt/internals/parser/SbtParser.scala @@ -155,8 +155,8 @@ private[sbt] case class SbtParser(file: File, lines: Seq[String]) extends Parsed private def importsToLineRanges(modifiedContent: String, imports: Seq[Tree]): Seq[(String, Int)] = { val toLineRange = imports map convertImport(modifiedContent) val groupedByLineNumber = toLineRange.groupBy { case (_, lineNumber) => lineNumber } - val mergedImports = groupedByLineNumber.map { case (l, seq) => (extractLine(modifiedContent, seq), l) } - mergedImports.toSeq.sortBy(_._2) + val mergedImports = groupedByLineNumber.map { case (l, seq) => (l, extractLine(modifiedContent, seq)) } + mergedImports.toSeq.sortBy(_._1).map { case (k, v) => (v, k) } } /**