mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-13210 Unused star import in Django settings.py
This commit is contained in:
@@ -18,7 +18,7 @@ package com.jetbrains.jython;
|
||||
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
|
||||
import com.jetbrains.python.PythonTestUtil;
|
||||
import com.jetbrains.python.inspections.PyCallingNonCallableInspection;
|
||||
import com.jetbrains.python.inspections.PyUnresolvedReferencesInspection;
|
||||
import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
|
||||
@@ -20,5 +20,5 @@ package com.jetbrains.python.psi;
|
||||
*
|
||||
* @author vlan
|
||||
*/
|
||||
public interface PyImportedNameDefiner extends NameDefiner {
|
||||
public interface PyImportedNameDefiner extends NameDefiner, PyElement {
|
||||
}
|
||||
|
||||
@@ -20,5 +20,5 @@ package com.jetbrains.python.psi;
|
||||
* User: dcheryasov
|
||||
* Date: Jul 28, 2008
|
||||
*/
|
||||
public interface PyStarImportElement extends PyElement, PyImportedNameDefiner {
|
||||
public interface PyStarImportElement extends PyImportedNameDefiner {
|
||||
}
|
||||
|
||||
@@ -270,7 +270,7 @@
|
||||
|
||||
<localInspection language="Python" shortName="PyArgumentListInspection" bundle="com.jetbrains.python.PyBundle" key="INSP.NAME.incorrect.call.arguments" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyArgumentListInspection"/>
|
||||
<localInspection language="Python" shortName="PyRedeclarationInspection" bundle="com.jetbrains.python.PyBundle" key="INSP.NAME.redeclaration" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyRedeclarationInspection"/>
|
||||
<localInspection language="Python" shortName="PyUnresolvedReferencesInspection" bundle="com.jetbrains.python.PyBundle" key="INSP.NAME.unresolved.refs" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyUnresolvedReferencesInspection"/>
|
||||
<localInspection language="Python" shortName="PyUnresolvedReferencesInspection" bundle="com.jetbrains.python.PyBundle" key="INSP.NAME.unresolved.refs" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection"/>
|
||||
<localInspection language="Python" shortName="PyInterpreterInspection" bundle="com.jetbrains.python.PyBundle" key="INSP.NAME.invalid.interpreter" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyInterpreterInspection"/>
|
||||
<localInspection language="Python" shortName="PyMethodParametersInspection" bundle="com.jetbrains.python.PyBundle" key="INSP.NAME.problematic.first.parameter" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WEAK WARNING" implementationClass="com.jetbrains.python.inspections.PyMethodParametersInspection"/>
|
||||
<localInspection language="Python" shortName="PyUnreachableCodeInspection" bundle="com.jetbrains.python.PyBundle" key="INSP.NAME.unreachable.code" groupKey="INSP.GROUP.python" enabledByDefault="true" level="WARNING" implementationClass="com.jetbrains.python.inspections.PyUnreachableCodeInspection"/>
|
||||
@@ -532,6 +532,7 @@
|
||||
<extensionPoints>
|
||||
<extensionPoint qualifiedName="Pythonid.importResolver" interface="com.jetbrains.python.psi.impl.PyImportResolver"/>
|
||||
<extensionPoint qualifiedName="Pythonid.magicLiteral" interface="com.jetbrains.python.magicLiteral.PyMagicLiteralExtensionPoint"/>
|
||||
<extensionPoint qualifiedName="Pythonid.unresolvedReferenceSkipper" interface="com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferenceSkipperExtPoint"/>
|
||||
<extensionPoint qualifiedName="Pythonid.resolveResultRater" interface="com.jetbrains.python.psi.impl.PyResolveResultRater"/>
|
||||
<extensionPoint qualifiedName="Pythonid.typeProvider" interface="com.jetbrains.python.psi.impl.PyTypeProvider"/>
|
||||
<extensionPoint qualifiedName="Pythonid.pySuperMethodsSearch" interface="com.intellij.util.QueryExecutor"/>
|
||||
|
||||
@@ -21,7 +21,7 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiFileSystemItem;
|
||||
import com.jetbrains.python.formatter.PyBlock;
|
||||
import com.jetbrains.python.inspections.PyUnresolvedReferencesInspection;
|
||||
import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.jetbrains.python.documentation.doctest;
|
||||
import com.intellij.lang.injection.InjectedLanguageManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.jetbrains.python.inspections.*;
|
||||
import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection;
|
||||
import com.jetbrains.python.psi.PyFile;
|
||||
import com.jetbrains.python.validation.DocStringAnnotator;
|
||||
import com.jetbrains.python.validation.HighlightingAnnotator;
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.Consumer;
|
||||
import com.jetbrains.python.inspections.PyUnresolvedReferencesInspection;
|
||||
import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection;
|
||||
import com.intellij.psi.util.QualifiedName;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ import com.intellij.usageView.UsageInfo;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.codeInsight.imports.AddImportHelper;
|
||||
import com.jetbrains.python.inspections.PyUnresolvedReferencesInspection;
|
||||
import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.refactoring.PyRefactoringUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package com.jetbrains.python.inspections.unresolvedReference;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.jetbrains.python.psi.PyImportedNameDefiner;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Inject this point to ask "unused reference" inspection to skip some unused references.
|
||||
* For example in Django you may import "I18N" to your "settings.py". It is not used in "settings.py", but used by Django
|
||||
* and should not be marked as "unused".
|
||||
*
|
||||
* @author Ilya.Kazakevich
|
||||
*/
|
||||
public interface PyUnresolvedReferenceSkipperExtPoint {
|
||||
@NotNull
|
||||
ExtensionPointName<PyUnresolvedReferenceSkipperExtPoint> EP_NAME = ExtensionPointName.create("Pythonid.unresolvedReferenceSkipper");
|
||||
|
||||
/**
|
||||
* Checks if some unused import should be skipped
|
||||
*
|
||||
* @param importNameDefiner unused import
|
||||
* @return true if should be skipped
|
||||
*/
|
||||
boolean unusedImportShouldBeSkipped(@NotNull PyImportedNameDefiner importNameDefiner);
|
||||
}
|
||||
+40
-10
@@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.jetbrains.python.inspections;
|
||||
package com.jetbrains.python.inspections.unresolvedReference;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.intellij.codeInspection.*;
|
||||
@@ -45,6 +45,7 @@ import com.jetbrains.python.codeInsight.imports.PythonReferenceImporter;
|
||||
import com.jetbrains.python.console.PydevConsoleRunner;
|
||||
import com.jetbrains.python.documentation.DocStringParameterReference;
|
||||
import com.jetbrains.python.documentation.DocStringTypeReference;
|
||||
import com.jetbrains.python.inspections.*;
|
||||
import com.jetbrains.python.inspections.quickfix.*;
|
||||
import com.jetbrains.python.packaging.PyPIPackageUtil;
|
||||
import com.jetbrains.python.packaging.PyPackageManager;
|
||||
@@ -68,6 +69,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.*;
|
||||
import java.util.HashSet;
|
||||
|
||||
import static com.jetbrains.python.inspections.quickfix.AddIgnoredIdentifierQuickFix.END_WILDCARD;
|
||||
|
||||
@@ -78,7 +80,8 @@ import static com.jetbrains.python.inspections.quickfix.AddIgnoredIdentifierQuic
|
||||
*/
|
||||
public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
private static Key<Visitor> KEY = Key.create("PyUnresolvedReferencesInspection.Visitor");
|
||||
public static final Key<PyUnresolvedReferencesInspection> SHORT_NAME_KEY = Key.create(PyUnresolvedReferencesInspection.class.getSimpleName());
|
||||
public static final Key<PyUnresolvedReferencesInspection> SHORT_NAME_KEY =
|
||||
Key.create(PyUnresolvedReferencesInspection.class.getSimpleName());
|
||||
|
||||
public JDOMExternalizableStringList ignoredIdentifiers = new JDOMExternalizableStringList();
|
||||
|
||||
@@ -125,7 +128,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
|
||||
public static class Visitor extends PyInspectionVisitor {
|
||||
private Set<PsiElement> myUsedImports = Collections.synchronizedSet(new HashSet<PsiElement>());
|
||||
private Set<NameDefiner> myAllImports = Collections.synchronizedSet(new HashSet<NameDefiner>());
|
||||
private Set<PyImportedNameDefiner> myAllImports = Collections.synchronizedSet(new HashSet<PyImportedNameDefiner>());
|
||||
private final ImmutableSet<String> myIgnoredIdentifiers;
|
||||
private volatile Boolean myIsEnabled = null;
|
||||
|
||||
@@ -285,10 +288,10 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
|
||||
private void processInjection(@Nullable PsiLanguageInjectionHost node) {
|
||||
if (node == null) return;
|
||||
final List<Pair<PsiElement,TextRange>>
|
||||
final List<Pair<PsiElement, TextRange>>
|
||||
files = InjectedLanguageManager.getInstance(node.getProject()).getInjectedPsiFiles(node);
|
||||
if (files != null) {
|
||||
for (Pair<PsiElement,TextRange> pair : files) {
|
||||
for (Pair<PsiElement, TextRange> pair : files) {
|
||||
new PyRecursiveElementVisitor() {
|
||||
@Override
|
||||
public void visitPyElement(PyElement element) {
|
||||
@@ -478,7 +481,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
addAddSelfFix(node, expr, actions);
|
||||
PyCallExpression callExpression = PsiTreeUtil.getParentOfType(element, PyCallExpression.class);
|
||||
if (callExpression != null && (!(callExpression.getCallee() instanceof PyQualifiedExpression) ||
|
||||
((PyQualifiedExpression)callExpression.getCallee()).getQualifier() == null)) {
|
||||
((PyQualifiedExpression)callExpression.getCallee()).getQualifier() == null)) {
|
||||
actions.add(new UnresolvedRefCreateFunctionQuickFix(callExpression, expr));
|
||||
}
|
||||
PyFunction parentFunction = PsiTreeUtil.getParentOfType(element, PyFunction.class);
|
||||
@@ -780,8 +783,9 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
if (decoratorList != null) {
|
||||
for (PyDecorator decorator : decoratorList.getDecorators()) {
|
||||
final PyExpression callee = decorator.getCallee();
|
||||
if (callee != null && PyNames.CLASSMETHOD.equals(callee.getText()))
|
||||
if (callee != null && PyNames.CLASSMETHOD.equals(callee.getText())) {
|
||||
isClassMethod = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (PyTargetExpression target : containedClass.getInstanceAttributes()) {
|
||||
@@ -926,8 +930,20 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
}
|
||||
List<PsiElement> result = new ArrayList<PsiElement>();
|
||||
|
||||
Set<NameDefiner> unusedImports = new HashSet<NameDefiner>(myAllImports);
|
||||
Set<PyImportedNameDefiner> unusedImports = new HashSet<PyImportedNameDefiner>(myAllImports);
|
||||
unusedImports.removeAll(myUsedImports);
|
||||
|
||||
// Remove those unsed, that are reported to be skipped by extension points
|
||||
final Set<PyImportedNameDefiner> unusedImportToSkip = new HashSet<PyImportedNameDefiner>();
|
||||
for (final PyImportedNameDefiner unusedImport : unusedImports) {
|
||||
if (importShouldBeSkippedByExtPoint(unusedImport)) { // Pass to extension points
|
||||
unusedImportToSkip.add(unusedImport);
|
||||
}
|
||||
}
|
||||
|
||||
unusedImports.removeAll(unusedImportToSkip);
|
||||
|
||||
|
||||
Set<String> usedImportNames = new HashSet<String>();
|
||||
for (PsiElement usedImport : myUsedImports) {
|
||||
if (usedImport instanceof NameDefiner) {
|
||||
@@ -942,7 +958,8 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
QualifiedName packageQName = null;
|
||||
List<String> dunderAll = null;
|
||||
|
||||
for (NameDefiner unusedImport : unusedImports) {
|
||||
// TODO: Use strategies instead of pack of "continue"
|
||||
for (PyImportedNameDefiner unusedImport : unusedImports) {
|
||||
if (packageQName == null) {
|
||||
final PsiFile file = unusedImport.getContainingFile();
|
||||
if (file instanceof PyFile) {
|
||||
@@ -1014,7 +1031,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
return result;
|
||||
}
|
||||
|
||||
private static boolean areAllImportsUnused(PyImportStatementBase importStatement, Set<NameDefiner> unusedImports) {
|
||||
private static boolean areAllImportsUnused(PyImportStatementBase importStatement, Set<PyImportedNameDefiner> unusedImports) {
|
||||
final PyImportElement[] elements = importStatement.getImportElements();
|
||||
for (PyImportElement element : elements) {
|
||||
if (!unusedImports.contains(element)) {
|
||||
@@ -1034,4 +1051,17 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if one or more extension points ask unused import to be skipped
|
||||
* @param importNameDefiner unused import
|
||||
* @return true of one or more asks
|
||||
*/
|
||||
private static boolean importShouldBeSkippedByExtPoint(@NotNull final PyImportedNameDefiner importNameDefiner) {
|
||||
for (final PyUnresolvedReferenceSkipperExtPoint skipper : PyUnresolvedReferenceSkipperExtPoint.EP_NAME.getExtensions()) {
|
||||
if (skipper.unusedImportShouldBeSkipped(importNameDefiner)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
*
|
||||
* Inspection that reports unresolved and unused references.
|
||||
* You can inject logic to mark some unused imports as used. See extension points in this package.
|
||||
* @author Ilya.Kazakevich
|
||||
*/
|
||||
package com.jetbrains.python.inspections.unresolvedReference;
|
||||
@@ -23,6 +23,7 @@ import com.jetbrains.python.documentation.DocStringFormat;
|
||||
import com.jetbrains.python.documentation.PyDocumentationSettings;
|
||||
import com.jetbrains.python.fixtures.PyTestCase;
|
||||
import com.jetbrains.python.inspections.*;
|
||||
import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection;
|
||||
import com.jetbrains.python.psi.LanguageLevel;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.jetbrains.python;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.jetbrains.python.fixtures.PyTestCase;
|
||||
import com.jetbrains.python.inspections.PyInspection;
|
||||
import com.jetbrains.python.inspections.PyUnresolvedReferencesInspection;
|
||||
import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection;
|
||||
import com.jetbrains.python.inspections.PyUnusedLocalInspection;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
+1
@@ -20,6 +20,7 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.jetbrains.python.fixtures.PyTestCase;
|
||||
import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection;
|
||||
import com.jetbrains.python.psi.LanguageLevel;
|
||||
import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyFile;
|
||||
|
||||
+1
@@ -16,6 +16,7 @@
|
||||
package com.jetbrains.python.inspections;
|
||||
|
||||
import com.jetbrains.python.fixtures.PyInspectionTestCase;
|
||||
import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection;
|
||||
import com.jetbrains.python.psi.LanguageLevel;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.jetbrains.python.inspections;
|
||||
|
||||
import com.jetbrains.python.fixtures.PyTestCase;
|
||||
import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.jetbrains.python.quickFixes;
|
||||
import com.intellij.testFramework.TestDataPath;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyQuickFixTestCase;
|
||||
import com.jetbrains.python.inspections.PyUnresolvedReferencesInspection;
|
||||
import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection;
|
||||
import com.jetbrains.python.inspections.PyUnusedLocalInspection;
|
||||
|
||||
/**
|
||||
|
||||
@@ -18,7 +18,7 @@ package com.jetbrains.python.quickFixes;
|
||||
import com.jetbrains.python.PyBundle;
|
||||
import com.jetbrains.python.PyQuickFixTestCase;
|
||||
import com.jetbrains.python.inspections.PyClassHasNoInitInspection;
|
||||
import com.jetbrains.python.inspections.PyUnresolvedReferencesInspection;
|
||||
import com.jetbrains.python.inspections.unresolvedReference.PyUnresolvedReferencesInspection;
|
||||
|
||||
/**
|
||||
* User: ktisha
|
||||
|
||||
Reference in New Issue
Block a user