From c7bb8d27e7241e9c67c28dcfa824e036562c1f19 Mon Sep 17 00:00:00 2001 From: Cheng Lian Date: Sun, 3 May 2020 22:18:39 -0700 Subject: [PATCH] Fix a corner case about quoted identifiers containing curly braces (#32) --- .../scala/fix/ExpandRelativeQuotedIdent.scala | 5 ++-- .../scala/fix/ExpandRelativeQuotedIdent.scala | 5 ++-- .../src/main/scala/fix/OrganizeImports.scala | 29 ++++++++++++++----- shared/src/main/scala/fix/QuotedIdent.scala | 1 + 4 files changed, 26 insertions(+), 14 deletions(-) diff --git a/input/src/main/scala/fix/ExpandRelativeQuotedIdent.scala b/input/src/main/scala/fix/ExpandRelativeQuotedIdent.scala index ab46607..d91fe7f 100644 --- a/input/src/main/scala/fix/ExpandRelativeQuotedIdent.scala +++ b/input/src/main/scala/fix/ExpandRelativeQuotedIdent.scala @@ -6,7 +6,6 @@ package fix import QuotedIdent.`a.b` import `a.b`.c +import `a.b`.`{ d }` -object ExpandRelativeQuotedIdent { - val refC = c -} +object ExpandRelativeQuotedIdent diff --git a/output/src/main/scala/fix/ExpandRelativeQuotedIdent.scala b/output/src/main/scala/fix/ExpandRelativeQuotedIdent.scala index 2d5b136..24c79cb 100644 --- a/output/src/main/scala/fix/ExpandRelativeQuotedIdent.scala +++ b/output/src/main/scala/fix/ExpandRelativeQuotedIdent.scala @@ -1,8 +1,7 @@ package fix import fix.QuotedIdent.`a.b` +import fix.QuotedIdent.`a.b`.`{ d }` import fix.QuotedIdent.`a.b`.c -object ExpandRelativeQuotedIdent { - val refC = c -} +object ExpandRelativeQuotedIdent diff --git a/rules/src/main/scala/fix/OrganizeImports.scala b/rules/src/main/scala/fix/OrganizeImports.scala index d35f31c..b83fdf5 100644 --- a/rules/src/main/scala/fix/OrganizeImports.scala +++ b/rules/src/main/scala/fix/OrganizeImports.scala @@ -176,7 +176,7 @@ class OrganizeImports(config: OrganizeImportsConfig) extends SemanticRule("Organ case Explode => explodeImportees(importers) case Keep => importers } - } map coalesceImportees map sortImportees + } map (coalesceImportees _ andThen sortImportees _) config.importsOrder match { case Ascii => @@ -252,17 +252,30 @@ object OrganizeImports { private def prettyPrintImportGroup(group: Seq[Importer]): String = group - .map(fixedImporterSyntax) - .map("import " + _) + .map { i => "import " + fixedImporterSyntax(i) } .mkString("\n") - // Hack: The scalafix pretty-printer decides to add spaces after open and before close braces in + // HACK: The scalafix pretty-printer decides to add spaces after open and before close braces in // imports, i.e., "import a.{ b, c }" instead of "import a.{b, c}". Unfortunately, this behavior // cannot be overriden. This function removes the unwanted spaces as a workaround. - private def fixedImporterSyntax(importer: Importer): String = - importer.syntax - .replace("{ ", "{") - .replace(" }", "}") + private def fixedImporterSyntax(importer: Importer): String = { + // NOTE: We need to check whether the input importer is curly braced first and then replace the + // first "{ " and the last " }" if any. Naive string replacements is not sufficient, e.g., a + // quoted-identifier like "`{ d }`" may cause broken output. + val isCurlyBraced = importer.importees match { + case Importees(_, _ :: _, _, _) => true // At least one rename + case Importees(_, _, _ :: _, _) => true // At least one unimport + case importees if importees.length > 1 => true // Multiple importees + case _ => false + } + + val syntax = importer.syntax + + (isCurlyBraced, syntax lastIndexOfSlice " }") match { + case (true, index) if index > -1 => syntax.patch(index, "}", 2).replaceFirst("\\{ ", "{") + case _ => syntax + } + } @tailrec private def topQualifierOf(term: Term): Term.Name = term match { diff --git a/shared/src/main/scala/fix/QuotedIdent.scala b/shared/src/main/scala/fix/QuotedIdent.scala index b9274bd..ff59d70 100644 --- a/shared/src/main/scala/fix/QuotedIdent.scala +++ b/shared/src/main/scala/fix/QuotedIdent.scala @@ -3,5 +3,6 @@ package fix object QuotedIdent { object `a.b` { object c + object `{ d }` } }