IDEA-76469 Regenerate the javadoc All javadoc fixes except ordering

This commit is contained in:
Denis.Zhdanov
2012-09-24 16:50:17 +04:00
parent 8fb8308982
commit 698499bfb0
2 changed files with 211 additions and 42 deletions
@@ -24,6 +24,8 @@ import com.intellij.javadoc.JavadocNavigationDelegate;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.javadoc.PsiDocComment;
@@ -63,28 +65,15 @@ public class JavaDocCommentFixer implements DocCommentFixer {
*/
@NotNull private static final Set<String> CARET_ANCHOR_TAGS = ContainerUtilRt.newHashSet(PARAM_TAG, "@throws", "@return");
@NotNull private static final List<String> TAGS_ORDER = new ArrayList<String>();
static {
String tags = System.getProperty("java.doc.comment.fix.tags.order");
if (tags == null) {
tags = "@param:@return:@throws";
}
for (String s : tags.split(":")) {
String tagName = s.trim();
if (!tagName.isEmpty()) {
TAGS_ORDER.add("@" + tagName);
}
}
}
private static final Comparator<PsiElement> COMPARATOR = new Comparator<PsiElement>() {
@NotNull private static final Comparator<PsiElement> COMPARATOR = new Comparator<PsiElement>() {
@Override
public int compare(PsiElement e1, PsiElement e2) {
return e2.getTextRange().getEndOffset() - e1.getTextRange().getEndOffset();
}
};
@NotNull private static final String PARAM_TAG_NAME = "param";
@Override
public void fixComment(@NotNull Project project, @NotNull Editor editor, @NotNull PsiComment comment) {
if (!(comment instanceof PsiDocComment)) {
@@ -96,7 +85,12 @@ public class JavaDocCommentFixer implements DocCommentFixer {
if (owner == null) {
return;
}
PsiFile file = comment.getContainingFile();
if (file == null) {
return;
}
JavaDocReferenceInspection referenceInspection = new JavaDocReferenceInspection();
JavaDocLocalInspection localInspection = getDocLocalInspection();
@@ -125,7 +119,7 @@ public class JavaDocCommentFixer implements DocCommentFixer {
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument());
ensureContentOrdered(docComment, editor.getDocument());
locateCaret(docComment, editor);
locateCaret(docComment, editor, file);
}
@NotNull
@@ -163,7 +157,16 @@ public class JavaDocCommentFixer implements DocCommentFixer {
}
}
// TODO den add doc
/**
* This fixer is based on existing javadoc inspections - there are two of them. One detects invalid references (to unexisted
* method parameter or non-declared checked exception). Another one handles all other cases (parameter documentation is missing;
* parameter doesn't have a description etc). This method handles result of the second exception
*
* @param problems detected problems
* @param comment target comment to fix
* @param document target document which contains text of the commen being fixed
* @param project current project
*/
@SuppressWarnings("unchecked")
private static void fixCommonProblems(@NotNull ProblemDescriptor[] problems,
@NotNull PsiComment comment,
@@ -200,8 +203,9 @@ public class JavaDocCommentFixer implements DocCommentFixer {
if (toRemove.size() > 1) {
Collections.sort(toRemove, COMPARATOR);
}
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(document);
PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(project);
psiDocumentManager.doPostponedOperationsAndUnblockDocument(document);
CharSequence text = document.getCharsSequence();
for (PsiElement element : toRemove) {
int startOffset = element.getTextRange().getStartOffset();
@@ -225,20 +229,90 @@ public class JavaDocCommentFixer implements DocCommentFixer {
}
document.deleteString(startOffset, endOffset);
}
psiDocumentManager.commitDocument(document);
}
private static void ensureContentOrdered(@NotNull PsiDocComment comment, @NotNull Document document) {
//region Parse existing doc comment parameters.
List<String> current = new ArrayList<String>();
Map<String, Pair<TextRange, String>> tagInfoByName = new HashMap<String, Pair<TextRange, String>>();
for (PsiDocTag tag : comment.getTags()) {
if (!PARAM_TAG_NAME.equals(tag.getName())) {
continue;
}
PsiDocTagValue valueElement = tag.getValueElement();
if (valueElement == null) {
continue;
}
String paramName = valueElement.getText();
if (paramName != null) {
current.add(paramName);
tagInfoByName.put(paramName, parseTagValue(tag, document));
}
}
//endregion
//region Calculate desired parameters order
List<String> ordered = new ArrayList<String>();
PsiDocCommentOwner owner = comment.getOwner();
if ((owner instanceof PsiMethod)) {
ensureParametersOrder(comment, (PsiMethod)owner, document);
PsiParameter[] parameters = ((PsiMethod)owner).getParameterList().getParameters();
for (PsiParameter parameter : parameters) {
ordered.add(parameter.getName());
}
}
if (owner instanceof PsiTypeParameterListOwner) {
PsiTypeParameter[] typeParameters = ((PsiTypeParameterListOwner)owner).getTypeParameters();
for (PsiTypeParameter parameter : typeParameters) {
ordered.add(String.format("<%s>", parameter.getName()));
}
}
//endregion
//region Fix order if necessary.
if (current.size() != ordered.size()) {
// Something is wrong, stop the processing.
return;
}
boolean changed = false;
for (int i = current.size() - 1; i >= 0; i--) {
String newTag = ordered.get(i);
String oldTag = current.get(i);
if (newTag.equals(oldTag)) {
continue;
}
TextRange range = tagInfoByName.get(oldTag).first;
document.replaceString(range.getStartOffset(), range.getEndOffset(), tagInfoByName.get(newTag).second);
changed = true;
}
if (changed) {
PsiDocumentManager manager = PsiDocumentManager.getInstance(comment.getProject());
manager.commitDocument(document);
}
//endregion
}
private static void ensureParametersOrder(@NotNull PsiDocComment comment, @NotNull PsiMethod method, @NotNull Document document) {
@NotNull
private static Pair<TextRange, String> parseTagValue(@NotNull PsiDocTag tag, @NotNull Document document) {
PsiDocTagValue valueElement = tag.getValueElement();
assert valueElement != null;
int startOffset = valueElement.getTextRange().getStartOffset();
int endOffset = tag.getTextRange().getEndOffset();
// Javadoc PSI is rather weird...
CharSequence text = document.getCharsSequence();
int i = CharArrayUtil.shiftBackward(text, endOffset - 1, " \t*");
if (i > 0 && text.charAt(i) == '\n') {
endOffset = i;
}
return Pair.create(TextRange.create(startOffset, endOffset), text.subSequence(startOffset, endOffset).toString());
}
private static void locateCaret(@NotNull PsiDocComment comment, @NotNull Editor editor) {
private static void locateCaret(@NotNull PsiDocComment comment, @NotNull Editor editor, @NotNull PsiFile file) {
Document document = editor.getDocument();
int lineToNavigate = -1;
for (PsiDocTag tag : comment.getTags()) {
@@ -274,7 +348,7 @@ public class JavaDocCommentFixer implements DocCommentFixer {
if (lineToNavigate >= 0) {
editor.getCaretModel().moveToOffset(document.getLineEndOffset(lineToNavigate));
JavadocNavigationDelegate.navigateToLineEnd(editor, comment.getContainingFile());
JavadocNavigationDelegate.navigateToLineEnd(editor, file);
}
}
}
@@ -427,14 +427,15 @@ class Test<T, V> {
}''')
}
void _testCorrectParametersOrder() {
void testCorrectParametersOrder() {
doTest(
initial: '''\
class Test {
/**
* @param j
* @param k k description
* @param i
* @param k single line description
* @param i multi-line
* description
*/
public void test(int i, int j, int k) {<caret>
}
@@ -442,9 +443,10 @@ class Test {
expected: '''\
class Test {
/**
* @param i <caret>
* @param j
* @param k k description
* @param i multi-line
* description
* @param j <caret>
* @param k single line description
*/
public void test(int i, int j, int k) {
}
@@ -452,12 +454,113 @@ class Test {
)
}
void testCorrectTypeParametersOrder() {
// TODO den implement
void testCorrectParametersDescriptionWhenIndentIsDefines() {
doTest(
initial: '''\
class Test {
/**
* @param j
* @param i
*/
public void test(int i, int j) {<caret>
}
}''',
expected: '''\
class Test {
/**
* @param i <caret>
* @param j
*/
public void test(int i, int j) {
}
}'''
)
}
void testCorrectMethodTypeParametersOrder() {
doTest(
initial: '''\
class Test {
/**
* @param <B>
* @param <A> A description
*/
<A, B> void test() {<caret>
}
}''',
expected: '''\
class Test {
/**
* @param <A> A description
* @param <B> <caret>
*/
<A, B> void test() {
}
}'''
)
}
void testCorrectClassTypeParametersOrder() {
doTest(
initial: '''\
/**
* Class description
* @author Zigmund
* @param <B> multi-line
* description
* @param <A>
*/
class Test<A, B> {<caret>
}''',
expected: '''\
/**
* Class description
* @author Zigmund
* @param <A> <caret>
* @param <B> multi-line
* description
*/
class Test<A, B> {
}'''
)
}
void testAllesZusammen() {
// TODO den implement
doTest(
initial: '''\
class MyException1 extends Exception {}
class MyException2 extends Exception {}
class Test {
/**
* Method description
* @param j j description (single line)
* @param s s description
* @param k
* k description (single line but located at another line)
* @throws MyException2
* @return some value
*/
void test(int i, int j, int k) throws MyException1 {<caret>
}
}''',
expected: '''\
class MyException1 extends Exception {}
class MyException2 extends Exception {}
class Test {
/**
* Method description
* @param i <caret>
* @param j j description (single line)
* @param k
* k description (single line but located at another line)
* @throws MyException1
*/
void test(int i, int j, int k) throws MyException1 {
}
}'''
)
}
void testNavigateToMissingParamDescription() {
@@ -481,14 +584,6 @@ class Test {
)
}
void testNavigateToMissingReturnDescription() {
// TODO den implement
}
void testNavigateToMissingThrowsDescription() {
// TODO den implement
}
private def doTest(Map args) {
configureFromFileText("${getTestName(false)}.java", args.initial)
myEditor.settings.virtualSpace = false