improve formatting of comment created with the "Replace with block comment" intention
[fedora-idea.git] / plugins / IntentionPowerPak / src / com / siyeh / ipp / comment / ChangeToCStyleCommentIntention.java
blob323ad8dabc78ed1661f83e51b1b935b80dc3f5aa
1 /*
2 * Copyright 2003-2009 Dave Griffith, Bas Leijdekkers
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com.siyeh.ipp.comment;
18 import com.intellij.openapi.util.text.StringUtil;
19 import com.intellij.psi.*;
20 import com.intellij.psi.tree.IElementType;
21 import com.intellij.psi.util.PsiTreeUtil;
22 import com.intellij.util.IncorrectOperationException;
23 import com.siyeh.ipp.base.Intention;
24 import com.siyeh.ipp.base.PsiElementPredicate;
25 import org.jetbrains.annotations.NotNull;
27 import java.util.ArrayList;
28 import java.util.List;
30 public class ChangeToCStyleCommentIntention extends Intention {
32 private static final Class<PsiWhiteSpace>[] WHITESPACE_CLASS =
33 new Class[]{PsiWhiteSpace.class};
35 @Override
36 @NotNull
37 protected PsiElementPredicate getElementPredicate() {
38 return new EndOfLineCommentPredicate();
41 @Override
42 public void processIntention(PsiElement element)
43 throws IncorrectOperationException {
44 PsiComment firstComment = (PsiComment) element;
45 while (true) {
46 final PsiElement prevComment =
47 PsiTreeUtil.skipSiblingsBackward(firstComment,
48 WHITESPACE_CLASS);
49 if (!isEndOfLineComment(prevComment)) {
50 break;
52 assert prevComment != null;
53 firstComment = (PsiComment)prevComment;
55 final JavaPsiFacade psiFacade =
56 JavaPsiFacade.getInstance(element.getProject());
57 final PsiElementFactory factory = psiFacade.getElementFactory();
58 final List<PsiComment> multiLineComments = new ArrayList<PsiComment>();
59 PsiElement nextComment = firstComment;
60 String whiteSpace = null;
61 while (true) {
62 nextComment = PsiTreeUtil.skipSiblingsForward(nextComment,
63 WHITESPACE_CLASS);
64 if (!isEndOfLineComment(nextComment)) {
65 break;
67 assert nextComment != null;
68 if (whiteSpace == null) {
69 final PsiElement prevSibling = nextComment.getPrevSibling();
70 assert prevSibling != null;
71 final String text = prevSibling.getText();
72 whiteSpace = getIndent(text);
74 multiLineComments.add((PsiComment)nextComment);
76 final String newCommentString;
77 if (multiLineComments.isEmpty()) {
78 final String text = getCommentContents(firstComment);
79 newCommentString = "/* " + text + " */";
80 } else {
81 final StringBuilder text = new StringBuilder();
82 text.append("/*\n");
83 text.append(whiteSpace);
84 text.append(getCommentContents(firstComment));
85 for (PsiComment multiLineComment : multiLineComments) {
86 text.append('\n');
87 text.append(whiteSpace);
88 text.append(getCommentContents(multiLineComment));
90 text.append('\n');
91 text.append(whiteSpace);
92 text.append("*/");
93 newCommentString = text.toString();
95 final PsiComment newComment =
96 factory.createCommentFromText(newCommentString, element);
97 firstComment.replace(newComment);
98 for (PsiElement commentToDelete : multiLineComments) {
99 commentToDelete.delete();
103 private static String getIndent(String whitespace) {
104 for (int i = whitespace.length() - 1; i >= 0; i--) {
105 final char c = whitespace.charAt(i);
106 if (c == '\n') {
107 if (i == whitespace.length() - 1) {
108 return "";
110 return whitespace.substring(i + 1);
113 return whitespace;
116 private static boolean isEndOfLineComment(PsiElement element) {
117 if (!(element instanceof PsiComment)) {
118 return false;
120 final PsiComment comment = (PsiComment)element;
121 final IElementType tokenType = comment.getTokenType();
122 return JavaTokenType.END_OF_LINE_COMMENT.equals(tokenType);
125 private static String getCommentContents(@NotNull PsiComment comment) {
126 final String text = comment.getText();
127 return StringUtil.replace(text.substring(2), "*/", "* /").trim();