mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
-4
@@ -450,8 +450,4 @@ public class CompilerReferenceServiceImpl extends CompilerReferenceService imple
|
||||
return 31 * mySearchType.hashCode() + mySearchFileType.hashCode();
|
||||
}
|
||||
}
|
||||
|
||||
private static class RawSearchResult {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+12
-8
@@ -20,8 +20,10 @@ import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.lang.java.lexer.JavaLexer;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.pom.java.LanguageLevel;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
|
||||
@@ -87,7 +89,7 @@ public class StreamToLoopInspection extends BaseJavaBatchLocalInspectionTool {
|
||||
private static boolean isSupportedCodeLocation(PsiMethodCallExpression call) {
|
||||
PsiElement cur = call;
|
||||
PsiElement parent = cur.getParent();
|
||||
while(parent instanceof PsiExpression) {
|
||||
while(parent instanceof PsiExpression || parent instanceof PsiExpressionList) {
|
||||
// TODO: support in single expression lambdas
|
||||
if(parent instanceof PsiLambdaExpression) {
|
||||
return false;
|
||||
@@ -133,9 +135,10 @@ public class StreamToLoopInspection extends BaseJavaBatchLocalInspectionTool {
|
||||
if(InheritanceUtil.isInheritor(aClass, CommonClassNames.JAVA_UTIL_STREAM_BASE_STREAM)) {
|
||||
PsiExpression qualifier = call.getMethodExpression().getQualifierExpression();
|
||||
if(qualifier != null) {
|
||||
Operation op = Operation.createIntermediate(name, args, outVar, getStreamElementType(qualifier.getType()));
|
||||
PsiType elementType = getStreamElementType(qualifier.getType());
|
||||
Operation op = Operation.createIntermediate(name, args, outVar, elementType);
|
||||
if (op != null) return op;
|
||||
op = TerminalOperation.createTerminal(name, args, callType, className, call.getParent() instanceof PsiExpressionStatement);
|
||||
op = TerminalOperation.createTerminal(name, args, elementType, callType, call.getParent() instanceof PsiExpressionStatement);
|
||||
if (op != null) return op;
|
||||
}
|
||||
}
|
||||
@@ -232,11 +235,12 @@ public class StreamToLoopInspection extends BaseJavaBatchLocalInspectionTool {
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
String text = terminalCall.getText();
|
||||
if(temporaryStreamPlaceholder.isPhysical()) {
|
||||
// Just in case if something went wrong: at least try to restore the original stream code
|
||||
temporaryStreamPlaceholder.replace(factory.createExpressionFromText(terminalCall.getText(), temporaryStreamPlaceholder));
|
||||
temporaryStreamPlaceholder.replace(factory.createExpressionFromText(text, temporaryStreamPlaceholder));
|
||||
}
|
||||
throw ex;
|
||||
throw new RuntimeException("Error converting Stream to loop: "+text, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -380,9 +384,9 @@ public class StreamToLoopInspection extends BaseJavaBatchLocalInspectionTool {
|
||||
}
|
||||
|
||||
private boolean isUsed(String varName) {
|
||||
if(myUsedNames.contains(varName)) return true;
|
||||
// TODO: cleaner solution
|
||||
return !varName.equals(JavaCodeStyleManager.getInstance(myStatement.getProject()).suggestUniqueVariableName(varName, myStatement, true));
|
||||
return myUsedNames.contains(varName) || JavaLexer.isKeyword(varName, LanguageLevel.HIGHEST) ||
|
||||
// TODO: cleaner solution
|
||||
!varName.equals(JavaCodeStyleManager.getInstance(myStatement.getProject()).suggestUniqueVariableName(varName, myStatement, true));
|
||||
}
|
||||
|
||||
public String declare(String desiredName, String type, String initializer) {
|
||||
|
||||
+24
-18
@@ -63,7 +63,7 @@ abstract class TerminalOperation extends Operation {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static TerminalOperation createTerminal(String name, PsiExpression[] args, PsiType callType, String className, boolean isVoid) {
|
||||
static TerminalOperation createTerminal(String name, PsiExpression[] args, PsiType elementType, PsiType resultType, boolean isVoid) {
|
||||
if(isVoid) {
|
||||
if ((name.equals("forEach") || name.equals("forEachOrdered")) && args.length == 1) {
|
||||
FunctionHelper fn = FunctionHelper.create(args[0], 1, true);
|
||||
@@ -75,23 +75,22 @@ abstract class TerminalOperation extends Operation {
|
||||
return new AccumulatedTerminalOperation("count", "long", "0", "{acc}++;");
|
||||
}
|
||||
if(name.equals("sum") && args.length == 0) {
|
||||
return new AccumulatedTerminalOperation("sum", callType.getCanonicalText(), "0", "{acc}+={item};");
|
||||
return new AccumulatedTerminalOperation("sum", resultType.getCanonicalText(), "0", "{acc}+={item};");
|
||||
}
|
||||
if(name.equals("average") && args.length == 0) {
|
||||
if(className.equals(CommonClassNames.JAVA_UTIL_STREAM_DOUBLE_STREAM)) {
|
||||
if(elementType.equals(PsiType.DOUBLE)) {
|
||||
return new AverageTerminalOperation(true);
|
||||
}
|
||||
else if(className.equals(CommonClassNames.JAVA_UTIL_STREAM_INT_STREAM) ||
|
||||
className.equals(CommonClassNames.JAVA_UTIL_STREAM_LONG_STREAM)) {
|
||||
else if(elementType.equals(PsiType.INT) || elementType.equals(PsiType.LONG)) {
|
||||
return new AverageTerminalOperation(false);
|
||||
}
|
||||
}
|
||||
if(name.equals("summaryStatistics") && args.length == 0) {
|
||||
return new AccumulatedTerminalOperation("stat", callType.getCanonicalText(), "new " + callType.getCanonicalText() + "()",
|
||||
return new AccumulatedTerminalOperation("stat", resultType.getCanonicalText(), "new " + resultType.getCanonicalText() + "()",
|
||||
"{acc}.accept({item});");
|
||||
}
|
||||
if((name.equals("findFirst") || name.equals("findAny")) && args.length == 0) {
|
||||
return new FindTerminalOperation(callType.getCanonicalText());
|
||||
return new FindTerminalOperation(resultType.getCanonicalText());
|
||||
}
|
||||
if((name.equals("anyMatch") || name.equals("allMatch") || name.equals("noneMatch")) && args.length == 1) {
|
||||
FunctionHelper fn = FunctionHelper.create(args[0], 1, true);
|
||||
@@ -101,11 +100,11 @@ abstract class TerminalOperation extends Operation {
|
||||
if(args.length == 2 || args.length == 3) {
|
||||
FunctionHelper fn = FunctionHelper.create(args[1], 2, true);
|
||||
if(fn != null) {
|
||||
return new ReduceTerminalOperation(args[0], fn, callType.getCanonicalText());
|
||||
return new ReduceTerminalOperation(args[0], fn, resultType.getCanonicalText());
|
||||
}
|
||||
}
|
||||
if(args.length == 1) {
|
||||
PsiType optionalElementType = getOptionalElementType(callType);
|
||||
PsiType optionalElementType = getOptionalElementType(resultType);
|
||||
FunctionHelper fn = FunctionHelper.create(args[0], 2, true);
|
||||
if(fn != null && optionalElementType != null) {
|
||||
return new ReduceToOptionalTerminalOperation(fn, optionalElementType.getCanonicalText());
|
||||
@@ -113,8 +112,8 @@ abstract class TerminalOperation extends Operation {
|
||||
}
|
||||
}
|
||||
if(name.equals("toArray") && args.length < 2) {
|
||||
if(!(callType instanceof PsiArrayType)) return null;
|
||||
PsiType componentType = ((PsiArrayType)callType).getComponentType();
|
||||
if(!(resultType instanceof PsiArrayType)) return null;
|
||||
PsiType componentType = ((PsiArrayType)resultType).getComponentType();
|
||||
if (componentType instanceof PsiPrimitiveType) {
|
||||
if(args.length == 0) return new ToPrimitiveArrayTerminalOperation(componentType.getCanonicalText());
|
||||
}
|
||||
@@ -130,7 +129,7 @@ abstract class TerminalOperation extends Operation {
|
||||
if(!(type instanceof PsiArrayType)) return null;
|
||||
arr = "new "+type.getCanonicalText().replaceFirst("\\[]", "[0]");
|
||||
}
|
||||
return new AccumulatedTerminalOperation("list", CommonClassNames.JAVA_UTIL_LIST + "<" + componentType.getCanonicalText() + ">",
|
||||
return new AccumulatedTerminalOperation("list", CommonClassNames.JAVA_UTIL_LIST + "<" + elementType.getCanonicalText() + ">",
|
||||
"new "+ CommonClassNames.JAVA_UTIL_ARRAY_LIST+"<>()", "{acc}.add({item});",
|
||||
"{acc}.toArray("+arr+")");
|
||||
}
|
||||
@@ -144,25 +143,25 @@ abstract class TerminalOperation extends Operation {
|
||||
PsiClass collectorClass = collector.getContainingClass();
|
||||
if(collectorClass != null && CommonClassNames.JAVA_UTIL_STREAM_COLLECTORS.equals(collectorClass.getQualifiedName())) {
|
||||
if(collector.getName().equals("toList") && collectorArgs.length == 0) {
|
||||
return AccumulatedTerminalOperation.toCollection(callType, CommonClassNames.JAVA_UTIL_ARRAY_LIST, "list");
|
||||
return AccumulatedTerminalOperation.toCollection(resultType, CommonClassNames.JAVA_UTIL_ARRAY_LIST, "list");
|
||||
}
|
||||
if(collector.getName().equals("toSet") && collectorArgs.length == 0) {
|
||||
return AccumulatedTerminalOperation.toCollection(callType, CommonClassNames.JAVA_UTIL_HASH_SET, "set");
|
||||
return AccumulatedTerminalOperation.toCollection(resultType, CommonClassNames.JAVA_UTIL_HASH_SET, "set");
|
||||
}
|
||||
if(collector.getName().equals("toCollection") && collectorArgs.length == 1) {
|
||||
FunctionHelper fn = FunctionHelper.create(collectorArgs[0], 0, true);
|
||||
if(fn != null) {
|
||||
return new ToCollectionTerminalOperation(fn, callType);
|
||||
return new ToCollectionTerminalOperation(fn, resultType);
|
||||
}
|
||||
}
|
||||
if(collector.getName().equals("reducing") && collectorArgs.length == 2) {
|
||||
FunctionHelper fn = FunctionHelper.create(collectorArgs[1], 2, true);
|
||||
if(fn != null) {
|
||||
return new ReduceTerminalOperation(collectorArgs[0], fn, callType.getCanonicalText());
|
||||
return new ReduceTerminalOperation(collectorArgs[0], fn, resultType.getCanonicalText());
|
||||
}
|
||||
}
|
||||
if(collector.getName().equals("reducing") && collectorArgs.length == 1) {
|
||||
PsiType optionalElementType = getOptionalElementType(callType);
|
||||
PsiType optionalElementType = getOptionalElementType(resultType);
|
||||
FunctionHelper fn = FunctionHelper.create(collectorArgs[0], 2, true);
|
||||
if(fn != null && optionalElementType != null) {
|
||||
return new ReduceToOptionalTerminalOperation(fn, optionalElementType.getCanonicalText());
|
||||
@@ -355,7 +354,14 @@ abstract class TerminalOperation extends Operation {
|
||||
@Override
|
||||
String generate(StreamVariable inVar, StreamToLoopReplacementContext context) {
|
||||
myFn.transform(context, inVar.getName());
|
||||
String expression = myNegatePredicate ? BoolUtils.getNegatedExpressionText(myFn.getExpression()) : myFn.getText();
|
||||
String expression;
|
||||
if (myNegatePredicate) {
|
||||
PsiLambdaExpression lambda = (PsiLambdaExpression)context.createExpression("(" + inVar.getDeclaration() + ")->" + myFn.getText());
|
||||
expression = BoolUtils.getNegatedExpressionText((PsiExpression)lambda.getBody());
|
||||
}
|
||||
else {
|
||||
expression = myFn.getText();
|
||||
}
|
||||
return "if(" + expression + ") {\n" +
|
||||
context.assignAndBreak(myName, PsiType.BOOLEAN.getCanonicalText(), String.valueOf(!myDefaultValue), String.valueOf(myDefaultValue)) +
|
||||
"}\n";
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
// "Replace Stream API chain with loop" "true"
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
private static boolean test(List<String> list) {
|
||||
for (String s : list) {
|
||||
if (s.trim() != s.toLowerCase()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(test(Arrays.asList("a", "b", "c")));
|
||||
}
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
// "Replace Stream API chain with loop" "true"
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class Main {
|
||||
private static test(List<String> packages) {
|
||||
Optional<String> found = Optional.empty();
|
||||
for (String s : packages) {
|
||||
if (s.startsWith("xyz")) {
|
||||
found = Optional.of(s);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return found.filter(pkg -> pkg.endsWith("abc")).isPresent();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(test(Arrays.asList("xyzabc", "xyz123", "123abc", "123")));
|
||||
}
|
||||
}
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// "Replace Stream API chain with loop" "true"
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Main {
|
||||
private static void test(List<String> test) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String s : test) {
|
||||
sb.append(s);
|
||||
}
|
||||
System.out.println("x"+ sb.toString() +"y");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(test(Arrays.asList("a", "b", "c")));
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -7,7 +7,7 @@ import java.util.List;
|
||||
|
||||
public class Main {
|
||||
private static List<?>[] test(int[] numbers) {
|
||||
List<List<?>> list = new ArrayList<>();
|
||||
List<List<Integer>> list = new ArrayList<>();
|
||||
for (int number : numbers) {
|
||||
Integer n = number;
|
||||
List<Integer> integers = Collections.singletonList(n);
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@ import java.util.List;
|
||||
|
||||
public class Main {
|
||||
private static Object[] test(int[] numbers) {
|
||||
List<Object> list = new ArrayList<>();
|
||||
List<Integer> list = new ArrayList<>();
|
||||
for (int number : numbers) {
|
||||
Integer integer = number;
|
||||
list.add(integer);
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// "Replace Stream API chain with loop" "true"
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class Main {
|
||||
private static Number[] test(Object[] objects) {
|
||||
List<Object> list = new ArrayList<>();
|
||||
for (Object object : objects) {
|
||||
if (Number.class.isInstance(object)) {
|
||||
list.add(object);
|
||||
}
|
||||
}
|
||||
return list.toArray(new Number[0]);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(Arrays.asList(test(new Object[]{1, 2, 3, "string", 4})));
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Replace Stream API chain with loop" "true"
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
private static boolean test(List<String> list) {
|
||||
return list.stream().al<caret>lMatch(s -> s.trim() == s.toLowerCase());
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(test(Arrays.asList("a", "b", "c")));
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Replace Stream API chain with loop" "true"
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class Main {
|
||||
private static test(List<String> packages) {
|
||||
return packages.stream().filter(pkg -> pkg.startsWith("xyz")).fin<caret>dAny().filter(pkg -> pkg.endsWith("abc")).isPresent();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(test(Arrays.asList("xyzabc", "xyz123", "123abc", "123")));
|
||||
}
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
// "Replace Stream API chain with loop" "true"
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.*;
|
||||
|
||||
public class Main {
|
||||
private static void test(List<String> test) {
|
||||
System.out.println("x"+test.stream().c<caret>ollect(Collectors.joining())+"y");
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(test(Arrays.asList("a", "b", "c")));
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// "Replace Stream API chain with loop" "true"
|
||||
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class Main {
|
||||
private static Number[] test(Object[] objects) {
|
||||
return Stream.of(objects).filter(Number.class::isInstance).toArr<caret>ay(Number[]::new);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
System.out.println(Arrays.asList(test(new Object[]{1, 2, 3, "string", 4})));
|
||||
}
|
||||
}
|
||||
@@ -17,4 +17,11 @@ package com.intellij.codeInsight.hints
|
||||
|
||||
class InlayInfo(val text: String, val offset: Int)
|
||||
|
||||
class MethodInfo(val fullyQualifiedName: String, val paramNames: List<String>)
|
||||
open class MethodInfo(val fullyQualifiedName: String, val paramNames: List<String>) {
|
||||
|
||||
open fun getMethodName(): String {
|
||||
val start = fullyQualifiedName.lastIndexOf('.') + 1
|
||||
return fullyQualifiedName.substring(start)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -40,34 +40,30 @@ import com.intellij.psi.util.PsiTreeUtil
|
||||
|
||||
private fun String.capitalize() = StringUtil.capitalizeWords(this, true)
|
||||
|
||||
class ShowParameterHintsSettings : AnAction() {
|
||||
class ShowSettingsWithAddedPattern : AnAction() {
|
||||
init {
|
||||
val presentation = templatePresentation
|
||||
presentation.text = CodeInsightBundle.message("inlay.hints.show.settings").capitalize()
|
||||
presentation.description = CodeInsightBundle.message("inlay.hints.show.settings.description")
|
||||
templatePresentation.description = CodeInsightBundle.message("inlay.hints.show.settings.description")
|
||||
}
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
val file = CommonDataKeys.PSI_FILE.getData(e.dataContext) ?: return
|
||||
val editor = CommonDataKeys.EDITOR.getData(e.dataContext) ?: return
|
||||
val info = getMethodInfoAtOffset(editor, file) ?: return
|
||||
|
||||
val name = info.getMethodName()
|
||||
e.presentation.text = CodeInsightBundle.message("inlay.hints.show.settings", name)
|
||||
}
|
||||
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
val project = CommonDataKeys.PROJECT.getData(e.dataContext) ?: return
|
||||
val file = CommonDataKeys.PSI_FILE.getData(e.dataContext) ?: return
|
||||
val hintExtension = InlayParameterHintsExtension.forLanguage(file.language) ?: return
|
||||
val dialog = ParameterNameHintsConfigurable(project, hintExtension.defaultBlackList, file.language)
|
||||
dialog.show()
|
||||
}
|
||||
}
|
||||
|
||||
class BlacklistCurrentMethodAction : AnAction() {
|
||||
init {
|
||||
val presentation = templatePresentation
|
||||
presentation.text = CodeInsightBundle.message("inlay.hints.blacklist.method").capitalize()
|
||||
presentation.description = CodeInsightBundle.message("inlay.hints.blacklist.method.description")
|
||||
}
|
||||
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
val editor = CommonDataKeys.EDITOR.getData(e.dataContext) ?: return
|
||||
val file = CommonDataKeys.PSI_FILE.getData(e.dataContext) ?: return
|
||||
|
||||
val hintExtension = InlayParameterHintsExtension.forLanguage(file.language) ?: return
|
||||
val info = getMethodInfoAtOffset(editor, file) ?: return
|
||||
val dialog = ParameterNameHintsConfigurable(project, hintExtension.defaultBlackList, file.language, info.toPattern())
|
||||
|
||||
addMethodAtCaretToBlackList(editor, file)
|
||||
dialog.show()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,18 +156,19 @@ private fun refreshAllOpenEditors() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun addMethodAtCaretToBlackList(editor: Editor, file: PsiFile) {
|
||||
private fun getMethodInfoAtOffset(editor: Editor, file: PsiFile): MethodInfo? {
|
||||
val offset = editor.caretModel.offset
|
||||
|
||||
val element = file.findElementAt(offset)
|
||||
val hintsProvider = InlayParameterHintsExtension.forLanguage(file.language) ?: return
|
||||
|
||||
val method = PsiTreeUtil.findFirstParent(element, { e -> hintsProvider.getMethodInfo(e) != null }) ?: return
|
||||
val info = hintsProvider.getMethodInfo(method) ?: return
|
||||
|
||||
val pattern = info.fullyQualifiedName + '(' + info.paramNames.joinToString(",") + ')'
|
||||
ParameterNameHintsSettings.getInstance().addIgnorePattern(file.language, pattern)
|
||||
|
||||
val hintsProvider = InlayParameterHintsExtension.forLanguage(file.language) ?: return null
|
||||
|
||||
val method = PsiTreeUtil.findFirstParent(element, { e -> hintsProvider.getMethodInfo(e) != null }) ?: return null
|
||||
return hintsProvider.getMethodInfo(method)
|
||||
}
|
||||
|
||||
private fun addMethodAtCaretToBlackList(editor: Editor, file: PsiFile) {
|
||||
val info = getMethodInfoAtOffset(editor, file) ?: return
|
||||
ParameterNameHintsSettings.getInstance().addIgnorePattern(file.language, info.toPattern())
|
||||
refreshAllOpenEditors()
|
||||
}
|
||||
|
||||
@@ -189,3 +186,5 @@ fun isPossibleHintNearOffset(file: PsiFile, offset: Int): Boolean {
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
fun MethodInfo.toPattern() = this.fullyQualifiedName + '(' + this.paramNames.joinToString(",") + ')'
|
||||
|
||||
+57
-19
@@ -17,37 +17,49 @@ package com.intellij.codeInsight.hints.settings;
|
||||
|
||||
import com.intellij.codeInsight.hints.filtering.MatcherConstructor;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.editor.event.DocumentAdapter;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.fileTypes.PlainTextLanguage;
|
||||
import com.intellij.openapi.fileTypes.FileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.ui.EditorTextField;
|
||||
import com.intellij.ui.EditorTextFieldProvider;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ParameterNameHintsConfigurable extends DialogWrapper {
|
||||
public JPanel myConfigurable;
|
||||
private EditorTextField myEditorTextField;
|
||||
|
||||
private final Project myProject;
|
||||
private final Set<String> myDefaultBlackList;
|
||||
private final Language myLanguage;
|
||||
private final String myNewPreselectedItem;
|
||||
private final Project myProject;
|
||||
|
||||
public ParameterNameHintsConfigurable(@NotNull Project project,
|
||||
public ParameterNameHintsConfigurable(@NotNull Project project,
|
||||
@NotNull Set<String> defaultBlackList,
|
||||
@NotNull Language language) {
|
||||
this(project, defaultBlackList, language, null);
|
||||
}
|
||||
|
||||
public ParameterNameHintsConfigurable(@NotNull Project project,
|
||||
@NotNull Set<String> defaultBlackList,
|
||||
@NotNull Language language,
|
||||
@Nullable String newPreselectedPattern) {
|
||||
super(project);
|
||||
myProject = project;
|
||||
myDefaultBlackList = defaultBlackList;
|
||||
myLanguage = language;
|
||||
myDefaultBlackList = defaultBlackList;
|
||||
myNewPreselectedItem = newPreselectedPattern;
|
||||
setTitle("Configure Parameter Name Hints Blacklist");
|
||||
init();
|
||||
}
|
||||
@@ -84,18 +96,11 @@ public class ParameterNameHintsConfigurable extends DialogWrapper {
|
||||
return myConfigurable;
|
||||
}
|
||||
|
||||
public JPanel myConfigurable;
|
||||
private EditorTextField myEditorTextField;
|
||||
|
||||
private void createUIComponents() {
|
||||
EditorTextFieldProvider service = ServiceManager.getService(myProject, EditorTextFieldProvider.class);
|
||||
myEditorTextField = service.getEditorField(PlainTextLanguage.INSTANCE, myProject, ContainerUtil.emptyIterable());
|
||||
|
||||
Diff diff = ParameterNameHintsSettings.getInstance().getBlackListDiff(myLanguage);
|
||||
Set<String> blacklist = diff.applyOn(myDefaultBlackList);
|
||||
|
||||
String text = StringUtil.join(blacklist, "\n");
|
||||
myEditorTextField.setText(text);
|
||||
|
||||
myEditorTextField = createEditor(blacklist, myNewPreselectedItem);
|
||||
myEditorTextField.addDocumentListener(new DocumentAdapter() {
|
||||
@Override
|
||||
public void documentChanged(DocumentEvent e) {
|
||||
@@ -103,7 +108,40 @@ public class ParameterNameHintsConfigurable extends DialogWrapper {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private EditorTextField createEditor(@NotNull Set<String> blacklist, @Nullable String newPreselectedItem) {
|
||||
String text = StringUtil.join(blacklist, "\n");
|
||||
|
||||
final TextRange range;
|
||||
if (newPreselectedItem != null) {
|
||||
text += "\n";
|
||||
|
||||
final int startOffset = text.length();
|
||||
text += newPreselectedItem;
|
||||
range = new TextRange(startOffset, text.length());
|
||||
}
|
||||
else {
|
||||
range = null;
|
||||
}
|
||||
|
||||
return createEditorField(text, range);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private EditorTextField createEditorField(@NotNull String text, @Nullable TextRange rangeToSelect) {
|
||||
Document document = EditorFactory.getInstance().createDocument(text);
|
||||
EditorTextField field = new EditorTextField(document, myProject, FileTypes.PLAIN_TEXT, false, false);
|
||||
field.setPreferredSize(new Dimension(200, 350));
|
||||
field.addSettingsProvider(editor -> {
|
||||
editor.setVerticalScrollbarVisible(true);
|
||||
editor.setHorizontalScrollbarVisible(true);
|
||||
editor.getSettings().setAdditionalLinesCount(2);
|
||||
if (rangeToSelect != null) {
|
||||
editor.getCaretModel().moveToOffset(rangeToSelect.getStartOffset());
|
||||
editor.getScrollingModel().scrollVertically(document.getTextLength() - 1);
|
||||
editor.getSelectionModel().setSelection(rangeToSelect.getStartOffset(), rangeToSelect.getEndOffset());
|
||||
}
|
||||
});
|
||||
return field;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -445,7 +445,26 @@ public class SearchReplaceComponent extends EditorHeaderComponent implements Dat
|
||||
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
|
||||
NEW_LINE_KEYSTROKE,
|
||||
WHEN_FOCUSED);
|
||||
wrapper.setContent(textArea);
|
||||
|
||||
textComponent.registerKeyboardAction(e -> {
|
||||
if (isMultiline(textComponent)) {
|
||||
if (textComponent.isEditable() && textComponent.isEnabled()) {
|
||||
textComponent.replaceSelection("\t");
|
||||
}
|
||||
else {
|
||||
UIManager.getLookAndFeel().provideErrorFeedback(textComponent);
|
||||
}
|
||||
}
|
||||
else {
|
||||
textComponent.transferFocus();
|
||||
}
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), WHEN_FOCUSED);
|
||||
|
||||
textComponent.registerKeyboardAction(e -> {
|
||||
textComponent.transferFocusBackward();
|
||||
}, KeyStroke.getKeyStroke(KeyEvent.VK_TAB, InputEvent.SHIFT_DOWN_MASK), WHEN_FOCUSED);
|
||||
|
||||
wrapper.setContent(textArea);
|
||||
|
||||
UIUtil.addUndoRedoActions(textComponent);
|
||||
Utils.setSmallerFont(textComponent);
|
||||
@@ -491,6 +510,10 @@ public class SearchReplaceComponent extends EditorHeaderComponent implements Dat
|
||||
area.setRows(Math.max(2, Math.min(3, StringUtil.countChars(area.getText(), '\n') + 1)));
|
||||
}
|
||||
|
||||
private static boolean isMultiline(@NotNull JTextComponent component) {
|
||||
return component.getText().contains("\n");
|
||||
}
|
||||
|
||||
|
||||
private void installCloseOnEscapeAction(@NotNull JTextComponent c) {
|
||||
ActionListener action = new ActionListener() {
|
||||
|
||||
@@ -50,6 +50,7 @@ import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.text.DefaultEditorKit;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.geom.RoundRectangle2D;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
@@ -181,6 +182,9 @@ public class SearchTextArea extends NonOpaquePanel implements PropertyChangeList
|
||||
myInfoLabel.setText(info);
|
||||
}
|
||||
|
||||
private static Color enabledBorderColor = new JBColor(Gray._196, Gray._100);
|
||||
private static Color disabledBorderColor = Gray._83;
|
||||
|
||||
@Override
|
||||
public void paint(Graphics graphics) {
|
||||
Graphics2D g = (Graphics2D)graphics.create();
|
||||
@@ -191,18 +195,25 @@ public class SearchTextArea extends NonOpaquePanel implements PropertyChangeList
|
||||
if (r.height % 2 == 1) r.height--;
|
||||
int arcSize = Math.min(25, r.height-1);
|
||||
boolean hasFocus = myTextArea.hasFocus();
|
||||
g.setColor(myTextArea.isEnabled() ? Gray._196 : Gray._83);
|
||||
|
||||
Color borderColor = myTextArea.isEnabled() ? enabledBorderColor : disabledBorderColor;
|
||||
if (SystemInfo.isMac && (UIUtil.isUnderIntelliJLaF() || UIUtil.isUnderAquaLookAndFeel())) {
|
||||
g.setColor(borderColor);
|
||||
MacIntelliJTextFieldUI.paintAquaSearchFocusRing(g, r, myTextArea);
|
||||
}
|
||||
else {
|
||||
JBInsets.removeFrom(r, new Insets(3, 3, 3, 3));
|
||||
if (hasFocus) {
|
||||
JBInsets.removeFrom(r, new JBInsets(3, 3, 3, 3));
|
||||
if (hasFocus && (UIUtil.isUnderIntelliJLaF() || UIUtil.isUnderDarcula())) {
|
||||
DarculaUIUtil.paintSearchFocusRing(g, r, myTextArea, arcSize+6);
|
||||
}
|
||||
else {
|
||||
g.drawRoundRect(r.x, r.y, r.width, r.height, arcSize, arcSize);
|
||||
Shape shape = UIUtil.isUnderWindowsLookAndFeel()
|
||||
? new Rectangle(r.x, r.y, r.width, r.height)
|
||||
: new RoundRectangle2D.Double(r.x, r.y, r.width, r.height, arcSize, arcSize);
|
||||
g.setColor(borderColor);
|
||||
g.setColor(myTextArea.getBackground());
|
||||
g.fill(shape);
|
||||
g.setColor(borderColor);
|
||||
g.draw(shape);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.ide.actions;
|
||||
|
||||
import com.intellij.codeInsight.hint.HintUtil;
|
||||
import com.intellij.codeInsight.navigation.NavigationUtil;
|
||||
import com.intellij.navigation.GotoRelatedItem;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
@@ -22,12 +23,16 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.ui.popup.Balloon;
|
||||
import com.intellij.openapi.ui.popup.JBPopupFactory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.ui.IdeBorderFactory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.annotations.TestOnly;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -43,17 +48,28 @@ public class GotoRelatedSymbolAction extends AnAction {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(@NotNull AnActionEvent e) {
|
||||
PsiElement element = getContextElement(e.getDataContext());
|
||||
final DataContext dataContext = e.getDataContext();
|
||||
|
||||
final PsiElement element = getContextElement(dataContext);
|
||||
if (element == null) return;
|
||||
|
||||
List<GotoRelatedItem> items = NavigationUtil.collectRelatedItems(element, e.getDataContext());
|
||||
if (items.isEmpty()) return;
|
||||
List<GotoRelatedItem> items = NavigationUtil.collectRelatedItems(element, dataContext);
|
||||
if (items.isEmpty()) {
|
||||
final JComponent label = HintUtil.createErrorLabel("No related symbols");
|
||||
label.setBorder(IdeBorderFactory.createEmptyBorder(2, 7, 2, 7));
|
||||
JBPopupFactory.getInstance().createBalloonBuilder(label)
|
||||
.setFadeoutTime(3000)
|
||||
.setFillColor(HintUtil.ERROR_COLOR)
|
||||
.createBalloon()
|
||||
.show(JBPopupFactory.getInstance().guessBestPopupLocation(dataContext), Balloon.Position.above);
|
||||
return;
|
||||
}
|
||||
|
||||
if (items.size() == 1 && items.get(0).getElement() != null) {
|
||||
items.get(0).navigate();
|
||||
return;
|
||||
}
|
||||
NavigationUtil.getRelatedItemsPopup(items, "Choose Target").showInBestPositionFor(e.getDataContext());
|
||||
NavigationUtil.getRelatedItemsPopup(items, "Choose Target").showInBestPositionFor(dataContext);
|
||||
}
|
||||
|
||||
@TestOnly
|
||||
|
||||
+1
-1
@@ -220,7 +220,7 @@ public class MacIntelliJTextFieldUI extends TextFieldWithPopupHandlerUI {
|
||||
g.setStroke(new BasicStroke(.5f));
|
||||
g.draw(getShape(r, 4, false));
|
||||
|
||||
if (true || c.hasFocus()) {
|
||||
if (c.hasFocus()) {
|
||||
Color graphiteColor = new Color(0x6f6f72);
|
||||
Color blueColor = ColorUtil.brighter(new Color(0x006de2), 3);
|
||||
g.setColor(ColorUtil.withAlpha(IntelliJLaf.isGraphite() ? graphiteColor : blueColor, .3));
|
||||
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* 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.ui.popup;
|
||||
|
||||
import com.intellij.util.ReflectionUtil;
|
||||
|
||||
import javax.swing.JWindow;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.ComponentListener;
|
||||
import java.util.ArrayDeque;
|
||||
|
||||
/**
|
||||
* @author Sergey Malenkov
|
||||
*/
|
||||
final class HeavyWeightPopupCache implements ComponentListener {
|
||||
/**
|
||||
* Returns a cached window or creates a new one if cache is empty.
|
||||
*
|
||||
* @param owner the window from which a popup is displayed
|
||||
* @return a window for the specified owner
|
||||
*/
|
||||
public static Window create(Window owner) {
|
||||
if (owner != null) {
|
||||
HeavyWeightPopupCache cache = getCache(owner);
|
||||
if (cache != null) {
|
||||
Window popup = cache.poll();
|
||||
if (popup != null) return popup;
|
||||
}
|
||||
}
|
||||
Window popup = new JWindow(owner);
|
||||
popup.setType(Window.Type.POPUP);
|
||||
return popup;
|
||||
}
|
||||
|
||||
/**
|
||||
* Caches a window if possible.
|
||||
*
|
||||
* @param popup the popup window that is not needed
|
||||
*/
|
||||
public static void dispose(Window popup) {
|
||||
if (popup != null) {
|
||||
hide(popup);
|
||||
Window owner = popup.getOwner();
|
||||
if (owner == null || !owner.isDisplayable()) {
|
||||
popup.dispose();
|
||||
}
|
||||
else {
|
||||
HeavyWeightPopupCache cache = getCache(owner);
|
||||
if (cache == null) {
|
||||
cache = new HeavyWeightPopupCache();
|
||||
owner.addComponentListener(cache);
|
||||
}
|
||||
cache.push(popup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static HeavyWeightPopupCache getCache(Window owner) {
|
||||
for (ComponentListener listener : owner.getComponentListeners()) {
|
||||
if (listener instanceof HeavyWeightPopupCache) {
|
||||
return (HeavyWeightPopupCache)listener;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Window poll(ArrayDeque<Window> windows) {
|
||||
return windows.poll();
|
||||
}
|
||||
|
||||
private static void push(ArrayDeque<Window> windows, Window popup) {
|
||||
windows.push(popup);
|
||||
}
|
||||
|
||||
private static void hide(ArrayDeque<Window> windows) {
|
||||
for (Window window : windows) hide(window);
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables showing a child window with its parent.
|
||||
*
|
||||
* @param window the popup window that is not needed
|
||||
*/
|
||||
private static void hide(Window window) {
|
||||
// HACK: do not allow to show a hidden popup on showing its parent
|
||||
ReflectionUtil.setField(Window.class, window, boolean.class, "showWithParent", false);
|
||||
}
|
||||
|
||||
private final ArrayDeque<Window> myWindows = new ArrayDeque<>();
|
||||
|
||||
private Window poll() {
|
||||
return poll(myWindows);
|
||||
}
|
||||
|
||||
private void push(Window popup) {
|
||||
push(myWindows, popup);
|
||||
}
|
||||
|
||||
private void hide() {
|
||||
hide(myWindows);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentResized(ComponentEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentMoved(ComponentEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentShown(ComponentEvent event) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentHidden(ComponentEvent event) {
|
||||
Object source = event.getSource();
|
||||
if (source instanceof Window) {
|
||||
HeavyWeightPopupCache cache = getCache((Window)source);
|
||||
if (cache != null) cache.hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,13 +20,13 @@ import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayDeque;
|
||||
import java.awt.event.HierarchyListener;
|
||||
|
||||
/**
|
||||
* @author Sergey Malenkov
|
||||
*/
|
||||
public class MovablePopup {
|
||||
private static final Object CACHE = new Object();
|
||||
private final HierarchyListener myListener = event -> setVisible(false);
|
||||
private final Component myOwner;
|
||||
private final Component myContent;
|
||||
private Rectangle myViewBounds;
|
||||
@@ -161,11 +161,7 @@ public class MovablePopup {
|
||||
Window owner = UIUtil.getWindow(myOwner);
|
||||
if (owner != null) {
|
||||
if (myHeavyWeight) {
|
||||
Window view = pop(owner);
|
||||
if (view == null) {
|
||||
view = new JWindow(owner);
|
||||
view.setType(Window.Type.POPUP);
|
||||
}
|
||||
Window view = HeavyWeightPopupCache.create(owner);
|
||||
setAlwaysOnTop(view, myAlwaysOnTop);
|
||||
setWindowFocusable(view, myWindowFocusable);
|
||||
setWindowShadow(view, myWindowShadow);
|
||||
@@ -193,6 +189,7 @@ public class MovablePopup {
|
||||
myView.setBounds(myViewBounds);
|
||||
myView.setVisible(true);
|
||||
myViewBounds = null;
|
||||
myOwner.addHierarchyListener(myListener);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -206,6 +203,7 @@ public class MovablePopup {
|
||||
|
||||
private void disposeAndUpdate(boolean update) {
|
||||
if (myView != null) {
|
||||
myOwner.removeHierarchyListener(myListener);
|
||||
boolean visible = myView.isVisible();
|
||||
myView.setVisible(false);
|
||||
Container container = myContent.getParent();
|
||||
@@ -214,10 +212,7 @@ public class MovablePopup {
|
||||
}
|
||||
if (myView instanceof Window) {
|
||||
myViewBounds = myView.getBounds();
|
||||
Window window = (Window)myView;
|
||||
if (!push(UIUtil.getWindow(myOwner), window)) {
|
||||
window.dispose();
|
||||
}
|
||||
HeavyWeightPopupCache.dispose((Window)myView);
|
||||
}
|
||||
else {
|
||||
Container parent = myView.getParent();
|
||||
@@ -270,35 +265,4 @@ public class MovablePopup {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Window pop(Window owner) {
|
||||
JRootPane root = getRootPane(owner);
|
||||
if (root != null) {
|
||||
synchronized (CACHE) {
|
||||
@SuppressWarnings("unchecked")
|
||||
ArrayDeque<Window> cache = (ArrayDeque<Window>)root.getClientProperty(CACHE);
|
||||
if (cache != null && !cache.isEmpty()) {
|
||||
return cache.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean push(Window owner, Window window) {
|
||||
JRootPane root = getRootPane(owner);
|
||||
if (root != null) {
|
||||
synchronized (CACHE) {
|
||||
@SuppressWarnings("unchecked")
|
||||
ArrayDeque<Window> cache = (ArrayDeque<Window>)root.getClientProperty(CACHE);
|
||||
if (cache == null) {
|
||||
cache = new ArrayDeque<>();
|
||||
root.putClientProperty(CACHE, cache);
|
||||
}
|
||||
cache.push(window);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -528,8 +528,8 @@ highlight.imported.members.chooser.title=Choose Imported Members to Highlight
|
||||
javadoc.resolved.value=Resolved value\:
|
||||
javadoc.error.resolving.url=Couldn''t resolve URL <i>{0}</i> <p>Configuring paths to API docs in <a href="open://Project Settings">project settings</a> might help
|
||||
|
||||
inlay.hints.show.settings=Show parameter name hints settings...
|
||||
inlay.hints.show.settings.description=Show dialog with parameter name hints settings
|
||||
inlay.hints.show.settings=Add Method ''{0}'' to Blacklist...
|
||||
inlay.hints.show.settings.description=Open parameter name hints settings
|
||||
inlay.hints.blacklist.method=Do not show hints for current method
|
||||
inlay.hints.blacklist.method.description=Adds current method to parameter name hints blacklist
|
||||
inlay.hints.intention.family.name=Parameter Name Hints
|
||||
|
||||
@@ -300,8 +300,7 @@
|
||||
</group>
|
||||
|
||||
<group id="ParameterNameHints" popup="true">
|
||||
<action id="BlacklistCurrentMethodAction" class="com.intellij.codeInsight.hints.BlacklistCurrentMethodAction"/>
|
||||
<action id="ShowParameterHintsSettings" class="com.intellij.codeInsight.hints.ShowParameterHintsSettings"/>
|
||||
<action id="ShowSettingsWithAddedPattern" class="com.intellij.codeInsight.hints.ShowSettingsWithAddedPattern"/>
|
||||
</group>
|
||||
|
||||
<action id="ToggleInlineHintsAction" class="com.intellij.codeInsight.hints.ToggleInlineHintsAction">
|
||||
|
||||
@@ -747,7 +747,7 @@ database.scrollable.result.sets.description=Enables scrollable result sets, if J
|
||||
database.scrollable.result.sets=true
|
||||
database.src_storage.enabled.description=Enables database sources storage
|
||||
database.src_storage.enabled.restartRequired=true
|
||||
database.src_storage.enabled=false
|
||||
database.src_storage.enabled=true
|
||||
|
||||
git.status.write=true
|
||||
git.blocking.read=true
|
||||
|
||||
@@ -298,22 +298,26 @@ public final class IconLoader {
|
||||
LOG.error(icon); // # 22481
|
||||
return EMPTY_ICON;
|
||||
}
|
||||
final int scale = UIUtil.isRetina() ? 2 : 1;
|
||||
@SuppressWarnings("UndesirableClassUsage")
|
||||
BufferedImage image = new BufferedImage(scale*icon.getIconWidth(), scale*icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||
final Graphics2D graphics = image.createGraphics();
|
||||
if (icon instanceof CachedImageIcon) {
|
||||
disabledIcon = ((CachedImageIcon)icon).asDisabledIcon();
|
||||
} else {
|
||||
final int scale = UIUtil.isRetina() ? 2 : 1;
|
||||
@SuppressWarnings("UndesirableClassUsage")
|
||||
BufferedImage image = new BufferedImage(scale * icon.getIconWidth(), scale * icon.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
|
||||
final Graphics2D graphics = image.createGraphics();
|
||||
|
||||
graphics.setColor(UIUtil.TRANSPARENT_COLOR);
|
||||
graphics.fillRect(0, 0, icon.getIconWidth(), icon.getIconHeight());
|
||||
graphics.scale(scale, scale);
|
||||
icon.paintIcon(LabelHolder.ourFakeComponent, graphics, 0, 0);
|
||||
graphics.setColor(UIUtil.TRANSPARENT_COLOR);
|
||||
graphics.fillRect(0, 0, icon.getIconWidth(), icon.getIconHeight());
|
||||
graphics.scale(scale, scale);
|
||||
icon.paintIcon(LabelHolder.ourFakeComponent, graphics, 0, 0);
|
||||
|
||||
graphics.dispose();
|
||||
graphics.dispose();
|
||||
|
||||
Image img = ImageUtil.filter(image, UIUtil.getGrayFilter());
|
||||
if (UIUtil.isRetina()) img = RetinaImage.createFrom(img);
|
||||
Image img = ImageUtil.filter(image, UIUtil.getGrayFilter());
|
||||
if (UIUtil.isRetina()) img = RetinaImage.createFrom(img);
|
||||
|
||||
disabledIcon = new JBImageIcon(img);
|
||||
disabledIcon = new JBImageIcon(img);
|
||||
}
|
||||
ourIcon2DisabledIcon.put(icon, disabledIcon);
|
||||
}
|
||||
return disabledIcon;
|
||||
@@ -376,24 +380,36 @@ public final class IconLoader {
|
||||
private volatile boolean dark;
|
||||
private volatile int numberOfPatchers = ourPatchers.size();
|
||||
|
||||
private volatile ImageFilter filter;
|
||||
private ImageFilter[] myFilters;
|
||||
private final MyScaledIconsCache myScaledIconsCache = new MyScaledIconsCache();
|
||||
|
||||
public CachedImageIcon(@NotNull URL url) {
|
||||
private CachedImageIcon(@NotNull URL url, @NotNull ImageFilter[] filters) {
|
||||
myUrl = url;
|
||||
dark = USE_DARK_ICONS;
|
||||
filter = IMAGE_FILTER;
|
||||
myFilters = filters;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public CachedImageIcon(@NotNull URL url) {
|
||||
this(url, new ImageFilter[] {IMAGE_FILTER});
|
||||
}
|
||||
|
||||
private void setGlobalFilter(ImageFilter globalFilter) {
|
||||
myFilters[0] = globalFilter;
|
||||
}
|
||||
|
||||
private ImageFilter getGlobalFilter() {
|
||||
return myFilters[0];
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private synchronized ImageIcon getRealIcon() {
|
||||
if (isLoaderDisabled() && (myRealIcon == null || dark != USE_DARK_ICONS || needUpdateJBUIScale() || filter != IMAGE_FILTER || numberOfPatchers != ourPatchers.size())) return EMPTY_ICON;
|
||||
if (isLoaderDisabled() && (myRealIcon == null || dark != USE_DARK_ICONS || needUpdateJBUIScale() || getGlobalFilter() != IMAGE_FILTER || numberOfPatchers != ourPatchers.size())) return EMPTY_ICON;
|
||||
|
||||
if (!isValid()) {
|
||||
myRealIcon = null;
|
||||
dark = USE_DARK_ICONS;
|
||||
updateJBUIScale();
|
||||
filter = IMAGE_FILTER;
|
||||
setGlobalFilter(IMAGE_FILTER);
|
||||
myScaledIconsCache.clear();
|
||||
if (numberOfPatchers != ourPatchers.size()) {
|
||||
numberOfPatchers = ourPatchers.size();
|
||||
@@ -420,7 +436,7 @@ public final class IconLoader {
|
||||
if (icon != null) return (ImageIcon)icon;
|
||||
}
|
||||
|
||||
Image image = ImageLoader.loadFromUrl(myUrl, true, filter);
|
||||
Image image = ImageLoader.loadFromUrl(myUrl, true, myFilters);
|
||||
icon = checkIcon(image, myUrl);
|
||||
|
||||
if (icon != null) {
|
||||
@@ -437,7 +453,7 @@ public final class IconLoader {
|
||||
}
|
||||
|
||||
private boolean isValid() {
|
||||
return dark == USE_DARK_ICONS && !needUpdateJBUIScale() && filter == IMAGE_FILTER && numberOfPatchers == ourPatchers.size();
|
||||
return dark == USE_DARK_ICONS && !needUpdateJBUIScale() && getGlobalFilter() == IMAGE_FILTER && numberOfPatchers == ourPatchers.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -475,6 +491,10 @@ public final class IconLoader {
|
||||
return (icon != null) ? icon : this;
|
||||
}
|
||||
|
||||
private Icon asDisabledIcon() {
|
||||
return new CachedImageIcon(myUrl, new ImageFilter[] {getGlobalFilter(), UIUtil.getGrayFilter()});
|
||||
}
|
||||
|
||||
private class MyScaledIconsCache {
|
||||
// Map {false -> image}, {true -> image@2x}
|
||||
private Map<Boolean, SoftReference<Image>> origImagesCache = Collections.synchronizedMap(new HashMap<Boolean, SoftReference<Image>>(2));
|
||||
@@ -493,7 +513,7 @@ public final class IconLoader {
|
||||
Image img = SoftReference.dereference(origImagesCache.get(retina));
|
||||
|
||||
if (img == null) {
|
||||
img = ImageLoader.loadFromUrl(myUrl, UIUtil.isUnderDarcula(), retina, filter);
|
||||
img = ImageLoader.loadFromUrl(myUrl, UIUtil.isUnderDarcula(), retina, myFilters);
|
||||
origImagesCache.put(retina, new SoftReference<Image>(img));
|
||||
}
|
||||
return img;
|
||||
|
||||
@@ -2472,7 +2472,7 @@ public class StringUtil extends StringUtilRt {
|
||||
* Escape property name or key in property file. Unicode characters are escaped as well.
|
||||
*
|
||||
* @param input an input to escape
|
||||
* @param isKey if true, the rules for key escaping are applied. All spaces are escaped in that case.
|
||||
* @param isKey if true, the rules for key escaping are applied. The leading space is escaped in that case.
|
||||
* @return an escaped string
|
||||
*/
|
||||
@NotNull
|
||||
@@ -2483,7 +2483,7 @@ public class StringUtil extends StringUtilRt {
|
||||
final char ch = input.charAt(i);
|
||||
switch (ch) {
|
||||
case ' ':
|
||||
if (isKey) {
|
||||
if (isKey && i == 0) {
|
||||
// only the leading space has to be escaped
|
||||
escaped.append('\\');
|
||||
}
|
||||
|
||||
@@ -195,6 +195,14 @@ public class ImageLoader implements Serializable {
|
||||
return new ImageConverterChain();
|
||||
}
|
||||
|
||||
public ImageConverterChain withFilter(final ImageFilter[] filters) {
|
||||
ImageConverterChain chain = this;
|
||||
for (ImageFilter filter : filters) {
|
||||
chain = chain.withFilter(filter);
|
||||
}
|
||||
return chain;
|
||||
}
|
||||
|
||||
public ImageConverterChain withFilter(final ImageFilter filter) {
|
||||
return with(new ImageConverter() {
|
||||
@Override
|
||||
@@ -253,11 +261,16 @@ public class ImageLoader implements Serializable {
|
||||
|
||||
@Nullable
|
||||
public static Image loadFromUrl(@NotNull URL url, boolean allowFloatScaling) {
|
||||
return loadFromUrl(url, allowFloatScaling, null);
|
||||
return loadFromUrl(url, allowFloatScaling, (ImageFilter)null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Image loadFromUrl(@NotNull URL url, boolean allowFloatScaling, ImageFilter filter) {
|
||||
return loadFromUrl(url, allowFloatScaling, new ImageFilter[] {filter});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Image loadFromUrl(@NotNull URL url, boolean allowFloatScaling, ImageFilter[] filters) {
|
||||
final float scaleFactor = calcScaleFactor(allowFloatScaling);
|
||||
|
||||
// We can't check all 3rd party plugins and convince the authors to add @2x icons.
|
||||
@@ -271,7 +284,7 @@ public class ImageLoader implements Serializable {
|
||||
|
||||
return ImageDescList.create(url.toString(), null, UIUtil.isUnderDarcula(), loadRetinaImages, allowFloatScaling).load(
|
||||
ImageConverterChain.create().
|
||||
withFilter(filter).
|
||||
withFilter(filters).
|
||||
withRetina().
|
||||
with(new ImageConverter() {
|
||||
public Image convert(Image source, ImageDesc desc) {
|
||||
@@ -309,13 +322,18 @@ public class ImageLoader implements Serializable {
|
||||
|
||||
@Nullable
|
||||
public static Image loadFromUrl(URL url, boolean dark, boolean retina) {
|
||||
return loadFromUrl(url, dark, retina, null);
|
||||
return loadFromUrl(url, dark, retina, (ImageFilter[])null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Image loadFromUrl(URL url, boolean dark, boolean retina, ImageFilter filter) {
|
||||
return loadFromUrl(url, dark, retina, new ImageFilter[] {filter});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Image loadFromUrl(URL url, boolean dark, boolean retina, ImageFilter[] filters) {
|
||||
return ImageDescList.create(url.toString(), null, dark, retina, true).
|
||||
load(ImageConverterChain.create().withFilter(filter).withRetina());
|
||||
load(ImageConverterChain.create().withFilter(filters).withRetina());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -39,7 +39,7 @@ public class FontUtil {
|
||||
if (start == -1) return input;
|
||||
|
||||
Font font = null;
|
||||
StringBuilder result = new StringBuilder();
|
||||
StringBuilder result = new StringBuilder(input.substring(0, start));
|
||||
for (int i = start; i < input.length(); i++) {
|
||||
char c = input.charAt(i);
|
||||
if (baseFont.canDisplay(c)) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2015 JetBrains s.r.o.
|
||||
* 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.
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package org.jetbrains.idea.devkit.dom.impl;
|
||||
|
||||
import com.intellij.codeInsight.completion.CompletionConfidenceEP;
|
||||
import com.intellij.codeInsight.completion.CompletionContributorEP;
|
||||
import com.intellij.codeInspection.dataFlow.StringExpressionHelper;
|
||||
import com.intellij.icons.AllIcons;
|
||||
@@ -47,6 +48,7 @@ import javax.swing.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
class LanguageResolvingUtil {
|
||||
private static final String ANY_LANGUAGE_DEFAULT_ID = Language.ANY.getID();
|
||||
@@ -209,6 +211,11 @@ class LanguageResolvingUtil {
|
||||
return new LanguageDefinition(anyLanguageId, languageClass, AllIcons.FileTypes.Any_type, "<any language>");
|
||||
}
|
||||
|
||||
private static final Set<String> EP_WITH_ANY_LANGUAGE_ID = ContainerUtil.immutableSet(
|
||||
CompletionContributorEP.class.getName(),
|
||||
CompletionConfidenceEP.class.getName()
|
||||
);
|
||||
|
||||
private static String calculateAnyLanguageId(ConvertContext context) {
|
||||
final Extension extension = context.getInvocationElement().getParentOfType(Extension.class, true);
|
||||
if (extension == null) {
|
||||
@@ -220,7 +227,7 @@ class LanguageResolvingUtil {
|
||||
}
|
||||
|
||||
final GenericAttributeValue<PsiClass> epBeanClass = extensionPoint.getBeanClass();
|
||||
if (CompletionContributorEP.class.getName().equals(epBeanClass.getStringValue())) {
|
||||
if (EP_WITH_ANY_LANGUAGE_ID.contains(epBeanClass.getStringValue())) {
|
||||
return "any";
|
||||
}
|
||||
|
||||
|
||||
-3
@@ -178,9 +178,6 @@ public abstract class GroovyPsiElementFactory implements JVMElementFactory {
|
||||
@NotNull
|
||||
public abstract GrVariableDeclaration createVariableDeclaration(@Nullable String[] modifiers, @Nullable String initializer, @Nullable PsiType type, String... identifiers);
|
||||
|
||||
@NotNull
|
||||
public abstract GrVariableDeclaration createVariableDeclarationFromText(@NotNull String text, @Nullable PsiElement context);
|
||||
|
||||
@NotNull
|
||||
public abstract GrEnumConstant createEnumConstantFromText(@NotNull String text);
|
||||
|
||||
|
||||
-7
@@ -296,13 +296,6 @@ public class GroovyPsiElementFactoryImpl extends GroovyPsiElementFactory {
|
||||
return statement;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public GrVariableDeclaration createVariableDeclarationFromText(@NotNull String text, @Nullable PsiElement context) {
|
||||
final GroovyFile file = createGroovyFileChecked(text, false, context);
|
||||
return ((GrVariableDeclaration)file.getTopStatements()[0]);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public GrEnumConstant createEnumConstantFromText(@NotNull String text) {
|
||||
|
||||
+1
@@ -41,6 +41,7 @@ class GroovyClosurePattern : GroovyExpressionPattern<GrClosableBlock, GroovyClos
|
||||
}
|
||||
else -> return false
|
||||
}
|
||||
context?.put(closureCallKey, call)
|
||||
|
||||
val method = call.resolveMethod() ?: return false
|
||||
return methodPattern.accepts(method)
|
||||
|
||||
+5
-1
@@ -15,17 +15,21 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.lang.psi.patterns
|
||||
|
||||
import com.intellij.openapi.util.Key
|
||||
import com.intellij.patterns.PatternCondition
|
||||
import com.intellij.util.ProcessingContext
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.GrListOrMap
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrCall
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression
|
||||
|
||||
val closureCallKey = Key.create<GrCall>("groovy.pattern.closure.call")
|
||||
|
||||
inline fun <reified T : GrExpression> groovyExpression() = GroovyExpressionPattern.Capture(T::class.java)
|
||||
|
||||
fun groovyList() = groovyExpression<GrListOrMap>().with(object : PatternCondition<GrListOrMap>("isList") {
|
||||
override fun accepts(t: GrListOrMap, context: ProcessingContext?) = !t.isMap
|
||||
})
|
||||
|
||||
fun psiMethod(containingClass: String, name: String) = GroovyPatterns.psiMethod().withName(name).definedInClass(containingClass)
|
||||
fun psiMethod(containingClass: String, vararg name: String) = GroovyPatterns.psiMethod().withName(*name).definedInClass(containingClass)
|
||||
|
||||
fun groovyClosure() = GroovyClosurePattern()
|
||||
|
||||
+1
-2
@@ -106,8 +106,7 @@ public class GrStubFileElementType extends IStubFileElementType<GrFileStub> {
|
||||
public GrFileStub deserialize(@NotNull final StubInputStream dataStream, final StubElement parentStub) throws IOException {
|
||||
StringRef name = dataStream.readName();
|
||||
boolean isScript = dataStream.readBoolean();
|
||||
String[] annotations = GrStubUtils.readStringArray(dataStream);
|
||||
return new GrFileStub(name, isScript, annotations);
|
||||
return new GrFileStub(name, isScript, GrStubUtils.readStringArray(dataStream));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user