diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/DocCommentBlock.java b/java/java-impl/src/com/intellij/psi/formatter/java/DocCommentBlock.java index d5b7e90b2fe6..b65393f3a4b3 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/DocCommentBlock.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/DocCommentBlock.java @@ -18,9 +18,9 @@ package com.intellij.psi.formatter.java; import com.intellij.formatting.*; import com.intellij.formatting.alignment.AlignmentStrategy; import com.intellij.lang.ASTNode; +import com.intellij.psi.JavaDocTokenType; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; import com.intellij.psi.formatter.FormatterUtil; -import com.intellij.psi.impl.source.tree.ElementType; import org.jetbrains.annotations.NotNull; import java.util.ArrayList; @@ -37,7 +37,7 @@ public class DocCommentBlock extends AbstractJavaBlock{ ASTNode child = myNode.getFirstChildNode(); while (child != null) { - if (child.getElementType() == ElementType.DOC_COMMENT_START) { + if (child.getElementType() == JavaDocTokenType.DOC_COMMENT_START) { result.add(createJavaBlock(child, mySettings, Indent.getNoneIndent(), null, AlignmentStrategy.getNullStrategy())); } else if (!FormatterUtil.containsWhiteSpacesOnly(child) && child.getText().trim().length() > 0){ result.add(createJavaBlock(child, mySettings, Indent.getSpaceIndent(1), null, AlignmentStrategy.getNullStrategy())); diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/FormatCommentsProcessor.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/FormatCommentsProcessor.java index de9cd1036298..841b8b530e16 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/FormatCommentsProcessor.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/FormatCommentsProcessor.java @@ -50,16 +50,30 @@ public class FormatCommentsProcessor implements PreFormatProcessor { @NotNull private static TextRange formatCommentsInner(@NotNull Project project, @NotNull ASTNode element, @NotNull final TextRange markedRange) { TextRange resultTextRange = markedRange; + final PsiElement elementPsi = element.getPsi(); boolean shouldFormat = markedRange.contains(element.getTextRange()); if (shouldFormat) { - TextRange before = element.getTextRange(); + final ASTNode rangeAnchor; + // There are two possible cases: + // 1. Given element correspond to comment's owner (e.g. field or method); + // 2. Given element corresponds to comment itself; + // However, doc comment formatter replaces old comment with the new one, hence, old element becomes invalid. That's why we need + // to calculate text length delta not for the given comment element (it's invalid because removed from the AST tree) but for + // its parent. + if (elementPsi instanceof PsiDocComment) { + rangeAnchor = element.getTreeParent(); + } + else { + rangeAnchor = element; + } + TextRange before = rangeAnchor.getTextRange(); new CommentFormatter(project).processComment(element); - int deltaRange = element.getTextRange().getLength() - before.getLength(); + int deltaRange = rangeAnchor.getTextRange().getLength() - before.getLength(); resultTextRange = new TextRange(markedRange.getStartOffset(), markedRange.getEndOffset() + deltaRange); } - final PsiElement elementPsi = element.getPsi(); + // If element is Psi{Method, Field, DocComment} and was formatted there is no reason to continue - we formatted all possible javadocs. // If element is out of range its children are also out of range. So in both cases formatting is finished. It's just for optimization. if ((shouldFormat && (elementPsi instanceof PsiMethod || elementPsi instanceof PsiField || elementPsi instanceof PsiDocComment)) @@ -70,7 +84,7 @@ public class FormatCommentsProcessor implements PreFormatProcessor { ASTNode current = element.getFirstChildNode(); while (current != null) { - //When element is PsiClass his PsiDocComment is formatted up to this moment, so we didn't need to format it again. + // When element is PsiClass its PsiDocComment is formatted up to this moment, so we didn't need to format it again. if (!(shouldFormat && current.getPsi() instanceof PsiDocComment && elementPsi instanceof PsiClass)) { resultTextRange = formatCommentsInner(project, current, resultTextRange); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/editorActions/FixDocCommentTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/editorActions/FixDocCommentTest.groovy index e5ff63b43a6a..183036b63e45 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/editorActions/FixDocCommentTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/editorActions/FixDocCommentTest.groovy @@ -34,7 +34,6 @@ class Test { expected: '''\ class Test { /** - * * @param i * @return */