I changed behavior of PyClassImpl#NameFinder processor, so that it
always tries to find an element with the first of the names passed to
its constructor. In particular, #findInitOrNew() returns __init__
unless there was only __new__ defined in the class. Otherwise its
behavior contradicts with the method's javadoc.
Some of them might have been left if the corresponding symbols were used
and imported via "from" imports in the same module or new imports of them
were combined with some exiting "from" imports in a dependent module.
Previously this method didn't consider import statement below the
first line comment so import optimizer didn't touch the file as if
all its imports were in order.
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.
Current solution is very crude, because we can't use standard IDE
facilities to find usages of the import element in the a file, once
that file was moved. And exactly that API MoveFileHandler offers to us.
Check that reference to moved module is contained in PyImportElement
part of a "from import" statement before calling
PyClassRefactoringUtil#updateImportOfElement. Because this method
relies solely on name equality, it can accidentally replace "from
import" of particular symbol from module with the "from import" of that
module itself.
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.
* `pass` is consistently inserted on the new line now
* excess spaces left after element was deleted are removed
Use PyUtil#deleteElementSafely in pull, push and extract superclass
refactoring implementations.
It turned out that all problems with whitespaces left after we moved
function are rooted in awkward implementation of PyFunctionImpl#delete()
that delegated to plain AST manipulation and thus ignored
usual additional reformatting step. I removed it and it's allowed to
clean a lot of test files and remove the code that was added previously
exactly for this purpose in PyMoveSymbolProcessor.
Also I updated test data for existing test where because of sorting of
imports new from-import was added *after* existing star-import (and thus
star-import was indeed optimized out). As result that test didn't
manage to detect the new problem.
However PACKAGE_NAME variable for Python templates is still undefined
and it seems that better to create such new files via FileTemplateUtil
instead somehow.
New policy is:
* Do not check name of the source file at all (if module was
unimportable before, moved symbol could not have references outside of
its file anyway).
* Do not check name of destination file if moved symbol had no
external references to it (outside of its own body), so that no imports
should be created/updated.
I added new method PyUtil#turnDirIntoPackageElement, that unlike
PyUtil#turnDirIntoInit is aware about namespace packages and return
passed directory itself in this case. Not sure, that altering
behavior of #turnDirIntoInit is a good idea, because its name will be
confusing then.
Previously new imports were always inserted after all other imports in
containing statement list, even if they were intended to replace
another existing import. I've changed meaning of "anchor" parameter a
bit, so that it can be used to specify exact insertion place for
new import.
For now we strive to replace relative imports with absolute imports
during "Move" refactoring. If we replace reference in specific
import element like in "from ..pkg import moved" we substitute
import statement altogether with "..pkg" part. However if reference was
in source part of relative import, e.g. "from ..moved import smth",
previously we'd only replaced corresponding reference expression
("moved") and left preceding dots untouched, and that was wrong.