mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Moved Cython-specific inspection checks to CythonInspectionExtension
This commit is contained in:
@@ -2,7 +2,13 @@ package com.jetbrains.python.inspections;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.jetbrains.python.psi.PyDocStringOwner;
|
||||
import com.jetbrains.python.psi.PyElement;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.PyQualifiedExpression;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -23,4 +29,20 @@ public abstract class PyInspectionExtension {
|
||||
public List<String> getFunctionParametersFromUsage(PsiElement elt) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean ignoreMethodParameters(@NotNull PyFunction function) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean ignorePackageNameInRequirements(@NotNull PyQualifiedExpression importedExpression) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean ignoreUnresolvedReference(@NotNull PyElement node, @NotNull PsiReference reference) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean ignoreUnresolvedMember(@NotNull PyType type, @NotNull String name) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -973,6 +973,7 @@
|
||||
<visitorFilter language="Cython" implementationClass="com.jetbrains.cython.CythonVisitorFilter"/>
|
||||
<pyModuleMembersProvider implementation="com.jetbrains.cython.CythonModuleMembersProvider"/>
|
||||
<pyReferenceResolveProvider implementation="com.jetbrains.cython.CythonReferenceResolveProvider"/>
|
||||
<inspectionExtension implementation="com.jetbrains.cython.CythonInspectionExtension"/>
|
||||
|
||||
<!-- Mako -->
|
||||
<dialectsTokenSetContributor implementation="com.jetbrains.mako.MakoTokenSetContributor"/>
|
||||
|
||||
@@ -5,10 +5,10 @@ import com.intellij.codeInspection.LocalInspectionToolSession;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.jetbrains.cython.psi.CythonClass;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.inspections.quickfix.AddSelfQuickFix;
|
||||
@@ -66,18 +66,19 @@ public class PyMethodParametersInspection extends PyInspection {
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visitPyFunction(final PyFunction node) {
|
||||
for (PyInspectionExtension extension : Extensions.getExtensions(PyInspectionExtension.EP_NAME)) {
|
||||
if (extension.ignoreMethodParameters(node)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
// maybe it's a zope interface?
|
||||
PsiElement zope_interface = findZopeInterface(node);
|
||||
final PyClass cls = node.getContainingClass();
|
||||
if (zope_interface instanceof PyClass) {
|
||||
if (cls != null && cls.isSubclass((PyClass) zope_interface)) return; // it can have any params
|
||||
}
|
||||
if (cls instanceof CythonClass && ((CythonClass)cls).isCppClass()) {
|
||||
return;
|
||||
}
|
||||
// analyze function itself
|
||||
PyUtil.MethodFlags flags = PyUtil.MethodFlags.of(node);
|
||||
if (flags != null) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.intellij.codeInspection.ui.ListEditForm;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.extensions.Extensions;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
@@ -21,8 +22,6 @@ import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.util.Function;
|
||||
import com.jetbrains.cython.psi.CythonCImportStatement;
|
||||
import com.jetbrains.cython.psi.CythonFromCImportStatement;
|
||||
import com.jetbrains.python.codeInsight.stdlib.PyStdlibUtil;
|
||||
import com.jetbrains.python.packaging.*;
|
||||
import com.jetbrains.python.packaging.ui.PyChooseRequirementsDialog;
|
||||
@@ -111,9 +110,6 @@ public class PyPackageRequirementsInspection extends PyInspection {
|
||||
|
||||
@Override
|
||||
public void visitPyFromImportStatement(PyFromImportStatement node) {
|
||||
if (node instanceof CythonFromCImportStatement) {
|
||||
return;
|
||||
}
|
||||
final PyReferenceExpression expr = node.getImportSource();
|
||||
if (expr != null) {
|
||||
checkPackageNameInRequirements(expr);
|
||||
@@ -122,9 +118,6 @@ public class PyPackageRequirementsInspection extends PyInspection {
|
||||
|
||||
@Override
|
||||
public void visitPyImportStatement(PyImportStatement node) {
|
||||
if (node instanceof CythonCImportStatement) {
|
||||
return;
|
||||
}
|
||||
for (PyImportElement element : node.getImportElements()) {
|
||||
final PyReferenceExpression expr = element.getImportReferenceExpression();
|
||||
if (expr != null) {
|
||||
@@ -134,6 +127,11 @@ public class PyPackageRequirementsInspection extends PyInspection {
|
||||
}
|
||||
|
||||
private void checkPackageNameInRequirements(@NotNull PyQualifiedExpression importedExpression) {
|
||||
for (PyInspectionExtension extension : Extensions.getExtensions(PyInspectionExtension.EP_NAME)) {
|
||||
if (extension.ignorePackageNameInRequirements(importedExpression)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
final List<PyExpression> expressions = PyResolveUtil.unwindQualifiers(importedExpression);
|
||||
if (!expressions.isEmpty()) {
|
||||
final PyExpression packageReferenceExpression = expressions.get(0);
|
||||
|
||||
@@ -15,9 +15,6 @@ import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.jetbrains.cython.psi.CythonFile;
|
||||
import com.jetbrains.cython.types.CythonBuiltinType;
|
||||
import com.jetbrains.cython.types.CythonType;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.codeInsight.PyCodeInsightSettings;
|
||||
@@ -233,9 +230,6 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
public void visitPyElement(final PyElement node) {
|
||||
super.visitPyElement(node);
|
||||
final PsiFile file = node.getContainingFile();
|
||||
if (file instanceof CythonFile && ((CythonFile)file).isIncludeFile()) {
|
||||
return;
|
||||
}
|
||||
final InjectedLanguageManager injectedLanguageManager =
|
||||
InjectedLanguageManager.getInstance(node.getProject());
|
||||
if (injectedLanguageManager.isInjectedFragment(file)) {
|
||||
@@ -325,7 +319,16 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
unresolved = (target == null);
|
||||
}
|
||||
if (unresolved) {
|
||||
registerUnresolvedReferenceProblem(node, reference, severity);
|
||||
boolean ignoreUnresolved = false;
|
||||
for (PyInspectionExtension extension : Extensions.getExtensions(PyInspectionExtension.EP_NAME)) {
|
||||
if (extension.ignoreUnresolvedReference(node, reference)) {
|
||||
ignoreUnresolved = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!ignoreUnresolved) {
|
||||
registerUnresolvedReferenceProblem(node, reference, severity);
|
||||
}
|
||||
// don't highlight unresolved imports as unused
|
||||
if (node.getParent() instanceof PyImportElement) {
|
||||
myAllImports.remove(node.getParent());
|
||||
@@ -477,7 +480,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
if (qualifier != null) {
|
||||
PyType qtype = myTypeEvalContext.getType(qualifier);
|
||||
if (qtype != null) {
|
||||
if (ignoreUnresolvedMemberForType(qtype, reference, ref_text)) {
|
||||
if (ignoreUnresolvedMemberForType(qtype, reference, refname)) {
|
||||
return;
|
||||
}
|
||||
addCreateMemberFromUsageFixes(qtype, reference, ref_text, actions);
|
||||
@@ -628,7 +631,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean ignoreUnresolvedMemberForType(@NotNull PyType qtype, PsiReference reference, String refText) {
|
||||
private boolean ignoreUnresolvedMemberForType(@NotNull PyType qtype, PsiReference reference, String name) {
|
||||
if (qtype instanceof PyNoneType || PyTypeChecker.isUnknown(qtype)) {
|
||||
// this almost always means that we don't know the type, so don't show an error in this case
|
||||
return true;
|
||||
@@ -644,7 +647,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
if (overridesGetAttr(cls, myTypeEvalContext)) {
|
||||
return true;
|
||||
}
|
||||
if (cls.findProperty(refText) != null) {
|
||||
if (cls.findProperty(name) != null) {
|
||||
return true;
|
||||
}
|
||||
if (PyUtil.hasUnresolvedAncestors(cls, myTypeEvalContext)) {
|
||||
@@ -653,11 +656,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
if (isDecoratedAsDynamic(cls, true)) {
|
||||
return true;
|
||||
}
|
||||
if (hasUnresolvedDynamicMember((PyClassType)qtype, reference, refText)) return true;
|
||||
}
|
||||
if (qtype instanceof CythonBuiltinType ||
|
||||
(qtype instanceof CythonType && reference instanceof PyOperatorReference)) {
|
||||
return true;
|
||||
if (hasUnresolvedDynamicMember((PyClassType)qtype, reference, name)) return true;
|
||||
}
|
||||
if (qtype instanceof PyFunctionType) {
|
||||
final Callable callable = ((PyFunctionType)qtype).getCallable();
|
||||
@@ -665,16 +664,21 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (PyInspectionExtension extension : Extensions.getExtensions(PyInspectionExtension.EP_NAME)) {
|
||||
if (extension.ignoreUnresolvedMember(qtype, name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean hasUnresolvedDynamicMember(@NotNull final PyClassType qtype,
|
||||
PsiReference reference,
|
||||
@NotNull final String refText) {
|
||||
@NotNull final String name) {
|
||||
for (PyClassMembersProvider provider : Extensions.getExtensions(PyClassMembersProvider.EP_NAME)) {
|
||||
final Collection<PyDynamicMember> resolveResult = provider.getMembers(qtype, reference.getElement());
|
||||
for (PyDynamicMember member : resolveResult) {
|
||||
if (member.getName().equals(refText)) return true;
|
||||
if (member.getName().equals(name)) return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -817,6 +817,10 @@ public class PyUtil {
|
||||
return name.startsWith("__") && !name.endsWith("__");
|
||||
}
|
||||
|
||||
public static boolean isSpecialName(@NotNull String name) {
|
||||
return name.length() > 4 && name.startsWith("__") && name.endsWith("__");
|
||||
}
|
||||
|
||||
public static boolean isPythonIdentifier(@NotNull String name) {
|
||||
return PyNames.isIdentifier(name);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user