From 4c7704c22260063736651cdfc959932c2cfffd3f Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Thu, 29 Aug 2013 17:50:59 +0400 Subject: [PATCH] Moved Cython-specific inspection checks to CythonInspectionExtension --- .../inspections/PyInspectionExtension.java | 22 +++++++++++ python/src/META-INF/python-plugin-common.xml | 1 + .../PyMethodParametersInspection.java | 11 +++--- .../PyPackageRequirementsInspection.java | 14 +++---- .../PyUnresolvedReferencesInspection.java | 38 ++++++++++--------- .../src/com/jetbrains/python/psi/PyUtil.java | 4 ++ 6 files changed, 60 insertions(+), 30 deletions(-) diff --git a/python/psi-api/src/com/jetbrains/python/inspections/PyInspectionExtension.java b/python/psi-api/src/com/jetbrains/python/inspections/PyInspectionExtension.java index 635cf96ccbc9..26b897d85251 100644 --- a/python/psi-api/src/com/jetbrains/python/inspections/PyInspectionExtension.java +++ b/python/psi-api/src/com/jetbrains/python/inspections/PyInspectionExtension.java @@ -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 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; + } } diff --git a/python/src/META-INF/python-plugin-common.xml b/python/src/META-INF/python-plugin-common.xml index b7a25ca8218f..8191eef98c16 100644 --- a/python/src/META-INF/python-plugin-common.xml +++ b/python/src/META-INF/python-plugin-common.xml @@ -973,6 +973,7 @@ + diff --git a/python/src/com/jetbrains/python/inspections/PyMethodParametersInspection.java b/python/src/com/jetbrains/python/inspections/PyMethodParametersInspection.java index d0ce70f819d2..a18fa7b837b8 100644 --- a/python/src/com/jetbrains/python/inspections/PyMethodParametersInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyMethodParametersInspection.java @@ -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) { diff --git a/python/src/com/jetbrains/python/inspections/PyPackageRequirementsInspection.java b/python/src/com/jetbrains/python/inspections/PyPackageRequirementsInspection.java index 9e80601cfeb8..8ed69c96594e 100644 --- a/python/src/com/jetbrains/python/inspections/PyPackageRequirementsInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyPackageRequirementsInspection.java @@ -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 expressions = PyResolveUtil.unwindQualifiers(importedExpression); if (!expressions.isEmpty()) { final PyExpression packageReferenceExpression = expressions.get(0); diff --git a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java index ac6a5cd69131..8ce034ccdd60 100644 --- a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java @@ -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 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; diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index 262fe2483db6..fe7fd9e95956 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -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); }