mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Fixed non-deterministic detection of unresolved attribute of named tuple defined in other file
This commit is contained in:
@@ -11,6 +11,7 @@ import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyBuiltinCache;
|
||||
import com.jetbrains.python.psi.impl.PyQualifiedName;
|
||||
import com.jetbrains.python.psi.impl.PyTypeProvider;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveContext;
|
||||
import com.jetbrains.python.psi.resolve.QualifiedNameFinder;
|
||||
import com.jetbrains.python.psi.types.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -41,11 +42,23 @@ public class PyStdlibTypeProvider extends PyTypeProviderBase {
|
||||
|
||||
@Override
|
||||
public PyType getReferenceType(@NotNull PsiElement referenceTarget, @NotNull TypeEvalContext context, @Nullable PsiElement anchor) {
|
||||
if (referenceTarget instanceof PyFunction &&
|
||||
PyNames.NAMEDTUPLE.equals(((PyFunction) referenceTarget).getName()) &&
|
||||
PyNames.COLLECTIONS_PY.equals(referenceTarget.getContainingFile().getName()) &&
|
||||
anchor instanceof PyCallExpression) {
|
||||
return PyNamedTupleType.fromCall((PyCallExpression)anchor);
|
||||
if (referenceTarget instanceof PyTargetExpression) {
|
||||
final PyTargetExpression target = (PyTargetExpression)referenceTarget;
|
||||
final PyQualifiedName calleeName = target.getCalleeName();
|
||||
if (calleeName != null && PyNames.NAMEDTUPLE.equals(calleeName.toString())) {
|
||||
// TODO: Create stubs for namedtuple for preventing switch from stub to AST
|
||||
final PyExpression value = target.findAssignedValue();
|
||||
if (value instanceof PyCallExpression) {
|
||||
final PyCallExpression call = (PyCallExpression)value;
|
||||
final PyCallExpression.PyMarkedCallee callee = call.resolveCallee(PyResolveContext.noImplicits());
|
||||
if (callee != null) {
|
||||
final Callable callable = callee.getCallable();
|
||||
if (PyNames.COLLECTIONS_PY.equals(callable.getContainingFile().getName())) {
|
||||
return PyNamedTupleType.fromCall(call);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
package com.jetbrains.python.inspections;
|
||||
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.jetbrains.python.fixtures.PyTestCase;
|
||||
import com.jetbrains.python.psi.LanguageLevel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* @author vlan
|
||||
*/
|
||||
public class Py3UnresolvedReferencesInspectionTest extends PyTestCase {
|
||||
private static final String TEST_DIRECTORY = "inspections/PyUnresolvedReferencesInspection3K/";
|
||||
|
||||
@Override
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return ourPy3Descriptor;
|
||||
}
|
||||
|
||||
private void doMultiFileTest(@NotNull final String filename, @NotNull LanguageLevel level) {
|
||||
runWithLanguageLevel(level, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final String testName = getTestName(false);
|
||||
myFixture.copyDirectoryToProject(TEST_DIRECTORY + testName, "");
|
||||
myFixture.configureFromTempProjectFile(filename);
|
||||
myFixture.enableInspections(PyUnresolvedReferencesInspection.class);
|
||||
myFixture.checkHighlighting(true, false, false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void doMultiFileTest(@NotNull String filename) {
|
||||
doMultiFileTest(filename, LanguageLevel.PYTHON33);
|
||||
}
|
||||
|
||||
public void testNamedTupleStub() {
|
||||
doMultiFileTest("a.py");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user