diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/CommentFormatter.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/CommentFormatter.java index e08bb4844969..8e3b75b6fab7 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/CommentFormatter.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/CommentFormatter.java @@ -15,7 +15,6 @@ */ package com.intellij.psi.impl.source.codeStyle.javadoc; -import com.intellij.codeInsight.javadoc.JavaDocUtil; import com.intellij.ide.highlighter.JavaFileType; import com.intellij.lang.ASTNode; import com.intellij.lang.java.JavaLanguage; @@ -31,9 +30,12 @@ import com.intellij.psi.impl.source.SourceTreeToPsiMap; import com.intellij.psi.javadoc.PsiDocComment; import com.intellij.psi.util.PsiUtil; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.text.CharArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import static com.intellij.psi.impl.source.codeStyle.javadoc.JDParser.CommentInfo; + /** * @author max */ @@ -63,47 +65,12 @@ public class CommentFormatter { if (!getSettings().ENABLE_JAVADOC_FORMATTING) return; PsiElement psiElement = SourceTreeToPsiMap.treeElementToPsi(element); - processElementComment(psiElement); - } - - private void processElementComment(@Nullable PsiElement psiElement) { - if (psiElement instanceof PsiClass) { - String newCommentText = formatClassComment((PsiClass)psiElement); - replaceDocComment(newCommentText, (PsiDocCommentOwner)psiElement); - } - else if (psiElement instanceof PsiMethod) { - String newCommentText = formatMethodComment((PsiMethod)psiElement); - replaceDocComment(newCommentText, (PsiDocCommentOwner)psiElement); - } - else if (psiElement instanceof PsiField) { - String newCommentText = formatFieldComment((PsiField)psiElement); - replaceDocComment(newCommentText, (PsiDocCommentOwner)psiElement); - } - else if (psiElement instanceof PsiDocComment) { - PsiDocComment comment = (PsiDocComment)psiElement; - if (JavaDocUtil.isInsidePackageInfo(comment)) { - String newCommentText = formatPackageComment(comment); - replaceCommentText(newCommentText, comment); - } else { - processElementComment(psiElement.getParent()); - } + if (psiElement != null) { + getParser().formatCommentText(psiElement, this); } } - private String formatPackageComment(@NotNull PsiDocComment comment) { - final String info = getCommentInfo(comment); - if (info == null) return null; - - JDComment jdComment = getParser().parse(info, new JDComment(this)); - return jdComment.generate(""); - } - - private void replaceDocComment(@Nullable String newCommentText, @NotNull final PsiDocCommentOwner psiDocCommentOwner) { - final PsiDocComment oldComment = psiDocCommentOwner.getDocComment(); - replaceCommentText(newCommentText, oldComment); - } - - private void replaceCommentText(@Nullable String newCommentText, @Nullable PsiDocComment oldComment) { + public void replaceCommentText(@Nullable String newCommentText, @Nullable PsiDocComment oldComment) { if (newCommentText != null) newCommentText = stripSpaces(newCommentText); if (newCommentText == null || oldComment == null || newCommentText.equals(oldComment.getText())) { return; @@ -142,53 +109,22 @@ public class CommentFormatter { } @Nullable - private String formatClassComment(@NotNull PsiClass psiClass) { - final String info = getOrigCommentInfo(psiClass); - if (info == null) return null; - - JDComment comment = getParser().parse(info, new JDClassComment(this)); - return comment.generate(getIndent(psiClass)); - } - - @Nullable - private String formatMethodComment(@NotNull PsiMethod psiMethod) { - final String info = getOrigCommentInfo(psiMethod); - if (info == null) return null; - - JDComment comment = getParser().parse(info, new JDMethodComment(this)); - return comment.generate(getIndent(psiMethod)); - } - - @Nullable - private String formatFieldComment(@NotNull PsiField psiField) { - final String info = getOrigCommentInfo(psiField); - if (info == null) return null; - - JDComment comment = getParser().parse(info, new JDComment(this)); - return comment.generate(getIndent(psiField)); - } - - - /** - * Returns the original comment info of the specified element or null - * - * @param element the specified element - * @return text chunk - */ - @Nullable - private static String getOrigCommentInfo(PsiDocCommentOwner element) { + public static CommentInfo getOrigCommentInfo(PsiDocCommentOwner element) { PsiElement e = element.getFirstChild(); if (!(e instanceof PsiComment)) { //no comments for this element return null; } else { - return getCommentInfo(((PsiComment)e)); + return getCommentInfo((PsiComment)e); } } @Nullable - private static String getCommentInfo(PsiComment element) { + public static CommentInfo getCommentInfo(PsiComment element) { + String commentHeader = null; + String commentFooter = null; + StringBuilder sb = new StringBuilder(); PsiElement e = element; boolean first = true; @@ -201,11 +137,18 @@ public class CommentFormatter { sb.append(text.substring(2).trim()); } else if (text.startsWith("/*")) { - if (text.charAt(2) == '*') { - text = text.substring(3, Math.max(3, text.length() - 2)); + int commentHeaderEndOffset = CharArrayUtil.shiftForward(text, 1, "*"); + int commentFooterStartOffset = CharArrayUtil.shiftBackward(text, text.length() - 2, "*"); + + if (commentHeaderEndOffset <= commentFooterStartOffset) { + commentHeader = text.substring(0, commentHeaderEndOffset); + commentFooter = text.substring(commentFooterStartOffset + 1); + text = text.substring(commentHeaderEndOffset, commentFooterStartOffset + 1); } else { - text = text.substring(2, Math.max(2, text.length() - 2)); + commentHeader = text.substring(0, commentHeaderEndOffset); + text = ""; + commentFooter = ""; } sb.append(text); } @@ -217,7 +160,7 @@ public class CommentFormatter { e = e.getNextSibling(); } - return sb.toString(); + return new CommentInfo(commentHeader, sb.toString(), commentFooter); } /** @@ -226,6 +169,9 @@ public class CommentFormatter { * @return indentation size */ private int getIndentSpecial(@NotNull PsiElement element) { + if (element instanceof PsiDocComment) { + return 0; + } LOG.assertTrue(element instanceof PsiClass || element instanceof PsiField || element instanceof PsiMethod); @@ -252,7 +198,7 @@ public class CommentFormatter { * @return indent which would be used for the given element when it's formatted according to the current code style settings */ @NotNull - private String getIndent(@NotNull PsiElement element) { + public String getIndent(@NotNull PsiElement element) { return StringUtil.repeatSymbol(' ', getIndentSpecial(element)); } } diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDComment.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDComment.java index 0d51c0d2111f..69bdd3c41bf9 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDComment.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDComment.java @@ -37,6 +37,8 @@ public class JDComment { private String mySince; private String myDeprecated; private boolean myMultiLineComment; + private String myFirstLine = "/**"; + private String myEndLine = "*/"; public JDComment(@NotNull CommentFormatter formatter) { myFormatter = formatter; @@ -128,13 +130,13 @@ public class JDComment { || sb.indexOf("\n") != sb.length() - 1) // If comment has become multiline after formatting - it must be shown as multiline. // Last symbol is always '\n', so we need to check if there is one more LF symbol before it. { - sb.insert(0, "/**\n"); + sb.insert(0, myFirstLine + '\n'); sb.append(indent); } else { sb.replace(0, prefix.length(), "/** "); sb.deleteCharAt(sb.length()-1); } - sb.append(" */"); + sb.append(' ').append(myEndLine); return sb.toString(); } @@ -142,6 +144,14 @@ public class JDComment { protected void generateSpecial(@NotNull String prefix, @NotNull StringBuilder sb) { } + public void setFirstCommentLine(@NotNull String firstCommentLine) { + myFirstLine = firstCommentLine; + } + + public void setLastCommentLine(@NotNull String lastCommentLine) { + myEndLine = lastCommentLine; + } + public void addSeeAlso(@NotNull String seeAlso) { if (mySeeAlsoList == null) { mySeeAlsoList = ContainerUtilRt.newArrayList(); diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java index f6dc9b9697f2..4745c3890cee 100644 --- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java +++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/javadoc/JDParser.java @@ -19,7 +19,9 @@ import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.javadoc.PsiDocComment; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -40,6 +42,8 @@ public class JDParser { private static final String P_START_TAG = "
"; private static final String SELF_CLOSED_P_TAG = "
"; + private static final char lineSeparator = '\n'; + private final CodeStyleSettings mySettings; private final LanguageLevel myLanguageLevel; @@ -48,11 +52,74 @@ public class JDParser { myLanguageLevel = languageLevel; } - private static final char lineSeparator = '\n'; + public void formatCommentText(@NotNull PsiElement element, @NotNull CommentFormatter formatter) { + CommentInfo info = getElementsCommentInfo(element); + JDComment comment = info != null ? parse(info, formatter) : null; + if (comment != null) { + String indent = formatter.getIndent(info.getCommentOwner()); + String commentText = comment.generate(indent); + formatter.replaceCommentText(commentText, (PsiDocComment)info.psiComment); + } + } + + private CommentInfo getElementsCommentInfo(@Nullable PsiElement psiElement) { + CommentInfo info = null; + if (psiElement instanceof PsiDocComment) { + final PsiDocComment docComment = (PsiDocComment)psiElement; + if (docComment.getOwner() == null && docComment.getParent() instanceof PsiJavaFile) { + info = CommentFormatter.getCommentInfo(docComment); + if (info != null) { + info.setCommentOwner(docComment); + info.setComment(docComment); + } + } + else { + return getElementsCommentInfo(psiElement.getParent()); + } + } + else if (psiElement instanceof PsiDocCommentOwner) { + PsiDocCommentOwner owner = (PsiDocCommentOwner)psiElement; + info = CommentFormatter.getOrigCommentInfo(owner); + if (info != null) { + info.setCommentOwner(owner); + info.setComment(owner.getDocComment()); + } + } + return info; + } + + private JDComment parse(@NotNull CommentInfo info, @NotNull CommentFormatter formatter) { + PsiElement owner = info.getCommentOwner(); + JDComment comment = createComment(owner, formatter); + if (comment == null) return null; + + parse(info.comment, comment); + if (info.commentHeader != null) { + comment.setFirstCommentLine(info.commentHeader); + } + if (info.commentFooter != null) { + comment.setLastCommentLine(info.commentFooter); + } + + return comment; + } + + private JDComment createComment(@NotNull PsiElement psiElement, @NotNull CommentFormatter formatter) { + if (psiElement instanceof PsiClass) { + return new JDClassComment(formatter); + } + else if (psiElement instanceof PsiMethod) { + return new JDMethodComment(formatter); + } + else if (psiElement instanceof PsiField || psiElement instanceof PsiDocComment) { + return new JDComment(formatter); + } + return null; + } @NotNull - public JDComment parse(@Nullable String text, @NotNull JDComment comment) { - if (text == null) return comment; + private void parse(@Nullable String text, @NotNull JDComment comment) { + if (text == null) return; List