Skip to content

Instantly share code, notes, and snippets.

@bjaglin
Created May 24, 2023 08:19
Show Gist options
  • Save bjaglin/b09ca270e254e0c56dda0f4761b9d4e8 to your computer and use it in GitHub Desktop.
Save bjaglin/b09ca270e254e0c56dda0f4761b9d4e8 to your computer and use it in GitHub Desktop.
commit b10f4f289d0b93741dabb916dbf01168c264ae74
Merge: afb12ac1 596459af
Author: Brice Jaglin <bjaglin@gmail.com>
Date: Tue May 23 23:30:18 2023 +0200
Merge remote-tracking branch 'organize-imports/master' into organize-imports
diff --combined CONTRIBUTING.md
index 3b3f5d92,00000000..2561dc95
mode 100644,000000..100644
--- a/CONTRIBUTING.md
--- /dev/null
++ b/CONTRIBUTING.md
@@@ -1,175 -1,0 +1,176 @@@
# Contributing
Contributions to Scalafix are welcome! This document is a guide to help you get
familiar with the Scalafix build, if you are unsure about anything, don't
hesitate to ask in the [Discord channel](https://discord.gg/8AHaqGx3Qj).
## Modules
- `scalafix-interfaces` Java facade to run rules within an existing JVM instance.
- `scalafix-core/` data structures for rewriting and linting Scala source code.
- `scalafix-reflect/` utilities to compile and classload rules from
configuration.
- `scalafix-rules/` built-in rules such as `RemoveUnused`.
- `scalafix-cli/` command-line interface.
- `scalafix-tests/` projects for unit and integration tests.
- `scalafix-docs/` documentation code for the Scalafix website.
## IntelliJ import
The project should import normally into IntelliJ and there should not be any
false red squiggles. To use the debugger or run tests from within IntelliJ, run
at least once tests through sbt to generate a `BuildInfo` file and property
files for Scalafix testkit.
## Testing
Start the SBT shell with `$ sbt`. The commands below assume you have a running
sbt shell.
```sh
# Fast unit tests for rules, cli, core.
> unit2_13/test
# Integration tests for rules, cli, core. Contains a lot
# of different test suites, so it's recommended to use testOnly
# and/or testQuick.
> integration2_13/test
# Use testWindows to exclude tests that are not expected to succeed
# on that OS.
> unit2_13/testWindows
> integration2_13/testWindows
# Only run tests for built-in rules, using scalafix-testkit.
> expect2_13Target2_13_10/test
# Only run ProcedureSyntax unit tests.
> expect2_13Target2_13_10/testOnly -- -z ProcedureSyntax
```
[sbt-projectmatrix](https://github.com/sbt/sbt-projectmatrix) is used to
generate several sbt projects `expectTargetY` with the same source code,
but for a combination of Scala versions:
- used for compiling the framework and rules (`X`)
- used for compiling and generating SemanticDB files for the test input (`Y`)
Unit tests for rules are written using scalafix-testkit
```
scalafix-tests
|
├── unit # Unit test suites
|
├── integration # Integration test suites
|
+├── shared # Code that is shared between input and unit projects
├── input # Source files to be analyzed and fixed by rules
├── output # Expected output from running rewrite rules
└── expect # Verify expectations defined in input/output using testkit
```
## Formatting
We use scalafix to apply some rules that are configured in .scalafix.conf.
Make sure to run `sbt scalafixAll` to apply those rules.
Be sure to run `scalafmt` (available in the `bin` folder) to ensure code
formatting. `./bin/scalafmt --diff` formats only the files that have changed
from the main branch. You can read more about it at http://scalafmt.org
## Documentation
The scalafix documentation website uses [Docusaurus](https://docusaurus.io/) and
[mdoc](https://github.com/olafurpg/mdoc).
First, make sure you have the [yarn](https://yarnpkg.com/en/) package manager
installed.
Next, start sbt and compile the markdown documentation. The documentation will
re-generate on file save.
```sh
$ sbt
> docs/run -w
```
To view the website in your browser, start the Docusaurus live reload server
```sh
cd website
yarn install
yarn start
```
Consult the Docusaurus website for instructions on how to customize the sidebar
or tweak the landing page.
## Binary Compatibility
To avoid breaking binary compatibility we use
[sbt-version-policy](https://github.com/scalacenter/sbt-version-policy).
Anything under the package `scalafix.internal._` does not have compatibility
restrictions.
Run `sbt versionPolicyCheck` to check for any compatibility issues.
## Publish setup
Scalafix uses [sbt-ci-release](https://github.com/olafurpg/sbt-ci-release) to
automate Sonatype releases. A new SNAPSHOT release is published on every merge
into main. A stable release is published to Maven Central on every git tag.
## Releasing
First, kickstart a CI release to Sonatype by pushing a git tag that correspond to the desired commit
```sh
git fetch && git log origin/main --pretty=oneline # choose the commit hash you want to tag
COMMIT_HASH=14a069a3765739f5540129e8220104b17f233020 # change this variable
VERSION=0.9.15 # change this variable
git tag -af "v$VERSION" $COMMIT_HASH -m "v$VERSION" && git push -f origin v$VERSION
```
While the CI is running, update the release notes at
https://github.com/scalacenter/scalafix/releases
After the CI completes, confirm that the release has successfully finished
```
./bin/test-release.sh $VERSION
```
You may need to update the test-release.sh script to include new cross-build
artifacts (for example a new Scala version).
Next, open a PR to sbt-scalafix that updates the version here
https://github.com/scalacenter/sbt-scalafix/blob/7a4b51ae520c26ab2b09c9bedb6e3962f809ac53/project/Dependencies.scala#L5.
Once the CI for this change is green, merge and push a new git tag to
sbt-scalafix.
Validate that the sbt-scalafix release completed successfully by running the
test-release.sh script in the sbt-scalafix repository.
When scalafix and sbt-scalafix have both completed the release, edit the release
draft in the GitHub web UI to point to the tag that you pushed and then click on
"Publish release".
Confirm that the documentation is advertising the new versions
- https://scalacenter.github.io/scalafix/docs/users/installation.html#sbt
- https://scalacenter.github.io/scalafix/docs/users/installation.html#help
If everything went smoothly, congrats! Tweet about the release and comment on
Discord linking to the release notes.
If something goes wrong for any reason making the artifacts not reach maven,
delete the pushed tag with the following command
```sh
TAG=??? # for example "v0.5.3"
git tag -d $TAG
git push origin :refs/tags/$TAG
```
It's important that the latest tag always has an accompanying release on Maven.
If there is no release matching the latest tag then the docs will point to
scalafix artifacts that cannot be resolved.
diff --combined build.sbt
index 35dc5ca4,881349c1..e2e27af5
--- a/build.sbt
--- a/build.sbt
++ b/build.sbt
@@@ -1,365 -1,153 +1,377 @@@
-lazy val v = _root_.scalafix.sbt.BuildInfo
-lazy val rulesCrossVersions = Seq(v.scala213, v.scala212, v.scala211)
-lazy val scala3Version = "3.2.1"
import Dependencies._
import TargetAxis.TargetProjectMatrix
import sbt.Keys.scalacOptions
inThisBuild(
List(
- organization := "com.github.liancheng",
- homepage := Some(url("https://github.com/liancheng/scalafix-organize-imports")),
- licenses := List("MIT" -> url("https://opensource.org/licenses/MIT")),
- developers := List(
- Developer(
- "liancheng",
- "Cheng Lian",
- "lian.cs.zju@gmail.com",
- url("https://github.com/liancheng")
- )
- ),
- scalacOptions ++= List(
- "-deprecation"
- ),
onLoadMessage := s"Welcome to scalafix ${version.value}",
semanticdbEnabled := true,
- // semanticdbTargetRoot makes it hard to have several input modules
- semanticdbIncludeInJar := true,
- semanticdbVersion := scalafixSemanticdb.revision,
- scalafixDependencies += "com.github.liancheng" %% "organize-imports" % "0.5.0",
- // Super shell output often messes up Scalafix test output.
- useSuperShell := false
semanticdbVersion := scalametaV,
scalafixScalaBinaryVersion := "2.13",
scalafixDependencies += "com.github.liancheng" %% "organize-imports" % "0.5.0"
)
)
-lazy val `scalafix-organize-imports` = project
- .in(file("."))
- .aggregate(
- rules.projectRefs ++
- input.projectRefs ++
- output.projectRefs ++
- tests.projectRefs: _*
Global / cancelable := true
noPublishAndNoMima
// force javac to fork by setting javaHome to get error messages during compilation,
// see https://github.com/sbt/zinc/issues/520
def inferJavaHome() = {
val home = file(sys.props("java.home"))
val actualHome =
if (System.getProperty("java.version").startsWith("1.8")) home.getParentFile
else home
Some(actualHome)
}
lazy val interfaces = projectMatrix
.in(file("scalafix-interfaces"))
.settings(
Compile / resourceGenerators += Def.task {
val props = new java.util.Properties()
props.put("scalafixVersion", version.value)
props.put("scalafixStableVersion", stableVersion.value)
props.put("scalametaVersion", scalametaV)
props.put("scala213", scala213)
props.put("scala212", scala212)
val out =
(Compile / managedResourceDirectories).value.head /
"scalafix-interfaces.properties"
IO.write(props, "Scalafix version constants", out)
List(out)
},
(Compile / javacOptions) ++= List(
"-Xlint:all",
"-Werror"
),
(Compile / doc / javacOptions) := List("-Xdoclint:none"),
(Compile / javaHome) := inferJavaHome(),
(Compile / doc / javaHome) := inferJavaHome(),
libraryDependencies += coursierInterfaces,
moduleName := "scalafix-interfaces",
crossPaths := false,
autoScalaLibrary := false
)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(false)
.disablePlugins(ScalafixPlugin)
lazy val core = projectMatrix
.in(file("scalafix-core"))
.settings(
- publish / skip := true
moduleName := "scalafix-core",
buildInfoSettingsForCore,
libraryDependencies += googleDiff,
libraryDependencies ++= {
if (isScala3.value) {
List(
scalameta
.exclude("com.lihaoyi", "sourcecode_2.13")
.exclude("org.scala-lang.modules", "scala-collection-compat_2.13")
)
} else {
List(
scalameta,
collectionCompat
)
}
},
libraryDependencies += metaconfig
)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(buildScalaVersions)
.enablePlugins(BuildInfoPlugin)
lazy val rules = projectMatrix
.in(file("scalafix-rules"))
.settings(
- moduleName := "organize-imports",
- conflictManager := ConflictManager.strict,
- dependencyOverrides ++= List(
- "org.scala-lang.modules" %% "scala-collection-compat" % "2.1.6",
- "com.lihaoyi" %% "sourcecode" % "0.2.1"
moduleName := "scalafix-rules",
description := "Built-in Scalafix rules",
buildInfoSettingsForRules,
libraryDependencies ++= {
if (!isScala3.value)
List(
"org.scala-lang" % "scala-compiler" % scalaVersion.value,
"org.scala-lang" % "scala-reflect" % scalaVersion.value,
semanticdbScalacCore,
collectionCompat
)
else Nil
}
)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(buildScalaVersions)
.dependsOn(core)
.enablePlugins(BuildInfoPlugin)
lazy val reflect = projectMatrix
.in(file("scalafix-reflect"))
.settings(
moduleName := "scalafix-reflect",
isFullCrossVersion,
libraryDependencies ++= {
if (!isScala3.value)
List(
"org.scala-lang" % "scala-compiler" % scalaVersion.value,
"org.scala-lang" % "scala-reflect" % scalaVersion.value
)
else
List(
"org.scala-lang" %% "scala3-compiler" % scalaVersion.value,
"org.scala-lang" %% "scala3-library" % scalaVersion.value
)
}
)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(buildScalaVersions)
.dependsOn(core)
lazy val cli = projectMatrix
.in(file("scalafix-cli"))
.settings(
moduleName := "scalafix-cli",
isFullCrossVersion,
libraryDependencies ++= Seq(
nailgunServer,
jgit,
commonText
),
- libraryDependencies += "ch.epfl.scala" %% "scalafix-core" % v.scalafixVersion,
- scalacOptions ++= List("-Ywarn-unused"),
- scalafixOnCompile := true
libraryDependencies ++= {
if (!isScala3.value)
Seq(java8Compat)
else
Seq()
},
libraryDependencies ++= {
if (isScala3.value) Seq()
else
Seq(
// metaconfig 0.10.0 shaded pprint but rules built with an old
// scalafix-core must have the original package in the classpath to link
// https://github.com/scalameta/metaconfig/pull/154/files#r794005161
pprint % Runtime
)
},
publishLocalTransitive := Def.taskDyn {
val ref = thisProjectRef.value
publishLocal.all(ScopeFilter(inDependencies(ref)))
}.value
)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(buildScalaVersions)
.dependsOn(reflect, interfaces, rules)
lazy val testkit = projectMatrix
.in(file("scalafix-testkit"))
.settings(
moduleName := "scalafix-testkit",
isFullCrossVersion,
libraryDependencies += googleDiff,
libraryDependencies += scalatestDep.value
)
.defaultAxes(VirtualAxis.jvm)
- .jvmPlatform(rulesCrossVersions)
.jvmPlatform(buildScalaVersions)
.dependsOn(cli)
lazy val shared = projectMatrix
+ .in(file("scalafix-tests/shared"))
.settings(
- publish / skip := true,
+ noPublishAndNoMima,
coverageEnabled := false
)
.defaultAxes(VirtualAxis.jvm)
- .jvmPlatform(scalaVersions = rulesCrossVersions :+ scala3Version)
+ .jvmPlatformFull(buildWithTargetVersions.map(_._2))
+ .disablePlugins(ScalafixPlugin)
lazy val input = projectMatrix
- .dependsOn(shared)
.in(file("scalafix-tests/input"))
.settings(
- publish / skip := true,
noPublishAndNoMima,
scalacOptions ~= (_.filterNot(_ == "-Yno-adapted-args")),
scalacOptions ++= warnAdaptedArgs.value, // For NoAutoTupling
scalacOptions ++= warnUnusedImports.value, // For RemoveUnused
scalacOptions ++= warnUnused.value, // For RemoveUnusedTerms
logLevel := Level.Error, // avoid flood of compiler warnings
libraryDependencies ++= testsDependencies.value,
coverageEnabled := false
)
.defaultAxes(VirtualAxis.jvm)
- .jvmPlatform(scalaVersions = rulesCrossVersions :+ scala3Version)
.jvmPlatformFull(buildWithTargetVersions.map(_._2))
.disablePlugins(ScalafixPlugin)
+ .dependsOn(shared)
lazy val output = projectMatrix
- .dependsOn(shared)
.in(file("scalafix-tests/output"))
.settings(
- publish / skip := true,
noPublishAndNoMima,
scalacOptions --= warnUnusedImports.value,
libraryDependencies ++= testsDependencies.value,
coverageEnabled := false
)
.defaultAxes(VirtualAxis.jvm)
- .jvmPlatform(scalaVersions = rulesCrossVersions :+ scala3Version)
-
-lazy val inputUnusedImports = projectMatrix
.jvmPlatform(buildScalaVersions)
.disablePlugins(ScalafixPlugin)
.dependsOn(shared)
lazy val unit = projectMatrix
.in(file("scalafix-tests/unit"))
.settings(
- publish / skip := true,
- coverageEnabled := false,
- scalacOptions += {
- if (scalaVersion.value.startsWith("2.11."))
- "-Ywarn-unused-import"
- else
- "-Ywarn-unused"
noPublishAndNoMima,
libraryDependencies ++= List(
jgit,
munit,
scalatest.withRevision(scalatestLatestV)
),
libraryDependencies += {
if (!isScala3.value) {
scalametaTeskit
} else {
// exclude _2.13 artifacts that have their _3 counterpart in the classpath
scalametaTeskit
.exclude("com.lihaoyi", "sourcecode_2.13")
.exclude("org.scala-lang.modules", "scala-collection-compat_2.13")
.exclude("org.scalameta", "munit_2.13")
}
},
buildInfoPackage := "scalafix.tests",
buildInfoKeys := Seq[BuildInfoKey](
"scalaVersion" -> scalaVersion.value
)
)
.defaultAxes(VirtualAxis.jvm)
- .jvmPlatform(scalaVersions = rulesCrossVersions :+ scala3Version)
.jvmPlatform(buildScalaVersions)
.enablePlugins(BuildInfoPlugin)
.dependsOn(testkit % Test)
-lazy val testsAggregate = Project("tests", file("target/testsAggregate"))
- .aggregate(tests.projectRefs: _*)
-
-lazy val tests = projectMatrix
- .dependsOn(rules)
- .enablePlugins(ScalafixTestkitPlugin)
lazy val integration = projectMatrix
.in(file("scalafix-tests/integration"))
.settings(
- publish / skip := true,
- coverageEnabled := false,
- libraryDependencies +=
- "ch.epfl.scala" % "scalafix-testkit" % v.scalafixVersion % Test cross CrossVersion.full,
- scalafixTestkitOutputSourceDirectories :=
- TargetAxis.resolve(output, Compile / unmanagedSourceDirectories).value,
- scalafixTestkitInputSourceDirectories := {
- val inputSrc =
- TargetAxis.resolve(input, Compile / unmanagedSourceDirectories).value
- val inputUnusedImportsSrc =
- TargetAxis.resolve(inputUnusedImports, Compile / unmanagedSourceDirectories).value
- inputSrc ++ inputUnusedImportsSrc
noPublishAndNoMima,
Test / parallelExecution := false,
libraryDependencies += {
if (!isScala3.value) {
coursier
} else {
// exclude _2.13 artifacts that have their _3 counterpart in the classpath
coursier
.exclude("org.scala-lang.modules", "scala-xml_2.13")
.exclude("org.scala-lang.modules", "scala-collection-compat_2.13")
}
},
- scalafixTestkitInputClasspath := {
- val inputClasspath =
- TargetAxis.resolve(input, Compile / fullClasspath).value
- val inputUnusedImportsClasspath =
- TargetAxis.resolve(inputUnusedImports, Compile / fullClasspath).value
- inputClasspath ++ inputUnusedImportsClasspath
buildInfoPackage := "scalafix.tests",
buildInfoObject := "BuildInfo",
// create a local alias for input / Compile / fullClasspath at an
// arbitrary, unused scope to be able to reference it (as a TaskKey) in
// buildInfoKeys (since the macro only accepts TaskKeys)
buildInfoKeys / fullClasspath :=
resolve(input, Compile / fullClasspath).value,
buildInfoKeys := Seq[BuildInfoKey](
"scalametaVersion" -> scalametaV,
"scalaVersion" -> scalaVersion.value,
"baseDirectory" ->
(ThisBuild / baseDirectory).value,
"resourceDirectory" ->
(Compile / resourceDirectory).value,
"semanticClasspath" ->
Seq((Compile / semanticdbTargetRoot).value),
"sourceroot" ->
(Compile / sourceDirectory).value,
"classDirectory" ->
(Compile / classDirectory).value,
BuildInfoKey.map(buildInfoKeys / fullClasspath) { case (_, v) =>
"inputClasspath" -> v
},
- scalafixTestkitInputScalacOptions :=
- TargetAxis.resolve(inputUnusedImports, Compile / scalacOptions).value,
- scalafixTestkitInputScalaVersion :=
- TargetAxis.resolve(inputUnusedImports, Compile / scalaVersion).value
"inputSemanticClasspath" ->
Seq(resolve(input, Compile / semanticdbTargetRoot).value),
"inputSourceroot" ->
resolve(input, Compile / sourceDirectory).value,
"outputSourceroot" ->
resolve(output, Compile / sourceDirectory).value
),
Test / test := (Test / test)
.dependsOn(cli.projectRefs.map(_ / publishLocalTransitive): _*)
.value,
Test / testWindows := (Test / testWindows)
.dependsOn(cli.projectRefs.map(_ / publishLocalTransitive): _*)
.value
)
- .defaultAxes(
- rulesCrossVersions.map(VirtualAxis.scalaABIVersion) :+ VirtualAxis.jvm: _*
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(buildScalaVersions)
.enablePlugins(BuildInfoPlugin)
.dependsOn(unit % "compile->test")
lazy val expect = projectMatrix
.in(file("scalafix-tests/expect"))
.settings(
noPublishAndNoMima,
Test / resourceGenerators += Def.task {
// make sure the output can be compiled
val _ = TargetAxis.resolve(output, Compile / compile).value
// copy-pasted code from ScalafixTestkitPlugin to avoid cyclic dependencies between build and sbt-scalafix.
val props = new java.util.Properties()
def put(key: String, files: Seq[File]): Unit = {
val value = files.iterator
.filter(_.exists())
.mkString(java.io.File.pathSeparator)
props.put(key, value)
}
put(
"inputClasspath",
TargetAxis
.resolve(input, Compile / fullClasspath)
.value
.map(_.data)
)
put(
"inputSourceDirectories",
TargetAxis
.resolve(input, Compile / unmanagedSourceDirectories)
.value
)
- .customRow(
- scalaVersions = Seq(v.scala212),
- axisValues = Seq(TargetAxis(scala3Version), VirtualAxis.jvm),
- settings = Seq()
put(
"outputSourceDirectories",
TargetAxis
.resolve(output, Compile / unmanagedSourceDirectories)
.value
)
- .customRow(
- scalaVersions = Seq(v.scala213),
- axisValues = Seq(TargetAxis(v.scala213), VirtualAxis.jvm),
- settings = Seq()
props.put(
"scalaVersion",
TargetAxis.resolve(input, Compile / scalaVersion).value
)
- .customRow(
- scalaVersions = Seq(v.scala212),
- axisValues = Seq(TargetAxis(v.scala212), VirtualAxis.jvm),
- settings = Seq()
props.put(
"scalacOptions",
TargetAxis
.resolve(input, Compile / scalacOptions)
.value
.mkString("|")
)
val out =
(Test / managedResourceDirectories).value.head /
"scalafix-testkit.properties"
IO.write(props, "Input data for scalafix testkit", out)
List(out)
}
)
- .customRow(
- scalaVersions = Seq(v.scala211),
- axisValues = Seq(TargetAxis(v.scala211), VirtualAxis.jvm),
- settings = Seq()
.defaultAxes(VirtualAxis.jvm)
.jvmPlatformWithTargets(buildWithTargetVersions)
.dependsOn(integration)
lazy val docs = projectMatrix
.in(file("scalafix-docs"))
.settings(
noPublishAndNoMima,
fork := true,
run / baseDirectory := (ThisBuild / baseDirectory).value,
moduleName := "scalafix-docs",
scalacOptions += "-Wconf:msg='match may not be exhaustive':s", // silence exhaustive pattern matching warning for documentation
scalacOptions += "-Xfatal-warnings",
mdoc := (Compile / run).evaluated,
libraryDependencies += metaconfigDoc
)
.defaultAxes(VirtualAxis.jvm)
.jvmPlatform(scalaVersions = Seq(scala213))
.dependsOn(testkit, core, cli)
.enablePlugins(DocusaurusPlugin)
.disablePlugins(ScalafixPlugin)
diff --combined docs/rules/OrganizeImports.md
index 00000000,908b190f..05844bf0
mode 000000,100644..100644
--- /dev/null
--- a/README.adoc
++ b/docs/rules/OrganizeImports.md
@@@ -1,0 -1,1393 +1,1330 @@@
-:latest-release: 0.6.0
-
-ifdef::env-github[]
-:caution-caption: :construction:
-:important-caption: :exclamation:
-:warning-caption: :warning:
-:tip-caption: :bulb:
-:note-caption: :notebook:
-endif::[]
-
-= OrganizeImports
-:icons: font
-:sectnums:
-:toc-placement!:
-:toc-title:
-:toc:
-:toclevels: 2
-
-image:https://github.com/liancheng/scalafix-organize-imports/workflows/Build/badge.svg[]
-https://github.com/liancheng/scalafix-organize-imports/releases/latest[image:https://img.shields.io/github/v/tag/liancheng/scalafix-organize-imports[]]
-https://github.com/liancheng/scalafix-organize-imports/blob/master/LICENSE[image:https://img.shields.io/github/license/liancheng/scalafix-organize-imports[]]
-https://scala-steward.org[image:https://img.shields.io/badge/Scala_Steward-helping-blue.svg[]]
-https://codecov.io/gh/liancheng/scalafix-organize-imports[image:https://img.shields.io/codecov/c/github/liancheng/scalafix-organize-imports[]]
-
-toc::[]
-
-`OrganizeImports` is a CI-friendly https://scalacenter.github.io/scalafix[Scalafix] semantic rule that helps you organize Scala import statements.
-
-https://scalameta.org/metals/[Metals], the Scala language server, also uses `OrganizeImports` to power its "organize imports" code action starting from version https://scalameta.org/metals/blog/2020/11/10/lithium.html#organize-imports-code-action[v0.9.5].
-
-image:https://i.imgur.com/8YBdjjC.gif[]
-
-== Getting started
-
-=== sbt
-
-Please refer to https://scalacenter.github.io/scalafix/docs/users/installation.html[the Scalafix documentation] for how to install Scalafix and invoking it in your sbt build.
-
-To try this rule in the sbt console without adding this rule to your sbt build:
-
-[source,subs="attributes+"]
-----
-sbt> scalafix dependency:OrganizeImports@com.github.liancheng:organize-imports:{latest-release}
-----
-
-To include this rule in your sbt build:
-
-[source,scala,subs="attributes+"]
-----
-ThisBuild / scalafixDependencies += "com.github.liancheng" %% "organize-imports" % "{latest-release}"
-----
-
-=== Mill
-
-You can also include this rule in your http://www.lihaoyi.com/mill/[Mill] build using https://github.com/joan38/mill-scalafix[mill-scalafix]:
-
-[source,scala,subs="attributes+"]
-----
-def scalafixIvyDeps = Agg(ivy"com.github.liancheng::organize-imports:{latest-release}")
-----
-
-=== For IntelliJ Scala plugin users
-
-`OrganizeImports` allows you to specify a preset style via the <<preset, `preset` option>>. To make it easier to add `OrganizeImports` into existing Scala projects built using the IntelliJ Scala plugin, `OrganizeImports` provides a preset style compatible with the default configuration of the IntelliJ Scala import optimizer. Please check the <<intellij-2020-3, `INTELLIJ_2020_3`>> preset style for more details.
-
-=== Source formatting tools
-
-The `OrganizeImports` rule respects source-formatting tools like https://scalameta.org/scalafmt/[Scalafmt]. If an import statement is already organized according to the configuration, its original source level format is preserved. Therefore, in an sbt project, if you run the following command sequence:
-
-[source]
-----
+---
+id: OrganizeImports
+title: OrganizeImports
+---
+
+OrganizeImports was originally a [community rule](https://github.com/liancheng/scalafix-organize-imports),
+created and maintained by [Cheng Lian](https://github.com/liancheng).
+Considering its [popularity, maturity and the lack of bandwidth from the
+author](https://github.com/liancheng/scalafix-organize-imports/discussions/215),
+it is now a built-in rule, since Scalafix 0.11.0.
+
+Getting started
+---------------
+
+### For IntelliJ Scala plugin users
+
+`OrganizeImports` allows you to specify a preset style via the [`preset`
+option](#preset). To make it easier to add `OrganizeImports` into
+existing Scala projects built using the IntelliJ Scala plugin,
+`OrganizeImports` provides a preset style compatible with the default
+configuration of the IntelliJ Scala import optimizer. Please check the
+[`INTELLIJ_2020_3`](#intellij-2020-3) preset style for more details.
+
+### Source formatting tools
+
+The `OrganizeImports` rule respects source-formatting tools like
+[Scalafmt](https://scalameta.org/scalafmt/). If an import statement is
+already organized according to the configuration, its original source
+level format is preserved. Therefore, in an sbt project, if you run the
+following command sequence:
+
+```
sbt> scalafixAll
...
sbt> scalafmtAll
...
sbt> scalafixAll --check
...
-----
+```
-Assuming that the first two commands run successfully, the last `scalafixAll --check` command should not fail even if some import statements are reformatted by the `scalafmtAll` command.
+Assuming that the first two commands run successfully, the last
+`scalafixAll --check` command should not fail even if some import
+statements are reformatted by the `scalafmtAll` command.
-However, you should make sure that the source-formatting tools you use do not rewrite import statements in ways that conflict with `OrganizeImports`. For example, when using Scalafmt together with `OrganizeImports`, the `ExpandImportSelectors`, `SortImports`, and `AsciiSortImports` rewriting rules should not be used.
+However, you should make sure that the source-formatting tools you use
+do not rewrite import statements in ways that conflict with
+`OrganizeImports`. For example, when using Scalafmt together with
+`OrganizeImports`, the `ExpandImportSelectors`, `SortImports`, and
+`AsciiSortImports` rewriting rules should not be used.
-=== Scala 3
-
-Available since v0.6.0.
-
-Running the rule on source files compiled with Scala 3 is still experimental.
+### Scala 3
Known limitations:
-. You must use Scalafix 0.9.28 or later
-. The <<removeUnused, `removeUnused`>> option must be explicitly set to `false` - the rule currently doesn't remove unused imports as it's currently not supported by the compiler.
-. Usage of http://dotty.epfl.ch/docs/reference/dropped-features/package-objects.html[deprecated package objects] may result in incorrect imports
-. The <<groupExplicitlyImportedImplicitsSeparately, groupExplicitlyImportedImplicitsSeparately>> option has no effect
-
-== Configuration
-
-=== Default Configuration values
-
-[source,hocon,subs=+macros]
-----
-OrganizeImports {
- <<blankLines, blankLines>> = Auto
- <<coalesceToWildcardImportThreshold, coalesceToWildcardImportThreshold>> = null
- <<expandRelative, expandRelative>> = false
- <<groupExplicitlyImportedImplicitsSeparately, groupExplicitlyImportedImplicitsSeparately>> = false
- <<groupedImports, groupedImports>> = Explode
- <<groups, groups>> = [
- "*"
- "re:(javax?|scala)\\."
- ]
- <<importSelectorsOrder, importSelectorsOrder>> = Ascii
- <<importsOrder, importsOrder>> = Ascii
- <<preset, preset>> = DEFAULT
- <<removeUnused, removeUnused>> = true
-}
-----
-
-[[remove-unused-warning]]
-[WARNING]
-====
-Please do NOT use the Scalafix built-in https://scalacenter.github.io/scalafix/docs/rules/RemoveUnused.html[`RemoveUnused.imports`] together with `OrganizeImports` to remove unused imports. You may end up with broken code! It is still safe to use `RemoveUnused` to remove unused private members or local definitions, though.
-
-Scalafix rewrites source files by applying patches generated by invoked rules. Each rule generates a patch based on the _original_ text of the source files. When two patches generated by different rules conflict with each other, Scalafix is not able to reconcile the conflicts, and may produce broken code. It is very likely to happen when `RemoveUnused` and `OrganizeImports` are used together, since both rules rewrite import statements.
-
-By default, `OrganizeImports` already removes unused imports for you (see the <<removeUnused, `removeUnused`>> option). It locates unused imports via compilation diagnostics, which is exactly how `RemoveUnused` does it. This mechanism works well in most cases, unless there are new unused imports generated while organizing imports, which is possible when the <<expandRelative, `expandRelative`>> option is set to true. For now, the only reliable workaround for this edge case is to run Scalafix with `OrganizeImports` twice.
-====
-
-[[blankLines]]
-=== `blankLines`
-
-Available since v0.5.0-alpha.1.
-
-Configures whether blank lines between adjacent import groups are automatically or manually inserted. This option is used together with the <<blank-line-marker, `---` blank line markers>>.
-
-==== Value type
+1. The [`removeUnused`](OrganizeImports.md#removeunused) option must be
+ explicitly set to `false` - the rule currently doesn’t remove unused
+ imports as it is currently not supported by the compiler.
+
+2. Usage of [deprecated package
+ objects](http://dotty.epfl.ch/docs/reference/dropped-features/package-objects.html)
+ may result in incorrect imports.
+
+3. The
+ [`groupExplicitlyImportedImplicitsSeparately`](OrganizeImports.md#groupexplicitlyimportedimplicitsseparately)
+ option has no effect.
+
+Configuration
+-------------
+
+> Please do NOT use the [`RemoveUnused.imports`](RemoveUnused.md) together with
+> `OrganizeImports` to remove unused imports. You may end up with broken code!
+> It is still safe to use `RemoveUnused` to remove unused private members or
+> local definitions, though.
+>
+> Scalafix rewrites source files by applying patches generated by invoked
+> rules. Each rule generates a patch based on the *original* text of the
+> source files. When two patches generated by different rules conflict
+> with each other, Scalafix is not able to reconcile the conflicts, and
+> may produce broken code. It is very likely to happen when `RemoveUnused`
+> and `OrganizeImports` are used together, since both rules rewrite import
+> statements.
+>
+> By default, `OrganizeImports` already removes unused imports for you
+> (see the [`removeUnused`](OrganizeImports.md#removeunused) option). It locates unused
+> imports via compilation diagnostics, which is exactly how `RemoveUnused`
+> does it. This mechanism works well in most cases, unless there are new
+> unused imports generated while organizing imports, which is possible
+> when the [`expandRelative`](OrganizeImports.md#expandrelative) option is set to true. For
+> now, the only reliable workaround for this edge case is to run Scalafix
+> with `OrganizeImports` twice.
+
+```scala mdoc:passthrough
+import scalafix.internal.rule._
+import scalafix.website._
+```
+
+```scala mdoc:passthrough
+println(
+ defaults(
+ "OrganizeImports",
+ flat(OrganizeImportsConfig.default)
+ )
+)
+```
+
+`blankLines`
+------------
+
+Configures whether blank lines between adjacent import groups are
+automatically or manually inserted. This option is used together with
+the [`---` blank line markers](OrganizeImports.md#a-blank-line-marker).
+
+### Value type
Enum: `Auto | Manual`
-Auto:: A blank line is automatically inserted between adjacent import groups. All blank line markers (`---`) configured in the <<groups, `groups` option>> are ignored.
+#### `Auto`
+A blank line is automatically inserted between adjacent import groups.
+All blank line markers (`---`) configured in the [`groups`
+option](#groups) are ignored.
-Manual:: A blank line is inserted at all the positions where blank line markers appear in the <<groups, `groups` option>>.
+#### `Manual`
+A blank line is inserted at all the positions where blank line markers
+appear in the [`groups` option](#groups).
The following two configurations are equivalent:
-[source,hocon]
-----
+```conf
OrganizeImports {
blankLines = Auto
groups = [
"re:javax?\\."
"scala."
"*"
]
}
+```
+```conf
OrganizeImports {
blankLines = Manual
groups = [
"re:javax?\\."
"---"
"scala."
"---"
"*"
]
}
-----
+```
-==== Default value
+### Default value
`Auto`
-==== Examples
+### Examples
-`Auto`::
-+
---
-Configuration:
+#### `Auto`
-[source,hocon]
-----
+```conf
OrganizeImports {
blankLines = Auto
groups = [
"re:javax?\\."
"scala."
"*"
]
}
-----
+```
Before:
-[source,scala]
-----
+```scala
import scala.collection.JavaConverters._
import java.time.Clock
import sun.misc.BASE64Encoder
import javax.annotation.Generated
import scala.concurrent.ExecutionContext
-----
+```
After:
-[source,scala]
-----
+```scala
import java.time.Clock
import javax.annotation.Generated
import scala.collection.JavaConverters._
import scala.concurrent.ExecutionContext
import sun.misc.BASE64Encoder
-----
---
+```
-`Manual`::
-+
---
-Configuration:
+#### `Manual`
-[source,hocon]
-----
+```conf
OrganizeImports {
blankLines = Manual
groups = [
"re:javax?\\."
"scala."
"---"
"*"
]
}
-----
+```
Before:
-[source,scala]
-----
+```scala
import scala.collection.JavaConverters._
import java.time.Clock
import sun.misc.BASE64Encoder
import javax.annotation.Generated
import scala.concurrent.ExecutionContext
-----
+```
After:
-[source,scala]
-----
+```scala
import java.time.Clock
import javax.annotation.Generated
import scala.collection.JavaConverters._
import scala.concurrent.ExecutionContext
import sun.misc.BASE64Encoder
-----
---
-
-[[coalesceToWildcardImportThreshold]]
-=== `coalesceToWildcardImportThreshold`
-
-When the number of imported names exceeds a certain threshold, coalesce them into a wildcard import. Renames and unimports are left untouched.
-
-[CAUTION]
-====
-Having this feature in `OrganizeImports` is mostly for feature parity with the IntelliJ IDEA Scala import optimizer, but coalescing grouped import selectors into a wildcard import may introduce _compilation errors_!
-
-Here is an example to illustrate the risk. The following snippet compiles successfully:
-
-[source,scala]
-----
-import scala.collection.immutable._
-import scala.collection.mutable.{ArrayBuffer, Map, Set}
-
-object Example {
- val m: Map[Int, Int] = ???
-}
-----
-The type of `Example.m` above is not ambiguous because the mutable `Map` explicitly imported in the second import takes higher precedence than the immutable `Map` imported via wildcard in the first import.
-
-However, if we coalesce the grouped imports in the second import statement into a wildcard, there will be a compilation error:
-[source,scala]
-----
-import scala.collection.immutable._
-import scala.collection.mutable._
-
-object Example {
- val m: Map[Int, Int] = ???
-}
-----
-This is because the type of `Example.m` becomes ambiguous now since both the mutable and immutable `Map` are imported via a wildcard and have the same precedence.
-====
-
-==== Value type
+```
+
+`coalesceToWildcardImportThreshold`
+-----------------------------------
+
+When the number of imported names exceeds a certain threshold, coalesce
+them into a wildcard import. Renames and unimports are left untouched.
+
+> Having this feature in `OrganizeImports` is mostly for feature parity
+> with the IntelliJ IDEA Scala import optimizer, but coalescing grouped
+> import selectors into a wildcard import may introduce *compilation
+> errors*!
+>
+> Here is an example to illustrate the risk. The following snippet
+> compiles successfully:
+>
+> ```scala
+> import scala.collection.immutable._
+> import scala.collection.mutable.{ArrayBuffer, Map, Set}
+>
+> object Example {
+> val m: Map[Int, Int] = ???
+> }
+> ```
+>
+> The type of `Example.m` above is not ambiguous because the mutable `Map`
+> explicitly imported in the second import takes higher precedence than
+> the immutable `Map` imported via wildcard in the first import.
+>
+> However, if we coalesce the grouped imports in the second import
+> statement into a wildcard, there will be a compilation error:
+>
+> ```scala
+> import scala.collection.immutable._
+> import scala.collection.mutable._
+>
+> object Example {
+> val m: Map[Int, Int] = ???
+> }
+> ```
+>
+> This is because the type of `Example.m` becomes ambiguous now since both
+> the mutable and immutable `Map` are imported via a wildcard and have the
+> same precedence.
+
+### Value type
Integer. Not setting it or setting it to `null` disables this feature.
-==== Default value
+### Default value
`null`
-==== Examples
+### Examples
-Configuration:
-
-[source,scala]
-----
+```conf
OrganizeImports {
groupedImports = Keep
coalesceToWildcardImportThreshold = 3
}
-----
+```
Before:
-[source,scala]
-----
+```scala
import scala.collection.immutable.{Seq, Map, Vector, Set}
import scala.collection.immutable.{Seq, Map, Vector}
import scala.collection.immutable.{Seq, Map, Vector => Vec, Set, Stream}
import scala.collection.immutable.{Seq, Map, Vector => _, Set, Stream}
-----
+```
After:
-[source,scala]
-----
+```scala
import scala.collection.immutable._
import scala.collection.immutable.{Map, Seq, Vector}
import scala.collection.immutable.{Vector => Vec, _}
import scala.collection.immutable.{Vector => _, _}
-----
+```
-[[expandRelative]]
-=== `expandRelative`
+`expandRelative`
+----------------
Expand relative imports into fully-qualified one.
-[CAUTION]
-====
-Expanding relative imports may introduce new unused imports. For instance, relative imports in the following snippet
+> Expanding relative imports may introduce new unused imports. For
+> instance, relative imports in the following snippet
+>
+> ```scala
+> import scala.util
+> import util.control
+> import control.NonFatal
+> ```
+>
+> are expanded into
+>
+> ```scala
+> import scala.util
+> import scala.util.control
+> import scala.util.control.NonFatal
+> ```
+>
+> If neither `scala.util` nor `scala.util.control` is referenced anywhere
+> after the expansion, they become unused imports.
+>
+> Unfortunately, these newly introduced unused imports cannot be removed
+> by setting `removeUnused` to `true`. Please refer to the
+> [`removeUnused`](OrganizeImports.md#removeunused) option for more details.
-[source,scala]
-----
-import scala.util
-import util.control
-import control.NonFatal
-----
-
-are expanded into
-
-[source,scala]
-----
-import scala.util
-import scala.util.control
-import scala.util.control.NonFatal
-----
-
-If neither `scala.util` nor `scala.util.control` is referenced anywhere after the expansion, they become unused imports.
-
-Unfortunately, these newly introduced unused imports cannot be removed by setting `removeUnused` to `true`. Please refer to the <<removeUnused, `removeUnused`>> option for more details.
-====
-
-==== Value type
+### Value type
Boolean
-==== Default value
+### Default value
`false`
-==== Examples
+### Examples
-Configuration:
-
-[source,hocon]
-----
+```conf
OrganizeImports {
expandRelative = true
groups = ["re:javax?\\.", "scala.", "*"]
}
-----
+```
Before:
-[source,scala]
-----
+```scala
import scala.util
import util.control
import control.NonFatal
import scala.collection.JavaConverters._
import java.time.Clock
import sun.misc.BASE64Encoder
import javax.annotation.Generated
import scala.concurrent.ExecutionContext
-----
+```
After:
-[source,scala]
-----
+```scala
import java.time.Clock
import javax.annotation.Generated
import scala.collection.JavaConverters._
import scala.concurrent.ExecutionContext
import scala.util
import scala.util.control
import scala.util.control.NonFatal
import sun.misc.BASE64Encoder
-----
+```
-[[groupExplicitlyImportedImplicitsSeparately]]
-=== `groupExplicitlyImportedImplicitsSeparately`
+`groupExplicitlyImportedImplicitsSeparately`
+--------------------------------------------
-This option provides a workaround to a subtle and rarely seen correctness issue related to explicitly imported implicit names.
+This option provides a workaround to a subtle and rarely seen
+correctness issue related to explicitly imported implicit names.
The following snippet helps illustrate the problem:
-[source,scala]
-----
+```scala
package a
import c._
import b.i
object b { implicit def i: Int = 1 }
object c { implicit def i: Int = 2 }
object Imports {
def f()(implicit i: Int) = println(1)
def main() = f()
}
-----
+```
-The above snippet compiles successfully and outputs `1`, because the explicitly imported implicit value `b.i` overrides `c.i`, which is made available via a wildcard import. However, if we reorder the two imports into:
+The above snippet compiles successfully and outputs `1`, because the
+explicitly imported implicit value `b.i` overrides `c.i`, which is made
+available via a wildcard import. However, if we reorder the two imports
+into:
-[source,scala]
-----
+```scala
import b.i
import c._
-----
+```
The Scala compiler starts complaining:
-----
+```
error: could not find implicit value for parameter i: Int
def main() = f()
^
-----
+```
-This behavior could be due to a Scala compiler bug since https://scala-lang.org/files/archive/spec/2.13/02-identifiers-names-and-scopes.html[the Scala language specification] requires that explicitly imported names should have higher precedence than names made available via a wildcard.
+This behavior could be due to a Scala compiler bug since [the Scala
+language
+specification](https://scala-lang.org/files/archive/spec/2.13/02-identifiers-names-and-scopes.html)
+requires that explicitly imported names should have higher precedence
+than names made available via a wildcard.
-Unfortunately, Scalafix is not able to surgically identify conflicting implicit values behind a wildcard import. In order to guarantee correctness in all cases, when the `groupExplicitlyImportedImplicitsSeparately` option is set to `true`, all explicitly imported implicit names are moved into the trailing order-preserving import group together with relative imports, if any (see the <<trailing-order-preserving-import-group, trailing order-preserving import group>> section for more details).
+Unfortunately, Scalafix is not able to surgically identify conflicting
+implicit values behind a wildcard import. In order to guarantee
+correctness in all cases, when the
+`groupExplicitlyImportedImplicitsSeparately` option is set to `true`,
+all explicitly imported implicit names are moved into the trailing
+order-preserving import group together with relative imports, if any
+(see the [trailing order-preserving import
+group](OrganizeImports.md#groups) section for more
+details).
-CAUTION: In general, order-sensitive imports are fragile, and can easily be broken by either human collaborators or tools (e.g., the IntelliJ IDEA Scala import optimizer does not handle this case correctly). They should be eliminated whenever possible. This option is mostly useful when you are dealing with a large trunk of legacy codebase, and you want to minimize manual intervention and guarantee correctness in all cases.
+> In general, order-sensitive imports are fragile, and can easily be
+> broken by either human collaborators or tools (e.g., the IntelliJ IDEA
+> Scala import optimizer does not handle this case correctly). They should
+> be eliminated whenever possible. This option is mostly useful when you
+> are dealing with a large trunk of legacy codebase, and you want to
+> minimize manual intervention and guarantee correctness in all cases.
+> The `groupExplicitlyImportedImplicitsSeparately` option has currently no
+> effect on source files compiled with Scala 3, as the [compiler does not
+> expose full signature
+> information](https://github.com/lampepfl/dotty/issues/12766), preventing
+> the rule to identify imported implicits.
-[IMPORTANT]
-====
-The `groupExplicitlyImportedImplicitsSeparately` option has currently no effect on source files compiled with Scala 3, as the https://github.com/lampepfl/dotty/issues/12766[compiler does not expose full signature information], preventing the rule to identify imported implicits.
-====
-
-
-==== Value type
+### Value type
Boolean
-==== Default value
+### Default value
`false`
-Rationale::
-+
---
-This option defaults to `false` due to the following reasons:
+Rationale:
-. Although setting it to `true` avoids the aforementioned correctness issue, the result is unintuitive and confusing for many users since it looks like the `groups` option is not respected.
-+
-E.g., why my `scala.concurrent.ExecutionContext.Implicits.global` import is moved to a separate group even if I have a `scala.` group defined in the `groups` option?
+1. Although setting it to `true` avoids the aforementioned correctness
+ issue, the result is unintuitive and confusing for many users since
+ it looks like the `groups` option is not respected.
-. The concerned correctness issue is rarely seen in real life. When it really happens, it is usually a sign of bad coding style, and you may want to tweak your imports to eliminate the root cause.
---
+ E.g., why my `scala.concurrent.ExecutionContext.Implicits.global`
+ import is moved to a separate group even if I have a `scala.` group
+ defined in the `groups` option?
-==== Examples
+2. The concerned correctness issue is rarely seen in real life. When it
+ really happens, it is usually a sign of bad coding style, and you
+ may want to tweak your imports to eliminate the root cause.
-Configuration:
+### Examples
-[source,hocon]
-----
+```conf
OrganizeImports {
groups = ["scala.", "*"]
groupExplicitlyImportedImplicitsSeparately = true // not supported in Scala 3
}
-----
+```
Before:
-[source,scala]
-----
+```scala
import org.apache.spark.SparkContext
import org.apache.spark.RDD
import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.Buffer
import scala.concurrent.ExecutionContext.Implicits.global
import scala.sys.process.stringToProcess
-----
+```
After:
-
-[source,scala]
-----
+```scala
import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.Buffer
import org.apache.spark.RDD
import org.apache.spark.SparkContext
import scala.concurrent.ExecutionContext.Implicits.global
import scala.sys.process.stringToProcess
-----
+```
-[[groupedImports]]
-=== `groupedImports`
+`groupedImports`
+----------------
Configure how to handle grouped imports.
-==== Value type
+### Value type
Enum: `Explode | Merge | AggressiveMerge | Keep`
-`Explode`:: Explode grouped imports into separate import statements.
-
-`Merge`::
-+
---
-Merge imports sharing the same prefix into a single grouped import statement.
-
-[TIP]
-====
-You may want to check the <<aggressive-merge, `AggressiveMerge`>> option for more concise results despite a relatively low risk of introducing compilation errors.
-====
-
-[IMPORTANT]
-====
-`OrganizeImports` does not support cases where one name is renamed to multiple aliases within the same source file when `groupedImports` is set to `Merge`. (The IntelliJ IDEA Scala import optimizer does not support this either.)
-
-Scala allows a name to be renamed to multiple aliases within a single source file, which makes merging import statements tricky. For example:
-
-[source,scala]
-----
-import java.lang.{Double => JDouble}
-import java.lang.{Double => JavaDouble}
-import java.lang.Integer
-----
-
-The above three imports can be merged into:
-
-[source,scala]
-----
-import java.lang.{Double => JDouble}
-import java.lang.{Double => JavaDouble, Integer}
-----
-
-but not:
-
-[source,scala]
-----
-import java.lang.{Double => JDouble, Double => JavaDouble, Integer}
-----
-
-because Scala disallow a name (in this case, `Double`) to appear in one import multiple times.
-
-Here's a more complicated example:
-
-[source,scala]
-----
-import p.{A => A1}
-import p.{A => A2}
-import p.{A => A3}
-
-import p.{B => B1}
-import p.{B => B2}
-
-import p.{C => C1}
-import p.{C => C2}
-import p.{C => C3}
-import p.{C => C4}
-----
-
-While merging these imports, we may want to "bin-pack" them to minimize the number of the result import statements:
-
-[source,scala]
-----
-import p.{A => A1, B => B1, C => C1}
-import p.{A => A2, B => B2, C => C2}
-import p.{A => A3, C3 => C3}
-import p.{C => C4}
-----
-
-However, in reality, renaming aliasing a name multiple times in the same source file is rarely a practical need. Therefore, `OrganizeImports` does not support this when `groupedImports` is set to `Merge` to avoid the extra complexity.
-====
---
-
-[[aggressive-merge]]
-`AggressiveMerge`::
-+
---
-Similar to `Merge`, but merges imports more aggressively and produces more concise results, despite a relatively low risk of introducing compilation errors.
-
-The `OrganizeImports` rule tries hard to guarantee correctness in all cases. This forces it to be more conservative when merging imports, and may sometimes produce suboptimal output. Here is a concrete example about correctness:
-
-[source,scala]
-----
+#### `Explode`
+Explode grouped imports into separate import statements.
+
+#### `Merge`
+Merge imports sharing the same prefix into a single grouped import
+statement.
+
+> You may want to check the [`AggressiveMerge`](OrganizeImports.md#aggressivemerge)
+> option for more concise results despite a relatively low risk of introducing
+> compilation errors.
+
+> `OrganizeImports` does not support cases where one name is renamed to
+> multiple aliases within the same source file when `groupedImports` is
+> set to `Merge`. (The IntelliJ IDEA Scala import optimizer does not
+> support this either.)
+>
+> Scala allows a name to be renamed to multiple aliases within a single
+> source file, which makes merging import statements tricky. For example:
+>
+> ```scala
+> import java.lang.{Double => JDouble}
+> import java.lang.{Double => JavaDouble}
+> import java.lang.Integer
+> ```
+>
+> The above three imports can be merged into:
+>
+> ```scala
+> import java.lang.{Double => JDouble}
+> import java.lang.{Double => JavaDouble, Integer}
+> ```
+>
+> but not:
+>
+> ```scala
+> import java.lang.{Double => JDouble, Double => JavaDouble, Integer}
+> ```
+>
+> because Scala disallow a name (in this case, `Double`) to appear in one
+> import multiple times.
+>
+> Here’s a more complicated example:
+>
+> ```scala
+> import p.{A => A1}
+> import p.{A => A2}
+> import p.{A => A3}
+>
+> import p.{B => B1}
+> import p.{B => B2}
+>
+> import p.{C => C1}
+> import p.{C => C2}
+> import p.{C => C3}
+> import p.{C => C4}
+> ```
+>
+> While merging these imports, we may want to "bin-pack" them to minimize
+> the number of the result import statements:
+>
+> ```scala
+> import p.{A => A1, B => B1, C => C1}
+> import p.{A => A2, B => B2, C => C2}
+> import p.{A => A3, C3 => C3}
+> import p.{C => C4}
+> ```
+>
+> However, in reality, renaming aliasing a name multiple times in the same
+> source file is rarely a practical need. Therefore, `OrganizeImports`
+> does not support this when `groupedImports` is set to `Merge` to avoid
+> the extra complexity.
+
+#### `AggressiveMerge`
+Similar to `Merge`, but merges imports more aggressively and produces
+more concise results, despite a relatively low risk of introducing
+compilation errors.
+
+The `OrganizeImports` rule tries hard to guarantee correctness in all
+cases. This forces it to be more conservative when merging imports, and
+may sometimes produce suboptimal output. Here is a concrete example
+about correctness:
+
+```scala
import scala.collection.immutable._
import scala.collection.mutable.Map
import scala.collection.mutable._
object Example {
val m: Map[Int, Int] = ???
}
-----
+```
-At a first glance, it seems feasible to simply drop the second import since `mutable._` already covers `mutble.Map`. However, similar to the example illustrated in the section about the <<coalesceToWildcardImportThreshold, `coalesceToWildcardImportThreshold` option>>, the type of `Example.m` above is `mutable.Map`, because the mutable `Map` explicitly imported in the second import takes higher precedence than the immutable `Map` imported via wildcard in the first import. If we merge the last two imports naively, we'll get:
+At a first glance, it seems feasible to simply drop the second import
+since `mutable._` already covers `mutble.Map`. However, similar to the
+example illustrated in the section about the
+[`coalesceToWildcardImportThreshold`
+option](OrganizeImports.md#coalescetowildcardimportthreshold), the type of `Example.m`
+above is `mutable.Map`, because the mutable `Map` explicitly imported in
+the second import takes higher precedence than the immutable `Map`
+imported via wildcard in the first import. If we merge the last two
+imports naively, we’ll get:
-[source,scala]
-----
+```scala
import scala.collection.immutable._
import scala.collection.mutable._
-----
+```
-This triggers in a compilation error, because both `immutable.Map` and `mutable.Map` are now imported via wildcards with the same precedence. This makes the type of `Example.m` ambiguous. The correct result should be:
+This triggers in a compilation error, because both `immutable.Map` and
+`mutable.Map` are now imported via wildcards with the same precedence.
+This makes the type of `Example.m` ambiguous. The correct result should
+be:
-[source,scala]
-----
+```scala
import scala.collection.immutable._
import scala.collection.mutable.{Map, _}
-----
+```
-On the other hand, the case discussed above is rarely seen in practice. A more commonly seen case is something like:
+On the other hand, the case discussed above is rarely seen in practice.
+A more commonly seen case is something like:
-[source,scala]
-----
+```scala
import scala.collection.mutable.Map
import scala.collection.mutable._
-----
+```
Instead of being conservative and produce a suboptimal output like:
-[source,scala]
-----
+```scala
import scala.collection.mutable.{Map, _}
-----
+```
setting `groupedImports` to `AggressiveMerge` produces
-
-[source,scala]
-----
+```scala
import scala.collection.mutable._
-----
---
+```
-`Keep`:: Leave grouped imports and imports sharing the same prefix untouched.
+#### `Keep`
+Leave grouped imports and imports sharing the same prefix untouched.
-==== Default value
+### Default value
`Explode`
-Rationale:: Despite making the import section lengthier, exploding grouped imports into separate import statements is made the default behavior because it is more friendly to version control and less likely to create annoying merge conflicts caused by trivial import changes.
+Rationale: despite making the import section lengthier, exploding grouped
+imports into separate import statements is made the default behavior because
+it is more friendly to version control and less likely to create annoying
+merge conflicts caused by trivial import changes.
-==== Examples
+### Examples
-`Explode`::
-+
---
-Configuration:
+#### `Explode`
-[source,hocon]
-----
+```conf
OrganizeImports.groupedImports = Explode
-----
+```
Before:
-[source,scala]
-----
+```scala
import scala.collection.mutable.{ArrayBuffer, Buffer, StringBuilder}
-----
+```
After:
-[source,scala]
-----
+```scala
import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.Buffer
import scala.collection.mutable.StringBuilder
-----
---
+```
-`Merge`::
-+
---
-Configuration:
+#### `Merge`
-[source,hocon]
-----
+```conf
OrganizeImports.groupedImports = Merge
-----
+```
Before:
-[source,scala]
-----
+```scala
import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.Buffer
import scala.collection.mutable.StringBuilder
import scala.collection.immutable.Set
import scala.collection.immutable._
-----
+```
After:
-[source,scala]
-----
+```scala
import scala.collection.mutable.{ArrayBuffer, Buffer, StringBuilder}
import scala.collection.immutable.{Set, _}
-----
---
+```
-`AggressiveMerge`::
-+
---
-Configuration:
+#### `AggressiveMerge`
-[source,hocon]
-----
+```conf
OrganizeImports.groupedImports = AggressiveMerge
-----
+```
Before:
-[source,scala]
-----
+```scala
import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.Buffer
import scala.collection.mutable.StringBuilder
import scala.collection.immutable.Set
import scala.collection.immutable._
-----
+```
After:
-[source,scala]
-----
+```scala
import scala.collection.mutable.{ArrayBuffer, Buffer, StringBuilder}
import scala.collection.immutable._
-----
---
-
-[[groups]]
-=== `groups`
-
-Defines import groups by prefix patterns. Only global imports are processed.
-
-All the imports matching the same prefix pattern are gathered into the same group and sorted by the order defined by the <<importsOrder, `importsOrder`>> option.
-
-CAUTION: Comments living _between_ imports being processed will be _removed_.
-
-[TIP]
-====
-`OrganizeImports` tries to match the longest prefix while grouping imports. For instance, the following configuration groups `scala.meta.` and `scala.` imports into different two groups properly:
-
-[source,hocon]
-----
-OrganizeImports.groups = [
- "re:javax?\\."
- "scala."
- "scala.meta."
- "*"
-]
-----
-====
-
-[[trailing-order-preserving-import-group]]
-[IMPORTANT]
-====
-No matter how the `groups` option is configured, a special order-preserving import group may appear after all the configured import groups when:
-
-. The `expandRelative` option is set to `false` and there are relative imports.
-. The `groupExplicitlyImportedImplicitsSeparately` option is set to `true` and there are implicit names explicitly imported.
-
-This special import group is necessary because the above two kinds of imports are order sensitive:
-
-Relative imports::
-+
---
-For instance, sorting the following imports in alphabetical order introduces compilation errors:
-
-[source,scala]
-----
-import scala.util
-import util.control
-import control.NonFatal
-----
---
-
-Explicitly imported implicit names:: Please refer to the <<groupExplicitlyImportedImplicitsSeparately, `groupExplicitlyImportedImplicitsSeparately`>> option for more details.
-====
-
-==== Value type
-
-An ordered list of import prefix pattern strings. A prefix pattern can be one of the following:
-
-A plain-text pattern:: For instance, `"scala."` is a plain-text pattern that matches imports referring the `scala` package. Please note that the trailing dot is necessary, otherwise you may have `scalafix` and `scala` imports in the same group, which is not what you want in most cases.
-
-A regular expression pattern:: A regular expression pattern starts with `re:`. For instance, `"re:javax?\\."` is such a pattern that matches both the `java` and the `javax` packages. Please refer to the https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html[`java.util.regex.Pattern`] Javadoc page for the regular expression syntax. Note that special characters like backslashes must be escaped.
-
-The wildcard pattern::
-+
---
-The wildcard pattern, `"*"`, defines the wildcard group, which matches all fully-qualified imports not belonging to any other groups. It can be omitted when it's the last group. So the following two configurations are equivalent:
-
-[source,hocon]
-----
+```
+
+`groups`
+--------
+
+Defines import groups by prefix patterns. Only global imports are
+processed.
+
+All the imports matching the same prefix pattern are gathered into the
+same group and sorted by the order defined by the
+[`importsOrder`](OrganizeImports.md#importsorder) option.
+
+> Comments living *between* imports being processed will be *removed*.
+
+> `OrganizeImports` tries to match the longest prefix while grouping
+> imports. For instance, the following configuration groups `scala.meta.`
+> and `scala.` imports into different two groups properly:
+>
+> ```conf
+> OrganizeImports.groups = [
+> "re:javax?\\."
+> "scala."
+> "scala.meta."
+> "*"
+> ]
+> ```
+
+> No matter how the `groups` option is configured, a special
+> order-preserving import group may appear after all the configured import
+> groups when:
+>
+> 1. The `expandRelative` option is set to `false` and there are relative
+> imports.
+>
+> 2. The `groupExplicitlyImportedImplicitsSeparately` option is set to
+> `true` and there are implicit names explicitly imported.
+>
+> This special import group is necessary because the above two kinds of
+> imports are order sensitive:
+>
+> #### Relative imports
+> For instance, sorting the following imports in alphabetical order
+> introduces compilation errors:
+>
+> ```scala
+> import scala.util
+> import util.control
+> import control.NonFatal
+> ```
+> #### Explicitly imported implicit names
+> Please refer to the
+> [`groupExplicitlyImportedImplicitsSeparately`](OrganizeImports.md#groupexplicitlyimportedimplicitsseparately)
+> option for more details.
+
+### Value type
+
+An ordered list of import prefix pattern strings. A prefix pattern can
+be one of the following:
+
+#### A plain-text pattern
+For instance, `"scala."` is a plain-text pattern that matches imports
+referring the `scala` package. Please note that the trailing dot is
+necessary, otherwise you may have `scalafix` and `scala` imports in the
+same group, which is not what you want in most cases.
+
+#### A regular expression pattern
+A regular expression pattern starts with `re:`. For instance,
+`"re:javax?\\."` is such a pattern that matches both the `java` and the
+`javax` packages. Please refer to the
+[`java.util.regex.Pattern`](https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html)
+Javadoc page for the regular expression syntax. Note that special
+characters like backslashes must be escaped.
+
+#### The wildcard pattern
+The wildcard pattern, `"*"`, defines the wildcard group, which matches
+all fully-qualified imports not belonging to any other groups. It can be
+omitted when it’s the last group. So the following two configurations
+are equivalent:
+
+```conf
OrganizeImports.groups = ["re:javax?\\.", "scala.", "*"]
OrganizeImports.groups = ["re:javax?\\.", "scala."]
-----
---
+```
-[[blank-line-marker]]
-A blank line marker::
-+
---
-Available since v0.5.0-alpha.1.
+#### A blank line marker
+A blank line marker, `"---"`, defines a blank line between two adjacent
+import groups when [`blankLines`](OrganizeImports.md#blanklines) is
+set to `Manual`. It is ignored when `blankLines` is `Auto`. Leading and
+trailing blank line markers are always ignored. Multiple consecutive blank
+line markers are treated as a single one. So the following three configurations
+are all equivalent:
-A blank line marker, `"---"`, defines a blank line between two adjacent import groups when <<blankLines, `blankLines`>> is set to `Manual`. It is ignored when `blankLines` is `Auto`. Leading and trailing blank line markers are always ignored. Multiple consecutive blank line markers are treated as a single one. So the following three configurations are all equivalent:
-
-[source,hocon]
-----
+```conf
OrganizeImports {
blankLines = Manual
groups = [
"---"
"re:javax?\\."
"---"
"scala."
"---"
"---"
"*"
"---"
]
}
OrganizeImports {
blankLines = Manual
groups = [
"re:javax?\\."
"---"
"scala."
"---"
"*"
]
}
OrganizeImports {
blankLines = Auto
groups = [
"re:javax?\\."
"scala."
"*"
]
}
-----
---
+```
-==== Default value
+### Default value
-[source,hocon]
-----
+```conf
[
"*"
"re:(javax?|scala)\\."
]
-----
+```
-Rationale:: This aligns with the default configuration of the IntelliJ Scala plugin version 2020.3.
+Rationale: this aligns with the default configuration of the IntelliJ Scala plugin
+version 2020.3.
-==== Examples
+### Examples
-Fully-qualified imports only::
-+
---
-Configuration:
+#### Fully-qualified imports only
-[source,hocon]
-----
+```conf
OrganizeImports.groups = ["re:javax?\\.", "scala.", "*"]
-----
+```
Before:
-[source,scala]
-----
+```scala
import scala.collection.JavaConverters._
import java.time.Clock
import sun.misc.BASE64Encoder
import javax.annotation.Generated
import scala.concurrent.ExecutionContext
-----
+```
After:
-[source,scala]
-----
+```scala
import java.time.Clock
import javax.annotation.Generated
import scala.collection.JavaConverters._
import scala.concurrent.ExecutionContext
import sun.misc.BASE64Encoder
-----
---
+```
-With relative imports::
-+
---
-Configuration:
+#### With relative imports
-[source,hocon]
-----
+```conf
OrganizeImports.groups = ["re:javax?\\.", "scala.", "*"]
-----
+```
Before:
-[source,scala]
-----
-import scala.util
+```scala
+import scala.utilRationale
import util.control
import control.NonFatal
import scala.collection.JavaConverters._
import java.time.Clock
import sun.misc.BASE64Encoder
import javax.annotation.Generated
import scala.concurrent.ExecutionContext
-----
+```
After:
-
-[source,scala]
-----
+```scala
import java.time.Clock
import javax.annotation.Generated
import scala.collection.JavaConverters._
import scala.concurrent.ExecutionContext
import scala.util
import sun.misc.BASE64Encoder
import util.control
import control.NonFatal
-----
---
+```
-With relative imports and an explicitly imported implicit name::
-+
---
-Configuration:
+#### With relative imports and an explicitly imported implicit name
-[source,hocon]
-----
+```conf
OrganizeImports {
groups = ["re:javax?\\.", "scala.", "*"]
groupExplicitlyImportedImplicitsSeparately = true
}
-----
+```
Before:
-
-[source,scala]
-----
+```scala
import scala.util
import util.control
import control.NonFatal
import scala.collection.JavaConverters._
import java.time.Clock
import sun.misc.BASE64Encoder
import javax.annotation.Generated
import scala.concurrent.ExecutionContext.Implicits.global
-----
+```
After:
-[source,scala]
-----
+```scala
import java.time.Clock
import javax.annotation.Generated
import scala.collection.JavaConverters._
import scala.util
import sun.misc.BASE64Encoder
import util.control
import control.NonFatal
import scala.concurrent.ExecutionContext.Implicits.global
-----
---
+```
-Regular expression::
-+
---
-Defining import groups using regular expressions can be quite flexible. For instance, the `scala.meta` package is not part of the Scala standard library, but the default groups defined in the `OrganizeImports.groups` option move imports from this package into the `scala.` group. The following example illustrates how to move them into the wildcard group using regular expression.
+#### Regular expression
+Defining import groups using regular expressions can be quite flexible.
+For instance, the `scala.meta` package is not part of the Scala standard
+library, but the default groups defined in the `OrganizeImports.groups`
+option move imports from this package into the `scala.` group. The
+following example illustrates how to move them into the wildcard group
+using regular expression.
-Configuration:
-[source,hocon]
-----
+```conf
OrganizeImports.groups = [
"re:javax?\\."
"re:scala.(?!meta\\.)"
"*"
]
-----
+```
Before:
-[source,scala]
-----
+
+```scala
import scala.collection.JavaConverters._
import java.time.Clock
import sun.misc.BASE64Encoder
import scala.meta.Tree
import javax.annotation.Generated
import scala.concurrent.ExecutionContext
import scala.meta.Import
import scala.meta.Pkg
-----
+```
After:
-[source,scala]
-----
+
+```scala
import java.time.Clock
import javax.annotation.Generated
import scala.collection.JavaConverters._
import scala.concurrent.ExecutionContext
import scala.meta.Import
import scala.meta.Pkg
import scala.meta.Tree
import sun.misc.BASE64Encoder
-----
---
+```
-With manually configured blank lines::
-+
---
-Configuration:
+#### With manually configured blank lines
-[source,hocon]
-----
+```conf
OrganizeImports {
blankLines = Manual
groups = [
"*"
"---"
"re:javax?\\."
"scala."
]
}
-----
+```
Before:
-[source,scala]
-----
+```scala
import scala.collection.JavaConverters._
import java.time.Clock
import sun.misc.BASE64Encoder
import javax.annotation.Generated
import scala.concurrent.ExecutionContext
-----
+```
After:
-[source,scala]
-----
+```scala
import sun.misc.BASE64Encoder
import java.time.Clock
import javax.annotation.Generated
import scala.collection.JavaConverters._
import scala.concurrent.ExecutionContext
-----
---
+```
-[[importSelectorsOrder]]
-=== `importSelectorsOrder`
+`importSelectorsOrder`
+----------------------
-Specifies the order of grouped import selectors within a single import expression.
+Specifies the order of grouped import selectors within a single import
+expression.
-==== Value type
+### Value type
Enum: `Ascii | SymbolsFirst | Keep`
-`Ascii`:: Sort import selectors by ASCII codes, equivalent to the https://scalameta.org/scalafmt/docs/configuration.html#asciisortimports[`AsciiSortImports`] rewriting rule in Scalafmt.
+#### `Ascii`
+Sort import selectors by ASCII codes, equivalent to the
+[`AsciiSortImports`](https://scalameta.org/scalafmt/docs/configuration.html#asciisortimports)
+rewriting rule in Scalafmt.
-`SymbolsFirst`:: Sort import selectors by the groups: symbols, lower-case, upper-case, equivalent to the https://scalameta.org/scalafmt/docs/configuration.html#sortimports[`SortImports`] rewriting rule in Scalafmt.
+#### `SymbolsFirst`
+Sort import selectors by the groups: symbols, lower-case, upper-case,
+equivalent to the
+[`SortImports`](https://scalameta.org/scalafmt/docs/configuration.html#sortimports)
+rewriting rule in Scalafmt.
-`Keep`:: Keep the original order.
+#### `Keep`
+Keep the original order.
-==== Default value
+### Default value
`Ascii`
-==== Examples
+### Examples
-`Ascii`::
-+
---
-Configuration:
+#### `Ascii`
-[source,hocon]
-----
+```conf
OrganizeImports {
groupedImports = Keep
importSelectorsOrder = Ascii
}
-----
+```
Before:
-[source,scala]
-----
+```scala
import foo.{~>, `symbol`, bar, Random}
-----
+```
After:
-[source,scala]
-----
+```scala
import foo.{Random, `symbol`, bar, ~>}
-----
---
+```
-`SymbolsFirst`::
-+
---
-Configuration:
+#### `SymbolsFirst`
-[source,hocon]
-----
+```conf
OrganizeImports {
groupedImports = Keep
importSelectorsOrder = SymbolsFirst
}
-----
+```
Before:
-[source,scala]
-----
+```scala
import foo.{Random, `symbol`, bar, ~>}
-----
+```
After:
-
-[source,scala]
-----
+```scala
import foo.{~>, `symbol`, bar, Random}
-----
---
+```
-[[importsOrder]]
-=== `importsOrder`
+`importsOrder`
+--------------
-Specifies the order of import statements within import groups defined by the <<groups, `OrganizeImports.groups`>> option.
+Specifies the order of import statements within import groups defined by
+the [`OrganizeImports.groups`](#groups) option.
-==== Value type
+### Value type
Enum: `Ascii | SymbolsFirst | Keep`
-`Ascii`:: Sort import statements by ASCII codes. This is the default sorting order that the IntelliJ IDEA Scala import optimizer picks ("lexicographically" option).
+#### `Ascii`
+Sort import statements by ASCII codes. This is the default sorting order
+that the IntelliJ IDEA Scala import optimizer picks ("lexicographically"
+option).
-`SymbolsFirst`:: Put wildcard imports and grouped imports with braces first, otherwise same as `Ascii`. This replicates IntelliJ IDEA Scala's "scalastyle consistent" option.
+#### `SymbolsFirst`
+Put wildcard imports and grouped imports with braces first, otherwise
+same as `Ascii`. This replicates IntelliJ IDEA Scala’s "scalastyle
+consistent" option.
-`Keep`:: Keep the original order.
+#### `Keep`
+Keep the original order.
-==== Default value
+### Default value
`Ascii`
-==== Examples
+### Examples
-`Ascii`::
-+
---
-Configuration:
+#### `Ascii`
-[source,hocon]
-----
+```conf
OrganizeImports {
groupedImports = Keep
importsOrder = Ascii
}
-----
+```
Before:
-[source,scala]
-----
+```scala
import scala.concurrent._
import scala.concurrent.{Future, Promise}
import scala.concurrent.ExecutionContext.Implicits._
import scala.concurrent.duration
-----
+```
After:
-[source,scala]
-----
+```scala
import scala.concurrent.ExecutionContext.Implicits._
import scala.concurrent._
import scala.concurrent.duration
import scala.concurrent.{Promise, Future}
-----
---
+```
-`SymbolsFirst`::
-+
---
-Configuration:
+#### `SymbolsFirst`
-[source,hocon]
-----
+```conf
OrganizeImports {
groupedImports = Keep
importsOrder = SymbolsFirst
}
-----
+```
Before:
-[source,scala]
-----
+```scala
import scala.concurrent.ExecutionContext.Implicits._
import scala.concurrent._
import scala.concurrent.duration
import scala.concurrent.{Promise, Future}
-----
+```
After:
-[source,scala]
-----
+```scala
import scala.concurrent._
import scala.concurrent.{Future, Promise}
import scala.concurrent.ExecutionContext.Implicits._
import scala.concurrent.duration
-----
---
+```
-[[preset]]
-=== `preset`
-
-Available since v0.5.0.
+`preset`
+--------
Specify a preset style.
-==== Value type
+### Value type
Enum: `DEFAULT | INTELLIJ_2020_3`
-`DEFAULT`::
-+
---
-An opinionated style recommended for new projects. The `OrganizeImports` rule tries its best to ensure correctness in all cases when possible. This default style aligns with this principal. In addition, by setting `groupedImports` to `Explode`, this style is also more friendly to version control and less likely to create annoying merge conflicts caused by trivial import changes.
+#### `DEFAULT`
+An opinionated style recommended for new projects. The `OrganizeImports`
+rule tries its best to ensure correctness in all cases when possible.
+This default style aligns with this principal. In addition, by setting
+`groupedImports` to `Explode`, this style is also more friendly to
+version control and less likely to create annoying merge conflicts
+caused by trivial import changes.
-[source,hocon]
-----
+```conf
OrganizeImports {
blankLines = Auto
coalesceToWildcardImportThreshold = null
expandRelative = false
groupExplicitlyImportedImplicitsSeparately = false
groupedImports = Explode
groups = [
"*"
"re:(javax?|scala)\\."
]
importSelectorsOrder = Ascii
importsOrder = Ascii
preset = DEFAULT
removeUnused = true
}
-----
---
+```
-[[intellij-2020-3]]
-`INTELLIJ_2020_3`::
-+
---
-A style that is compatible with the default configuration of the IntelliJ Scala 2020.3 import optimizer. It is mostly useful for adding `OrganizeImports` to existing projects developed using the IntelliJ Scala plugin. However, the configuration of this style may introduce subtle correctness issues (so does the default configuration of the IntelliJ Scala plugin). Please see the <<coalesceToWildcardImportThreshold, `coalesceToWildcardImportThreshold` option>> for more details.
+#### `INTELLIJ_2020_3`
+A style that is compatible with the default configuration of the
+IntelliJ Scala 2020.3 import optimizer. It is mostly useful for adding
+`OrganizeImports` to existing projects developed using the IntelliJ
+Scala plugin. However, the configuration of this style may introduce
+subtle correctness issues (so does the default configuration of the
+IntelliJ Scala plugin). Please see the
+[`coalesceToWildcardImportThreshold`
+option](OrganizeImports.md#coalescetowildcardimportthreshold)
+for more details.
-[source,hocon]
-----
+```conf
OrganizeImports {
blankLines = Auto
coalesceToWildcardImportThreshold = 5
expandRelative = false
groupExplicitlyImportedImplicitsSeparately = false
groupedImports = Merge
groups = [
"*"
"re:(javax?|scala)\\."
]
importSelectorsOrder = Ascii
importsOrder = Ascii
preset = INTELLIJ_2020_3
removeUnused = true
}
-----
---
+```
-==== Default value
+### Default value
`DEFAULT`
-[[removeUnused]]
-=== `removeUnused`
+`removeUnused`
+--------------
Remove unused imports.
-[CAUTION]
-====
-As mentioned in <<remove-unused-warning, a previous section>>, the `removeUnused` option doesn't play perfectly with the `expandRelative` option. Setting `expandRelative` to `true` might introduce new unused imports (see <<expandRelative, `expandRelative`>>). These newly introduced unused imports cannot be removed by setting `removeUnused` to `true`. This is because unused imports are identified using Scala compilation diagnostics information, and the compilation phase happens before Scalafix rules get applied.
-====
+> The `removeUnused` option doesn’t play perfectly with the `expandRelative`
+> option. Setting `expandRelative` to `true` might introduce new unused
+> imports (see [`expandRelative`](OrganizeImports.md#expandrelative)).
+> These newly introduced unused imports cannot be removed by setting
+> `removeUnused` to `true`. This is because unused imports are identified
+> using Scala compilation diagnostics information, and the compilation phase
+> happens before Scalafix rules get applied.
-[IMPORTANT]
-====
-The `removeUnused` option is currently not supported for source files compiled with Scala 3, as the https://docs.scala-lang.org/scala3/guides/migration/options-lookup.html#warning-settings[compiler cannot issue warnings for unused imports yet]. As a result, you must set `removeUnused` to `false` when running the rule on source files compiled with Scala 3.
-====
+> The `removeUnused` option is currently not supported for source files
+> compiled with Scala 3, as the [compiler cannot issue warnings for unused
+> imports
+> yet](https://docs.scala-lang.org/scala3/guides/migration/options-lookup.html#warning-settings).
+> As a result, you must set `removeUnused` to `false` when running the
+> rule on source files compiled with Scala 3.
-==== Value type
+### Value type
Boolean
-==== Default value
+### Default value
`true`
-==== Examples
+### Examples
-Configuration:
-
-[source,hocon]
-----
+```conf
OrganizeImports {
groups = ["javax?\\.", "scala.", "*"]
removeUnused = true // not supported in Scala 3
}
-----
+```
Before:
-[source,scala]
-----
+```scala
import scala.collection.mutable.{Buffer, ArrayBuffer}
import java.time.Clock
import java.lang.{Long => JLong, Double => JDouble}
object RemoveUnused {
val buffer: ArrayBuffer[Int] = ArrayBuffer.empty[Int]
val long: JLong = JLong.parseLong("0")
}
-----
+```
After:
-[source,scala]
-----
+```scala
import java.lang.{Long => JLong}
import scala.collection.mutable.ArrayBuffer
object RemoveUnused {
val buffer: ArrayBuffer[Int] = ArrayBuffer.empty[Int]
val long: JLong = JLong.parseLong("0")
}
-----
+```
diff --combined docs/rules/community-rules.md
index 3a0c7868,00000000..ee2a247c
mode 100644,000000..100644
--- a/docs/rules/community-rules.md
--- /dev/null
++ b/docs/rules/community-rules.md
@@@ -1,58 -1,0 +1,57 @@@
---
id: community-rules
sidebar_label: Community rules
title: Community rules
---
Many rules have been developed and published by the community.
Follow [this documentation](external-rules.md) to use them in your project.
> Help us increase visibility & foster collaboration by
> [submitting your favorite rule(s) via pull requests](https://github.com/scalacenter/scalafix/edit/main/docs/rules/community-rules.md)!
## Hygiene rules
Hygiene rules enforce conventions, failing the build on violation or
rewriting the code when possible.
| Repository | Artifact | Description |
| - | - | - |
[ghostbuster91/scalafix-unified](https://github.com/ghostbuster91/scalafix-unified) | `io.github.ghostbuster91.scalafix-unified::unified` | Set of opinionated rules to unify your codebase
[jatcwang/scalafix-named-params](https://github.com/jatcwang/scalafix-named-params) | `com.github.jatcwang::scalafix-named-params` | Add named parameters for your constructor and method calls
- [liancheng/scalafix-organize-imports](https://github.com/liancheng/scalafix-organize-imports) | `com.github.liancheng::organize-imports` | Help you organize Scala import statements
[vovapolu/scaluzzi](https://github.com/vovapolu/scaluzzi) | `com.github.vovapolu::scaluzzi` | Ensure a subset of [scalazzi](http://yowconference.com.au/slides/yowwest2014/Morris-ParametricityTypesDocumentationCodeReadability.pdf)
[xuwei-k/scalafix-rules](https://github.com/xuwei-k/scalafix-rules) | `com.github.xuwei-k::scalafix-rules` | Avoid ambiguous or redundant Scala syntax & features
[pixiv/scalafix-pixiv-rule](https://github.com/pixiv/scalafix-pixiv-rule) | `net.pixiv::scalafix-pixiv-rule` | Redundant Scala code rewriting and anti-pattern warnings
## Migration rules
Migration rules make it easier for library users to cope with
deprecations and breaking changes.
Official migrations provided by library authors are not
advertized here as they are usually well documented in the
project itself. Note that
[Scala Steward](https://github.com/scala-steward-org/scala-steward)
[keeps track of many of them](https://github.com/scala-steward-org/scala-steward/blob/main/modules/core/src/main/resources/scalafix-migrations.conf),
to provide a seamless experience to library users opting-in
for the service.
| Repository | Artifact | Description |
| - | - | - |
[ohze/scala-rewrites](https://github.com/ohze/scala-rewrites) | `com.sandinh::scala-rewrites` | Rewrites for Scala
[OlegYch/enumeratum-scalafix](https://github.com/OlegYch/enumeratum-scalafix) | `io.github.olegych::enumeratum-scalafix` | Replace `scala.Enumeration` with enumeratum
[scala/scala-collection-compat](https://github.com/scala/scala-collection-compat) | `org.scala-lang.modules::scala-collection-migrations` | Rewrite upgrades to the 2.13 collections
[scala/scala-rewrites](https://github.com/scala/scala-rewrites) | `org.scala-lang::scala-rewrites` | Rewrites for Scala
[xuwei-k/play-ws-scalafix](https://github.com/xuwei-k/play-ws-scalafix) | `com.github.xuwei-k::play-ws-scalafix` | Migrate to play-ws-standalone
[tersesystems/echopraxia-scalafix](https://github.com/tersesystems/echopraxia-scalafix) | `com.tersesystems.echopraxia::scalafix` | Rewrite [Echopraxia](https://github.com/tersesystems/echopraxia) logging statements
## Code generation rules
Code generation rules extend the possibilities of the Scala language
by taking a route similar, yet parallel to macros.
| Repository | Artifact | Description |
| - | - | - |
[earldouglas/linear-scala](https://github.com/earldouglas/linear-scala) | `com.earldouglas::linear-scala-scalafix` | Add support for linear types in Scala
[rtimush/zio-magic-comments](https://github.com/rtimush/zio-magic-comments) | `com.timushev::zio-magic-comments` | Add explanatory graphs as comments to zio-magic methods
[sake92/kalem](https://github.com/sake92/kalem) | `ba.sake::kalem-rules` | Generate `with*` methods for classes
[typelevel/simulacrum-scalafix](https://github.com/typelevel/simulacrum-scalafix) | `org.typelevel::simulacrum-scalafix-annotations` | Simulacrum as Scalafix rules
diff --combined scalafix-docs/src/main/scala/docs/website.scala
index 841de916,00000000..8878d507
mode 100644,000000..100644
--- a/scalafix-docs/src/main/scala/docs/website.scala
--- /dev/null
++ b/scalafix-docs/src/main/scala/docs/website.scala
@@@ -1,193 -1,0 +1,193 @@@
package scalafix
import java.nio.file.Files
import scala.meta.internal.io.PathIO
import mdoc.Reporter
import metaconfig.generic.Setting
import metaconfig.generic.Settings
import scalafix.internal.v1.Rules
import scalafix.v0._
import scalatags.Text
import scalatags.Text.all._
package object website {
import scalafix.internal.rule.SimpleDefinitions
def url(name: String, relpath: String): Text.TypedTag[String] =
a(href := s"/scalafix/$relpath", name)
def ruleLink(name: String): Text.TypedTag[String] = {
url(name, s"docs/rules/$name.html")
}
def allRulesTable(reporter: Reporter): String = {
val rules = Rules
.all()
.filterNot(_.name.isDeprecated)
.filterNot(_.isExperimental)
.sortBy(_.name.value)
val (semantic, syntactic) = rules.partition(_.isInstanceOf[v1.SemanticRule])
def buildTable(rules: List[v1.Rule]): Text.TypedTag[String] = {
val rows: List[Text.TypedTag[String]] = rules.map { rule =>
val docPath = PathIO.workingDirectory
.resolve("docs")
.resolve("rules")
.resolve(rule.name.value + ".md")
if (!rule.isExperimental && !Files.isRegularFile(docPath.toNIO)) {
reporter.warning(s"Missing $docPath")
}
tr(
td(ruleLink(rule.name.value)),
td(rule.description)
)
}
val header =
thead(
tr(
th("Name"),
th("Description")
)
)
table(
header,
tbody(rows)
)
}
div(
h2("Semantic Rules"),
buildTable(semantic),
h2("Syntactic Rules"),
buildTable(syntactic)
).toString
}
// TODO(olafur) replace this hack with ConfEncoder[T] typeclass.
def render(any: Any): String = any match {
case s: Symbol =>
val syntax =
s.syntax.stripPrefix("_root_.").stripSuffix("#").stripSuffix(".")
new StringBuilder()
.append("\"")
.append(syntax)
.append("\"")
.toString()
case _ => any.toString
}
- private def flat[T](
+ def flat[T](
default: T
)(implicit settings: Settings[T], ev: T <:< Product): List[(Setting, Any)] = {
settings.settings
.zip(default.productIterator.iterator.to(Iterable))
.filterNot { case (setting, _) => setting.isHidden }
.flatMap {
case (s, d: SimpleDefinitions) =>
(s, d.kinds.mkString("['", "', '", "']")) :: Nil
case (deepSetting, defaultSetting: Product)
if deepSetting.underlying.nonEmpty =>
deepSetting.flat.zip(
defaultSetting.productIterator.iterator.to(Iterable)
)
case (s, lst: Iterable[_]) =>
val rendered = lst.map(render)
val string =
if (lst.size < 2) rendered.mkString("[", ", ", "]")
else rendered.mkString("[\n ", ",\n ", "\n]")
(s, string) :: Nil
case (s, defaultValue) =>
(s, defaultValue) :: Nil
}
}
def htmlSetting(setting: Setting): Text.TypedTag[String] = {
val tpe = setting.field.tpe
.replace("scalafix.v0.Symbol.Global", "Symbol")
.replace("java.util.regex.", "")
.replace("scalafix.CustomMessage", "Message")
.replace("scalafix.internal.config.", "")
tr(
td(code(setting.name)),
td(code(tpe)),
td(setting.description)
)
}
def html(all: List[Setting]): String = {
val fields = all.map { setting =>
htmlSetting(setting)
}
table(
thead(
tr(
th("Name"),
th("Type"),
th("Description")
)
),
tbody(fields)
).toString()
}
def config[T](name: String)(implicit settings: Settings[T]): String =
s"\n\n### $name\n\n" +
html(settings.settings)
def defaults[T](ruleName: String, all: List[(Setting, Any)]): String = {
val sb = new StringBuilder
sb.append("\n\n### Defaults\n\n```")
all.foreach { case (setting, default) =>
sb.append("\n")
.append(ruleName)
.append(".")
.append(setting.name)
.append(" = ")
.append(default)
}
sb.append("\n```\n\n")
sb.toString()
}
def examples[T](ruleName: String)(implicit settings: Settings[T]): String = {
if (settings.settings.forall(_.exampleValues.isEmpty)) ""
else {
val sb = new StringBuilder
sb.append("\n\n### Examples\n\n```")
settings.settings.foreach { setting =>
setting.exampleValues match {
case Nil =>
case example :: _ =>
sb.append("\n")
.append(ruleName)
.append(".")
.append(setting.name)
.append(" = ")
.append(example)
}
}
sb.append("\n```\n\n")
sb.toString()
}
}
def rule[T](
ruleName: String,
default: T
)(implicit
settings: Settings[T],
ev: T <:< Product
): String = {
val sb = new StringBuilder
val all = flat(default)
sb.append(html(all.map(_._1)))
sb.append(defaults(ruleName, all))
sb.append(examples[T](ruleName))
sb.toString()
}
}
diff --combined scalafix-rules/src/main/resources-2/META-INF/services/scalafix.v1.Rule
index c3d34973,00000000..f2526029
mode 100644,000000..100644
--- a/scalafix-rules/src/main/resources-2/META-INF/services/scalafix.v1.Rule
--- /dev/null
++ b/scalafix-rules/src/main/resources-2/META-INF/services/scalafix.v1.Rule
@@@ -1,8 -1,0 +1,9 @@@
scalafix.internal.rule.DisableSyntax
scalafix.internal.rule.ExplicitResultTypes
scalafix.internal.rule.NoAutoTupling
scalafix.internal.rule.NoValInForComprehension
+scalafix.internal.rule.OrganizeImports
scalafix.internal.rule.ProcedureSyntax
scalafix.internal.rule.RedundantSyntax
scalafix.internal.rule.RemoveUnused
scalafix.internal.rule.LeakingImplicitClassVal
diff --combined scalafix-rules/src/main/resources-3/META-INF/services/scalafix.v1.Rule
index 2578d8ae,00000000..6c02c66e
mode 100644,000000..100644
--- a/scalafix-rules/src/main/resources-3/META-INF/services/scalafix.v1.Rule
--- /dev/null
++ b/scalafix-rules/src/main/resources-3/META-INF/services/scalafix.v1.Rule
@@@ -1,6 -1,0 +1,7 @@@
scalafix.internal.rule.DisableSyntax
scalafix.internal.rule.NoAutoTupling
scalafix.internal.rule.NoValInForComprehension
+scalafix.internal.rule.OrganizeImports
scalafix.internal.rule.RedundantSyntax
scalafix.internal.rule.RemoveUnused
scalafix.internal.rule.LeakingImplicitClassVal
diff --combined scalafix-rules/src/main/scala/scalafix/internal/rule/ImportMatcher.scala
index 00000000,5d3689eb..b1341e85
mode 000000,100644..100644
--- /dev/null
--- a/rules/src/main/scala/fix/ImportMatcher.scala
++ b/scalafix-rules/src/main/scala/scalafix/internal/rule/ImportMatcher.scala
@@@ -1,0 -1,40 +1,42 @@@
-package fix
+package scalafix.internal.rule
import scala.util.matching.Regex
import scala.meta.Importer
+import scala.meta.XtensionSyntax
sealed trait ImportMatcher {
def matches(i: Importer): Int
}
object ImportMatcher {
def parse(pattern: String): ImportMatcher =
pattern match {
case p if p startsWith "re:" => RE(new Regex(p stripPrefix "re:"))
case "---" => ---
case "*" => *
case p => PlainText(p)
}
case class RE(pattern: Regex) extends ImportMatcher {
override def matches(i: Importer): Int =
pattern findPrefixMatchOf i.syntax map (_.end) getOrElse 0
}
case class PlainText(pattern: String) extends ImportMatcher {
- override def matches(i: Importer): Int = if (i.syntax startsWith pattern) pattern.length else 0
+ override def matches(i: Importer): Int =
+ if (i.syntax startsWith pattern) pattern.length else 0
}
case object * extends ImportMatcher {
// The wildcard matcher matches nothing. It is special-cased at the end of the import group
// matching process.
def matches(importer: Importer): Int = 0
}
case object --- extends ImportMatcher {
// Blank line matchers are pseudo matchers matching nothing. They are special-cased at the end
// of the import group matching process.
override def matches(i: Importer): Int = 0
}
}
diff --combined scalafix-rules/src/main/scala/scalafix/internal/rule/OrganizeImports.scala
index 00000000,e88c54f7..9abbb301
mode 000000,100644..100644
--- /dev/null
--- a/rules/src/main/scala/fix/OrganizeImports.scala
++ b/scalafix-rules/src/main/scala/scalafix/internal/rule/OrganizeImports.scala
@@@ -1,0 -1,914 +1,1006 @@@
-package fix
+package scalafix.internal.rule
import scala.annotation.tailrec
import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer
import scala.util.Try
-import fix.ImportMatcher.*
-import fix.ImportMatcher.---
-import fix.ImportMatcher.parse
-import metaconfig.Conf
-import metaconfig.ConfDecoder
-import metaconfig.ConfEncoder
-import metaconfig.ConfOps
-import metaconfig.Configured
-import metaconfig.internal.ConfGet
import scala.meta.Import
import scala.meta.Importee
import scala.meta.Importee.GivenAll
import scala.meta.Importee.Wildcard
import scala.meta.Importer
import scala.meta.Name
import scala.meta.Pkg
import scala.meta.Source
import scala.meta.Stat
import scala.meta.Term
import scala.meta.Tree
+import scala.meta.XtensionClassifiable
+import scala.meta.XtensionCollectionLikeUI
+import scala.meta.XtensionSyntax
import scala.meta.inputs.Position
import scala.meta.tokens.Token
+
+import metaconfig.Conf
+import metaconfig.ConfDecoder
+import metaconfig.ConfEncoder
+import metaconfig.ConfOps
+import metaconfig.Configured
+import metaconfig.internal.ConfGet
+import scalafix.internal.rule.ImportMatcher.*
+import scalafix.internal.rule.ImportMatcher.---
+import scalafix.internal.rule.ImportMatcher.parse
import scalafix.lint.Diagnostic
import scalafix.patch.Patch
import scalafix.v1.Configuration
import scalafix.v1.Rule
import scalafix.v1.RuleName.stringToRuleName
import scalafix.v1.SemanticDocument
import scalafix.v1.SemanticRule
import scalafix.v1.Symbol
import scalafix.v1.SymbolInformation
+import scalafix.v1.XtensionSeqPatch
import scalafix.v1.XtensionTreeScalafix
-class OrganizeImports(config: OrganizeImportsConfig) extends SemanticRule("OrganizeImports") {
+class OrganizeImports(config: OrganizeImportsConfig)
+ extends SemanticRule("OrganizeImports") {
import OrganizeImports._
import ImportMatcher._
private val matchers = buildImportMatchers(config)
private val wildcardGroupIndex: Int = matchers indexOf *
- private val unusedImporteePositions: mutable.Set[Position] = mutable.Set.empty[Position]
+ private val unusedImporteePositions: mutable.Set[Position] =
+ mutable.Set.empty[Position]
- private val diagnostics: ArrayBuffer[Diagnostic] = ArrayBuffer.empty[Diagnostic]
+ private val diagnostics: ArrayBuffer[Diagnostic] =
+ ArrayBuffer.empty[Diagnostic]
def this() = this(OrganizeImportsConfig())
override def isLinter: Boolean = true
override def isRewrite: Boolean = true
- override def isExperimental: Boolean = true
-
override def withConfiguration(config: Configuration): Configured[Rule] =
config.conf
.getOrElse("OrganizeImports")(OrganizeImportsConfig())
.andThen(patchPreset(_, config.conf))
.andThen(checkScalacOptions(_, config.scalacOptions, config.scalaVersion))
override def fix(implicit doc: SemanticDocument): Patch = {
unusedImporteePositions ++= doc.diagnostics.collect {
case d if d.message == "Unused import" => d.position
}
val (globalImports, localImports) = collectImports(doc.tree)
val globalImportsPatch =
if (globalImports.isEmpty) Patch.empty
else organizeGlobalImports(globalImports)
val localImportsPatch =
if (!config.removeUnused || localImports.isEmpty) Patch.empty
else removeUnused(localImports)
diagnostics.map(Patch.lint).asPatch + globalImportsPatch + localImportsPatch
}
private def isUnused(importee: Importee): Boolean =
unusedImporteePositions contains positionOf(importee)
- private def organizeGlobalImports(imports: Seq[Import])(implicit doc: SemanticDocument): Patch = {
+ private def organizeGlobalImports(
+ imports: Seq[Import]
+ )(implicit doc: SemanticDocument): Patch = {
val noUnused = imports flatMap (_.importers) flatMap (removeUnused(_).toSeq)
val (implicits, noImplicits) =
if (!config.groupExplicitlyImportedImplicitsSeparately) (Nil, noUnused)
else partitionImplicits(noUnused)
- val (fullyQualifiedImporters, relativeImporters) = noImplicits partition isFullyQualified
+ val (fullyQualifiedImporters, relativeImporters) =
+ noImplicits partition isFullyQualified
// Organizes all the fully-qualified global importers.
val fullyQualifiedGroups: Seq[ImportGroup] = {
- val expanded = if (config.expandRelative) relativeImporters map expandRelative else Nil
+ val expanded =
+ if (config.expandRelative) relativeImporters map expandRelative else Nil
groupImporters(fullyQualifiedImporters ++ expanded)
}
- // Moves relative imports (when `config.expandRelative` is false) and explicitly imported
- // implicit names into a separate order preserving group. This group will be appended after
- // all the other groups.
+ // Moves relative imports (when `config.expandRelative` is false) and
+ // explicitly imported implicit names into a separate order preserving
+ // group. This group will be appended after all the other groups.
//
- // See https://github.com/liancheng/scalafix-organize-imports/issues/30 for why implicits
- // require special handling.
+ // See https://github.com/liancheng/scalafix-organize-imports/issues/30
+ // for why implicits require special handling.
val orderPreservingGroup = {
val relatives = if (config.expandRelative) Nil else relativeImporters
- Option(relatives ++ implicits sortBy (_.importees.head.pos.start)) filter (_.nonEmpty)
+ Option(
+ relatives ++ implicits sortBy (_.importees.head.pos.start)
+ ) filter (_.nonEmpty)
}
// Builds a patch that inserts the organized imports.
val insertionPatch = insertOrganizedImports(
imports.head.tokens.head,
- fullyQualifiedGroups ++ orderPreservingGroup.map(ImportGroup(matchers.length, _))
+ fullyQualifiedGroups ++
+ orderPreservingGroup.map(ImportGroup(matchers.length, _))
)
// Builds a patch that removes all the tokens forming the original imports.
val removalPatch = Patch.removeTokens(
doc.tree.tokens.slice(
imports.head.tokens.start,
imports.last.tokens.end
)
)
(insertionPatch + removalPatch).atomic
}
private def removeUnused(imports: Seq[Import]): Patch =
Patch.fromIterable {
imports flatMap (_.importers) flatMap { case Importer(_, importees) =>
- val hasUsedWildcard = importees exists { i => i.is[Importee.Wildcard] && !isUnused(i) }
+ val hasUsedWildcard = importees exists { i =>
+ i.is[Importee.Wildcard] && !isUnused(i)
+ }
importees collect {
case i @ Importee.Rename(_, to) if isUnused(i) && hasUsedWildcard =>
- // Unimport the identifier instead of removing the importee since unused renamed may
- // still impact compilation by shadowing an identifier.
+ // Unimport the identifier instead of removing the importee since
+ // unused renamed may still impact compilation by shadowing an
+ // identifier.
//
// See https://github.com/scalacenter/scalafix/issues/614
Patch.replaceTree(to, "_").atomic
case i if isUnused(i) =>
Patch.removeImportee(i).atomic
}
}
}
private def removeUnused(importer: Importer): Option[Importer] =
if (!config.removeUnused) Some(importer)
else {
val hasUsedWildcard = importer.importees exists { i =>
i.is[Importee.Wildcard] && !isUnused(i)
}
var rewritten = false
val noUnused = importer.importees.flatMap {
case i @ Importee.Rename(from, _) if isUnused(i) && hasUsedWildcard =>
- // Unimport the identifier instead of removing the importee since unused renamed may still
- // impact compilation by shadowing an identifier.
+ // Unimport the identifier instead of removing the importee since
+ // unused renamed may still impact compilation by shadowing an
+ // identifier.
//
// See https://github.com/scalacenter/scalafix/issues/614
rewritten = true
Importee.Unimport(from) :: Nil
case i if isUnused(i) =>
rewritten = true
Nil
case i =>
i :: Nil
}
if (!rewritten) Some(importer)
else if (noUnused.isEmpty) None
else Some(importer.copy(importees = noUnused))
}
private def partitionImplicits(
importers: Seq[Importer]
)(implicit doc: SemanticDocument): (Seq[Importer], Seq[Importer]) = {
val (implicits, implicitPositions) = importers.flatMap {
case importer @ Importer(_, importees) =>
importees collect {
case i: Importee.Name if i.symbol.infoNoThrow exists (_.isImplicit) =>
importer.copy(importees = i :: Nil) -> i.pos
}
}.unzip
val noImplicits = importers.flatMap {
- _.filterImportees { importee => !implicitPositions.contains(importee.pos) }.toSeq
+ _.filterImportees { importee =>
+ !implicitPositions.contains(importee.pos)
+ }.toSeq
}
(implicits, noImplicits)
}
- private def isFullyQualified(importer: Importer)(implicit doc: SemanticDocument): Boolean = {
+ private def isFullyQualified(
+ importer: Importer
+ )(implicit doc: SemanticDocument): Boolean = {
val topQualifier = topQualifierOf(importer.ref)
val topQualifierSymbol = topQualifier.symbol
val owner = topQualifierSymbol.owner
(
// The owner of the top qualifier is `_root_`, e.g.: `import scala.util`
owner.isRootPackage ||
// The top qualifier is a top-level class/trait/object defined under no packages. In this
// case, Scalameta defines the owner to be the empty package.
owner.isEmptyPackage ||
// The top qualifier itself is `_root_`, e.g.: `import _root_.scala.util`
topQualifier.value == "_root_" ||
- // Issue #64: Sometimes, the symbol of the top qualifier can be missing due to unknown reasons
- // (see https://github.com/liancheng/scalafix-organize-imports/issues/64). In this case, we
- // issue a warning and continue processing assuming that the top qualifier is fully-qualified.
+ // https://github.com/liancheng/scalafix-organize-imports/issues/64:
+ // Sometimes, the symbol of the top qualifier can be missing due to
+ // unknown reasons. In this case, we issue a warning and continue
+ // processing assuming that the top qualifier is fully-qualified.
topQualifierSymbol.isNone && {
diagnostics += ImporterSymbolNotFound(topQualifier)
true
}
)
}
- private def expandRelative(importer: Importer)(implicit doc: SemanticDocument): Importer = {
+ private def expandRelative(
+ importer: Importer
+ )(implicit doc: SemanticDocument): Importer = {
/**
* Converts a `Symbol` into a fully-qualified `Term.Ref`.
*
- * NOTE: The returned `Term.Ref` does NOT contain symbol information since it's not parsed from
- * the source file.
+ * NOTE: The returned `Term.Ref` does NOT contain symbol information since
+ * it's not parsed from the source file.
*/
def toFullyQualifiedRef(symbol: Symbol): Term.Ref = {
val owner = symbol.owner
symbol match {
// When importing names defined within package objects, skip the `package` part for brevity.
// For instance, with the following definition:
//
// package object foo { val x: Int = ??? }
//
// when importing `foo.x`, we prefer "import foo.x" instead of "import foo.`package`.x",
// which is also valid, but unnecessarily lengthy.
//
// See https://github.com/liancheng/scalafix-organize-imports/issues/55.
case _ if symbol.infoNoThrow exists (_.isPackageObject) =>
toFullyQualifiedRef(owner)
- // See the comment marked with "Issue #64" for the case of `symbol.isNone`
- case _ if symbol.isNone || owner.isRootPackage || owner.isEmptyPackage =>
+ // See the comment marked with "issues/64" for the case of `symbol.isNone`
+ case _
+ if symbol.isNone || owner.isRootPackage || owner.isEmptyPackage =>
Term.Name(symbol.displayName)
case _ =>
Term.Select(toFullyQualifiedRef(owner), Term.Name(symbol.displayName))
}
}
- val fullyQualifiedTopQualifier = toFullyQualifiedRef(topQualifierOf(importer.ref).symbol)
- importer.copy(ref = replaceTopQualifier(importer.ref, fullyQualifiedTopQualifier))
+ val fullyQualifiedTopQualifier =
+ toFullyQualifiedRef(topQualifierOf(importer.ref).symbol)
+
+ importer.copy(
+ ref = replaceTopQualifier(importer.ref, fullyQualifiedTopQualifier)
+ )
}
private def groupImporters(importers: Seq[Importer]): Seq[ImportGroup] =
importers
.groupBy(matchImportGroup) // Groups imports by importer prefix.
.mapValues(deduplicateImportees _ andThen organizeImportGroup)
- .map(ImportGroup.tupled)
+ .map { case (index, imports) => ImportGroup(index, imports) }
.toSeq
.sortBy(_.index)
private def deduplicateImportees(importers: Seq[Importer]): Seq[Importer] = {
// Scalameta `Tree` nodes do not provide structural equality comparisons, here we pretty-print
// them and compare the string results.
val seenImportees = mutable.Set.empty[(String, String)]
importers flatMap { importer =>
importer filterImportees { importee =>
importee.is[Importee.Wildcard] || importee.is[Importee.GivenAll] ||
seenImportees.add(importee.syntax -> importer.ref.syntax)
}
}
}
private def organizeImportGroup(importers: Seq[Importer]): Seq[Importer] = {
- // Issue #96: For importers with only a single `Importee.Name` importee, if the importee is
- // curly-braced, remove the unneeded curly-braces. For example: `import p.{X}` should be
- // rewritten into `import p.X`.
+ // https://github.com/liancheng/scalafix-organize-imports/issues/96: For
+ // importers with only a single `Importee.Name` importee, if the importee
+ // is curly-braced, remove the unneeded curly-braces. For example:
+ // `import p.{X}` should be rewritten into `import p.X`.
val noUnneededBraces = importers map removeRedundantBrances
val importeesSorted = locally {
config.groupedImports match {
- case GroupedImports.Merge => mergeImporters(noUnneededBraces, aggressive = false)
- case GroupedImports.AggressiveMerge => mergeImporters(noUnneededBraces, aggressive = true)
- case GroupedImports.Explode => explodeImportees(noUnneededBraces)
- case GroupedImports.Keep => noUnneededBraces
+ case GroupedImports.Merge =>
+ mergeImporters(noUnneededBraces, aggressive = false)
+ case GroupedImports.AggressiveMerge =>
+ mergeImporters(noUnneededBraces, aggressive = true)
+ case GroupedImports.Explode =>
+ explodeImportees(noUnneededBraces)
+ case GroupedImports.Keep =>
+ noUnneededBraces
}
} map (coalesceImportees _ andThen sortImportees)
config.importsOrder match {
- // Issue #84: The Scalameta `Tree` node pretty-printer checks whether the node originates
- // directly from the parser. If yes, the original source code text is returned, and may
- // interfere imports sort order. The `.copy()` call below erases the source position
- // information so that the pretty-printer would actually pretty-print an `Importer` into a
- // single line.
- //
- // See https://github.com/liancheng/scalafix-organize-imports/issues/84 for more details.
- case ImportsOrder.Ascii => importeesSorted sortBy (i => importerSyntax(i.copy()))
- case ImportsOrder.SymbolsFirst => sortImportersSymbolsFirst(importeesSorted)
- case ImportsOrder.Keep => importeesSorted
+ // https://github.com/liancheng/scalafix-organize-imports/issues/84: The Scalameta `Tree` node pretty-printer
+ // checks whether the node originates directly from the parser. If yes, the original source
+ // code text is returned, and may interfere imports sort order. The `.copy()` call below
+ // erases the source position information so that the pretty-printer would actually
+ // pretty-print an `Importer` into a single line.
+ case ImportsOrder.Ascii =>
+ importeesSorted sortBy (i => importerSyntax(i.copy()))
+ case ImportsOrder.SymbolsFirst =>
+ sortImportersSymbolsFirst(importeesSorted)
+ case ImportsOrder.Keep =>
+ importeesSorted
}
}
- private def removeRedundantBrances(importer: Importer): Importer = importer match {
+ private def removeRedundantBrances(importer: Importer): Importer =
+ importer match {
case i @ Importer(_, Importee.Name(_) :: Nil) =>
import Token.{Ident, LeftBrace, RightBrace}
i.tokens.reverse.toList match {
// The `.copy()` call erases the source position information from the original importer, so
// that instead of returning the original source text, the pretty-printer will reformat
// `importer` without the unneeded curly-braces.
case RightBrace() :: Ident(_) :: LeftBrace() :: _ => i.copy()
case _ => i
}
case _ => importer
}
- private def mergeImporters(importers: Seq[Importer], aggressive: Boolean): Seq[Importer] =
+ private def mergeImporters(
+ importers: Seq[Importer],
+ aggressive: Boolean
+ ): Seq[Importer] =
importers.groupBy(_.ref.syntax).values.toSeq.flatMap {
case importer :: Nil =>
// If this group has only one importer, returns it as is to preserve the original source
// level formatting.
importer :: Nil
case group @ Importer(ref, _) :: _ =>
val importeeLists = group map (_.importees)
val hasWildcard = group exists (_.hasWildcard)
val hasGivenAll = group exists (_.hasGivenAll)
// Collects the last set of unimports with a wildcard, if any. It cancels all previous
// unimports. E.g.:
//
// import p.{A => _}
// import p.{B => _, _}
// import p.{C => _, _}
//
// Only `C` is unimported. `A` and `B` are still available.
//
// TODO: Shall we issue a warning here as using order-sensitive imports is a bad practice?
val lastUnimportsWithWildcard = importeeLists.reverse collectFirst {
case Importees(_, _, unimports @ _ :: _, _, _, Some(_)) => unimports
}
val lastUnimportsWithGivenAll = importeeLists.reverse collectFirst {
case Importees(_, _, unimports @ _ :: _, _, Some(_), _) => unimports
}
// Collects all unimports without an accompanying wildcard.
- val unimports = importeeLists.collect { case Importees(_, _, unimports, _, None, None) =>
+ val unimports = importeeLists.collect {
+ case Importees(_, _, unimports, _, None, None) =>
unimports
}.flatten
- val (givens, nonGivens) = group.flatMap(_.importees).toList.partition(_.is[Importee.Given])
+ val (givens, nonGivens) =
+ group.flatMap(_.importees).toList.partition(_.is[Importee.Given])
// Here we assume that a name is renamed at most once within a single source file, which is
// true in most cases.
//
// Note that the IntelliJ IDEA Scala import optimizer does not handle this case properly
// either. If a name is renamed more than once, it only keeps one of the renames in the
// result and may break compilation (unless other renames are not actually referenced).
val renames = nonGivens
.collect { case rename: Importee.Rename => rename }
.groupBy(_.name.value)
.map {
case (_, rename :: Nil) => rename
case (_, renames @ (head @ Importee.Rename(from, _)) :: _) =>
diagnostics += TooManyAliases(from, renames)
head
}
.toList
// Collects distinct explicitly imported names, and filters out those that are also renamed.
// If an explicitly imported name is also renamed, both the original name and the new name
// are available. This implies that both of them must be preserved in the merged result, but
// in two separate import statements (Scala only allows a name to appear in an import at
// most once). E.g.:
//
// import p.A
// import p.{A => A1}
// import p.B
// import p.{B => B1}
//
// The above snippet should be rewritten into:
//
// import p.{A, B}
// import p.{A => A1, B => B1}
val (renamedImportedNames, importedNames) = {
- val renamedNames = renames.map { case Importee.Rename(Name(from), _) =>
+ val renamedNames =
+ renames.map { case Importee.Rename(Name(from), _) =>
from
}.toSet
nonGivens
.filter(_.is[Importee.Name])
.groupBy { case Importee.Name(Name(name)) => name }
.map { case (_, importees) => importees.head }
.toList
- .partition { case Importee.Name(Name(name)) => renamedNames contains name }
+ .partition { case Importee.Name(Name(name)) =>
+ renamedNames contains name
+ }
}
val mergedNonGivens = (hasWildcard, lastUnimportsWithWildcard) match {
case (true, _) =>
// A few things to note in this case:
//
// 1. Unimports are discarded because they are canceled by the wildcard. E.g.:
//
// import scala.collection.mutable.{Set => _, _}
// import scala.collection.mutable._
//
// The above two imports should be merged into:
//
// import scala.collection.mutable._
//
// 2. Explicitly imported names can NOT be discarded even though they seem to be covered
// by the wildcard, unless groupedImports is set to AggressiveMerge. This is because
// explicitly imported names have higher precedence than names imported via a
// wildcard. Discarding them may introduce ambiguity in some cases. E.g.:
//
// import scala.collection.immutable._
// import scala.collection.mutable._
// import scala.collection.mutable.Set
//
// object Main { val s: Set[Int] = ??? }
//
// The type of `Main.s` above is unambiguous because `mutable.Set` is explicitly
// imported, and has higher precedence than `immutable.Set`, which is made available
// via a wildcard. In this case, the imports should be merged into:
//
// import scala.collection.immutable._
// import scala.collection.mutable.{Set, _}
//
// rather than
//
// import scala.collection.immutable._
// import scala.collection.mutable._
//
// Otherwise, the type of `Main.s` becomes ambiguous and a compilation error is
// introduced.
//
// 3. However, the case discussed above is relatively rare in real life. A more common
// case is something like:
//
// import scala.collection.Set
// import scala.collection._
//
// In this case, we do want to merge them into:
//
// import scala.collection._
//
// rather than
//
// import scala.collection.{Set, _}
//
// To achieve this, users may set `groupedImports` to `AggressiveMerge`. Instead of
// being conservative and ensure correctness in all the cases, this option merges
// imports aggressively for conciseness.
//
// 4. Renames must be moved into a separate import statement to make sure that the
// original names made available by the wildcard are still preserved. E.g.:
//
// import p._
// import p.{A => A1}
//
// The above imports cannot be merged into
//
// import p.{A => A1, _}
//
// Otherwise, the original name `A` is no longer available.
if (aggressive) Seq(renames, Wildcard() :: Nil)
else Seq(renames, importedNames :+ Wildcard())
case (false, Some(lastUnimports)) =>
// A wildcard must be appended for unimports.
- Seq(renamedImportedNames, importedNames ++ renames ++ lastUnimports :+ Wildcard())
+ Seq(
+ renamedImportedNames,
+ importedNames ++ renames ++ lastUnimports :+ Wildcard()
+ )
case (false, None) =>
Seq(renamedImportedNames, importedNames ++ renames ++ unimports)
}
/* Adjust the result to add givens imports, these are
* are the Scala 3 way of importing implicits, which are not imported
* with the wildcard import.
*/
val newImporteeListsWithGivens = if (hasGivenAll) {
if (aggressive) mergedNonGivens :+ List(GivenAll())
else mergedNonGivens :+ (givens :+ GivenAll())
} else {
lastUnimportsWithGivenAll match {
- case Some(unimports) => mergedNonGivens :+ (givens ++ unimports :+ GivenAll())
- case None => mergedNonGivens :+ givens
+ case Some(unimports) =>
+ mergedNonGivens :+ (givens ++ unimports :+ GivenAll())
+ case None =>
+ mergedNonGivens :+ givens
}
}
- preserveOriginalImportersFormatting(group, newImporteeListsWithGivens, ref)
+ preserveOriginalImportersFormatting(
+ group,
+ newImporteeListsWithGivens,
+ ref
+ )
}
- private def sortImportersSymbolsFirst(importers: Seq[Importer]): Seq[Importer] =
+ private def sortImportersSymbolsFirst(
+ importers: Seq[Importer]
+ ): Seq[Importer] =
importers.sortBy { importer =>
- // See the comment marked with "Issue #84" for why a `.copy()` is needed.
+ // See the comment marked with "issues/84" for why a `.copy()` is needed.
val syntax = importer.copy().syntax
importer match {
case Importer(_, Importee.Wildcard() :: Nil) =>
syntax.patch(syntax.lastIndexOfSlice("._"), ".\u0001", 2)
case _ if importer.isCurlyBraced =>
syntax
.replaceFirst("[{]", "\u0002")
.patch(syntax.lastIndexOf("}"), "\u0002", 1)
case _ => syntax
}
}
private def coalesceImportees(importer: Importer): Importer = {
val Importees(names, renames, unimports, givens, _, _) = importer.importees
config.coalesceToWildcardImportThreshold
.filter(importer.importees.length > _)
// Skips if there's no `Name`s or `Given`s. `Rename`s and `Unimport`s cannot be coalesced.
.filterNot(_ => names.isEmpty && givens.isEmpty)
.map {
case _ if givens.isEmpty => renames ++ unimports :+ Wildcard()
case _ if names.isEmpty => renames ++ unimports :+ GivenAll()
case _ => renames ++ unimports :+ GivenAll() :+ Wildcard()
}
.map(importees => importer.copy(importees = importees))
.getOrElse(importer)
}
private def sortImportees(importer: Importer): Importer = {
import ImportSelectorsOrder._
// The Scala language spec allows an import expression to have at most one final wildcard, which
// can only appears in the last position.
val (wildcards, others) =
- importer.importees partition (i => i.is[Importee.Wildcard] || i.is[Importee.GivenAll])
+ importer.importees partition (i =>
+ i.is[Importee.Wildcard] || i.is[Importee.GivenAll]
+ )
val orderedImportees = config.importSelectorsOrder match {
- case Ascii => Seq(others, wildcards) map (_.sortBy(_.syntax)) reduce (_ ++ _)
- case SymbolsFirst => Seq(others, wildcards) map sortImporteesSymbolsFirst reduce (_ ++ _)
- case Keep => importer.importees
+ case Ascii =>
+ Seq(others, wildcards) map (_.sortBy(_.syntax)) reduce (_ ++ _)
+ case SymbolsFirst =>
+ Seq(others, wildcards) map sortImporteesSymbolsFirst reduce (_ ++ _)
+ case Keep =>
+ importer.importees
}
// Checks whether importees of the input importer are already sorted. If yes, we should return
// the original importer to preserve the original source level formatting.
val alreadySorted =
config.importSelectorsOrder == Keep ||
(importer.importees corresponds orderedImportees) { (lhs, rhs) =>
lhs.syntax == rhs.syntax
}
if (alreadySorted) importer else importer.copy(importees = orderedImportees)
}
/**
- * Returns the index of the group to which the given importer belongs. Each group is represented
- * by an `ImportMatcher`. If multiple `ImporterMatcher`s match the given import, the one matches
- * the longest prefix wins.
+ * Returns the index of the group to which the given importer belongs. Each
+ * group is represented by an `ImportMatcher`. If multiple `ImporterMatcher`s
+ * match the given import, the one matches the longest prefix wins.
*/
private def matchImportGroup(importer: Importer): Int = {
val matchedGroups = matchers
.map(_ matches importer)
.zipWithIndex
.filter { case (length, _) => length > 0 }
if (matchedGroups.isEmpty) wildcardGroupIndex
else {
val (_, index) = matchedGroups.maxBy { case (length, _) => length }
index
}
}
- private def insertOrganizedImports(token: Token, importGroups: Seq[ImportGroup]): Patch = {
- val prettyPrintedGroups = importGroups.map { case ImportGroup(index, imports) =>
+ private def insertOrganizedImports(
+ token: Token,
+ importGroups: Seq[ImportGroup]
+ ): Patch = {
+ val prettyPrintedGroups = importGroups.map {
+ case ImportGroup(index, imports) =>
index -> prettyPrintImportGroup(imports)
}
val blankLines = {
// Indices of all blank lines configured in `OrganizeImports.groups`, either automatically or
// manually.
- val blankLineIndices = matchers.zipWithIndex.collect { case (`---`, index) => index }.toSet
+ val blankLineIndices = matchers.zipWithIndex.collect {
+ case (`---`, index) => index
+ }.toSet
// Checks each pair of adjacent import groups. Inserts a blank line between them if necessary.
- importGroups map (_.index) sliding 2 filter (_.length == 2) flatMap { case Seq(lhs, rhs) =>
+ importGroups map (_.index) sliding 2 filter (_.length == 2) flatMap {
+ case Seq(lhs, rhs) =>
val hasBlankLine = blankLineIndices exists (i => lhs < i && i < rhs)
if (hasBlankLine) Some((lhs + 1) -> "") else None
}
}
val withBlankLines = (prettyPrintedGroups ++ blankLines)
.sortBy { case (index, _) => index }
.map { case (_, lines) => lines }
.mkString("\n")
// Global imports within curly-braced packages must be indented accordingly, e.g.:
//
// package foo {
// package bar {
// import baz
// import qux
// }
// }
val indented = withBlankLines.linesIterator.zipWithIndex.map {
// The first line will be inserted at an already indented position.
case (line, 0) => line
case (line, _) if line.isEmpty => line
case (line, _) => " " * token.pos.startColumn + line
}
Patch.addLeft(token, indented mkString "\n")
}
}
object OrganizeImports {
private case class ImportGroup(index: Int, imports: Seq[Importer])
private def patchPreset(
ruleConf: OrganizeImportsConfig,
conf: Conf
): Configured[OrganizeImportsConfig] = {
val preset = OrganizeImportsConfig.presets(ruleConf.preset)
val presetConf = ConfEncoder[OrganizeImportsConfig].write(preset)
- val userConf = ConfGet.getKey(conf, "OrganizeImports" :: Nil).getOrElse(Conf.Obj.empty)
+ val userConf =
+ ConfGet.getKey(conf, "OrganizeImports" :: Nil).getOrElse(Conf.Obj.empty)
val mergedConf = ConfOps.merge(presetConf, userConf)
ConfDecoder[OrganizeImportsConfig].read(mergedConf)
}
private def checkScalacOptions(
conf: OrganizeImportsConfig,
scalacOptions: List[String],
scalaVersion: String
): Configured[Rule] = {
val hasCompilerSupport = scalaVersion.startsWith("2")
val hasWarnUnused = hasCompilerSupport && {
val warnUnusedPrefix = Set("-Wunused", "-Ywarn-unused")
val warnUnusedString = Set("-Xlint", "-Xlint:unused")
scalacOptions exists { option =>
(warnUnusedPrefix exists option.startsWith) || (warnUnusedString contains option)
}
}
if (!conf.removeUnused || hasWarnUnused)
Configured.ok(new OrganizeImports(conf))
else if (hasCompilerSupport)
Configured.error(
"The Scala compiler option \"-Ywarn-unused\" is required to use OrganizeImports with"
+ " \"OrganizeImports.removeUnused\" set to true. To fix this problem, update your"
+ " build to use at least one Scala compiler option like -Ywarn-unused-import (2.11"
+ " only), -Ywarn-unused, -Xlint:unused (2.12.2 or above) or -Wunused (2.13 only)."
)
else
Configured.error(
"\"OrganizeImports.removeUnused\" is not supported on Scala 3 as the compiler is"
+ " not providing enough information. Run the rule with"
+ " \"OrganizeImports.removeUnused\" set to false to organize imports while keeping"
+ " potentially unused imports."
)
}
- private def buildImportMatchers(config: OrganizeImportsConfig): Seq[ImportMatcher] = {
+ private def buildImportMatchers(
+ config: OrganizeImportsConfig
+ ): Seq[ImportMatcher] = {
val withWildcard = {
val parsed = config.groups map parse
// The wildcard group should always exist. Appends one at the end if omitted.
if (parsed contains *) parsed else parsed :+ *
}
// Inserts a blank line marker between adjacent import groups when `blankLines` is `Auto`.
config.blankLines match {
case BlankLines.Manual => withWildcard
case BlankLines.Auto => withWildcard.flatMap(_ :: --- :: Nil)
}
}
private def positionOf(importee: Importee): Position =
importee match {
case Importee.Rename(from, _) => from.pos
case _ => importee.pos
}
- @tailrec private def collectImports(tree: Tree): (Seq[Import], Seq[Import]) = {
+ @tailrec private def collectImports(
+ tree: Tree
+ ): (Seq[Import], Seq[Import]) = {
def extractImports(stats: Seq[Stat]): (Seq[Import], Seq[Import]) = {
val (importStats, otherStats) = stats.span(_.is[Import])
val globalImports = importStats.map { case i: Import => i }
val localImports = otherStats.flatMap(_.collect { case i: Import => i })
(globalImports, localImports)
}
tree match {
case Source(Seq(p: Pkg)) => collectImports(p)
case Pkg(_, Seq(p: Pkg)) => collectImports(p)
case Source(stats) => extractImports(stats)
case Pkg(_, stats) => extractImports(stats)
case _ => (Nil, Nil)
}
}
private def prettyPrintImportGroup(group: Seq[Importer]): String =
group
.map(i => "import " + importerSyntax(i))
.mkString("\n")
/**
- * HACK: The Scalafix pretty-printer decides to add spaces after open and before close braces in
- * imports with multiple importees, i.e., `import a.{ b, c }` instead of `import a.{b, c}`. On the
- * other hand, renames are pretty-printed without the extra spaces, e.g., `import a.{b => c}`.
- * This behavior is not customizable and makes ordering imports by ASCII order complicated.
+ * HACK: The Scalafix pretty-printer decides to add spaces after open and
+ * before close braces in imports with multiple importees, i.e., `import a.{
+ * b, c }` instead of `import a.{b, c}`. On the other hand, renames are
+ * pretty-printed without the extra spaces, e.g., `import a.{b => c}`. This
+ * behavior is not customizable and makes ordering imports by ASCII order
+ * complicated.
*
- * This function removes the unwanted spaces as a workaround. In cases where users do want the
- * inserted spaces, Scalafmt should be used after running the `OrganizeImports` rule.
+ * This function removes the unwanted spaces as a workaround. In cases where
+ * users do want the inserted spaces, Scalafmt should be used after running
+ * the `OrganizeImports` rule.
*/
private def importerSyntax(importer: Importer): String =
importer.pos match {
case pos: Position.Range =>
// Position found, implies that `importer` was directly parsed from the source code. Returns
// the original parsed text to preserve the original source level formatting.
pos.text
case Position.None =>
// Position not found, implies that `importer` is derived from certain existing import
// statement(s). Pretty-prints it.
val syntax = importer.syntax
// 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 replacement is insufficient, e.g.,
// a quoted-identifier like "`{ d }`" may cause broken output.
(importer.isCurlyBraced, syntax lastIndexOfSlice " }") match {
- case (_, -1) => syntax
- case (true, index) => syntax.patch(index, "}", 2).replaceFirst("\\{ ", "{")
- case _ => syntax
+ case (_, -1) =>
+ syntax
+ case (true, index) =>
+ syntax.patch(index, "}", 2).replaceFirst("\\{ ", "{")
+ case _ =>
+ syntax
}
}
@tailrec private def topQualifierOf(term: Term): Term.Name =
term match {
case Term.Select(qualifier, _) => topQualifierOf(qualifier)
case name: Term.Name => name
}
- /** Replaces the top-qualifier of the input `term` with a new term `newTopQualifier`. */
- private def replaceTopQualifier(term: Term, newTopQualifier: Term.Ref): Term.Ref =
+ /**
+ * Replaces the top-qualifier of the input `term` with a new term
+ * `newTopQualifier`.
+ */
+ private def replaceTopQualifier(
+ term: Term,
+ newTopQualifier: Term.Ref
+ ): Term.Ref =
term match {
case _: Term.Name =>
newTopQualifier
case Term.Select(qualifier, name) =>
Term.Select(replaceTopQualifier(qualifier, newTopQualifier), name)
}
- private def sortImporteesSymbolsFirst(importees: List[Importee]): List[Importee] = {
+ private def sortImporteesSymbolsFirst(
+ importees: List[Importee]
+ ): List[Importee] = {
val symbols = ArrayBuffer.empty[Importee]
val lowerCases = ArrayBuffer.empty[Importee]
val upperCases = ArrayBuffer.empty[Importee]
importees.foreach {
case i if i.syntax.head.isLower => lowerCases += i
case i if i.syntax.head.isUpper => upperCases += i
case i => symbols += i
}
List(symbols, lowerCases, upperCases) flatMap (_ sortBy (_.syntax))
}
private def explodeImportees(importers: Seq[Importer]): Seq[Importer] =
importers flatMap {
case importer @ Importer(_, _ :: Nil) =>
// If the importer has exactly one importee, returns it as is to preserve the original
// source level formatting.
importer :: Nil
case importer @ Importer(
ref,
Importees(names, renames, unimports, givens, givenAll, wildcard)
) if givenAll.isDefined || wildcard.isDefined =>
// When a wildcard exists, all renames, unimports, and the wildcard must appear in the same
// importer, e.g.:
//
// import p.{A => _, B => _, C => D, E, _}
//
// should be rewritten into
//
// import p.{A => _, B => _, C => D, _}
// import p.E
val importeesList =
- (names ++ givens).map(_ :: Nil) :+ (renames ++ unimports ++ wildcard ++ givenAll)
+ (names ++ givens).map(
+ _ :: Nil
+ ) :+ (renames ++ unimports ++ wildcard ++ givenAll)
preserveOriginalImportersFormatting(Seq(importer), importeesList, ref)
case importer =>
importer.importees map (i => importer.copy(importees = i :: Nil))
}
/**
- * Issue #127: After merging or exploding imports, checks whether there are any input importers
- * left untouched. For those importers, returns the original importer instance to preserve the
- * original source level formatting.
+ * https://github.com/liancheng/scalafix-organize-imports/issues/127: After
+ * merging or exploding imports, checks whether there are any input importers
+ * left untouched. For those importers, returns the original importer instance
+ * to preserve the original source level formatting.
*/
private def preserveOriginalImportersFormatting(
importers: Seq[Importer],
newImporteeLists: Seq[List[Importee]],
newImporterRef: Term.Ref
) = {
val importerSyntaxMap = importers.map { i => i.copy().syntax -> i }.toMap
newImporteeLists filter (_.nonEmpty) map { importees =>
val newImporter = Importer(newImporterRef, importees)
importerSyntaxMap.getOrElse(newImporter.syntax, newImporter)
}
}
/**
* Categorizes a list of `Importee`s into the following four groups:
*
* - Names, e.g., `Seq`, `Option`, etc.
* - Renames, e.g., `{Long => JLong}`, `{Duration => D}`, etc.
* - Unimports, e.g., `{Foo => _}`.
* - Givens, e.g., `{given Foo}`.
* - GivenAll, i.e., `given`.
* - Wildcard, i.e., `_`.
*/
object Importees {
def unapply(importees: Seq[Importee]): Option[
(
List[Importee.Name],
List[Importee.Rename],
List[Importee.Unimport],
List[Importee.Given],
Option[Importee.GivenAll],
Option[Importee.Wildcard]
)
] = {
val names = ArrayBuffer.empty[Importee.Name]
val renames = ArrayBuffer.empty[Importee.Rename]
val givens = ArrayBuffer.empty[Importee.Given]
val unimports = ArrayBuffer.empty[Importee.Unimport]
var maybeWildcard: Option[Importee.Wildcard] = None
var maybeGivenAll: Option[Importee.GivenAll] = None
importees foreach {
case i: Importee.Wildcard => maybeWildcard = Some(i)
case i: Importee.Unimport => unimports += i
case i: Importee.Rename => renames += i
case i: Importee.Name => names += i
case i: Importee.Given => givens += i
case i: Importee.GivenAll => maybeGivenAll = Some(i)
}
Option(
(
names.toList,
renames.toList,
unimports.toList,
givens.toList,
maybeGivenAll,
maybeWildcard
)
)
}
}
implicit private class SymbolExtension(symbol: Symbol) {
/**
- * HACK: In certain cases, `Symbol#info` may throw `MissingSymbolException` due to some unknown
- * reason. This implicit class adds a safe version of `Symbol#info` to return `None` instead of
- * throw an exception when this happens.
+ * HACK: In certain cases, `Symbol#info` may throw `MissingSymbolException`
+ * due to some unknown reason. This implicit class adds a safe version of
+ * `Symbol#info` to return `None` instead of throw an exception when this
+ * happens.
*
* See [[https://github.com/scalacenter/scalafix/issues/1123 issue #1123]].
*/
def infoNoThrow(implicit doc: SemanticDocument): Option[SymbolInformation] =
Try(symbol.info).toOption.flatten
}
implicit private class ImporterExtension(importer: Importer) {
/** Checks whether the `Importer` is curly-braced when pretty-printed. */
def isCurlyBraced: Boolean = {
- val importees @ Importees(_, renames, unimports, _, _, _) = importer.importees
+ val importees @ Importees(_, renames, unimports, _, _, _) =
+ importer.importees
renames.nonEmpty || unimports.nonEmpty || importees.length > 1
}
/**
- * Returns an `Importer` with all the `Importee`s that are selected from the input `Importer`
- * and satisfy a predicate. If all the `Importee`s are selected, the input `Importer` instance
- * is returned to preserve the original source level formatting. If none of the `Importee`s are
+ * Returns an `Importer` with all the `Importee`s that are selected from the
+ * input `Importer` and satisfy a predicate. If all the `Importee`s are
+ * selected, the input `Importer` instance is returned to preserve the
+ * original source level formatting. If none of the `Importee`s are
* selected, returns a `None`.
*/
def filterImportees(f: Importee => Boolean): Option[Importer] = {
val filtered = importer.importees filter f
if (filtered.length == importer.importees.length) Some(importer)
else if (filtered.isEmpty) None
else Some(importer.copy(importees = filtered))
}
/** Returns true if the `Importer` contains a standalone wildcard. */
def hasWildcard: Boolean = {
val Importees(_, _, unimports, _, _, wildcard) = importer.importees
unimports.isEmpty && wildcard.nonEmpty
}
/** Returns true if the `Importer` contains a standalone given wildcard. */
def hasGivenAll: Boolean = {
val Importees(_, _, unimports, _, givenAll, _) = importer.importees
unimports.isEmpty && givenAll.nonEmpty
}
}
}
diff --combined scalafix-rules/src/main/scala/scalafix/internal/rule/OrganizeImportsConfig.scala
index 00000000,f91c16a3..d9703df4
mode 000000,100644..100644
--- /dev/null
--- a/rules/src/main/scala/fix/OrganizeImportsConfig.scala
++ b/scalafix-rules/src/main/scala/scalafix/internal/rule/OrganizeImportsConfig.scala
@@@ -1,0 -1,102 +1,111 @@@
-package fix
+package scalafix.internal.rule
import metaconfig.Conf
import metaconfig.ConfDecoder
import metaconfig.ConfEncoder
import metaconfig.generic.Surface
import metaconfig.generic.deriveDecoder
import metaconfig.generic.deriveEncoder
import metaconfig.generic.deriveSurface
import scalafix.internal.config.ReaderUtil
sealed trait ImportsOrder
object ImportsOrder {
case object Ascii extends ImportsOrder
case object SymbolsFirst extends ImportsOrder
case object Keep extends ImportsOrder
- implicit def reader: ConfDecoder[ImportsOrder] = ReaderUtil.oneOf(Ascii, SymbolsFirst, Keep)
- implicit def writer: ConfEncoder[ImportsOrder] = ConfEncoder.instance(v => Conf.Str(v.toString))
+ implicit def reader: ConfDecoder[ImportsOrder] =
+ ReaderUtil.oneOf(Ascii, SymbolsFirst, Keep)
+ implicit def writer: ConfEncoder[ImportsOrder] =
+ ConfEncoder.instance(v => Conf.Str(v.toString))
}
sealed trait ImportSelectorsOrder
object ImportSelectorsOrder {
case object Ascii extends ImportSelectorsOrder
case object SymbolsFirst extends ImportSelectorsOrder
case object Keep extends ImportSelectorsOrder
implicit def reader: ConfDecoder[ImportSelectorsOrder] =
ReaderUtil.oneOf(Ascii, SymbolsFirst, Keep)
implicit def writer: ConfEncoder[ImportSelectorsOrder] =
ConfEncoder.instance(v => Conf.Str(v.toString))
}
sealed trait GroupedImports
object GroupedImports {
case object AggressiveMerge extends GroupedImports
case object Merge extends GroupedImports
case object Explode extends GroupedImports
case object Keep extends GroupedImports
implicit def reader: ConfDecoder[GroupedImports] =
ReaderUtil.oneOf(AggressiveMerge, Merge, Explode, Keep)
implicit def writer: ConfEncoder[GroupedImports] =
ConfEncoder.instance(v => Conf.Str(v.toString))
}
sealed trait BlankLines
object BlankLines {
case object Auto extends BlankLines
case object Manual extends BlankLines
- implicit def reader: ConfDecoder[BlankLines] = ReaderUtil.oneOf(Auto, Manual)
- implicit def writer: ConfEncoder[BlankLines] = ConfEncoder.instance(v => Conf.Str(v.toString))
+ implicit def reader: ConfDecoder[BlankLines] =
+ ReaderUtil.oneOf(Auto, Manual)
+ implicit def writer: ConfEncoder[BlankLines] =
+ ConfEncoder.instance(v => Conf.Str(v.toString))
}
sealed trait Preset
object Preset {
case object DEFAULT extends Preset
case object INTELLIJ_2020_3 extends Preset
- implicit def reader: ConfDecoder[Preset] = ReaderUtil.oneOf(DEFAULT, INTELLIJ_2020_3)
- implicit def writer: ConfEncoder[Preset] = ConfEncoder.instance(v => Conf.Str(v.toString))
+ implicit def reader: ConfDecoder[Preset] =
+ ReaderUtil.oneOf(DEFAULT, INTELLIJ_2020_3)
+ implicit def writer: ConfEncoder[Preset] =
+ ConfEncoder.instance(v => Conf.Str(v.toString))
}
final case class OrganizeImportsConfig(
blankLines: BlankLines = BlankLines.Auto,
coalesceToWildcardImportThreshold: Option[Int] = None,
expandRelative: Boolean = false,
groupExplicitlyImportedImplicitsSeparately: Boolean = false,
groupedImports: GroupedImports = GroupedImports.Explode,
groups: Seq[String] = Seq(
"*",
"re:(javax?|scala)\\."
),
importSelectorsOrder: ImportSelectorsOrder = ImportSelectorsOrder.Ascii,
importsOrder: ImportsOrder = ImportsOrder.Ascii,
preset: Preset = Preset.DEFAULT,
removeUnused: Boolean = true
)
object OrganizeImportsConfig {
val default: OrganizeImportsConfig = OrganizeImportsConfig()
- implicit val surface: Surface[OrganizeImportsConfig] = deriveSurface
- implicit val encoder: ConfEncoder[OrganizeImportsConfig] = deriveEncoder
- implicit val decoder: ConfDecoder[OrganizeImportsConfig] = deriveDecoder(default)
+ implicit val surface: Surface[OrganizeImportsConfig] =
+ deriveSurface
+ implicit val encoder: ConfEncoder[OrganizeImportsConfig] =
+ deriveEncoder
+ implicit val decoder: ConfDecoder[OrganizeImportsConfig] =
+ deriveDecoder(default)
val presets: Map[Preset, OrganizeImportsConfig] = Map(
Preset.DEFAULT -> OrganizeImportsConfig(),
Preset.INTELLIJ_2020_3 -> OrganizeImportsConfig(
coalesceToWildcardImportThreshold = Some(5),
groupedImports = GroupedImports.Merge
)
)
}
diff --combined scalafix-rules/src/main/scala/scalafix/internal/rule/diagnostics.scala
index 00000000,58d2b5ee..bf7c6e6e
mode 000000,100644..100644
--- /dev/null
--- a/rules/src/main/scala/fix/diagnostics.scala
++ b/scalafix-rules/src/main/scala/scalafix/internal/rule/diagnostics.scala
@@@ -1,0 -1,42 +1,45 @@@
-package fix
+package scalafix.internal.rule
import scala.meta.Importee
import scala.meta.Name
import scala.meta.Term
+import scala.meta.XtensionSyntax
+
import scalafix.lint.Diagnostic
import scalafix.lint.LintSeverity
case class ImporterSymbolNotFound(ref: Term.Name) extends Diagnostic {
override def position: meta.Position = ref.pos
override def message: String =
s"Could not determine whether '${ref.syntax}' is fully-qualified because the symbol" +
" information is missing. We will continue processing assuming that it is fully-qualified." +
" Please check whether the corresponding .semanticdb file is properly generated."
override def severity: LintSeverity = LintSeverity.Warning
}
-case class TooManyAliases(name: Name, renames: Seq[Importee.Rename]) extends Diagnostic {
+case class TooManyAliases(name: Name, renames: Seq[Importee.Rename])
+ extends Diagnostic {
assert(renames.length > 1)
override def position: meta.Position = name.pos
override def message: String = {
val aliases = renames
.map { case Importee.Rename(_, Name(alias)) => alias }
.sorted
.map("'" + _ + "'")
val aliasList = aliases match {
case head :: last :: Nil => s"$head and $last"
case init :+ last => init.mkString("", ", ", s", and $last")
}
s"When `OrganizeImports.groupedImports` is set to `Merge`, renaming a name to multiple" +
s" aliases within the same source file is not supported. In this case, '${name.value}' is" +
s" renamed to $aliasList."
}
override def severity: LintSeverity = LintSeverity.Error
}
diff --combined scalafix-tests/input/src/main/scala-2/test/organizeImports/ExpandRelativePackageObject.scala
index 00000000,fa8019b0..b133e16c
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala-2/fix/ExpandRelativePackageObject.scala
++ b/scalafix-tests/input/src/main/scala-2/test/organizeImports/ExpandRelativePackageObject.scala
@@@ -1,0 -1,10 +1,10 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.expandRelative = true
*/
-package fix
+package test.organizeImports
import PackageObject.a
object ExpandRelativePackageObject
diff --combined scalafix-tests/input/src/main/scala-2/test/organizeImports/ExplicitlyImportedImplicits.scala
index 00000000,18b1c804..774d2427
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala-2/fix/ExplicitlyImportedImplicits.scala
++ b/scalafix-tests/input/src/main/scala-2/test/organizeImports/ExplicitlyImportedImplicits.scala
@@@ -1,0 -1,18 +1,18 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groupExplicitlyImportedImplicitsSeparately = true
*/
-package fix
+package test.organizeImports
import scala.concurrent.ExecutionContext
-import fix.Implicits.b._
+import test.organizeImports.Implicits.b._
import ExecutionContext.Implicits.global
-import fix.Implicits.a.{nonImplicit, intImplicit, stringImplicit}
+import test.organizeImports.Implicits.a.{nonImplicit, intImplicit, stringImplicit}
object ExplicitlyImportedImplicits {
def f1()(implicit i: Int) = ???
def f2()(implicit s: String) = ???
f1()
f2()
}
diff --combined scalafix-tests/input/src/main/scala-2/test/organizeImports/PresetDefault.scala
index 00000000,dba899e8..f473347c
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala-2/fix/PresetDefault.scala
++ b/scalafix-tests/input/src/main/scala-2/test/organizeImports/PresetDefault.scala
@@@ -1,0 -1,21 +1,22 @@@
/*
rules = [OrganizeImports]
OrganizeImports {
preset = DEFAULT
groupedImports = Merge
+ removeUnused = false
}
*/
-package fix
+package test.organizeImports
import scala.collection.mutable
import scala.util.Try
import java.math.BigDecimal
import java.math.BigInteger
import java.util.Collections.binarySearch
import java.util.Collections.emptyList
import javax.management.MXBean
-import fix.PresetDefault.a
+import test.organizeImports.PresetDefault.a
object PresetDefault {
val a: Any = ???
}
diff --combined scalafix-tests/input/src/main/scala-2/test/organizeImports/PresetIntelliJ_2020_3.scala
index 00000000,ee66e39a..1415bc93
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala-2/fix/PresetIntelliJ_2020_3.scala
++ b/scalafix-tests/input/src/main/scala-2/test/organizeImports/PresetIntelliJ_2020_3.scala
@@@ -1,0 -1,21 +1,22 @@@
/*
rules = [OrganizeImports]
OrganizeImports {
preset = INTELLIJ_2020_3
groupedImports = Explode
+ removeUnused = false
}
*/
-package fix
+package test.organizeImports
import scala.collection.mutable
import scala.util.Try
import java.math.BigDecimal
import java.math.BigInteger
import java.util.Collections.binarySearch
import java.util.Collections.emptyList
import javax.management.MXBean
-import fix.PresetIntelliJ_2020_3.a
+import test.organizeImports.PresetIntelliJ_2020_3.a
object PresetIntelliJ_2020_3 {
val a: Any = ???
}
diff --combined scalafix-tests/input/src/main/scala-2/test/organizeImports/RemoveUnused.scala
index 00000000,47ffd9d6..43040f9f
mode 000000,100644..100644
--- /dev/null
--- a/inputUnusedImports/src/main/scala-2/fix/RemoveUnused.scala
++ b/scalafix-tests/input/src/main/scala-2/test/organizeImports/RemoveUnused.scala
@@@ -1,0 -1,19 +1,19 @@@
/*
rules = [OrganizeImports]
OrganizeImports {
groups = ["re:javax?\\.", "scala.", "*"]
removeUnused = true
}
*/
-package fix
+package test.organizeImports
-import fix.UnusedImports.a.{v1, v2}
-import fix.UnusedImports.b.v3
-import fix.UnusedImports.c.{v5 => w1, v6 => w2}
-import fix.UnusedImports.d.{v7 => unused, _}
+import test.organizeImports.UnusedImports.a.{v1, v2}
+import test.organizeImports.UnusedImports.b.v3
+import test.organizeImports.UnusedImports.c.{v5 => w1, v6 => w2}
+import test.organizeImports.UnusedImports.d.{v7 => unused, _}
object RemoveUnused {
val x1 = v1
val x2 = w2
val x3 = v8
}
diff --combined scalafix-tests/input/src/main/scala-2/test/organizeImports/RemoveUnusedDisabled.scala
index 00000000,34d08b63..d839dd34
mode 000000,100644..100644
--- /dev/null
--- a/inputUnusedImports/src/main/scala-2/fix/RemoveUnusedDisabled.scala
++ b/scalafix-tests/input/src/main/scala-2/test/organizeImports/RemoveUnusedDisabled.scala
@@@ -1,0 -1,21 +1,21 @@@
/*
rules = [OrganizeImports]
OrganizeImports {
groups = ["re:javax?\\.", "scala.", "*"]
removeUnused = false
}
*/
-package fix
+package test.organizeImports
-import fix.UnusedImports.a.{v1, v2}
-import fix.UnusedImports.b.v3
-import fix.UnusedImports.c.{v5 => w1, v6 => w2}
-import fix.UnusedImports.d.{v7 => unused, _}
+import test.organizeImports.UnusedImports.a.{v1, v2}
+import test.organizeImports.UnusedImports.b.v3
+import test.organizeImports.UnusedImports.c.{v5 => w1, v6 => w2}
+import test.organizeImports.UnusedImports.d.{v7 => unused, _}
object RemoveUnusedDisabled {
- import fix.UnusedImports.e.v9
+ import test.organizeImports.UnusedImports.e.v9
val x1 = v1
val x2 = w2
val x3 = v8
}
diff --combined scalafix-tests/input/src/main/scala-2/test/organizeImports/RemoveUnusedLocal.scala
index 00000000,85db5211..336d0cbb
mode 000000,100644..100644
--- /dev/null
--- a/inputUnusedImports/src/main/scala-2/fix/RemoveUnusedLocal.scala
++ b/scalafix-tests/input/src/main/scala-2/test/organizeImports/RemoveUnusedLocal.scala
@@@ -1,0 -1,20 +1,20 @@@
/*
rules = [OrganizeImports]
OrganizeImports {
groups = ["re:javax?\\.", "scala.", "*"]
removeUnused = true
}
*/
-package fix
+package test.organizeImports
object RemoveUnusedLocal {
import UnusedImports._
import a.{v1, v2}
import b.v3
import c.{v5 => w1, v6 => w2}
import d.{v7 => unused, _}
val x1 = v1
val x2 = w2
val x3 = v8
}
diff --combined scalafix-tests/input/src/main/scala-2/test/organizeImports/RemoveUnusedMixed.scala
index 00000000,6a848740..030911ed
mode 000000,100644..100644
--- /dev/null
--- a/inputUnusedImports/src/main/scala-2/fix/RemoveUnusedMixed.scala
++ b/scalafix-tests/input/src/main/scala-2/test/organizeImports/RemoveUnusedMixed.scala
@@@ -1,0 -1,20 +1,20 @@@
/*
rules = [OrganizeImports]
OrganizeImports {
groups = ["re:javax?\\.", "scala.", "*"]
removeUnused = true
}
*/
-package fix
+package test.organizeImports
-import fix.UnusedImports.a.{v1, v2}
-import fix.UnusedImports.b.v3
-import fix.UnusedImports.c.{v5 => w1, v6 => w2}
-import fix.UnusedImports.d.{v7 => unused, _}
+import test.organizeImports.UnusedImports.a.{v1, v2}
+import test.organizeImports.UnusedImports.b.v3
+import test.organizeImports.UnusedImports.c.{v5 => w1, v6 => w2}
+import test.organizeImports.UnusedImports.d.{v7 => unused, _}
object RemoveUnusedMixed {
- import fix.UnusedImports.e.v9
+ import test.organizeImports.UnusedImports.e.v9
val x1 = v1
val x2 = w2
val x3 = v8
}
diff --combined scalafix-tests/input/src/main/scala-2/test/organizeImports/RemoveUnusedRelative.scala
index 00000000,360ebe66..68926796
mode 000000,100644..100644
--- /dev/null
--- a/inputUnusedImports/src/main/scala-2/fix/RemoveUnusedRelative.scala
++ b/scalafix-tests/input/src/main/scala-2/test/organizeImports/RemoveUnusedRelative.scala
@@@ -1,0 -1,26 +1,26 @@@
/*
rules = [OrganizeImports]
OrganizeImports {
expandRelative = true
groupedImports = Explode
groups = ["re:javax?\\.", "scala.", "*"]
removeUnused = true
}
*/
-package fix
+package test.organizeImports
-import fix.UnusedImports.a
-import fix.UnusedImports.b
-import fix.UnusedImports.c
-import fix.UnusedImports.d
+import test.organizeImports.UnusedImports.a
+import test.organizeImports.UnusedImports.b
+import test.organizeImports.UnusedImports.c
+import test.organizeImports.UnusedImports.d
import a.{v1, v2}
import b.v3
import c.{v5 => w1, v6 => w2}
import d.{v7 => unused, _}
object RemoveUnusedRelative {
val x1 = v1
val x2 = w2
val x3 = v8
}
diff --combined scalafix-tests/input/src/main/scala-3/test/organizeImports/CoalesceImporteesGivensAndNames.scala
index 00000000,bf6fc672..0d6a6fe0
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala-3/fix/CoalesceImporteesGivensAndNames.scala
++ b/scalafix-tests/input/src/main/scala-3/test/organizeImports/CoalesceImporteesGivensAndNames.scala
@@@ -1,0 -1,14 +1,14 @@@
/*
rules = [OrganizeImports]
OrganizeImports {
groupedImports = Keep
coalesceToWildcardImportThreshold = 2
removeUnused = false
}
*/
-package fix
+package test.organizeImports
-import fix.Givens._
-import fix.Givens.{A, B => B1, C => _, given D, _}
+import test.organizeImports.Givens._
+import test.organizeImports.Givens.{A, B => B1, C => _, given D, _}
object CoalesceImporteesGivensAndNames
diff --combined scalafix-tests/input/src/main/scala-3/test/organizeImports/CoalesceImporteesNoGivens.scala
index 00000000,ae931e84..82e3aa7a
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala-3/fix/CoalesceImporteesNoGivens.scala
++ b/scalafix-tests/input/src/main/scala-3/test/organizeImports/CoalesceImporteesNoGivens.scala
@@@ -1,0 -1,13 +1,13 @@@
/*
rules = [OrganizeImports]
OrganizeImports {
groupedImports = Keep
coalesceToWildcardImportThreshold = 2
removeUnused = false
}
*/
-package fix
+package test.organizeImports
-import fix.Givens.{A, B, C => C1}
+import test.organizeImports.Givens.{A, B, C => C1}
object CoalesceImporteesNoGivens
diff --combined scalafix-tests/input/src/main/scala-3/test/organizeImports/CoalesceImporteesNoGivensNoNames.scala
index 00000000,bc9a9124..e91fedb2
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala-3/fix/CoalesceImporteesNoGivensNoNames.scala
++ b/scalafix-tests/input/src/main/scala-3/test/organizeImports/CoalesceImporteesNoGivensNoNames.scala
@@@ -1,0 -1,13 +1,13 @@@
/*
rules = [OrganizeImports]
OrganizeImports {
groupedImports = Keep
coalesceToWildcardImportThreshold = 2
removeUnused = false
}
*/
-package fix
+package test.organizeImports
-import fix.Givens.{A => A1, B => _, _}
+import test.organizeImports.Givens.{A => A1, B => _, _}
object CoalesceImporteesNoGivensNoNames
diff --combined scalafix-tests/input/src/main/scala-3/test/organizeImports/CoalesceImporteesNoNames.scala
index 00000000,63ecb353..9e374ccf
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala-3/fix/CoalesceImporteesNoNames.scala
++ b/scalafix-tests/input/src/main/scala-3/test/organizeImports/CoalesceImporteesNoNames.scala
@@@ -1,0 -1,14 +1,14 @@@
/*
rules = [OrganizeImports]
OrganizeImports {
groupedImports = Keep
coalesceToWildcardImportThreshold = 2
removeUnused = false
}
*/
-package fix
+package test.organizeImports
-import fix.Givens._
-import fix.Givens.{A => A1, given B, given C}
+import test.organizeImports.Givens._
+import test.organizeImports.Givens.{A => A1, given B, given C}
object CoalesceImporteesNoNames
diff --combined scalafix-tests/input/src/main/scala-3/test/organizeImports/DeduplicateGivenImportees.scala
index 00000000,7a469b94..9005f193
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala-3/fix/DeduplicateGivenImportees.scala
++ b/scalafix-tests/input/src/main/scala-3/test/organizeImports/DeduplicateGivenImportees.scala
@@@ -1,0 -1,13 +1,13 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
*/
-package fix
+package test.organizeImports
-import fix.Givens._
-import fix.Givens.{given A, given B}
-import fix.Givens.given A
-import fix.Givens.given C
-import fix.Givens.given C
+import test.organizeImports.Givens._
+import test.organizeImports.Givens.{given A, given B}
+import test.organizeImports.Givens.given A
+import test.organizeImports.Givens.given C
+import test.organizeImports.Givens.given C
object DeduplicateGivenImportees
diff --combined scalafix-tests/input/src/main/scala-3/test/organizeImports/ExpandGiven.scala
index 00000000,b92ca178..f23f6848
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala-3/fix/ExpandGiven.scala
++ b/scalafix-tests/input/src/main/scala-3/test/organizeImports/ExpandGiven.scala
@@@ -1,0 -1,12 +1,12 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
*/
-package fix
+package test.organizeImports
-import fix.GivenImports.Beta
-import fix.GivenImports.Alpha
-import fix.GivenImports.{given Beta, given Alpha}
+import test.organizeImports.GivenImports.Beta
+import test.organizeImports.GivenImports.Alpha
+import test.organizeImports.GivenImports.{given Beta, given Alpha}
import scala.util.Either
object ExpandGiven
diff --combined scalafix-tests/input/src/main/scala-3/test/organizeImports/ExpandUnimportGiven.scala
index 00000000,eb31b93f..457db872
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala-3/fix/ExpandUnimportGiven.scala
++ b/scalafix-tests/input/src/main/scala-3/test/organizeImports/ExpandUnimportGiven.scala
@@@ -1,0 -1,14 +1,14 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
*/
-package fix
+package test.organizeImports
-import fix.GivenImports.Beta
-import fix.GivenImports.Alpha
-import fix.GivenImports.given Alpha
-import fix.GivenImports.{alpha => _}
-import fix.GivenImports.{beta => _, given}
+import test.organizeImports.GivenImports.Beta
+import test.organizeImports.GivenImports.Alpha
+import test.organizeImports.GivenImports.given Alpha
+import test.organizeImports.GivenImports.{alpha => _}
+import test.organizeImports.GivenImports.{beta => _, given}
import scala.util.Either
object ExpandUnimportGiven
diff --combined scalafix-tests/input/src/main/scala-3/test/organizeImports/GroupedGivenImportsMergeUnimports.scala
index 00000000,35b1f2b7..f34b7189
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala-3/fix/GroupedGivenImportsMergeUnimports.scala
++ b/scalafix-tests/input/src/main/scala-3/test/organizeImports/GroupedGivenImportsMergeUnimports.scala
@@@ -1,0 -1,19 +1,19 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groupedImports = Merge
*/
-package fix
+package test.organizeImports
-import fix.GivenImports._
-import fix.GivenImports.{alpha => _, given}
-import fix.GivenImports.{given Beta}
-import fix.GivenImports.{gamma => _, given}
-import fix.GivenImports.{given Zeta}
+import test.organizeImports.GivenImports._
+import test.organizeImports.GivenImports.{alpha => _, given}
+import test.organizeImports.GivenImports.{given Beta}
+import test.organizeImports.GivenImports.{gamma => _, given}
+import test.organizeImports.GivenImports.{given Zeta}
-import fix.GivenImports2.{alpha => _}
-import fix.GivenImports2.{beta => _}
-import fix.GivenImports2.{given Gamma}
-import fix.GivenImports2.{given Zeta}
+import test.organizeImports.GivenImports2.{alpha => _}
+import test.organizeImports.GivenImports2.{beta => _}
+import test.organizeImports.GivenImports2.{given Gamma}
+import test.organizeImports.GivenImports2.{given Zeta}
object GroupedGivenImportsMergeUnimports
diff --combined scalafix-tests/input/src/main/scala-3/test/organizeImports/GroupedImportsAggressiveMergeGivenAll.scala
index 00000000,4ab1627a..bb0632fc
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala-3/fix/GroupedImportsAggressiveMergeGivenAll.scala
++ b/scalafix-tests/input/src/main/scala-3/test/organizeImports/GroupedImportsAggressiveMergeGivenAll.scala
@@@ -1,0 -1,23 +1,23 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groupedImports = AggressiveMerge
*/
-package fix
+package test.organizeImports
-import fix.MergeImports.Wildcard1._
-import fix.MergeImports.Wildcard1.{a => _, _}
-import fix.MergeImports.Wildcard1.{b => B}
-import fix.MergeImports.Wildcard1.{c => _, _}
-import fix.MergeImports.Wildcard1.d
+import test.organizeImports.MergeImports.Wildcard1._
+import test.organizeImports.MergeImports.Wildcard1.{a => _, _}
+import test.organizeImports.MergeImports.Wildcard1.{b => B}
+import test.organizeImports.MergeImports.Wildcard1.{c => _, _}
+import test.organizeImports.MergeImports.Wildcard1.d
-import fix.GivenImports._
-import fix.GivenImports.{Alpha, Beta, Zeta}
-import fix.GivenImports.{given Alpha, given Beta, given Zeta}
-import fix.GivenImports.given
+import test.organizeImports.GivenImports._
+import test.organizeImports.GivenImports.{Alpha, Beta, Zeta}
+import test.organizeImports.GivenImports.{given Alpha, given Beta, given Zeta}
+import test.organizeImports.GivenImports.given
-import fix.MergeImports.Wildcard2._
-import fix.MergeImports.Wildcard2.{a, b}
+import test.organizeImports.MergeImports.Wildcard2._
+import test.organizeImports.MergeImports.Wildcard2.{a, b}
object GroupedImportsAggressiveMergeGivenAll
diff --combined scalafix-tests/input/src/main/scala-3/test/organizeImports/MergeGiven.scala
index 00000000,5d5204c9..a7d628d9
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala-3/fix/MergeGiven.scala
++ b/scalafix-tests/input/src/main/scala-3/test/organizeImports/MergeGiven.scala
@@@ -1,0 -1,14 +1,14 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groupedImports = Merge
*/
-package fix
+package test.organizeImports
-import fix.GivenImports.Beta
-import fix.GivenImports.Alpha
-import fix.GivenImports.{given Beta}
-import fix.GivenImports.{given Alpha}
+import test.organizeImports.GivenImports.Beta
+import test.organizeImports.GivenImports.Alpha
+import test.organizeImports.GivenImports.{given Beta}
+import test.organizeImports.GivenImports.{given Alpha}
import scala.util.Either
object MergeGiven
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/AlreadyOrganized.scala
index 00000000,6488ed44..392a2d28
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/AlreadyOrganized.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/AlreadyOrganized.scala
@@@ -1,0 -1,15 +1,15 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groupedImports = Merge
*/
-package fix
+package test.organizeImports
import scala.collection.mutable.{
ArrayBuffer,
Map,
Queue,
Set
}
object AlreadyOrganized
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/BlankLinesManual.scala
index 00000000,060d4a17..593975a7
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/BlankLinesManual.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/BlankLinesManual.scala
@@@ -1,0 -1,21 +1,21 @@@
/*
rules = [OrganizeImports]
OrganizeImports {
blankLines = Manual
groups = [
"re:javax?\\."
"scala."
"---"
"*"
]
removeUnused = false
}
*/
-package fix
+package test.organizeImports
import scala.collection.mutable
import java.util.Arrays
import sun.misc.Unsafe
object BlankLinesManual
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/CoalesceImportees.scala
index 00000000,8c1e9f7f..6a35ea97
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/CoalesceImportees.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/CoalesceImportees.scala
@@@ -1,0 -1,16 +1,16 @@@
/*
rules = [OrganizeImports]
OrganizeImports {
groupedImports = Keep
coalesceToWildcardImportThreshold = 3
removeUnused = false
}
*/
-package fix
+package test.organizeImports
import scala.collection.immutable.{Seq, Map, Vector}
import scala.collection.mutable.{Buffer, Seq, Map, Set}
import scala.concurrent.{Await, Channel => Ch, Future, Promise, duration}
import scala.util.{Either, Random => _, Try, Success, Failure}
object CoalesceImportees
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/CurlyBracedSingleImportee.scala
index 00000000,66eb557d..9f8255a6
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/CurlyBracedSingleImportee.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/CurlyBracedSingleImportee.scala
@@@ -1,0 -1,10 +1,10 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
*/
-package fix
+package test.organizeImports
import scala.collection.{Map}
import scala.collection.{Set => ImmutableSet}
object CurlyBracedSingleImportee
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/DeduplicateImportees.scala
index 00000000,8b7fde25..4150b056
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/DeduplicateImportees.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/DeduplicateImportees.scala
@@@ -1,0 -1,12 +1,12 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
*/
-package fix
+package test.organizeImports
import scala.collection.immutable.Vector
import scala.collection.immutable.{Map => Dict}
import scala.collection.immutable.{Set => _, Map => Dict, _}
import scala.collection.immutable.{Map => Dict, Vector}
object DeduplicateImportees
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/ExpandRelative.scala
index 00000000,4f0081d7..8b900b7a
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/ExpandRelative.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/ExpandRelative.scala
@@@ -1,0 -1,12 +1,12 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.expandRelative = true
*/
-package fix
+package test.organizeImports
import scala.util
import util.control
import control.NonFatal
object ExpandRelative
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/ExpandRelativeEmptyPackage.scala
index 00000000,1ffe6ba6..cfa3dd50
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/ExpandRelativeRootPackage.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/ExpandRelativeEmptyPackage.scala
@@@ -1,0 -1,22 +1,22 @@@
/*
rules = [OrganizeImports]
OrganizeImports {
expandRelative = true
groupedImports = Explode
removeUnused = false
}
*/
import P._
import Q.x
import Q._
object P {
object x
}
object Q {
object x
object y
}
-object ExpandRelativeRootPackage
+object ExpandRelativeEmptyPackage
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/ExpandRelativeMultiGroups.scala
index 00000000,e6e5a1cc..7fa9ce00
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/ExpandRelativeMultiGroups.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/ExpandRelativeMultiGroups.scala
@@@ -1,0 -1,14 +1,14 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.expandRelative = true
*/
-package fix
+package test.organizeImports
import scala.util
import java.time.Clock
import util.control
import javax.management.JMX
import control.NonFatal
object ExpandRelativeMultiGroups
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/ExpandRelativeQuotedIdent.scala
index 00000000,1ce6c7dc..834cea54
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/ExpandRelativeQuotedIdent.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/ExpandRelativeQuotedIdent.scala
@@@ -1,0 -1,13 +1,13 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.expandRelative = true
*/
-package fix
+package test.organizeImports
import QuotedIdent.`a.b`
import QuotedIdent.`macro`
import `a.b`.c
import `a.b`.`{ d }`
object ExpandRelativeQuotedIdent
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/ExpandRelativeRootPackage.scala
index 00000000,241c3e75..0b096c22
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/ExpandRelativeRootPackage.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/ExpandRelativeRootPackage.scala
@@@ -1,0 -1,13 +1,13 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.expandRelative = true
*/
-package fix
+package test.organizeImports
import _root_.scala.collection.mutable.ArrayBuffer
import _root_.scala.util
import util.control
import control.NonFatal
object ExpandRelativeRootPackage
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/ExplodeImportsFormatPreserving.scala
index 00000000,8b769d1b..179b9c68
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/ExplodeImportsFormatPreserving.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/ExplodeImportsFormatPreserving.scala
@@@ -1,0 -1,12 +1,12 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groupedImports = Explode
*/
-package fix
+package test.organizeImports
-import fix.ExplodeImports.FormatPreserving.g1.{ a, b }
-import fix.ExplodeImports.FormatPreserving.g2.{ c => C, _ }
+import test.organizeImports.ExplodeImports.FormatPreserving.g1.{ a, b }
+import test.organizeImports.ExplodeImports.FormatPreserving.g2.{ c => C, _ }
object ExplodeImportsFormatPreserving
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/GlobalImportsOnly.scala
index 00000000,58dc4636..76d13478
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/GlobalImportsOnly.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/GlobalImportsOnly.scala
@@@ -1,0 -1,17 +1,17 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
*/
-package fix
+package test.organizeImports
import scala.collection.mutable
import scala.concurrent.duration.Duration
import java.time.Clock
import java.sql.DriverManager
object GlobalImportsOnly
// These imports should not be organized
import java.time.Duration, java.sql.Connection
object Foo
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/GroupedImportsAggressiveMergeWildcard.scala
index 00000000,6cfa22d8..e31c7082
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/GroupedImportsAggressiveMergeWildcard.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/GroupedImportsAggressiveMergeWildcard.scala
@@@ -1,0 -1,17 +1,17 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groupedImports = AggressiveMerge
*/
-package fix
+package test.organizeImports
-import fix.MergeImports.Wildcard1._
-import fix.MergeImports.Wildcard1.{a => _, _}
-import fix.MergeImports.Wildcard1.{b => B}
-import fix.MergeImports.Wildcard1.{c => _, _}
-import fix.MergeImports.Wildcard1.d
+import test.organizeImports.MergeImports.Wildcard1._
+import test.organizeImports.MergeImports.Wildcard1.{a => _, _}
+import test.organizeImports.MergeImports.Wildcard1.{b => B}
+import test.organizeImports.MergeImports.Wildcard1.{c => _, _}
+import test.organizeImports.MergeImports.Wildcard1.d
-import fix.MergeImports.Wildcard2._
-import fix.MergeImports.Wildcard2.{a, b}
+import test.organizeImports.MergeImports.Wildcard2._
+import test.organizeImports.MergeImports.Wildcard2.{a, b}
object GroupedImportsAggressiveMergeWildcard
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/GroupedImportsExplode.scala
index 00000000,798752dc..059af75c
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/GroupedImportsExplode.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/GroupedImportsExplode.scala
@@@ -1,0 -1,9 +1,9 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
*/
-package fix
+package test.organizeImports
import scala.collection.mutable.{ArrayBuffer, Buffer, StringBuilder}
object GroupedImportsExplode
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/GroupedImportsExplodeMixed.scala
index 00000000,9c208061..9d438645
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/GroupedImportsExplodeMixed.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/GroupedImportsExplodeMixed.scala
@@@ -1,0 -1,10 +1,10 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
*/
-package fix
+package test.organizeImports
import scala.collection.immutable._
import scala.collection.mutable.{Map, Seq => S, Buffer => _, _}
object GroupedImportsExplodeMixed
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/GroupedImportsExplodeUnimport.scala
index 00000000,83dfdb0e..acd497ce
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/GroupedImportsExplodeUnimport.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/GroupedImportsExplodeUnimport.scala
@@@ -1,0 -1,9 +1,9 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
*/
-package fix
+package test.organizeImports
import scala.collection.{Seq => _, _}
object GroupedImportExplodeUnimport
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/GroupedImportsKeep.scala
index 00000000,dfcbb195..7ba18bd9
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/GroupedImportsKeep.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/GroupedImportsKeep.scala
@@@ -1,0 -1,11 +1,11 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groupedImports = Keep
*/
-package fix
+package test.organizeImports
import scala.collection.mutable.{ArrayBuffer, Buffer}
import scala.collection.mutable.StringBuilder
object GroupedImportsKeep
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/GroupedImportsMerge.scala
index 00000000,ebb06c11..21761dfa
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/GroupedImportsMerge.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/GroupedImportsMerge.scala
@@@ -1,0 -1,12 +1,12 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groupedImports = Merge
*/
-package fix
+package test.organizeImports
import scala.collection.mutable.Buffer
import scala.collection.mutable.StringBuilder
import scala.collection.mutable.ArrayBuffer
object GroupedImportsMerge
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/GroupedImportsMergeDedup.scala
index 00000000,c7fcd5ed..15fe853f
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/GroupedImportsMergeDedup.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/GroupedImportsMergeDedup.scala
@@@ -1,0 -1,15 +1,15 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groupedImports = Merge
*/
-package fix
+package test.organizeImports
-import fix.MergeImports.Dedup.a
-import fix.MergeImports.Dedup.a
-import fix.MergeImports.Dedup.{b => b1}
-import fix.MergeImports.Dedup.{b => b1}
-import fix.MergeImports.Dedup.{c => _}
-import fix.MergeImports.Dedup.{c => _}
+import test.organizeImports.MergeImports.Dedup.a
+import test.organizeImports.MergeImports.Dedup.a
+import test.organizeImports.MergeImports.Dedup.{b => b1}
+import test.organizeImports.MergeImports.Dedup.{b => b1}
+import test.organizeImports.MergeImports.Dedup.{c => _}
+import test.organizeImports.MergeImports.Dedup.{c => _}
object GroupedImportsMergeDedup
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/GroupedImportsMergeRenames.scala
index 00000000,3718c2a9..3a4c2cc6
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/GroupedImportsMergeRenames.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/GroupedImportsMergeRenames.scala
@@@ -1,0 -1,19 +1,19 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groupedImports = Merge
*/
-package fix
+package test.organizeImports
-import fix.MergeImports.Rename1.{a => A}
-import fix.MergeImports.Rename1.{b => B}
-import fix.MergeImports.Rename1.c
-import fix.MergeImports.Rename1.d
+import test.organizeImports.MergeImports.Rename1.{a => A}
+import test.organizeImports.MergeImports.Rename1.{b => B}
+import test.organizeImports.MergeImports.Rename1.c
+import test.organizeImports.MergeImports.Rename1.d
-import fix.MergeImports.Rename2.a
-import fix.MergeImports.Rename2.{a => A}
-import fix.MergeImports.Rename2.b
-import fix.MergeImports.Rename2.{b => B}
-import fix.MergeImports.Rename2.c
+import test.organizeImports.MergeImports.Rename2.a
+import test.organizeImports.MergeImports.Rename2.{a => A}
+import test.organizeImports.MergeImports.Rename2.b
+import test.organizeImports.MergeImports.Rename2.{b => B}
+import test.organizeImports.MergeImports.Rename2.c
object GroupedImportsMergeRenames
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/GroupedImportsMergeUnimports.scala
index 00000000,b1275c73..51121366
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/GroupedImportsMergeUnimports.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/GroupedImportsMergeUnimports.scala
@@@ -1,0 -1,18 +1,18 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groupedImports = Merge
*/
-package fix
+package test.organizeImports
-import fix.MergeImports.Unimport1.{a => _, _}
-import fix.MergeImports.Unimport1.{b => B}
-import fix.MergeImports.Unimport1.{c => _, _}
-import fix.MergeImports.Unimport1.d
+import test.organizeImports.MergeImports.Unimport1.{a => _, _}
+import test.organizeImports.MergeImports.Unimport1.{b => B}
+import test.organizeImports.MergeImports.Unimport1.{c => _, _}
+import test.organizeImports.MergeImports.Unimport1.d
-import fix.MergeImports.Unimport2.{a => _}
-import fix.MergeImports.Unimport2.{b => _}
-import fix.MergeImports.Unimport2.{c => C}
-import fix.MergeImports.Unimport2.d
+import test.organizeImports.MergeImports.Unimport2.{a => _}
+import test.organizeImports.MergeImports.Unimport2.{b => _}
+import test.organizeImports.MergeImports.Unimport2.{c => C}
+import test.organizeImports.MergeImports.Unimport2.d
object GroupedImportsMergeUnimports
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/GroupedImportsMergeWildcard.scala
index 00000000,0133646c..b8114850
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/GroupedImportsMergeWildcard.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/GroupedImportsMergeWildcard.scala
@@@ -1,0 -1,17 +1,17 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groupedImports = Merge
*/
-package fix
+package test.organizeImports
-import fix.MergeImports.Wildcard1._
-import fix.MergeImports.Wildcard1.{a => _, _}
-import fix.MergeImports.Wildcard1.{b => B}
-import fix.MergeImports.Wildcard1.{c => _, _}
-import fix.MergeImports.Wildcard1.d
+import test.organizeImports.MergeImports.Wildcard1._
+import test.organizeImports.MergeImports.Wildcard1.{a => _, _}
+import test.organizeImports.MergeImports.Wildcard1.{b => B}
+import test.organizeImports.MergeImports.Wildcard1.{c => _, _}
+import test.organizeImports.MergeImports.Wildcard1.d
-import fix.MergeImports.Wildcard2._
-import fix.MergeImports.Wildcard2.{a, b}
+import test.organizeImports.MergeImports.Wildcard2._
+import test.organizeImports.MergeImports.Wildcard2.{a, b}
object GroupedImportsMergeWildcard
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/Groups.scala
index 00000000,ee587bbf..4f0a8097
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/Groups.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/Groups.scala
@@@ -1,0 -1,14 +1,14 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groups = ["re:javax?\\.", "*", "scala."]
*/
-package fix
+package test.organizeImports
import java.time.Clock
import scala.collection.JavaConverters._
import sun.misc.Unsafe
import scala.concurrent.ExecutionContext
import javax.net.ssl
object Groups
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/GroupsLongestMatch.scala
index 00000000,d9a6543e..5b7182b6
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/GroupsLongestMatch.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/GroupsLongestMatch.scala
@@@ -1,0 -1,16 +1,16 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groups = ["re:javax?\\.", "scala.", "scala.util.", "*"]
*/
-package fix
+package test.organizeImports
import java.time.Clock
import scala.collection.JavaConverters._
import sun.misc.Unsafe
import scala.concurrent.ExecutionContext
import javax.net.ssl
import scala.util.control.NonFatal
import scala.util.Random
object GroupsLongestMatch
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/ImportsOrderAsciiPreformatted.scala
index 00000000,d4273848..19a62636
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/ImportsOrderAsciiPreformatted.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/ImportsOrderAsciiPreformatted.scala
@@@ -1,0 -1,14 +1,14 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groupedImports = Keep
*/
-package fix
+package test.organizeImports
import scala.collection.immutable.{
Map,
Seq
}
import scala.collection.immutable.{Vector, IntMap}
object ImportsOrderAsciiPreformatted
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/ImportsOrderKeep.scala
index 00000000,ca933944..7e08de4d
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/ImportsOrderKeep.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/ImportsOrderKeep.scala
@@@ -1,0 -1,20 +1,20 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports {
groupedImports = Keep
importSelectorsOrder = Keep
importsOrder = Keep
}
*/
-package fix
+package test.organizeImports
import scala.concurrent.ExecutionContext.Implicits._
-import fix.QuotedIdent.`a.b`.`{ d }`.e
+import test.organizeImports.QuotedIdent.`a.b`.`{ d }`.e
import scala.concurrent.duration
-import fix.QuotedIdent._
+import test.organizeImports.QuotedIdent._
import scala.concurrent._
-import fix.QuotedIdent.`a.b`.{c => _, _}
+import test.organizeImports.QuotedIdent.`a.b`.{c => _, _}
import scala.concurrent.{Promise, Future}
object ImportsOrderKeep
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/ImportsOrderSymbolsFirst.scala
index 00000000,cf2e42d8..ee3b2db0
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/ImportsOrderSymbolsFirst.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/ImportsOrderSymbolsFirst.scala
@@@ -1,0 -1,21 +1,21 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports {
groupedImports = Keep
importSelectorsOrder = Keep
importsOrder = SymbolsFirst
}
*/
-package fix
+package test.organizeImports
import scala.concurrent.ExecutionContext.Implicits._
import scala.concurrent._
import scala.concurrent.duration
import scala.concurrent.{Promise, Future}
-import fix.QuotedIdent.`a.b`.`{ d }`.e
-import fix.QuotedIdent.`a.b`.{c => _, _}
-import fix.QuotedIdent._
+import test.organizeImports.QuotedIdent.`a.b`.`{ d }`.e
+import test.organizeImports.QuotedIdent.`a.b`.{c => _, _}
+import test.organizeImports.QuotedIdent._
object ImportsOrderSymbolsFirst
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/ImportsOrderSymbolsFirstPreformatted.scala
index 00000000,0c1d9a3d..686e3358
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/ImportsOrderSymbolsFirstPreformatted.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/ImportsOrderSymbolsFirstPreformatted.scala
@@@ -1,0 -1,17 +1,17 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports {
groupedImports = Keep
importsOrder = SymbolsFirst
}
*/
-package fix
+package test.organizeImports
import scala.collection.immutable.{
Map,
Seq
}
import scala.collection.immutable.{Vector, IntMap}
object ImportsOrderSymbolsFirstPreformatted
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/Inheritance.scala
index 00000000,97cfeafb..b83a18e2
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/Inheritance.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/Inheritance.scala
@@@ -1,0 -1,10 +1,10 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.expandRelative = true
*/
-package fix
+package test.organizeImports
import SomeObject.field.any
object Inheritance
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/MergeImportsFormatPreserving.scala
index 00000000,2ebc9863..9be512c1
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/MergeImportsFormatPreserving.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/MergeImportsFormatPreserving.scala
@@@ -1,0 -1,13 +1,13 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groupedImports = Merge
*/
-package fix
+package test.organizeImports
-import fix.MergeImports.FormatPreserving.g1.{ a, b }
-import fix.MergeImports.FormatPreserving.g2._
-import fix.MergeImports.FormatPreserving.g2.{ d => D }
+import test.organizeImports.MergeImports.FormatPreserving.g1.{ a, b }
+import test.organizeImports.MergeImports.FormatPreserving.g2._
+import test.organizeImports.MergeImports.FormatPreserving.g2.{ d => D }
object MergeImportsFormatPreserving
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/NoImports.scala
index 00000000,240aeaa9..b966bbbe
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/NoImports.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/NoImports.scala
@@@ -1,0 -1,7 +1,7 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
*/
-package fix
+package test.organizeImports
object NoImports
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/OrganizeImportsRootPackage.scala
index 00000000,d8cca9bd..d8cca9bd
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/OrganizeImportsRootPackage.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/OrganizeImportsRootPackage.scala
@@@ -1,0 -1,12 +1,12 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groups = ["re:javax?\\.", "*", "scala."]
*/
import java.time.Clock
import scala.collection.JavaConverters._
import sun.misc.Unsafe
import scala.concurrent.ExecutionContext
import javax.net.ssl
object OrganizeImportsRootPackage
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/RelativeImports.scala
index 00000000,8c11fef6..7e3b0084
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/RelativeImports.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/RelativeImports.scala
@@@ -1,0 -1,13 +1,13 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groups = ["scala.", "*"]
*/
-package fix
+package test.organizeImports
import scala.util
import sun.misc.Unsafe
import util.control
import control.NonFatal
object RelativeImports
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/SortImportSelectorsAscii.scala
index 00000000,b6e22d88..59e21b6d
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/SortImportSelectorsAscii.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/SortImportSelectorsAscii.scala
@@@ -1,0 -1,10 +1,10 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groupedImports = Keep
*/
-package fix
+package test.organizeImports
import scala.{Any, ::, collection, :+, Predef, concurrent}
object SortImportSelectorsAscii
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/SortImportSelectorsKeep.scala
index 00000000,b2d1546c..ddd5a19f
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/SortImportSelectorsKeep.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/SortImportSelectorsKeep.scala
@@@ -1,0 -1,13 +1,13 @@@
/*
rules = OrganizeImports
OrganizeImports {
importSelectorsOrder = Keep
groupedImports = Keep
removeUnused = false
}
*/
-package fix
+package test.organizeImports
import scala.{Any, ::, collection, :+, Predef, concurrent}
object SortImportSelectorsKeep
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/SortImportSelectorsSymbolsFirst.scala
index 00000000,97a04fae..0db2501b
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/SortImportSelectorsSymbolsFirst.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/SortImportSelectorsSymbolsFirst.scala
@@@ -1,0 -1,13 +1,13 @@@
/*
rules = [OrganizeImports]
OrganizeImports {
importSelectorsOrder = SymbolsFirst
groupedImports = Keep
removeUnused = false
}
*/
-package fix
+package test.organizeImports
import scala.{Any, ::, collection, :+, Predef, concurrent}
object SortImportSelectorsSymbolsFirst
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/Suppression.scala
index 00000000,6cea83e4..deb9f5d8
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/Suppression.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/Suppression.scala
@@@ -1,0 -1,16 +1,16 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groups = ["re:javax?\\.", "*", "scala."]
*/
-package fix
+package test.organizeImports
// scalafix:off
import java.time.Clock
import scala.collection.JavaConverters._
import sun.misc.Unsafe
import scala.concurrent.ExecutionContext
import javax.net.ssl
// scalafix:on
object Suppression
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/nested/NestedPackage.scala
index 00000000,af646ea9..661c26d1
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/nested/NestedPackage.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/nested/NestedPackage.scala
@@@ -1,0 -1,15 +1,15 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
OrganizeImports.groups = ["re:javax?\\.", "*", "scala."]
*/
-package fix
+package test.organizeImports
package nested
import java.time.Clock
import scala.collection.JavaConverters._
import sun.misc.Unsafe
import scala.concurrent.ExecutionContext
import javax.net.ssl
object OrganizeImportsNestedPackage
diff --combined scalafix-tests/input/src/main/scala/test/organizeImports/nested/NestedPackageWithBraces.scala
index 00000000,e89f75b4..600c7573
mode 000000,100644..100644
--- /dev/null
--- a/input/src/main/scala/fix/nested/NestedPackageWithBraces.scala
++ b/scalafix-tests/input/src/main/scala/test/organizeImports/nested/NestedPackageWithBraces.scala
@@@ -1,0 -1,15 +1,15 @@@
/*
rules = [OrganizeImports]
OrganizeImports.removeUnused = false
*/
-package fix {
+package test.organizeImports {
package nested {
import java.time.Clock
import scala.collection.JavaConverters._
import sun.misc.Unsafe
import scala.concurrent.ExecutionContext
import javax.net.ssl
object NestedPackageWithBraces
}
}
diff --combined scalafix-tests/output/src/main/scala-3/test/organizeImports/CoalesceImporteesGivensAndNames.scala
index 00000000,a0612f7c..e9530cea
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala-3/fix/CoalesceImporteesGivensAndNames.scala
++ b/scalafix-tests/output/src/main/scala-3/test/organizeImports/CoalesceImporteesGivensAndNames.scala
@@@ -1,0 -1,6 +1,6 @@@
-package fix
+package test.organizeImports
-import fix.Givens._
-import fix.Givens.{B => B1, C => _, _, given}
+import test.organizeImports.Givens._
+import test.organizeImports.Givens.{B => B1, C => _, _, given}
object CoalesceImporteesGivensAndNames
diff --combined scalafix-tests/output/src/main/scala-3/test/organizeImports/CoalesceImporteesNoGivens.scala
index 00000000,40393d12..b5bbceec
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala-3/fix/CoalesceImporteesNoGivens.scala
++ b/scalafix-tests/output/src/main/scala-3/test/organizeImports/CoalesceImporteesNoGivens.scala
@@@ -1,0 -1,5 +1,5 @@@
-package fix
+package test.organizeImports
-import fix.Givens.{C => C1, _}
+import test.organizeImports.Givens.{C => C1, _}
object CoalesceImporteesNoGivens
diff --combined scalafix-tests/output/src/main/scala-3/test/organizeImports/CoalesceImporteesNoGivensNoNames.scala
index 00000000,eb3e6d24..7d440196
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala-3/fix/CoalesceImporteesNoGivensNoNames.scala
++ b/scalafix-tests/output/src/main/scala-3/test/organizeImports/CoalesceImporteesNoGivensNoNames.scala
@@@ -1,0 -1,5 +1,5 @@@
-package fix
+package test.organizeImports
-import fix.Givens.{A => A1, B => _, _}
+import test.organizeImports.Givens.{A => A1, B => _, _}
object CoalesceImporteesNoGivensNoNames
diff --combined scalafix-tests/output/src/main/scala-3/test/organizeImports/CoalesceImporteesNoNames.scala
index 00000000,e9a3b2db..c6a2d294
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala-3/fix/CoalesceImporteesNoNames.scala
++ b/scalafix-tests/output/src/main/scala-3/test/organizeImports/CoalesceImporteesNoNames.scala
@@@ -1,0 -1,6 +1,6 @@@
-package fix
+package test.organizeImports
-import fix.Givens._
-import fix.Givens.{A => A1, given}
+import test.organizeImports.Givens._
+import test.organizeImports.Givens.{A => A1, given}
object CoalesceImporteesNoNames
diff --combined scalafix-tests/output/src/main/scala-3/test/organizeImports/DeduplicateGivenImportees.scala
index 00000000,9657f0bd..67b6cb5c
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala-3/fix/DeduplicateGivenImportees.scala
++ b/scalafix-tests/output/src/main/scala-3/test/organizeImports/DeduplicateGivenImportees.scala
@@@ -1,0 -1,8 +1,8 @@@
-package fix
+package test.organizeImports
-import fix.Givens._
-import fix.Givens.given A
-import fix.Givens.given B
-import fix.Givens.given C
+import test.organizeImports.Givens._
+import test.organizeImports.Givens.given A
+import test.organizeImports.Givens.given B
+import test.organizeImports.Givens.given C
object DeduplicateGivenImportees
diff --combined scalafix-tests/output/src/main/scala-3/test/organizeImports/ExpandGiven.scala
index 00000000,b68c136a..e5e028ac
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala-3/fix/ExpandGiven.scala
++ b/scalafix-tests/output/src/main/scala-3/test/organizeImports/ExpandGiven.scala
@@@ -1,0 -1,10 +1,10 @@@
-package fix
+package test.organizeImports
-import fix.GivenImports.Alpha
-import fix.GivenImports.Beta
-import fix.GivenImports.given Alpha
-import fix.GivenImports.given Beta
+import test.organizeImports.GivenImports.Alpha
+import test.organizeImports.GivenImports.Beta
+import test.organizeImports.GivenImports.given Alpha
+import test.organizeImports.GivenImports.given Beta
import scala.util.Either
object ExpandGiven
diff --combined scalafix-tests/output/src/main/scala-3/test/organizeImports/ExpandUnimportGiven.scala
index 00000000,1d34dbd2..132be591
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala-3/fix/ExpandUnimportGiven.scala
++ b/scalafix-tests/output/src/main/scala-3/test/organizeImports/ExpandUnimportGiven.scala
@@@ -1,0 -1,11 +1,11 @@@
-package fix
+package test.organizeImports
-import fix.GivenImports.Alpha
-import fix.GivenImports.Beta
-import fix.GivenImports.given Alpha
-import fix.GivenImports.{alpha => _}
-import fix.GivenImports.{beta => _, given}
+import test.organizeImports.GivenImports.Alpha
+import test.organizeImports.GivenImports.Beta
+import test.organizeImports.GivenImports.given Alpha
+import test.organizeImports.GivenImports.{alpha => _}
+import test.organizeImports.GivenImports.{beta => _, given}
import scala.util.Either
object ExpandUnimportGiven
diff --combined scalafix-tests/output/src/main/scala-3/test/organizeImports/GroupedGivenImportsMergeUnimports.scala
index 00000000,4ca4060d..4a1a27b2
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala-3/fix/GroupedGivenImportsMergeUnimports.scala
++ b/scalafix-tests/output/src/main/scala-3/test/organizeImports/GroupedGivenImportsMergeUnimports.scala
@@@ -1,0 -1,8 +1,8 @@@
-package fix
+package test.organizeImports
-import fix.GivenImports._
-import fix.GivenImports.{gamma => _, given Beta, given Zeta, given}
-import fix.GivenImports2.{alpha => _, beta => _}
-import fix.GivenImports2.{given Gamma, given Zeta}
+import test.organizeImports.GivenImports._
+import test.organizeImports.GivenImports.{gamma => _, given Beta, given Zeta, given}
+import test.organizeImports.GivenImports2.{alpha => _, beta => _}
+import test.organizeImports.GivenImports2.{given Gamma, given Zeta}
object GroupedGivenImportsMergeUnimports
diff --combined scalafix-tests/output/src/main/scala-3/test/organizeImports/GroupedImportsAggressiveMergeGivenAll.scala
index 00000000,4a5fdfc1..2c5436cc
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala-3/fix/GroupedImportsAggressiveMergeGivenAll.scala
++ b/scalafix-tests/output/src/main/scala-3/test/organizeImports/GroupedImportsAggressiveMergeGivenAll.scala
@@@ -1,0 -1,10 +1,10 @@@
-package fix
+package test.organizeImports
-import fix.GivenImports._
-import fix.GivenImports.given
-import fix.MergeImports.Wildcard1._
-import fix.MergeImports.Wildcard1.{b => B}
-import fix.MergeImports.Wildcard2._
+import test.organizeImports.GivenImports._
+import test.organizeImports.GivenImports.given
+import test.organizeImports.MergeImports.Wildcard1._
+import test.organizeImports.MergeImports.Wildcard1.{b => B}
+import test.organizeImports.MergeImports.Wildcard2._
object GroupedImportsAggressiveMergeGivenAll
diff --combined scalafix-tests/output/src/main/scala-3/test/organizeImports/MergeGiven.scala
index 00000000,dfef4011..b02b7e82
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala-3/fix/MergeGiven.scala
++ b/scalafix-tests/output/src/main/scala-3/test/organizeImports/MergeGiven.scala
@@@ -1,0 -1,8 +1,8 @@@
-package fix
+package test.organizeImports
-import fix.GivenImports.{Alpha, Beta}
-import fix.GivenImports.{given Alpha, given Beta}
+import test.organizeImports.GivenImports.{Alpha, Beta}
+import test.organizeImports.GivenImports.{given Alpha, given Beta}
import scala.util.Either
object MergeGiven
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/AlreadyOrganized.scala
index 00000000,a40177b9..8c4fbc1e
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/AlreadyOrganized.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/AlreadyOrganized.scala
@@@ -1,0 -1,10 +1,10 @@@
-package fix
+package test.organizeImports
import scala.collection.mutable.{
ArrayBuffer,
Map,
Queue,
Set
}
object AlreadyOrganized
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/BlankLinesManual.scala
index 00000000,ee2a2d17..23496588
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/BlankLinesManual.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/BlankLinesManual.scala
@@@ -1,0 -1,8 +1,8 @@@
-package fix
+package test.organizeImports
import java.util.Arrays
import scala.collection.mutable
import sun.misc.Unsafe
object BlankLinesManual
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/CoalesceImportees.scala
index 00000000,4023264f..fd90a9de
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/CoalesceImportees.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/CoalesceImportees.scala
@@@ -1,0 -1,8 +1,8 @@@
-package fix
+package test.organizeImports
import scala.collection.immutable.{Map, Seq, Vector}
import scala.collection.mutable._
import scala.concurrent.{Channel => Ch, _}
import scala.util.{Random => _, _}
object CoalesceImportees
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/CurlyBracedSingleImportee.scala
index 00000000,2a696255..4a299624
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/CurlyBracedSingleImportee.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/CurlyBracedSingleImportee.scala
@@@ -1,0 -1,6 +1,6 @@@
-package fix
+package test.organizeImports
import scala.collection.Map
import scala.collection.{Set => ImmutableSet}
object CurlyBracedSingleImportee
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/DeduplicateImportees.scala
index 00000000,858589e5..1264c587
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/DeduplicateImportees.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/DeduplicateImportees.scala
@@@ -1,0 -1,7 +1,7 @@@
-package fix
+package test.organizeImports
import scala.collection.immutable.Vector
import scala.collection.immutable.{Map => Dict}
import scala.collection.immutable.{Set => _, _}
object DeduplicateImportees
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/ExpandRelative.scala
index 00000000,55059c5e..25417176
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/ExpandRelative.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/ExpandRelative.scala
@@@ -1,0 -1,7 +1,7 @@@
-package fix
+package test.organizeImports
import scala.util
import scala.util.control
import scala.util.control.NonFatal
object ExpandRelative
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/ExpandRelativeEmptyPackage.scala
index 00000000,6422996b..9db51822
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/ExpandRelativeRootPackage.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/ExpandRelativeEmptyPackage.scala
@@@ -1,0 -1,14 +1,14 @@@
import P._
import Q._
import Q.x
object P {
object x
}
object Q {
object x
object y
}
-object ExpandRelativeRootPackage
+object ExpandRelativeEmptyPackage
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/ExpandRelativeMultiGroups.scala
index 00000000,965367df..ab5f229f
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/ExpandRelativeMultiGroups.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/ExpandRelativeMultiGroups.scala
@@@ -1,0 -1,9 +1,9 @@@
-package fix
+package test.organizeImports
import java.time.Clock
import javax.management.JMX
import scala.util
import scala.util.control
import scala.util.control.NonFatal
object ExpandRelativeMultiGroups
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/ExpandRelativePackageObject.scala
index 00000000,8d42e6ab..1a5f3013
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/ExpandRelativePackageObject.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/ExpandRelativePackageObject.scala
@@@ -1,0 -1,5 +1,5 @@@
-package fix
+package test.organizeImports
-import fix.PackageObject.a
+import test.organizeImports.PackageObject.a
object ExpandRelativePackageObject
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/ExpandRelativeQuotedIdent.scala
index 00000000,633c3f3b..6ae0b6bc
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/ExpandRelativeQuotedIdent.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/ExpandRelativeQuotedIdent.scala
@@@ -1,0 -1,8 +1,8 @@@
-package fix
+package test.organizeImports
-import fix.QuotedIdent.`a.b`
-import fix.QuotedIdent.`a.b`.`{ d }`
-import fix.QuotedIdent.`a.b`.c
-import fix.QuotedIdent.`macro`
+import test.organizeImports.QuotedIdent.`a.b`
+import test.organizeImports.QuotedIdent.`a.b`.`{ d }`
+import test.organizeImports.QuotedIdent.`a.b`.c
+import test.organizeImports.QuotedIdent.`macro`
object ExpandRelativeQuotedIdent
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/ExpandRelativeRootPackage.scala
index 00000000,0e0f0e49..c8e61214
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/ExpandRelativeRootPackage.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/ExpandRelativeRootPackage.scala
@@@ -1,0 -1,9 +1,9 @@@
-package fix
+package test.organizeImports
import _root_.scala.collection.mutable.ArrayBuffer
import _root_.scala.util
import scala.util.control
import scala.util.control.NonFatal
object ExpandRelativeRootPackage
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/ExplicitlyImportedImplicits.scala
index 00000000,25905cb1..5115ab56
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/ExplicitlyImportedImplicits.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/ExplicitlyImportedImplicits.scala
@@@ -1,0 -1,17 +1,17 @@@
-package fix
+package test.organizeImports
-import fix.Implicits.a.nonImplicit
-import fix.Implicits.b._
+import test.organizeImports.Implicits.a.nonImplicit
+import test.organizeImports.Implicits.b._
import scala.concurrent.ExecutionContext
import ExecutionContext.Implicits.global
-import fix.Implicits.a.intImplicit
-import fix.Implicits.a.stringImplicit
+import test.organizeImports.Implicits.a.intImplicit
+import test.organizeImports.Implicits.a.stringImplicit
object ExplicitlyImportedImplicits {
def f1()(implicit i: Int) = ???
def f2()(implicit s: String) = ???
f1()
f2()
}
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/ExplodeImportsFormatPreserving.scala
index 00000000,3b4ca7e9..fef0bb4e
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/ExplodeImportsFormatPreserving.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/ExplodeImportsFormatPreserving.scala
@@@ -1,0 -1,7 +1,7 @@@
-package fix
+package test.organizeImports
-import fix.ExplodeImports.FormatPreserving.g1.a
-import fix.ExplodeImports.FormatPreserving.g1.b
-import fix.ExplodeImports.FormatPreserving.g2.{ c => C, _ }
+import test.organizeImports.ExplodeImports.FormatPreserving.g1.a
+import test.organizeImports.ExplodeImports.FormatPreserving.g1.b
+import test.organizeImports.ExplodeImports.FormatPreserving.g2.{ c => C, _ }
object ExplodeImportsFormatPreserving
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/GlobalImportsOnly.scala
index 00000000,1928171e..b89d37ab
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/GlobalImportsOnly.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/GlobalImportsOnly.scala
@@@ -1,0 -1,13 +1,13 @@@
-package fix
+package test.organizeImports
import java.sql.DriverManager
import java.time.Clock
import scala.collection.mutable
import scala.concurrent.duration.Duration
object GlobalImportsOnly
// These imports should not be organized
import java.time.Duration, java.sql.Connection
object Foo
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/GroupedImportsAggressiveMergeWildcard.scala
index 00000000,914e7e2e..e184fab9
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/GroupedImportsAggressiveMergeWildcard.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/GroupedImportsAggressiveMergeWildcard.scala
@@@ -1,0 -1,7 +1,7 @@@
-package fix
+package test.organizeImports
-import fix.MergeImports.Wildcard1._
-import fix.MergeImports.Wildcard1.{b => B}
-import fix.MergeImports.Wildcard2._
+import test.organizeImports.MergeImports.Wildcard1._
+import test.organizeImports.MergeImports.Wildcard1.{b => B}
+import test.organizeImports.MergeImports.Wildcard2._
object GroupedImportsAggressiveMergeWildcard
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/GroupedImportsExplode.scala
index 00000000,c71c9474..b7f8052c
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/GroupedImportsExplode.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/GroupedImportsExplode.scala
@@@ -1,0 -1,7 +1,7 @@@
-package fix
+package test.organizeImports
import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.Buffer
import scala.collection.mutable.StringBuilder
object GroupedImportsExplode
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/GroupedImportsExplodeMixed.scala
index 00000000,67074e0b..6b851dd2
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/GroupedImportsExplodeMixed.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/GroupedImportsExplodeMixed.scala
@@@ -1,0 -1,7 +1,7 @@@
-package fix
+package test.organizeImports
import scala.collection.immutable._
import scala.collection.mutable.Map
import scala.collection.mutable.{Buffer => _, Seq => S, _}
object GroupedImportsExplodeMixed
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/GroupedImportsExplodeUnimport.scala
index 00000000,5611e8ae..c48b6304
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/GroupedImportsExplodeUnimport.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/GroupedImportsExplodeUnimport.scala
@@@ -1,0 -1,5 +1,5 @@@
-package fix
+package test.organizeImports
import scala.collection.{Seq => _, _}
object GroupedImportExplodeUnimport
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/GroupedImportsKeep.scala
index 00000000,ca37b56b..cacbb69e
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/GroupedImportsKeep.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/GroupedImportsKeep.scala
@@@ -1,0 -1,6 +1,6 @@@
-package fix
+package test.organizeImports
import scala.collection.mutable.StringBuilder
import scala.collection.mutable.{ArrayBuffer, Buffer}
object GroupedImportsKeep
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/GroupedImportsMerge.scala
index 00000000,f7cac59c..102e99f9
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/GroupedImportsMerge.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/GroupedImportsMerge.scala
@@@ -1,0 -1,5 +1,5 @@@
-package fix
+package test.organizeImports
import scala.collection.mutable.{ArrayBuffer, Buffer, StringBuilder}
object GroupedImportsMerge
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/GroupedImportsMergeDedup.scala
index 00000000,118c4601..ce414cdc
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/GroupedImportsMergeDedup.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/GroupedImportsMergeDedup.scala
@@@ -1,0 -1,5 +1,5 @@@
-package fix
+package test.organizeImports
-import fix.MergeImports.Dedup.{a, b => b1, c => _}
+import test.organizeImports.MergeImports.Dedup.{a, b => b1, c => _}
object GroupedImportsMergeDedup
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/GroupedImportsMergeRenames.scala
index 00000000,e40a3b2a..05058591
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/GroupedImportsMergeRenames.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/GroupedImportsMergeRenames.scala
@@@ -1,0 -1,7 +1,7 @@@
-package fix
+package test.organizeImports
-import fix.MergeImports.Rename1.{a => A, b => B, c, d}
-import fix.MergeImports.Rename2.{a => A, b => B, c}
-import fix.MergeImports.Rename2.{a, b}
+import test.organizeImports.MergeImports.Rename1.{a => A, b => B, c, d}
+import test.organizeImports.MergeImports.Rename2.{a => A, b => B, c}
+import test.organizeImports.MergeImports.Rename2.{a, b}
object GroupedImportsMergeRenames
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/GroupedImportsMergeUnimports.scala
index 00000000,06d5c67a..a8c7b14b
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/GroupedImportsMergeUnimports.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/GroupedImportsMergeUnimports.scala
@@@ -1,0 -1,6 +1,6 @@@
-package fix
+package test.organizeImports
-import fix.MergeImports.Unimport1.{b => B, c => _, d, _}
-import fix.MergeImports.Unimport2.{a => _, b => _, c => C, d}
+import test.organizeImports.MergeImports.Unimport1.{b => B, c => _, d, _}
+import test.organizeImports.MergeImports.Unimport2.{a => _, b => _, c => C, d}
object GroupedImportsMergeUnimports
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/GroupedImportsMergeWildcard.scala
index 00000000,6399a8b6..9b502ea1
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/GroupedImportsMergeWildcard.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/GroupedImportsMergeWildcard.scala
@@@ -1,0 -1,7 +1,7 @@@
-package fix
+package test.organizeImports
-import fix.MergeImports.Wildcard1.{b => B}
-import fix.MergeImports.Wildcard1.{d, _}
-import fix.MergeImports.Wildcard2.{a, b, _}
+import test.organizeImports.MergeImports.Wildcard1.{b => B}
+import test.organizeImports.MergeImports.Wildcard1.{d, _}
+import test.organizeImports.MergeImports.Wildcard2.{a, b, _}
object GroupedImportsMergeWildcard
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/Groups.scala
index 00000000,5c48e694..cd706d64
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/Groups.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/Groups.scala
@@@ -1,0 -1,11 +1,11 @@@
-package fix
+package test.organizeImports
import java.time.Clock
import javax.net.ssl
import sun.misc.Unsafe
import scala.collection.JavaConverters._
import scala.concurrent.ExecutionContext
object Groups
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/GroupsLongestMatch.scala
index 00000000,8f45a5f8..1ca80683
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/GroupsLongestMatch.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/GroupsLongestMatch.scala
@@@ -1,0 -1,14 +1,14 @@@
-package fix
+package test.organizeImports
import java.time.Clock
import javax.net.ssl
import scala.collection.JavaConverters._
import scala.concurrent.ExecutionContext
import scala.util.Random
import scala.util.control.NonFatal
import sun.misc.Unsafe
object GroupsLongestMatch
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/ImportsOrderAsciiPreformatted.scala
index 00000000,b9e621ee..d056bac1
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/ImportsOrderAsciiPreformatted.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/ImportsOrderAsciiPreformatted.scala
@@@ -1,0 -1,9 +1,9 @@@
-package fix
+package test.organizeImports
import scala.collection.immutable.{IntMap, Vector}
import scala.collection.immutable.{
Map,
Seq
}
object ImportsOrderAsciiPreformatted
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/ImportsOrderKeep.scala
index 00000000,6001a1c6..e742e4d3
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/ImportsOrderKeep.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/ImportsOrderKeep.scala
@@@ -1,0 -1,12 +1,12 @@@
-package fix
+package test.organizeImports
-import fix.QuotedIdent.`a.b`.`{ d }`.e
-import fix.QuotedIdent._
-import fix.QuotedIdent.`a.b`.{c => _, _}
+import test.organizeImports.QuotedIdent.`a.b`.`{ d }`.e
+import test.organizeImports.QuotedIdent._
+import test.organizeImports.QuotedIdent.`a.b`.{c => _, _}
import scala.concurrent.ExecutionContext.Implicits._
import scala.concurrent.duration
import scala.concurrent._
import scala.concurrent.{Promise, Future}
object ImportsOrderKeep
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/ImportsOrderSymbolsFirst.scala
index 00000000,d43c2b35..5bd3317c
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/ImportsOrderSymbolsFirst.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/ImportsOrderSymbolsFirst.scala
@@@ -1,0 -1,12 +1,12 @@@
-package fix
+package test.organizeImports
-import fix.QuotedIdent._
-import fix.QuotedIdent.`a.b`.{c => _, _}
-import fix.QuotedIdent.`a.b`.`{ d }`.e
+import test.organizeImports.QuotedIdent._
+import test.organizeImports.QuotedIdent.`a.b`.{c => _, _}
+import test.organizeImports.QuotedIdent.`a.b`.`{ d }`.e
import scala.concurrent._
import scala.concurrent.{Promise, Future}
import scala.concurrent.ExecutionContext.Implicits._
import scala.concurrent.duration
object ImportsOrderSymbolsFirst
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/ImportsOrderSymbolsFirstPreformatted.scala
index 00000000,331b57bd..416b9294
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/ImportsOrderSymbolsFirstPreformatted.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/ImportsOrderSymbolsFirstPreformatted.scala
@@@ -1,0 -1,9 +1,9 @@@
-package fix
+package test.organizeImports
import scala.collection.immutable.{IntMap, Vector}
import scala.collection.immutable.{
Map,
Seq
}
object ImportsOrderSymbolsFirstPreformatted
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/Inheritance.scala
index 00000000,c569c7ec..df855c63
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/Inheritance.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/Inheritance.scala
@@@ -1,0 -1,5 +1,5 @@@
-package fix
+package test.organizeImports
-import fix.SomeObject.field.any
+import test.organizeImports.SomeObject.field.any
object Inheritance
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/MergeImportsFormatPreserving.scala
index 00000000,072a5a3c..dee1ea2a
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/MergeImportsFormatPreserving.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/MergeImportsFormatPreserving.scala
@@@ -1,0 -1,7 +1,7 @@@
-package fix
+package test.organizeImports
-import fix.MergeImports.FormatPreserving.g1.{ a, b }
-import fix.MergeImports.FormatPreserving.g2._
-import fix.MergeImports.FormatPreserving.g2.{ d => D }
+import test.organizeImports.MergeImports.FormatPreserving.g1.{ a, b }
+import test.organizeImports.MergeImports.FormatPreserving.g2._
+import test.organizeImports.MergeImports.FormatPreserving.g2.{ d => D }
object MergeImportsFormatPreserving
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/NoImports.scala
index 00000000,00000000..d22b896f
new file mode 100644
--- /dev/null
--- /dev/null
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/NoImports.scala
@@@ -1,0 -1,0 +1,3 @@@
+package test.organizeImports
+
+object NoImports
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/OrganizeImportsRootPackage.scala
index 00000000,926b68df..926b68df
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/OrganizeImportsRootPackage.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/OrganizeImportsRootPackage.scala
@@@ -1,0 -1,9 +1,9 @@@
import java.time.Clock
import javax.net.ssl
import sun.misc.Unsafe
import scala.collection.JavaConverters._
import scala.concurrent.ExecutionContext
object OrganizeImportsRootPackage
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/PresetDefault.scala
index 00000000,327045c5..9cb2ccb5
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/PresetDefault.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/PresetDefault.scala
@@@ -1,0 -1,13 +1,13 @@@
-package fix
+package test.organizeImports
-import fix.PresetDefault.a
+import test.organizeImports.PresetDefault.a
import java.math.{BigDecimal, BigInteger}
import java.util.Collections.{binarySearch, emptyList}
import javax.management.MXBean
import scala.collection.mutable
import scala.util.Try
object PresetDefault {
val a: Any = ???
}
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/PresetIntelliJ_2020_3.scala
index 00000000,1b45dfd8..4ff7dcff
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/PresetIntelliJ_2020_3.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/PresetIntelliJ_2020_3.scala
@@@ -1,0 -1,15 +1,15 @@@
-package fix
+package test.organizeImports
-import fix.PresetIntelliJ_2020_3.a
+import test.organizeImports.PresetIntelliJ_2020_3.a
import java.math.BigDecimal
import java.math.BigInteger
import java.util.Collections.binarySearch
import java.util.Collections.emptyList
import javax.management.MXBean
import scala.collection.mutable
import scala.util.Try
object PresetIntelliJ_2020_3 {
val a: Any = ???
}
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/RelativeImports.scala
index 00000000,03ffa935..bd8bca1f
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/RelativeImports.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/RelativeImports.scala
@@@ -1,0 -1,10 +1,10 @@@
-package fix
+package test.organizeImports
import scala.util
import sun.misc.Unsafe
import util.control
import control.NonFatal
object RelativeImports
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/RemoveUnused.scala
index 00000000,bf35dcf3..4ed70725
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/RemoveUnused.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/RemoveUnused.scala
@@@ -1,0 -1,11 +1,11 @@@
-package fix
+package test.organizeImports
-import fix.UnusedImports.a.v1
-import fix.UnusedImports.c.{v6 => w2}
-import fix.UnusedImports.d.{v7 => _, _}
+import test.organizeImports.UnusedImports.a.v1
+import test.organizeImports.UnusedImports.c.{v6 => w2}
+import test.organizeImports.UnusedImports.d.{v7 => _, _}
object RemoveUnused {
val x1 = v1
val x2 = w2
val x3 = v8
}
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/RemoveUnusedDisabled.scala
index 00000000,ba16113a..79fc47a2
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/RemoveUnusedDisabled.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/RemoveUnusedDisabled.scala
@@@ -1,0 -1,16 +1,16 @@@
-package fix
+package test.organizeImports
-import fix.UnusedImports.a.v1
-import fix.UnusedImports.a.v2
-import fix.UnusedImports.b.v3
-import fix.UnusedImports.c.{v5 => w1}
-import fix.UnusedImports.c.{v6 => w2}
-import fix.UnusedImports.d.{v7 => unused, _}
+import test.organizeImports.UnusedImports.a.v1
+import test.organizeImports.UnusedImports.a.v2
+import test.organizeImports.UnusedImports.b.v3
+import test.organizeImports.UnusedImports.c.{v5 => w1}
+import test.organizeImports.UnusedImports.c.{v6 => w2}
+import test.organizeImports.UnusedImports.d.{v7 => unused, _}
object RemoveUnusedDisabled {
- import fix.UnusedImports.e.v9
+ import test.organizeImports.UnusedImports.e.v9
val x1 = v1
val x2 = w2
val x3 = v8
}
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/RemoveUnusedLocal.scala
index 00000000,d867a711..8dac4161
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/RemoveUnusedLocal.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/RemoveUnusedLocal.scala
@@@ -1,0 -1,12 +1,12 @@@
-package fix
+package test.organizeImports
object RemoveUnusedLocal {
import UnusedImports._
import a.v1
import c.{v6 => w2}
import d.{v7 => _, _}
val x1 = v1
val x2 = w2
val x3 = v8
}
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/RemoveUnusedMixed.scala
index 00000000,db6da7fa..e7e339a9
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/RemoveUnusedMixed.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/RemoveUnusedMixed.scala
@@@ -1,0 -1,11 +1,11 @@@
-package fix
+package test.organizeImports
-import fix.UnusedImports.a.v1
-import fix.UnusedImports.c.{v6 => w2}
-import fix.UnusedImports.d.{v7 => _, _}
+import test.organizeImports.UnusedImports.a.v1
+import test.organizeImports.UnusedImports.c.{v6 => w2}
+import test.organizeImports.UnusedImports.d.{v7 => _, _}
object RemoveUnusedMixed {
val x1 = v1
val x2 = w2
val x3 = v8
}
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/RemoveUnusedRelative.scala
index 00000000,d365a468..3f873f0d
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/RemoveUnusedRelative.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/RemoveUnusedRelative.scala
@@@ -1,0 -1,15 +1,15 @@@
-package fix
+package test.organizeImports
-import fix.UnusedImports.a
-import fix.UnusedImports.a.v1
-import fix.UnusedImports.b
-import fix.UnusedImports.c
-import fix.UnusedImports.c.{v6 => w2}
-import fix.UnusedImports.d
-import fix.UnusedImports.d.{v7 => _, _}
+import test.organizeImports.UnusedImports.a
+import test.organizeImports.UnusedImports.a.v1
+import test.organizeImports.UnusedImports.b
+import test.organizeImports.UnusedImports.c
+import test.organizeImports.UnusedImports.c.{v6 => w2}
+import test.organizeImports.UnusedImports.d
+import test.organizeImports.UnusedImports.d.{v7 => _, _}
object RemoveUnusedRelative {
val x1 = v1
val x2 = w2
val x3 = v8
}
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/SortImportSelectorsAscii.scala
index 00000000,4f71b51d..c2c90a60
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/SortImportSelectorsAscii.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/SortImportSelectorsAscii.scala
@@@ -1,0 -1,5 +1,5 @@@
-package fix
+package test.organizeImports
import scala.{:+, ::, Any, Predef, collection, concurrent}
object SortImportSelectorsAscii
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/SortImportSelectorsKeep.scala
index 00000000,f26f9446..a2b6a642
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/SortImportSelectorsKeep.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/SortImportSelectorsKeep.scala
@@@ -1,0 -1,5 +1,5 @@@
-package fix
+package test.organizeImports
import scala.{Any, ::, collection, :+, Predef, concurrent}
object SortImportSelectorsKeep
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/SortImportSelectorsSymbolsFirst.scala
index 00000000,cced0588..980b72e7
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/SortImportSelectorsSymbolsFirst.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/SortImportSelectorsSymbolsFirst.scala
@@@ -1,0 -1,5 +1,5 @@@
-package fix
+package test.organizeImports
import scala.{:+, ::, collection, concurrent, Any, Predef}
object SortImportSelectorsSymbolsFirst
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/Suppression.scala
index 00000000,3116253d..42baa723
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/Suppression.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/Suppression.scala
@@@ -1,0 -1,11 +1,11 @@@
-package fix
+package test.organizeImports
// scalafix:off
import java.time.Clock
import scala.collection.JavaConverters._
import sun.misc.Unsafe
import scala.concurrent.ExecutionContext
import javax.net.ssl
// scalafix:on
object Suppression
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/nested/NestedPackage.scala
index 00000000,fde60523..aedfa20e
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/nested/NestedPackage.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/nested/NestedPackage.scala
@@@ -1,0 -1,12 +1,12 @@@
-package fix
+package test.organizeImports
package nested
import java.time.Clock
import javax.net.ssl
import sun.misc.Unsafe
import scala.collection.JavaConverters._
import scala.concurrent.ExecutionContext
object OrganizeImportsNestedPackage
diff --combined scalafix-tests/output/src/main/scala/test/organizeImports/nested/NestedPackageWithBraces.scala
index 00000000,550e36f5..ddc5cd4d
mode 000000,100644..100644
--- /dev/null
--- a/output/src/main/scala/fix/nested/NestedPackageWithBraces.scala
++ b/scalafix-tests/output/src/main/scala/test/organizeImports/nested/NestedPackageWithBraces.scala
@@@ -1,0 -1,12 +1,12 @@@
-package fix {
+package test.organizeImports {
package nested {
import sun.misc.Unsafe
import java.time.Clock
import javax.net.ssl
import scala.collection.JavaConverters._
import scala.concurrent.ExecutionContext
object NestedPackageWithBraces
}
}
diff --combined scalafix-tests/shared/src/main/scala-3/test/organizeImports/GivenImports.scala
index 00000000,e10942d6..9a417ded
mode 000000,100644..100644
--- /dev/null
--- a/shared/src/main/scala-3/fix/GivenImports.scala
++ b/scalafix-tests/shared/src/main/scala-3/test/organizeImports/GivenImports.scala
@@@ -1,0 -1,25 +1,25 @@@
-package fix
+package test.organizeImports
object GivenImports {
trait Alpha
trait Beta
trait Gamma
trait Delta
trait Zeta
given alpha: Alpha = ???
given beta: Beta = ???
given gamma: Gamma = ???
given delta: Delta = ???
given zeta: Zeta = ???
}
object GivenImports2 {
import GivenImports.*
given alpha: Alpha = ???
given beta: Beta = ???
given gamma: Gamma = ???
given delta: Delta = ???
given zeta: Zeta = ???
}
diff --combined scalafix-tests/shared/src/main/scala-3/test/organizeImports/Givens.scala
index 00000000,65778653..69e136ed
mode 000000,100644..100644
--- /dev/null
--- a/shared/src/main/scala-3/fix/Givens.scala
++ b/scalafix-tests/shared/src/main/scala-3/test/organizeImports/Givens.scala
@@@ -1,0 -1,15 +1,15 @@@
-package fix
+package test.organizeImports
object Givens {
trait A
trait B
trait C
trait D
trait E
given a: A = ???
given b: B = ???
given c: C = ???
given d: D = ???
given e: E = ???
}
diff --combined scalafix-tests/shared/src/main/scala/test/organizeImports/ExplodeImports.scala
index 00000000,834ad5f9..4a7e585d
mode 000000,100644..100644
--- /dev/null
--- a/shared/src/main/scala/fix/ExplodeImports.scala
++ b/scalafix-tests/shared/src/main/scala/test/organizeImports/ExplodeImports.scala
@@@ -1,0 -1,60 +1,60 @@@
-package fix
+package test.organizeImports
object ExplodeImports {
object Wildcard1 {
object a
object b
object c
object d
}
object Wildcard2 {
object a
object b
}
object Unimport1 {
object a
object b
object c
object d
}
object Unimport2 {
object a
object b
object c
object d
}
object Rename1 {
object a
object b
object c
object d
}
object Rename2 {
object a
object b
object c
}
object Dedup {
object a
object b
object c
}
object FormatPreserving {
object g1 {
object a
object b
}
object g2 {
object c
object d
}
}
}
diff --combined scalafix-tests/shared/src/main/scala/test/organizeImports/Implicits.scala
index 00000000,fd2903f9..2eed0d4f
mode 000000,100644..100644
--- /dev/null
--- a/shared/src/main/scala/fix/Implicits.scala
++ b/scalafix-tests/shared/src/main/scala/test/organizeImports/Implicits.scala
@@@ -1,0 -1,14 +1,14 @@@
-package fix
+package test.organizeImports
object Implicits {
object a {
def nonImplicit: Unit = ???
implicit def intImplicit: Int = ???
implicit def stringImplicit: String = ???
}
object b {
implicit def intImplicit: Int = ???
implicit def stringImplicit: String = ???
}
}
diff --combined scalafix-tests/shared/src/main/scala/test/organizeImports/Inheritance.scala
index 00000000,1a42554d..9ff845ca
mode 000000,100644..100644
--- /dev/null
--- a/shared/src/main/scala/fix/Inheritance.scala
++ b/scalafix-tests/shared/src/main/scala/test/organizeImports/Inheritance.scala
@@@ -1,0 -1,11 +1,11 @@@
-package fix
+package test.organizeImports
class SomeClass {
val any: Any = ???
}
trait SomeTrait {
val field = new SomeClass
}
object SomeObject extends SomeTrait
diff --combined scalafix-tests/shared/src/main/scala/test/organizeImports/MergeImports.scala
index 00000000,16d26fa5..ede6105b
mode 000000,100644..100644
--- /dev/null
--- a/shared/src/main/scala/fix/MergeImports.scala
++ b/scalafix-tests/shared/src/main/scala/test/organizeImports/MergeImports.scala
@@@ -1,0 -1,60 +1,60 @@@
-package fix
+package test.organizeImports
object MergeImports {
object Wildcard1 {
object a
object b
object c
object d
}
object Wildcard2 {
object a
object b
}
object Unimport1 {
object a
object b
object c
object d
}
object Unimport2 {
object a
object b
object c
object d
}
object Rename1 {
object a
object b
object c
object d
}
object Rename2 {
object a
object b
object c
}
object Dedup {
object a
object b
object c
}
object FormatPreserving {
object g1 {
object a
object b
}
object g2 {
object c
object d
}
}
}
diff --combined scalafix-tests/shared/src/main/scala/test/organizeImports/QuotedIdent.scala
index 00000000,121d61f9..4bfd2b57
mode 000000,100644..100644
--- /dev/null
--- a/shared/src/main/scala/fix/QuotedIdent.scala
++ b/scalafix-tests/shared/src/main/scala/test/organizeImports/QuotedIdent.scala
@@@ -1,0 -1,12 +1,12 @@@
-package fix
+package test.organizeImports
object QuotedIdent {
object `a.b` {
object c
object `{ d }` {
object e
}
}
object `macro`
}
diff --combined scalafix-tests/shared/src/main/scala/test/organizeImports/UnusedImports.scala
index 00000000,017b07dd..ac50470b
mode 000000,100644..100644
--- /dev/null
--- a/shared/src/main/scala/fix/UnusedImports.scala
++ b/scalafix-tests/shared/src/main/scala/test/organizeImports/UnusedImports.scala
@@@ -1,0 -1,27 +1,27 @@@
-package fix
+package test.organizeImports
object UnusedImports {
object a {
object v1
object v2
}
object b {
object v3
object v4
}
object c {
object v5
object v6
}
object d {
object v7
object v8
}
object e {
object v9
}
}
diff --combined scalafix-tests/shared/src/main/scala/test/organizeImports/package.scala
index 00000000,207f0701..c4858a72
mode 000000,100644..100644
--- /dev/null
--- a/shared/src/main/scala/fix/package.scala
++ b/scalafix-tests/shared/src/main/scala/test/organizeImports/package.scala
@@@ -1,0 -1,5 +1,5 @@@
-package object fix {
+package test.organizeImports {
object PackageObject {
object a
}
}
diff --combined website/i18n/en.json
index 9f08d5ed,00000000..77bee14a
mode 100644,000000..100644
--- a/website/i18n/en.json
--- /dev/null
++ b/website/i18n/en.json
@@@ -1,105 -1,0 +1,118 @@@
{
"_comment": "This file is auto-generated by write-translations.js",
"localized-strings": {
"next": "Next",
"previous": "Previous",
"tagline": "Refactoring and linting tool for Scala",
"docs": {
"developers/api": {
"title": "API Overview",
"sidebar_label": "Overview"
},
"developers/before-you-begin": {
"title": "Before you write code"
},
"developers/contributing": {
"title": "Contributing Guide",
"sidebar_label": "Guide"
},
+ "developers/cross-publish-custom-rules": {
+ "title": "Cross publish custom rules"
+ },
"developers/local-rules": {
"title": "Local rules"
},
"developers/patch": {
"title": "Patch"
},
"developers/semantic-tree": {
"title": "SemanticTree"
},
"developers/semantic-type": {
"title": "SemanticType"
},
"developers/setup": {
"title": "Setup"
},
"developers/symbol-information": {
"title": "SymbolInformation"
},
"developers/symbol-matcher": {
"title": "SymbolMatcher"
},
"developers/tutorial": {
"title": "Tutorial"
},
+ "rules/community-rules": {
+ "title": "Community rules",
+ "sidebar_label": "Community rules"
+ },
"rules/DisableSyntax": {
"title": "DisableSyntax"
},
"rules/ExplicitResultTypes": {
"title": "ExplicitResultTypes"
},
"rules/external-rules": {
"title": "Using external rules",
"sidebar_label": "Using external rules"
},
"rules/LeakingImplicitClassVal": {
"title": "LeakingImplicitClassVal"
},
"rules/NoAutoTupling": {
"title": "NoAutoTupling"
},
"rules/NoValInForComprehension": {
"title": "NoValInForComprehension"
},
+ "rules/OrganizeImports": {
+ "title": "OrganizeImports"
+ },
"rules/overview": {
"title": "Built-in Rules",
"sidebar_label": "Built-in rules"
},
"rules/ProcedureSyntax": {
"title": "ProcedureSyntax"
},
+ "rules/RedundantSyntax": {
+ "title": "RedundantSyntax"
+ },
"rules/RemoveUnused": {
"title": "RemoveUnused"
},
"users/configuration": {
"title": "Configuration"
},
"users/installation": {
"title": "Installation"
},
"users/related-projects": {
"title": "Related projects"
},
"users/suppression": {
"title": "Suppressing rules"
}
},
"links": {
"User guide": "User guide",
"Developer guide": "Developer guide",
"Browse sources": "Browse sources",
"GitHub": "GitHub"
},
"categories": {
"Usage": "Usage",
"Rules": "Rules",
"Misc": "Misc",
"Implementing rules": "Implementing rules",
"API Reference": "API Reference",
"Contributing": "Contributing"
}
},
"pages-strings": {
"Help Translate|recruit community translators for your project": "Help Translate",
"Edit this Doc|recruitment message asking to edit the doc source": "Edit",
"Translate this Doc|recruitment message asking to translate the docs": "Translate"
}
}
diff --combined website/sidebars.json
index 5eb350b8,00000000..90d84b4a
mode 100644,000000..100644
--- a/website/sidebars.json
--- /dev/null
++ b/website/sidebars.json
@@@ -1,37 -1,0 +1,38 @@@
{
"users": {
"Usage": ["users/installation", "users/configuration", "users/suppression"],
"Rules": [
"rules/overview",
"rules/DisableSyntax",
"rules/ExplicitResultTypes",
"rules/LeakingImplicitClassVal",
"rules/NoAutoTupling",
"rules/NoValInForComprehension",
+ "rules/OrganizeImports",
"rules/ProcedureSyntax",
"rules/RedundantSyntax",
"rules/RemoveUnused",
"rules/external-rules",
"rules/community-rules"
],
"Misc": ["users/related-projects"]
},
"developers": {
"Implementing rules": [
"developers/setup",
"developers/before-you-begin",
"developers/tutorial",
"developers/local-rules",
"developers/cross-publish-custom-rules"
],
"API Reference": [
"developers/api",
"developers/patch",
"developers/symbol-matcher",
"developers/symbol-information",
"developers/semantic-type",
"developers/semantic-tree"
],
"Contributing": ["developers/contributing"]
}
}
@bjaglin
Copy link
Author

bjaglin commented May 24, 2023

Produced for scalacenter/scalafix#1480 with

➜  scalafix git:(organize-imports) ✗ git show b10f4f289d0b93741dabb916dbf01168c264ae74 -c --combined-all-paths --word-diff -M10 --patience -w | sed 's/^ -/-/' | sed 's/^ +/ /' | sed 's/^+ / /' | sed 's/^++/+/'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment