mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-06 06:21:16 +07:00
PY-36374 Enforce that ImportCandidateHolder stores a PsiNamedElement
Making it straightforward to retrieve this name from an element and not have to pass it from the outside. Deprecated stubs for AutoImportQuickFix.addImport() overloads, accepting a "raw" PSI element, were provided for existing plugins. GitOrigin-RevId: 899752ae9aa78a139eb0b6632ad9ca0d68e53337
This commit is contained in:
committed by
intellij-monorepo-bot
parent
3ba2747c51
commit
57251de36e
+32
-3
@@ -15,6 +15,7 @@ import com.jetbrains.python.PyPsiBundle;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.PyImportElement;
|
||||
import com.jetbrains.python.psi.impl.PyPsiUtils;
|
||||
import org.jetbrains.annotations.ApiStatus;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -69,7 +70,7 @@ public class AutoImportQuickFix extends LocalQuickFixOnPsiElement implements Hig
|
||||
* @param file the file which is the source of the importable
|
||||
* @param importElement an existing import element that can be a source for the importable.
|
||||
*/
|
||||
public void addImport(@NotNull PsiElement importable, @NotNull PsiFile file, @Nullable PyImportElement importElement) {
|
||||
public void addImport(@NotNull PsiNamedElement importable, @NotNull PsiFile file, @Nullable PyImportElement importElement) {
|
||||
myImports.add(new ImportCandidateHolder(importable, file, importElement, null));
|
||||
}
|
||||
|
||||
@@ -79,14 +80,42 @@ public class AutoImportQuickFix extends LocalQuickFixOnPsiElement implements Hig
|
||||
* @param file the file which is the source of the importable
|
||||
* @param path import path for the file, as a qualified name (a.b.c)
|
||||
*/
|
||||
public void addImport(@NotNull PsiElement importable, @NotNull PsiFileSystemItem file, @Nullable QualifiedName path) {
|
||||
public void addImport(@NotNull PsiNamedElement importable, @NotNull PsiFileSystemItem file, @Nullable QualifiedName path) {
|
||||
myImports.add(new ImportCandidateHolder(importable, file, null, path));
|
||||
}
|
||||
|
||||
public void addImport(@NotNull PsiElement importable, @NotNull PsiFileSystemItem file, @Nullable QualifiedName path, @Nullable String asName) {
|
||||
/**
|
||||
* @deprecated Use {@link #addImport(PsiNamedElement, PsiFileSystemItem, QualifiedName)} accepting a named element.
|
||||
*/
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2021.3")
|
||||
@Deprecated
|
||||
public void addImport(@NotNull PsiElement importable, @NotNull PsiFileSystemItem file, @Nullable QualifiedName path) {
|
||||
if (importable instanceof PsiNamedElement) {
|
||||
addImport((PsiNamedElement)importable, file, path);
|
||||
}
|
||||
}
|
||||
|
||||
public void addImport(@NotNull PsiNamedElement importable,
|
||||
@NotNull PsiFileSystemItem file,
|
||||
@Nullable QualifiedName path,
|
||||
@Nullable String asName) {
|
||||
myImports.add(new ImportCandidateHolder(importable, file, null, path, asName));
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link #addImport(PsiNamedElement, PsiFileSystemItem, QualifiedName, String)} accepting a named element.
|
||||
*/
|
||||
@ApiStatus.ScheduledForRemoval(inVersion = "2021.3")
|
||||
@Deprecated
|
||||
public void addImport(@NotNull PsiElement importable,
|
||||
@NotNull PsiFileSystemItem file,
|
||||
@Nullable QualifiedName path,
|
||||
@Nullable String asName) {
|
||||
if (importable instanceof PsiNamedElement) {
|
||||
addImport((PsiNamedElement)importable, file, path, asName);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String getText() {
|
||||
|
||||
+8
-7
@@ -31,11 +31,11 @@ import java.util.List;
|
||||
// visibility is intentionally package-level
|
||||
public class ImportCandidateHolder implements Comparable<ImportCandidateHolder> {
|
||||
private static final Logger LOG = Logger.getInstance(ImportCandidateHolder.class);
|
||||
@NotNull private final SmartPsiElementPointer<PsiElement> myImportable;
|
||||
@NotNull private final SmartPsiElementPointer<PsiNamedElement> myImportable;
|
||||
@Nullable private final SmartPsiElementPointer<PyImportElement> myImportElement;
|
||||
@NotNull private final SmartPsiElementPointer<PsiFileSystemItem> myFile;
|
||||
@Nullable private final QualifiedName myPath;
|
||||
private final String myImportableName;
|
||||
@NotNull private final String myImportableName;
|
||||
@Nullable private final String myAsName;
|
||||
private final int myRelevance;
|
||||
|
||||
@@ -51,12 +51,13 @@ public class ImportCandidateHolder implements Comparable<ImportCandidateHolder>
|
||||
* (empty for modules and packages located at source roots).
|
||||
*
|
||||
*/
|
||||
public ImportCandidateHolder(@NotNull PsiElement importable, @NotNull PsiFileSystemItem file,
|
||||
public ImportCandidateHolder(@NotNull PsiNamedElement importable, @NotNull PsiFileSystemItem file,
|
||||
@Nullable PyImportElement importElement, @Nullable QualifiedName path, @Nullable String asName) {
|
||||
SmartPointerManager pointerManager = SmartPointerManager.getInstance(importable.getProject());
|
||||
myFile = pointerManager.createSmartPsiElementPointer(file);
|
||||
myImportable = pointerManager.createSmartPsiElementPointer(importable);
|
||||
myImportableName = importable instanceof PsiNamedElement ? PyUtil.getElementNameWithoutExtension(((PsiNamedElement)importable)) : null;
|
||||
myImportableName = PyUtil.getElementNameWithoutExtension(importable);
|
||||
assert myImportableName != null;
|
||||
myImportElement = importElement != null ? pointerManager.createSmartPsiElementPointer(importElement) : null;
|
||||
myPath = path;
|
||||
myAsName = asName;
|
||||
@@ -65,17 +66,17 @@ public class ImportCandidateHolder implements Comparable<ImportCandidateHolder>
|
||||
assert importElement != null || path != null; // one of these must be present
|
||||
}
|
||||
|
||||
public ImportCandidateHolder(@NotNull PsiElement importable, @NotNull PsiFileSystemItem file,
|
||||
public ImportCandidateHolder(@NotNull PsiNamedElement importable, @NotNull PsiFileSystemItem file,
|
||||
@Nullable PyImportElement importElement, @Nullable QualifiedName path) {
|
||||
this(importable, file, importElement, path, null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement getImportable() {
|
||||
public PsiNamedElement getImportable() {
|
||||
return myImportable.getElement();
|
||||
}
|
||||
|
||||
public String getImportableName() {
|
||||
public @NotNull String getImportableName() {
|
||||
return myImportableName;
|
||||
}
|
||||
|
||||
|
||||
+9
-11
@@ -87,16 +87,17 @@ public class PyImportCollector {
|
||||
PyFile sourceFile = as(PyUtil.turnDirIntoInit(source), PyFile.class);
|
||||
if (sourceFile instanceof PyFileImpl) {
|
||||
|
||||
PsiElement res = sourceFile.findExportedName(myRefText);
|
||||
final String name = res instanceof PyQualifiedNameOwner ? ((PyQualifiedNameOwner)res).getQualifiedName() : null;
|
||||
PsiElement variant = sourceFile.findExportedName(myRefText);
|
||||
final String name = variant instanceof PyQualifiedNameOwner ? ((PyQualifiedNameOwner)variant).getQualifiedName() : null;
|
||||
if (name != null && seenCandidateNames.contains(name)) {
|
||||
return existingImportFile;
|
||||
}
|
||||
PsiNamedElement definition = as(variant, PsiNamedElement.class);
|
||||
// allow importing from this source if it either declares the name itself or represents a higher-level package that reexports the name
|
||||
if (res != null && !(res instanceof PyFile) && !(res instanceof PyImportElement) && res.getContainingFile() != null &&
|
||||
PsiTreeUtil.isAncestor(source, res.getContainingFile(), false)) {
|
||||
if (definition != null && !(definition instanceof PyFile || definition instanceof PyImportElement) &&
|
||||
definition.getContainingFile() != null && PsiTreeUtil.isAncestor(source, definition.getContainingFile(), false)) {
|
||||
existingImportFile = sourceFile;
|
||||
fix.addImport(res, sourceFile, importElement);
|
||||
fix.addImport(definition, sourceFile, importElement);
|
||||
if (name != null) {
|
||||
seenCandidateNames.add(name);
|
||||
}
|
||||
@@ -107,7 +108,7 @@ public class PyImportCollector {
|
||||
|
||||
private void addSymbolImportCandidates(PsiFile existingImportFile) {
|
||||
Project project = myNode.getProject();
|
||||
List<PsiElement> symbols = new ArrayList<>(PyClassNameIndex.find(myRefText, project, true));
|
||||
List<PsiNamedElement> symbols = new ArrayList<>(PyClassNameIndex.find(myRefText, project, true));
|
||||
GlobalSearchScope scope = PySearchUtilBase.excludeSdkTestsScope(myNode);
|
||||
if (!isQualifier()) {
|
||||
symbols.addAll(PyFunctionNameIndex.find(myRefText, project, scope));
|
||||
@@ -120,7 +121,7 @@ public class PyImportCollector {
|
||||
symbols.addAll(findImportableModules(packageQName, project, scope));
|
||||
}
|
||||
}
|
||||
for (PsiElement symbol : symbols) {
|
||||
for (PsiNamedElement symbol : symbols) {
|
||||
if (isIndexableTopLevel(symbol)) { // we only want top-level symbols
|
||||
PsiFileSystemItem srcfile =
|
||||
symbol instanceof PsiFileSystemItem ? ((PsiFileSystemItem)symbol).getParent() : symbol.getContainingFile();
|
||||
@@ -132,10 +133,7 @@ public class PyImportCollector {
|
||||
if (symbol instanceof PsiFileSystemItem) {
|
||||
importPath = importPath.removeTail(1);
|
||||
}
|
||||
if (!(symbol instanceof PsiNamedElement)) {
|
||||
continue;
|
||||
}
|
||||
String name = PyUtil.getElementNameWithoutExtension((PsiNamedElement)symbol);
|
||||
String name = PyUtil.getElementNameWithoutExtension(symbol);
|
||||
final String symbolImportQName = importPath.append(name).toString();
|
||||
if (seenCandidateNames.add(symbolImportQName)) {
|
||||
String alias = name.equals(myRefText) ? null : myRefText;
|
||||
|
||||
Reference in New Issue
Block a user