From 0a832ffaa1709467bd9a0529f580640feddf0f6f Mon Sep 17 00:00:00 2001 From: Gerard Basler Date: Mon, 17 Dec 2012 17:52:26 +0100 Subject: [PATCH 01/36] Add new option `noSpacesAroundMultiImports` to disable reformatting of `import a.b.c.{d, e, f}` into `import a.b.c.{ d, e, f }`. Especially for Java experienced coders this looks more natural. --- .../scala/scalariform/formatter/ExprFormatter.scala | 4 ++++ .../formatter/preferences/PreferenceDescriptor.scala | 10 ++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) mode change 100644 => 100755 scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala mode change 100644 => 100755 scalariform/src/main/scala/scalariform/formatter/preferences/PreferenceDescriptor.scala diff --git a/scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala b/scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala old mode 100644 new mode 100755 index f06d6804..7c950a77 --- a/scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala +++ b/scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala @@ -909,9 +909,13 @@ trait ExprFormatter { self: HasFormattingPreferences with AnnotationFormatter wi val newFormatterState = formatterState.copy(inSingleLineBlock = singleLineBlock) if (singleLineBlock) { + if (formattingPreferences(NoSpacesAroundMultiImports)) + formatResult = formatResult.before(firstImportSelector.firstToken, Compact) formatResult ++= format(firstImportSelector) for ((comma, otherImportSelector) ← otherImportSelectors) formatResult ++= format(otherImportSelector) + if (formattingPreferences(NoSpacesAroundMultiImports)) + formatResult = formatResult.before(rbrace, Compact) } else { formatResult = formatResult.before(firstImportSelector.firstToken, formatterState.nextIndentLevelInstruction) formatResult ++= format(firstImportSelector) diff --git a/scalariform/src/main/scala/scalariform/formatter/preferences/PreferenceDescriptor.scala b/scalariform/src/main/scala/scalariform/formatter/preferences/PreferenceDescriptor.scala old mode 100644 new mode 100755 index 48975161..96cb17fa --- a/scalariform/src/main/scala/scalariform/formatter/preferences/PreferenceDescriptor.scala +++ b/scalariform/src/main/scala/scalariform/formatter/preferences/PreferenceDescriptor.scala @@ -64,7 +64,7 @@ object AllPreferences { PreserveSpaceBeforeArguments, AlignParameters, DoubleIndentClassDeclaration, FormatXml, IndentPackageBlocks, AlignSingleLineCaseStatements, AlignSingleLineCaseStatements.MaxArrowIndent, IndentLocalDefs, PreserveDanglingCloseParenthesis, SpaceInsideParentheses, SpaceInsideBrackets, SpacesWithinPatternBinders, MultilineScaladocCommentsStartOnFirstLine, IndentWithTabs, - CompactControlReadability, PlaceScaladocAsterisksBeneathSecondAsterisk) + CompactControlReadability, PlaceScaladocAsterisksBeneathSecondAsterisk, NoSpacesAroundMultiImports) val preferencesByKey: Map[String, PreferenceDescriptor[_]] = { var map: Map[String, PreferenceDescriptor[_]] = Map() @@ -196,4 +196,10 @@ case object PlaceScaladocAsterisksBeneathSecondAsterisk extends BooleanPreferenc val key = "placeScaladocAsterisksBeneathSecondAsterisk" val description = "Place Scaladoc asterisks beneath the second asterisk in the opening '/**', as opposed to the first" val defaultValue = false -} \ No newline at end of file +} + +case object NoSpacesAroundMultiImports extends BooleanPreferenceDescriptor { + val key = "noSpacesAroundMultiImports" + val description = "Don't place spaces around multi imports (Java-style)" + val defaultValue = false +} From f35f29e1debde7106ed116f2dff39f72eccd86f0 Mon Sep 17 00:00:00 2001 From: Gerard Basler Date: Tue, 25 Dec 2012 19:03:12 +0100 Subject: [PATCH 02/36] Add multi-line case formatting option. --- .../scala/scalariform/formatter/CaseClauseFormatter.scala | 3 ++- .../formatter/preferences/PreferenceDescriptor.scala | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala b/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala index 9255a4bc..516b2612 100644 --- a/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala +++ b/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala @@ -86,7 +86,8 @@ trait CaseClauseFormatter { self: HasFormattingPreferences with ExprFormatter wi val clauseBodyIsMultiline = containsNewline(pruneTrailingNewline(statSeq)) || statSeq.firstTokenOption.exists(hiddenPredecessors(_).containsNewline) - if (formattedCasePattern.contains('\n') || (first && !clausesAreMultiline) || (!first && !newlineBeforeClause) || clauseBodyIsMultiline) + if (!formattingPreferences(AlignSingleLineCaseStatements.AlignMultiLineCaseStatements) && + (formattedCasePattern.contains('\n') || (first && !clausesAreMultiline) || (!first && !newlineBeforeClause) || clauseBodyIsMultiline)) Right(caseClause) :: otherClausesGrouped else { val arrowAdjust = (if (formattingPreferences(RewriteArrowSymbols)) 1 else casePattern.arrow.length) + 1 diff --git a/scalariform/src/main/scala/scalariform/formatter/preferences/PreferenceDescriptor.scala b/scalariform/src/main/scala/scalariform/formatter/preferences/PreferenceDescriptor.scala index 96cb17fa..daba01d6 100755 --- a/scalariform/src/main/scala/scalariform/formatter/preferences/PreferenceDescriptor.scala +++ b/scalariform/src/main/scala/scalariform/formatter/preferences/PreferenceDescriptor.scala @@ -62,7 +62,7 @@ trait IntegerPreferenceDescriptor extends PreferenceDescriptor[Int] { object AllPreferences { val preferences: List[PreferenceDescriptor[_]] = List(RewriteArrowSymbols, IndentSpaces, SpaceBeforeColon, CompactStringConcatenation, PreserveSpaceBeforeArguments, AlignParameters, DoubleIndentClassDeclaration, FormatXml, IndentPackageBlocks, - AlignSingleLineCaseStatements, AlignSingleLineCaseStatements.MaxArrowIndent, IndentLocalDefs, PreserveDanglingCloseParenthesis, + AlignSingleLineCaseStatements, AlignSingleLineCaseStatements.MaxArrowIndent, AlignSingleLineCaseStatements.AlignMultiLineCaseStatements, IndentLocalDefs, PreserveDanglingCloseParenthesis, SpaceInsideParentheses, SpaceInsideBrackets, SpacesWithinPatternBinders, MultilineScaladocCommentsStartOnFirstLine, IndentWithTabs, CompactControlReadability, PlaceScaladocAsterisksBeneathSecondAsterisk, NoSpacesAroundMultiImports) @@ -142,6 +142,12 @@ case object AlignSingleLineCaseStatements extends BooleanPreferenceDescriptor { val defaultValue = 40 } + case object AlignMultiLineCaseStatements extends BooleanPreferenceDescriptor { + val key = "alignSingleLineCaseStatements.alignMultiLineCaseStatements" + val description = "Align the arrows of consecutive multi-line case statements" + val defaultValue = false + } + } case object IndentLocalDefs extends BooleanPreferenceDescriptor { From 2aa424986a96de79e0d09070803d9d0d6e76c5d8 Mon Sep 17 00:00:00 2001 From: Gerard Basler Date: Sun, 13 Jan 2013 19:42:54 +0100 Subject: [PATCH 03/36] Add `GroupByNewLine` option that let's you format blocks in case statements individually (IntelliJ compatibility). --- .../formatter/CaseClauseFormatter.scala | 25 +++- .../preferences/PreferenceDescriptor.scala | 6 + .../main/scala/scalariform/lexer/Token.scala | 2 + .../scala/scalariform/lexer/TokenType.scala | 4 +- .../formatter/CaseClausesFormatterTest.scala | 109 ++++++++++++++++++ 5 files changed, 142 insertions(+), 4 deletions(-) diff --git a/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala b/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala index 516b2612..ecc2a441 100644 --- a/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala +++ b/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala @@ -1,6 +1,6 @@ package scalariform.formatter -import scalariform.lexer.Token +import scalariform.lexer.{TokenType, Token} import scalariform.lexer.Tokens._ import scalariform.parser._ import scalariform.utils.Utils @@ -81,7 +81,7 @@ trait CaseClauseFormatter { self: HasFormattingPreferences with ExprFormatter wi val newlineBeforeClause = hiddenPredecessors(caseClause.firstToken).containsNewline || previousCaseClauseEndsWithNewline(caseClause, caseClausesAstNode) - // To evaluate whether a clause body is multiline, we ignore a trailing newline: + // To evaluate whether a clause body is multiline, we ignore a trailing newline: val prunedStatSeq = pruneTrailingNewline(statSeq) val clauseBodyIsMultiline = containsNewline(pruneTrailingNewline(statSeq)) || statSeq.firstTokenOption.exists(hiddenPredecessors(_).containsNewline) @@ -100,7 +100,26 @@ trait CaseClauseFormatter { self: HasFormattingPreferences with ExprFormatter wi } } } - groupClauses(caseClausesAstNode.caseClauses, first = true) + + val caseClauses: List[CaseClause] = caseClausesAstNode.caseClauses + + val ranges: List[(Int, Int)] = if (formattingPreferences(AlignSingleLineCaseStatements.GroupByNewLine)) { + val newLinesAt = (caseClauses.zipWithIndex.collect { + case (c, i) if c.tokens.exists(_.isNewlines) => i + 1 + }) + + val newLinesWithBeginAndEnd = (if (newLinesAt.contains(0)) List() else List(0)) ++ newLinesAt ++ List(caseClauses.length) + + newLinesWithBeginAndEnd.zip(newLinesWithBeginAndEnd.tail) + } else { + List(0 -> caseClauses.length) + } + + ranges.foldLeft(List[Either[ConsecutiveSingleLineCaseClauses, CaseClause]]()) { + case (acc, (begin, end)) => + val slice = caseClauses.slice(begin, end) + acc ++ groupClauses(slice, first = true) + } } private case class ConsecutiveSingleLineCaseClauses(clauses: List[CaseClause], largestCasePatternLength: Int, smallestCasePatternLength: Int) { diff --git a/scalariform/src/main/scala/scalariform/formatter/preferences/PreferenceDescriptor.scala b/scalariform/src/main/scala/scalariform/formatter/preferences/PreferenceDescriptor.scala index daba01d6..cc2cd1aa 100755 --- a/scalariform/src/main/scala/scalariform/formatter/preferences/PreferenceDescriptor.scala +++ b/scalariform/src/main/scala/scalariform/formatter/preferences/PreferenceDescriptor.scala @@ -148,6 +148,12 @@ case object AlignSingleLineCaseStatements extends BooleanPreferenceDescriptor { val defaultValue = false } + case object GroupByNewLine extends BooleanPreferenceDescriptor { + val key = "alignSingleLineCaseStatements.groupByNewLine" + val description = "Treat blocks that are separated by newlines independently" + val defaultValue = false + } + } case object IndentLocalDefs extends BooleanPreferenceDescriptor { diff --git a/scalariform/src/main/scala/scalariform/lexer/Token.scala b/scalariform/src/main/scala/scalariform/lexer/Token.scala index 365122eb..6e5cb72b 100644 --- a/scalariform/src/main/scala/scalariform/lexer/Token.scala +++ b/scalariform/src/main/scala/scalariform/lexer/Token.scala @@ -27,6 +27,8 @@ case class Token(tokenType: TokenType, text: String, offset: Int, rawText: Strin def isNewline = tokenType.isNewline + def isNewlines = tokenType.isNewlines + @deprecated(message = "Use text instead" /*, since = "0.1.2"*/ ) def getText = text diff --git a/scalariform/src/main/scala/scalariform/lexer/TokenType.scala b/scalariform/src/main/scala/scalariform/lexer/TokenType.scala index 2f51e561..fb64f3ba 100644 --- a/scalariform/src/main/scala/scalariform/lexer/TokenType.scala +++ b/scalariform/src/main/scala/scalariform/lexer/TokenType.scala @@ -2,7 +2,9 @@ package scalariform.lexer case class TokenType(name: String, isXml: Boolean = false) { - def isNewline = this == Tokens.NEWLINE || this == Tokens.NEWLINES + def isNewline = this == Tokens.NEWLINE || isNewlines + + def isNewlines = this == Tokens.NEWLINES def isKeyword = Tokens.KEYWORDS contains this diff --git a/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala b/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala index a2e106a6..0a7966d4 100644 --- a/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala +++ b/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala @@ -306,4 +306,113 @@ class CaseClausesFormatterTest extends AbstractExpressionFormatterTest { | case elem @ Multi(values @ _*) => |}""" + { + implicit val formattingPreferences = FormattingPreferences.setPreference(AlignSingleLineCaseStatements, true) + .setPreference(AlignSingleLineCaseStatements.AlignMultiLineCaseStatements, true) + + """a match { + |case "once" => + |println("einmal") + |println("nochmal") + |case "many times" => + |println("again") + |println("multiline") + |case _ => + |println("again") + |println("multiline") + |}""" ==> + """a match { + | case "once" => + | println("einmal") + | println("nochmal") + | case "many times" => + | println("again") + | println("multiline") + | case _ => + | println("again") + | println("multiline") + |}""" + } + + { + implicit val formattingPreferences = FormattingPreferences.setPreference(AlignSingleLineCaseStatements, true) + .setPreference(AlignSingleLineCaseStatements.AlignMultiLineCaseStatements, true) + .setPreference(AlignSingleLineCaseStatements.GroupByNewLine, false) + + """a match { + |case "once" => + |println("einmal") + |println("nochmal") + |case "many times" => + |println("again") + |println("multiline") + |case _ => + |println("again") + |println("multiline") + | + |case "after a newline" => + |println("IntelliJ") + |println("formats") + |case "next lines" => + |println("separately") + |}""" ==> + """a match { + | case "once" => + | println("einmal") + | println("nochmal") + | case "many times" => + | println("again") + | println("multiline") + | case _ => + | println("again") + | println("multiline") + | + | case "after a newline" => + | println("IntelliJ") + | println("formats") + | case "next lines" => + | println("separately") + |}""" + } + + { + implicit val formattingPreferences = FormattingPreferences.setPreference(AlignSingleLineCaseStatements, true) + .setPreference(AlignSingleLineCaseStatements.AlignMultiLineCaseStatements, true) + .setPreference(AlignSingleLineCaseStatements.GroupByNewLine, true) + + """a match { + |case "once" => + |println("einmal") + |println("nochmal") + |case "many times" => + |println("again") + |println("multiline") + |case _ => + |println("again") + |println("multiline") + | + |case "after a newline" => + |println("IntelliJ") + |println("formats") + |case "next lines" => + |println("separately") + |}""" ==> + """a match { + | case "once" => + | println("einmal") + | println("nochmal") + | case "many times" => + | println("again") + | println("multiline") + | case _ => + | println("again") + | println("multiline") + | + | case "after a newline" => + | println("IntelliJ") + | println("formats") + | case "next lines" => + | println("separately") + |}""" + } } From 1e2d29e51c5ce4665590a918007b32196c0219f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9rard=20Basler?= Date: Sun, 13 Jan 2013 19:52:58 +0100 Subject: [PATCH 04/36] Update README.rst --- README.rst | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.rst b/README.rst index 5fbc3945..f318e010 100644 --- a/README.rst +++ b/README.rst @@ -28,6 +28,15 @@ You can also configure formatting to be run as a save action (Window -> Preferen To set preferences, go to Window -> Preferences -> Scala -> Formatter +Integration with IntelliJ +------------------------- + +IntelliJ already has a built-in Scala code formatter (C-L). +I use the original settings plus `Wraping and Braces` -> `Align columns in case branches`. +In order to achieve exactly the same formatting use the following options:: + +alignSingleLineCaseStatements +alignSingleLineCaseStatements.AlignMultiLineCaseStatements +alignSingleLineCaseStatements.GroupByNewLine + + Integration with Emacs/ENSIME ----------------------------- From 63a17eeaec7c6f2e035144d473e7ceaabd2bf769 Mon Sep 17 00:00:00 2001 From: Gerard Basler Date: Mon, 14 Jan 2013 02:07:38 +0100 Subject: [PATCH 05/36] Bugfix for `final` modifier in constructor arguments. --- .../src/main/scala/scalariform/formatter/ScalaFormatter.scala | 2 +- .../scala/scalariform/formatter/TemplateFormatterTest.scala | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/scalariform/src/main/scala/scalariform/formatter/ScalaFormatter.scala b/scalariform/src/main/scala/scalariform/formatter/ScalaFormatter.scala index 17f945af..3bba7e08 100644 --- a/scalariform/src/main/scala/scalariform/formatter/ScalaFormatter.scala +++ b/scalariform/src/main/scala/scalariform/formatter/ScalaFormatter.scala @@ -348,7 +348,7 @@ abstract class ScalaFormatter extends HasFormattingPreferences with TypeFormatte return CompactEnsuringGap if (type1 == MINUS && (type2 == INTEGER_LITERAL || type2 == FLOATING_POINT_LITERAL)) return Compact - if (Set(IMPLICIT, VAL, VAR, PRIVATE, PROTECTED, OVERRIDE).contains(type2) && type1 == LPAREN) + if (Set(IMPLICIT, VAL, VAR, PRIVATE, PROTECTED, OVERRIDE, FINAL).contains(type2) && type1 == LPAREN) return Compact if ((type1 == PROTECTED || type1 == PRIVATE) && type2 == LBRACKET) return Compact diff --git a/scalariform/src/test/scala/scalariform/formatter/TemplateFormatterTest.scala b/scalariform/src/test/scala/scalariform/formatter/TemplateFormatterTest.scala index e36c9c59..39e930ab 100644 --- a/scalariform/src/test/scala/scalariform/formatter/TemplateFormatterTest.scala +++ b/scalariform/src/test/scala/scalariform/formatter/TemplateFormatterTest.scala @@ -195,6 +195,7 @@ class TemplateFormatterTest extends AbstractFormatterTest { "class A(private val b: C)" ==> "class A(private val b: C)" "class A(protected val b: C)" ==> "class A(protected val b: C)" "class A(override val b: C)" ==> "class A(override val b: C)" + "class A(final val b: C)" ==> "class A(final val b: C)" """class C[T <: A {val n: Int |val m :Int}]""" ==> From 749a1c397095b0579636aae32aa4b1beaf63001b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9rard=20Basler?= Date: Mon, 14 Jan 2013 02:16:58 +0100 Subject: [PATCH 06/36] Update README.rst --- README.rst | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/README.rst b/README.rst index f318e010..63869b6e 100644 --- a/README.rst +++ b/README.rst @@ -34,7 +34,23 @@ Integration with IntelliJ IntelliJ already has a built-in Scala code formatter (C-L). I use the original settings plus `Wraping and Braces` -> `Align columns in case branches`. In order to achieve exactly the same formatting use the following options:: - +alignSingleLineCaseStatements +alignSingleLineCaseStatements.AlignMultiLineCaseStatements +alignSingleLineCaseStatements.GroupByNewLine + + + def formattingPreferences = { + import scalariform.formatter.preferences._ + FormattingPreferences() + .setPreference(AlignParameters, true) + .setPreference(AlignSingleLineCaseStatements, true) + .setPreference(AlignSingleLineCaseStatements.AlignMultiLineCaseStatements, true) + .setPreference(AlignSingleLineCaseStatements.MaxArrowIndent, 120) + .setPreference(AlignSingleLineCaseStatements.GroupByNewLine, true) // IntelliJ compatible + .setPreference(CompactControlReadability, false) + .setPreference(NoSpacesAroundMultiImports, true) + .setPreference(FormatXml, false) + .setPreference(PreserveSpaceBeforeArguments, true) + .setPreference(IndentWithTabs, false) + .setPreference(SpacesWithinPatternBinders, false) // IntelliJ compatible + } Integration with Emacs/ENSIME From f43acd026bc04b5875262b3fb474e906de6aae18 Mon Sep 17 00:00:00 2001 From: Gerard Basler Date: Wed, 16 Jan 2013 09:36:01 +0100 Subject: [PATCH 07/36] Bugfix: align multi line case guards correctly in pattern matches. --- .../formatter/CaseClauseFormatter.scala | 20 +++++++++++++++++- .../formatter/CaseClausesFormatterTest.scala | 21 +++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) mode change 100644 => 100755 scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala mode change 100644 => 100755 scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala diff --git a/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala b/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala old mode 100644 new mode 100755 index ecc2a441..df7ee244 --- a/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala +++ b/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala @@ -91,7 +91,10 @@ trait CaseClauseFormatter { self: HasFormattingPreferences with ExprFormatter wi Right(caseClause) :: otherClausesGrouped else { val arrowAdjust = (if (formattingPreferences(RewriteArrowSymbols)) 1 else casePattern.arrow.length) + 1 - val casePatternLength = formattedCasePattern.length - arrowAdjust + val casePatternLengthConsideringNewLines = { + formattedCasePattern.split('\n').map(_.length).max + } + val casePatternLength = casePatternLengthConsideringNewLines - arrowAdjust otherClausesGrouped match { case Left(consecutiveSingleLineCaseClauses) :: otherGroups ⇒ Left(consecutiveSingleLineCaseClauses.prepend(caseClause, casePatternLength)) :: otherGroups @@ -134,6 +137,21 @@ trait CaseClauseFormatter { self: HasFormattingPreferences with ExprFormatter wi val CasePattern(caseToken: Token, pattern: Expr, guardOption: Option[Guard], arrow: Token) = casePattern var formatResult: FormatResult = NoFormatResult formatResult ++= format(pattern) + + val beginTokensAfterPipe = List(casePattern.pattern.tokens.head) ++ casePattern.pattern.tokens.zip(casePattern.pattern.tokens.tail).collect { + case (Token(PIPE, _, _, _), b) if b.associatedWhitespaceAndComments.containsNewline => b + } + + val alignBeginTokens: Map[Token, IntertokenFormatInstruction] = beginTokensAfterPipe.zip(beginTokensAfterPipe.tail).flatMap { + case (a, b) => if (b.associatedWhitespaceAndComments.containsNewline) { + Map(b -> EnsureNewlineAndIndent(0, Some(a))) + } else { + Map.empty[Token, IntertokenFormatInstruction] + } + }.toMap + + formatResult ++= FormatResult(alignBeginTokens, Map(), Map()) + for (guard ← guardOption) formatResult ++= format(guard) arrowInstructionOpt foreach { instruction ⇒ formatResult = formatResult.before(arrow, instruction) } diff --git a/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala b/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala old mode 100644 new mode 100755 index 0a7966d4..daff0ecc --- a/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala +++ b/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala @@ -415,4 +415,25 @@ class CaseClausesFormatterTest extends AbstractExpressionFormatterTest { | println("separately") |}""" } + + { + implicit val formattingPreferences = FormattingPreferences.setPreference(AlignSingleLineCaseStatements, true) + .setPreference(AlignSingleLineCaseStatements.MaxArrowIndent, 200) + .setPreference(AlignSingleLineCaseStatements.AlignMultiLineCaseStatements, true) + .setPreference(AlignSingleLineCaseStatements.GroupByNewLine, true) + + """x match { + |case 1 | 2 | + |3 | 4 | + |5 | 6 => 1 + |case 7 | 8 => 1 + |}""" ==> + """x match { + | case 1 | 2 | + | 3 | 4 | + | 5 | 6 => 1 + | case 7 | 8 => 1 + |}""" + } + } From a59db57c134c595b53e6d5fe0f575000130fc249 Mon Sep 17 00:00:00 2001 From: Gerard Basler Date: Wed, 16 Jan 2013 18:06:04 +0100 Subject: [PATCH 08/36] Bugfix: non-multi line cases were missing spaces before `=>`. --- .../scala/scalariform/formatter/CaseClauseFormatter.scala | 4 ++-- .../scalariform/formatter/CaseClausesFormatterTest.scala | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala b/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala index df7ee244..d216adf5 100755 --- a/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala +++ b/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala @@ -86,8 +86,8 @@ trait CaseClauseFormatter { self: HasFormattingPreferences with ExprFormatter wi val clauseBodyIsMultiline = containsNewline(pruneTrailingNewline(statSeq)) || statSeq.firstTokenOption.exists(hiddenPredecessors(_).containsNewline) - if (!formattingPreferences(AlignSingleLineCaseStatements.AlignMultiLineCaseStatements) && - (formattedCasePattern.contains('\n') || (first && !clausesAreMultiline) || (!first && !newlineBeforeClause) || clauseBodyIsMultiline)) + if (formattedCasePattern.contains('\n') || (first && !clausesAreMultiline) || (!first && !newlineBeforeClause) || + !formattingPreferences(AlignSingleLineCaseStatements.AlignMultiLineCaseStatements) && clauseBodyIsMultiline) Right(caseClause) :: otherClausesGrouped else { val arrowAdjust = (if (formattingPreferences(RewriteArrowSymbols)) 1 else casePattern.arrow.length) + 1 diff --git a/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala b/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala index daff0ecc..dad2aec7 100755 --- a/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala +++ b/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala @@ -436,4 +436,11 @@ class CaseClausesFormatterTest extends AbstractExpressionFormatterTest { |}""" } + { + implicit val formattingPreferences = FormattingPreferences.setPreference(AlignSingleLineCaseStatements, true) + .setPreference(AlignSingleLineCaseStatements.AlignMultiLineCaseStatements, true) + + """x match { case _: X => Y }""" ==> + """x match { case _: X => Y }""" + } } From a71331185b58d042501ac41cda9f64b7063dbbaf Mon Sep 17 00:00:00 2001 From: Gerard Basler Date: Sun, 20 Jan 2013 17:41:50 +0100 Subject: [PATCH 09/36] Fix multi line formatting. --- .../formatter/CaseClauseFormatter.scala | 2 +- .../formatter/CaseClausesFormatterTest.scala | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) mode change 100755 => 100644 scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala diff --git a/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala b/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala index d216adf5..ef0004c6 100755 --- a/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala +++ b/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala @@ -86,7 +86,7 @@ trait CaseClauseFormatter { self: HasFormattingPreferences with ExprFormatter wi val clauseBodyIsMultiline = containsNewline(pruneTrailingNewline(statSeq)) || statSeq.firstTokenOption.exists(hiddenPredecessors(_).containsNewline) - if (formattedCasePattern.contains('\n') || (first && !clausesAreMultiline) || (!first && !newlineBeforeClause) || + if (first && !clausesAreMultiline || !first && !newlineBeforeClause || !formattingPreferences(AlignSingleLineCaseStatements.AlignMultiLineCaseStatements) && clauseBodyIsMultiline) Right(caseClause) :: otherClausesGrouped else { diff --git a/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala b/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala old mode 100755 new mode 100644 index dad2aec7..1001a9fa --- a/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala +++ b/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala @@ -443,4 +443,26 @@ class CaseClausesFormatterTest extends AbstractExpressionFormatterTest { """x match { case _: X => Y }""" ==> """x match { case _: X => Y }""" } + + { + implicit val formattingPreferences = FormattingPreferences.setPreference(AlignSingleLineCaseStatements, true) + .setPreference(AlignSingleLineCaseStatements.AlignMultiLineCaseStatements, true) + .setPreference(AlignSingleLineCaseStatements.MaxArrowIndent, 200) + .setPreference(AlignSingleLineCaseStatements.GroupByNewLine, true) + + """|x match { + | case 1 => A + | case 1234 | + | 5678 => A + | case 5 => A + | case 12345678 => A + |}""" ==> + """|x match { + | case 1 => A + | case 1234 | + | 5678 => A + | case 5 => A + | case 12345678 => A + |}""" + } } From c962c531ff99a06c03f52aff58f4fe87b4dc17cb Mon Sep 17 00:00:00 2001 From: Gerard Basler Date: Tue, 22 Jan 2013 08:25:18 +0100 Subject: [PATCH 10/36] Fix newline detection for case clauses. --- .../formatter/CaseClauseFormatter.scala | 10 +++++-- .../formatter/CaseClausesFormatterTest.scala | 29 +++++++++++++++++++ 2 files changed, 36 insertions(+), 3 deletions(-) mode change 100644 => 100755 scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala diff --git a/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala b/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala index ef0004c6..ece81fc1 100755 --- a/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala +++ b/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala @@ -187,10 +187,14 @@ trait CaseClauseFormatter { self: HasFormattingPreferences with ExprFormatter wi if separator.isNewline } yield separator - private def previousCaseClauseTrailingNewlineOpt(caseClause: CaseClause, caseClauses: CaseClauses): Option[Token] = - Utils.pairWithPrevious(caseClauses.caseClauses).collect { + private def previousCaseClauseTrailingNewlineOpt(caseClause: CaseClause, caseClauses: CaseClauses): Option[Token] = { + val previousCaseClauseOpt = Utils.pairWithPrevious(caseClauses.caseClauses).collect { case (Some(previousClause), `caseClause`) ⇒ previousClause - }.headOption.flatMap(getTrailingNewline) + }.headOption + val hasNewLine = previousCaseClauseOpt.flatMap(getTrailingNewline) + val hasNewLineAtEnd = previousCaseClauseOpt.flatMap(_.statSeq.tokens.lastOption.filter(_.isNewline)) + hasNewLine.orElse(hasNewLineAtEnd) + } private def previousCaseClauseEndsWithNewline(caseClause: CaseClause, caseClauses: CaseClauses): Boolean = previousCaseClauseTrailingNewlineOpt(caseClause, caseClauses).isDefined diff --git a/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala b/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala old mode 100644 new mode 100755 index 1001a9fa..1eaeb60f --- a/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala +++ b/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala @@ -465,4 +465,33 @@ class CaseClausesFormatterTest extends AbstractExpressionFormatterTest { | case 12345678 => A |}""" } + + { + implicit val formattingPreferences = FormattingPreferences.setPreference(AlignSingleLineCaseStatements, true) + .setPreference(AlignSingleLineCaseStatements.AlignMultiLineCaseStatements, true) + .setPreference(AlignSingleLineCaseStatements.MaxArrowIndent, 200) + + """|x match { + |case AA => a + |case B => b + |}""" ==> + """|x match { + | case AA => a + | case B => b + |}""" + } + + { + implicit val formattingPreferences = FormattingPreferences.setPreference(AlignSingleLineCaseStatements, true) + .setPreference(AlignSingleLineCaseStatements.AlignMultiLineCaseStatements, true) + + """|x match { + |case AA => (s: Int) => 1 + |case B => (s: Int) => 2 + |}""" ==> + """|x match { + | case AA => (s: Int) => 1 + | case B => (s: Int) => 2 + |}""" + } } From abf4f150abe5d8298e675769654caaab294688cc Mon Sep 17 00:00:00 2001 From: Gerard Basler Date: Wed, 30 Jan 2013 21:37:01 +0100 Subject: [PATCH 11/36] Bugfix: format new scopes after `=>` in lambda function correctly. --- .../scala/scalariform/formatter/ExprFormatter.scala | 11 +++++++++-- .../formatter/MiscExpressionFormatterTest.scala | 11 +++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala b/scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala index 7c950a77..403c92b6 100755 --- a/scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala +++ b/scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala @@ -636,15 +636,22 @@ trait ExprFormatter { self: HasFormattingPreferences with AnnotationFormatter wi (CompactEnsuringGap, indentedState) formatResult = formatResult.before(statSeq.firstToken, instruction) formatResult ++= format(params) + + val hasNewScopeAfterArrow = { + val arrowIndex = statSeq.tokens.indexWhere(_.tokenType == ARROW) + val tokenAfterArrow = statSeq.tokens.lift(arrowIndex + 1) + tokenAfterArrow.map(_.tokenType == lbrace.tokenType).getOrElse(false) + } for (firstToken ← subStatSeq.firstTokenOption) { val instruction = - if (hiddenPredecessors(firstToken).containsNewline || containsNewline(subStatSeq)) + if (hiddenPredecessors(firstToken).containsNewline || containsNewline(subStatSeq) && !hasNewScopeAfterArrow) statFormatterState(subStatSeq.firstStatOpt)(subStatState).currentIndentLevelInstruction else CompactEnsuringGap formatResult = formatResult.before(firstToken, instruction) } - formatResult ++= format(subStatSeq)(subStatState) + val subStatStateAfterArrow = if(hasNewScopeAfterArrow) newFormatterState.indent else subStatState + formatResult ++= format(subStatSeq)(subStatStateAfterArrow) case _ ⇒ val instruction = statSeq.selfReferenceOpt match { case Some((selfReference, arrow)) if !hiddenPredecessors(selfReference.firstToken).containsNewline ⇒ diff --git a/scalariform/src/test/scala/scalariform/formatter/MiscExpressionFormatterTest.scala b/scalariform/src/test/scala/scalariform/formatter/MiscExpressionFormatterTest.scala index 0f319ad6..0be5d901 100644 --- a/scalariform/src/test/scala/scalariform/formatter/MiscExpressionFormatterTest.scala +++ b/scalariform/src/test/scala/scalariform/formatter/MiscExpressionFormatterTest.scala @@ -771,6 +771,17 @@ class MiscExpressionFormatterTest extends AbstractExpressionFormatterTest { | b => c |}""" + """|a map { + |q => { + |2 * q + |} + |}""" ==> + """|a map { + | q => { + | 2 * q + | } + |}""" + "f()[Foo]" ==> "f()[Foo]" "a [ b . C ] [ d . E ] [ f . G ] " ==> "a[b.C][d.E][f.G]" From 3e81616534631d55847323233eff50881fbbdbcf Mon Sep 17 00:00:00 2001 From: Gerard Basler Date: Mon, 4 Feb 2013 09:04:40 +0100 Subject: [PATCH 12/36] Fix formatting for new scope after arrow. --- .../scala/scalariform/formatter/ExprFormatter.scala | 2 +- .../formatter/MiscExpressionFormatterTest.scala | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) mode change 100644 => 100755 scalariform/src/test/scala/scalariform/formatter/MiscExpressionFormatterTest.scala diff --git a/scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala b/scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala index 403c92b6..da4e7bfd 100755 --- a/scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala +++ b/scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala @@ -644,7 +644,7 @@ trait ExprFormatter { self: HasFormattingPreferences with AnnotationFormatter wi } for (firstToken ← subStatSeq.firstTokenOption) { val instruction = - if (hiddenPredecessors(firstToken).containsNewline || containsNewline(subStatSeq) && !hasNewScopeAfterArrow) + if (!hasNewScopeAfterArrow && (hiddenPredecessors(firstToken).containsNewline || containsNewline(subStatSeq))) statFormatterState(subStatSeq.firstStatOpt)(subStatState).currentIndentLevelInstruction else CompactEnsuringGap diff --git a/scalariform/src/test/scala/scalariform/formatter/MiscExpressionFormatterTest.scala b/scalariform/src/test/scala/scalariform/formatter/MiscExpressionFormatterTest.scala old mode 100644 new mode 100755 index 0be5d901..4601cd9a --- a/scalariform/src/test/scala/scalariform/formatter/MiscExpressionFormatterTest.scala +++ b/scalariform/src/test/scala/scalariform/formatter/MiscExpressionFormatterTest.scala @@ -782,6 +782,18 @@ class MiscExpressionFormatterTest extends AbstractExpressionFormatterTest { | } |}""" + """|a map { + |q => + |{ + |2 * q + |} + |}""" ==> + """|a map { + | q => { + | 2 * q + | } + |}""" + "f()[Foo]" ==> "f()[Foo]" "a [ b . C ] [ d . E ] [ f . G ] " ==> "a[b.C][d.E][f.G]" From 2bdc31900f335bc98adb35c774df20deb8ff4a7f Mon Sep 17 00:00:00 2001 From: Gerard Basler Date: Mon, 4 Feb 2013 09:38:06 +0100 Subject: [PATCH 13/36] Don't use snapshot version of eclipse plugin, disable signing. --- project/plugins.sbt | 4 ++-- project/project/plugins.sbt | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) mode change 100644 => 100755 project/plugins.sbt mode change 100644 => 100755 project/project/plugins.sbt diff --git a/project/plugins.sbt b/project/plugins.sbt old mode 100644 new mode 100755 index 25bb8511..2bdafff3 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -4,13 +4,13 @@ addSbtPlugin("com.github.retronym" % "sbt-onejar" % "0.8") resolvers += Classpaths.typesafeSnapshots -addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0-SNAPSHOT") +addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0") addSbtPlugin("com.typesafe.sbtscalariform" % "sbtscalariform" % "0.5.1") // resolvers += Resolver.url("sbt-plugin-releases", new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases/"))(Resolver.ivyStylePatterns) -addSbtPlugin("com.jsuereth" % "xsbt-gpg-plugin" % "0.6") +// addSbtPlugin("com.jsuereth" % "xsbt-gpg-plugin" % "0.6") addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.2.0") diff --git a/project/project/plugins.sbt b/project/project/plugins.sbt old mode 100644 new mode 100755 index 1baaef62..267807a5 --- a/project/project/plugins.sbt +++ b/project/project/plugins.sbt @@ -1,4 +1,4 @@ resolvers += Classpaths.typesafeSnapshots -addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0-SNAPSHOT") +addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0") From 9f721698cce5c3fecf6858ae7c7f6718f1c9f37d Mon Sep 17 00:00:00 2001 From: Gerard Basler Date: Fri, 15 Feb 2013 10:30:09 +0100 Subject: [PATCH 14/36] New option to reformat chained packages. --- README.rst | 16 +++++++++ .../scalariform/formatter/ExprFormatter.scala | 35 +++++++++++++++++-- .../formatter/ScalaFormatter.scala | 7 +++- .../preferences/PreferenceDescriptor.scala | 15 +++++++- .../formatter/PackageFormatterTest.scala | 23 ++++++++++++ 5 files changed, 91 insertions(+), 5 deletions(-) mode change 100644 => 100755 README.rst mode change 100644 => 100755 scalariform/src/main/scala/scalariform/formatter/ScalaFormatter.scala mode change 100644 => 100755 scalariform/src/test/scala/scalariform/formatter/PackageFormatterTest.scala diff --git a/README.rst b/README.rst old mode 100644 new mode 100755 index 63869b6e..e329e450 --- a/README.rst +++ b/README.rst @@ -499,6 +499,22 @@ If ``false``,:: case elem@Multi(values@_*) => +chainedPackageClauses +~~~~~~~~~~~~~~~~~~~~~ + +Default: ``false`` + +Example:: +``` + package com.company.analytics.math.curves.interpolators +``` + +Will be reformatted to:: +``` + package com.company.analytics.math + package curves + package interpolators +``` Scala Style Guide ~~~~~~~~~~~~~~~~~ diff --git a/scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala b/scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala index da4e7bfd..af8e3ebf 100755 --- a/scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala +++ b/scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala @@ -690,7 +690,7 @@ trait ExprFormatter { self: HasFormattingPreferences with AnnotationFormatter wi } for (stat ← firstStatOpt) - formatResult ++= format(stat)(firstStatFormatterState) + formatResult ++= format(stat, true)(firstStatFormatterState) for ((semi, otherStatOption) ← otherStats) { @@ -709,7 +709,7 @@ trait ExprFormatter { self: HasFormattingPreferences with AnnotationFormatter wi CompactEnsuringGap formatResult = formatResult.before(firstToken, instruction) } - formatResult ++= format(otherStat)(otherStatFormatterState) + formatResult ++= format(otherStat, false)(otherStatFormatterState) } } @@ -717,15 +717,44 @@ trait ExprFormatter { self: HasFormattingPreferences with AnnotationFormatter wi formatResult } - private def format(stat: Stat)(implicit formatterState: FormatterState): FormatResult = + private def format(stat: Stat, firstStat: Boolean)(implicit formatterState: FormatterState): FormatResult = stat match { case expr: Expr ⇒ format(expr) case fullDefOrDcl: FullDefOrDcl ⇒ format(fullDefOrDcl) case import_ : ImportClause ⇒ format(import_) case packageBlock: PackageBlock ⇒ format(packageBlock) + case packageStat: PackageStat ⇒ format(packageStat, firstStat) case _ ⇒ NoFormatResult // TODO } + def format(packageStat: PackageStat, firstPackage: Boolean)(implicit formatterState: FormatterState): FormatResult = { + val PackageStat(packageToken: Token, name: CallExpr) = packageStat + + val packageDepth = if(firstPackage) formattingPreferences(ChainedPackageClauses.PackageDepth) else 1 + + def dotsForPackageNames(name: CallExpr): List[Token] = { + name.exprDotOpt match { + case Some((List(c@CallExpr(_, id, _, _, _)), dot)) => + dot :: dotsForPackageNames(c) + case _ => + Nil + } + } + + val dotsBetweenPackageNames = dotsForPackageNames(name) + + val lineBreaksAfter = dotsBetweenPackageNames.reverse.drop(packageDepth-1) + + var formatResult: FormatResult = NoFormatResult + for { + token <- lineBreaksAfter + } { + formatResult ++= FormatResult(Map(token -> EnsureNewlineAndIndent(0, Some(packageToken))), Map(), Map()) + } + + formatResult + } + def format(packageBlock: PackageBlock)(implicit formatterState: FormatterState): FormatResult = { val PackageBlock(packageToken: Token, name: CallExpr, newlineOpt: Option[Token], lbrace: Token, topStats: StatSeq, rbrace: Token) = packageBlock diff --git a/scalariform/src/main/scala/scalariform/formatter/ScalaFormatter.scala b/scalariform/src/main/scala/scalariform/formatter/ScalaFormatter.scala old mode 100644 new mode 100755 index 3bba7e08..508ad6c1 --- a/scalariform/src/main/scala/scalariform/formatter/ScalaFormatter.scala +++ b/scalariform/src/main/scala/scalariform/formatter/ScalaFormatter.scala @@ -221,7 +221,12 @@ abstract class ScalaFormatter extends HasFormattingPreferences with TypeFormatte val replacement = builder.substring(startPos) positionHintOption match { case Some(positionHint) if hiddenTokens.isEmpty ⇒ - Some(TextEdit(positionHint, length = 0, replacement = replacement)) + instruction match { + case EnsureNewlineAndIndent(indentLevel, Some(Token(PACKAGE, _, _, _))) => + Some(TextEdit(positionHint, length = 1, replacement = replacement + "package ")) + case _ => + Some(TextEdit(positionHint, length = 0, replacement = replacement)) + } case _ ⇒ for { firstToken ← hiddenTokens.firstTokenOption diff --git a/scalariform/src/main/scala/scalariform/formatter/preferences/PreferenceDescriptor.scala b/scalariform/src/main/scala/scalariform/formatter/preferences/PreferenceDescriptor.scala index cc2cd1aa..ed73714d 100755 --- a/scalariform/src/main/scala/scalariform/formatter/preferences/PreferenceDescriptor.scala +++ b/scalariform/src/main/scala/scalariform/formatter/preferences/PreferenceDescriptor.scala @@ -64,7 +64,7 @@ object AllPreferences { PreserveSpaceBeforeArguments, AlignParameters, DoubleIndentClassDeclaration, FormatXml, IndentPackageBlocks, AlignSingleLineCaseStatements, AlignSingleLineCaseStatements.MaxArrowIndent, AlignSingleLineCaseStatements.AlignMultiLineCaseStatements, IndentLocalDefs, PreserveDanglingCloseParenthesis, SpaceInsideParentheses, SpaceInsideBrackets, SpacesWithinPatternBinders, MultilineScaladocCommentsStartOnFirstLine, IndentWithTabs, - CompactControlReadability, PlaceScaladocAsterisksBeneathSecondAsterisk, NoSpacesAroundMultiImports) + CompactControlReadability, PlaceScaladocAsterisksBeneathSecondAsterisk, NoSpacesAroundMultiImports, ChainedPackageClauses, ChainedPackageClauses.PackageDepth) val preferencesByKey: Map[String, PreferenceDescriptor[_]] = { var map: Map[String, PreferenceDescriptor[_]] = Map() @@ -215,3 +215,16 @@ case object NoSpacesAroundMultiImports extends BooleanPreferenceDescriptor { val description = "Don't place spaces around multi imports (Java-style)" val defaultValue = false } + +case object ChainedPackageClauses extends BooleanPreferenceDescriptor { + val key = "chainedPackageClauses" + val description = "Break up chained package clauses" + val defaultValue = false + + case object PackageDepth extends IntegerPreferenceDescriptor { + val key = "chainedPackageClauses.packageDepth" + val description = "Depth of package nesting" + val preferenceType = IntegerPreference(1, 100) + val defaultValue = 4 + } +} diff --git a/scalariform/src/test/scala/scalariform/formatter/PackageFormatterTest.scala b/scalariform/src/test/scala/scalariform/formatter/PackageFormatterTest.scala old mode 100644 new mode 100755 index 4634e8d5..0ef4a5c3 --- a/scalariform/src/test/scala/scalariform/formatter/PackageFormatterTest.scala +++ b/scalariform/src/test/scala/scalariform/formatter/PackageFormatterTest.scala @@ -63,5 +63,28 @@ class PackageFormatterTest extends AbstractFormatterTest { } + """package a.b.c.d.e.f + |""" ==> + """package a.b.c.d + |package e + |package f + |""" + + """package com.company.analytics.math.curves.interpolators + |""" ==> + """package com.company.analytics.math + |package curves + |package interpolators + |""" + + """package a.b.c.d.e.f + |package g.h + |""" ==> + """package a.b.c.d + |package e + |package f + |package g + |package h + |""" } From c6c45c6e89d31588172ccc28fc2c52b0f182ca03 Mon Sep 17 00:00:00 2001 From: Gerard Basler Date: Fri, 15 Feb 2013 11:06:08 +0100 Subject: [PATCH 15/36] Fix missing chained package format option. --- .../scalariform/formatter/ExprFormatter.scala | 35 ++++++++++--------- .../formatter/PackageFormatterTest.scala | 6 +++- 2 files changed, 24 insertions(+), 17 deletions(-) diff --git a/scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala b/scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala index af8e3ebf..ef59659c 100755 --- a/scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala +++ b/scalariform/src/main/scala/scalariform/formatter/ExprFormatter.scala @@ -728,28 +728,31 @@ trait ExprFormatter { self: HasFormattingPreferences with AnnotationFormatter wi } def format(packageStat: PackageStat, firstPackage: Boolean)(implicit formatterState: FormatterState): FormatResult = { - val PackageStat(packageToken: Token, name: CallExpr) = packageStat + var formatResult: FormatResult = NoFormatResult + + if (formattingPreferences(ChainedPackageClauses)) { + val PackageStat(packageToken: Token, name: CallExpr) = packageStat - val packageDepth = if(firstPackage) formattingPreferences(ChainedPackageClauses.PackageDepth) else 1 + val packageDepth = if(firstPackage) formattingPreferences(ChainedPackageClauses.PackageDepth) else 1 - def dotsForPackageNames(name: CallExpr): List[Token] = { - name.exprDotOpt match { - case Some((List(c@CallExpr(_, id, _, _, _)), dot)) => - dot :: dotsForPackageNames(c) - case _ => - Nil + def dotsForPackageNames(name: CallExpr): List[Token] = { + name.exprDotOpt match { + case Some((List(c@CallExpr(_, id, _, _, _)), dot)) => + dot :: dotsForPackageNames(c) + case _ => + Nil + } } - } - val dotsBetweenPackageNames = dotsForPackageNames(name) + val dotsBetweenPackageNames = dotsForPackageNames(name) - val lineBreaksAfter = dotsBetweenPackageNames.reverse.drop(packageDepth-1) + val lineBreaksAfter = dotsBetweenPackageNames.reverse.drop(packageDepth-1) - var formatResult: FormatResult = NoFormatResult - for { - token <- lineBreaksAfter - } { - formatResult ++= FormatResult(Map(token -> EnsureNewlineAndIndent(0, Some(packageToken))), Map(), Map()) + for { + token <- lineBreaksAfter + } { + formatResult ++= FormatResult(Map(token -> EnsureNewlineAndIndent(0, Some(packageToken))), Map(), Map()) + } } formatResult diff --git a/scalariform/src/test/scala/scalariform/formatter/PackageFormatterTest.scala b/scalariform/src/test/scala/scalariform/formatter/PackageFormatterTest.scala index 0ef4a5c3..6301657d 100755 --- a/scalariform/src/test/scala/scalariform/formatter/PackageFormatterTest.scala +++ b/scalariform/src/test/scala/scalariform/formatter/PackageFormatterTest.scala @@ -63,6 +63,10 @@ class PackageFormatterTest extends AbstractFormatterTest { } + { + + implicit val formattingPreferences = FormattingPreferences.setPreference(ChainedPackageClauses, true) + """package a.b.c.d.e.f |""" ==> """package a.b.c.d @@ -86,5 +90,5 @@ class PackageFormatterTest extends AbstractFormatterTest { |package g |package h |""" - + } } From 8bd6c1752ac190842236c495d3305921eaa6853b Mon Sep 17 00:00:00 2001 From: Gerard Basler Date: Thu, 21 Feb 2013 23:39:24 +0100 Subject: [PATCH 16/36] Fix multi line case clauses formatting. --- .../formatter/CaseClauseFormatter.scala | 4 +-- .../formatter/CaseClausesFormatterTest.scala | 26 +++++++++++++++++++ 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala b/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala index ece81fc1..fedb2ba8 100755 --- a/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala +++ b/scalariform/src/main/scala/scalariform/formatter/CaseClauseFormatter.scala @@ -91,9 +91,7 @@ trait CaseClauseFormatter { self: HasFormattingPreferences with ExprFormatter wi Right(caseClause) :: otherClausesGrouped else { val arrowAdjust = (if (formattingPreferences(RewriteArrowSymbols)) 1 else casePattern.arrow.length) + 1 - val casePatternLengthConsideringNewLines = { - formattedCasePattern.split('\n').map(_.length).max - } + val casePatternLengthConsideringNewLines = formattedCasePattern.split('\n').last.length val casePatternLength = casePatternLengthConsideringNewLines - arrowAdjust otherClausesGrouped match { case Left(consecutiveSingleLineCaseClauses) :: otherGroups ⇒ diff --git a/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala b/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala index 1eaeb60f..06b20136 100755 --- a/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala +++ b/scalariform/src/test/scala/scalariform/formatter/CaseClausesFormatterTest.scala @@ -494,4 +494,30 @@ class CaseClausesFormatterTest extends AbstractExpressionFormatterTest { | case B => (s: Int) => 2 |}""" } + + { + implicit val formattingPreferences = FormattingPreferences.setPreference(AlignSingleLineCaseStatements, true) + .setPreference(AlignSingleLineCaseStatements.AlignMultiLineCaseStatements, true) + .setPreference(AlignSingleLineCaseStatements.MaxArrowIndent, 160) + .setPreference(AlignSingleLineCaseStatements.GroupByNewLine, true) + .setPreference(SpacesWithinPatternBinders, false) + + """|pairs.flatMap { + | case (p1@(t1, MandatoryGridPoint(true) | ExtremalGridPoint), + | (t2, MandatoryGridPoint(true) | ExtremalGridPoint)) => + | val fillPointTime = (t1 + t2) / 2 + | val fillPoint = (fillPointTime, FillingGridPoint) + | Seq(p1, fillPoint) + | case (p1, p2) => Seq(p1) + |}""" ==> + """|pairs.flatMap { + | case (p1@(t1, MandatoryGridPoint(true) | ExtremalGridPoint), + | (t2, MandatoryGridPoint(true) | ExtremalGridPoint)) => + | val fillPointTime = (t1 + t2) / 2 + | val fillPoint = (fillPointTime, FillingGridPoint) + | Seq(p1, fillPoint) + | case (p1, p2) => Seq(p1) + |}""" + } + } From cc917fb388a9db9fdedce2f9b1e468468bce6dec Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Wed, 24 Apr 2013 13:29:01 +0100 Subject: [PATCH 17/36] Updates for Scala 2.10.0 --- cli/.classpath | 21 +++++---- misc/.classpath | 25 +++++------ .../scalariform/gui/FormatterFrame.scala | 15 ++++--- project/Build.scala | 12 ++--- project/build.properties | 2 +- project/plugins.sbt | 6 +-- project/project/plugins.sbt | 3 +- scalariform/.classpath | 25 ++++++----- scalariform/.project | 45 +++++-------------- 9 files changed, 65 insertions(+), 89 deletions(-) diff --git a/cli/.classpath b/cli/.classpath index 9b3704ea..e92a111b 100644 --- a/cli/.classpath +++ b/cli/.classpath @@ -1,12 +1,11 @@ - - - - - - - - - - - + + + + + + + + + + \ No newline at end of file diff --git a/misc/.classpath b/misc/.classpath index 3f447726..c89ac363 100644 --- a/misc/.classpath +++ b/misc/.classpath @@ -1,14 +1,13 @@ - - - - - - - - - - - - - + + + + + + + + + + + + \ No newline at end of file diff --git a/misc/src/main/scala/scalariform/gui/FormatterFrame.scala b/misc/src/main/scala/scalariform/gui/FormatterFrame.scala index edafd1be..78c42c91 100644 --- a/misc/src/main/scala/scalariform/gui/FormatterFrame.scala +++ b/misc/src/main/scala/scalariform/gui/FormatterFrame.scala @@ -195,8 +195,8 @@ class FormatterFrame extends JFrame with SpecificFormatter { tokensTable.setModel(tableModel) } } catch { - case e ⇒ - outputTextPane.setText(e.toString + "\n" + e.getStackTrace.mkString("\n")) + case t: Throwable ⇒ + outputTextPane.setText(t.toString + "\n" + t.getStackTrace.mkString("\n")) outputTextPane.setCaretPosition(0) } @@ -350,13 +350,14 @@ class FormatterFrame extends JFrame with SpecificFormatter { } def specificFormatter: SpecificFormatter = - productionComboBox.getSelectedItem.asInstanceOf[ProductionComboBoxModel.ProductionItem].formatter + productionComboBox.getSelectedItem.asInstanceOf[ProductionItem].formatter - object ProductionComboBoxModel extends DefaultComboBoxModel { + class ProductionItem(name: String, val formatter: SpecificFormatter) { + override def toString = name + } + + object ProductionComboBoxModel extends DefaultComboBoxModel[ProductionItem] { - class ProductionItem(name: String, val formatter: SpecificFormatter) { - override def toString = name - } val compilationUnitFormatter = new SpecificFormatter { diff --git a/project/Build.scala b/project/Build.scala index 8a13ddc9..53960374 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -3,19 +3,19 @@ import sbt.Keys._ import com.github.retronym.SbtOneJar import com.typesafe.sbteclipse.core.EclipsePlugin.EclipseKeys._ import com.typesafe.sbteclipse.core.EclipsePlugin._ -import com.typesafe.sbtscalariform.ScalariformPlugin -import com.typesafe.sbtscalariform.ScalariformPlugin.ScalariformKeys +import com.typesafe.sbt.SbtScalariform +import com.typesafe.sbt.SbtScalariform.ScalariformKeys import scalariform.formatter.preferences._ object ScalariformBuild extends Build { - lazy val commonSettings = Defaults.defaultSettings ++ ScalariformPlugin.defaultScalariformSettings ++ Seq( + lazy val commonSettings = Defaults.defaultSettings ++ SbtScalariform.defaultScalariformSettings ++ Seq( organization := "org.scalariform", version := "0.1.4-SNAPSHOT", - scalaVersion := "2.9.2", + scalaVersion := "2.10.0", crossScalaVersions := Seq( - "2.10.0-M7", + "2.10.0", "2.9.2", "2.9.1-1", "2.9.1", "2.9.0-1", "2.9.0", "2.8.2", "2.8.1", "2.8.0" ), @@ -37,7 +37,7 @@ object ScalariformBuild extends Build { def getScalaTestDependency(scalaVersion: String) = scalaVersion match { case "2.8.0" ⇒ "org.scalatest" %% "scalatest" % "1.3.1.RC2" % "test" - case "2.10.0-M7" ⇒ "org.scalatest" % "scalatest_2.10.0-M7" % "1.9-2.10.0-M7-B1" % "test" + case "2.10.0" =>"org.scalatest" % "scalatest_2.10" % "1.9.1" % "test" case _ ⇒ "org.scalatest" %% "scalatest" % "1.7.2" % "test" } diff --git a/project/build.properties b/project/build.properties index 4474a03e..9b860e23 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=0.12.1 +sbt.version=0.12.3 diff --git a/project/plugins.sbt b/project/plugins.sbt index 2bdafff3..2ff7631e 100755 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -4,15 +4,15 @@ addSbtPlugin("com.github.retronym" % "sbt-onejar" % "0.8") resolvers += Classpaths.typesafeSnapshots -addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0") +addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.2") -addSbtPlugin("com.typesafe.sbtscalariform" % "sbtscalariform" % "0.5.1") +addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.0.1") // resolvers += Resolver.url("sbt-plugin-releases", new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases/"))(Resolver.ivyStylePatterns) // addSbtPlugin("com.jsuereth" % "xsbt-gpg-plugin" % "0.6") -addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.2.0") +addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.2.2") retrieveManaged := true diff --git a/project/project/plugins.sbt b/project/project/plugins.sbt index 267807a5..d0201e8a 100755 --- a/project/project/plugins.sbt +++ b/project/project/plugins.sbt @@ -1,4 +1,3 @@ resolvers += Classpaths.typesafeSnapshots -addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.0") - +addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.2") diff --git a/scalariform/.classpath b/scalariform/.classpath index 41ff9ff0..93d8e858 100644 --- a/scalariform/.classpath +++ b/scalariform/.classpath @@ -1,13 +1,14 @@ - - - - - - - - - - - - + + + + + + + + + + + + + \ No newline at end of file diff --git a/scalariform/.project b/scalariform/.project index 369bc479..f848d8a7 100644 --- a/scalariform/.project +++ b/scalariform/.project @@ -1,35 +1,12 @@ - - scalariform - scalariform 0.1 - - - - - org.eclipse.pde.ManifestBuilder - - - - - org.eclipse.pde.SchemaBuilder - - - - - org.scala-ide.sdt.core.scalabuilder - - - - - org.scalastyle.scalastyleplugin.core.ScalastyleBuilder - - - - - - org.scala-ide.sdt.core.scalanature - org.eclipse.jdt.core.javanature - org.eclipse.pde.PluginNature - org.scalastyle.scalastyleplugin.core.ScalastyleNature - - + scalariform + + + org.scala-ide.sdt.core.scalabuilder + + + + org.scala-ide.sdt.core.scalanature + org.eclipse.jdt.core.javanature + + \ No newline at end of file From 166d35d2ada9d807211780472c7379c4015412a5 Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Wed, 24 Apr 2013 13:33:54 +0100 Subject: [PATCH 18/36] Update CHANGELOG --- CHANGELOG | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 3913a1ff..2fcd0a1d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,8 +1,11 @@ +0.1.4 (..) +* FIX: Allow declarations as last statement in case block (issue #60) +* Update to build 2.10 final + 0.1.3 (3/October/12) * Add EOF to ComplilationUnit, ensuring entire source is represented in the tree * Support $this references in String interpolation * Update build to sbt 0.12.1 -* FIX: Allow declarations as last statement in case block (issue #60). 0.1.2 (7/May/12) From 0810e748f6837ae6b4f64295d100a9453c5d9c6d Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Wed, 24 Apr 2013 13:49:45 +0100 Subject: [PATCH 19/36] Preparing for 0.1.4 release --- CHANGELOG | 2 +- README.rst | 2 +- project/plugins.sbt | 4 ++-- scalariform/notes/0.1.4.markdown | 3 +++ 4 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 scalariform/notes/0.1.4.markdown diff --git a/CHANGELOG b/CHANGELOG index 2fcd0a1d..3c3e6589 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,4 +1,4 @@ -0.1.4 (..) +0.1.4 (24/April/13) * FIX: Allow declarations as last statement in case block (issue #60) * Update to build 2.10 final diff --git a/README.rst b/README.rst index e329e450..31604173 100755 --- a/README.rst +++ b/README.rst @@ -84,7 +84,7 @@ Usage:: org.scalariform scalariform-maven-plugin - 0.1.3 + 0.1.4 process-sources diff --git a/project/plugins.sbt b/project/plugins.sbt index 2ff7631e..a81cb0a0 100755 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -8,9 +8,9 @@ addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.2") addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.0.1") -// resolvers += Resolver.url("sbt-plugin-releases", new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases/"))(Resolver.ivyStylePatterns) +resolvers += Resolver.url("sbt-plugin-releases", new URL("http://scalasbt.artifactoryonline.com/scalasbt/sbt-plugin-releases/"))(Resolver.ivyStylePatterns) -// addSbtPlugin("com.jsuereth" % "xsbt-gpg-plugin" % "0.6") +addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8") addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.2.2") diff --git a/scalariform/notes/0.1.4.markdown b/scalariform/notes/0.1.4.markdown new file mode 100644 index 00000000..61370721 --- /dev/null +++ b/scalariform/notes/0.1.4.markdown @@ -0,0 +1,3 @@ +* FIX: Allow declarations as last statement in case block (issue #60) +* Update to build 2.10 final + From 373889ebca99b0bfb471e2fe1846850c4b4d4a4c Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Wed, 24 Apr 2013 14:56:38 +0100 Subject: [PATCH 20/36] Version tweaks (cherry picked from commit 974e73fd415902babe29aa23873ec85b2663ca6e) --- project/Build.scala | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 53960374..4f9987a3 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -15,7 +15,8 @@ object ScalariformBuild extends Build { version := "0.1.4-SNAPSHOT", scalaVersion := "2.10.0", crossScalaVersions := Seq( - "2.10.0", +// "2.11.0-M2", + "2.10.0", "2.10.1", "2.9.2", "2.9.1-1", "2.9.1", "2.9.0-1", "2.9.0", "2.8.2", "2.8.1", "2.8.0" ), @@ -37,7 +38,8 @@ object ScalariformBuild extends Build { def getScalaTestDependency(scalaVersion: String) = scalaVersion match { case "2.8.0" ⇒ "org.scalatest" %% "scalatest" % "1.3.1.RC2" % "test" - case "2.10.0" =>"org.scalatest" % "scalatest_2.10" % "1.9.1" % "test" + case "2.10.0" =>"org.scalatest" %% "scalatest" % "1.9.1" % "test" + case "2.10.1" =>"org.scalatest" %% "scalatest" % "1.9.1" % "test" case _ ⇒ "org.scalatest" %% "scalatest" % "1.7.2" % "test" } From 243a2ed1d9ae2c1461501384a3c3eee098061c7e Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Wed, 24 Apr 2013 19:55:37 +0100 Subject: [PATCH 21/36] Tweaks for 0.1.4 (cherry picked from commit 4d06f576092514745a18e0def259b744afa89912) --- project/Build.scala | 3 ++- .../test/scala/scalariform/lexer/NewlineInferencerTest.scala | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/project/Build.scala b/project/Build.scala index 4f9987a3..5709b404 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -17,7 +17,7 @@ object ScalariformBuild extends Build { crossScalaVersions := Seq( // "2.11.0-M2", "2.10.0", "2.10.1", - "2.9.2", "2.9.1-1", "2.9.1", "2.9.0-1", "2.9.0", + "2.9.3", "2.9.2", "2.9.1-1", "2.9.1", "2.9.0-1", "2.9.0", "2.8.2", "2.8.1", "2.8.0" ), exportJars := true, // Needed for cli oneJar @@ -40,6 +40,7 @@ object ScalariformBuild extends Build { case "2.8.0" ⇒ "org.scalatest" %% "scalatest" % "1.3.1.RC2" % "test" case "2.10.0" =>"org.scalatest" %% "scalatest" % "1.9.1" % "test" case "2.10.1" =>"org.scalatest" %% "scalatest" % "1.9.1" % "test" + case "2.9.3" =>"org.scalatest" %% "scalatest" % "1.9.1" % "test" case _ ⇒ "org.scalatest" %% "scalatest" % "1.7.2" % "test" } diff --git a/scalariform/src/test/scala/scalariform/lexer/NewlineInferencerTest.scala b/scalariform/src/test/scala/scalariform/lexer/NewlineInferencerTest.scala index 2ecbd04f..6455dced 100644 --- a/scalariform/src/test/scala/scalariform/lexer/NewlineInferencerTest.scala +++ b/scalariform/src/test/scala/scalariform/lexer/NewlineInferencerTest.scala @@ -14,7 +14,7 @@ import java.io._ class NewlineInferencerTest extends FlatSpec with ShouldMatchers { implicit def string2TestString(s: String)(implicit forgiveErrors: Boolean = false, scalaVersion: ScalaVersion = ScalaVersions.DEFAULT) = - new TestString(s, forgiveErrors, scalaVersion) + new TestString(s, forgiveErrors, scalaVersion); // See issue #60 """ From e0553984f26caac8e91a2204aef6a5beaf0cca42 Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Wed, 24 Apr 2013 19:57:36 +0100 Subject: [PATCH 22/36] Update versions for 0.1.5-SNAPSHOT --- docs/source/conf.py | 4 ++-- pom.xml | 2 +- project/Build.scala | 2 +- scalariform.feature/feature.xml | 2 +- scalariform.feature/pom.xml | 4 ++-- scalariform.update/pom.xml | 4 ++-- scalariform.update/site.xml | 2 +- scalariform/META-INF/MANIFEST.MF | 2 +- scalariform/pom.xml | 4 ++-- 9 files changed, 13 insertions(+), 13 deletions(-) diff --git a/docs/source/conf.py b/docs/source/conf.py index 63da561a..c08bd721 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -45,9 +45,9 @@ # built documents. # # The short X.Y version. -version = '0.1.4-SNAPSHOT' +version = '0.1.5-SNAPSHOT' # The full version, including alpha/beta/rc tags. -release = '0.1.4-SNAPSHOT' +release = '0.1.5-SNAPSHOT' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/pom.xml b/pom.xml index 7bec643d..2f81b073 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 org.scalariform scalariform.parent - 0.1.4-SNAPSHOT + 0.1.5-SNAPSHOT pom diff --git a/project/Build.scala b/project/Build.scala index 5709b404..897d20f4 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -12,7 +12,7 @@ object ScalariformBuild extends Build { lazy val commonSettings = Defaults.defaultSettings ++ SbtScalariform.defaultScalariformSettings ++ Seq( organization := "org.scalariform", - version := "0.1.4-SNAPSHOT", + version := "0.1.5-SNAPSHOT", scalaVersion := "2.10.0", crossScalaVersions := Seq( // "2.11.0-M2", diff --git a/scalariform.feature/feature.xml b/scalariform.feature/feature.xml index d056b45e..d10adaad 100644 --- a/scalariform.feature/feature.xml +++ b/scalariform.feature/feature.xml @@ -2,7 +2,7 @@ + version="0.1.5.qualifier"> Code formatter for Scala 2.8 diff --git a/scalariform.feature/pom.xml b/scalariform.feature/pom.xml index e3f1c6a5..6f78f8d9 100644 --- a/scalariform.feature/pom.xml +++ b/scalariform.feature/pom.xml @@ -5,11 +5,11 @@ 4.0.0 scalariform.feature eclipse-feature - 0.1.4-SNAPSHOT + 0.1.5-SNAPSHOT scalariform.parent org.scalariform - 0.1.4-SNAPSHOT + 0.1.5-SNAPSHOT diff --git a/scalariform.update/pom.xml b/scalariform.update/pom.xml index 190ed28c..8ed0b120 100644 --- a/scalariform.update/pom.xml +++ b/scalariform.update/pom.xml @@ -5,11 +5,11 @@ 4.0.0 scalariform.update eclipse-update-site - 0.1.4-SNAPSHOT + 0.1.5-SNAPSHOT scalariform.parent org.scalariform - 0.1.4-SNAPSHOT + 0.1.5-SNAPSHOT diff --git a/scalariform.update/site.xml b/scalariform.update/site.xml index dd8f0a1a..0f1492e9 100644 --- a/scalariform.update/site.xml +++ b/scalariform.update/site.xml @@ -3,7 +3,7 @@ Scalariform Update Site - + diff --git a/scalariform/META-INF/MANIFEST.MF b/scalariform/META-INF/MANIFEST.MF index 7b688db4..735b5c2f 100644 --- a/scalariform/META-INF/MANIFEST.MF +++ b/scalariform/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Scalariform Bundle-SymbolicName: scalariform -Bundle-Version: 0.1.4.qualifier +Bundle-Version: 0.1.5.qualifier Require-Bundle: org.scala-ide.scala.library Bundle-ClassPath: . Export-Package: scalariform, diff --git a/scalariform/pom.xml b/scalariform/pom.xml index dfc3b2de..b5e025e5 100644 --- a/scalariform/pom.xml +++ b/scalariform/pom.xml @@ -4,12 +4,12 @@ 4.0.0 org.scalariform scalariform - 0.1.4-SNAPSHOT + 0.1.5-SNAPSHOT eclipse-plugin scalariform.parent org.scalariform - 0.1.4-SNAPSHOT + 0.1.5-SNAPSHOT From 97cf986b641c9e24967081617756b2bb41a6a344 Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Wed, 24 Apr 2013 20:18:43 +0100 Subject: [PATCH 23/36] Amazon S3 download link --- README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.rst b/README.rst index 31604173..0246c4cd 100755 --- a/README.rst +++ b/README.rst @@ -128,7 +128,7 @@ the following to ``.vimrc`` :: The executable scalariform.jar can be downloaded from: - https://github.com/downloads/mdr/scalariform/scalariform.jar + https://s3.amazonaws.com/scalariform/scalariform.jar Command line tool ----------------- From 9521a844d1e863351a7f1d440075ead729f489ac Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Thu, 25 Apr 2013 18:36:06 +0100 Subject: [PATCH 24/36] Support parameterised traits per Scalac master --- .../formatter/TemplateFormatter.scala | 22 +++++++++++-- .../scala/scalariform/parser/AstNodes.scala | 5 +-- .../scalariform/parser/ScalaParser.scala | 32 +++++++++++-------- .../MiscExpressionFormatterTest.scala | 10 ++++++ .../formatter/TemplateFormatterTest.scala | 9 ++++++ 5 files changed, 59 insertions(+), 19 deletions(-) diff --git a/scalariform/src/main/scala/scalariform/formatter/TemplateFormatter.scala b/scalariform/src/main/scala/scalariform/formatter/TemplateFormatter.scala index 81a3a9fd..44c66347 100644 --- a/scalariform/src/main/scala/scalariform/formatter/TemplateFormatter.scala +++ b/scalariform/src/main/scala/scalariform/formatter/TemplateFormatter.scala @@ -50,16 +50,20 @@ trait TemplateFormatter { self: HasFormattingPreferences with AnnotationFormatte formatResult ++= format(earlyBody)(currentFormatterState) for (templateParents ← templateParentsOpt) { - val TemplateParents(type1: Type, argumentExprss: List[ArgumentExprs], withTypes: List[(Token, Type)]) = templateParents + val TemplateParents((type1: Type, argumentExprss: List[ArgumentExprs]), withTypes: List[(Token, Type, List[ArgumentExprs])]) = templateParents + formatResult ++= format(type1)(currentFormatterState) for (argumentExprs ← argumentExprss) formatResult ++= format(argumentExprs)(currentFormatterState)._1 - for ((withToken, type_) ← withTypes) { + + for ((withToken, type_, argumentExprss2) ← withTypes) { if (hiddenPredecessors(withToken).containsNewline) { currentFormatterState = formatterState.indent(inheritanceIndent) formatResult = formatResult.before(withToken, currentFormatterState.currentIndentLevelInstruction) } formatResult ++= format(type_)(currentFormatterState) + for (argumentExprs2 ← argumentExprss2) + formatResult ++= format(argumentExprs2)(currentFormatterState)._1 } } } @@ -113,8 +117,20 @@ trait TemplateFormatter { self: HasFormattingPreferences with AnnotationFormatte private def format(templateParents: TemplateParents)(implicit formatterState: FormatterState): FormatResult = { var formatResult: FormatResult = NoFormatResult - for (argumentExprs ← templateParents.argumentExprss) + val TemplateParents((type1: Type, argumentExprss: List[ArgumentExprs]), withTypes: List[(Token, Type, List[ArgumentExprs])]) = templateParents + formatResult ++= format(type1) + for (argumentExprs ← argumentExprss) formatResult ++= format(argumentExprs)._1 + + // TODO: Unify with TmplDef code + + val currentFormatterState = formatterState + for ((withToken, type_, argumentExprss2) ← withTypes) { + formatResult ++= format(type_)(currentFormatterState) + for (argumentExprs2 ← argumentExprss2) + formatResult ++= format(argumentExprs2)(currentFormatterState)._1 + } + formatResult } diff --git a/scalariform/src/main/scala/scalariform/parser/AstNodes.scala b/scalariform/src/main/scala/scalariform/parser/AstNodes.scala index 9e05b063..fc72afe7 100644 --- a/scalariform/src/main/scala/scalariform/parser/AstNodes.scala +++ b/scalariform/src/main/scala/scalariform/parser/AstNodes.scala @@ -26,6 +26,7 @@ sealed trait AstNode extends CaseClassReflector { protected implicit def listToFlattenable[T <% Flattenable](list: List[T]): Flattenable = new Flattenable { val tokens = list flatMap { _.tokens } } protected implicit def optionToFlattenable[T <% Flattenable](option: Option[T]): Flattenable = new Flattenable { val tokens = option.toList flatMap { _.tokens } } protected implicit def pairToFlattenable[T1 <% Flattenable, T2 <% Flattenable](pair: (T1, T2)): Flattenable = new Flattenable { val tokens = pair._1.tokens ::: pair._2.tokens } + protected implicit def tripleToFlattenable[T1 <% Flattenable, T2 <% Flattenable, T3 <% Flattenable](triple: (T1, T2, T3)): Flattenable = new Flattenable { val tokens = triple._1.tokens ++ triple._2.tokens ++ triple._3.tokens } protected implicit def eitherToFlattenable[T1 <% Flattenable, T2 <% Flattenable](either: T1 Either T2): Flattenable = new Flattenable { val tokens = either match { case Left(f) ⇒ f.tokens @@ -355,8 +356,8 @@ case class StatSeq(selfReferenceOpt: Option[(Expr, Token)], } -case class TemplateParents(type1: Type, argumentExprss: List[ArgumentExprs], withTypes: List[(Token, Type)]) extends AstNode { - lazy val tokens = flatten(type1, argumentExprss, withTypes) +case class TemplateParents(typeAndArgs: (Type, List[ArgumentExprs]), withTypesAndArgs: List[(Token, Type, List[ArgumentExprs])]) extends AstNode { + lazy val tokens = flatten(typeAndArgs, withTypesAndArgs) } case class ImportClause(importToken: Token, importExpr: ImportExpr, otherImportExprs: List[(Token, ImportExpr)]) extends AstNode with Stat { diff --git a/scalariform/src/main/scala/scalariform/parser/ScalaParser.scala b/scalariform/src/main/scala/scalariform/parser/ScalaParser.scala index 3bc845c8..036923a1 100644 --- a/scalariform/src/main/scala/scalariform/parser/ScalaParser.scala +++ b/scalariform/src/main/scala/scalariform/parser/ScalaParser.scala @@ -798,7 +798,7 @@ class ScalaParser(tokens: Array[Token]) { case NEW ⇒ canApply = false val newToken = nextToken() - val template_ = template(isTrait = false) + val template_ = template() List(New(newToken, template_)) case _ ⇒ throw new ScalaParserException("illegal start of simple expression: " + currentToken) @@ -1543,33 +1543,37 @@ class ScalaParser(tokens: Array[Token]) { templateBodyOption = templateOpt_.templateBodyOpt) } - private def templateParents(isTrait: Boolean): TemplateParents = { - val type1 = Type(startAnnotType()) - val argumentExprs_ = - if (LPAREN && !isTrait) multipleArgumentExprs() - else Nil - val withTypes = ListBuffer[(Token, Type)]() + private def templateParents(): TemplateParents = { + def readAppliedParent(): (Type, List[ArgumentExprs]) = { + val parent = Type(startAnnotType()) + val argss = + if (LPAREN) multipleArgumentExprs() + else Nil + (parent, argss) + } + val withTypes = ListBuffer[(Token, Type, List[ArgumentExprs])]() + val (type1, argumentExprs) = readAppliedParent() while (WITH) { val withToken = nextToken() - val withType = Type(startAnnotType()) - withTypes += ((withToken, withType)) + val (type2, argumentExprs2) = readAppliedParent() + withTypes += ((withToken, type2, argumentExprs2)) } - TemplateParents(type1, argumentExprs_, withTypes.toList) + TemplateParents((type1, argumentExprs), withTypes.toList) } - private def template(isTrait: Boolean): Template = { + private def template(): Template = { val newLineOpt = newLineOptWhenFollowedBy(LBRACE) if (LBRACE) { val templateBody_ = templateBody().copy(newlineOpt = newLineOpt) if (WITH) { // TODO check cond val withToken = nextToken() - val templateParents_ = templateParents(isTrait) + val templateParents_ = templateParents() val templateBodyOpt_ = templateBodyOpt() Template(Some(EarlyDefs(templateBody_, Some(withToken))), Some(templateParents_), templateBodyOpt_) } else Template(Some(EarlyDefs(templateBody_, withOpt = None)), templateParentsOpt = None, templateBodyOpt = None) } else { - val templateParents_ = templateParents(isTrait) + val templateParents_ = templateParents() val templateBodyOpt_ = templateBodyOpt() Template(earlyDefsOpt = None, Some(templateParents_), templateBodyOpt_) } @@ -1578,7 +1582,7 @@ class ScalaParser(tokens: Array[Token]) { private def templateOpt(isTrait: Boolean): TemplateOpt = { if (EXTENDS || SUBTYPE && isTrait) { val extendsOrSubtypeToken = nextToken() - template(isTrait) match { + template() match { case Template(earlyDefsOpt, templateParentsOpt, templateBodyOpt) ⇒ TemplateOpt(Some(TemplateInheritanceSection(extendsOrSubtypeToken, earlyDefsOpt, templateParentsOpt)), templateBodyOpt) } diff --git a/scalariform/src/test/scala/scalariform/formatter/MiscExpressionFormatterTest.scala b/scalariform/src/test/scala/scalariform/formatter/MiscExpressionFormatterTest.scala index 4601cd9a..8b3427ad 100755 --- a/scalariform/src/test/scala/scalariform/formatter/MiscExpressionFormatterTest.scala +++ b/scalariform/src/test/scala/scalariform/formatter/MiscExpressionFormatterTest.scala @@ -799,6 +799,16 @@ class MiscExpressionFormatterTest extends AbstractExpressionFormatterTest { "{ val P(a, b*c) = p }" ==> "{ val P(a, b * c) = p }" + + """new {} with A(new { + |val x = 42}) with B(new { + |val x = 42})""" ==> + """new {} with A(new { + | val x = 42 + |}) with B(new { + | val x = 42 + |})""" + override val debug = false } diff --git a/scalariform/src/test/scala/scalariform/formatter/TemplateFormatterTest.scala b/scalariform/src/test/scala/scalariform/formatter/TemplateFormatterTest.scala index 39e930ab..9ada51d5 100644 --- a/scalariform/src/test/scala/scalariform/formatter/TemplateFormatterTest.scala +++ b/scalariform/src/test/scala/scalariform/formatter/TemplateFormatterTest.scala @@ -599,6 +599,15 @@ class TemplateFormatterTest extends AbstractFormatterTest { | @D def e |}""" + """class A extends B(42 , 43) with C(44 , 45) { + | foo() + | bar() + |}""" ==> + """class A extends B(42, 43) with C(44, 45) { + | foo() + | bar() + |}""" + // format: ON override val debug = false From adb872f8149e581c7b3ad5192bb463f833c3e485 Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Fri, 26 Apr 2013 08:21:43 +0100 Subject: [PATCH 25/36] Added notes of hashes of scalac files to sync parser changes --- notes/scala-sync.txt | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 notes/scala-sync.txt diff --git a/notes/scala-sync.txt b/notes/scala-sync.txt new file mode 100644 index 00000000..30a3f4f0 --- /dev/null +++ b/notes/scala-sync.txt @@ -0,0 +1,4 @@ +scalac changes checked 26/April/2013 + +Scanners.scala: cdffcf8962c9fa606c027fcb5a50a4273976a576 +Parsers.scala: cd148d97225fc7738f7a8ff9d4479cd46d632371 From 2780b45e496fb7ee81eb725b0a76fb00032259ef Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Mon, 29 Apr 2013 18:05:08 +0100 Subject: [PATCH 26/36] Fix parser updates on Inferred Semi parser --- .../parser/InferredSemicolonScalaParser.scala | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/scalariform/src/main/scala/scalariform/parser/InferredSemicolonScalaParser.scala b/scalariform/src/main/scala/scalariform/parser/InferredSemicolonScalaParser.scala index 2be86d90..7707f71f 100644 --- a/scalariform/src/main/scala/scalariform/parser/InferredSemicolonScalaParser.scala +++ b/scalariform/src/main/scala/scalariform/parser/InferredSemicolonScalaParser.scala @@ -406,6 +406,10 @@ class InferredSemicolonScalaParser(tokens: Array[Token]) { dropAnyBraces(pattern()) else if (isIdent) ident() + else if (LBRACE) + expr() + else if (THIS) + nextToken() else expr() } @@ -651,7 +655,7 @@ class InferredSemicolonScalaParser(tokens: Array[Token]) { case NEW ⇒ canApply = false nextToken() - template(isTrait = false) + template() case _ ⇒ throw new ScalaParserException("illegal start of simple expression: " + currentToken) } @@ -1259,27 +1263,30 @@ class InferredSemicolonScalaParser(tokens: Array[Token]) { templateOpt(isTrait = false) } - private def templateParents(isTrait: Boolean) = { - startAnnotType() - if (LPAREN && !isTrait) multipleArgumentExprs() - else Nil + private def templateParents() { + def readAppliedParent() { + startAnnotType() + if (LPAREN) + multipleArgumentExprs() + } + readAppliedParent() while (WITH) { nextToken() - startAnnotType() + readAppliedParent() } } - private def template(isTrait: Boolean) { + private def template() { newLineOptWhenFollowedBy(LBRACE) if (LBRACE) { templateBody() if (WITH) { // TODO check cond nextToken() - templateParents(isTrait) + templateParents() templateBodyOpt() } } else { - templateParents(isTrait) + templateParents() templateBodyOpt() } } @@ -1287,7 +1294,7 @@ class InferredSemicolonScalaParser(tokens: Array[Token]) { private def templateOpt(isTrait: Boolean) { if (EXTENDS || SUBTYPE && isTrait) { nextToken() - template(isTrait) + template() } else { // val newLineOpt = newLineOptWhenFollowedBy(LBRACE) // Will be picked up by templateBodyOpt ... TODO: double check this templateBodyOpt() From c29e9ff40073bda7b0edb8f648dbea7cd3ceb6d2 Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Mon, 29 Apr 2013 18:28:46 +0100 Subject: [PATCH 27/36] Formatting tweaks --- .../scala/scalariform/gui/FormatterFrame.scala | 3 +-- project/Build.scala | 16 +++++++--------- .../main/scala/scalariform/ScalaVersions.scala | 8 ++++---- .../formatter/SpecificFormatter.scala | 4 ++-- .../formatter/TemplateFormatter.scala | 2 +- .../scalariform/lexer/NewlineInferencer.scala | 4 ++-- .../main/scala/scalariform/parser/AstNodes.scala | 3 +++ .../src/main/scala/scalariform/utils/Utils.scala | 2 +- .../formatter/TemplateFormatterTest.scala | 2 +- .../scala/scalariform/parser/ParserTest.scala | 4 ++-- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/misc/src/main/scala/scalariform/gui/FormatterFrame.scala b/misc/src/main/scala/scalariform/gui/FormatterFrame.scala index 78c42c91..e8649426 100644 --- a/misc/src/main/scala/scalariform/gui/FormatterFrame.scala +++ b/misc/src/main/scala/scalariform/gui/FormatterFrame.scala @@ -355,9 +355,8 @@ class FormatterFrame extends JFrame with SpecificFormatter { class ProductionItem(name: String, val formatter: SpecificFormatter) { override def toString = name } - - object ProductionComboBoxModel extends DefaultComboBoxModel[ProductionItem] { + object ProductionComboBoxModel extends DefaultComboBoxModel[ProductionItem] { val compilationUnitFormatter = new SpecificFormatter { diff --git a/project/Build.scala b/project/Build.scala index 897d20f4..b84ef8d1 100644 --- a/project/Build.scala +++ b/project/Build.scala @@ -9,17 +9,15 @@ import scalariform.formatter.preferences._ object ScalariformBuild extends Build { - lazy val commonSettings = Defaults.defaultSettings ++ SbtScalariform.defaultScalariformSettings ++ Seq( organization := "org.scalariform", version := "0.1.5-SNAPSHOT", scalaVersion := "2.10.0", crossScalaVersions := Seq( -// "2.11.0-M2", + // "2.11.0-M2", "2.10.0", "2.10.1", "2.9.3", "2.9.2", "2.9.1-1", "2.9.1", "2.9.0-1", "2.9.0", - "2.8.2", "2.8.1", "2.8.0" - ), + "2.8.2", "2.8.1", "2.8.0"), exportJars := true, // Needed for cli oneJar retrieveManaged := true, scalacOptions += "-deprecation", @@ -37,11 +35,11 @@ object ScalariformBuild extends Build { publishLocal := ())) aggregate (scalariform, cli, misc) def getScalaTestDependency(scalaVersion: String) = scalaVersion match { - case "2.8.0" ⇒ "org.scalatest" %% "scalatest" % "1.3.1.RC2" % "test" - case "2.10.0" =>"org.scalatest" %% "scalatest" % "1.9.1" % "test" - case "2.10.1" =>"org.scalatest" %% "scalatest" % "1.9.1" % "test" - case "2.9.3" =>"org.scalatest" %% "scalatest" % "1.9.1" % "test" - case _ ⇒ "org.scalatest" %% "scalatest" % "1.7.2" % "test" + case "2.8.0" ⇒ "org.scalatest" %% "scalatest" % "1.3.1.RC2" % "test" + case "2.10.0" ⇒ "org.scalatest" %% "scalatest" % "1.9.1" % "test" + case "2.10.1" ⇒ "org.scalatest" %% "scalatest" % "1.9.1" % "test" + case "2.9.3" ⇒ "org.scalatest" %% "scalatest" % "1.9.1" % "test" + case _ ⇒ "org.scalatest" %% "scalatest" % "1.7.2" % "test" } lazy val scalariform: Project = Project("scalariform", file("scalariform"), settings = diff --git a/scalariform/src/main/scala/scalariform/ScalaVersions.scala b/scalariform/src/main/scala/scalariform/ScalaVersions.scala index 71c34cf0..3aedf44c 100644 --- a/scalariform/src/main/scala/scalariform/ScalaVersions.scala +++ b/scalariform/src/main/scala/scalariform/ScalaVersions.scala @@ -12,12 +12,12 @@ object ScalaVersion { def parse(s: String): Option[ScalaVersion] = s match { - case VersionPattern(majorStr, minorStr, extra) => + case VersionPattern(majorStr, minorStr, extra) ⇒ for { - major <- majorStr.toIntOpt - minor <- minorStr.toIntOpt + major ← majorStr.toIntOpt + minor ← minorStr.toIntOpt } yield ScalaVersion(major, minor, extra) - case _ => + case _ ⇒ None } diff --git a/scalariform/src/main/scala/scalariform/formatter/SpecificFormatter.scala b/scalariform/src/main/scala/scalariform/formatter/SpecificFormatter.scala index b0b976d2..82bac11a 100644 --- a/scalariform/src/main/scala/scalariform/formatter/SpecificFormatter.scala +++ b/scalariform/src/main/scala/scalariform/formatter/SpecificFormatter.scala @@ -51,10 +51,10 @@ trait SpecificFormatter { } actualFormattingPreferences = actualFormattingPreferences.setPreference(preference, onOrOff) val parsedTokens = parseResult.tokens.filter(_.tokenType != EOF) - require(parsedTokens == tokens.init /* <-- drop EOF */, "Parse tokens differ from expected.\n Actual = \n" + + require(parsedTokens == tokens.init /* <-- drop EOF */ , "Parse tokens differ from expected.\n Actual = \n" + parsedTokens.mkString("\n") + "\n expected = \n" + tokens.init.mkString("\n") + "\n parseResult = \n" + parseResult) - + if (debug) { println("Parse result: " + parseResult) } val elapsedTime = System.currentTimeMillis - startTime // if (debug) diff --git a/scalariform/src/main/scala/scalariform/formatter/TemplateFormatter.scala b/scalariform/src/main/scala/scalariform/formatter/TemplateFormatter.scala index 44c66347..d201fb5b 100644 --- a/scalariform/src/main/scala/scalariform/formatter/TemplateFormatter.scala +++ b/scalariform/src/main/scala/scalariform/formatter/TemplateFormatter.scala @@ -123,7 +123,7 @@ trait TemplateFormatter { self: HasFormattingPreferences with AnnotationFormatte formatResult ++= format(argumentExprs)._1 // TODO: Unify with TmplDef code - + val currentFormatterState = formatterState for ((withToken, type_, argumentExprss2) ← withTypes) { formatResult ++= format(type_)(currentFormatterState) diff --git a/scalariform/src/main/scala/scalariform/lexer/NewlineInferencer.scala b/scalariform/src/main/scala/scalariform/lexer/NewlineInferencer.scala index 2a37e73a..a06b508c 100644 --- a/scalariform/src/main/scala/scalariform/lexer/NewlineInferencer.scala +++ b/scalariform/src/main/scala/scalariform/lexer/NewlineInferencer.scala @@ -100,8 +100,8 @@ class NewlineInferencer(delegate: WhitespaceAndCommentsGrouper) extends Iterator false else if (TOKENS_WHICH_CANNOT_BEGIN_A_STATEMENT contains currentTokenType) false -// else if (currentTokenType == CASE && !followingTokenIsClassOrObject(nextToken)) -// false + // else if (currentTokenType == CASE && !followingTokenIsClassOrObject(nextToken)) + // false else if (regionMarkerStack.nonEmpty && regionMarkerStack.head != RBRACE) false else diff --git a/scalariform/src/main/scala/scalariform/parser/AstNodes.scala b/scalariform/src/main/scala/scalariform/parser/AstNodes.scala index fc72afe7..23988e7f 100644 --- a/scalariform/src/main/scala/scalariform/parser/AstNodes.scala +++ b/scalariform/src/main/scala/scalariform/parser/AstNodes.scala @@ -416,12 +416,15 @@ sealed trait XmlExprElement extends ExprElement case class XmlStartTag(startOpen: Token, name: Token, attributes: List[(Option[Token], XmlAttribute)], whitespaceOption: Option[Token], tagClose: Token) extends XmlExprElement { lazy val tokens = flatten(startOpen, name, attributes, whitespaceOption, tagClose) } + case class XmlAttribute(name: Token, whitespaceOption: Option[Token], equals: Token, whitespaceOption2: Option[Token], valueOrEmbeddedScala: Either[Token, Expr]) extends XmlExprElement { lazy val tokens = flatten(name, whitespaceOption, equals, whitespaceOption2, valueOrEmbeddedScala) } + case class XmlEmptyElement(startOpen: Token, name: Token, attributes: List[(Option[Token], XmlAttribute)], whitespaceOption: Option[Token], emptyClose: Token) extends XmlElement { lazy val tokens = flatten(startOpen, name, attributes, whitespaceOption, emptyClose) } + case class XmlEndTag(endOpen: Token, name: Token, whitespaceOption: Option[Token], tagClose: Token) extends XmlExprElement { lazy val tokens = flatten(endOpen, name, whitespaceOption, tagClose) } diff --git a/scalariform/src/main/scala/scalariform/utils/Utils.scala b/scalariform/src/main/scala/scalariform/utils/Utils.scala index 771b5106..4f796857 100644 --- a/scalariform/src/main/scala/scalariform/utils/Utils.scala +++ b/scalariform/src/main/scala/scalariform/utils/Utils.scala @@ -21,7 +21,7 @@ object Utils { implicit def string2PimpedString(s: String) = new PimpedString(s) class PimpedString(s: String) { - def toIntOpt: Option[Int] = try Some(s.toInt) catch { case _: NumberFormatException => None } + def toIntOpt: Option[Int] = try Some(s.toInt) catch { case _: NumberFormatException ⇒ None } } def stagger[T](iterable: Iterable[T]) = iterable zip iterable.tail diff --git a/scalariform/src/test/scala/scalariform/formatter/TemplateFormatterTest.scala b/scalariform/src/test/scala/scalariform/formatter/TemplateFormatterTest.scala index 9ada51d5..cc0a2783 100644 --- a/scalariform/src/test/scala/scalariform/formatter/TemplateFormatterTest.scala +++ b/scalariform/src/test/scala/scalariform/formatter/TemplateFormatterTest.scala @@ -607,7 +607,7 @@ class TemplateFormatterTest extends AbstractFormatterTest { | foo() | bar() |}""" - + // format: ON override val debug = false diff --git a/scalariform/src/test/scala/scalariform/parser/ParserTest.scala b/scalariform/src/test/scala/scalariform/parser/ParserTest.scala index 0b000233..4a2063da 100644 --- a/scalariform/src/test/scala/scalariform/parser/ParserTest.scala +++ b/scalariform/src/test/scala/scalariform/parser/ParserTest.scala @@ -25,7 +25,7 @@ class ParserTest extends FlatSpec with ShouldMatchers { parseExpression("{ case List[String]() => 12 }") } - // See issue #60 + // See issue #60 "Parser" should "not throw an exception on case block ending with decl" in { parseExpression(""" args(0) match { @@ -36,7 +36,7 @@ class ParserTest extends FlatSpec with ShouldMatchers { } """) } - + "Parser" should "throw a parse exception in bad package blocks" in { evaluating { parseCompilationUnit("package a {} package b {}") } should produce[ScalaParserException] } From c0b2403ba92baa7c4580659dc8b6a9343c2bdf68 Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Mon, 29 Apr 2013 22:17:06 +0100 Subject: [PATCH 28/36] FIX: Type formatter crash on multiline types --- CHANGELOG | 5 +++++ .../src/main/scala/scalariform/formatter/TypeFormatter.scala | 2 +- .../test/scala/scalariform/formatter/TypeFormatterTest.scala | 4 ++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 3c3e6589..805f6ca8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,8 @@ +0.1.5 (..) +* FIX: Type formatter crash on multiline types +* Track scalac parser -- allow trait-position parents to have parameter blocks +* Sync changes to InferredSemicolonParser + 0.1.4 (24/April/13) * FIX: Allow declarations as last statement in case block (issue #60) * Update to build 2.10 final diff --git a/scalariform/src/main/scala/scalariform/formatter/TypeFormatter.scala b/scalariform/src/main/scala/scalariform/formatter/TypeFormatter.scala index d69d6c11..7b2b725a 100644 --- a/scalariform/src/main/scala/scalariform/formatter/TypeFormatter.scala +++ b/scalariform/src/main/scala/scalariform/formatter/TypeFormatter.scala @@ -20,7 +20,7 @@ trait TypeFormatter { self: HasFormattingPreferences with AnnotationFormatter wi previousElement.isInstanceOf[InfixTypeConstructor] || element.isInstanceOf[Refinement] || element.isInstanceOf[InfixTypeConstructor]) - formatResult = formatResult.before(element.firstToken, CompactEnsuringGap) + formatResult = formatResult.formatNewlineOrOrdinary(element.firstToken, CompactEnsuringGap) else if (element.isInstanceOf[Annotation]) { val instruction = previousElement match { diff --git a/scalariform/src/test/scala/scalariform/formatter/TypeFormatterTest.scala b/scalariform/src/test/scala/scalariform/formatter/TypeFormatterTest.scala index ce2d39a8..2906e8e0 100644 --- a/scalariform/src/test/scala/scalariform/formatter/TypeFormatterTest.scala +++ b/scalariform/src/test/scala/scalariform/formatter/TypeFormatterTest.scala @@ -63,6 +63,10 @@ class TypeFormatterTest extends AbstractFormatterTest { "b[c# ::[d]]" ==> "b[c# ::[d]]" + """C :: + | D""" ==> + """C :: D""" // To check that this doesn't blow up -- we should maintain the newline + override val debug = false type Result = Type From 7bf725ec994efa723a7e17c9c837b8047fd32a0a Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Tue, 30 Apr 2013 12:36:00 +0100 Subject: [PATCH 29/36] Improvements for GUI --- .../scala/scalariform/commandline/Main.scala | 15 --- .../scalariform/gui/FormatterFrame.scala | 91 ++++++++----------- .../src/main/scala/scalariform/gui/Main.scala | 14 ++- .../scalariform/gui/ParseTreeModel.scala | 85 +++++++++-------- .../scala/scalariform/gui/SwingUtils.scala | 13 +++ .../scala/scalariform/gui/TokenTable.scala | 55 +++++++++++ .../scalariform/formatter/FormatResult.scala | 6 ++ 7 files changed, 166 insertions(+), 113 deletions(-) create mode 100644 misc/src/main/scala/scalariform/gui/SwingUtils.scala create mode 100644 misc/src/main/scala/scalariform/gui/TokenTable.scala diff --git a/cli/src/main/scala/scalariform/commandline/Main.scala b/cli/src/main/scala/scalariform/commandline/Main.scala index a549d067..3cd343b6 100644 --- a/cli/src/main/scala/scalariform/commandline/Main.scala +++ b/cli/src/main/scala/scalariform/commandline/Main.scala @@ -254,26 +254,11 @@ object Main { private def transformFilesInPlace(files: Seq[File], encoding: String, doFormat: String ⇒ Option[String], log: String ⇒ Unit): Boolean = { var problems = false - // val futures = - // for (file ← files) yield asyncExec { - // problems &= transformFileInPlace(file, encoding, doFormat, log) - // } - // futures.map(_.get()) for (file ← files) problems &= transformFileInPlace(file, encoding, doFormat, log) problems } - // private val lock = new ReentrantLock - // private lazy val executorService = Executors.newCachedThreadPool() - // private def asyncExec(x: ⇒ Unit): Future[_] = executorService.submit(new Runnable { def run() = x }) - // private def withLock[T](x: ⇒ T): T = { - // lock.lock() - // try - // x - // finally - // lock.unlock() - // } /** * @return true iff file is already formatted correctly */ diff --git a/misc/src/main/scala/scalariform/gui/FormatterFrame.scala b/misc/src/main/scala/scalariform/gui/FormatterFrame.scala index e8649426..f12d1c27 100644 --- a/misc/src/main/scala/scalariform/gui/FormatterFrame.scala +++ b/misc/src/main/scala/scalariform/gui/FormatterFrame.scala @@ -21,6 +21,10 @@ import scalariform.formatter._ import scalariform.formatter.preferences._ import scalariform.lexer._ import scalariform.lexer.Tokens._ +import scalariform.gui.SwingUtils._ +import scalariform.parser._ +import scala.util.parsing.input._ +import scala.util.parsing.combinator._ class FormatterFrame extends JFrame with SpecificFormatter { @@ -101,10 +105,9 @@ class FormatterFrame extends JFrame with SpecificFormatter { val textFont = new Font("monospaced", Font.PLAIN, 14) val astTree = new JTree - val tokensTable = new JTable - tokensTable.setCellSelectionEnabled(false) - tokensTable.setRowSelectionAllowed(true) - tokensTable.setColumnSelectionAllowed(false) + + val tokensTable = new TokenTable + val rawTokensTable = new TokenTable val outputTextPane = new JTextPane setFont(outputTextPane, textFont) @@ -155,8 +158,10 @@ class FormatterFrame extends JFrame with SpecificFormatter { case e: RuntimeException ⇒ if (showAstCheckBox.isSelected) { val tokens = ScalaLexer.tokenise(inputText, scalaVersion = SCALA_VERSION) + val rawTokens = ScalaLexer.rawTokenise(inputText, scalaVersion = SCALA_VERSION) val tableModel = new TokenTableModel(tokens, FormatResult(Map(), Map(), Map())) - tokensTable.setModel(tableModel) + tokensTable.setTokens(tokens) + rawTokensTable.setTokens(rawTokens) try { val parseResult = specificFormatter.parse(new ScalaParser(tokens.toArray)) val treeModel = new ParseTreeModel(parseResult) @@ -168,21 +173,19 @@ class FormatterFrame extends JFrame with SpecificFormatter { } val duration = System.currentTimeMillis - startTime val tokens = ScalaLexer.tokenise(inputText, scalaVersion = SCALA_VERSION) + val rawTokens = ScalaLexer.rawTokenise(inputText, scalaVersion = SCALA_VERSION) val tokenCount = tokens.size setTitle("Scalariform " + scalariform.BuildInfo.version + " -- " + duration + "ms, " + tokenCount + " tokens, speed = " + (1000 * tokenCount / (duration + 1)) + " tokens/second") outputTextPane.setText(outputText) if (showAstCheckBox.isSelected) { - import scalariform.parser._ - import scala.util.parsing.input._ - import scala.util.parsing.combinator._ val parseResult = try specificFormatter.parse(new ScalaParser(tokens.toArray)) catch { case e: RuntimeException ⇒ - val tableModel = new TokenTableModel(tokens, FormatResult(Map(), Map(), Map())) - tokensTable.setModel(tableModel) + tokensTable.setTokens(tokens) + rawTokensTable.setTokens(rawTokens) throw e } val treeModel = new ParseTreeModel(parseResult) @@ -191,8 +194,8 @@ class FormatterFrame extends JFrame with SpecificFormatter { val (outputText, formatResult) = specificFormatter.fullFormat(inputText, scalaVersion = SCALA_VERSION)(OptionsPanel.getFormattingPreferences) - val tableModel = new TokenTableModel(tokens, formatResult) - tokensTable.setModel(tableModel) + tokensTable.setTokens(tokens, formatResult) + rawTokensTable.setTokens(rawTokens) } } catch { case t: Throwable ⇒ @@ -211,6 +214,7 @@ class FormatterFrame extends JFrame with SpecificFormatter { resultTabbedPane.addTab("Output", new JScrollPane(outputTextPane)) resultTabbedPane.addTab("AST", new JScrollPane(astTree)) resultTabbedPane.addTab("Tokens", new JScrollPane(tokensTable)) + resultTabbedPane.addTab("Raw Tokens", new JScrollPane(rawTokensTable)) val splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT) splitPane.setTopComponent(new JScrollPane(inputTextPane)) @@ -304,26 +308,36 @@ class FormatterFrame extends JFrame with SpecificFormatter { val parseTreeModel = astTree.getModel.asInstanceOf[ParseTreeModel] for { lastComponent ← Option(astTree.getLastSelectedPathComponent) - (from, to) ← parseTreeModel.getDocumentRange(lastComponent) + range ← parseTreeModel.getDocumentRange(lastComponent) } { - inputTextPane.setSelectionStart(from) - inputTextPane.setSelectionEnd(to + 1) + inputTextPane.setSelectionStart(range.offset) + inputTextPane.setSelectionEnd(range.offset + range.length) + inputTextPane.requestFocusInWindow() + astTree.requestFocusInWindow() } } }) - tokensTable.getSelectionModel.addListSelectionListener(new ListSelectionListener() { - def valueChanged(e: ListSelectionEvent) { - val tableModel = tokensTable.getModel.asInstanceOf[TokenTableModel] - val selectionIndex = e.getFirstIndex - if (selectionIndex >= 0) { - val (from, to) = tableModel.getDocumentRange(selectionIndex) - inputTextPane.setSelectionStart(from) - inputTextPane.setSelectionEnd(to + 1) - } + tokensTable.getSelectionModel.addListSelectionListener { e: ListSelectionEvent ⇒ + for (token ← tokensTable.getSelectedToken) { + val range = token.range + inputTextPane.setSelectionStart(range.offset) + inputTextPane.setSelectionEnd(range.offset + range.length) + inputTextPane.requestFocusInWindow() + tokensTable.requestFocusInWindow() } - }) + } + + rawTokensTable.getSelectionModel.addListSelectionListener { e: ListSelectionEvent ⇒ + for (token ← rawTokensTable.getSelectedToken) { + val range = token.range + inputTextPane.setSelectionStart(range.offset) + inputTextPane.setSelectionEnd(range.offset + range.length) + inputTextPane.requestFocusInWindow() + rawTokensTable.requestFocusInWindow() + } + } { val menuBar = new JMenuBar @@ -412,31 +426,4 @@ object Samples { |}""".stripMargin } // format: ON -class TokenTableModel(tokens: List[Token], formatResult: FormatResult) extends AbstractTableModel { - def getColumnCount = 5 - def getRowCount = tokens.size - def getValueAt(row: Int, col: Int): AnyRef = { - val token = tokens(row) - col match { - case 0 ⇒ token.tokenType - case 1 ⇒ token.text - case 2 ⇒ token.offset.asInstanceOf[java.lang.Integer] - case 3 ⇒ token.lastCharacterOffset.asInstanceOf[java.lang.Integer] - case 4 ⇒ { - formatResult.predecessorFormatting.get(token) orElse formatResult.inferredNewlineFormatting.get(token) getOrElse "" - } - } - } - override def getColumnName(col: Int) = col match { - case 0 ⇒ "Type" - case 1 ⇒ "Token text" - case 2 ⇒ "Start" - case 3 ⇒ "Finish" - case 4 ⇒ "Instruction" - } - def getDocumentRange(index: Int): (Int, Int) = { - val token = tokens(index) - (token.offset, token.lastCharacterOffset) - } -} diff --git a/misc/src/main/scala/scalariform/gui/Main.scala b/misc/src/main/scala/scalariform/gui/Main.scala index 7f6d360f..35599e9c 100644 --- a/misc/src/main/scala/scalariform/gui/Main.scala +++ b/misc/src/main/scala/scalariform/gui/Main.scala @@ -3,15 +3,13 @@ package scalariform.gui import scalariform.utils.Utils._ import javax.swing.JFrame -object Main { +object Main extends App { - def main(args: Array[String]) { - onSwingThread { - val frame = new FormatterFrame - frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) - frame.setSize(1280, 600) - frame.setVisible(true) - } + onSwingThread { + val frame = new FormatterFrame + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE) + frame.setSize(1280, 600) + frame.setVisible(true) } } diff --git a/misc/src/main/scala/scalariform/gui/ParseTreeModel.scala b/misc/src/main/scala/scalariform/gui/ParseTreeModel.scala index 224f1fc9..edc26d7d 100644 --- a/misc/src/main/scala/scalariform/gui/ParseTreeModel.scala +++ b/misc/src/main/scala/scalariform/gui/ParseTreeModel.scala @@ -1,85 +1,90 @@ package scalariform.gui -import java.awt.event._ -import net.miginfocom.layout._ -import net.miginfocom.swing._ -import javax.swing._ -import javax.swing.text._ -import java.awt.event._ -import java.awt.{ List ⇒ _, _ } - -import javax.swing._ -import javax.swing.event._ -import javax.swing.text._ +import javax.swing.event.TreeModelListener import javax.swing.tree._ - -import javax.swing.{ JMenu, JMenuItem, JMenuBar } - -import scalariform.utils.Utils._ -import scalariform.parser._ -import scalariform.formatter._ -import scalariform.lexer._ -import scalariform.lexer.Tokens._ +import scalariform.lexer.Token +import scalariform.parser.AstNode +import scalariform.utils.Range class ParseTreeModel(rootAstNode: AstNode) extends TreeModel { - def getDocumentRange(obj: AnyRef): Option[(Int, Int)] = obj.asInstanceOf[TreeNode].range + def getDocumentRange(obj: AnyRef): Option[Range] = obj.asInstanceOf[TreeNode].range abstract sealed class TreeNode(name: String) { + def children: List[TreeNode] - override def toString = name - lazy val range: Option[(Int, Int)] = { - val childRanges = children flatMap { _.range } - for { - firstRange ← childRanges.headOption - lastRange ← childRanges.lastOption - } yield (firstRange._1, lastRange._2) + + lazy val range: Option[Range] = { + val childRanges = children.flatMap(_.range) + if (childRanges.isEmpty) + None + else + Some(childRanges.reduceLeft(_ mergeWith _)) } + override def toString = name + } case class AstNodeNode(name: String, astNode: AstNode) extends TreeNode(name) { + val fields = astNode.getFields + lazy val children = fields flatMap { - case (_, None) | (_, Nil) ⇒ None + case (_, None) | (_, Nil) ⇒ None case (fieldName, value) ⇒ Some(makeTreeNode(value.asInstanceOf[AnyRef], fieldName)) } + override def toString = { val typeName = astNode.getClass.getSimpleName (if (name != "") name + ": " else "") + typeName } + } case class TokenNode(name: String, token: Token) extends TreeNode(name) { + val children = Nil + + override lazy val range = Some(token.range) + override def toString = name + ": " + token - override lazy val range = Some(token.offset, token.lastCharacterOffset) } case class ListNode(name: String, list: List[Any]) extends TreeNode(name) { - lazy val children = list map { x ⇒ makeTreeNode(x) } + + lazy val children = list.zipWithIndex map { case (x, i) ⇒ makeTreeNode(x, i.toString) } + } case class OptionNode(name: String, opt: Option[Any]) extends TreeNode(name) { - lazy val children = opt map { x ⇒ makeTreeNode(x) } toList + + lazy val children = opt map { x ⇒ makeTreeNode(x, "Some") } toList + } case class EitherNode(name: String, either: Either[Any, Any]) extends TreeNode(name) { + lazy val children = either match { - case Left(obj) ⇒ List(makeTreeNode(obj)) - case Right(obj) ⇒ List(makeTreeNode(obj)) + case Left(obj) ⇒ List(makeTreeNode(obj, "Left")) + case Right(obj) ⇒ List(makeTreeNode(obj, "Right")) } } case class PairNode(name: String, pair: (Any, Any)) extends TreeNode(name) { - lazy val children = List(makeTreeNode(pair._1), makeTreeNode(pair._2)) + + lazy val children = List(makeTreeNode(pair._1, "_1"), makeTreeNode(pair._2, "_2")) + } case class TodoNode(name: String, obj: Any) extends TreeNode(name) { + val children = Nil + override def toString = name + ": " + obj + } def makeTreeNode(obj: Any, name: String = ""): TreeNode = obj match { @@ -89,8 +94,10 @@ class ParseTreeModel(rootAstNode: AstNode) extends TreeModel { TokenNode(name, token) case list: List[_] ⇒ ListNode(name, list) - case option: Option[_] ⇒ - OptionNode(name, option) + case Some(x) ⇒ + makeTreeNode(x, name) + case None ⇒ + OptionNode(name, None) case either: Either[_, _] ⇒ EitherNode(name, either) case pair: (_, _) ⇒ @@ -103,8 +110,6 @@ class ParseTreeModel(rootAstNode: AstNode) extends TreeModel { def getChildCount(obj: AnyRef) = getChildren(obj).length - private def getChildren(obj: AnyRef) = obj.asInstanceOf[TreeNode].children - def getChild(parent: AnyRef, index: Int): AnyRef = getChildren(parent)(index) def getIndexOfChild(parent: AnyRef, child: AnyRef) = getChildren(parent).indexOf(child) @@ -112,8 +117,12 @@ class ParseTreeModel(rootAstNode: AstNode) extends TreeModel { def isLeaf(obj: AnyRef): Boolean = getChildCount(obj) == 0 def addTreeModelListener(l: TreeModelListener) {} + def removeTreeModelListener(l: TreeModelListener) {} + def valueForPathChanged(path: TreePath, newValue: Any) {} + private def getChildren(obj: AnyRef) = obj.asInstanceOf[TreeNode].children + } diff --git a/misc/src/main/scala/scalariform/gui/SwingUtils.scala b/misc/src/main/scala/scalariform/gui/SwingUtils.scala new file mode 100644 index 00000000..7b5180d2 --- /dev/null +++ b/misc/src/main/scala/scalariform/gui/SwingUtils.scala @@ -0,0 +1,13 @@ +package scalariform.gui + +import javax.swing.event.ListSelectionListener +import javax.swing.event.ListSelectionEvent + +object SwingUtils { + + implicit def fn2ListSelectionListener(handler: ListSelectionEvent ⇒ Unit): ListSelectionListener = new ListSelectionListener() { + def valueChanged(e: ListSelectionEvent) = handler(e) + } + + +} \ No newline at end of file diff --git a/misc/src/main/scala/scalariform/gui/TokenTable.scala b/misc/src/main/scala/scalariform/gui/TokenTable.scala new file mode 100644 index 00000000..c71ef964 --- /dev/null +++ b/misc/src/main/scala/scalariform/gui/TokenTable.scala @@ -0,0 +1,55 @@ +package scalariform.gui + +import scalariform.formatter.FormatResult +import javax.swing.JTable +import scalariform.lexer.Token +import javax.swing.table.AbstractTableModel +import scalariform.utils.Range + +class TokenTable extends JTable(new TokenTableModel(Nil, FormatResult.EMPTY)) { + + setCellSelectionEnabled(false) + setRowSelectionAllowed(true) + setColumnSelectionAllowed(false) + + def setTokens(tokens: List[Token], formatResult: FormatResult = FormatResult.EMPTY) { + val tableModel = new TokenTableModel(tokens, formatResult) + setModel(tableModel) + } + + override def getModel = super.getModel.asInstanceOf[TokenTableModel] + + def getSelectedToken: Option[Token] = + getSelectedRow() match { + case -1 ⇒ None + case n ⇒ Some(getModel.tokens(n)) + } + +} + +class TokenTableModel(val tokens: List[Token], formatResult: FormatResult) extends AbstractTableModel { + + def getColumnCount = 5 + + def getRowCount = tokens.size + + def getValueAt(row: Int, col: Int): AnyRef = { + val token = tokens(row) + col match { + case 0 ⇒ token.tokenType + case 1 ⇒ token.text + case 2 ⇒ token.offset.asInstanceOf[java.lang.Integer] + case 3 ⇒ token.lastCharacterOffset.asInstanceOf[java.lang.Integer] + case 4 ⇒ formatResult.predecessorFormatting.get(token) orElse formatResult.inferredNewlineFormatting.get(token) getOrElse "" + } + } + + override def getColumnName(col: Int) = col match { + case 0 ⇒ "Type" + case 1 ⇒ "Token text" + case 2 ⇒ "Start" + case 3 ⇒ "Finish" + case 4 ⇒ "Instruction" + } + +} \ No newline at end of file diff --git a/scalariform/src/main/scala/scalariform/formatter/FormatResult.scala b/scalariform/src/main/scala/scalariform/formatter/FormatResult.scala index 20da836a..92d0cd54 100644 --- a/scalariform/src/main/scala/scalariform/formatter/FormatResult.scala +++ b/scalariform/src/main/scala/scalariform/formatter/FormatResult.scala @@ -5,6 +5,12 @@ import scalariform.lexer._ import scalariform.parser._ import scalariform.utils._ +object FormatResult { + + val EMPTY = FormatResult(Map(), Map(), Map()) + +} + case class FormatResult(predecessorFormatting: Map[Token, IntertokenFormatInstruction], inferredNewlineFormatting: Map[Token, IntertokenFormatInstruction], xmlRewrites: Map[Token, String]) { From ad8aef3c8c263cb576405383c0fe11ac6e0acc00 Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Fri, 24 May 2013 15:46:08 +0100 Subject: [PATCH 30/36] Corpus stuff --- .../corpusscan/CorpusScanner.scala | 29 ++++++++++--------- project/plugins.sbt | 2 +- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/misc/src/main/scala/scalariform/corpusscan/CorpusScanner.scala b/misc/src/main/scala/scalariform/corpusscan/CorpusScanner.scala index 2d127a92..143b3deb 100644 --- a/misc/src/main/scala/scalariform/corpusscan/CorpusScanner.scala +++ b/misc/src/main/scala/scalariform/corpusscan/CorpusScanner.scala @@ -1,16 +1,17 @@ package scalariform.corpusscan -import scalariform.lexer.{ Token ⇒ _, _ } -import scalariform.formatter._ -import scalariform.formatter.preferences._ -import scalariform.parser._ -import scala.util.parsing.input._ -import scala.util.parsing.combinator._ import java.io.File + import scala.io.Source -import scalariform.utils.Utils.writeText + import org.apache.commons.io.FileUtils + import scalariform.commandline.ScalaFileWalker +import scalariform.formatter._ +import scalariform.formatter.preferences.FormattingPreferences +import scalariform.lexer._ +import scalariform.parser._ +import scalariform.utils.Utils.writeText sealed trait ParseFault case object TokensDoNotCoverSource extends ParseFault @@ -31,9 +32,9 @@ object CorpusScanner extends SpecificFormatter { val tokens = ScalaLexer.tokenise(source) try { val result = new ScalaParser(tokens.toArray).compilationUnitOrScript() - if (result.tokens != tokens.init) /* drop EOF */ + if (result.tokens != tokens) { Some(BadAstTokens) - else + } else None } catch { case e: ScalaParserException ⇒ Some(UnsuccessfulParse) @@ -66,9 +67,9 @@ object CorpusScanner extends SpecificFormatter { } -object Runner { +object Runner extends App { - val corpusDir = "/home/matt/coding/scala-corpus" + val corpusDir = "/home/matthew/coding/scala-corpus/repos2" // val corpusDir = "/home/matt/scala-corpus" def checkParser() { @@ -93,14 +94,14 @@ object Runner { for (file ← ScalaFileWalker.findScalaFiles(corpusDir)) { print("Formatting: " + file) CorpusScanner.formatFile(file) - val parsed = CorpusScanner.attemptToParse(file) - require(parsed == None, parsed.toString) + val parseFaultOpt = CorpusScanner.attemptToParse(file) + require(parseFaultOpt == None, parseFaultOpt.toString) println() count += 1 } println(count + " files formatted.") } - def main(args: Array[String]) = formatInPlace() + formatInPlace() } diff --git a/project/plugins.sbt b/project/plugins.sbt index a81cb0a0..4a817d0f 100755 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -4,7 +4,7 @@ addSbtPlugin("com.github.retronym" % "sbt-onejar" % "0.8") resolvers += Classpaths.typesafeSnapshots -addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.1.2") +addSbtPlugin("com.typesafe.sbteclipse" % "sbteclipse-plugin" % "2.2.0") addSbtPlugin("com.typesafe.sbt" % "sbt-scalariform" % "1.0.1") From 41c5ca97d3e4eb75584dc591502bb7fc7eb61538 Mon Sep 17 00:00:00 2001 From: Matt Russell Date: Fri, 24 May 2013 15:51:20 +0100 Subject: [PATCH 31/36] Remove long-dead "requires" keyword, fixes #79 --- .../src/main/scala/scalariform/formatter/ScalaFormatter.scala | 4 ++-- scalariform/src/main/scala/scalariform/lexer/Keywords.scala | 3 +-- .../src/main/scala/scalariform/lexer/NewlineInferencer.scala | 2 +- scalariform/src/main/scala/scalariform/lexer/Tokens.scala | 3 +-- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/scalariform/src/main/scala/scalariform/formatter/ScalaFormatter.scala b/scalariform/src/main/scala/scalariform/formatter/ScalaFormatter.scala index 508ad6c1..e6c1792e 100755 --- a/scalariform/src/main/scala/scalariform/formatter/ScalaFormatter.scala +++ b/scalariform/src/main/scala/scalariform/formatter/ScalaFormatter.scala @@ -428,7 +428,7 @@ object ScalaFormatter { FINALLY, FOR, FORSOME, IF, IMPLICIT, IMPORT, LAZY, MATCH, NEW, OBJECT, OVERRIDE, PACKAGE, PRIVATE, PROTECTED, - REQUIRES, RETURN, SEALED, /* SUPER, THIS, */ + RETURN, SEALED, /* SUPER, THIS, */ THROW, TRAIT, TRY, /* TYPE ,*/ VAL, VAR, WHILE, WITH, YIELD, /* USCORE, */ COLON, EQUALS, ARROW, LARROW, SUBTYPE, VIEWBOUND, SUPERTYPE, /* HASH, AT */ @@ -440,7 +440,7 @@ object ScalaFormatter { FINALLY, /* FOR, */ FORSOME, /* IF, */ IMPLICIT, /* IMPORT, */ LAZY, MATCH, /* NEW, */ OBJECT, OVERRIDE, /* PACKAGE, */ PRIVATE, PROTECTED, - /* REQUIRES, RETURN, */ SEALED, /* SUPER, THIS, */ + /* RETURN, */ SEALED, /* SUPER, THIS, */ /* THROW, */ TRAIT, /* TRY, TYPE, */ VAL, VAR, /* WHILE, */ WITH, YIELD, /* USCORE, COLON, */ EQUALS, /* ARROW, */ LARROW, SUBTYPE, VIEWBOUND, SUPERTYPE, /*, HASH, AT, */ diff --git a/scalariform/src/main/scala/scalariform/lexer/Keywords.scala b/scalariform/src/main/scala/scalariform/lexer/Keywords.scala index 552d2f11..1932b4f8 100644 --- a/scalariform/src/main/scala/scalariform/lexer/Keywords.scala +++ b/scalariform/src/main/scala/scalariform/lexer/Keywords.scala @@ -32,7 +32,6 @@ object Keywords { "package" -> PACKAGE, "private" -> PRIVATE, "protected" -> PROTECTED, - "requires" -> REQUIRES, "return" -> RETURN, "sealed" -> SEALED, "super" -> SUPER, @@ -65,4 +64,4 @@ object Keywords { "~" -> TILDE, "!" -> EXCLAMATION) -} \ No newline at end of file +} diff --git a/scalariform/src/main/scala/scalariform/lexer/NewlineInferencer.scala b/scalariform/src/main/scala/scalariform/lexer/NewlineInferencer.scala index a06b508c..b008a602 100644 --- a/scalariform/src/main/scala/scalariform/lexer/NewlineInferencer.scala +++ b/scalariform/src/main/scala/scalariform/lexer/NewlineInferencer.scala @@ -138,7 +138,7 @@ object NewlineInferencer { XML_COMMENT, XML_CDATA, XML_UNPARSED, XML_PROCESSING_INSTRUCTION, USCORE, RPAREN, RBRACKET, RBRACE) private val TOKENS_WHICH_CANNOT_BEGIN_A_STATEMENT: Set[TokenType] = Set( - CATCH, ELSE, EXTENDS, FINALLY, FORSOME, MATCH, REQUIRES, WITH, YIELD, COMMA, DOT, SEMI, COLON, /* USCORE, */ EQUALS, + CATCH, ELSE, EXTENDS, FINALLY, FORSOME, MATCH, WITH, YIELD, COMMA, DOT, SEMI, COLON, /* USCORE, */ EQUALS, ARROW, LARROW, SUBTYPE, VIEWBOUND, SUPERTYPE, HASH, LBRACKET, RPAREN, RBRACKET, RBRACE) private val BLANK_LINE_PATTERN = """(?s).*\n\s*\n.*""" diff --git a/scalariform/src/main/scala/scalariform/lexer/Tokens.scala b/scalariform/src/main/scala/scalariform/lexer/Tokens.scala index 3b2be011..4e7b305a 100644 --- a/scalariform/src/main/scala/scalariform/lexer/Tokens.scala +++ b/scalariform/src/main/scala/scalariform/lexer/Tokens.scala @@ -78,7 +78,6 @@ object Tokens { val SEMI = TokenType("SEMI") val COLON = TokenType("COLON") val OTHERID = TokenType("OTHERID") - val REQUIRES = TokenType("REQUIRES") val NEWLINE = TokenType("NEWLINE") val FINALLY = TokenType("FINALLY") val OVERRIDE = TokenType("OVERRIDE") @@ -105,7 +104,7 @@ object Tokens { FINALLY, FOR, FORSOME, IF, IMPLICIT, IMPORT, LAZY, MATCH, NEW, OBJECT, OVERRIDE, PACKAGE, PRIVATE, PROTECTED, - REQUIRES, RETURN, SEALED, SUPER, THIS, + RETURN, SEALED, SUPER, THIS, THROW, TRAIT, TRY, TYPE, VAL, VAR, WHILE, WITH, YIELD) From 0f2145a3a9a7003b598cc340e3840984da572596 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Mon, 26 Aug 2013 12:08:01 -0700 Subject: [PATCH 32/36] Upgrade to scala-maven-plugin 3.1.5 --- pom.xml | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 2f81b073..e6154056 100644 --- a/pom.xml +++ b/pom.xml @@ -18,7 +18,14 @@ 2.8.0 http://download.scala-ide.org UTF-8 + 3.0.4 + + + ${maven.version} + + + scalariform scalariform.feature @@ -83,9 +90,9 @@ - org.scala-tools - maven-scala-plugin - 2.14 + net.alchim31.maven + scala-maven-plugin + 3.1.5 From 983807b678ad700f6da6abe7bc0002aed2e273ce Mon Sep 17 00:00:00 2001 From: Iulian Dragos Date: Wed, 11 Sep 2013 15:59:32 +0200 Subject: [PATCH 33/36] Switch maven build to Kepler repo. --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index e6154056..af7b627d 100644 --- a/pom.xml +++ b/pom.xml @@ -113,9 +113,9 @@ - galileo + kepler p2 - http://download.eclipse.org/releases/galileo + http://download.eclipse.org/releases/kepler sonatype.release From 3561fae5b159d3bba517db144fc95936502475fc Mon Sep 17 00:00:00 2001 From: Iulian Dragos Date: Wed, 11 Sep 2013 16:00:44 +0200 Subject: [PATCH 34/36] Upgrade Tycho and Scala (default) version. Fixed duplicated entry for the build number plugin. --- pom.xml | 10 +++------- scalariform/pom.xml | 4 ++-- 2 files changed, 5 insertions(+), 9 deletions(-) diff --git a/pom.xml b/pom.xml index af7b627d..35f82c31 100644 --- a/pom.xml +++ b/pom.xml @@ -14,8 +14,8 @@ - 0.12.0 - 2.8.0 + 0.18.1 + 2.10.2 http://download.scala-ide.org UTF-8 3.0.4 @@ -56,15 +56,11 @@ - - org.codehaus.mojo - buildnumber-maven-plugin - 1.1 - org.codehaus.mojo buildnumber-maven-plugin + 1.1 validate diff --git a/scalariform/pom.xml b/scalariform/pom.xml index b5e025e5..2381a734 100644 --- a/scalariform/pom.xml +++ b/scalariform/pom.xml @@ -16,8 +16,8 @@ - org.sonatype.tycho - maven-osgi-compiler-plugin + org.eclipse.tycho + tycho-compiler-plugin ${tycho.version} From 5a20ed225f00eccd8eabbcbd6a6e63fe43b779e4 Mon Sep 17 00:00:00 2001 From: Iulian Dragos Date: Wed, 11 Sep 2013 16:01:36 +0200 Subject: [PATCH 35/36] Removed obsolete release profiles. --- pom.xml | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/pom.xml b/pom.xml index 35f82c31..de438f24 100644 --- a/pom.xml +++ b/pom.xml @@ -129,39 +129,6 @@ - - release-ide-29 - - - scala-toolchain-scalaide-2.0 - Scala Toolchain for Scala IDE 2.0 p2 repository - p2 - http://download.scala-ide.org/incoming-release-29/dependencies/osgi-toolchain - - - - - release-ide-210 - - - scala-toolchain-scalaide-2.1 - Scala Toolchain for Scala IDE 2.0 p2 repository - p2 - http://download.scala-ide.org/incoming-release-210/dependencies/osgi-toolchain - - - - - release-ide-211 - - - scala-toolchain-scalaide-2.1 - Scala Toolchain for Scala IDE 2.0 p2 repository - p2 - http://download.scala-ide.org/incoming-release-211/dependencies/osgi-toolchain - - - scala-2.9.x From 563db390950eace7b8b0953f3d922fc9b6466340 Mon Sep 17 00:00:00 2001 From: Iulian Dragos Date: Fri, 1 Feb 2013 16:04:36 +0100 Subject: [PATCH 36/36] Use vanilla Scala OSGi bundles. Add Scala version suffix to BundleVersion. --- pom.xml | 47 ++++++++++++-------------------- scalariform/META-INF/MANIFEST.MF | 3 +- 2 files changed, 20 insertions(+), 30 deletions(-) diff --git a/pom.xml b/pom.xml index de438f24..e990a1df 100644 --- a/pom.xml +++ b/pom.xml @@ -16,9 +16,11 @@ 0.18.1 2.10.2 - http://download.scala-ide.org UTF-8 3.0.4 + 2.11.0-M5 + 1.0.0-RC5 + 2_10 @@ -81,7 +83,7 @@ tycho-packaging-plugin ${tycho.version} - yyyyMMddHHmm'-${buildNumber}' + '${version.suffix}-'yyyyMMddHHmm'-${buildNumber}' true @@ -129,38 +131,25 @@ - - scala-2.9.x - - - scala-toolchain-2.9.x - Scala Toolchain 2.9.x p2 repository - p2 - ${repo.scala-ide}/scala-eclipse-toolchain-osgi-29x - - - scala-2.10.x - - - scala-toolchain-2.10.x - Scala Toolchain trunk p2 repository - p2 - ${repo.scala-ide}/scala-eclipse-toolchain-osgi-210x - - + + 2_10 + scala-2.11.x - - - scala-toolchain-2.11.x - Scala Toolchain trunk p2 repository - p2 - ${repo.scala-ide}/scala-eclipse-toolchain-osgi-211x - - + + 2.11.0-SNAPSHOT + 2_11 + + + + org.scala-lang.modules + scala-xml_${scala.binary.version} + ${scala.xml.version} + + diff --git a/scalariform/META-INF/MANIFEST.MF b/scalariform/META-INF/MANIFEST.MF index 735b5c2f..fe283350 100644 --- a/scalariform/META-INF/MANIFEST.MF +++ b/scalariform/META-INF/MANIFEST.MF @@ -3,7 +3,8 @@ Bundle-ManifestVersion: 2 Bundle-Name: Scalariform Bundle-SymbolicName: scalariform Bundle-Version: 0.1.5.qualifier -Require-Bundle: org.scala-ide.scala.library +Require-Bundle: org.scala-lang.scala-library +Import-Package: scala.xml.parsing Bundle-ClassPath: . Export-Package: scalariform, scalariform.astselect,