From 6d223ec43cf27d708ba262a4e5c8198af24aaa2a Mon Sep 17 00:00:00 2001 From: Semyon Proshev Date: Wed, 2 Nov 2016 15:20:25 +0300 Subject: [PATCH] Highlight abc.abcstractproperty decorator as deprecated in Pythons >= 3.3 --- .../inspections/PyDeprecationInspection.java | 35 ++++++++++++++++--- .../deprecation/abcAbstractProperty.py | 7 ++++ .../jetbrains/python/PyDeprecationTest.java | 14 +++++++- 3 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 python/testData/deprecation/abcAbstractProperty.py diff --git a/python/src/com/jetbrains/python/inspections/PyDeprecationInspection.java b/python/src/com/jetbrains/python/inspections/PyDeprecationInspection.java index 1c28413a740c..c03861b0331e 100644 --- a/python/src/com/jetbrains/python/inspections/PyDeprecationInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyDeprecationInspection.java @@ -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); + } + ); + } + } } } diff --git a/python/testData/deprecation/abcAbstractProperty.py b/python/testData/deprecation/abcAbstractProperty.py new file mode 100644 index 000000000000..341c23e24f96 --- /dev/null +++ b/python/testData/deprecation/abcAbstractProperty.py @@ -0,0 +1,7 @@ +import abc + + +class A(metaclass=abc.ABCMeta): + @abc.abstractproperty + def prop(self): + pass \ No newline at end of file diff --git a/python/testSrc/com/jetbrains/python/PyDeprecationTest.java b/python/testSrc/com/jetbrains/python/PyDeprecationTest.java index 595a8bd9f462..7f88073d0cc0 100644 --- a/python/testSrc/com/jetbrains/python/PyDeprecationTest.java +++ b/python/testSrc/com/jetbrains/python/PyDeprecationTest.java @@ -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();