diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java
index 3ba029ce380d..43b214584b65 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/Breakpoint.java
@@ -32,7 +32,7 @@ import com.intellij.debugger.jdi.StackFrameProxyImpl;
import com.intellij.debugger.jdi.ThreadReferenceProxyImpl;
import com.intellij.debugger.requests.ClassPrepareRequestor;
import com.intellij.debugger.settings.DebuggerSettings;
-import com.intellij.debugger.ui.impl.watch.EvaluationDescriptor;
+import com.intellij.debugger.ui.impl.watch.CompilingEvaluatorImpl;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
@@ -245,7 +245,7 @@ public abstract class Breakpoint
implements
}
throw new EventProcessingException(title[0], ex.getMessage(), ex);
- }
+ }
return true;
}
@@ -269,7 +269,7 @@ public abstract class Breakpoint
implements
SourcePosition position = ContextUtil.getSourcePosition(context);
PsiElement element = ContextUtil.getContextElement(context, position);
ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(myProject, () ->
- createExpressionEvaluator(myProject, context, element, position, expressionToEvaluate, this::createLogMessageCodeFragment));
+ createExpressionEvaluator(myProject, element, position, expressionToEvaluate, this::createLogMessageCodeFragment));
Value eval = evaluator.evaluate(context);
buf.append(eval instanceof VoidValue ? "void" : DebuggerUtils.getValueAsString(context, eval));
}
@@ -342,9 +342,8 @@ public abstract class Breakpoint
implements
}
try {
- Project project = context.getProject();
SourcePosition contextSourcePosition = ContextUtil.getSourcePosition(context);
- ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(project, () -> {
+ ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(myProject, () -> {
// IMPORTANT: calculate context psi element basing on the location where the exception
// has been hit, not on the location where it was set. (For line breakpoints these locations are the same, however,
// for method, exception and field breakpoints these locations differ)
@@ -352,7 +351,7 @@ public abstract class Breakpoint
implements
if (contextPsiElement == null) {
contextPsiElement = getEvaluationElement(); // as a last resort
}
- return createExpressionEvaluator(project, context, contextPsiElement, contextSourcePosition, getCondition(),
+ return createExpressionEvaluator(myProject, contextPsiElement, contextSourcePosition, getCondition(),
this::createConditionCodeFragment);
});
return DebuggerUtilsEx.evaluateBoolean(evaluator, context);
@@ -368,7 +367,6 @@ public abstract class Breakpoint
implements
}
private static ExpressionEvaluator createExpressionEvaluator(Project project,
- EvaluationContextImpl context,
PsiElement contextPsiElement,
SourcePosition contextSourcePosition,
TextWithImports text,
@@ -378,7 +376,7 @@ public abstract class Breakpoint
implements
return EvaluatorBuilderImpl.build(text, contextPsiElement, contextSourcePosition, project);
}
catch (UnsupportedExpressionException ex) {
- ExpressionEvaluator eval = EvaluationDescriptor.createCompilingEvaluator(context, contextPsiElement, fragmentFactory);
+ ExpressionEvaluator eval = CompilingEvaluatorImpl.create(project, contextPsiElement, fragmentFactory);
if (eval != null) {
return eval;
}
@@ -387,11 +385,11 @@ public abstract class Breakpoint
implements
}
private PsiCodeFragment createConditionCodeFragment(PsiElement context) {
- return createCodeFragment(getProject(), getCondition(), context);
+ return createCodeFragment(myProject, getCondition(), context);
}
private PsiCodeFragment createLogMessageCodeFragment(PsiElement context) {
- return createCodeFragment(getProject(), getLogMessage(), context);
+ return createCodeFragment(myProject, getLogMessage(), context);
}
private static PsiCodeFragment createCodeFragment(Project project, TextWithImports text, PsiElement context) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java
index 8a945476661c..6a7c25653a0e 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluator.java
@@ -51,10 +51,12 @@ import java.util.Collection;
* @author egor
*/
public abstract class CompilingEvaluator implements ExpressionEvaluator {
+ @NotNull protected final Project myProject;
@NotNull protected final PsiElement myPsiContext;
@NotNull protected final ExtractLightMethodObjectHandler.ExtractedData myData;
- public CompilingEvaluator(@NotNull PsiElement context, @NotNull ExtractLightMethodObjectHandler.ExtractedData data) {
+ public CompilingEvaluator(@NotNull Project project, @NotNull PsiElement context, @NotNull ExtractLightMethodObjectHandler.ExtractedData data) {
+ myProject = project;
myPsiContext = context;
myData = data;
}
@@ -86,16 +88,15 @@ public abstract class CompilingEvaluator implements ExpressionEvaluator {
try {
// invoke base evaluator on call code
- Project project = ApplicationManager.getApplication().runReadAction((Computable)myPsiContext::getProject);
SourcePosition position = ContextUtil.getSourcePosition(evaluationContext);
ExpressionEvaluator evaluator =
- DebuggerInvocationUtil.commitAndRunReadAction(project, new EvaluatingComputable() {
+ DebuggerInvocationUtil.commitAndRunReadAction(myProject, new EvaluatingComputable() {
@Override
public ExpressionEvaluator compute() throws EvaluateException {
TextWithImports callCode = getCallCode();
PsiElement copyContext = myData.getAnchor();
CodeFragmentFactory factory = DebuggerUtilsEx.findAppropriateCodeFragmentFactory(callCode, copyContext);
- return factory.getEvaluatorBuilder().build(factory.createCodeFragment(callCode, copyContext, project), position);
+ return factory.getEvaluatorBuilder().build(factory.createCodeFragment(callCode, copyContext, myProject), position);
}
});
((EvaluationContextImpl)evaluationContext).setClassLoader(classLoader);
@@ -148,12 +149,8 @@ public abstract class CompilingEvaluator implements ExpressionEvaluator {
protected String getGenClassQName() {
- return ApplicationManager.getApplication().runReadAction(new Computable() {
- @Override
- public String compute() {
- return JVMNameUtil.getNonAnonymousClassName(myData.getGeneratedInnerClass());
- }
- });
+ return ApplicationManager.getApplication().runReadAction(
+ (Computable)() -> JVMNameUtil.getNonAnonymousClassName(myData.getGeneratedInnerClass()));
}
///////////////// Compiler stuff
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluatorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluatorImpl.java
index e7445b0fc3c6..0fd2b1870129 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluatorImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/CompilingEvaluatorImpl.java
@@ -18,7 +18,7 @@ package com.intellij.debugger.ui.impl.watch;
import com.intellij.compiler.CompilerConfiguration;
import com.intellij.compiler.server.BuildManager;
import com.intellij.debugger.engine.evaluation.EvaluateException;
-import com.intellij.debugger.engine.evaluation.EvaluationContextImpl;
+import com.intellij.debugger.engine.evaluation.expression.ExpressionEvaluator;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.compiler.ClassObject;
import com.intellij.openapi.compiler.CompilationException;
@@ -26,15 +26,20 @@ import com.intellij.openapi.compiler.CompilerManager;
import com.intellij.openapi.compiler.CompilerMessageCategory;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
+import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.ThrowableComputable;
import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.registry.Registry;
import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.PsiCodeFragment;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
+import com.intellij.refactoring.extractMethod.PrepareFailedException;
import com.intellij.refactoring.extractMethodObject.ExtractLightMethodObjectHandler;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -44,35 +49,31 @@ import org.jetbrains.jps.model.java.compiler.AnnotationProcessingConfiguration;
import java.io.File;
import java.io.IOException;
import java.util.*;
+import java.util.function.Function;
// todo: consider batching compilations in order not to start a separate process for every class that needs to be compiled
public class CompilingEvaluatorImpl extends CompilingEvaluator {
-
- private final EvaluationContextImpl myEvaluationContext;
-
- public CompilingEvaluatorImpl(EvaluationContextImpl evaluationContext, @NotNull PsiElement context, @NotNull ExtractLightMethodObjectHandler.ExtractedData data) {
- super(context, data);
- myEvaluationContext = evaluationContext;
+ public CompilingEvaluatorImpl(@NotNull Project project,
+ @NotNull PsiElement context,
+ @NotNull ExtractLightMethodObjectHandler.ExtractedData data) {
+ super(project, context, data);
}
@Override
@NotNull
protected Collection compile(@Nullable JavaSdkVersion debuggeeVersion) throws EvaluateException {
- final Module module = ApplicationManager.getApplication().runReadAction(new Computable() {
- @Override
- public Module compute() {
- return ModuleUtilCore.findModuleForPsiElement(myPsiContext);
- }
- });
- final List options = new ArrayList<>();
+ Module module = ApplicationManager.getApplication().runReadAction(
+ (Computable)() -> ModuleUtilCore.findModuleForPsiElement(myPsiContext));
+ List options = new ArrayList<>();
options.add("-encoding");
options.add("UTF-8");
- final List platformClasspath = new ArrayList<>();
- final List classpath = new ArrayList<>();
+ List platformClasspath = new ArrayList<>();
+ List classpath = new ArrayList<>();
AnnotationProcessingConfiguration profile = null;
if (module != null) {
- profile = CompilerConfiguration.getInstance(module.getProject()).getAnnotationProcessingConfiguration(module);
- final ModuleRootManager rootManager = ModuleRootManager.getInstance(module);
+ assert myProject.equals(module.getProject()) : module + " is from another project";
+ profile = CompilerConfiguration.getInstance(myProject).getAnnotationProcessingConfiguration(module);
+ ModuleRootManager rootManager = ModuleRootManager.getInstance(module);
for (String s : rootManager.orderEntries().compileOnly().recursively().exportedOnly().withoutSdk().getPathsList().getPathList()) {
classpath.add(new File(s));
}
@@ -82,31 +83,31 @@ public class CompilingEvaluatorImpl extends CompilingEvaluator {
}
JavaBuilder.addAnnotationProcessingOptions(options, profile);
- final Pair runtime = BuildManager.getJavacRuntimeSdk(myEvaluationContext.getProject());
- final JavaSdkVersion buildRuntimeVersion = runtime.getSecond();
+ Pair runtime = BuildManager.getJavacRuntimeSdk(myProject);
+ JavaSdkVersion buildRuntimeVersion = runtime.getSecond();
// if compiler or debuggee version or both are unknown, let source and target be the compiler's defaults
if (buildRuntimeVersion != null && debuggeeVersion != null) {
- final JavaSdkVersion minVersion = buildRuntimeVersion.ordinal() > debuggeeVersion.ordinal() ? debuggeeVersion : buildRuntimeVersion;
- final String sourceOption = getSourceOption(minVersion.getMaxLanguageLevel());
+ JavaSdkVersion minVersion = buildRuntimeVersion.ordinal() > debuggeeVersion.ordinal() ? debuggeeVersion : buildRuntimeVersion;
+ String sourceOption = getSourceOption(minVersion.getMaxLanguageLevel());
options.add("-source");
options.add(sourceOption);
options.add("-target");
options.add(sourceOption);
}
- final CompilerManager compilerManager = CompilerManager.getInstance(myEvaluationContext.getProject());
+ CompilerManager compilerManager = CompilerManager.getInstance(myProject);
File sourceFile = null;
try {
sourceFile = generateTempSourceFile(compilerManager.getJavacCompilerWorkingDir());
- final File srcDir = sourceFile.getParentFile();
- final List sourcePath = Collections.emptyList();
- final Set sources = Collections.singleton(sourceFile);
+ File srcDir = sourceFile.getParentFile();
+ List sourcePath = Collections.emptyList();
+ Set sources = Collections.singleton(sourceFile);
return compilerManager.compileJavaCode(options, platformClasspath, classpath, Collections.emptyList(), sourcePath, sources, srcDir);
}
catch (CompilationException e) {
- final StringBuilder res = new StringBuilder("Compilation failed:\n");
+ StringBuilder res = new StringBuilder("Compilation failed:\n");
for (CompilationException.Message m : e.getMessages()) {
if (m.getCategory() == CompilerMessageCategory.ERROR) {
res.append(m.getText()).append("\n");
@@ -130,7 +131,7 @@ public class CompilingEvaluatorImpl extends CompilingEvaluator {
}
private File generateTempSourceFile(File workingDir) throws IOException {
- final Pair fileData = ApplicationManager.getApplication().runReadAction((Computable>)() -> {
+ Pair fileData = ApplicationManager.getApplication().runReadAction((Computable>)() -> {
PsiFile file = myData.getGeneratedInnerClass().getContainingFile();
return Pair.create(file.getName(), file.getText());
});
@@ -140,8 +141,34 @@ public class CompilingEvaluatorImpl extends CompilingEvaluator {
if (fileData.second == null) {
throw new IOException("Class source code not specified");
}
- final File file = new File(workingDir, "debugger/src/"+fileData.first);
+ File file = new File(workingDir, "debugger/src/" + fileData.first);
FileUtil.writeToFile(file, fileData.second);
return file;
}
+
+ @Nullable
+ public static ExpressionEvaluator create(@NotNull Project project,
+ @Nullable PsiElement psiContext,
+ @NotNull Function fragmentFactory)
+ throws EvaluateException {
+ if (Registry.is("debugger.compiling.evaluator") && psiContext != null) {
+ return ApplicationManager.getApplication().runReadAction((ThrowableComputable)() -> {
+ try {
+ ExtractLightMethodObjectHandler.ExtractedData data = ExtractLightMethodObjectHandler.extractLightMethodObject(
+ project,
+ psiContext.getContainingFile(),
+ fragmentFactory.apply(psiContext),
+ getGeneratedClassName());
+ if (data != null) {
+ return new CompilingEvaluatorImpl(project, psiContext, data);
+ }
+ }
+ catch (PrepareFailedException e) {
+ NodeDescriptorImpl.LOG.info(e);
+ }
+ return null;
+ });
+ }
+ return null;
+ }
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java
index e9f4592b5e9f..a84617b9aabe 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/EvaluationDescriptor.java
@@ -30,20 +30,16 @@ import com.intellij.debugger.engine.evaluation.expression.UnsupportedExpressionE
import com.intellij.debugger.impl.DebuggerContextImpl;
import com.intellij.debugger.impl.DebuggerUtilsEx;
import com.intellij.debugger.jdi.StackFrameProxyImpl;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.ThrowableComputable;
-import com.intellij.openapi.util.registry.Registry;
-import com.intellij.psi.*;
-import com.intellij.refactoring.extractMethod.PrepareFailedException;
-import com.intellij.refactoring.extractMethodObject.ExtractLightMethodObjectHandler;
+import com.intellij.psi.PsiCodeFragment;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiExpressionCodeFragment;
import com.intellij.xdebugger.frame.XValueModifier;
import com.sun.jdi.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
-import java.util.function.Function;
-
/**
* @author lex
*/
@@ -71,25 +67,26 @@ public abstract class EvaluationDescriptor extends ValueDescriptorImpl {
return DebuggerUtilsEx.findAppropriateCodeFragmentFactory(text, context).createCodeFragment(text, context, myProject);
}
- public final Value calcValue(final EvaluationContextImpl evaluationContext) throws EvaluateException {
+ public final Value calcValue(EvaluationContextImpl evaluationContext) throws EvaluateException {
try {
- final EvaluationContextImpl thisEvaluationContext = getEvaluationContext(evaluationContext);
+ EvaluationContextImpl thisEvaluationContext = getEvaluationContext(evaluationContext);
SourcePosition position = ContextUtil.getSourcePosition(evaluationContext);
PsiElement psiContext = ContextUtil.getContextElement(evaluationContext, position);
- ExpressionEvaluator evaluator;
- try {
- evaluator = DebuggerInvocationUtil.commitAndRunReadAction(myProject, () ->
- DebuggerUtilsEx.findAppropriateCodeFragmentFactory(getEvaluationText(), psiContext)
+ ExpressionEvaluator evaluator = DebuggerInvocationUtil.commitAndRunReadAction(myProject, () -> {
+ try {
+ return DebuggerUtilsEx.findAppropriateCodeFragmentFactory(getEvaluationText(), psiContext)
.getEvaluatorBuilder()
- .build(getEvaluationCode(thisEvaluationContext), position));
- }
- catch (UnsupportedExpressionException ex) {
- evaluator = createCompilingEvaluator(evaluationContext, psiContext, this::createCodeFragment);
- if (evaluator == null) {
+ .build(getEvaluationCode(thisEvaluationContext), position);
+ }
+ catch (UnsupportedExpressionException ex) {
+ ExpressionEvaluator eval = CompilingEvaluatorImpl.create(myProject, psiContext, this::createCodeFragment);
+ if (eval != null) {
+ return eval;
+ }
throw ex;
}
- }
+ });
if (!thisEvaluationContext.getDebugProcess().isAttached()) {
throw EvaluateExceptionUtil.PROCESS_EXITED;
@@ -115,32 +112,6 @@ public abstract class EvaluationDescriptor extends ValueDescriptorImpl {
}
}
- @Nullable
- public static ExpressionEvaluator createCompilingEvaluator(EvaluationContextImpl evaluationContext,
- @Nullable PsiElement psiContext,
- Function fragmentFactory)
- throws EvaluateException {
- if (Registry.is("debugger.compiling.evaluator") && psiContext != null) {
- return ApplicationManager.getApplication().runReadAction((ThrowableComputable)() -> {
- try {
- ExtractLightMethodObjectHandler.ExtractedData data = ExtractLightMethodObjectHandler.extractLightMethodObject(
- evaluationContext.getProject(),
- psiContext.getContainingFile(),
- fragmentFactory.apply(psiContext),
- CompilingEvaluator.getGeneratedClassName());
- if (data != null) {
- return new CompilingEvaluatorImpl(evaluationContext, psiContext, data);
- }
- }
- catch (PrepareFailedException e) {
- LOG.info(e);
- }
- return null;
- });
- }
- return null;
- }
-
public PsiExpression getDescriptorEvaluation(DebuggerContext context) throws EvaluateException {
PsiElement evaluationCode = getEvaluationCode(context);
if (evaluationCode instanceof PsiExpressionCodeFragment) {
diff --git a/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java b/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java
index d13e4ee1240a..5d715ed42399 100644
--- a/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java
+++ b/java/execution/impl/src/com/intellij/execution/junit/JUnitUtil.java
@@ -16,7 +16,6 @@
package com.intellij.execution.junit;
import com.intellij.codeInsight.AnnotationUtil;
-import com.intellij.codeInsight.MetaAnnotationUtil;
import com.intellij.codeInsight.TestFrameworks;
import com.intellij.execution.*;
import com.intellij.execution.junit2.info.MethodLocation;
@@ -26,19 +25,22 @@ import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.util.*;
import com.intellij.testIntegration.JavaTestFramework;
import com.intellij.testIntegration.TestFramework;
+import com.intellij.util.ConcurrencyUtil;
+import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
+import java.util.concurrent.ConcurrentMap;
@SuppressWarnings({"UtilityClassWithoutPrivateConstructor"})
public class JUnitUtil {
@@ -223,11 +225,11 @@ public class JUnitUtil {
if (module != null) {
for (final PsiMethod method : psiClass.getAllMethods()) {
ProgressManager.checkCanceled();
- if (isMetaAnnotated(method, TEST5_ANNOTATIONS, module)) return true;
+ if (isMetaAnnotated(method, TEST5_ANNOTATIONS)) return true;
}
for (PsiClass aClass : psiClass.getInnerClasses()) {
- if (isMetaAnnotated(aClass, JUNIT5_NESTED, module)) return true;
+ if (isMetaAnnotated(aClass, Collections.singleton(JUNIT5_NESTED))) return true;
}
}
@@ -260,23 +262,62 @@ public class JUnitUtil {
return true;
}
- Module module = ModuleUtilCore.findModuleForPsiElement(method);
- return module != null && isMetaAnnotated(method, TEST5_ANNOTATIONS, module);
+ return isMetaAnnotated(method, TEST5_ANNOTATIONS);
}
- private static boolean isMetaAnnotated(PsiModifierListOwner owner, final Collection metaAnnotations, final Module module) {
- for (String annotation : metaAnnotations) {
- if (isMetaAnnotated(owner, annotation, module)) return true;
+ private static final ConcurrentMap> annotationsKeyForProvider = ContainerUtil.newConcurrentMap();
+ @NotNull
+ private static Key> getKeyForAnnotations(Collection annotations) {
+ String name = StringUtil.join(annotations, ", ");
+ Key key = annotationsKeyForProvider.get(name);
+ if (key == null) {
+ key = ConcurrencyUtil.cacheOrGet(annotationsKeyForProvider, name, Key.create(name));
+ }
+ //noinspection unchecked
+ return (Key)key;
+ }
+
+ private static boolean isMetaAnnotated(PsiModifierListOwner listOwner, final Collection annotations) {
+ if (AnnotationUtil.isAnnotated(listOwner, annotations, false)) {
+ return true;
+ }
+ PsiModifierList modifierList = listOwner.getModifierList();
+ if (modifierList != null) {
+ for (PsiAnnotation annotation : modifierList.getApplicableAnnotations()) {
+ PsiJavaCodeReferenceElement nameReferenceElement = annotation.getNameReferenceElement();
+ if (nameReferenceElement != null) {
+ PsiElement resolve = nameReferenceElement.resolve();
+ if (resolve instanceof PsiClass) {
+ Boolean annotated = CachedValuesManager.getManager(listOwner.getProject()).getCachedValue(resolve, getKeyForAnnotations(annotations), () -> new CachedValueProvider.Result<>(
+ isTestAnnotatedAnnotation((PsiClass)resolve, new HashSet<>(), annotations), PsiModificationTracker.JAVA_STRUCTURE_MODIFICATION_COUNT), false);
+ if (annotated != null && annotated) return true;
+ }
+ }
+ }
}
return false;
}
- private static boolean isMetaAnnotated(PsiModifierListOwner owner, String annotation, Module module) {
- Collection annotations = MetaAnnotationUtil.getAnnotationTypesWithChildren(module, annotation, true);
- Stream qualifiedNames = annotations.stream().map(psiClass -> psiClass.getQualifiedName());
- if (AnnotationUtil.isAnnotated(owner, qualifiedNames.collect(Collectors.toSet()), false)) {
+
+ private static boolean isTestAnnotatedAnnotation(PsiClass aClass, final Set visited, final Collection annotations) {
+ if (AnnotationUtil.isAnnotated(aClass, annotations, false)) {
return true;
}
+ PsiModifierList modifierList = aClass.getModifierList();
+ if (modifierList != null) {
+ for (PsiAnnotation psiAnnotation : modifierList.getApplicableAnnotations()) {
+ PsiJavaCodeReferenceElement nameReferenceElement = psiAnnotation.getNameReferenceElement();
+ if (nameReferenceElement != null) {
+ PsiElement resolve = nameReferenceElement.resolve();
+ if (resolve instanceof PsiClass && visited.add((PsiClass)resolve) &&
+ ((PsiClass)resolve).isAnnotationType() &&
+ isTestAnnotatedAnnotation((PsiClass)resolve, visited, annotations)) {
+ return true;
+ }
+ }
+ }
+ }
+
return false;
}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaModuleGraphUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaModuleGraphUtil.java
index 3aaad5acea97..210616c7ab05 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaModuleGraphUtil.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaModuleGraphUtil.java
@@ -51,13 +51,13 @@ public class JavaModuleGraphUtil {
public static Collection findCycle(@NotNull PsiJavaModule module) {
Project project = module.getProject();
List> cycles = CachedValuesManager.getManager(project).getCachedValue(project, () ->
- Result.create(findCycles(project), JavaModuleFileChangeTracker.getInstance(project)));
+ Result.create(findCycles(project), JavaModuleFileChangeTracker.getDependencies(project)));
return ContainerUtil.find(cycles, set -> set.contains(module));
}
public static boolean exports(@NotNull PsiJavaModule source, @NotNull String packageName, @NotNull PsiJavaModule target) {
Map> exports = CachedValuesManager.getCachedValue(source, () ->
- Result.create(exportsMap(source), JavaModuleFileChangeTracker.getInstance(source.getProject())));
+ Result.create(exportsMap(source), JavaModuleFileChangeTracker.getDependencies(source.getProject())));
Set targets = exports.get(packageName);
return targets != null && (targets.isEmpty() || targets.contains(target.getModuleName()));
}
@@ -65,7 +65,7 @@ public class JavaModuleGraphUtil {
public static boolean reads(@NotNull PsiJavaModule source, @NotNull PsiJavaModule destination) {
Project project = source.getProject();
RequiresGraph graph = CachedValuesManager.getManager(project).getCachedValue(project, () ->
- Result.create(buildRequiresGraph(project), JavaModuleFileChangeTracker.getInstance(project)));
+ Result.create(buildRequiresGraph(project), JavaModuleFileChangeTracker.getDependencies(project)));
return graph.reads(source, destination);
}
diff --git a/java/java-impl/src/com/intellij/codeInsight/hints/JavaInlayParameterHintsProvider.kt b/java/java-impl/src/com/intellij/codeInsight/hints/JavaInlayParameterHintsProvider.kt
index 2cd887426c2a..fbc0fbecd63e 100644
--- a/java/java-impl/src/com/intellij/codeInsight/hints/JavaInlayParameterHintsProvider.kt
+++ b/java/java-impl/src/com/intellij/codeInsight/hints/JavaInlayParameterHintsProvider.kt
@@ -15,8 +15,6 @@
*/
package com.intellij.codeInsight.hints
-import com.intellij.lang.Language
-import com.intellij.lang.java.JavaLanguage
import com.intellij.psi.PsiCallExpression
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
@@ -48,8 +46,6 @@ class JavaInlayParameterHintsProvider : InlayParameterHintsProvider {
return MethodInfo(fullMethodName, paramNames)
}
- override val language: Language = JavaLanguage.INSTANCE
-
override val defaultBlackList = setOf(
"(begin*, end*)",
"(start*, end*)",
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightJavaModule.java b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightJavaModule.java
index 72464a05e4d9..4283a0415e73 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/light/LightJavaModule.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/light/LightJavaModule.java
@@ -150,7 +150,7 @@ public class LightJavaModule extends LightElement implements PsiJavaModule {
@Override
public Result compute(Pair p) {
LightJavaModule module = new LightJavaModule(p.first, p.second);
- return Result.create(module, JavaModuleFileChangeTracker.getInstance(p.first.getProject()));
+ return Result.create(module, JavaModuleFileChangeTracker.getDependencies(p.first.getProject()));
}
}, false, pair(manager, jarRoot));
}
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaModuleFileChangeTracker.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaModuleFileChangeTracker.java
index 8ebd1854d11d..a3f347e26d93 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaModuleFileChangeTracker.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaModuleFileChangeTracker.java
@@ -16,57 +16,14 @@
package com.intellij.psi.impl.source;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.ModificationTracker;
-import com.intellij.openapi.util.NotNullLazyKey;
-import com.intellij.psi.*;
-import com.intellij.psi.PsiTreeChangeEvent;
-import com.intellij.util.NotNullFunction;
+import com.intellij.openapi.roots.ProjectRootModificationTracker;
import org.jetbrains.annotations.NotNull;
-import static com.intellij.psi.PsiTreeChangeEvent.*;
-
-public class JavaModuleFileChangeTracker implements ModificationTracker {
- private static final NotNullLazyKey KEY = NotNullLazyKey.create("", new NotNullFunction() {
- @NotNull
- @Override
- public ModificationTracker fun(Project project) {
- return new JavaModuleFileChangeTracker(project);
- }
- });
+import static com.intellij.psi.util.PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT;
+public class JavaModuleFileChangeTracker {
@NotNull
- public static ModificationTracker getInstance(@NotNull Project p) {
- return KEY.getValue(p);
- }
-
- private volatile long myCount = 0;
-
- private JavaModuleFileChangeTracker(Project project) {
- PsiManager.getInstance(project).addPsiTreeChangeListener(new PsiTreeChangeAdapter() {
- @Override public void childAdded(@NotNull PsiTreeChangeEvent event) { process(event.getFile()); }
- @Override public void childRemoved(@NotNull PsiTreeChangeEvent event) { process(event.getFile()); }
- @Override public void childReplaced(@NotNull PsiTreeChangeEvent event) { process(event.getFile()); }
- @Override public void childMoved(@NotNull PsiTreeChangeEvent event) { process(event.getFile()); }
- @Override public void childrenChanged(@NotNull PsiTreeChangeEvent event) { process(event.getFile()); }
-
- private void process(PsiFile file) {
- if (file != null && PsiJavaModule.MODULE_INFO_FILE.equals(file.getName())) {
- myCount++;
- }
- }
-
- @Override
- public void propertyChanged(@NotNull PsiTreeChangeEvent event) {
- String name = event.getPropertyName();
- if (name == PROP_FILE_NAME || name == PROP_DIRECTORY_NAME || name == PROP_ROOTS) {
- myCount++;
- }
- }
- }, project);
- }
-
- @Override
- public long getModificationCount() {
- return myCount;
+ public static Object[] getDependencies(@NotNull Project project) {
+ return new Object[]{OUT_OF_CODE_BLOCK_MODIFICATION_COUNT, ProjectRootModificationTracker.getInstance(project)};
}
}
\ No newline at end of file
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaModuleReference.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaModuleReference.java
index 38dce76f92d7..d61db2d5317d 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaModuleReference.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaModuleReference.java
@@ -137,7 +137,7 @@ public class PsiJavaModuleReference extends PsiReferenceBase.Poly compute(Pair p) {
Collection modules = Resolver.findModules(refOwner.getContainingFile(), p.first, p.second);
PsiJavaModule module = modules.size() == 1 ? modules.iterator().next() : null;
- return Result.create(module, JavaModuleFileChangeTracker.getInstance(refOwner.getProject()));
+ return Result.create(module, JavaModuleFileChangeTracker.getDependencies(refOwner.getProject()));
}
}, false, pair(refText, incompleteCode));
}
diff --git a/lib/required_for_dist.txt b/lib/required_for_dist.txt
index 18be950a6b8e..bf43ee4533da 100644
--- a/lib/required_for_dist.txt
+++ b/lib/required_for_dist.txt
@@ -3,6 +3,7 @@ automaton.jar
cglib-nodep-3.2.4.jar
cli-parser-1.1.jar
commons-codec-1.9.jar
+commons-compress-1.10.jar
commons-httpclient-3.1-patched.jar
commons-logging-1.2.jar
commons-net-3.3.jar
diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightingSessionImpl.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightingSessionImpl.java
index fc96bd5347b5..16d7f4548085 100644
--- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightingSessionImpl.java
+++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/HighlightingSessionImpl.java
@@ -23,13 +23,11 @@ import com.intellij.openapi.editor.colors.EditorColorsScheme;
import com.intellij.openapi.editor.ex.RangeHighlighterEx;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.util.ConcurrencyUtil;
-import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.TransferToEDTQueue;
import gnu.trove.THashMap;
@@ -47,6 +45,8 @@ public class HighlightingSessionImpl implements HighlightingSession {
@NotNull private final Project myProject;
private final Document myDocument;
private final Map myRanges2markersCache = new THashMap<>();
+ private final TransferToEDTQueue myAddHighlighterInEDTQueue;
+ private final TransferToEDTQueue myDisposeHighlighterInEDTQueue;
private HighlightingSessionImpl(@NotNull PsiFile psiFile,
@Nullable Editor editor,
@@ -58,6 +58,18 @@ public class HighlightingSessionImpl implements HighlightingSession {
myEditorColorsScheme = editorColorsScheme;
myProject = psiFile.getProject();
myDocument = PsiDocumentManager.getInstance(myProject).getDocument(psiFile);
+ myDisposeHighlighterInEDTQueue = new TransferToEDTQueue<>("Dispose abandoned highlighter", highlighter -> {
+ highlighter.dispose();
+ return true;
+ }, o -> myProject.isDisposed() || getProgressIndicator().isCanceled(), 200);
+ myAddHighlighterInEDTQueue = new TransferToEDTQueue<>("Apply highlighting results", info -> {
+ final EditorColorsScheme colorsScheme = getColorsScheme();
+ UpdateHighlightersUtil.addHighlighterToEditorIncrementally(myProject, getDocument(), getPsiFile(), info.myRestrictRange.getStartOffset(),
+ info.myRestrictRange.getEndOffset(),
+ info.myInfo, colorsScheme, info.myGroupId, myRanges2markersCache);
+
+ return true;
+ }, o -> myProject.isDisposed() || getProgressIndicator().isCanceled(), 200);
}
private static final Key> HIGHLIGHTING_SESSION = Key.create("HIGHLIGHTING_SESSION");
@@ -119,39 +131,6 @@ public class HighlightingSessionImpl implements HighlightingSession {
return myEditorColorsScheme;
}
- private final TransferToEDTQueue myAddHighlighterInEDTQueue =
- new TransferToEDTQueue<>("Apply highlighting results", new Processor() {
- @Override
- public boolean process(Info info) {
- final EditorColorsScheme colorsScheme = getColorsScheme();
- UpdateHighlightersUtil
- .addHighlighterToEditorIncrementally(myProject, getDocument(), getPsiFile(), info.myRestrictRange.getStartOffset(),
- info.myRestrictRange.getEndOffset(),
- info.myInfo, colorsScheme, info.myGroupId, myRanges2markersCache);
-
- return true;
- }
- }, new Condition() {
- @Override
- public boolean value(Object o) {
- return myProject.isDisposed() || getProgressIndicator().isCanceled();
- }
- }, 200);
- private final TransferToEDTQueue myDisposeHighlighterInEDTQueue =
- new TransferToEDTQueue<>("Dispose abandoned highlighter", new Processor() {
- @Override
- public boolean process(@NotNull RangeHighlighterEx highlighter) {
- highlighter.dispose();
- return true;
- }
- }, new Condition() {
- @Override
- public boolean value(Object o) {
- return myProject.isDisposed() || getProgressIndicator().isCanceled();
- }
- }, 200);
-
-
void queueHighlightInfo(@NotNull HighlightInfo info,
@NotNull TextRange priorityRange,
@NotNull TextRange restrictedRange,
diff --git a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/ProgressableTextEditorHighlightingPass.java b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/ProgressableTextEditorHighlightingPass.java
index 32861ec99a6a..564dac79f821 100644
--- a/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/ProgressableTextEditorHighlightingPass.java
+++ b/platform/analysis-impl/src/com/intellij/codeInsight/daemon/impl/ProgressableTextEditorHighlightingPass.java
@@ -17,6 +17,7 @@
package com.intellij.codeInsight.daemon.impl;
import com.intellij.codeHighlighting.TextEditorHighlightingPass;
+import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.progress.ProgressIndicator;
@@ -151,8 +152,16 @@ public abstract class ProgressableTextEditorHighlightingPass extends TextEditorH
}
}
+ void waitForHighlightInfosApplied() {
+ ApplicationManager.getApplication().assertIsDispatchThread();
+ HighlightingSessionImpl session = (HighlightingSessionImpl)myHighlightingSession;
+ if (session != null) {
+ session.waitForHighlightInfosApplied();
+ }
+ }
+
static class EmptyPass extends TextEditorHighlightingPass {
- public EmptyPass(final Project project, @Nullable final Document document) {
+ EmptyPass(final Project project, @Nullable final Document document) {
super(project, document, false);
}
diff --git a/platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityLibraryLicenses.groovy b/platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityLibraryLicenses.groovy
index d54b19666b5b..517eefe1f447 100644
--- a/platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityLibraryLicenses.groovy
+++ b/platform/build-scripts/groovy/org/jetbrains/intellij/build/CommunityLibraryLicenses.groovy
@@ -64,6 +64,8 @@ class CommunityLibraryLicenses {
license: "Apache 2.0", url: "http://hc.apache.org/httpclient-3.x"),
new LibraryLicense(name: "Apache Commons IO", libraryName: "commons-io-1.4.jar", version: "1.4", license: "Apache 2.0",
url: "http://commons.apache.org/io/", licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0.txt"),
+ new LibraryLicense(name: "Apache Commons Lang", libraryName: "commons-lang", version: "2.6", license: "Apache 2.0",
+ licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0.txt", url: "http://commons.apache.org/proper/commons-lang/"),
new LibraryLicense(name: "Apache Commons Lang 3", libraryName: "commons-lang3-3.2.1.jar", version: "3.2.1", license: "Apache 2.0",
licenseUrl: "http://www.apache.org/licenses/LICENSE-2.0.txt", url: "http://commons.apache.org/proper/commons-lang/"),
new LibraryLicense(name: "Apache Commons Logging", libraryName: "commons-logging", version: "1.1.1", license: "Apache 2.0",
diff --git a/platform/lang-api/src/com/intellij/codeInsight/hints/InlayParameterHintsProvider.kt b/platform/lang-api/src/com/intellij/codeInsight/hints/InlayParameterHintsProvider.kt
index 6d9dc91dd9bd..e04cd417f15f 100644
--- a/platform/lang-api/src/com/intellij/codeInsight/hints/InlayParameterHintsProvider.kt
+++ b/platform/lang-api/src/com/intellij/codeInsight/hints/InlayParameterHintsProvider.kt
@@ -15,7 +15,6 @@
*/
package com.intellij.codeInsight.hints
-import com.intellij.lang.Language
import com.intellij.lang.LanguageExtension
import com.intellij.psi.PsiElement
import org.jetbrains.annotations.ApiStatus
@@ -36,13 +35,7 @@ interface InlayParameterHintsProvider {
* and selects "Do not show for this method".
*/
fun getMethodInfo(element: PsiElement): MethodInfo? = null
-
- /**
- * Language used when saving blacklist methods
- * Maybe will be moved to MethodInfo
- */
- val language: Language
-
+
/**
* Default list of methods for which hints should not be shown
*/
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DefaultHighlightInfoProcessor.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DefaultHighlightInfoProcessor.java
index 706582e1d4a1..d5029ddf7ca1 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DefaultHighlightInfoProcessor.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/DefaultHighlightInfoProcessor.java
@@ -33,7 +33,6 @@ import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiUtilBase;
import com.intellij.util.Alarm;
-import com.intellij.util.Processor;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java
index 10ffb48c7a8f..57db3cd614a4 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/PassExecutorService.java
@@ -517,6 +517,9 @@ class PassExecutorService implements Disposable {
throw new RuntimeException(message, e);
}
if (threadsToStartCountdown.decrementAndGet() == 0) {
+ if (pass instanceof ProgressableTextEditorHighlightingPass) {
+ ((ProgressableTextEditorHighlightingPass)pass).waitForHighlightInfosApplied();
+ }
log(updateProgress, pass, "Stopping ");
updateProgress.stopIfRunning();
}
@@ -543,7 +546,7 @@ class PassExecutorService implements Disposable {
}
private static void sortById(@NotNull List result) {
- ContainerUtil.quickSort(result, (o1, o2) -> o1.getId() - o2.getId());
+ ContainerUtil.quickSort(result, Comparator.comparingInt(TextEditorHighlightingPass::getId));
}
private static int getThreadNum() {
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hints/ParameterHintsPassFactory.java b/platform/lang-impl/src/com/intellij/codeInsight/hints/ParameterHintsPassFactory.java
index fd49d5736ed5..f34b61e7db29 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/hints/ParameterHintsPassFactory.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/hints/ParameterHintsPassFactory.java
@@ -22,7 +22,9 @@ import com.intellij.codeHighlighting.TextEditorHighlightingPassRegistrar;
import com.intellij.codeInsight.daemon.impl.ParameterHintsPresentationManager;
import com.intellij.codeInsight.hints.filtering.Matcher;
import com.intellij.codeInsight.hints.filtering.MatcherConstructor;
+import com.intellij.codeInsight.hints.settings.Diff;
import com.intellij.codeInsight.hints.settings.ParameterNameHintsSettings;
+import com.intellij.lang.Language;
import com.intellij.openapi.components.AbstractProjectComponent;
import com.intellij.openapi.editor.Caret;
import com.intellij.openapi.editor.Editor;
@@ -71,12 +73,14 @@ public class ParameterHintsPassFactory extends AbstractProjectComponent implemen
myAnnotations.clear();
if (!isEnabled()) return;
- InlayParameterHintsProvider provider = InlayParameterHintsExtension.INSTANCE.forLanguage(myFile.getLanguage());
+ Language language = myFile.getLanguage();
+ InlayParameterHintsProvider provider = InlayParameterHintsExtension.INSTANCE.forLanguage(language);
if (provider == null) return;
- List matchers = ParameterNameHintsSettings
- .getInstance()
- .getIgnorePatternSet(provider)
+ Diff diff = ParameterNameHintsSettings.getInstance().getBlackListDiff(language);
+ Set blackList = diff.applyOn(provider.getDefaultBlackList());
+
+ List matchers = blackList
.stream()
.map((item) -> MatcherConstructor.INSTANCE.createMatcher(item))
.collect(Collectors.toList());
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt b/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt
index 1d4e224bd6ab..cbbe24034532 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt
+++ b/platform/lang-impl/src/com/intellij/codeInsight/hints/PopupActions.kt
@@ -50,7 +50,7 @@ class ShowParameterHintsSettings : AnAction() {
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)
+ val dialog = ParameterNameHintsConfigurable(project, hintExtension.defaultBlackList, file.language)
dialog.show()
}
}
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hints/settings/ParameterNameHintsConfigurable.java b/platform/lang-impl/src/com/intellij/codeInsight/hints/settings/ParameterNameHintsConfigurable.java
index fc19484b00b4..fad2ac7c7039 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/hints/settings/ParameterNameHintsConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/hints/settings/ParameterNameHintsConfigurable.java
@@ -15,8 +15,8 @@
*/
package com.intellij.codeInsight.hints.settings;
-import com.intellij.codeInsight.hints.InlayParameterHintsProvider;
import com.intellij.codeInsight.hints.filtering.MatcherConstructor;
+import com.intellij.lang.Language;
import com.intellij.openapi.components.ServiceManager;
import com.intellij.openapi.editor.event.DocumentAdapter;
import com.intellij.openapi.editor.event.DocumentEvent;
@@ -38,12 +38,16 @@ import java.util.stream.Collectors;
public class ParameterNameHintsConfigurable extends DialogWrapper {
private final Project myProject;
- private final InlayParameterHintsProvider myHintsProvider;
-
- public ParameterNameHintsConfigurable(@NotNull Project project, @NotNull InlayParameterHintsProvider provider) {
+ private final Set myDefaultBlackList;
+ private final Language myLanguage;
+
+ public ParameterNameHintsConfigurable(@NotNull Project project,
+ @NotNull Set defaultBlackList,
+ @NotNull Language language) {
super(project);
myProject = project;
- myHintsProvider = provider;
+ myDefaultBlackList = defaultBlackList;
+ myLanguage = language;
setTitle("Configure Parameter Name Hints Blacklist");
init();
}
@@ -70,7 +74,8 @@ public class ParameterNameHintsConfigurable extends DialogWrapper {
.filter((e) -> !e.trim().isEmpty())
.collect(Collectors.toSet());
- ParameterNameHintsSettings.getInstance().setIgnorePatternSet(myHintsProvider, updatedBlackList);
+ Diff diff = Diff.Builder.build(myDefaultBlackList, updatedBlackList);
+ ParameterNameHintsSettings.getInstance().setBlackListDiff(myLanguage, diff);
}
@Nullable
@@ -85,10 +90,11 @@ public class ParameterNameHintsConfigurable extends DialogWrapper {
private void createUIComponents() {
EditorTextFieldProvider service = ServiceManager.getService(myProject, EditorTextFieldProvider.class);
myEditorTextField = service.getEditorField(PlainTextLanguage.INSTANCE, myProject, ContainerUtil.emptyIterable());
-
- Set blacklist = ParameterNameHintsSettings.getInstance().getIgnorePatternSet(myHintsProvider);
+
+ Diff diff = ParameterNameHintsSettings.getInstance().getBlackListDiff(myLanguage);
+ Set blacklist = diff.applyOn(myDefaultBlackList);
+
String text = StringUtil.join(blacklist, "\n");
-
myEditorTextField.setText(text);
myEditorTextField.addDocumentListener(new DocumentAdapter() {
@Override
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hints/settings/ParameterNameHintsSettings.kt b/platform/lang-impl/src/com/intellij/codeInsight/hints/settings/ParameterNameHintsSettings.kt
index e0362885e391..1a941281117d 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/hints/settings/ParameterNameHintsSettings.kt
+++ b/platform/lang-impl/src/com/intellij/codeInsight/hints/settings/ParameterNameHintsSettings.kt
@@ -1,6 +1,5 @@
package com.intellij.codeInsight.hints.settings
-import com.intellij.codeInsight.hints.InlayParameterHintsProvider
import com.intellij.lang.Language
import com.intellij.openapi.components.PersistentStateComponent
import com.intellij.openapi.components.State
@@ -19,11 +18,52 @@ private object XmlTagHelper {
}
+class Diff(val added: Set, val removed: Set) {
+
+ fun applyOn(base: Set): Set {
+ val baseSet = base.toMutableSet()
+ added.forEach { baseSet.add(it) }
+ removed.forEach { baseSet.remove(it) }
+ return baseSet
+ }
+
+ companion object Builder {
+ fun build(base: Set, updated: Set): Diff {
+ val removed = base.toMutableSet()
+ removed.removeAll(updated)
+
+ val added = updated.toMutableSet()
+ added.removeAll(base)
+
+ return Diff(added, removed)
+ }
+ }
+
+}
+
+
@State(name = "ParameterNameHintsSettings", storages = arrayOf(Storage("parameter.hints.xml")))
class ParameterNameHintsSettings : PersistentStateComponent {
- private val myRemovedPatterns = hashMapOf>()
- private val myAddedPatterns = hashMapOf>()
+ private val myRemovedPatterns = hashMapOf>()
+ private val myAddedPatterns = hashMapOf>()
+ fun addIgnorePattern(language: Language, pattern: String) {
+ val patternsBefore = getAddedPatterns(language)
+ setAddedPatterns(language, patternsBefore + pattern)
+ }
+
+ fun getBlackListDiff(language: Language): Diff {
+ val added = getAddedPatterns(language)
+ val removed = getRemovedPatterns(language)
+
+ return Diff(added, removed)
+ }
+
+ fun setBlackListDiff(language: Language, diff: Diff) {
+ setAddedPatterns(language, diff.added)
+ setRemovedPatterns(language, diff.removed)
+ }
+
override fun getState(): Element {
val root = Element("settings")
val blacklists = root.getOrCreateChild(XmlTagHelper.BLACKLISTS)
@@ -47,73 +87,43 @@ class ParameterNameHintsSettings : PersistentStateComponent {
myRemovedPatterns[language] = it.extractPatterns(XmlTagHelper.REMOVED)
}
}
-
- fun addIgnorePattern(language: Language, pattern: String) {
- val patternsBefore = getAddedPatterns(language)
- setAddedPatterns(language, patternsBefore + pattern)
- }
-
- fun getIgnorePatternSet(hintsProvider: InlayParameterHintsProvider): Set {
- val added = getAddedPatterns(hintsProvider.language)
- val removed = getRemovedPatterns(hintsProvider.language)
-
- val updated = hintsProvider.defaultBlackList.toMutableSet()
- updated.removeAll(removed)
- updated.addAll(added)
-
- return updated
- }
-
- fun setIgnorePatternSet(provider: InlayParameterHintsProvider, updatedBlackList: Set) {
- val defaultBlackList = provider.defaultBlackList
-
- val removed = defaultBlackList.toMutableSet()
- removed.removeAll(updatedBlackList)
-
- val added = updatedBlackList.toMutableSet()
- added.removeAll(defaultBlackList)
-
- val language = provider.language
- setRemovedPatterns(language, removed)
- setAddedPatterns(language, added)
- }
companion object {
@JvmStatic
fun getInstance() = service()
}
- private fun getAddedPatterns(language: Language): List {
+ private fun getAddedPatterns(language: Language): Set {
val key = language.displayName
- return myAddedPatterns[key] ?: emptyList()
+ return myAddedPatterns[key] ?: emptySet()
}
- private fun getRemovedPatterns(language: Language): List {
+ private fun getRemovedPatterns(language: Language): Set {
val key = language.displayName
- return myRemovedPatterns[key] ?: emptyList()
+ return myRemovedPatterns[key] ?: emptySet()
}
- private fun setRemovedPatterns(language: Language, removed: Collection) {
+ private fun setRemovedPatterns(language: Language, removed: Set) {
val key = language.displayName
- myRemovedPatterns[key] = removed.toList()
+ myRemovedPatterns[key] = removed
}
- private fun setAddedPatterns(language: Language, added: Collection) {
+ private fun setAddedPatterns(language: Language, added: Set) {
val key = language.displayName
- myAddedPatterns[key] = added.toList()
+ myAddedPatterns[key] = added
}
}
-private fun Element.addLanguagePatternElements(language: String, patterns: List, tag: String) {
+private fun Element.addLanguagePatternElements(language: String, patterns: Set, tag: String) {
val list = getOrCreateChild(XmlTagHelper.LANGUAGE_LIST)
list.setAttribute(XmlTagHelper.LANGUAGE, language)
val elements = patterns.map { it.toPatternElement(tag) }
list.addContent(elements)
}
-private fun Element.extractPatterns(tag: String): List {
- return getChildren(tag).mapNotNull { it.attributeValue(XmlTagHelper.PATTERN) }
+private fun Element.extractPatterns(tag: String): Set {
+ return getChildren(tag).mapNotNull { it.attributeValue(XmlTagHelper.PATTERN) }.toSet()
}
private fun Element.attributeValue(attr: String): String? = this.getAttribute(attr)?.value
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupPreview.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupPreview.java
index a3908fa72984..4c0e852b2289 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupPreview.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupPreview.java
@@ -24,6 +24,7 @@ import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.refactoring.rename.inplace.InplaceRefactoring;
import com.intellij.ui.JBColor;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.FList;
@@ -52,11 +53,14 @@ class LookupPreview {
myInlays.clear();
String suffix = getSuffixText(item);
- if (!suffix.isEmpty() && myLookup.getTopLevelEditor() instanceof EditorImpl) {
- myLookup.getTopLevelEditor().getCaretModel().runForEachCaret(caret -> {
+ Editor editor = myLookup.getTopLevelEditor();
+ if (!suffix.isEmpty() && editor instanceof EditorImpl &&
+ !editor.getSelectionModel().hasSelection() &&
+ InplaceRefactoring.getActiveInplaceRenamer(editor) == null) {
+ for (Caret caret : editor.getCaretModel().getAllCarets()) {
ensureCaretBeforeInlays(caret);
addInlay(suffix, caret.getOffset());
- });
+ }
}
}
diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java b/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java
index 3315eac0b979..366ae79af5a6 100644
--- a/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java
+++ b/platform/lang-impl/src/com/intellij/find/findUsages/CommonFindUsagesDialog.java
@@ -47,7 +47,7 @@ public class CommonFindUsagesDialog extends AbstractFindUsagesDialog {
boolean isSingleFile,
@NotNull FindUsagesHandler handler) {
super(project, findUsagesOptions, toShowInNewTab, mustOpenInNewTab, isSingleFile, isTextSearch(element, isSingleFile, handler),
- !isSingleFile && !element.getManager().isInProject(element));
+ true);
myPsiElement = element;
myHelpId = ObjectUtils.chooseNotNull(handler.getHelpId(), HelpID.FIND_OTHER_USAGES);
init();
diff --git a/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java b/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java
index 7865871d0f3f..0da1029c159b 100644
--- a/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java
+++ b/platform/lang-impl/src/com/intellij/ide/ui/search/TraverseUIStarter.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2014 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.
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.intellij.ide.ui.search;
import com.intellij.application.options.OptionsContainingConfigurable;
@@ -34,31 +33,30 @@ import com.intellij.openapi.options.UnnamedConfigurable;
import com.intellij.openapi.options.ex.ConfigurableWrapper;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.util.JDOMUtil;
+import com.intellij.openapi.util.io.FileUtil;
import org.jdom.Document;
import org.jdom.Element;
-import org.jetbrains.annotations.NonNls;
import java.io.File;
import java.io.IOException;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Set;
-import java.util.TreeSet;
+import java.util.*;
/**
- * Used by Installer's build buildSearchableOptions step. In order to run locally use TraverseUi configuration.
- * Pass corresponding -Didea.platform.prefix=YOUR_IDE_PREFIX to vm options and choose main_YOUR_IDE module
+ * Used in installer's "build searchable options" step.
+ *
+ * In order to run locally, use "TraverseUi" run configuration (pass corresponding "idea.platform.prefix" property via VM options,
+ * and choose correct main module).
*/
-@SuppressWarnings({"CallToPrintStackTrace", "SynchronizeOnThis"})
+@SuppressWarnings({"CallToPrintStackTrace", "SynchronizeOnThis", "UseOfSystemOutOrSystemErr"})
public class TraverseUIStarter extends ApplicationStarterEx {
- @NonNls private static final String OPTIONS = "options";
- @NonNls private static final String CONFIGURABLE = "configurable";
- @NonNls private static final String ID = "id";
- @NonNls private static final String CONFIGURABLE_NAME = "configurable_name";
- @NonNls private static final String OPTION = "option";
- @NonNls private static final String NAME = "name";
- @NonNls private static final String PATH = "path";
- @NonNls private static final String HIT = "hit";
+ private static final String OPTIONS = "options";
+ private static final String CONFIGURABLE = "configurable";
+ private static final String ID = "id";
+ private static final String CONFIGURABLE_NAME = "configurable_name";
+ private static final String OPTION = "option";
+ private static final String NAME = "name";
+ private static final String PATH = "path";
+ private static final String HIT = "hit";
private String OUTPUT_PATH;
@@ -68,7 +66,6 @@ public class TraverseUIStarter extends ApplicationStarterEx {
}
@Override
- @NonNls
public String getCommandName() {
return "traverseUI";
}
@@ -79,7 +76,7 @@ public class TraverseUIStarter extends ApplicationStarterEx {
}
@Override
- public void main(String[] args){
+ public void main(String[] args) {
System.out.println("Starting searchable options index builder");
try {
startup(OUTPUT_PATH);
@@ -93,52 +90,54 @@ public class TraverseUIStarter extends ApplicationStarterEx {
}
public static void startup(String outputPath) throws IOException {
- final HashMap> options =
- new HashMap<>();
+ Map> options = new HashMap<>();
SearchUtil.processProjectConfigurables(ProjectManager.getInstance().getDefaultProject(), options);
+
Element root = new Element(OPTIONS);
- for (SearchableConfigurable configurable : options.keySet()) {
+ for (SearchableConfigurable option : options.keySet()) {
+ SearchableConfigurable configurable = option;
+
Element configurableElement = new Element(CONFIGURABLE);
- final String id = configurable.getId();
- if (id == null) continue;
+ String id = configurable.getId();
configurableElement.setAttribute(ID, id);
configurableElement.setAttribute(CONFIGURABLE_NAME, configurable.getDisplayName());
- final TreeSet sortedOptions = options.get(configurable);
+ Set sortedOptions = options.get(configurable);
writeOptions(configurableElement, sortedOptions);
+
if (configurable instanceof ConfigurableWrapper) {
- final UnnamedConfigurable wrapped = ((ConfigurableWrapper)configurable).getConfigurable();
+ UnnamedConfigurable wrapped = ((ConfigurableWrapper)configurable).getConfigurable();
if (wrapped instanceof SearchableConfigurable) {
configurable = (SearchableConfigurable)wrapped;
}
}
- if (configurable instanceof KeymapPanel){
+ if (configurable instanceof KeymapPanel) {
processKeymap(configurableElement);
- } else if (configurable instanceof OptionsContainingConfigurable){
+ }
+ else if (configurable instanceof OptionsContainingConfigurable) {
processOptionsContainingConfigurable((OptionsContainingConfigurable)configurable, configurableElement);
- } else if (configurable instanceof PluginManagerConfigurable) {
- final TreeSet descriptions = wordsToOptionDescriptors(Collections.singleton(AvailablePluginsManagerMain.MANAGE_REPOSITORIES));
- for (OptionDescription description : descriptions) {
+ }
+ else if (configurable instanceof PluginManagerConfigurable) {
+ for (OptionDescription description : wordsToOptionDescriptors(Collections.singleton(AvailablePluginsManagerMain.MANAGE_REPOSITORIES))) {
append(null, AvailablePluginsManagerMain.MANAGE_REPOSITORIES, description.getOption(), configurableElement);
}
- } else if (configurable instanceof AllFileTemplatesConfigurable) {
+ }
+ else if (configurable instanceof AllFileTemplatesConfigurable) {
processFileTemplates(configurableElement);
}
+
root.addContent(configurableElement);
configurable.disposeUIResources();
}
- final File file = new File(outputPath);
- if (!file.isFile()) {
- file.getParentFile().mkdirs();
- file.createNewFile();
- }
+
+ FileUtil.ensureCanCreateFile(new File(outputPath));
JDOMUtil.writeDocument(new Document(root), outputPath, "\n");
System.out.println("Searchable options index builder completed");
}
private static void processFileTemplates(Element configurableElement) {
- final SearchableOptionsRegistrar optionsRegistrar = SearchableOptionsRegistrar.getInstance();
- TreeSet options = new TreeSet<>();
+ SearchableOptionsRegistrar optionsRegistrar = SearchableOptionsRegistrar.getInstance();
+ Set options = new TreeSet<>();
FileTemplateManager fileTemplateManager = FileTemplateManager.getDefaultInstance();
processTemplates(optionsRegistrar, options, fileTemplateManager.getAllTemplates());
@@ -149,45 +148,30 @@ public class TraverseUIStarter extends ApplicationStarterEx {
writeOptions(configurableElement, options);
}
- private static void processTemplates(SearchableOptionsRegistrar optionsRegistrar,
- TreeSet options,
- FileTemplate[] templates) {
+ private static void processTemplates(SearchableOptionsRegistrar registrar, Set options, FileTemplate[] templates) {
for (FileTemplate template : templates) {
- collectOptions(optionsRegistrar, options, template.getName());
- //collectOptions(optionsRegistrar, options, template.getDescription());
+ collectOptions(registrar, options, template.getName(), null);
}
}
- private static void collectOptions(SearchableOptionsRegistrar optionsRegistrar,
- TreeSet options,
- String text) {
- collectOptions(optionsRegistrar, options, text, null);
- }
-
- private static void collectOptions(SearchableOptionsRegistrar optionsRegistrar,
- TreeSet options,
- String text,
- String path) {
- final Set strings = optionsRegistrar.getProcessedWordsWithoutStemming(text);
- for (String word : strings) {
+ private static void collectOptions(SearchableOptionsRegistrar registrar, Set options, String text, String path) {
+ for (String word : registrar.getProcessedWordsWithoutStemming(text)) {
options.add(new OptionDescription(word, text, path));
}
}
- private static void processOptionsContainingConfigurable(final OptionsContainingConfigurable configurable,
- final Element configurableElement) {
- final Set optionsPath = configurable.processListOptions();
- final TreeSet result = wordsToOptionDescriptors(optionsPath);
+ private static void processOptionsContainingConfigurable(OptionsContainingConfigurable configurable, Element configurableElement) {
+ Set optionsPath = configurable.processListOptions();
+ Set result = wordsToOptionDescriptors(optionsPath);
writeOptions(configurableElement, result);
}
- private static TreeSet wordsToOptionDescriptors(Set optionsPath) {
- SearchableOptionsRegistrar searchableOptionsRegistrar = SearchableOptionsRegistrar.getInstance();
- final TreeSet result = new TreeSet<>();
+ private static Set wordsToOptionDescriptors(Set optionsPath) {
+ SearchableOptionsRegistrar registrar = SearchableOptionsRegistrar.getInstance();
+ Set result = new TreeSet<>();
for (String opt : optionsPath) {
- final Set words = searchableOptionsRegistrar.getProcessedWordsWithoutStemming(opt);
- for (String word : words) {
- if (word != null){
+ for (String word : registrar.getProcessedWordsWithoutStemming(opt)) {
+ if (word != null) {
result.add(new OptionDescription(word, opt, null));
}
}
@@ -195,7 +179,7 @@ public class TraverseUIStarter extends ApplicationStarterEx {
return result;
}
- private static void processKeymap(final Element configurableElement){
+ private static void processKeymap(Element configurableElement) {
final ActionManager actionManager = ActionManager.getInstance();
final String componentName = actionManager.getComponentName();
final SearchableOptionsRegistrar searchableOptionsRegistrar = SearchableOptionsRegistrar.getInstance();
@@ -215,7 +199,7 @@ public class TraverseUIStarter extends ApplicationStarterEx {
writeOptions(configurableElement, options);
}
- private static void writeOptions(Element configurableElement, TreeSet options) {
+ private static void writeOptions(Element configurableElement, Set options) {
for (OptionDescription opt : options) {
append(opt.getPath(), opt.getHit(), opt.getOption(), configurableElement);
}
@@ -230,4 +214,4 @@ public class TraverseUIStarter extends ApplicationStarterEx {
optionElement.setAttribute(HIT, hit);
configurableElement.addContent(optionElement);
}
-}
+}
\ No newline at end of file
diff --git a/platform/lang-impl/testSources/com/intellij/codeInsight/hints/settings/ParameterNameSettingsTest.kt b/platform/lang-impl/testSources/com/intellij/codeInsight/hints/settings/ParameterNameSettingsTest.kt
index 83bd177c73be..b46d1dc63c5b 100644
--- a/platform/lang-impl/testSources/com/intellij/codeInsight/hints/settings/ParameterNameSettingsTest.kt
+++ b/platform/lang-impl/testSources/com/intellij/codeInsight/hints/settings/ParameterNameSettingsTest.kt
@@ -16,14 +16,12 @@
package com.intellij.codeInsight.hints.settings
import com.intellij.codeInsight.hints.InlayParameterHintsProvider
-import com.intellij.lang.Language
import com.intellij.openapi.fileTypes.PlainTextLanguage
import junit.framework.TestCase
-class MockInlayProvider(override val defaultBlackList: Set): InlayParameterHintsProvider {
- override val language: Language = PlainTextLanguage.INSTANCE
-}
+class MockInlayProvider(override val defaultBlackList: Set): InlayParameterHintsProvider
+
class ParameterNameSettingsTest : TestCase() {
@@ -40,14 +38,20 @@ class ParameterNameSettingsTest : TestCase() {
}
fun addIgnorePattern(newPattern: String) {
- settings.addIgnorePattern(inlayProvider.language, newPattern)
+ settings.addIgnorePattern(PlainTextLanguage.INSTANCE, newPattern)
}
fun setIgnorePattern(vararg newPatternSet: String) {
- settings.setIgnorePatternSet(inlayProvider, setOf(*newPatternSet))
+ val base = inlayProvider.defaultBlackList
+ val diff = Diff.build(base, setOf(*newPatternSet))
+
+ settings.setBlackListDiff(PlainTextLanguage.INSTANCE, diff)
}
- fun getIgnoreSet(): Set = settings.getIgnorePatternSet(inlayProvider)
+ fun getIgnoreSet(): Set {
+ val diff = settings.getBlackListDiff(PlainTextLanguage.INSTANCE)
+ return diff.applyOn(inlayProvider.defaultBlackList)
+ }
fun `test ignore pattern is added`() {
defaultSettingsUpdated("xxx")
diff --git a/platform/platform-api/src/com/intellij/ui/components/JBViewport.java b/platform/platform-api/src/com/intellij/ui/components/JBViewport.java
index 601872389483..92136929c053 100644
--- a/platform/platform-api/src/com/intellij/ui/components/JBViewport.java
+++ b/platform/platform-api/src/com/intellij/ui/components/JBViewport.java
@@ -165,12 +165,26 @@ public class JBViewport extends JViewport implements ZoomableViewport {
@Override
public void scrollRectToVisible(Rectangle bounds) {
Component view = getView();
- if (view instanceof JComponent) {
+ if (view instanceof JComponent && !isAutoscroll(bounds)) {
JBInsets.addTo(bounds, getViewInsets((JComponent)view));
}
super.scrollRectToVisible(bounds);
}
+ private boolean isAutoscroll(Rectangle bounds) {
+ if (bounds.x == -bounds.width || bounds.x == getWidth()) {
+ if (bounds.y + bounds.height + bounds.y == getHeight()) {
+ return true;
+ }
+ }
+ if (bounds.y == -bounds.height || bounds.y == getHeight()) {
+ if (bounds.x + bounds.width + bounds.x == getWidth()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
/**
* Returns the alignment of the specified scroll bar
* if and only if the specified scroll bar
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/search/SearchUtil.java b/platform/platform-impl/src/com/intellij/ide/ui/search/SearchUtil.java
index f0c4464c18f7..854fc1e46720 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/search/SearchUtil.java
+++ b/platform/platform-impl/src/com/intellij/ide/ui/search/SearchUtil.java
@@ -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.
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
package com.intellij.ide.ui.search;
import com.intellij.application.options.SkipSelfSearchComponent;
@@ -24,15 +23,12 @@ import com.intellij.openapi.options.MasterDetails;
import com.intellij.openapi.options.SearchableConfigurable;
import com.intellij.openapi.options.ex.GlassPanel;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.popup.JBPopup;
-import com.intellij.openapi.ui.popup.JBPopupFactory;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.ui.*;
-import com.intellij.ui.components.JBList;
-import com.intellij.util.Alarm;
-import com.intellij.util.Consumer;
+import com.intellij.ui.JBColor;
+import com.intellij.ui.SimpleColoredComponent;
+import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.ui.TabbedPaneWrapper;
import com.intellij.util.containers.ContainerUtil;
-import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -40,36 +36,32 @@ import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import java.awt.*;
-import java.awt.event.KeyAdapter;
-import java.awt.event.KeyEvent;
import java.util.*;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
- * User: anna
- * Date: 07-Feb-2006
+ * @author anna
+ * @since 07.02.2006
*/
public class SearchUtil {
private static final Pattern HTML_PATTERN = Pattern.compile("<[^<>]*>");
- private static final Pattern QUOTED = Pattern.compile("\\\"([^\\\"]+)\\\"");
+ private static final Pattern QUOTED = Pattern.compile("\"([^\"]+)\"");
public static final String HIGHLIGHT_WITH_BORDER = "searchUtil.highlightWithBorder";
public static final String STYLE_END = "";
- private SearchUtil() {
- }
+ private SearchUtil() { }
- public static void processProjectConfigurables(Project project, HashMap> options) {
+ public static void processProjectConfigurables(Project project, Map> options) {
processConfigurables(ShowSettingsUtilImpl.getConfigurables(project, false), options);
}
- private static void processConfigurables(final Configurable[] configurables,
- final HashMap> options) {
+ private static void processConfigurables(Configurable[] configurables, Map> options) {
for (Configurable configurable : configurables) {
if (configurable instanceof SearchableConfigurable) {
- TreeSet configurableOptions = new TreeSet<>();
+ Set configurableOptions = new TreeSet<>();
if (configurable instanceof Configurable.Composite) {
final Configurable[] children = ((Configurable.Composite)configurable).getConfigurables();
@@ -86,26 +78,24 @@ public class SearchUtil {
if (configurable instanceof MasterDetails) {
final MasterDetails md = (MasterDetails)configurable;
md.initUi();
- _processComponent(configurable, configurableOptions, md.getMaster());
- _processComponent(configurable, configurableOptions, md.getDetails().getComponent());
+ processComponent(configurable, configurableOptions, md.getMaster());
+ processComponent(configurable, configurableOptions, md.getDetails().getComponent());
}
else {
- _processComponent(configurable, configurableOptions, configurable.createComponent());
+ processComponent(configurable, configurableOptions, configurable.createComponent());
}
}
}
}
- private static void _processComponent(final Configurable configurable, final TreeSet configurableOptions,
- final JComponent component) {
-
- if (component == null) return;
-
- processUILabel(configurable.getDisplayName(), configurableOptions, null);
- processComponent(component, configurableOptions, null);
+ private static void processComponent(Configurable configurable, Set configurableOptions, JComponent component) {
+ if (component != null) {
+ processUILabel(configurable.getDisplayName(), configurableOptions, null);
+ processComponent(component, configurableOptions, null);
+ }
}
- public static void processComponent(final JComponent component, final Set configurableOptions, @NonNls String path) {
+ private static void processComponent(JComponent component, Set configurableOptions, String path) {
if (component instanceof SkipSelfSearchComponent) return;
final Border border = component.getBorder();
if (border instanceof TitledBorder) {
@@ -122,19 +112,19 @@ public class SearchUtil {
}
}
else if (component instanceof JCheckBox) {
- @NonNls final String checkBoxTitle = ((JCheckBox)component).getText();
+ final String checkBoxTitle = ((JCheckBox)component).getText();
if (checkBoxTitle != null) {
processUILabel(checkBoxTitle, configurableOptions, path);
}
}
else if (component instanceof JRadioButton) {
- @NonNls final String radioButtonTitle = ((JRadioButton)component).getText();
+ final String radioButtonTitle = ((JRadioButton)component).getText();
if (radioButtonTitle != null) {
processUILabel(radioButtonTitle, configurableOptions, path);
}
}
else if (component instanceof JButton) {
- @NonNls final String buttonTitle = ((JButton)component).getText();
+ final String buttonTitle = ((JButton)component).getText();
if (buttonTitle != null) {
processUILabel(buttonTitle, configurableOptions, path);
}
@@ -163,18 +153,15 @@ public class SearchUtil {
}
}
- private static void processUILabel(@NonNls final String title, final Set configurableOptions, String path) {
+ private static void processUILabel(String title, Set configurableOptions, String path) {
final Set words = SearchableOptionsRegistrar.getInstance().getProcessedWordsWithoutStemming(title);
- @NonNls final String regex = "[\\W&&[^\\p{Punct}\\p{Blank}]]";
+ final String regex = "[\\W&&[^\\p{Punct}\\p{Blank}]]";
for (String option : words) {
configurableOptions.add(new OptionDescription(option, HTML_PATTERN.matcher(title).replaceAll(" ").replaceAll(regex, " "), path));
}
}
- public static Runnable lightOptions(final SearchableConfigurable configurable,
- final JComponent component,
- final String option,
- final GlassPanel glassPanel) {
+ public static Runnable lightOptions(SearchableConfigurable configurable, JComponent component, String option, GlassPanel glassPanel) {
return () -> {
if (!traverseComponentsTree(configurable, glassPanel, component, option, true)) {
traverseComponentsTree(configurable, glassPanel, component, option, false);
@@ -191,7 +178,8 @@ public class SearchUtil {
final Set titleWords = searchableOptionsRegistrar.getProcessedWords(title);
pathWords.removeAll(titleWords);
if (pathWords.isEmpty()) return i;
- } else if (tabIdx.equalsIgnoreCase(title)) { //e.g. only stop words
+ }
+ else if (tabIdx.equalsIgnoreCase(title)) { //e.g. only stop words
return i;
}
}
@@ -210,12 +198,11 @@ public class SearchUtil {
return -1;
}
- private static boolean traverseComponentsTree(final SearchableConfigurable configurable,
+ private static boolean traverseComponentsTree(SearchableConfigurable configurable,
GlassPanel glassPanel,
JComponent rootComponent,
String option,
boolean force) {
-
rootComponent.putClientProperty(HIGHLIGHT_WITH_BORDER, null);
if (option == null || option.trim().length() == 0) return false;
@@ -271,7 +258,6 @@ public class SearchUtil {
}
}
-
final Component[] components = rootComponent.getComponents();
for (Component component : components) {
if (component instanceof JComponent) {
@@ -298,20 +284,19 @@ public class SearchUtil {
return highlight;
}
- public static boolean isComponentHighlighted(String text, String option, final boolean force, final SearchableConfigurable configurable) {
+ public static boolean isComponentHighlighted(String text, String option, boolean force, final SearchableConfigurable configurable) {
if (text == null || option == null || option.length() == 0) return false;
final SearchableOptionsRegistrar searchableOptionsRegistrar = SearchableOptionsRegistrar.getInstance();
final Set words = searchableOptionsRegistrar.getProcessedWords(option);
- final Set options =
- configurable != null ? searchableOptionsRegistrar.replaceSynonyms(words, configurable) : words;
+ final Set options = configurable != null ? searchableOptionsRegistrar.replaceSynonyms(words, configurable) : words;
if (options == null || options.isEmpty()) {
- return text.toLowerCase().indexOf(option.toLowerCase()) != -1;
+ return text.toLowerCase(Locale.US).contains(option.toLowerCase(Locale.US));
}
final Set tokens = searchableOptionsRegistrar.getProcessedWords(text);
if (!force) {
options.retainAll(tokens);
final boolean highlight = !options.isEmpty();
- return highlight || text.toLowerCase().indexOf(option.toLowerCase()) != -1;
+ return highlight || text.toLowerCase(Locale.US).contains(option.toLowerCase(Locale.US));
}
else {
options.removeAll(tokens);
@@ -319,7 +304,7 @@ public class SearchUtil {
}
}
- public static String markup(@NonNls @NotNull String textToMarkup, @Nullable String filter) {
+ public static String markup(@NotNull String textToMarkup, @Nullable String filter) {
if (filter == null || filter.length() == 0) {
return textToMarkup;
}
@@ -332,11 +317,13 @@ public class SearchUtil {
head = textToMarkup.substring(0, bodyStart);
if (bodyEnd >= 0) {
foot = textToMarkup.substring(bodyEnd);
- } else {
+ }
+ else {
foot = "";
}
textToMarkup = textToMarkup.substring(bodyStart, bodyEnd);
- } else {
+ }
+ else {
foot = "";
head = "";
}
@@ -360,7 +347,7 @@ public class SearchUtil {
private static String quoteStrictOccurrences(final String textToMarkup, final String filter) {
String cur = "";
- final String s = textToMarkup.toLowerCase();
+ final String s = textToMarkup.toLowerCase(Locale.US);
for (String part : filter.split(" ")) {
if (s.contains(part)) {
cur += "\"" + part + "\" ";
@@ -372,13 +359,14 @@ public class SearchUtil {
return cur;
}
- private static String markup(@NonNls String textToMarkup, final Pattern insideHtmlTagPattern, final String option) {
+ private static String markup(String textToMarkup, final Pattern insideHtmlTagPattern, final String option) {
final int styleIdx = textToMarkup.indexOf("