mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-13 21:55:01 +07:00
literal arguments folding: fold one char instead of the whole literal; folding in case of generic method fixed; Settings|Editor|General|Code Folding|Literal arguments|Minimum arguments to fold and Minimum parameter name length settings added
This commit is contained in:
+42
-11
@@ -27,16 +27,47 @@ 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"));
|
||||
checkBox("COLLAPSE_ANONYMOUS_CLASSES", ApplicationBundle.message("checkbox.collapse.anonymous.classes"));
|
||||
checkBox("COLLAPSE_ANNOTATIONS", ApplicationBundle.message("checkbox.collapse.annotations"));
|
||||
checkBox("COLLAPSE_CLOSURES", ApplicationBundle.message("checkbox.collapse.closures"));
|
||||
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"));
|
||||
JavaCodeFoldingSettings settings = getInstance();
|
||||
checkBox(ApplicationBundle.message("checkbox.collapse.boolean.parameters"), settings::isInlineParameterNamesForLiteralCallArguments, settings::setInlineParameterNamesForLiteralCallArguments);
|
||||
JavaCodeFoldingSettingsPanel panel = new JavaCodeFoldingSettingsPanel();
|
||||
|
||||
component(panel.getRow0(),
|
||||
() -> null,
|
||||
pair -> {},
|
||||
() -> null,
|
||||
pair -> {}
|
||||
);
|
||||
component(panel.getRow1(),
|
||||
settings::getInlineLiteralParameterMinNameLength,
|
||||
settings::setInlineLiteralParameterMinNameLength,
|
||||
panel::getMinNameLengthThresholdText,
|
||||
panel::setMinNameLengthThresholdText
|
||||
);
|
||||
component(panel.getRow2(),
|
||||
settings::getInlineLiteralParameterMinArgumentsToFold,
|
||||
settings::setInlineLiteralParameterMinArgumentsToFold,
|
||||
panel::getMinArgumentsToFoldText,
|
||||
panel::setMinArgumentsToFoldText
|
||||
);
|
||||
|
||||
checkBox(ApplicationBundle.message("checkbox.collapse.one.line.methods"), settings::isCollapseOneLineMethods, settings::setCollapseOneLineMethods);
|
||||
|
||||
checkBox(ApplicationBundle.message("checkbox.collapse.simple.property.accessors"), settings::isCollapseAccessors, settings::setCollapseAccessors);
|
||||
|
||||
checkBox(ApplicationBundle.message("checkbox.collapse.inner.classes"), settings::isCollapseInnerClasses, settings::setCollapseInnerClasses);
|
||||
|
||||
checkBox(ApplicationBundle.message("checkbox.collapse.anonymous.classes"), settings::isCollapseAnonymousClasses, settings::setCollapseAnonymousClasses);
|
||||
|
||||
checkBox(ApplicationBundle.message("checkbox.collapse.annotations"), settings::isCollapseAnnotations, settings::setCollapseAnnotations);
|
||||
|
||||
checkBox(ApplicationBundle.message("checkbox.collapse.closures"), settings::isCollapseLambdas, settings::setCollapseLambdas);
|
||||
|
||||
checkBox(ApplicationBundle.message("checkbox.collapse.generic.constructor.parameters"), settings::isCollapseConstructorGenericParameters, settings::setCollapseConstructorGenericParameters);
|
||||
|
||||
checkBox(ApplicationBundle.message("checkbox.collapse.i18n.messages"), settings::isCollapseI18nMessages, settings::setCollapseI18nMessages);
|
||||
|
||||
checkBox(ApplicationBundle.message("checkbox.collapse.suppress.warnings"), settings::isCollapseSuppressWarnings, settings::setCollapseSuppressWarnings);
|
||||
|
||||
checkBox(ApplicationBundle.message("checkbox.collapse.end.of.line.comments"), settings::isCollapseEndOfLineComments, settings::setCollapseEndOfLineComments);
|
||||
}
|
||||
}
|
||||
+83
@@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.application.options.editor.JavaCodeFoldingSettingsPanel">
|
||||
<grid id="27dc6" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="852" height="97"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<grid id="bc2a4" binding="row1" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="a067a" class="javax.swing.JTextField" binding="minNameLengthThresholdText">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="2746f" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="5" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Minimum Parameter Name Length:"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="8e464" binding="row2" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="11578" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="5" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Minimum Number of Arguments To Fold:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="dc29a" class="javax.swing.JTextField" binding="minArgumentsToFoldText">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="72ed7" binding="row0" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="c0ee0" class="com.intellij.ui.TitledSeparator">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="4" anchor="0" fill="1" indent="3" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Literal Arguments Options"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.application.options.editor;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
public class JavaCodeFoldingSettingsPanel {
|
||||
private JTextField minNameLengthThresholdText;
|
||||
private JTextField minArgumentsToFoldText;
|
||||
private JPanel row0;
|
||||
private JPanel row1;
|
||||
private JPanel row2;
|
||||
|
||||
int getMinNameLengthThresholdText() {
|
||||
try {
|
||||
return Integer.parseInt(minNameLengthThresholdText.getText());
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
void setMinNameLengthThresholdText(int value) {
|
||||
minNameLengthThresholdText.setText(String.valueOf(value));
|
||||
}
|
||||
|
||||
int getMinArgumentsToFoldText() {
|
||||
try {
|
||||
return Integer.parseInt(minArgumentsToFoldText.getText());
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
void setMinArgumentsToFoldText(int value) {
|
||||
minArgumentsToFoldText.setText(String.valueOf(value));
|
||||
}
|
||||
|
||||
JComponent getRow0() {
|
||||
return row0;
|
||||
}
|
||||
|
||||
JPanel getRow1() {
|
||||
return row1;
|
||||
}
|
||||
|
||||
JPanel getRow2() {
|
||||
return row2;
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,7 @@ public abstract class JavaCodeFoldingSettings {
|
||||
public abstract void setCollapseAccessors(boolean value);
|
||||
|
||||
public abstract boolean isCollapseOneLineMethods();
|
||||
public abstract void setCollapseOneLineMethods(boolean value);
|
||||
|
||||
public abstract boolean isCollapseInnerClasses();
|
||||
public abstract void setCollapseInnerClasses(boolean value);
|
||||
@@ -67,4 +68,10 @@ public abstract class JavaCodeFoldingSettings {
|
||||
|
||||
public abstract boolean isInlineParameterNamesForLiteralCallArguments();
|
||||
public abstract void setInlineParameterNamesForLiteralCallArguments(boolean value);
|
||||
|
||||
public abstract int getInlineLiteralParameterMinNameLength();
|
||||
public abstract void setInlineLiteralParameterMinNameLength(int value);
|
||||
|
||||
public abstract int getInlineLiteralParameterMinArgumentsToFold();
|
||||
public abstract void setInlineLiteralParameterMinArgumentsToFold(int value);
|
||||
}
|
||||
|
||||
+38
-11
@@ -19,17 +19,19 @@ import com.intellij.codeInsight.folding.CodeFoldingSettings;
|
||||
import com.intellij.codeInsight.folding.JavaCodeFoldingSettings;
|
||||
|
||||
public class JavaCodeFoldingSettingsBase extends JavaCodeFoldingSettings {
|
||||
@SuppressWarnings("WeakerAccess") public boolean COLLAPSE_ACCESSORS;
|
||||
@SuppressWarnings("WeakerAccess") public boolean COLLAPSE_ONE_LINE_METHODS = true;
|
||||
@SuppressWarnings("WeakerAccess") public boolean COLLAPSE_INNER_CLASSES;
|
||||
@SuppressWarnings("WeakerAccess") public boolean COLLAPSE_ANONYMOUS_CLASSES;
|
||||
@SuppressWarnings("WeakerAccess") public boolean COLLAPSE_ANNOTATIONS;
|
||||
@SuppressWarnings("WeakerAccess") public boolean COLLAPSE_CLOSURES = true;
|
||||
@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;
|
||||
@SuppressWarnings("WeakerAccess") public boolean INLINE_PARAMETER_NAMES_FOR_LITERAL_CALL_ARGUMENTS;
|
||||
private boolean COLLAPSE_ACCESSORS;
|
||||
private boolean COLLAPSE_ONE_LINE_METHODS = true;
|
||||
private boolean COLLAPSE_INNER_CLASSES;
|
||||
private boolean COLLAPSE_ANONYMOUS_CLASSES;
|
||||
private boolean COLLAPSE_ANNOTATIONS;
|
||||
private boolean COLLAPSE_CLOSURES = true;
|
||||
private boolean COLLAPSE_CONSTRUCTOR_GENERIC_PARAMETERS = true;
|
||||
private boolean COLLAPSE_I18N_MESSAGES = true;
|
||||
private boolean COLLAPSE_SUPPRESS_WARNINGS = true;
|
||||
private boolean COLLAPSE_END_OF_LINE_COMMENTS;
|
||||
private boolean INLINE_PARAMETER_NAMES_FOR_LITERAL_CALL_ARGUMENTS;
|
||||
private int INLINE_LITERAL_PARAMETER_MIN_NAME_LENGTH = 3;
|
||||
private int INLINE_LITERAL_PARAMETER_MIN_ARGS_TO_FOLD = 2;
|
||||
|
||||
@Override
|
||||
public boolean isCollapseImports() {
|
||||
@@ -85,6 +87,11 @@ public class JavaCodeFoldingSettingsBase extends JavaCodeFoldingSettings {
|
||||
return COLLAPSE_ONE_LINE_METHODS;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCollapseOneLineMethods(boolean value) {
|
||||
COLLAPSE_ONE_LINE_METHODS = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCollapseInnerClasses() {
|
||||
return COLLAPSE_INNER_CLASSES;
|
||||
@@ -174,4 +181,24 @@ public class JavaCodeFoldingSettingsBase extends JavaCodeFoldingSettings {
|
||||
public void setInlineParameterNamesForLiteralCallArguments(boolean value) {
|
||||
INLINE_PARAMETER_NAMES_FOR_LITERAL_CALL_ARGUMENTS = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInlineLiteralParameterMinNameLength() {
|
||||
return INLINE_LITERAL_PARAMETER_MIN_NAME_LENGTH;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInlineLiteralParameterMinNameLength(int value) {
|
||||
INLINE_LITERAL_PARAMETER_MIN_NAME_LENGTH = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getInlineLiteralParameterMinArgumentsToFold() {
|
||||
return INLINE_LITERAL_PARAMETER_MIN_ARGS_TO_FOLD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInlineLiteralParameterMinArgumentsToFold(int value) {
|
||||
INLINE_LITERAL_PARAMETER_MIN_ARGS_TO_FOLD = value;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-3
@@ -807,13 +807,12 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
|
||||
|
||||
private static void inlineLiteralArgumentsNames(@NotNull PsiCallExpression expression,
|
||||
@NotNull List<FoldingDescriptor> foldElements,
|
||||
boolean quick)
|
||||
{
|
||||
boolean quick) {
|
||||
if (quick || !JavaCodeFoldingSettings.getInstance().isInlineParameterNamesForLiteralCallArguments()) {
|
||||
return;
|
||||
}
|
||||
ParameterNameFoldingManager manager = new ParameterNameFoldingManager(expression);
|
||||
foldElements.addAll(manager.buildDescriptors());
|
||||
foldElements.addAll(manager.getDescriptors());
|
||||
}
|
||||
|
||||
private boolean addClosureFolding(@NotNull PsiClass aClass,
|
||||
|
||||
+52
-46
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.codeInsight.folding.impl;
|
||||
|
||||
import com.intellij.codeInsight.folding.JavaCodeFoldingSettings;
|
||||
import com.intellij.lang.folding.FoldingDescriptor;
|
||||
import com.intellij.lang.folding.NamedFoldingDescriptor;
|
||||
import com.intellij.openapi.util.Couple;
|
||||
@@ -27,12 +28,11 @@ import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ParameterNameFoldingManager {
|
||||
private static final int MIN_NAME_LENGTH_THRESHOLD = 3;
|
||||
private static final int MIN_ARGS_TO_FOLD = 2;
|
||||
|
||||
class ParameterNameFoldingManager {
|
||||
private static final List<Couple<String>> COMMONLY_USED_PARAMETER_PAIR = ContainerUtil.newArrayList(
|
||||
Couple.of("begin", "end"),
|
||||
Couple.of("start", "end"),
|
||||
@@ -43,16 +43,27 @@ public class ParameterNameFoldingManager {
|
||||
Couple.of("min", "max")
|
||||
);
|
||||
|
||||
private final PsiCallExpression myCallExpression;
|
||||
@NotNull
|
||||
private final List<FoldingDescriptor> myDescriptors;
|
||||
|
||||
private PsiExpression[] myCallArguments;
|
||||
private PsiParameter[] myParameters;
|
||||
ParameterNameFoldingManager(@NotNull PsiCallExpression callExpression) {
|
||||
PsiExpression[] callArguments = getArguments(callExpression);
|
||||
JavaResolveResult resolveResult = callExpression.resolveMethodGenerics();
|
||||
|
||||
public ParameterNameFoldingManager(@NotNull PsiCallExpression callExpression) {
|
||||
myCallExpression = callExpression;
|
||||
JavaCodeFoldingSettings settings = JavaCodeFoldingSettings.getInstance();
|
||||
List<FoldingDescriptor> descriptors = Collections.emptyList();
|
||||
if (callArguments.length >= settings.getInlineLiteralParameterMinArgumentsToFold() &&
|
||||
hasLiteralExpression(callArguments) &&
|
||||
resolveResult.getElement() instanceof PsiMethod) {
|
||||
PsiMethod method = (PsiMethod)resolveResult.getElement();
|
||||
PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
descriptors = buildDescriptorsForLiteralArguments(callArguments, parameters, resolveResult);
|
||||
}
|
||||
|
||||
myDescriptors = descriptors;
|
||||
}
|
||||
|
||||
public static boolean isLiteralExpression(@Nullable PsiElement callArgument) {
|
||||
static boolean isLiteralExpression(@Nullable PsiElement callArgument) {
|
||||
if (callArgument instanceof PsiLiteralExpression)
|
||||
return true;
|
||||
|
||||
@@ -66,43 +77,32 @@ public class ParameterNameFoldingManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiExpression[] getArguments(@NotNull PsiCallExpression call) {
|
||||
@NotNull
|
||||
private static PsiExpression[] getArguments(@NotNull PsiCallExpression call) {
|
||||
PsiExpressionList callArgumentsList = call.getArgumentList();
|
||||
return callArgumentsList != null ? callArgumentsList.getExpressions() : null;
|
||||
return callArgumentsList == null ? PsiExpression.EMPTY_ARRAY : callArgumentsList.getExpressions();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<FoldingDescriptor> buildDescriptors() {
|
||||
myCallArguments = getArguments(myCallExpression);
|
||||
|
||||
if (myCallArguments != null && myCallArguments.length >= MIN_ARGS_TO_FOLD && hasLiteralExpression(myCallArguments)) {
|
||||
PsiMethod method = myCallExpression.resolveMethod();
|
||||
|
||||
if (method != null) {
|
||||
myParameters = method.getParameterList().getParameters();
|
||||
if (myParameters.length == myCallArguments.length) {
|
||||
return buildDescriptorsForLiteralArguments();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ContainerUtil.emptyList();
|
||||
List<FoldingDescriptor> getDescriptors() {
|
||||
return myDescriptors;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<FoldingDescriptor> buildDescriptorsForLiteralArguments() {
|
||||
List<FoldingDescriptor> descriptors = ContainerUtil.newArrayList();
|
||||
private static List<FoldingDescriptor> buildDescriptorsForLiteralArguments(@NotNull PsiExpression[] callArguments,
|
||||
@NotNull PsiParameter[] parameters,
|
||||
@NotNull JavaResolveResult resolveResult) {
|
||||
List<FoldingDescriptor> descriptors = new ArrayList<FoldingDescriptor>();
|
||||
|
||||
int i = 0;
|
||||
while (i < myCallArguments.length) {
|
||||
if (i + 1 < myCallArguments.length && isCommonlyNamedParameterPair(i, i + 1)) {
|
||||
while (i < callArguments.length && i < parameters.length) {
|
||||
if (i + 1 < callArguments.length && isCommonlyNamedParameterPair(i, i + 1, parameters)) {
|
||||
i += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (shouldInlineParameterName(i)) {
|
||||
descriptors.add(createFoldingDescriptor(myCallArguments[i], myParameters[i]));
|
||||
if (!(parameters[i].getType() instanceof PsiEllipsisType) && shouldInlineParameterName(i, callArguments, parameters, resolveResult)) {
|
||||
descriptors.add(createFoldingDescriptor(callArguments[i], parameters[i]));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
@@ -112,16 +112,17 @@ public class ParameterNameFoldingManager {
|
||||
|
||||
@NotNull
|
||||
private static NamedFoldingDescriptor createFoldingDescriptor(@NotNull PsiExpression callArgument, @NotNull PsiParameter methodParam) {
|
||||
TextRange range = callArgument.getTextRange();
|
||||
String placeholderText = methodParam.getName() + ": " + callArgument.getText();
|
||||
return new NamedFoldingDescriptor(callArgument, range.getStartOffset(), range.getEndOffset(), null, placeholderText);
|
||||
PsiElement lParenOrCommaOrWhitespaceOrComment = callArgument.getPrevSibling();
|
||||
TextRange range = lParenOrCommaOrWhitespaceOrComment.getTextRange();
|
||||
String placeholderText = StringUtil.last(lParenOrCommaOrWhitespaceOrComment.getText(), 1, false) + methodParam.getName() + ": ";
|
||||
return new NamedFoldingDescriptor(callArgument, range.getEndOffset()-1, range.getEndOffset(), null, placeholderText);
|
||||
}
|
||||
|
||||
private boolean isCommonlyNamedParameterPair(int first, int second) {
|
||||
assert first < myParameters.length && second < myParameters.length;
|
||||
private static boolean isCommonlyNamedParameterPair(int first, int second, PsiParameter[] parameters) {
|
||||
if (!(first < parameters.length && second < parameters.length)) return false;
|
||||
|
||||
String firstParamName = myParameters[first].getName();
|
||||
String secondParamName = myParameters[second].getName();
|
||||
String firstParamName = parameters[first].getName();
|
||||
String secondParamName = parameters[second].getName();
|
||||
if (firstParamName == null || secondParamName == null) return false;
|
||||
|
||||
for (Couple<String> knownPair : COMMONLY_USED_PARAMETER_PAIR) {
|
||||
@@ -134,13 +135,18 @@ public class ParameterNameFoldingManager {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean shouldInlineParameterName(int paramIndex) {
|
||||
PsiExpression argument = myCallArguments[paramIndex];
|
||||
private static boolean shouldInlineParameterName(int paramIndex,
|
||||
@NotNull PsiExpression[] callArguments,
|
||||
@NotNull PsiParameter[] parameters,
|
||||
@NotNull JavaResolveResult resolveResult) {
|
||||
PsiExpression argument = callArguments[paramIndex];
|
||||
if (isLiteralExpression(argument) && argument.getType() != null) {
|
||||
PsiParameter parameter = myParameters[paramIndex];
|
||||
PsiParameter parameter = parameters[paramIndex];
|
||||
String paramName = parameter.getName();
|
||||
if (paramName != null && paramName.length() >= MIN_NAME_LENGTH_THRESHOLD) {
|
||||
return TypeConversionUtil.isAssignable(parameter.getType(), argument.getType());
|
||||
JavaCodeFoldingSettings settings = JavaCodeFoldingSettings.getInstance();
|
||||
if (paramName != null && paramName.length() >= settings.getInlineLiteralParameterMinNameLength()) {
|
||||
PsiType parameterType = resolveResult.getSubstitutor().substitute(parameter.getType());
|
||||
return TypeConversionUtil.isAssignable(parameterType, argument.getType());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -31,7 +31,6 @@ import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider
|
||||
import com.intellij.openapi.util.registry.Registry
|
||||
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.EditorTestUtil
|
||||
@@ -687,15 +686,13 @@ class Test {
|
||||
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
|
||||
}
|
||||
checkTheFoldingStartsRightBefore(regions[1], text, "(testNow: ", "true")
|
||||
checkTheFoldingStartsRightBefore(regions[2], text, " shouldIgnoreRoots: ", "false")
|
||||
checkTheFoldingStartsRightBefore(regions[3], text, " times: ", "555")
|
||||
checkTheFoldingStartsRightBefore(regions[4], text, " pii: ", "3.141f")
|
||||
checkTheFoldingStartsRightBefore(regions[5], text, " title: ", '"Huge Title"')
|
||||
checkTheFoldingStartsRightBefore(regions[6], text, " terminate: ", "'c'")
|
||||
checkTheFoldingStartsRightBefore(regions[7], text, " file: ", "null")
|
||||
}
|
||||
|
||||
public void "test do not inline name if setter"() {
|
||||
@@ -738,8 +735,7 @@ public class VarArgTest {
|
||||
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"
|
||||
checkTheFoldingStartsRightBefore(regions[1], text, "(test: ", "13")
|
||||
}
|
||||
|
||||
public void "test do not inline if parameter length is one or two"() {
|
||||
@@ -857,14 +853,11 @@ public class CharSymbol {
|
||||
def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
|
||||
assert regions.size() == 5
|
||||
|
||||
checkRangeOffsetByPositionInText(regions[1], text, "100")
|
||||
assert regions[1].placeholderText == "test: 100"
|
||||
checkTheFoldingStartsRightBefore(regions[1], text, "(test: ", "100")
|
||||
|
||||
checkRangeOffsetByPositionInText(regions[2], text, "false")
|
||||
assert regions[2].placeholderText == "boo: false"
|
||||
checkTheFoldingStartsRightBefore(regions[2], text, " boo: ", "false")
|
||||
|
||||
checkRangeOffsetByPositionInText(regions[3], text, '"Hi!"')
|
||||
assert regions[3].placeholderText == 'seq: "Hi!"'
|
||||
checkTheFoldingStartsRightBefore(regions[3], text, " seq: ", '"Hi!"')
|
||||
}
|
||||
|
||||
public void "test inline negative and positive numbers"() {
|
||||
@@ -890,11 +883,53 @@ public class CharSymbol {
|
||||
def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
|
||||
assert regions.size() == 4
|
||||
|
||||
checkRangeOffsetByPositionInText(regions[1], text, "-1")
|
||||
assert regions[1].placeholderText == "test: -1"
|
||||
checkTheFoldingStartsRightBefore(regions[1], text, "(test: ", "-1")
|
||||
checkTheFoldingStartsRightBefore(regions[2], text, "(test: ", "+1")
|
||||
}
|
||||
|
||||
checkRangeOffsetByPositionInText(regions[2], text, "+1")
|
||||
assert regions[2].placeholderText == "test: +1"
|
||||
public void "test inline literal arguments with crazy settings"() {
|
||||
myFoldingSettings.setInlineParameterNamesForLiteralCallArguments(true);
|
||||
myFoldingSettings.setInlineLiteralParameterMinArgumentsToFold(1);
|
||||
myFoldingSettings.setInlineLiteralParameterMinNameLength(1);
|
||||
@Language("JAVA")
|
||||
def text = """
|
||||
public class Test {
|
||||
public void main(boolean isActive, boolean requestFocus, int xoo) {
|
||||
System.out.println("AAA");
|
||||
main(true,false, /*comment*/2);
|
||||
}
|
||||
}
|
||||
"""
|
||||
configure text
|
||||
def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
|
||||
|
||||
checkTheFoldingStartsRightBefore(regions[1], text, "(x: ", '"AAA"')
|
||||
checkTheFoldingStartsRightBefore(regions[2], text, "(isActive: ", "true")
|
||||
checkTheFoldingStartsRightBefore(regions[3], text, ",requestFocus: ", "false")
|
||||
checkTheFoldingStartsRightBefore(regions[4], text, "/xoo: ", "2")
|
||||
}
|
||||
|
||||
public void "test inline literal arguments with generics"() {
|
||||
myFoldingSettings.setInlineParameterNamesForLiteralCallArguments(true);
|
||||
myFoldingSettings.setInlineLiteralParameterMinArgumentsToFold(1);
|
||||
myFoldingSettings.setInlineLiteralParameterMinNameLength(1);
|
||||
@Language("JAVA")
|
||||
def text = """
|
||||
import java.util.*;
|
||||
public class Test {
|
||||
public void main(Comparator<Integer> c, List<String> l) {
|
||||
c.compare(0, /** ddd */3);
|
||||
l.add(1, "uuu");
|
||||
}
|
||||
}
|
||||
"""
|
||||
configure text
|
||||
def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
|
||||
|
||||
checkTheFoldingStartsRightBefore(regions[1], text, "(o1: ", '0')
|
||||
checkTheFoldingStartsRightBefore(regions[2], text, "/o2: ", "3")
|
||||
checkTheFoldingStartsRightBefore(regions[3], text, "(index: ", "1")
|
||||
checkTheFoldingStartsRightBefore(regions[4], text, " element: ", '"uuu"')
|
||||
}
|
||||
|
||||
public void "test inline constructor literal arguments names"() {
|
||||
@@ -922,11 +957,14 @@ public class Test {
|
||||
def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
|
||||
assert regions.length == 6
|
||||
|
||||
assert regions[1].placeholderText == "isActive: true"
|
||||
assert regions[2].placeholderText == "requestFocus: false"
|
||||
checkTheFoldingStartsRightBefore(regions[1], text, "(isActive: ", "true")
|
||||
checkTheFoldingStartsRightBefore(regions[2], text, " requestFocus: ", "false")
|
||||
}
|
||||
|
||||
checkRangeOffsetByPositionInText(regions[1], text, "true")
|
||||
checkRangeOffsetByPositionInText(regions[2], text, "false")
|
||||
private static def checkTheFoldingStartsRightBefore(FoldRegion region, String fileText, String placeHolder, String fileTextAfterFold) {
|
||||
assert region.endOffset == fileText.indexOf(fileTextAfterFold)
|
||||
assert region.startOffset == region.endOffset - 1
|
||||
assert region.placeholderText == placeHolder : "expected placeholder text: "+placeHolder+"; but got: "+region.placeholderText
|
||||
}
|
||||
|
||||
public void "test inline anonymous class constructor literal arguments names"() {
|
||||
@@ -951,18 +989,10 @@ public class Test {
|
||||
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")
|
||||
checkTheFoldingStartsRightBefore(regions[2], text, "(counter: ", "10")
|
||||
checkTheFoldingStartsRightBefore(regions[3], text, " shouldTest: ", "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)
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
package com.intellij.openapi.options;
|
||||
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Getter;
|
||||
import com.intellij.openapi.util.Setter;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -48,26 +50,27 @@ public abstract class BeanConfigurable<T> implements UnnamedConfigurable {
|
||||
return myComponent;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
abstract T createComponent();
|
||||
|
||||
boolean isModified(Object instance) {
|
||||
boolean isModified(@NotNull Object instance) {
|
||||
final Object componentValue = getComponentValue();
|
||||
final Object beanValue = getBeanValue(instance);
|
||||
return !Comparing.equal(componentValue, beanValue);
|
||||
}
|
||||
|
||||
void apply(Object instance) {
|
||||
void apply(@NotNull Object instance) {
|
||||
setBeanValue(instance, getComponentValue());
|
||||
}
|
||||
|
||||
void reset(Object instance) {
|
||||
void reset(@NotNull Object instance) {
|
||||
setComponentValue(getBeanValue(instance));
|
||||
}
|
||||
|
||||
abstract Object getComponentValue();
|
||||
abstract void setComponentValue(Object value);
|
||||
|
||||
Object getBeanValue(Object instance) {
|
||||
Object getBeanValue(@NotNull Object instance) {
|
||||
try {
|
||||
Field field = instance.getClass().getField(myFieldName);
|
||||
return field.get(instance);
|
||||
@@ -121,6 +124,7 @@ public abstract class BeanConfigurable<T> implements UnnamedConfigurable {
|
||||
myTitle = title;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
JCheckBox createComponent() {
|
||||
return new JCheckBox(myTitle);
|
||||
@@ -153,14 +157,81 @@ public abstract class BeanConfigurable<T> implements UnnamedConfigurable {
|
||||
myInstance = beanInstance;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected T getInstance() {
|
||||
return myInstance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #checkBox(String, Getter, Setter)} instead
|
||||
*/
|
||||
protected void checkBox(@NonNls String fieldName, String title) {
|
||||
myFields.add(new CheckboxField(fieldName, title));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds check box with given {@code title}.
|
||||
* Initial checkbox value is obtained from {@code getter}.
|
||||
* After the apply, the value from the check box is written back to model via {@code setter}.
|
||||
*/
|
||||
protected void checkBox(@NotNull String title, @NotNull Getter<Boolean> getter, @NotNull Setter<Boolean> setter) {
|
||||
CheckboxField field = new CheckboxField("", title) {
|
||||
@Override
|
||||
Object getBeanValue(@NotNull Object instance) {
|
||||
return getter.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
void setBeanValue(Object instance, Object value) {
|
||||
setter.set((Boolean)value);
|
||||
}
|
||||
};
|
||||
myFields.add(field);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds custom component (e.g. edit box).
|
||||
* Initial value is obtained from {@code beanGetter} and applied to the component via {@code componentSetter}.
|
||||
* E.g. text is read from the model and set to the edit box.
|
||||
* After the apply, the value from the component is queried via {@code componentGetter} and written back to model via {@code beanSetter}.
|
||||
* E.g. text from the edit box is queried and saved back to model bean.
|
||||
*/
|
||||
protected <V> void component(@NotNull JComponent component, @NotNull Getter<V> beanGetter, @NotNull Setter<V> beanSetter, @NotNull Getter<V> componentGetter, @NotNull Setter<V> componentSetter) {
|
||||
BeanField<JComponent> field = new BeanField<JComponent>("") {
|
||||
@NotNull
|
||||
@Override
|
||||
JComponent createComponent() {
|
||||
return component;
|
||||
}
|
||||
|
||||
@Override
|
||||
Object getComponentValue() {
|
||||
return componentGetter.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
void setComponentValue(Object value) {
|
||||
componentSetter.set((V)value);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class getValueClass() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
Object getBeanValue(@NotNull Object instance) {
|
||||
return beanGetter.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
void setBeanValue(Object instance, Object value) {
|
||||
beanSetter.set((V)value);
|
||||
}
|
||||
};
|
||||
myFields.add(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent createComponent() {
|
||||
final JPanel panel = new JPanel(new GridLayout(myFields.size(), 1));
|
||||
|
||||
@@ -6,5 +6,8 @@
|
||||
<item name="com.intellij.openapi.util.Getter">
|
||||
<annotation name="java.lang.FunctionalInterface" />
|
||||
</item>
|
||||
<item name="com.intellij.openapi.util.Setter">
|
||||
<annotation name="java.lang.FunctionalInterface" />
|
||||
</item>
|
||||
</root>
|
||||
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2000-2016 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.openapi.util;
|
||||
|
||||
public interface Setter<T> {
|
||||
void set(T value);
|
||||
}
|
||||
Reference in New Issue
Block a user