redundant throws fix should remove javadoc tag too (IDEA-185105)

This commit is contained in:
Dmitry Batkovich
2018-01-18 15:05:24 +03:00
parent 9539926b4b
commit cc8d990786
6 changed files with 72 additions and 39 deletions
@@ -2,6 +2,7 @@
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.javadoc.JavaDocUtil;
import com.intellij.codeInspection.LocalQuickFixOnPsiElement;
import com.intellij.openapi.command.undo.UndoUtil;
import com.intellij.openapi.diagnostic.Logger;
@@ -9,11 +10,14 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.psi.util.PsiFormatUtilBase;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
public class MethodThrowsFix extends LocalQuickFixOnPsiElement {
private static final Logger LOG = Logger.getInstance(MethodThrowsFix.class);
@@ -69,12 +73,27 @@ public class MethodThrowsFix extends LocalQuickFixOnPsiElement {
}
}
}
if (myAddThrow && !alreadyThrows) {
final PsiElementFactory factory = JavaPsiFacade.getInstance(myMethod.getProject()).getElementFactory();
final PsiClassType type = (PsiClassType)factory.createTypeFromText(myThrowsCanonicalText, myMethod);
PsiJavaCodeReferenceElement ref = factory.createReferenceElementByType(type);
ref = (PsiJavaCodeReferenceElement)JavaCodeStyleManager.getInstance(project).shortenClassReferences(ref);
myMethod.getThrowsList().add(ref);
if (myAddThrow) {
if (!alreadyThrows) {
final PsiElementFactory factory = JavaPsiFacade.getInstance(myMethod.getProject()).getElementFactory();
final PsiClassType type = (PsiClassType)factory.createTypeFromText(myThrowsCanonicalText, myMethod);
PsiJavaCodeReferenceElement ref = factory.createReferenceElementByType(type);
ref = (PsiJavaCodeReferenceElement)JavaCodeStyleManager.getInstance(project).shortenClassReferences(ref);
myMethod.getThrowsList().add(ref);
}
} else {
PsiDocComment comment = myMethod.getDocComment();
if (comment != null) {
Arrays
.stream(comment.getTags())
.filter(tag -> "throws".equals(tag.getName()))
.filter(tag -> {
PsiClass tagValueClass = JavaDocUtil.resolveClassInTagValue(tag.getValueElement());
return tagValueClass != null && myThrowsCanonicalText.equals(tagValueClass.getQualifiedName());
})
.forEach(tag -> tag.delete());
}
}
UndoUtil.markPsiFileForUndo(file);
}
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// 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.intellij.codeInsight.javadoc;
import com.intellij.openapi.diagnostic.Logger;
@@ -21,6 +7,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.javadoc.PsiDocComment;
import com.intellij.psi.javadoc.PsiDocTagValue;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.IncorrectOperationException;
@@ -39,6 +26,23 @@ public class JavaDocUtil {
private JavaDocUtil() {
}
@Nullable
public static PsiClass resolveClassInTagValue(@Nullable PsiDocTagValue value) {
if (value == null) return null;
PsiElement refHolder = value.getFirstChild();
if (refHolder != null) {
PsiElement refElement = refHolder.getFirstChild();
if (refElement instanceof PsiJavaCodeReferenceElement) {
PsiElement target = ((PsiJavaCodeReferenceElement)refElement).resolve();
if (target instanceof PsiClass) {
return (PsiClass)target;
}
}
}
return null;
}
/**
* Extracts a reference to a source element from the beginning of the text.
*
@@ -1,4 +1,4 @@
// Copyright 2000-2017 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.
// 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.intellij.psi.impl.source.javadoc;
import com.intellij.codeInsight.daemon.JavaErrorMessages;
@@ -45,19 +45,4 @@ abstract class ClassReferenceTagInfo implements JavadocTagInfo {
public PsiReference getReference(PsiDocTagValue value) {
return null;
}
protected static PsiClass resolveClass(PsiDocTagValue value) {
PsiElement refHolder = value.getFirstChild();
if (refHolder != null) {
PsiElement refElement = refHolder.getFirstChild();
if (refElement instanceof PsiJavaCodeReferenceElement) {
PsiElement target = ((PsiJavaCodeReferenceElement)refElement).resolve();
if (target instanceof PsiClass) {
return (PsiClass)target;
}
}
}
return null;
}
}
@@ -1,4 +1,4 @@
// Copyright 2000-2017 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.
// 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.intellij.psi.impl.source.javadoc;
import com.intellij.codeInsight.daemon.JavaErrorMessages;
@@ -6,6 +6,8 @@ import com.intellij.psi.*;
import com.intellij.psi.javadoc.PsiDocTagValue;
import com.intellij.psi.util.PsiTreeUtil;
import static com.intellij.codeInsight.javadoc.JavaDocUtil.resolveClassInTagValue;
/**
* @author mike
*/
@@ -24,7 +26,7 @@ class ExceptionTagInfo extends ClassReferenceTagInfo {
String result = super.checkTagValue(value);
if (result != null) return result;
PsiClass exceptionClass = resolveClass(value);
PsiClass exceptionClass = resolveClassInTagValue(value);
if (exceptionClass == null) return null;
PsiClass throwable = JavaPsiFacade.getInstance(value.getProject()).findClass(CommonClassNames.JAVA_LANG_THROWABLE, value.getResolveScope());
@@ -0,0 +1,11 @@
// "Remove 'IOException' from 'foo' throws list" "true"
import java.io.*;
class A {
/**
* some description
*/
private void foo() {
}
}
@@ -0,0 +1,12 @@
// "Remove 'IOException' from 'foo' throws list" "true"
import java.io.*;
class A {
/**
* some description
* @throws IOException
*/
private void foo() throws <caret>IOException {
}
}