mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-18 09:34:34 +07:00
IDEA-125863 Folding: inline parameter names for literal call arguments
This commit is contained in:
+1
@@ -27,6 +27,7 @@ import com.intellij.openapi.options.BeanConfigurable;
|
||||
public class JavaCodeFoldingOptionsProvider extends BeanConfigurable<JavaCodeFoldingSettings> implements CodeFoldingOptionsProvider {
|
||||
public JavaCodeFoldingOptionsProvider() {
|
||||
super(JavaCodeFoldingSettings.getInstance());
|
||||
checkBox("INLINE_PARAMETER_NAMES_FOR_LITERAL_CALL_ARGUMENTS", ApplicationBundle.message("checkbox.collapse.boolean.parameters"));
|
||||
checkBox("COLLAPSE_ONE_LINE_METHODS", ApplicationBundle.message("checkbox.collapse.one.line.methods"));
|
||||
checkBox("COLLAPSE_ACCESSORS", ApplicationBundle.message("checkbox.collapse.simple.property.accessors"));
|
||||
checkBox("COLLAPSE_INNER_CLASSES", ApplicationBundle.message("checkbox.collapse.inner.classes"));
|
||||
|
||||
@@ -64,4 +64,7 @@ public abstract class JavaCodeFoldingSettings {
|
||||
|
||||
public abstract boolean isCollapseEndOfLineComments();
|
||||
public abstract void setCollapseEndOfLineComments(boolean value);
|
||||
|
||||
public abstract boolean isInlineParameterNamesForLiteralCallArguments();
|
||||
public abstract void setInlineParameterNamesForLiteralCallArguments(boolean value);
|
||||
}
|
||||
|
||||
+11
@@ -14,6 +14,7 @@ public class JavaCodeFoldingSettingsBase extends JavaCodeFoldingSettings {
|
||||
@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;
|
||||
@SuppressWarnings({"WeakerAccess"}) public boolean INLINE_PARAMETER_NAMES_FOR_LITERAL_CALL_ARGUMENTS = true;
|
||||
|
||||
@Override
|
||||
public boolean isCollapseImports() {
|
||||
@@ -148,4 +149,14 @@ public class JavaCodeFoldingSettingsBase extends JavaCodeFoldingSettings {
|
||||
public void setCollapseEndOfLineComments(boolean value) {
|
||||
COLLAPSE_END_OF_LINE_COMMENTS = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInlineParameterNamesForLiteralCallArguments() {
|
||||
return INLINE_PARAMETER_NAMES_FOR_LITERAL_CALL_ARGUMENTS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInlineParameterNamesForLiteralCallArguments(boolean value) {
|
||||
INLINE_PARAMETER_NAMES_FOR_LITERAL_CALL_ARGUMENTS = value;
|
||||
}
|
||||
}
|
||||
|
||||
+52
@@ -703,6 +703,12 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
|
||||
else if (element instanceof PsiComment) {
|
||||
return settings.isCollapseEndOfLineComments();
|
||||
}
|
||||
else if (element instanceof PsiLiteralExpression
|
||||
&& element.getParent() instanceof PsiExpressionList
|
||||
&& (element.getParent().getParent() instanceof PsiCallExpression
|
||||
|| element.getParent().getParent() instanceof PsiAnonymousClass)) {
|
||||
return settings.isInlineParameterNamesForLiteralCallArguments();
|
||||
}
|
||||
else {
|
||||
LOG.error("Unknown element:" + element);
|
||||
return false;
|
||||
@@ -725,6 +731,7 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
|
||||
public void visitMethodCallExpression(PsiMethodCallExpression expression) {
|
||||
if (!dumb) {
|
||||
addMethodGenericParametersFolding(expression, foldElements, document, quick);
|
||||
inlineLiteralArgumentsNames(expression, foldElements, quick);
|
||||
}
|
||||
|
||||
super.visitMethodCallExpression(expression);
|
||||
@@ -734,6 +741,7 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
|
||||
public void visitNewExpression(PsiNewExpression expression) {
|
||||
if (!dumb) {
|
||||
addGenericParametersFolding(expression, foldElements, document, quick);
|
||||
inlineLiteralArgumentsNames(expression, foldElements, quick);
|
||||
}
|
||||
|
||||
super.visitNewExpression(expression);
|
||||
@@ -747,6 +755,50 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
|
||||
});
|
||||
}
|
||||
|
||||
private static void inlineLiteralArgumentsNames(@NotNull PsiCallExpression expression,
|
||||
@NotNull List<FoldingDescriptor> foldElements,
|
||||
boolean quick)
|
||||
{
|
||||
if (quick || !JavaCodeFoldingSettings.getInstance().isInlineParameterNamesForLiteralCallArguments()) {
|
||||
return;
|
||||
}
|
||||
PsiExpressionList callArgumentsList = expression.getArgumentList();
|
||||
if (callArgumentsList == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
PsiExpression[] callArguments = callArgumentsList.getExpressions();
|
||||
if (callArguments.length > 1) {
|
||||
PsiParameter[] parameters = null;
|
||||
boolean isResolved = false;
|
||||
|
||||
for (int i = 0; i < callArguments.length; i++) {
|
||||
PsiExpression callArgument = callArguments[i];
|
||||
|
||||
if (callArgument instanceof PsiLiteralExpression) {
|
||||
if (!isResolved) {
|
||||
PsiMethod method = expression.resolveMethod();
|
||||
isResolved = true;
|
||||
if (method == null) {
|
||||
return;
|
||||
}
|
||||
parameters = method.getParameterList().getParameters();
|
||||
if (parameters.length != callArguments.length) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
PsiParameter methodParam = parameters[i];
|
||||
if (PsiType.NULL.equals(callArgument.getType()) || methodParam.getType().equals(callArgument.getType())) {
|
||||
TextRange range = callArgument.getTextRange();
|
||||
String placeholderText = methodParam.getName() + ": " + callArgument.getText();
|
||||
foldElements.add(new NamedFoldingDescriptor(callArgument, range.getStartOffset(), range.getEndOffset(), null, placeholderText));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean addClosureFolding(final PsiClass aClass, final Document document, final List<FoldingDescriptor> foldElements,
|
||||
@NotNull Set<PsiElement> processedComments, final boolean quick) {
|
||||
if (!JavaCodeFoldingSettings.getInstance().isCollapseLambdas()) {
|
||||
|
||||
@@ -27,6 +27,7 @@ import com.intellij.openapi.editor.impl.FoldingModelImpl
|
||||
import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider
|
||||
import com.intellij.psi.JavaPsiFacade
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiLiteralExpression
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
@@ -592,6 +593,147 @@ class Test {
|
||||
assert regions[0].placeholderText == '{...}'
|
||||
}
|
||||
|
||||
public void "test insert boolean literal argument name"() {
|
||||
def text = """class Groo {
|
||||
|
||||
public void test() {
|
||||
boolean testNow = System.currentTimeMillis() > 34000;
|
||||
int times = 1;
|
||||
float pi = 4;
|
||||
String title = "Testing..."
|
||||
char ch = 'q'
|
||||
File file;
|
||||
|
||||
configure(true, false, 555, 3.141f, "Huge Title", 'c', null);
|
||||
configure(testNow, shouldIgnoreRoots(), fourteen, pi, title, c, file);
|
||||
}
|
||||
|
||||
pubic void configure(boolean testNow, boolean shouldIgnoreRoots, int times, float pi, String title, char terminate, File file) {
|
||||
System.out.println();
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
}"""
|
||||
configure text
|
||||
PsiClass fooClass = JavaPsiFacade.getInstance(project).findClass('Groo', GlobalSearchScope.allScope(project))
|
||||
|
||||
def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
|
||||
assert regions.size() == 9
|
||||
|
||||
def literals = fooClass.methods[0].body.statements[6].children[0].children[1].children.findAll { it instanceof PsiLiteralExpression }
|
||||
def parameters = fooClass.methods[1].parameterList.parameters
|
||||
|
||||
for (int i = 0; i < literals.size(); i++) {
|
||||
def currentElement = literals[i]
|
||||
def correspondingFolding = regions[i + 1]
|
||||
assert correspondingFolding.startOffset == currentElement.textRange.startOffset && correspondingFolding.endOffset == currentElement.textRange.endOffset
|
||||
assert correspondingFolding.placeholderText == parameters[i].name + ": " + currentElement.text
|
||||
}
|
||||
}
|
||||
|
||||
public void "test do not inline name if setter"() {
|
||||
def text = """class Groo {
|
||||
|
||||
public void test() {
|
||||
setTestNow(false);
|
||||
System.out.println("");
|
||||
}
|
||||
|
||||
pubic void setTestNow(boolean testNow) {
|
||||
System.out.println("");
|
||||
System.out.println("");
|
||||
}
|
||||
|
||||
}"""
|
||||
configure text
|
||||
def regions = myFixture.editor.foldingModel.allFoldRegions
|
||||
assert regions.size() == 2
|
||||
}
|
||||
|
||||
public void "test do not collapse varargs"() {
|
||||
def text = """
|
||||
public class VarArgTest {
|
||||
|
||||
public void main() {
|
||||
System.out.println("AAA");
|
||||
testBooleanVarargs(13, false);
|
||||
}
|
||||
|
||||
public boolean testBooleanVarargs(int test, boolean... booleans) {
|
||||
int temp = test;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
"""
|
||||
configure text
|
||||
def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
|
||||
assert regions.size() == 3
|
||||
checkRangeOffsetByPositionInText(regions[1], text, "13")
|
||||
assert regions[1].placeholderText == "test: 13"
|
||||
}
|
||||
|
||||
public void "test inline constructor literal arguments names"() {
|
||||
def text = """
|
||||
public class Test {
|
||||
|
||||
public void main() {
|
||||
System.out.println("AAA");
|
||||
Checker r = new Checker(true, false) {
|
||||
@Override
|
||||
void test() {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
abstract class Checker {
|
||||
Checker(boolean applyToFirst, boolean applyToSecond) {}
|
||||
abstract void test();
|
||||
}
|
||||
}
|
||||
"""
|
||||
configure text
|
||||
def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
|
||||
assert regions.length == 6
|
||||
|
||||
assert regions[1].placeholderText == "applyToFirst: true"
|
||||
assert regions[2].placeholderText == "applyToSecond: false"
|
||||
|
||||
checkRangeOffsetByPositionInText(regions[1], text, "true")
|
||||
checkRangeOffsetByPositionInText(regions[2], text, "false")
|
||||
}
|
||||
|
||||
public void "test inline anonymous class constructor literal arguments names"() {
|
||||
def text = """
|
||||
public class Test {
|
||||
|
||||
Test(int counter, boolean shouldTest) {
|
||||
System.out.println();
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
public static void main() {
|
||||
System.out.println();
|
||||
Test t = new Test(10, false);
|
||||
}
|
||||
|
||||
}
|
||||
"""
|
||||
configure text
|
||||
def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
|
||||
assert regions.length == 4
|
||||
|
||||
assert regions[2].placeholderText == "counter: 10"
|
||||
assert regions[3].placeholderText == "shouldTest: false"
|
||||
|
||||
checkRangeOffsetByPositionInText(regions[2], text, "10")
|
||||
checkRangeOffsetByPositionInText(regions[3], text, "false")
|
||||
}
|
||||
|
||||
private static def checkRangeOffsetByPositionInText(FoldRegion region, String text, String foldElement) {
|
||||
assert region.startOffset == text.indexOf(foldElement) && region.endOffset == text.indexOf(foldElement) + foldElement.length()
|
||||
}
|
||||
|
||||
|
||||
private def changeFoldRegions(Closure op) {
|
||||
myFixture.editor.foldingModel.runBatchFoldingOperationDoNotCollapseCaret(op)
|
||||
}
|
||||
|
||||
@@ -350,6 +350,7 @@ checkbox.collapse.annotations=<html>Annotations</html>
|
||||
checkbox.collapse.inner.classes=Inner classes
|
||||
checkbox.collapse.simple.property.accessors=<html>Simple property accessors<html>
|
||||
checkbox.collapse.one.line.methods=<html>One-line methods<html>
|
||||
checkbox.collapse.boolean.parameters=<html>Inline parameter names for literal call arguments</html>
|
||||
checkbox.collapse.method.bodies=Method bodies
|
||||
checkbox.collapse.javadoc.comments=Documentation comments
|
||||
checkbox.collapse.title.imports=Imports
|
||||
|
||||
Reference in New Issue
Block a user