mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
While zope.interface.Interface is defined as target with call assigned, check super class qualified name (PY-17038)
This commit is contained in:
@@ -44,10 +44,24 @@ public abstract class PyInspectionExtension {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use {@link PyInspectionExtension#ignoreMethodParameters(PyFunction, TypeEvalContext)} instead.
|
||||
* This method will be removed in 2019.2.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean ignoreMethodParameters(@NotNull PyFunction function) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param function function that is inspecting in {@link com.jetbrains.python.inspections.PyMethodParametersInspection}
|
||||
* @param context type evaluation context
|
||||
* @return true if the passed function could be ignored
|
||||
*/
|
||||
public boolean ignoreMethodParameters(@NotNull PyFunction function, @NotNull TypeEvalContext context) {
|
||||
return ignoreMethodParameters(function);
|
||||
}
|
||||
|
||||
public boolean ignorePackageNameInRequirements(@NotNull PyQualifiedExpression importedExpression) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -814,6 +814,7 @@
|
||||
<!-- Other -->
|
||||
<pythonFlavorProvider implementation="com.jetbrains.python.sdk.flavors.MayaFlavorProvider"/>
|
||||
<pyPregeneratedSkeletonsProvider id="default" implementation="com.jetbrains.python.sdk.skeletons.DefaultPregeneratedSkeletonsProvider"/>
|
||||
<inspectionExtension implementation="com.jetbrains.python.inspections.PyThirdPartyInspectionExtension"/>
|
||||
</extensions>
|
||||
|
||||
<actions>
|
||||
|
||||
@@ -8,17 +8,14 @@ import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.ui.ComboBox;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.util.QualifiedName;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.inspections.quickfix.AddSelfQuickFix;
|
||||
import com.jetbrains.python.inspections.quickfix.RenameParameterQuickFix;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.resolve.ResolveImportUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -87,39 +84,19 @@ public class PyMethodParametersInspection extends PyInspection {
|
||||
}
|
||||
|
||||
public class Visitor extends PyInspectionVisitor {
|
||||
private Ref<PsiElement> myPossibleZopeRef = null;
|
||||
|
||||
public Visitor(@Nullable ProblemsHolder holder, @NotNull LocalInspectionToolSession session) {
|
||||
super(holder, session);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiElement findZopeInterface(PsiElement foothold) {
|
||||
PsiElement ret;
|
||||
synchronized (this) { // other threads would wait as long in resolveInRoots() anyway
|
||||
if (myPossibleZopeRef == null) {
|
||||
myPossibleZopeRef = new Ref<>();
|
||||
ret = ResolveImportUtil.resolveModuleInRoots(QualifiedName.fromDottedString("zope.interface.Interface"), foothold);
|
||||
myPossibleZopeRef.set(ret); // null is OK
|
||||
}
|
||||
else ret = myPossibleZopeRef.get();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPyFunction(final PyFunction node) {
|
||||
for (PyInspectionExtension extension : PyInspectionExtension.EP_NAME.getExtensionList()) {
|
||||
if (extension.ignoreMethodParameters(node)) {
|
||||
if (extension.ignoreMethodParameters(node, myTypeEvalContext)) {
|
||||
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, myTypeEvalContext)) return; // it can have any params
|
||||
}
|
||||
|
||||
// analyze function itself
|
||||
PyUtil.MethodFlags flags = PyUtil.MethodFlags.of(node);
|
||||
if (flags != null) {
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.jetbrains.python.inspections
|
||||
|
||||
import com.intellij.util.containers.ContainerUtil
|
||||
import com.jetbrains.python.psi.PyElement
|
||||
import com.jetbrains.python.psi.PyExpression
|
||||
import com.jetbrains.python.psi.PyFunction
|
||||
import com.jetbrains.python.psi.PyUtil
|
||||
import com.jetbrains.python.psi.resolve.PyResolveContext
|
||||
import com.jetbrains.python.psi.resolve.QualifiedNameFinder
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext
|
||||
|
||||
class PyThirdPartyInspectionExtension : PyInspectionExtension() {
|
||||
|
||||
override fun ignoreMethodParameters(function: PyFunction, context: TypeEvalContext): Boolean {
|
||||
val cls = function.containingClass
|
||||
if (cls != null) {
|
||||
// zope.interface.Interface inheritor could have any parameters
|
||||
val interfaceQName = "zope.interface.interface.Interface"
|
||||
if (cls.isSubclass(interfaceQName, context)) return true
|
||||
|
||||
// Checking for subclassing above does not help while zope.interface.Interface is defined as target with call expression assigned
|
||||
val resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(context)
|
||||
for (expression in cls.superClassExpressions) {
|
||||
if (resolvesTo(expression, interfaceQName, resolveContext)) return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun resolvesTo(expression: PyExpression, qualifiedName: String, resolveContext: PyResolveContext): Boolean {
|
||||
return ContainerUtil.exists(PyUtil.multiResolveTopPriority(expression, resolveContext)) {
|
||||
it is PyElement && QualifiedNameFinder.getQualifiedName(it) == qualifiedName
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user