Update test data.
1. Unresolved imports are not removed with optimize imports
2. Unresolved imports are not marked as unused
GitOrigin-RevId: 2c32c368ae0907fb75ea76fc9749e903c160667c
First of all, removed duplication and slightly simplified convoluted
transformImportStatements() method.
Also, extended existing test to include handling of comments when splitting
"from" imports.
Both packages/module names and names of individual imported symbols in
"from" imports are sorted case-insensitively if it's enabled.
To keep things simple I decided not to replicate the exact scheme used
by isort to order names in "from" imports where they have different priority
depending on whether they are ALL_CAPS or CamelCased (check the issue for
related discussion).
It doesn't affect new imports received as a result of joining several
existing ones sharing the same source. For them user must explicitly
set preferred type of formatting in code style settings.
It happened due to the bug in the platform and only when the number of
blank lines after the import statement is greater than that before it.
As a temporary workaround before the relevant fix in the platform is
accepted I delete old imports as text through the underlying document.
I tweaked Python import optimizer so that it inserts new imports
and their comments after the last of original imports, not before the
first of them (and then deletes the old ones). The reason is that it
turned out to be practically impossible to use PsiComment as the anchor
for PsiElement#addRangeBefore(), because of the hardcoded behavior of
CodeEditUtil.addChildren() which skips preceding whitespaces in this
scenario.
Otherwise, if the blank line before "# noinspection" comment preceding
the first imports statement gets removed, next time this comment will be
left in place, considered part of the top-level module comment
e.g. license.
Optimize imports now differentiate between "bound" and "unbound" comments
interleaving import statements. The former immediately precede
the import after them without any blank lines between them, while all
the rest are considered the latter, "unbound", comments which are
grouped and inserted after the whole import block. It allows to handle
the comments before the first import more accurately, moving comments
like "# noinspection" as expected, yet leaving licenses, shebangs and
encoding declarations in place if they are separated with a blank line.
Additionally, this is almost identical to the way "isort" utility
handles line comments.
They usually serve some specific purpose, e.g. general information
about the module, licence, shebang comment, etc.
Overall, it seems safer to keep them intact.
As suggested in IDEA-CR-19238
When there are a few such comments after "from" imports that are
going to be combined into one, the first of the comments is inserted
on the same line after the statement, and the remaining ones appear
below as extra line comments.
Basically, collect line comments before each import statement and insert
them back when generating the new import block.
A few corner cases:
If a normal import statement is split into several new ones, all its
comments appear before the first of these partial statements.
On the other hand, if several "from" imports are combined into one,
their comments are joined together in the same order as the names listed
in these statements (they may get additionaly sorted).
Shebang comments are ignored.
Namely, it automatically surrounds them with parentheses and inserts
a trailing comma after the last imported name if necessary, e.g. when
several "from" imports with the same source were combined into a
single long statement that needs to be wrapped.
It's necessary for the rare case when the same definition, module or
package is imported multiple times with different aliases or both
with and without alias.
This way several imports for the same module or package are placed
together regardless of their type. For instance, "import pkg1",
"import pkg2", "from pkg1 import a" are ordered as "import pkg1",
"from pkg1 import a", "import pkg2", i.e. imports of the same kind are
not necessarily put together since names of qualifier and imported
symbols have greater priority.
This is similar to the style "google" of flake8-import-order package and
flag "--force-sort-within-sections" of isort.
For instance, "from" import statements where imported names are already
ordered. Otherwise even when all imports are well formed, the whole
import block will be inserted anew and reformatted.
Namely allow to:
* disable alphabetical ordering of imports
* order individual imported names inside "from" import (PY-19292)
* combine multiple "from" imports with the same source (PY-14176)
Additionally PyImportOptimizer visits PSI comments collecting
information about unused imports, otherwise it doesn't take into
account references inside any kind of type comments.
This applies to all outer definitions except imports where we resolve
only to the latest imports as we used to do. This is required for
detecting and optimizing unused imports and adding imports during
refactorings.
The implementation of ResolveProcessor has been rewritten as
PyResolveProcessor.
For consistency all unresolved imports are treated as imports from
project. Previously (controversially) some of them were recognized as
BUILTIN imports and some as PROJECT imports.
Fix affected test data where reformat is invoked during refactoring.
Also use entire sample provided by user in the corresponding test case
for the issue.