mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
better resolve for imported elements in python
This commit is contained in:
@@ -24,5 +24,5 @@ package com.jetbrains.python.psi;
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public interface PyImportStatement extends PyStatement {
|
||||
PyImportElement getImportElement();
|
||||
PyImportElement[] getImportElements();
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementFactory;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -70,7 +71,14 @@ public class PyResolveUtil {
|
||||
}
|
||||
|
||||
public boolean execute(PsiElement element, ResolveState substitutor) {
|
||||
if (element instanceof PsiNamedElement) {
|
||||
if (element instanceof PyFile) {
|
||||
final VirtualFile file = ((PyFile)element).getVirtualFile();
|
||||
if (file != null && _name.equals(file.getNameWithoutExtension())) {
|
||||
_result = element;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (element instanceof PsiNamedElement) {
|
||||
if (_name.equals(((PsiNamedElement)element).getName())) {
|
||||
_result = element;
|
||||
return false;
|
||||
|
||||
@@ -77,7 +77,7 @@ public class PyFromImportStatementImpl extends PyElementImpl implements PyFromIm
|
||||
if (isStarImport()) {
|
||||
PyReferenceExpression expr = getImportSource();
|
||||
if (expr != null) {
|
||||
final PsiElement importedFile = ResolveImportUtil.resolveImportReference(expr, expr.getReferencedName());
|
||||
final PsiElement importedFile = ResolveImportUtil.resolveImportReference(expr);
|
||||
if (importedFile != null) {
|
||||
return importedFile.processDeclarations(processor, state, null, place);
|
||||
}
|
||||
|
||||
@@ -44,6 +44,11 @@ public class PyImportElementImpl extends PyElementImpl implements PyImportElemen
|
||||
@Override
|
||||
public boolean processDeclarations(@NotNull final PsiScopeProcessor processor, @NotNull final ResolveState state, final PsiElement lastParent,
|
||||
@NotNull final PsiElement place) {
|
||||
return processor.execute(getImportReference(), state);
|
||||
final PyReferenceExpression importRef = getImportReference();
|
||||
final PsiElement element = importRef.resolve();
|
||||
if (element != null) {
|
||||
return processor.execute(element, state);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,10 +20,11 @@ import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.ResolveState;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.jetbrains.python.PyElementTypes;
|
||||
import com.jetbrains.python.psi.PyImportElement;
|
||||
import com.jetbrains.python.psi.PyImportStatement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
@@ -33,17 +34,23 @@ import com.jetbrains.python.psi.PyImportStatement;
|
||||
* To change this template use File | Settings | File Templates.
|
||||
*/
|
||||
public class PyImportStatementImpl extends PyElementImpl implements PyImportStatement {
|
||||
public PyImportStatementImpl(ASTNode astNode) {
|
||||
super(astNode);
|
||||
}
|
||||
public PyImportStatementImpl(ASTNode astNode) {
|
||||
super(astNode);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processDeclarations(@NotNull final PsiScopeProcessor processor, @NotNull final ResolveState state, final PsiElement lastParent,
|
||||
public boolean processDeclarations(@NotNull final PsiScopeProcessor processor,
|
||||
@NotNull final ResolveState state,
|
||||
final PsiElement lastParent,
|
||||
@NotNull final PsiElement place) {
|
||||
return getImportElement().processDeclarations(processor, state, lastParent, place);
|
||||
for (PyImportElement element : getImportElements()) {
|
||||
if (element == lastParent) continue;
|
||||
if (!element.processDeclarations(processor, state, null, place)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public PyImportElement getImportElement() {
|
||||
return (PyImportElement)getNode().findChildByType(PyElementTypes.IMPORT_ELEMENT).getPsi();
|
||||
public PyImportElement[] getImportElements() {
|
||||
return childrenToPsi(TokenSet.create(PyElementTypes.IMPORT_ELEMENT), new PyImportElement[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,6 +96,10 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere
|
||||
final String referencedName = getReferencedName();
|
||||
if (referencedName == null) return null;
|
||||
|
||||
if (getParent() instanceof PyImportElement || getParent() instanceof PyFromImportStatement) {
|
||||
return ResolveImportUtil.resolveImportReference(this);
|
||||
}
|
||||
|
||||
final PyExpression qualifier = getQualifier();
|
||||
if (qualifier != null) {
|
||||
if (qualifier instanceof PyCallExpression) {
|
||||
@@ -125,10 +129,6 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere
|
||||
return null; // TODO?
|
||||
}
|
||||
|
||||
if (getParent() instanceof PyImportElement || getParent() instanceof PyFromImportStatement) {
|
||||
return ResolveImportUtil.resolveImportReference(this, referencedName);
|
||||
}
|
||||
|
||||
return PyResolveUtil.treeWalkUp(new PyResolveUtil.ResolveProcessor(referencedName), this, this, null);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
package com.jetbrains.python.psi.impl;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.search.FilenameIndex;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.jetbrains.python.psi.PyElement;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
@@ -15,9 +15,23 @@ public class ResolveImportUtil {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static PsiElement resolveImportReference(final PyElement context, final String referencedName) {
|
||||
final PsiFile[] files = FilenameIndex.getFilesByName(context.getProject(), referencedName + ".py",
|
||||
GlobalSearchScope.allScope(context.getProject()));
|
||||
static PsiElement resolveImportReference(final PyReferenceExpression importRef) {
|
||||
String referencedName = importRef.getReferencedName();
|
||||
if (referencedName == null) return null;
|
||||
if (importRef.getParent() instanceof PyImportElement) {
|
||||
PyImportElement parent = (PyImportElement) importRef.getParent();
|
||||
if (parent.getParent() instanceof PyFromImportStatement) {
|
||||
PyFromImportStatement stmt = (PyFromImportStatement) parent.getParent();
|
||||
final PyReferenceExpression source = stmt.getImportSource();
|
||||
if (source == null) return null;
|
||||
PsiElement sourceFile = resolveImportReference(source);
|
||||
if (sourceFile instanceof PyFile) {
|
||||
return PyResolveUtil.treeWalkUp(new PyResolveUtil.ResolveProcessor(referencedName), sourceFile, null, importRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
final PsiFile[] files = FilenameIndex.getFilesByName(importRef.getProject(), referencedName + ".py",
|
||||
GlobalSearchScope.allScope(importRef.getProject()));
|
||||
if (files.length == 1) return files[0];
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user