mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-2980 Unresolved reference for ForeignKey defined as string
This commit is contained in:
@@ -12,4 +12,9 @@ public interface FQNamesProvider {
|
||||
*/
|
||||
@NotNull
|
||||
String[] getNames();
|
||||
|
||||
/**
|
||||
* @return is name of class (true) or function (false)
|
||||
*/
|
||||
boolean isClass();
|
||||
}
|
||||
|
||||
@@ -2,14 +2,13 @@ package com.jetbrains.python.nameResolver;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyElement;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.PyQualifiedNameOwner;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author Ilya.Kazakevich
|
||||
@@ -52,25 +51,28 @@ public final class NameResolverTools {
|
||||
elementToCheck = (PyElement)resolvedElement;
|
||||
}
|
||||
}
|
||||
String qualifiedName = null;
|
||||
if (elementToCheck instanceof PyQualifiedNameOwner) {
|
||||
final String qualifiedName = ((PyQualifiedNameOwner)elementToCheck).getQualifiedName();
|
||||
return getNames(namesProviders).contains(qualifiedName);
|
||||
qualifiedName = ((PyQualifiedNameOwner)elementToCheck).getQualifiedName();
|
||||
}
|
||||
String className = null;
|
||||
if (elementToCheck instanceof PyFunction) {
|
||||
final PyClass aClass = ((PyFunction)elementToCheck).getContainingClass();
|
||||
if (aClass != null) {
|
||||
className = aClass.getQualifiedName();
|
||||
}
|
||||
}
|
||||
|
||||
for (final FQNamesProvider provider : namesProviders) {
|
||||
final List<String> names = Arrays.asList(provider.getNames());
|
||||
if (qualifiedName != null && names.contains(qualifiedName)) {
|
||||
return true;
|
||||
}
|
||||
if (className != null && provider.isClass() && names.contains(className)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns set of names all providers provide
|
||||
*
|
||||
* @param providers providers to check
|
||||
* @return set of names
|
||||
*/
|
||||
@NotNull
|
||||
private static Collection<String> getNames(@NotNull final FQNamesProvider... providers) {
|
||||
final Set<String> result = new HashSet<String>();
|
||||
for (final FQNamesProvider provider : providers) {
|
||||
result.addAll(Arrays.asList(provider.getNames()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.jetbrains.python.psi;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.FunctionParameter;
|
||||
import com.jetbrains.python.nameResolver.FQNamesProvider;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveContext;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -66,6 +67,16 @@ public interface PyCallExpression extends PyExpression {
|
||||
@Nullable
|
||||
<T extends PsiElement> T getArgument(int index, String keyword, Class<T> argClass);
|
||||
|
||||
/**
|
||||
* Returns the argument if one is present in the list.
|
||||
*
|
||||
* @param parameter parameter
|
||||
* @param argClass argument expected type
|
||||
* @return the argument or null
|
||||
*/
|
||||
@Nullable
|
||||
<T extends PsiElement> T getArgument(@NotNull final FunctionParameter parameter, @NotNull Class<T> argClass);
|
||||
|
||||
@Nullable
|
||||
PyExpression getKeywordArgument(String keyword);
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.ResolveResult;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.jetbrains.python.FunctionParameter;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.nameResolver.FQNamesProvider;
|
||||
import com.jetbrains.python.nameResolver.NameResolverTools;
|
||||
@@ -361,6 +362,27 @@ public class PyCallExpressionHelper {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns argument if it exists and has appropriate type
|
||||
* @param parameter argument
|
||||
* @param argClass expected class
|
||||
* @param expression call expression
|
||||
* @param <T> expected class
|
||||
* @return argument expression or null if has wrong type of does not exist
|
||||
*/
|
||||
@Nullable
|
||||
public static <T extends PsiElement> T getArgument(
|
||||
@NotNull final FunctionParameter parameter,
|
||||
@NotNull final Class<T> argClass,
|
||||
@NotNull final PyCallExpression expression) {
|
||||
final PyArgumentList list = expression.getArgumentList();
|
||||
if (list == null) {
|
||||
return null;
|
||||
}
|
||||
return PyUtil.as(list.getValueExpressionForParam(parameter), argClass);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PyExpression getKeywordArgument(PyCallExpression expr, String keyword) {
|
||||
for (PyExpression arg : expr.getArguments()) {
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.jetbrains.python.psi.impl;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.jetbrains.python.FunctionParameter;
|
||||
import com.jetbrains.python.nameResolver.FQNamesProvider;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveContext;
|
||||
@@ -72,6 +73,12 @@ public class PyCallExpressionImpl extends PyElementImpl implements PyCallExpress
|
||||
return getArgument(index, argClass);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T extends PsiElement> T getArgument(@NotNull final FunctionParameter parameter, @NotNull final Class<T> argClass) {
|
||||
return PyCallExpressionHelper.getArgument(parameter, argClass, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PyExpression getKeywordArgument(String keyword) {
|
||||
return PyCallExpressionHelper.getKeywordArgument(this, keyword);
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.QualifiedName;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.jetbrains.python.FunctionParameter;
|
||||
import com.jetbrains.python.PyElementTypes;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.PythonDialectsTokenSetProvider;
|
||||
@@ -128,6 +129,12 @@ public class PyDecoratorImpl extends StubBasedPsiElementBase<PyDecoratorStub> im
|
||||
return getArgument(index, argClass);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public <T extends PsiElement> T getArgument(@NotNull final FunctionParameter parameter, @NotNull final Class<T> argClass) {
|
||||
return PyCallExpressionHelper.getArgument(parameter, argClass, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PyExpression getKeywordArgument(String keyword) {
|
||||
return PyCallExpressionHelper.getKeywordArgument(this, keyword);
|
||||
|
||||
Reference in New Issue
Block a user