From 604b4b2ba804631d013da0c472f533267b3a3789 Mon Sep 17 00:00:00 2001 From: Sergey Patrikeev Date: Mon, 22 Apr 2019 16:52:14 +0300 Subject: [PATCH] IDEA-211443: Deprecation inspection must report links to deprecated elements in Javadoc. GitOrigin-RevId: 512187024d767acaef4db482e7fa5ee85a068036 --- .../deprecatedUsageInJavadoc/expected.xml | 23 +++++++++++++++++++ .../deprecatedUsageInJavadoc/src/Test.java | 12 ++++++++++ .../src/deprecated/DeprecatedClass.java | 5 ++++ .../src/deprecated/DeprecatedOwner.java | 17 ++++++++++++++ .../DeprecationInspectionTest.java | 4 ++++ .../jetbrains/uast/baseElements/UComment.kt | 6 ++++- .../uast/java/JavaUastLanguagePlugin.kt | 12 ++++++++-- .../jetbrains/uast/java/psiElementMapping.kt | 8 +++++-- .../uast/test/common/ResolveTestBase.kt | 2 +- 9 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 java/java-tests/testData/inspection/deprecation/deprecatedUsageInJavadoc/expected.xml create mode 100644 java/java-tests/testData/inspection/deprecation/deprecatedUsageInJavadoc/src/Test.java create mode 100644 java/java-tests/testData/inspection/deprecation/deprecatedUsageInJavadoc/src/deprecated/DeprecatedClass.java create mode 100644 java/java-tests/testData/inspection/deprecation/deprecatedUsageInJavadoc/src/deprecated/DeprecatedOwner.java diff --git a/java/java-tests/testData/inspection/deprecation/deprecatedUsageInJavadoc/expected.xml b/java/java-tests/testData/inspection/deprecation/deprecatedUsageInJavadoc/expected.xml new file mode 100644 index 000000000000..60d71cd91e7f --- /dev/null +++ b/java/java-tests/testData/inspection/deprecation/deprecatedUsageInJavadoc/expected.xml @@ -0,0 +1,23 @@ + + + + Test.java + 5 + 'DeprecatedClass' is deprecated + + + Test.java + 6 + 'DEPRECATED_CONSTANT' is deprecated + + + Test.java + 7 + 'deprecatedField' is deprecated + + + Test.java + 8 + 'deprecatedMethod' is deprecated + + \ No newline at end of file diff --git a/java/java-tests/testData/inspection/deprecation/deprecatedUsageInJavadoc/src/Test.java b/java/java-tests/testData/inspection/deprecation/deprecatedUsageInJavadoc/src/Test.java new file mode 100644 index 000000000000..8d9393309784 --- /dev/null +++ b/java/java-tests/testData/inspection/deprecation/deprecatedUsageInJavadoc/src/Test.java @@ -0,0 +1,12 @@ +import deprecated.DeprecatedClass; +import deprecated.DeprecatedOwner; + +/** + * {@link DeprecatedClass} + * {@link DeprecatedOwner#DEPRECATED_CONSTANT} + * {@link DeprecatedOwner#deprecatedField} + * {@link DeprecatedOwner#deprecatedMethod(String)} + * {@link DeprecatedOwner#deprecatedMethod(int)} is not deprecated + */ +class Test { +} \ No newline at end of file diff --git a/java/java-tests/testData/inspection/deprecation/deprecatedUsageInJavadoc/src/deprecated/DeprecatedClass.java b/java/java-tests/testData/inspection/deprecation/deprecatedUsageInJavadoc/src/deprecated/DeprecatedClass.java new file mode 100644 index 000000000000..423e2cd6f133 --- /dev/null +++ b/java/java-tests/testData/inspection/deprecation/deprecatedUsageInJavadoc/src/deprecated/DeprecatedClass.java @@ -0,0 +1,5 @@ +package deprecated; + +@Deprecated +public class DeprecatedClass { +} diff --git a/java/java-tests/testData/inspection/deprecation/deprecatedUsageInJavadoc/src/deprecated/DeprecatedOwner.java b/java/java-tests/testData/inspection/deprecation/deprecatedUsageInJavadoc/src/deprecated/DeprecatedOwner.java new file mode 100644 index 000000000000..718393897f84 --- /dev/null +++ b/java/java-tests/testData/inspection/deprecation/deprecatedUsageInJavadoc/src/deprecated/DeprecatedOwner.java @@ -0,0 +1,17 @@ +package deprecated; + +public class DeprecatedOwner { + @Deprecated + public static final int DEPRECATED_CONSTANT = 42; + + @Deprecated + public String deprecatedField; + + //This method is not deprecated, but its overloading is. + public void deprecatedMethod(int x) { + } + + @Deprecated + public void deprecatedMethod(String s) { + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInspection/DeprecationInspectionTest.java b/java/java-tests/testSrc/com/intellij/java/codeInspection/DeprecationInspectionTest.java index 25f08a660592..fa1dc18ddbfd 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInspection/DeprecationInspectionTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInspection/DeprecationInspectionTest.java @@ -97,6 +97,10 @@ public class DeprecationInspectionTest extends InspectionTestCase { doTest("deprecation/" + getTestName(true), tool); } + public void testDeprecatedUsageInJavadoc() { + doTest(); + } + @NotNull @Override protected LightProjectDescriptor getProjectDescriptor() { diff --git a/uast/uast-common/src/org/jetbrains/uast/baseElements/UComment.kt b/uast/uast-common/src/org/jetbrains/uast/baseElements/UComment.kt index 2a3034cf7cda..748a6425cc66 100644 --- a/uast/uast-common/src/org/jetbrains/uast/baseElements/UComment.kt +++ b/uast/uast-common/src/org/jetbrains/uast/baseElements/UComment.kt @@ -18,11 +18,15 @@ package org.jetbrains.uast import com.intellij.psi.PsiComment import org.jetbrains.uast.internal.log -class UComment(override val sourcePsi: PsiComment, override val uastParent: UElement) : UElement { +open class UComment(override val sourcePsi: PsiComment, private val givenParent: UElement?) : UElement { @Suppress("OverridingDeprecatedMember") override val psi get() = sourcePsi + override val uastParent: UElement? by lazy { + givenParent ?: sourcePsi.parent?.toUElement() + } + val text: String get() = asSourceString() diff --git a/uast/uast-java/src/org/jetbrains/uast/java/JavaUastLanguagePlugin.kt b/uast/uast-java/src/org/jetbrains/uast/java/JavaUastLanguagePlugin.kt index 90bff79f6192..70159ef899b7 100644 --- a/uast/uast-java/src/org/jetbrains/uast/java/JavaUastLanguagePlugin.kt +++ b/uast/uast-java/src/org/jetbrains/uast/java/JavaUastLanguagePlugin.kt @@ -19,7 +19,10 @@ package org.jetbrains.uast.java import com.intellij.lang.Language import com.intellij.lang.java.JavaLanguage import com.intellij.psi.* +import com.intellij.psi.impl.source.javadoc.PsiDocMethodOrFieldRef import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl +import com.intellij.psi.javadoc.PsiDocComment +import com.intellij.psi.javadoc.PsiDocToken import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.uast.* import org.jetbrains.uast.java.expressions.JavaUAnnotationCallExpression @@ -202,8 +205,13 @@ internal object JavaConverter { is PsiTypeElement -> el(build(::JavaUTypeReferenceExpression)) is PsiJavaCodeReferenceElement -> convertReference(el, givenParent, requiredType) is PsiAnnotation -> el.takeIf { PsiTreeUtil.getParentOfType(it, PsiAnnotationMemberValue::class.java, true) != null }?.let { - el { JavaUAnnotationCallExpression(it, givenParent) } - } + el { JavaUAnnotationCallExpression(it, givenParent) } + } + is PsiComment -> el(build(::UComment)) + is PsiDocToken -> el { el.takeIf { it.tokenType == JavaDocTokenType.DOC_TAG_VALUE_TOKEN }?.let { + val methodOrFieldRef = el.parent as? PsiDocMethodOrFieldRef ?: return@let null + JavaUSimpleNameReferenceExpression(el, el.text, givenParent, methodOrFieldRef.reference) } + } else -> null } } diff --git a/uast/uast-java/src/org/jetbrains/uast/java/psiElementMapping.kt b/uast/uast-java/src/org/jetbrains/uast/java/psiElementMapping.kt index 5c6b66ecca05..8b8de35a6501 100644 --- a/uast/uast-java/src/org/jetbrains/uast/java/psiElementMapping.kt +++ b/uast/uast-java/src/org/jetbrains/uast/java/psiElementMapping.kt @@ -4,6 +4,8 @@ package org.jetbrains.uast.java import com.intellij.openapi.util.registry.Registry import com.intellij.psi.* import com.intellij.psi.impl.source.tree.java.PsiLiteralExpressionImpl +import com.intellij.psi.javadoc.PsiDocComment +import com.intellij.psi.javadoc.PsiDocToken import org.jetbrains.uast.* import org.jetbrains.uast.internal.ClassSet import org.jetbrains.uast.internal.UElementToPsiElementMapping @@ -42,7 +44,8 @@ private val conversionMapping = UElementToPsiElementMapping( UImportStatement::class.java to ClassSet(PsiImportStatementBase::class.java), USimpleNameReferenceExpression::class.java to ClassSet(PsiIdentifier::class.java, PsiReferenceExpression::class.java, - PsiJavaCodeReferenceElement::class.java), + PsiJavaCodeReferenceElement::class.java, + PsiDocToken::class.java), UIdentifier::class.java to ClassSet(PsiIdentifier::class.java), UNamedExpression::class.java to ClassSet(PsiNameValuePair::class.java), UCallExpression::class.java to ClassSet( @@ -96,7 +99,8 @@ private val conversionMapping = UElementToPsiElementMapping( UExpressionList::class.java to ClassSet(PsiSwitchLabelStatementBase::class.java), UExpression::class.java to ClassSet(PsiExpressionStatement::class.java), - USwitchClauseExpression::class.java to ClassSet(PsiSwitchLabelStatementBase::class.java) + USwitchClauseExpression::class.java to ClassSet(PsiSwitchLabelStatementBase::class.java), + UComment::class.java to ClassSet(PsiComment::class.java) ) val uElementClassSet = ClassSet(*conversionMapping.baseMapping.flatMap { it.value.initialClasses.asIterable() }.toTypedArray()) diff --git a/uast/uast-tests/src/org/jetbrains/uast/test/common/ResolveTestBase.kt b/uast/uast-tests/src/org/jetbrains/uast/test/common/ResolveTestBase.kt index fa801f413e81..18b041787099 100644 --- a/uast/uast-tests/src/org/jetbrains/uast/test/common/ResolveTestBase.kt +++ b/uast/uast-tests/src/org/jetbrains/uast/test/common/ResolveTestBase.kt @@ -29,7 +29,7 @@ interface ResolveTestBase { "No // RESULT tag in file") val refText = refComment.text.substringAfter("REF:") - val parent = refComment.uastParent + val parent = refComment.uastParent!! val matchingElement = parent.findElementByText(refText) val resolveResult = matchingElement.resolve() ?: throw IllegalArgumentException("Unresolved reference") val resultText = resolveResult.javaClass.simpleName + (if (resolveResult is PsiNamedElement) ":${resolveResult.name}" else "")