mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 13:02:30 +07:00
IDEA-63303 Collapsing of multiline //-style comment feature request
1. Added ability to configure IJ editor to auto-collapse multiple subsequent end of line comments; 2. Corresponding test is added;
This commit is contained in:
@@ -35,5 +35,6 @@ public class JavaCodeFoldingOptionsProvider extends BeanConfigurable<JavaCodeFol
|
||||
checkBox("COLLAPSE_CONSTRUCTOR_GENERIC_PARAMETERS", ApplicationBundle.message("checkbox.collapse.generic.constructor.parameters"));
|
||||
checkBox("COLLAPSE_I18N_MESSAGES", ApplicationBundle.message("checkbox.collapse.i18n.messages"));
|
||||
checkBox("COLLAPSE_SUPPRESS_WARNINGS", ApplicationBundle.message("checkbox.collapse.suppress.warnings"));
|
||||
checkBox("COLLAPSE_END_OF_LINE_COMMENTS", ApplicationBundle.message("checkbox.collapse.end.of.line.comments"));
|
||||
}
|
||||
}
|
||||
@@ -138,6 +138,16 @@ public class JavaCodeFoldingSettingsImpl extends JavaCodeFoldingSettings impleme
|
||||
COLLAPSE_SUPPRESS_WARNINGS = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollapseEndOfLineComments() {
|
||||
return COLLAPSE_END_OF_LINE_COMMENTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCollapseEndOfLineComments(boolean value) {
|
||||
COLLAPSE_END_OF_LINE_COMMENTS = value;
|
||||
}
|
||||
|
||||
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_ACCESSORS = false;
|
||||
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_INNER_CLASSES = false;
|
||||
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_ANONYMOUS_CLASSES = false;
|
||||
@@ -146,6 +156,7 @@ public class JavaCodeFoldingSettingsImpl extends JavaCodeFoldingSettings impleme
|
||||
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_CONSTRUCTOR_GENERIC_PARAMETERS = true;
|
||||
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_I18N_MESSAGES = true;
|
||||
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_SUPPRESS_WARNINGS = true;
|
||||
@SuppressWarnings({"WeakerAccess"}) public boolean COLLAPSE_END_OF_LINE_COMMENTS = false;
|
||||
|
||||
@NotNull
|
||||
public File[] getExportFiles() {
|
||||
|
||||
@@ -34,6 +34,7 @@ import com.intellij.psi.impl.source.SourceTreeToPsiMap;
|
||||
import com.intellij.psi.impl.source.jsp.jspJava.JspHolderMethod;
|
||||
import com.intellij.psi.impl.source.tree.JavaDocElementType;
|
||||
import com.intellij.psi.javadoc.PsiDocComment;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.PropertyUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
@@ -43,9 +44,7 @@ import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
|
||||
public class JavaFoldingBuilder extends FoldingBuilderEx implements DumbAware {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.folding.impl.JavaFoldingBuilder");
|
||||
@@ -115,6 +114,7 @@ public class JavaFoldingBuilder extends FoldingBuilderEx implements DumbAware {
|
||||
addAnnotationsToFold(aClass.getModifierList(), list, document);
|
||||
|
||||
PsiElement[] children = aClass.getChildren();
|
||||
Set<PsiElement> processedComments = new HashSet<PsiElement>();
|
||||
for (PsiElement child : children) {
|
||||
ProgressManager.checkCanceled();
|
||||
|
||||
@@ -132,7 +132,7 @@ public class JavaFoldingBuilder extends FoldingBuilderEx implements DumbAware {
|
||||
|
||||
PsiCodeBlock body = method.getBody();
|
||||
if (body != null) {
|
||||
addCodeBlockFolds(body, list, document, quick);
|
||||
addCodeBlockFolds(body, list, processedComments, document, quick);
|
||||
}
|
||||
}
|
||||
else if (child instanceof PsiField) {
|
||||
@@ -146,19 +146,22 @@ public class JavaFoldingBuilder extends FoldingBuilderEx implements DumbAware {
|
||||
addAnnotationsToFold(field.getModifierList(), list, document);
|
||||
PsiExpression initializer = field.getInitializer();
|
||||
if (initializer != null) {
|
||||
addCodeBlockFolds(initializer, list, document, quick);
|
||||
addCodeBlockFolds(initializer, list, processedComments, document, quick);
|
||||
} else if (field instanceof PsiEnumConstant) {
|
||||
addCodeBlockFolds(field, list, document, quick);
|
||||
addCodeBlockFolds(field, list, processedComments, document, quick);
|
||||
}
|
||||
}
|
||||
else if (child instanceof PsiClassInitializer) {
|
||||
PsiClassInitializer initializer = (PsiClassInitializer)child;
|
||||
addToFold(list, initializer, document, true);
|
||||
addCodeBlockFolds(initializer, list, document, quick);
|
||||
addCodeBlockFolds(initializer, list, processedComments, document, quick);
|
||||
}
|
||||
else if (child instanceof PsiClass) {
|
||||
addElementsToFold(list, (PsiClass)child, document, true, quick);
|
||||
}
|
||||
else if (child instanceof PsiComment) {
|
||||
addCommentFolds((PsiComment)child, processedComments, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,9 +186,12 @@ public class JavaFoldingBuilder extends FoldingBuilderEx implements DumbAware {
|
||||
else if (element instanceof PsiAnnotation) {
|
||||
return "@{...}";
|
||||
}
|
||||
if (element instanceof PsiReferenceParameterList) {
|
||||
else if (element instanceof PsiReferenceParameterList) {
|
||||
return SMILEY;
|
||||
}
|
||||
else if (element instanceof PsiComment) {
|
||||
return "//...";
|
||||
}
|
||||
return "...";
|
||||
}
|
||||
|
||||
@@ -226,6 +232,9 @@ public class JavaFoldingBuilder extends FoldingBuilderEx implements DumbAware {
|
||||
else if (element instanceof PsiAnnotation) {
|
||||
return settings.isCollapseAnnotations();
|
||||
}
|
||||
else if (element instanceof PsiComment) {
|
||||
return settings.isCollapseEndOfLineComments();
|
||||
}
|
||||
else {
|
||||
LOG.error("Unknown element:" + element);
|
||||
return false;
|
||||
@@ -349,10 +358,12 @@ public class JavaFoldingBuilder extends FoldingBuilderEx implements DumbAware {
|
||||
}
|
||||
}
|
||||
|
||||
private void addCodeBlockFolds(PsiElement scope, final List<FoldingDescriptor> foldElements, final Document document, final boolean quick) {
|
||||
private void addCodeBlockFolds(PsiElement scope, final List<FoldingDescriptor> foldElements,
|
||||
final @NotNull Set<PsiElement> processedComments, final Document document, final boolean quick)
|
||||
{
|
||||
scope.accept(new JavaRecursiveElementWalkingVisitor() {
|
||||
@Override public void visitClass(PsiClass aClass) {
|
||||
if (!addClosureFolding(aClass, document, foldElements, quick)) {
|
||||
if (!addClosureFolding(aClass, document, foldElements, processedComments, quick)) {
|
||||
addToFold(foldElements, aClass, document, true);
|
||||
addElementsToFold(foldElements, aClass, document, false, quick);
|
||||
}
|
||||
@@ -371,9 +382,64 @@ public class JavaFoldingBuilder extends FoldingBuilderEx implements DumbAware {
|
||||
|
||||
super.visitNewExpression(expression);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitComment(PsiComment comment) {
|
||||
addCommentFolds(comment, processedComments, foldElements);
|
||||
super.visitComment(comment);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* We want to allow to fold subsequent single line comments like
|
||||
* <pre>
|
||||
* // this is comment line 1
|
||||
* // this is comment line 2
|
||||
* </pre>
|
||||
*
|
||||
* @param comment comment to check
|
||||
* @param processedComments set that contains already processed elements. It is necessary because we process all elements of
|
||||
* the PSI tree, hence, this method may be called for both comments from the example above. However,
|
||||
* we want to create fold region during the first comment processing, put second comment to it and
|
||||
* skip processing when current method is called for the second element
|
||||
* @param foldElements fold descriptors holder to store newly created descriptor (if any)
|
||||
*/
|
||||
private static void addCommentFolds(@NotNull PsiComment comment, @NotNull Set<PsiElement> processedComments,
|
||||
@NotNull List<FoldingDescriptor> foldElements)
|
||||
{
|
||||
if (processedComments.contains(comment) || comment.getTokenType() != JavaTokenType.END_OF_LINE_COMMENT) {
|
||||
return;
|
||||
}
|
||||
|
||||
PsiElement end = null;
|
||||
for (PsiElement current = comment.getNextSibling(); current != null; current = current.getNextSibling()) {
|
||||
ASTNode node = current.getNode();
|
||||
if (node == null) {
|
||||
break;
|
||||
}
|
||||
IElementType elementType = node.getElementType();
|
||||
if (elementType == JavaTokenType.END_OF_LINE_COMMENT) {
|
||||
end = current;
|
||||
// We don't want to process, say, the second comment in case of three subsequent comments when it's being examined
|
||||
// during all elements traversal. I.e. we expect to start from the first comment and grab as many subsequent
|
||||
// comments as possible during the single iteration.
|
||||
processedComments.add(current);
|
||||
continue;
|
||||
}
|
||||
if (elementType == JavaTokenType.WHITE_SPACE) {
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (end != null) {
|
||||
foldElements.add(
|
||||
new FoldingDescriptor(comment, new TextRange(comment.getTextRange().getStartOffset(), end.getTextRange().getEndOffset()))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private static void addMethodGenericParametersFolding(PsiMethodCallExpression expression, List<FoldingDescriptor> foldElements, Document document, boolean quick) {
|
||||
final PsiReferenceExpression methodExpression = expression.getMethodExpression();
|
||||
final PsiReferenceParameterList list = methodExpression.getParameterList();
|
||||
@@ -485,7 +551,8 @@ public class JavaFoldingBuilder extends FoldingBuilderEx implements DumbAware {
|
||||
return anonymousClass.getMethods().length == 1;
|
||||
}
|
||||
|
||||
private boolean addClosureFolding(final PsiClass aClass, final Document document, final List<FoldingDescriptor> foldElements, final boolean quick) {
|
||||
private boolean addClosureFolding(final PsiClass aClass, final Document document, final List<FoldingDescriptor> foldElements,
|
||||
@NotNull Set<PsiElement> processedComments, final boolean quick) {
|
||||
if (!JavaCodeFoldingSettings.getInstance().isCollapseLambdas()) {
|
||||
return false;
|
||||
}
|
||||
@@ -595,7 +662,7 @@ public class JavaFoldingBuilder extends FoldingBuilderEx implements DumbAware {
|
||||
}
|
||||
});
|
||||
}
|
||||
addCodeBlockFolds(body, foldElements, document, quick);
|
||||
addCodeBlockFolds(body, foldElements, processedComments, document, quick);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
class Test {
|
||||
|
||||
<fold text='//...'>// class-level folding1
|
||||
// class-level folding2</fold>
|
||||
|
||||
public void foo() <fold text='{...}'>{
|
||||
<fold text='//...'>// method-level folding1
|
||||
// method-level folding2</fold>
|
||||
int i = 1;
|
||||
// method-level folding2
|
||||
}</fold>
|
||||
|
||||
// class-level folding3
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2000-2011 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.
|
||||
*/
|
||||
package com.intellij.codeInsight.folding;
|
||||
|
||||
import com.intellij.openapi.application.ex.PathManagerEx;
|
||||
import com.intellij.testFramework.fixtures.CodeInsightFixtureTestCase;
|
||||
|
||||
/**
|
||||
* @author Denis Zhdanov
|
||||
* @since 1/17/11 1:00 PM
|
||||
*/
|
||||
public class JavaFoldingTest extends CodeInsightFixtureTestCase {
|
||||
|
||||
public void testEndOfLineComments() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
StringBuilder path = new StringBuilder(PathManagerEx.getTestDataPath()).append("/codeInsight/folding/")
|
||||
.append(getTestName(false)).append(".java");
|
||||
myFixture.testFolding(path.toString());
|
||||
}
|
||||
}
|
||||
@@ -58,6 +58,8 @@ public abstract class JavaCodeFoldingSettings {
|
||||
public abstract void setCollapseI18nMessages(boolean value);
|
||||
|
||||
public abstract boolean isCollapseSuppressWarnings();
|
||||
|
||||
public abstract void setCollapseSuppressWarnings(boolean value);
|
||||
|
||||
public abstract boolean isCollapseEndOfLineComments();
|
||||
public abstract void setCollapseEndOfLineComments(boolean value);
|
||||
}
|
||||
|
||||
@@ -516,3 +516,4 @@ use.external.annotations=Use &external annotations
|
||||
insert.override.annotation=Insert @&Override annotation
|
||||
auto.import=Auto Import
|
||||
checkbox.collapse.suppress.warnings=<html>@SuppressWarnings</html>
|
||||
checkbox.collapse.end.of.line.comments=<html>End of line comments sequence</html>
|
||||
|
||||
Reference in New Issue
Block a user