Highlight abc.abcstractproperty decorator as deprecated in Pythons >= 3.3

This commit is contained in:
Semyon Proshev
2017-02-14 19:19:47 +03:00
committed by Semyon Proshev
parent e5b4db9357
commit 6d223ec43c
3 changed files with 50 additions and 6 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,13 +21,16 @@ import com.intellij.codeInspection.ProblemsHolder;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiPolyVariantReference;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.QualifiedName;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.PyKnownDecoratorUtil.KnownDecorator;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Arrays;
/**
* @author yole
*/
@@ -59,9 +62,7 @@ public class PyDeprecationInspection extends PyInspection {
final PyExpression exceptClass = exceptPart.getExceptClass();
if (exceptClass != null && "ImportError".equals(exceptClass.getText())) return;
}
final PsiPolyVariantReference reference = node.getReference(getResolveContext());
if (reference == null) return;
final PsiElement resolveResult = reference.resolve();
final PsiElement resolveResult = node.getReference(getResolveContext()).resolve();
final PyFromImportStatement importStatement = PsiTreeUtil.getParentOfType(node, PyFromImportStatement.class);
if (importStatement != null) {
final PsiElement element = importStatement.resolveImportSource();
@@ -79,5 +80,29 @@ public class PyDeprecationInspection extends PyInspection {
registerProblem(nameElement == null ? node : nameElement.getPsi(), deprecationMessage, ProblemHighlightType.LIKE_DEPRECATED);
}
}
@Override
public void visitPyFunction(PyFunction node) {
super.visitPyFunction(node);
final PyDecoratorList decoratorList = node.getDecoratorList();
if (LanguageLevel.forElement(node).isAtLeast(LanguageLevel.PYTHON33) && decoratorList != null) {
Arrays
.stream(decoratorList.getDecorators())
.filter(decorator -> KnownDecorator.ABC_ABSTRACTPROPERTY.getQualifiedName().equals(decorator.getQualifiedName()))
.forEach(
decorator -> {
final QualifiedName abcAbsPropertyQName = KnownDecorator.ABC_ABSTRACTPROPERTY.getQualifiedName();
final QualifiedName propertyQName = KnownDecorator.PROPERTY.getQualifiedName();
final QualifiedName abcAbsMethodQName = KnownDecorator.ABC_ABSTRACTMETHOD.getQualifiedName();
final String message = "'" + abcAbsPropertyQName + "' is deprecated since Python 3.3. " +
"Use '" + propertyQName + "' with '" + abcAbsMethodQName + "' instead.";
registerProblem(decorator, message, ProblemHighlightType.LIKE_DEPRECATED);
}
);
}
}
}
}
@@ -0,0 +1,7 @@
import abc
class A(metaclass=abc.ABCMeta):
<warning descr="'abc.abstractproperty' is deprecated since Python 3.3. Use 'property' with 'abc.abstractmethod' instead.">@abc.abstractproperty</warning>
def prop(self):
pass
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package com.jetbrains.python;
import com.intellij.testFramework.PlatformTestUtil;
import com.jetbrains.python.fixtures.PyTestCase;
import com.jetbrains.python.inspections.PyDeprecationInspection;
import com.jetbrains.python.psi.LanguageLevel;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.PyFunction;
@@ -77,6 +78,17 @@ public class PyDeprecationTest extends PyTestCase {
myFixture.checkHighlighting(true, false, false);
}
public void testAbsAbstractProperty() {
runWithLanguageLevel(
LanguageLevel.PYTHON33,
() -> {
myFixture.enableInspections(PyDeprecationInspection.class);
myFixture.configureByFile("deprecation/abcAbstractProperty.py");
myFixture.checkHighlighting(true, false, false);
}
);
}
public void testFileStub() {
myFixture.configureByFile("deprecation/deprecatedModule.py");
PyFile file = (PyFile)myFixture.getFile();