mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
parameter name folding reducing:
- do not inline if parameter length is less than 3 - do not inline if two subsequent parameters has interval names (beginIndex, endIndex; startId, endId; from, to...)
This commit is contained in:
+3
-51
@@ -45,7 +45,6 @@ import com.intellij.psi.util.*;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -701,7 +700,7 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
|
||||
else if (element instanceof PsiComment) {
|
||||
return settings.isCollapseEndOfLineComments();
|
||||
}
|
||||
else if (isLiteralExpression(element)
|
||||
else if (ParameterNameFoldingManager.isLiteralExpression(element)
|
||||
&& element.getParent() instanceof PsiExpressionList
|
||||
&& (element.getParent().getParent() instanceof PsiCallExpression
|
||||
|| element.getParent().getParent() instanceof PsiAnonymousClass)) {
|
||||
@@ -760,55 +759,8 @@ public abstract class JavaFoldingBuilderBase extends CustomFoldingBuilder implem
|
||||
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.getType() != null && isLiteralExpression(callArgument)) {
|
||||
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 (TypeConversionUtil.isAssignable(methodParam.getType(), callArgument.getType())) {
|
||||
TextRange range = callArgument.getTextRange();
|
||||
String placeholderText = methodParam.getName() + ": " + callArgument.getText();
|
||||
foldElements.add(new NamedFoldingDescriptor(callArgument, range.getStartOffset(), range.getEndOffset(), null, placeholderText));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Contract("null -> false")
|
||||
private static boolean isLiteralExpression(@Nullable PsiElement callArgument) {
|
||||
if (callArgument instanceof PsiLiteralExpression)
|
||||
return true;
|
||||
|
||||
if (callArgument instanceof PsiPrefixExpression) {
|
||||
PsiPrefixExpression expr = (PsiPrefixExpression)callArgument;
|
||||
IElementType tokenType = expr.getOperationTokenType();
|
||||
return JavaTokenType.MINUS.equals(tokenType) && expr.getOperand() instanceof PsiLiteralExpression;
|
||||
}
|
||||
|
||||
return false;
|
||||
ParameterNameFoldingManager manager = new ParameterNameFoldingManager(expression);
|
||||
foldElements.addAll(manager.buildDescriptors());
|
||||
}
|
||||
|
||||
private boolean addClosureFolding(final PsiClass aClass, final Document document, final List<FoldingDescriptor> foldElements,
|
||||
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
* Copyright 2000-2014 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.impl;
|
||||
|
||||
import com.intellij.lang.folding.FoldingDescriptor;
|
||||
import com.intellij.lang.folding.NamedFoldingDescriptor;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
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;
|
||||
|
||||
private static final String[] RANGE_START_WORDS = {
|
||||
"begin", "start", "from", "first"
|
||||
};
|
||||
private static final String[] RANGE_END_WORDS = {
|
||||
"end", "to", "last"
|
||||
};
|
||||
|
||||
private final PsiCallExpression myCallExpression;
|
||||
|
||||
private PsiExpression[] myCallArguments;
|
||||
private PsiParameter[] myParameters;
|
||||
|
||||
public ParameterNameFoldingManager(@NotNull PsiCallExpression callExpression) {
|
||||
myCallExpression = callExpression;
|
||||
}
|
||||
|
||||
public static boolean isLiteralExpression(@Nullable PsiElement callArgument) {
|
||||
if (callArgument instanceof PsiLiteralExpression)
|
||||
return true;
|
||||
|
||||
if (callArgument instanceof PsiPrefixExpression) {
|
||||
PsiPrefixExpression expr = (PsiPrefixExpression)callArgument;
|
||||
IElementType tokenType = expr.getOperationTokenType();
|
||||
return JavaTokenType.MINUS.equals(tokenType) && expr.getOperand() instanceof PsiLiteralExpression;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiExpression[] getArguments(@NotNull PsiCallExpression call) {
|
||||
PsiExpressionList callArgumentsList = call.getArgumentList();
|
||||
return callArgumentsList != null ? callArgumentsList.getExpressions() : null;
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<FoldingDescriptor> buildDescriptorsForLiteralArguments() {
|
||||
List<FoldingDescriptor> descriptors = ContainerUtil.newArrayList();
|
||||
|
||||
int i = 0;
|
||||
while (i < myCallArguments.length) {
|
||||
if (i + 1 < myCallArguments.length && isCommonlyNamedParameterPair(i, i + 1)) {
|
||||
i += 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (shouldInlineParameterName(i)) {
|
||||
descriptors.add(createFoldingDescriptor(myCallArguments[i], myParameters[i]));
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return descriptors;
|
||||
}
|
||||
|
||||
@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);
|
||||
}
|
||||
|
||||
private boolean isCommonlyNamedParameterPair(int first, int second) {
|
||||
assert first < myParameters.length && second < myParameters.length;
|
||||
|
||||
String firstParamName = myParameters[first].getName();
|
||||
String secondParamName = myParameters[second].getName();
|
||||
if (firstParamName == null || secondParamName == null) return false;
|
||||
|
||||
if (containsAnyWord(firstParamName, RANGE_START_WORDS) && containsAnyWord(secondParamName, RANGE_END_WORDS)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean containsAnyWord(@NotNull String str, @NotNull String[] words) {
|
||||
for (String word : words) {
|
||||
if (StringUtil.containsIgnoreCase(str, word)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean shouldInlineParameterName(int paramIndex) {
|
||||
PsiExpression argument = myCallArguments[paramIndex];
|
||||
if (isLiteralExpression(argument) && argument.getType() != null) {
|
||||
PsiParameter parameter = myParameters[paramIndex];
|
||||
String paramName = parameter.getName();
|
||||
if (paramName != null && paramName.length() >= MIN_NAME_LENGTH_THRESHOLD) {
|
||||
return TypeConversionUtil.isAssignable(parameter.getType(), argument.getType());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean hasLiteralExpression(@NotNull PsiExpression[] arguments) {
|
||||
for (PsiExpression argument : arguments) {
|
||||
if (isLiteralExpression(argument)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -608,7 +608,7 @@ class Test {
|
||||
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) {
|
||||
pubic void configure(boolean testNow, boolean shouldIgnoreRoots, int times, float pii, String title, char terminate, File file) {
|
||||
System.out.println();
|
||||
System.out.println();
|
||||
}
|
||||
@@ -672,7 +672,7 @@ public class VarArgTest {
|
||||
assert regions[1].placeholderText == "test: 13"
|
||||
}
|
||||
|
||||
public void "test inline if argument length is one (EA-57555)"() {
|
||||
public void "test do not inline if parameter length is one or two"() {
|
||||
def text = """
|
||||
public class CharSymbol {
|
||||
|
||||
@@ -681,7 +681,7 @@ public class CharSymbol {
|
||||
count(1, false);
|
||||
}
|
||||
|
||||
public void count(int test, boolean fast) {
|
||||
public void count(int t, boolean fa) {
|
||||
int temp = test;
|
||||
boolean isFast = fast;
|
||||
}
|
||||
@@ -689,13 +689,47 @@ public class CharSymbol {
|
||||
"""
|
||||
configure text
|
||||
def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
|
||||
assert regions.size() == 4
|
||||
assert regions.size() == 2
|
||||
}
|
||||
|
||||
checkRangeOffsetByPositionInText(regions[1], text, "1")
|
||||
assert regions[1].placeholderText == "test: 1"
|
||||
public void "test do not inline paired ranged names"() {
|
||||
def text = """
|
||||
public class CharSymbol {
|
||||
|
||||
checkRangeOffsetByPositionInText(regions[2], text, "false")
|
||||
assert regions[2].placeholderText == "fast: false"
|
||||
public void main() {
|
||||
String s = "AAA";
|
||||
int last = 3;
|
||||
|
||||
substring1(1, last);
|
||||
substring2(1, last);
|
||||
substring3(1, last);
|
||||
substring4(1, last);
|
||||
}
|
||||
|
||||
public void substring1(int beginIndex, int endIndex) {
|
||||
int start = beginIndex;
|
||||
int end = endIndex;
|
||||
}
|
||||
|
||||
public void substring2(int startIndex, int endIndex) {
|
||||
int start = beginIndex;
|
||||
int end = endIndex;
|
||||
}
|
||||
|
||||
public void substring3(int from, int to) {
|
||||
int start = beginIndex;
|
||||
int end = endIndex;
|
||||
}
|
||||
|
||||
public void substring4(int first, int last) {
|
||||
int start = beginIndex;
|
||||
int end = endIndex;
|
||||
}
|
||||
}
|
||||
"""
|
||||
configure text
|
||||
def regions = myFixture.editor.foldingModel.allFoldRegions.sort { it.startOffset }
|
||||
assert regions.size() == 5
|
||||
}
|
||||
|
||||
public void "test inline names if literal expression can be assigned to method parameter"() {
|
||||
@@ -764,7 +798,7 @@ public class Test {
|
||||
}
|
||||
|
||||
abstract class Checker {
|
||||
Checker(boolean applyToFirst, boolean applyToSecond) {}
|
||||
Checker(boolean isActive, boolean requestFocus) {}
|
||||
abstract void test();
|
||||
}
|
||||
}
|
||||
@@ -773,8 +807,8 @@ public class Test {
|
||||
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"
|
||||
assert regions[1].placeholderText == "isActive: true"
|
||||
assert regions[2].placeholderText == "requestFocus: false"
|
||||
|
||||
checkRangeOffsetByPositionInText(regions[1], text, "true")
|
||||
checkRangeOffsetByPositionInText(regions[2], text, "false")
|
||||
|
||||
Reference in New Issue
Block a user