diff --git a/build/scripts/utils.gant b/build/scripts/utils.gant
index f05aeb16070e..58628589ac90 100644
--- a/build/scripts/utils.gant
+++ b/build/scripts/utils.gant
@@ -65,7 +65,7 @@ binding.setVariable("guessHome", {
})
binding.setVariable("loadProject", {
- requireProperty("jdk", requireProperty("jdk15.home", guessJdk()))
+ requireProperty("jdk", requireProperty("jdk16.home", guessJdk()))
new IdeaProjectLoader().loadFromPath(project, "${home}")
binding.ant.patternset(id: "idea.compiler.resources") {
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java
index cfcbcca74353..e299e40d5f54 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java
@@ -46,7 +46,6 @@ import com.intellij.openapi.vfs.*;
import com.intellij.openapi.vfs.newvfs.FileAttribute;
import com.intellij.openapi.vfs.newvfs.ManagingFS;
import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
-import com.intellij.openapi.vfs.newvfs.impl.NullVirtualFile;
import com.intellij.openapi.vfs.newvfs.persistent.FSRecords;
import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
import com.intellij.util.containers.SLRUCache;
@@ -172,6 +171,9 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
while (scopeSrcIterator.hasNext()) {
final VirtualFile file = scopeSrcIterator.next();
if (!file.isValid()) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Skipping invalid file " + file.getPresentableUrl());
+ }
continue;
}
final int fileId = getFileId(file);
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java
index ce9b2590798a..97eb5afd45a1 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java
@@ -48,6 +48,7 @@ import com.intellij.execution.ExecutionResult;
import com.intellij.execution.Executor;
import com.intellij.execution.configurations.CommandLineState;
import com.intellij.execution.configurations.RemoteConnection;
+import com.intellij.execution.configurations.RunProfile;
import com.intellij.execution.configurations.RunProfileState;
import com.intellij.execution.filters.ExceptionFilter;
import com.intellij.execution.filters.TextConsoleBuilder;
@@ -1738,11 +1739,14 @@ public abstract class DebugProcessImpl implements DebugProcess {
// propagate exception only in case we succeded to obtain execution result,
// otherwise it the error is induced by the fact that there is nothing to debug, and there is no need to show
// this problem to the user
- SwingUtilities.invokeLater(new Runnable() {
- public void run() {
- ExecutionUtil.handleExecutionError(myProject, state.getRunnerSettings().getRunProfile(), e);
- }
- });
+ final RunProfile runProfile = state.getRunnerSettings().getRunProfile();
+ if (runProfile != null) {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ ExecutionUtil.handleExecutionError(myProject, runProfile, e);
+ }
+ });
+ }
}
break;
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebuggerManagerThreadImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebuggerManagerThreadImpl.java
index 1c46a54fbc32..416d63e8f8ae 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/DebuggerManagerThreadImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebuggerManagerThreadImpl.java
@@ -99,44 +99,31 @@ public class DebuggerManagerThreadImpl extends InvokeAndWaitThread
- * Note: if old thread is working and InterruptedException is not thrown
- * command will continue execution in old thread simulteniously with
- * commands in new thread
- *
- * use very carefully!
- */
-
- public void terminateCommand(final DebuggerCommandImpl command) {
- if (command == myEvents.getCurrentEvent()) {
- getCurrentRequest().interrupt();
- try {
- getCurrentRequest().join(RESTART_TIMEOUT);
- }
- catch (Exception e) {
- throw new RuntimeException(e);
- }
- startNewWorkerThread();
+ }, terminateTimeout);
}
}
- public DebuggerCommandImpl getCurrentCommand() {
- return myEvents.getCurrentEvent();
- }
-
public void processEvent(@NotNull DebuggerCommandImpl managerCommand) {
assertIsManagerThread();
diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java
index 4b574dfa9727..2da2f7f70b1a 100644
--- a/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/impl/DebuggerManagerImpl.java
@@ -35,6 +35,7 @@ import com.intellij.execution.process.ProcessAdapter;
import com.intellij.execution.process.ProcessEvent;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.runners.ProgramRunner;
+import com.intellij.openapi.Disposable;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.colors.EditorColorsListener;
@@ -50,7 +51,6 @@ import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.WriteExternalException;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.openapi.Disposable;
import com.intellij.psi.PsiClass;
import com.intellij.util.EventDispatcher;
import com.intellij.util.Function;
@@ -488,10 +488,10 @@ public class DebuggerManagerImpl extends DebuggerManagerEx {
return true;
}
- if (ApplicationManager.getApplication().isUnitTestMode()) {
+ //if (ApplicationManager.getApplication().isUnitTestMode()) {
// need this in unit tests to avoid false alarms when comparing actual output with expected output
- return true;
- }
+ //return true;
+ //}
final String version = JdkUtil.getJdkMainAttribute(jdk, Attributes.Name.IMPLEMENTATION_VERSION);
return version == null ||
diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/HotSwapManager.java b/java/debugger/impl/src/com/intellij/debugger/impl/HotSwapManager.java
index f7289ea7ad7e..647c6e9f6054 100644
--- a/java/debugger/impl/src/com/intellij/debugger/impl/HotSwapManager.java
+++ b/java/debugger/impl/src/com/intellij/debugger/impl/HotSwapManager.java
@@ -36,7 +36,6 @@ import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NotNull;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
@@ -132,18 +131,18 @@ public class HotSwapManager extends AbstractProjectComponent {
swapProgress.setCancelWorker(new Runnable() {
public void run() {
- scanClassesCommand.terminate();
+ scanClassesCommand.cancel();
}
});
- for (Iterator iterator = sessions.iterator(); iterator.hasNext();) {
- final DebuggerSession debuggerSession = iterator.next();
- if(debuggerSession.isAttached()) {
+ for (final DebuggerSession debuggerSession : sessions) {
+ if (debuggerSession.isAttached()) {
scanClassesCommand.addCommand(debuggerSession.getProcess(), new DebuggerCommandImpl() {
protected void action() throws Exception {
swapProgress.setDebuggerSession(debuggerSession);
- HashMap sessionClasses = getInstance(swapProgress.getProject()).getModifiedClasses(debuggerSession, swapProgress);
- if(!sessionClasses.isEmpty()) {
+ HashMap sessionClasses =
+ getInstance(swapProgress.getProject()).getModifiedClasses(debuggerSession, swapProgress);
+ if (!sessionClasses.isEmpty()) {
modifiedClasses.put(debuggerSession, sessionClasses);
}
}
@@ -162,16 +161,17 @@ public class HotSwapManager extends AbstractProjectComponent {
reloadClassesProgress.setCancelWorker(new Runnable() {
public void run() {
- reloadClassesCommand.terminate();
+ reloadClassesCommand.cancel();
}
});
- for (Iterator iterator = modifiedClasses.keySet().iterator(); iterator.hasNext();) {
- final DebuggerSession debuggerSession = iterator.next();
+ for (final DebuggerSession debuggerSession : modifiedClasses.keySet()) {
reloadClassesCommand.addCommand(debuggerSession.getProcess(), new DebuggerCommandImpl() {
protected void action() throws Exception {
reloadClassesProgress.setDebuggerSession(debuggerSession);
- getInstance(reloadClassesProgress.getProject()).reloadClasses(debuggerSession, modifiedClasses.get(debuggerSession), reloadClassesProgress);
+ getInstance(reloadClassesProgress.getProject()).reloadClasses(
+ debuggerSession, modifiedClasses.get(debuggerSession), reloadClassesProgress
+ );
}
});
}
diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/InvokeThread.java b/java/debugger/impl/src/com/intellij/debugger/impl/InvokeThread.java
index 6848a3f3450b..5faf11a1f930 100644
--- a/java/debugger/impl/src/com/intellij/debugger/impl/InvokeThread.java
+++ b/java/debugger/impl/src/com/intellij/debugger/impl/InvokeThread.java
@@ -121,15 +121,19 @@ public abstract class InvokeThread {
workerRequest.setRequestFuture( ApplicationManager.getApplication().executeOnPooledThread(workerRequest) );
}
- public void run(WorkerThreadRequest current) {
+ public void run(WorkerThreadRequest threadRequest) {
while(true) {
try {
- if(current.isInterrupted()) {
+ if(threadRequest.isInterrupted()) {
break;
}
- if(getCurrentRequest() != current) {
- LOG.error("Expected " + current + " instead of " + getCurrentRequest());
+ final WorkerThreadRequest currentRequest = getCurrentRequest();
+ if(currentRequest != threadRequest) {
+ LOG.error("Expected " + threadRequest + " instead of " + currentRequest);
+ if (currentRequest != null && !currentRequest.isDone()) {
+ continue; // ensure events are processed by one thread at a time
+ }
}
processEvent(myEvents.get());
diff --git a/java/debugger/impl/src/com/intellij/debugger/impl/MultiProcessCommand.java b/java/debugger/impl/src/com/intellij/debugger/impl/MultiProcessCommand.java
index 3c9f55966f96..ea3d4799fd7c 100644
--- a/java/debugger/impl/src/com/intellij/debugger/impl/MultiProcessCommand.java
+++ b/java/debugger/impl/src/com/intellij/debugger/impl/MultiProcessCommand.java
@@ -15,44 +15,31 @@
*/
package com.intellij.debugger.impl;
-import com.intellij.debugger.engine.DebugProcess;
import com.intellij.debugger.engine.DebugProcessImpl;
import com.intellij.debugger.engine.events.DebuggerCommandImpl;
-import com.intellij.debugger.engine.managerThread.DebuggerCommand;
import com.intellij.openapi.util.Pair;
-import java.util.List;
import java.util.ArrayList;
-import java.util.Iterator;
+import java.util.List;
public class MultiProcessCommand implements Runnable{
private final List> myCommands = new ArrayList>();
public void run() {
- for(;;) {
+ while(true) {
Pair pair;
-
synchronized(myCommands) {
- if(myCommands.isEmpty()) break;
-
- pair = myCommands.get(0);
+ if(myCommands.isEmpty()) {
+ break;
+ }
+ pair = myCommands.remove(0);
}
-
pair.getFirst().getManagerThread().invokeAndWait(pair.getSecond());
-
- synchronized(myCommands) {
- if(myCommands.isEmpty()) break;
-
- myCommands.remove(0);
- }
}
}
- public void terminate() {
+ public void cancel() {
synchronized(myCommands) {
- if(myCommands.isEmpty()) return;
- Pair pair = myCommands.get(0);
- pair.getFirst().getManagerThread().terminateCommand(pair.getSecond());
myCommands.clear();
}
}
diff --git a/java/execution/impl/src/com/intellij/execution/applet/AppletConfigurationProducer.java b/java/execution/impl/src/com/intellij/execution/applet/AppletConfigurationProducer.java
index 4c6706faf070..1c10dbb303b3 100644
--- a/java/execution/impl/src/com/intellij/execution/applet/AppletConfigurationProducer.java
+++ b/java/execution/impl/src/com/intellij/execution/applet/AppletConfigurationProducer.java
@@ -103,8 +103,8 @@ public class AppletConfigurationProducer extends JavaRuntimeConfigurationProduce
@Override
protected RunnerAndConfigurationSettings findExistingByElement(Location location,
- @NotNull RunnerAndConfigurationSettings[] existingConfigurations
- ) {
+ @NotNull RunnerAndConfigurationSettings[] existingConfigurations,
+ ConfigurationContext context) {
final PsiClass aClass = getAppletClass(location.getPsiElement(), PsiManager.getInstance(location.getProject()));
if (aClass != null) {
for (RunnerAndConfigurationSettings existingConfiguration : existingConfigurations) {
diff --git a/java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurationProducer.java b/java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurationProducer.java
index e57da79ece4c..8716509e92d4 100644
--- a/java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurationProducer.java
+++ b/java/execution/impl/src/com/intellij/execution/application/ApplicationConfigurationProducer.java
@@ -89,8 +89,8 @@ public class ApplicationConfigurationProducer extends JavaRuntimeConfigurationPr
@Override
protected RunnerAndConfigurationSettings findExistingByElement(Location location,
- @NotNull RunnerAndConfigurationSettings[] existingConfigurations
- ) {
+ @NotNull RunnerAndConfigurationSettings[] existingConfigurations,
+ ConfigurationContext context) {
final PsiClass aClass = ApplicationConfigurationType.getMainClass(location.getPsiElement());
if (aClass == null) {
return null;
diff --git a/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java b/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java
index 05f038b3b55a..5e369700c2c5 100644
--- a/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java
@@ -16,6 +16,7 @@
package com.intellij.codeInsight;
import com.intellij.codeInsight.completion.JavaCompletionUtil;
+import com.intellij.lang.Language;
import com.intellij.lang.StdLanguages;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
@@ -71,10 +72,11 @@ public class CodeInsightUtil {
@NotNull
public static PsiElement[] findStatementsInRange(@NotNull PsiFile file, int startOffset, int endOffset) {
+ Language language = findJavaOrLikeLanguage(file);
+ if (language == null) return PsiElement.EMPTY_ARRAY;
FileViewProvider viewProvider = file.getViewProvider();
- if (!viewProvider.getLanguages().contains(StdLanguages.JAVA)) return PsiElement.EMPTY_ARRAY;
- PsiElement element1 = viewProvider.findElementAt(startOffset, StdLanguages.JAVA);
- PsiElement element2 = viewProvider.findElementAt(endOffset - 1, StdLanguages.JAVA);
+ PsiElement element1 = viewProvider.findElementAt(startOffset, language);
+ PsiElement element2 = viewProvider.findElementAt(endOffset - 1, language);
if (element1 instanceof PsiWhiteSpace) {
startOffset = element1.getTextRange().getEndOffset();
element1 = file.findElementAt(startOffset);
@@ -148,6 +150,18 @@ public class CodeInsightUtil {
return array.toArray(new PsiElement[array.size()]);
}
+ @Nullable
+ public static Language findJavaOrLikeLanguage(@NotNull final PsiFile file) {
+ final Set languages = file.getViewProvider().getLanguages();
+ for (final Language language : languages) {
+ if (language == StdLanguages.JAVA) return language;
+ }
+ for (final Language language : languages) {
+ if (language.isKindOf(StdLanguages.JAVA)) return language;
+ }
+ return null;
+ }
+
public static void sortIdenticalShortNameClasses(PsiClass[] classes, @NotNull PsiElement context) {
if (classes.length <= 1) return;
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java b/java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java
index 0c30d28b266b..e7b76bbea611 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java
@@ -146,6 +146,17 @@ public class AllClassesGetter {
public void getClasses(final PsiElement context, final CompletionResultSet set, final int offset, final boolean filterByScope) {
if (context == null || !context.isValid()) return;
+ final boolean lookingForAnnotations = PsiJavaPatterns.psiElement().afterLeaf("@").accepts(context);
+ getClasses(context, set, offset, filterByScope, lookingForAnnotations);
+ }
+
+ public void getClasses(final PsiElement context,
+ final CompletionResultSet set,
+ final int offset,
+ final boolean filterByScope,
+ final boolean lookingForAnnotations) {
+ if (context == null || !context.isValid()) return;
+
final String packagePrefix = getPackagePrefix(context, offset);
final Set qnames = new THashSet();
@@ -157,8 +168,6 @@ public class AllClassesGetter {
});
final PrefixMatcher prefixMatcher = set.getPrefixMatcher();
- final boolean lookingForAnnotations = PsiJavaPatterns.psiElement().afterLeaf("@").accepts(context);
-
AllClassesSearch.search(scope, context.getProject(), new Condition() {
public boolean value(String s) {
return prefixMatcher.prefixMatches(s);
diff --git a/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java b/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java
index f28ab0552830..79e37f578cce 100644
--- a/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java
+++ b/java/java-impl/src/com/intellij/find/findUsages/JavaFindUsagesHandler.java
@@ -439,7 +439,7 @@ public class JavaFindUsagesHandler extends FindUsagesHandler{
}
final PsiClass methodClass = method.getContainingClass();
if (methodClass != null && manager.areElementsEquivalent(methodClass, aClass)){
- addMethodUsages(methods[i], results, options, options.searchScope);
+ addElementUsages(methods[i], results, options);
}
else{
boolean strictSignatureSearch = !options.isIncludeOverloadUsages;
@@ -453,9 +453,8 @@ public class JavaFindUsagesHandler extends FindUsagesHandler{
}
}
else {
- PsiMethod[] methods = aClass.getMethods();
- for (PsiMethod method : methods) {
- addMethodUsages(method, results, options, options.searchScope);
+ for (PsiMethod method : aClass.getMethods()) {
+ addElementUsages(method, results, options);
}
}
}
@@ -580,21 +579,10 @@ public class JavaFindUsagesHandler extends FindUsagesHandler{
}
}
- public static void addElementUsages(final PsiElement element, final Processor results, final FindUsagesOptions options) {
- if (element instanceof PsiMethod){
- addMethodUsages((PsiMethod)element, results, options, options.searchScope);
- }
- else {
- ReferencesSearch.search(element, options.searchScope, false).forEach(new ReadActionProcessor() {
- public boolean processInReadAction(final PsiReference ref) {
- return addResult(results, ref, options, element);
- }
- });
- }
- }
-
- private static void addMethodUsages(final PsiMethod method, final Processor result, final FindUsagesOptions options, SearchScope searchScope) {
- if (method.isConstructor()) {
+ public static void addElementUsages(final PsiElement element, final Processor result, final FindUsagesOptions options) {
+ final SearchScope searchScope = options.searchScope;
+ if (element instanceof PsiMethod && ((PsiMethod)element).isConstructor()){
+ PsiMethod method = (PsiMethod)element;
if (options.isIncludeOverloadUsages) {
for (PsiMethod constructor : method.getContainingClass().getConstructors()) {
addConstructorUsages(constructor, searchScope, result, options);
@@ -603,14 +591,24 @@ public class JavaFindUsagesHandler extends FindUsagesHandler{
else {
addConstructorUsages(method, searchScope, result, options);
}
+ return;
}
- else {
- boolean strictSignatureSearch = !options.isIncludeOverloadUsages;
- MethodReferencesSearch.search(method, searchScope, strictSignatureSearch).forEach(new PsiReferenceProcessorAdapter(new PsiReferenceProcessor() {
- public boolean execute(PsiReference ref) {
- return addResult(result, ref, options, method);
- }
- }));
+
+ final ReadActionProcessor consumer = new ReadActionProcessor() {
+ public boolean processInReadAction(final PsiReference ref) {
+ return addResult(result, ref, options, element);
+ }
+ };
+
+ if (options.fastTrack != null) {
+ SearchRequestor.collectRequests(element, options, options.fastTrack);
+ return;
+ }
+
+ if (element instanceof PsiMethod) {
+ MethodReferencesSearch.search((PsiMethod)element, searchScope, !options.isIncludeOverloadUsages).forEach(consumer);
+ } else {
+ ReferencesSearch.search(element, searchScope, false).forEach(consumer);
}
}
diff --git a/java/java-impl/src/com/intellij/psi/NonClasspathClassFinder.java b/java/java-impl/src/com/intellij/psi/NonClasspathClassFinder.java
index ca17db61386f..4583c530df75 100644
--- a/java/java-impl/src/com/intellij/psi/NonClasspathClassFinder.java
+++ b/java/java-impl/src/com/intellij/psi/NonClasspathClassFinder.java
@@ -73,8 +73,8 @@ public abstract class NonClasspathClassFinder extends PsiElementFinder {
List result = new ArrayList();
for (final VirtualFile classRoot : classRoots) {
if (scope.contains(classRoot)) {
- final String pkgName = psiPackage.getName();
- final VirtualFile dir = pkgName != null ? classRoot.findFileByRelativePath(pkgName.replace('.', '/')) : classRoot;
+ final String pkgName = psiPackage.getQualifiedName();
+ final VirtualFile dir = classRoot.findFileByRelativePath(pkgName.replace('.', '/'));
if (dir != null && dir.isDirectory()) {
for (final VirtualFile file : dir.getChildren()) {
if (!file.isDirectory()) {
@@ -121,8 +121,8 @@ public abstract class NonClasspathClassFinder extends PsiElementFinder {
List result = new ArrayList();
for (final VirtualFile classRoot : classRoots) {
if (scope.contains(classRoot)) {
- final String pkgName = psiPackage.getName();
- final VirtualFile dir = pkgName != null ? classRoot.findFileByRelativePath(pkgName.replace('.', '/')) : classRoot;
+ final String pkgName = psiPackage.getQualifiedName();
+ final VirtualFile dir = classRoot.findFileByRelativePath(pkgName.replace('.', '/'));
if (dir != null && dir.isDirectory()) {
for (final VirtualFile file : dir.getChildren()) {
if (file.isDirectory()) {
diff --git a/java/java-impl/src/com/intellij/psi/impl/search/MethodTextOccurenceProcessor.java b/java/java-impl/src/com/intellij/psi/impl/search/MethodTextOccurenceProcessor.java
index 651ddf81cf6c..e9dc0a5b75e3 100644
--- a/java/java-impl/src/com/intellij/psi/impl/search/MethodTextOccurenceProcessor.java
+++ b/java/java-impl/src/com/intellij/psi/impl/search/MethodTextOccurenceProcessor.java
@@ -16,7 +16,7 @@
package com.intellij.psi.impl.search;
import com.intellij.psi.*;
-import com.intellij.psi.search.TextOccurenceProcessor;
+import com.intellij.psi.search.RequestResultProcessor;
import com.intellij.psi.util.MethodSignature;
import com.intellij.psi.util.MethodSignatureUtil;
import com.intellij.psi.util.TypeConversionUtil;
@@ -26,62 +26,53 @@ import org.jetbrains.annotations.NotNull;
/**
* @author peter
*/
-public class MethodTextOccurenceProcessor implements TextOccurenceProcessor {
+public class MethodTextOccurenceProcessor extends RequestResultProcessor {
private final PsiMethod[] myMethods;
- private final Processor myConsumer;
private final PsiClass myContainingClass;
private final boolean myStrictSignatureSearch;
- public MethodTextOccurenceProcessor(final Processor consumer,
- @NotNull final PsiClass aClass,
- final boolean strictSignatureSearch,
- final PsiMethod... methods) {
+ public MethodTextOccurenceProcessor(@NotNull final PsiClass aClass, final boolean strictSignatureSearch, final PsiMethod... methods) {
myMethods = methods;
- myConsumer = consumer;
myContainingClass = aClass;
myStrictSignatureSearch = strictSignatureSearch;
}
- public boolean execute(PsiElement element, int offsetInElement) {
- final PsiReference[] refs = element.getReferences();
- for (PsiReference ref : refs) {
- if (ReferenceRange.containsOffsetInElement(ref, offsetInElement)) {
- for (PsiMethod method : myMethods) {
- if (!method.isValid()) {
- continue;
- }
+ @Override
+ protected boolean processReference(Processor consumer, PsiReference ref) {
+ for (PsiMethod method : myMethods) {
+ if (!method.isValid()) {
+ continue;
+ }
- if (ref instanceof ResolvingHint && !((ResolvingHint)ref).canResolveTo(method)) {
- return true;
- }
- if (ref.isReferenceTo(method)) {
- return myConsumer.process(ref);
- }
- PsiElement refElement = ref.resolve();
+ if (ref instanceof ResolvingHint && !((ResolvingHint)ref).canResolveTo(method)) {
+ return true;
+ }
+ if (ref.isReferenceTo(method)) {
+ return consumer.process(ref);
+ }
+ PsiElement refElement = ref.resolve();
- if (refElement instanceof PsiMethod) {
- PsiMethod refMethod = (PsiMethod)refElement;
- PsiClass refMethodClass = refMethod.getContainingClass();
- if (refMethodClass == null) continue;
+ if (refElement instanceof PsiMethod) {
+ PsiMethod refMethod = (PsiMethod)refElement;
+ PsiClass refMethodClass = refMethod.getContainingClass();
+ if (refMethodClass == null) continue;
- if (!refMethod.hasModifierProperty(PsiModifier.STATIC)) {
- PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(myContainingClass, refMethodClass, PsiSubstitutor.EMPTY);
- if (substitutor != null) {
- MethodSignature superSignature = method.getSignature(substitutor);
- MethodSignature refSignature = refMethod.getSignature(PsiSubstitutor.EMPTY);
+ if (!refMethod.hasModifierProperty(PsiModifier.STATIC)) {
+ PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(myContainingClass, refMethodClass, PsiSubstitutor.EMPTY);
+ if (substitutor != null) {
+ MethodSignature superSignature = method.getSignature(substitutor);
+ MethodSignature refSignature = refMethod.getSignature(PsiSubstitutor.EMPTY);
- if (MethodSignatureUtil.isSubsignature(superSignature, refSignature)) {
- if (!myConsumer.process(ref)) return false;
- }
- }
+ if (MethodSignatureUtil.isSubsignature(superSignature, refSignature)) {
+ if (!consumer.process(ref)) return false;
}
+ }
+ }
- if (!myStrictSignatureSearch) {
- PsiManager manager = method.getManager();
- if (manager.areElementsEquivalent(refMethodClass, myContainingClass)) {
- if (!myConsumer.process(ref)) return false;
- }
- }
+ if (!myStrictSignatureSearch) {
+ PsiManager manager = method.getManager();
+ if (manager.areElementsEquivalent(refMethodClass, myContainingClass)) {
+ if (!consumer.process(ref)) return false;
}
}
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java b/java/java-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java
index 5404edf9de36..b1afc09a7838 100644
--- a/java/java-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java
+++ b/java/java-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java
@@ -3,17 +3,11 @@
*/
package com.intellij.psi.impl.search;
+import com.intellij.find.findUsages.FindUsagesOptions;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.application.ReadActionProcessor;
-import com.intellij.openapi.extensions.Extensions;
-import com.intellij.openapi.fileTypes.StdFileTypes;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.search.*;
import com.intellij.psi.search.searches.MethodReferencesSearch;
-import com.intellij.psi.search.searches.ReferencesSearch;
-import com.intellij.psi.util.PropertyUtil;
import com.intellij.util.Processor;
import com.intellij.util.QueryExecutor;
import org.jetbrains.annotations.NotNull;
@@ -21,103 +15,102 @@ import org.jetbrains.annotations.NotNull;
/**
* @author max
*/
-public class MethodUsagesSearcher implements QueryExecutor {
+public class MethodUsagesSearcher extends SearchRequestor implements QueryExecutor {
+
public boolean execute(final MethodReferencesSearch.SearchParameters p, final Processor consumer) {
- final PsiMethod method = p.getMethod();
- final SearchScope searchScope = p.getScope();
- final PsiManager psiManager = PsiManager.getInstance(method.getProject());
- final boolean isStrictSignatureSearch = p.isStrictSignatureSearch();
-
- final PsiClass aClass = ApplicationManager.getApplication().runReadAction(new Computable() {
- public PsiClass compute() {
- return method.getContainingClass();
- }
- });
- if (aClass == null) return true;
-
- if (method.isConstructor()) {
- final ConstructorReferencesSearchHelper helper = new ConstructorReferencesSearchHelper(psiManager);
- if (!helper.processConstructorReferences(consumer, method, searchScope, !isStrictSignatureSearch, isStrictSignatureSearch)) {
- return false;
- }
+ if (p instanceof MySearchParameters) {
+ return true;
}
- boolean needStrictSignatureSearch = ApplicationManager.getApplication().runReadAction(new Computable() {
- public Boolean compute() {
- return method.isValid() && isStrictSignatureSearch && (aClass instanceof PsiAnonymousClass
- || aClass.hasModifierProperty(PsiModifier.FINAL)
- || method.hasModifierProperty(PsiModifier.STATIC)
- || method.hasModifierProperty(PsiModifier.FINAL)
- || method.hasModifierProperty(PsiModifier.PRIVATE));
+ final PsiMethod method = p.getMethod();
+ final SearchRequestCollector collector = new SearchRequestCollector();
+
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ public void run() {
+ final FindUsagesOptions options = new MyFindUsagesOptions(p);
+ options.isUsages = true;
+ contributeSearchTargets(method, options, collector, p.isStrictSignatureSearch());
+ SearchRequestor.collectRequests(method, options, collector);
}
- }).booleanValue();
- if (needStrictSignatureSearch) {
- return ReferencesSearch.search(method, searchScope, false).forEach(new ReadActionProcessor() {
- public boolean processInReadAction(final PsiReference psiReference) {
- return consumer.process(psiReference);
+ });
+
+ return method.getManager().getSearchHelper().processRequests(collector, consumer);
+ }
+
+ @Override
+ public void contributeRequests(@NotNull PsiElement target,
+ @NotNull final FindUsagesOptions options,
+ @NotNull SearchRequestCollector collector) {
+ if (options instanceof MyFindUsagesOptions) {
+ return;
+ }
+
+ if (target instanceof PsiMethod) {
+ final boolean strictSignatureSearch = !options.isIncludeOverloadUsages;
+ final PsiMethod method = (PsiMethod)target;
+ contributeSearchTargets(method, options, collector, strictSignatureSearch);
+ collector.searchCustom(new Processor>() {
+ public boolean process(Processor processor) {
+ return MethodReferencesSearch.search(new MySearchParameters(method, options, strictSignatureSearch)).forEach(processor);
+ }
+ });
+ }
+ }
+
+ private static void contributeSearchTargets(@NotNull final PsiMethod method,
+ @NotNull FindUsagesOptions options,
+ @NotNull SearchRequestCollector collector,
+ final boolean strictSignatureSearch) {
+ final SearchScope searchScope = options.searchScope;
+
+ final PsiManager psiManager = PsiManager.getInstance(method.getProject());
+
+ final PsiClass aClass = method.getContainingClass();
+ if (aClass == null) return;
+
+ if (method.isConstructor()) {
+ collector.searchCustom(new Processor>() {
+ public boolean process(Processor consumer) {
+ return new ConstructorReferencesSearchHelper(psiManager).
+ processConstructorReferences(consumer, method, searchScope, !strictSignatureSearch, strictSignatureSearch);
}
});
}
+ boolean needStrictSignatureSearch = method.isValid() && strictSignatureSearch && (aClass instanceof PsiAnonymousClass
+ || aClass.hasModifierProperty(PsiModifier.FINAL)
+ || method.hasModifierProperty(PsiModifier.STATIC)
+ || method.hasModifierProperty(PsiModifier.FINAL)
+ || method.hasModifierProperty(PsiModifier.PRIVATE));
+ if (needStrictSignatureSearch) {
+ // CacheBasedRefSearcher deals with that
+ return;
+ }
+
final String textToSearch = method.getName();
- final PsiMethod[] methods = isStrictSignatureSearch ? new PsiMethod[]{method} : getOverloads(method);
+ final PsiMethod[] methods = strictSignatureSearch ? new PsiMethod[]{method} : aClass.findMethodsByName(textToSearch, false);
- SearchScope accessScope = ApplicationManager.getApplication().runReadAction(new Computable() {
- public SearchScope compute() {
- if (!method.isValid()) return searchScope;
- SearchScope accessScope = methods[0].getUseScope();
- for (int i = 1; i < methods.length; i++) {
- PsiMethod method1 = methods[i];
- accessScope = accessScope.union(method1.getUseScope());
- }
- return accessScope;
- }
- });
-
- final TextOccurenceProcessor processor1 = new MethodTextOccurenceProcessor(consumer, aClass, isStrictSignatureSearch, methods);
+ SearchScope accessScope = methods[0].getUseScope();
+ for (int i = 1; i < methods.length; i++) {
+ PsiMethod method1 = methods[i];
+ accessScope = accessScope.union(method1.getUseScope());
+ }
final SearchScope restrictedByAccess = searchScope.intersectWith(accessScope);
short searchContext = UsageSearchContext.IN_CODE | UsageSearchContext.IN_COMMENTS | UsageSearchContext.IN_FOREIGN_LANGUAGES;
- PsiSearchHelper helper = psiManager.getSearchHelper();
- if (!helper.processElementsWithWord(processor1, restrictedByAccess, textToSearch, searchContext, true)) return false;
+ collector.searchWord(textToSearch, restrictedByAccess, searchContext, true, new MethodTextOccurenceProcessor(aClass, strictSignatureSearch, methods));
+ }
- final String propertyName = ApplicationManager.getApplication().runReadAction(new Computable(){
- public String compute() {
- if (!method.isValid()) return null;
- return PropertyUtil.getPropertyName(method);
- }
- });
- if (StringUtil.isEmpty(propertyName)) {
- return true;
+ private static class MySearchParameters extends MethodReferencesSearch.SearchParameters {
+ public MySearchParameters(PsiMethod method, FindUsagesOptions options, boolean strictSignatureSearch) {
+ super(method, options.searchScope, strictSignatureSearch);
}
- final SearchScope scope = ApplicationManager.getApplication().runReadAction(new Computable() {
- public SearchScope compute() {
- SearchScope additional = GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.allScope(psiManager.getProject()),
- StdFileTypes.JSP, StdFileTypes.JSPX,
- StdFileTypes.XML, StdFileTypes.XHTML);
-
- for (CustomPropertyScopeProvider provider : Extensions.getExtensions(CustomPropertyScopeProvider.EP_NAME)) {
- SearchScope s = provider.getScope(psiManager.getProject());
- additional = additional.union(s);
- }
-
- return restrictedByAccess.intersectWith(additional);
- }
- });
- return helper.processElementsWithWord(processor1, scope, propertyName, UsageSearchContext.IN_FOREIGN_LANGUAGES, true);
}
- @NotNull
- private static PsiMethod[] getOverloads(final PsiMethod method) {
- return ApplicationManager.getApplication().runReadAction(new Computable() {
- public PsiMethod[] compute() {
- if (!method.isValid()) return PsiMethod.EMPTY_ARRAY;
- PsiClass aClass = method.getContainingClass();
- if (aClass == null) return new PsiMethod[]{method};
- return aClass.findMethodsByName(method.getName(), false);
- }
- });
+ private static class MyFindUsagesOptions extends FindUsagesOptions {
+ public MyFindUsagesOptions(MethodReferencesSearch.SearchParameters p) {
+ super(p.getScope());
+ }
}
-
}
diff --git a/java/java-impl/src/com/intellij/psi/impl/search/SimpleAccessorReferenceSearcher.java b/java/java-impl/src/com/intellij/psi/impl/search/SimpleAccessorReferenceSearcher.java
index 0eaf74716fad..be7594cdc0d1 100644
--- a/java/java-impl/src/com/intellij/psi/impl/search/SimpleAccessorReferenceSearcher.java
+++ b/java/java-impl/src/com/intellij/psi/impl/search/SimpleAccessorReferenceSearcher.java
@@ -15,63 +15,42 @@
*/
package com.intellij.psi.impl.search;
-import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.find.findUsages.FindUsagesOptions;
+import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileTypes.StdFileTypes;
-import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.*;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
import com.intellij.psi.search.*;
-import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.util.PropertyUtil;
-import com.intellij.util.Processor;
-import com.intellij.util.QueryExecutor;
+import org.jetbrains.annotations.NotNull;
/**
* @author ven
*/
-public class SimpleAccessorReferenceSearcher implements QueryExecutor {
- public boolean execute(final ReferencesSearch.SearchParameters queryParameters, final Processor consumer) {
- final PsiElement refElement = queryParameters.getElementToSearch();
- if (!(refElement instanceof PsiMethod)) return true;
+public class SimpleAccessorReferenceSearcher extends SearchRequestor {
+
+ @Override
+ public void contributeRequests(@NotNull final PsiElement refElement,
+ @NotNull FindUsagesOptions options,
+ @NotNull SearchRequestCollector collector) {
+ if (!(refElement instanceof PsiMethod)) return;
+
final PsiMethod method = (PsiMethod)refElement;
- final String propertyName = ApplicationManager.getApplication().runReadAction(new Computable() {
- public String compute() {
- if (!method.isValid()) return null;
- return PropertyUtil.getPropertyName(method);
+
+ final String propertyName = PropertyUtil.getPropertyName(method);
+ if (StringUtil.isNotEmpty(propertyName)) {
+ SearchScope additional = GlobalSearchScope.getScopeRestrictedByFileTypes(GlobalSearchScope.allScope(method.getProject()),
+ StdFileTypes.JSP, StdFileTypes.JSPX,
+ StdFileTypes.XML, StdFileTypes.XHTML);
+
+ for (CustomPropertyScopeProvider provider : Extensions.getExtensions(CustomPropertyScopeProvider.EP_NAME)) {
+ additional = additional.union(provider.getScope(method.getProject()));
}
- });
- if (StringUtil.isEmptyOrSpaces(propertyName)) {
- return true;
+ assert propertyName != null;
+ final SearchScope propScope = options.searchScope.intersectWith(method.getUseScope()).intersectWith(additional);
+ collector.searchWord(propertyName, propScope, UsageSearchContext.IN_FOREIGN_LANGUAGES, true, refElement);
}
- SearchScope searchScope = ApplicationManager.getApplication().runReadAction(new Computable() {
- public SearchScope compute() {
- SearchScope searchScope = queryParameters.getEffectiveSearchScope();
- if (searchScope instanceof GlobalSearchScope) {
- searchScope = GlobalSearchScope.getScopeRestrictedByFileTypes((GlobalSearchScope)searchScope,
- StdFileTypes.JSP,
- StdFileTypes.JSPX,
- StdFileTypes.XML,
- StdFileTypes.XHTML);
- }
- return searchScope;
- }
- });
- final PsiSearchHelper helper = PsiManager.getInstance(refElement.getProject()).getSearchHelper();
- final TextOccurenceProcessor processor = new TextOccurenceProcessor() {
- public boolean execute(PsiElement element, int offsetInElement) {
- final PsiReference[] refs = element.getReferences();
- for (PsiReference ref : refs) {
- if (ReferenceRange.containsOffsetInElement(ref, offsetInElement)) {
- if (ref.isReferenceTo(refElement)) {
- return consumer.process(ref);
- }
- }
- }
- return true;
- }
- };
-
- return helper.processElementsWithWord(processor, searchScope, propertyName, UsageSearchContext.IN_FOREIGN_LANGUAGES, false);
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java
index 4bc6ba351d5e..8a3d350c78fb 100644
--- a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java
@@ -15,6 +15,7 @@
*/
package com.intellij.refactoring.rename;
+import com.intellij.lang.StdLanguages;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
@@ -133,7 +134,7 @@ public class RenameJavaVariableProcessor extends RenameJavaMemberProcessor {
}
public void prepareRenaming(final PsiElement element, final String newName, final Map allRenames) {
- if (element instanceof PsiField) {
+ if (element instanceof PsiField && StdLanguages.JAVA.equals(element.getLanguage())) {
prepareFieldRenaming((PsiField)element, newName, allRenames);
}
}
diff --git a/java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java b/java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java
index 6fd5ff28eedf..a79be5cf89d4 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java
@@ -289,6 +289,9 @@ public class InlineUtil {
PsiElement resolved = resolveResult.getElement();
if (resolved instanceof PsiTypeParameter) {
PsiType newType = resolveResult.getSubstitutor().putAll(substitutor).substitute((PsiTypeParameter)resolved);
+ if (newType == null) {
+ newType = PsiType.getJavaLangObject(resolved.getManager(), resolved.getResolveScope());
+ }
try {
typeElement.replace(factory.createTypeElement(newType));
return;
diff --git a/java/java-tests/testData/refactoring/inlineMethod/RawSubstitution.java b/java/java-tests/testData/refactoring/inlineMethod/RawSubstitution.java
new file mode 100644
index 000000000000..6e7f02ba0686
--- /dev/null
+++ b/java/java-tests/testData/refactoring/inlineMethod/RawSubstitution.java
@@ -0,0 +1,16 @@
+public class NotRaw {
+ T get(T t){
+ T tt = t;
+ if ( t == null) {
+ return null;
+ } else
+ return null;
+ }
+
+}
+
+class Raw extends NotRaw {
+ void foo() {
+ Object o = get(null);
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/inlineMethod/RawSubstitution.java.after b/java/java-tests/testData/refactoring/inlineMethod/RawSubstitution.java.after
new file mode 100644
index 000000000000..3bdbc002fb30
--- /dev/null
+++ b/java/java-tests/testData/refactoring/inlineMethod/RawSubstitution.java.after
@@ -0,0 +1,15 @@
+public class NotRaw {
+
+}
+
+class Raw extends NotRaw {
+ void foo() {
+ Object result;
+ Object tt = null;
+ if ( null == null) {
+ result = null;
+ } else
+ result = null;
+ Object o = result;
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java
index 650c7a70b987..6712233eab3a 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/inline/InlineMethodTest.java
@@ -153,6 +153,10 @@ public class InlineMethodTest extends LightCodeInsightTestCase {
doTest();
}
+ public void testRawSubstitution() throws Exception {
+ doTest();
+ }
+
@Override
protected Sdk getProjectJDK() {
return JavaSdkImpl.getMockJdk15("java 1.5");
diff --git a/java/openapi/src/com/intellij/patterns/PsiJavaPatterns.java b/java/openapi/src/com/intellij/patterns/PsiJavaPatterns.java
index e4dad22a0195..05ca4cf80b70 100644
--- a/java/openapi/src/com/intellij/patterns/PsiJavaPatterns.java
+++ b/java/openapi/src/com/intellij/patterns/PsiJavaPatterns.java
@@ -18,8 +18,11 @@ package com.intellij.patterns;
import com.intellij.psi.*;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.ProcessingContext;
-import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.List;
/**
* @author peter
@@ -55,10 +58,15 @@ public class PsiJavaPatterns extends StandardPatterns{
}
public static PsiJavaElementPattern.Capture psiLiteral(final ElementPattern value) {
- return new PsiJavaElementPattern.Capture(new InitialPatternCondition(PsiLiteral.class) {
+ return new PsiJavaElementPattern.Capture(new InitialPatternConditionPlus(PsiLiteral.class) {
public boolean accepts(@Nullable final Object o, final ProcessingContext context) {
return o instanceof PsiLiteral && (value == null || value.accepts(((PsiLiteral)o).getValue(), context));
}
+
+ @Override
+ public List> getPatterns() {
+ return Collections.>singletonList(value);
+ }
});
}
@@ -78,11 +86,16 @@ public class PsiJavaPatterns extends StandardPatterns{
public static PsiJavaElementPattern.Capture literalExpression(final ElementPattern value) {
- return new PsiJavaElementPattern.Capture(new InitialPatternCondition(PsiLiteralExpression.class) {
+ return new PsiJavaElementPattern.Capture(new InitialPatternConditionPlus(PsiLiteralExpression.class) {
public boolean accepts(@Nullable final Object o, final ProcessingContext context) {
return o instanceof PsiLiteralExpression
&& (value == null || value.accepts(((PsiLiteralExpression)o).getValue(), context));
}
+
+ @Override
+ public List> getPatterns() {
+ return Collections.>singletonList(value);
+ }
});
}
diff --git a/java/openapi/src/com/intellij/psi/search/searches/MethodReferencesSearch.java b/java/openapi/src/com/intellij/psi/search/searches/MethodReferencesSearch.java
index bfa2b88a9947..060dd0ffae5f 100644
--- a/java/openapi/src/com/intellij/psi/search/searches/MethodReferencesSearch.java
+++ b/java/openapi/src/com/intellij/psi/search/searches/MethodReferencesSearch.java
@@ -20,6 +20,7 @@ import com.intellij.psi.PsiReference;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.SearchScope;
import com.intellij.util.Query;
+import gnu.trove.TObjectHashingStrategy;
/**
* @author max
@@ -54,7 +55,12 @@ public class MethodReferencesSearch extends ExtensibleQueryFactory search(final PsiMethod method, SearchScope scope, final boolean strictSignatureSearch) {
- return INSTANCE.createUniqueResultsQuery(new SearchParameters(method, scope, strictSignatureSearch));
+ return search(new SearchParameters(method, scope, strictSignatureSearch));
+ }
+
+ public static Query search(final SearchParameters parameters) {
+ //noinspection unchecked
+ return INSTANCE.createUniqueResultsQuery(parameters, TObjectHashingStrategy.CANONICAL, ReferenceDescriptor.MAPPER);
}
public static Query search(final PsiMethod method, final boolean strictSignatureSearch) {
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestFixture.java b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestFixture.java
index 6565e6ab8413..0e94b11d159f 100644
--- a/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestFixture.java
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestFixture.java
@@ -29,4 +29,7 @@ public interface JavaCodeInsightTestFixture extends CodeInsightTestFixture {
JavaPsiFacade getJavaFacade();
PsiClass addClass(@NotNull @NonNls final String classText) throws IOException;
+
+ @NotNull
+ PsiClass findClass(@NotNull @NonNls String name);
}
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java
index 0b4f2d1180d9..32d51da7a14d 100644
--- a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java
@@ -17,6 +17,7 @@ package com.intellij.testFramework.fixtures.impl;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
+import com.intellij.psi.search.ProjectScope;
import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture;
import com.intellij.testFramework.fixtures.TempDirTestFixture;
@@ -54,5 +55,11 @@ public class JavaCodeInsightTestFixtureImpl extends CodeInsightTestFixtureImpl i
final PsiFile psiFile = addFileToProject(rootPath, qName.replace('.', '/') + ".java", classText);
return ((PsiJavaFile)psiFile).getClasses()[0];
}
-}
+ @NotNull
+ public PsiClass findClass(@NotNull @NonNls final String name) {
+ final PsiClass aClass = getJavaFacade().findClass(name, ProjectScope.getProjectScope(getProject()));
+ assertNotNull("Class " + name + " not found", aClass);
+ return aClass;
+ }
+}
diff --git a/platform/lang-api/src/com/intellij/execution/actions/ConfigurationContext.java b/platform/lang-api/src/com/intellij/execution/actions/ConfigurationContext.java
index 0ad8680e726b..95ea96eaf73a 100644
--- a/platform/lang-api/src/com/intellij/execution/actions/ConfigurationContext.java
+++ b/platform/lang-api/src/com/intellij/execution/actions/ConfigurationContext.java
@@ -106,12 +106,12 @@ public class ConfigurationContext {
if (producers == null) return null;
if (myRuntimeConfiguration != null) {
for (RuntimeConfigurationProducer producer : producers) {
- final RunnerAndConfigurationSettings configuration = producer.findExistingConfiguration(myLocation);
+ final RunnerAndConfigurationSettings configuration = producer.findExistingConfiguration(myLocation, this);
if (configuration != null && configuration.getConfiguration() == myRuntimeConfiguration) return configuration;
}
}
for (RuntimeConfigurationProducer producer : producers) {
- final RunnerAndConfigurationSettings configuration = producer.findExistingConfiguration(myLocation);
+ final RunnerAndConfigurationSettings configuration = producer.findExistingConfiguration(myLocation, this);
if (configuration != null) return configuration;
}
return null;
diff --git a/platform/lang-api/src/com/intellij/execution/actions/PreferedProducerFind.java b/platform/lang-api/src/com/intellij/execution/actions/PreferedProducerFind.java
index 502580dd600f..7725523362d1 100644
--- a/platform/lang-api/src/com/intellij/execution/actions/PreferedProducerFind.java
+++ b/platform/lang-api/src/com/intellij/execution/actions/PreferedProducerFind.java
@@ -116,7 +116,8 @@ class PreferedProducerFind {
@Override
protected RunnerAndConfigurationSettings findExistingByElement(Location location,
- @NotNull RunnerAndConfigurationSettings[] existingConfigurations) {
+ @NotNull RunnerAndConfigurationSettings[] existingConfigurations,
+ ConfigurationContext context) {
if (existingConfigurations.length > 0) {
ConfigurationType type = existingConfigurations[0].getType();
if (type instanceof LocatableConfigurationType) {
diff --git a/platform/lang-api/src/com/intellij/execution/junit/RuntimeConfigurationProducer.java b/platform/lang-api/src/com/intellij/execution/junit/RuntimeConfigurationProducer.java
index bbf73ecb7854..868e98e222ea 100644
--- a/platform/lang-api/src/com/intellij/execution/junit/RuntimeConfigurationProducer.java
+++ b/platform/lang-api/src/com/intellij/execution/junit/RuntimeConfigurationProducer.java
@@ -61,7 +61,7 @@ public abstract class RuntimeConfigurationProducer implements Comparable, Clonea
final RunManager runManager = RunManager.getInstance(context.getProject());
final ConfigurationType type = result.myConfiguration.getType();
final RunnerAndConfigurationSettings[] configurations = runManager.getConfigurationSettings(type);
- final RunnerAndConfigurationSettings configuration = findExistingByElement(_location, configurations);
+ final RunnerAndConfigurationSettings configuration = findExistingByElement(_location, configurations, context);
if (configuration != null) {
result.myConfiguration = configuration;
}
@@ -72,10 +72,10 @@ public abstract class RuntimeConfigurationProducer implements Comparable, Clonea
}
@Nullable
- public RunnerAndConfigurationSettings findExistingConfiguration(@NotNull Location location) {
+ public RunnerAndConfigurationSettings findExistingConfiguration(@NotNull Location location, ConfigurationContext context) {
final RunManager runManager = RunManager.getInstance(location.getProject());
final RunnerAndConfigurationSettings[] configurations = runManager.getConfigurationSettings(getConfigurationType());
- return findExistingByElement(location, configurations);
+ return findExistingByElement(location, configurations, context);
}
public abstract PsiElement getSourceElement();
@@ -89,7 +89,8 @@ public abstract class RuntimeConfigurationProducer implements Comparable, Clonea
@Nullable
protected RunnerAndConfigurationSettings findExistingByElement(final Location location,
- @NotNull final RunnerAndConfigurationSettings[] existingConfigurations) {
+ @NotNull final RunnerAndConfigurationSettings[] existingConfigurations,
+ ConfigurationContext context) {
return null;
}
diff --git a/platform/lang-api/src/com/intellij/patterns/PsiElementPattern.java b/platform/lang-api/src/com/intellij/patterns/PsiElementPattern.java
index de6be8172cea..6f4c943c1653 100644
--- a/platform/lang-api/src/com/intellij/patterns/PsiElementPattern.java
+++ b/platform/lang-api/src/com/intellij/patterns/PsiElementPattern.java
@@ -18,19 +18,21 @@ package com.intellij.patterns;
import com.intellij.lang.ASTNode;
import com.intellij.lang.Language;
import com.intellij.openapi.vfs.VirtualFile;
-import static com.intellij.patterns.PlatformPatterns.psiElement;
-import static com.intellij.patterns.StandardPatterns.collection;
-import static com.intellij.patterns.StandardPatterns.not;
import com.intellij.psi.*;
import com.intellij.psi.meta.PsiMetaData;
import com.intellij.psi.meta.PsiMetaOwner;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
+import com.intellij.util.PairProcessor;
import com.intellij.util.ProcessingContext;
import com.intellij.util.ReflectionCache;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
+import static com.intellij.patterns.PlatformPatterns.psiElement;
+import static com.intellij.patterns.StandardPatterns.collection;
+import static com.intellij.patterns.StandardPatterns.not;
+
/**
* @author peter
*/
@@ -206,11 +208,13 @@ public abstract class PsiElementPattern _withText(final ElementPattern pattern) {
- return new PatternCondition("_withText") {
- public boolean accepts(@NotNull final T t, final ProcessingContext context) {
- return pattern.getCondition().accepts(t.getText(), context);
+ return new PatternConditionPlus("_withText", pattern) {
+ @Override
+ public boolean processValues(T t,
+ ProcessingContext context,
+ PairProcessor processor) {
+ return processor.process(t.getText(), context);
}
-
};
}
diff --git a/platform/lang-api/src/com/intellij/psi/search/PsiSearchHelper.java b/platform/lang-api/src/com/intellij/psi/search/PsiSearchHelper.java
index b50e67181ab3..f8eb7efcf7e9 100644
--- a/platform/lang-api/src/com/intellij/psi/search/PsiSearchHelper.java
+++ b/platform/lang-api/src/com/intellij/psi/search/PsiSearchHelper.java
@@ -18,6 +18,7 @@ package com.intellij.psi.search;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiReference;
import com.intellij.util.Processor;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -175,6 +176,8 @@ public interface PsiSearchHelper {
*/
void processAllFilesWithWordInLiterals(@NotNull String word, @NotNull GlobalSearchScope scope, @NotNull Processor processor);
+ boolean processRequests(@NotNull SearchRequestCollector request, Processor processor);
+
boolean processElementsWithWord(@NotNull TextOccurenceProcessor processor,
@NotNull SearchScope searchScope,
@NotNull String text,
diff --git a/platform/lang-api/src/com/intellij/psi/search/PsiSearchRequest.java b/platform/lang-api/src/com/intellij/psi/search/PsiSearchRequest.java
new file mode 100644
index 000000000000..5e16c40b8c91
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/search/PsiSearchRequest.java
@@ -0,0 +1,28 @@
+package com.intellij.psi.search;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class PsiSearchRequest {
+ public final SearchScope searchScope;
+ public final String word;
+ public final short searchContext;
+ public final boolean caseSensitive;
+ public final RequestResultProcessor processor;
+
+ public PsiSearchRequest(@NotNull SearchScope searchScope,
+ @NotNull String word,
+ short searchContext,
+ boolean caseSensitive,
+ @NotNull RequestResultProcessor processor) {
+
+ this.searchScope = searchScope;
+ this.word = word;
+ this.searchContext = searchContext;
+ this.caseSensitive = caseSensitive;
+ this.processor = processor;
+ }
+
+}
diff --git a/platform/lang-api/src/com/intellij/psi/search/RequestResultProcessor.java b/platform/lang-api/src/com/intellij/psi/search/RequestResultProcessor.java
new file mode 100644
index 000000000000..e73f4431a59c
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/search/RequestResultProcessor.java
@@ -0,0 +1,26 @@
+package com.intellij.psi.search;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.ReferenceRange;
+import com.intellij.util.Processor;
+
+/**
+ * @author peter
+ */
+public abstract class RequestResultProcessor {
+
+ public boolean execute(PsiElement element, int offsetInElement, final Processor consumer) {
+ for (PsiReference ref : element.getReferences()) {
+ if (ReferenceRange.containsOffsetInElement(ref, offsetInElement)) {
+ if (!processReference(consumer, ref)) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ protected abstract boolean processReference(Processor consumer, PsiReference ref);
+
+}
diff --git a/platform/lang-api/src/com/intellij/psi/search/SearchRequestCollector.java b/platform/lang-api/src/com/intellij/psi/search/SearchRequestCollector.java
new file mode 100644
index 000000000000..8fb10bc42ab8
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/search/SearchRequestCollector.java
@@ -0,0 +1,42 @@
+package com.intellij.psi.search;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReference;
+import com.intellij.util.Processor;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+* @author peter
+*/
+public class SearchRequestCollector {
+ private final List myRequests = new ArrayList();
+ private final List>> myCustomSearchActions = new ArrayList>>();
+
+ public void searchWord(@NotNull String word, @NotNull SearchScope searchScope, boolean caseSensitive, @NotNull PsiElement searchTarget) {
+ final short searchContext = UsageSearchContext.IN_CODE | UsageSearchContext.IN_FOREIGN_LANGUAGES | UsageSearchContext.IN_COMMENTS;
+ searchWord(word, searchScope, searchContext, caseSensitive, searchTarget);
+ }
+
+ public void searchWord(@NotNull String word, @NotNull SearchScope searchScope, short searchContext, boolean caseSensitive, @NotNull PsiElement searchTarget) {
+ searchWord(word, searchScope, searchContext, caseSensitive, new SingleTargetRequestResultProcessor(searchTarget));
+ }
+
+ public void searchWord(@NotNull String word, @NotNull SearchScope searchScope, short searchContext, boolean caseSensitive, @NotNull RequestResultProcessor processor) {
+ myRequests.add(new PsiSearchRequest(searchScope, word, searchContext, caseSensitive, processor));
+ }
+
+ public void searchCustom(Processor> searchAction) {
+ myCustomSearchActions.add(searchAction);
+ }
+
+ public List getSearchRequests() {
+ return myRequests;
+ }
+
+ public List>> getCustomSearchActions() {
+ return myCustomSearchActions;
+ }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/search/SingleTargetRequestResultProcessor.java b/platform/lang-api/src/com/intellij/psi/search/SingleTargetRequestResultProcessor.java
new file mode 100644
index 000000000000..2f356959b21f
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/search/SingleTargetRequestResultProcessor.java
@@ -0,0 +1,25 @@
+package com.intellij.psi.search;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReference;
+import com.intellij.util.Processor;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class SingleTargetRequestResultProcessor extends RequestResultProcessor {
+ private final PsiElement myTarget;
+
+ public SingleTargetRequestResultProcessor(@NotNull PsiElement target) {
+ myTarget = target;
+ }
+
+ protected boolean processReference(Processor consumer, PsiReference ref) {
+ if (ref.isReferenceTo(myTarget)) {
+ return consumer.process(ref);
+ }
+ return true;
+ }
+
+}
diff --git a/platform/lang-api/src/com/intellij/psi/search/searches/ReferenceDescriptor.java b/platform/lang-api/src/com/intellij/psi/search/searches/ReferenceDescriptor.java
new file mode 100644
index 000000000000..7621f4d6f16e
--- /dev/null
+++ b/platform/lang-api/src/com/intellij/psi/search/searches/ReferenceDescriptor.java
@@ -0,0 +1,42 @@
+package com.intellij.psi.search.searches;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiReference;
+import com.intellij.util.Function;
+
+/**
+* @author max
+*/
+public class ReferenceDescriptor {
+ public static final Function MAPPER = new Function() {
+ public ReferenceDescriptor fun(PsiReference psiReference) {
+ final PsiElement element = psiReference.getElement();
+ final PsiFile file = element.getContainingFile();
+ return new ReferenceDescriptor(file, element.getTextRange().getStartOffset() + psiReference.getRangeInElement().getStartOffset());
+ }
+ };
+ private final PsiFile file;
+ private final int offset;
+
+ ReferenceDescriptor(PsiFile file, int offset) {
+ this.file = file;
+ this.offset = offset;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof ReferenceDescriptor)) return false;
+
+ ReferenceDescriptor that = (ReferenceDescriptor)o;
+
+ if (offset != that.offset) return false;
+ return file.equals(that.file);
+ }
+
+ @Override
+ public int hashCode() {
+ return 31 * file.hashCode() + offset;
+ }
+}
diff --git a/platform/lang-api/src/com/intellij/psi/search/searches/ReferencesSearch.java b/platform/lang-api/src/com/intellij/psi/search/searches/ReferencesSearch.java
index 1d1e49dd4389..63f33c59a83d 100644
--- a/platform/lang-api/src/com/intellij/psi/search/searches/ReferencesSearch.java
+++ b/platform/lang-api/src/com/intellij/psi/search/searches/ReferencesSearch.java
@@ -16,11 +16,9 @@
package com.intellij.psi.search.searches;
import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.SearchScope;
-import com.intellij.util.Function;
import com.intellij.util.Query;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NotNull;
@@ -31,40 +29,6 @@ import org.jetbrains.annotations.NotNull;
public class ReferencesSearch extends ExtensibleQueryFactory {
private static final ReferencesSearch INSTANCE = new ReferencesSearch();
- private static class ReferenceDescriptor {
- private final PsiFile file;
- private final int offset;
-
- private ReferenceDescriptor(PsiFile file, int offset) {
- this.file = file;
- this.offset = offset;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (!(o instanceof ReferenceDescriptor)) return false;
-
- ReferenceDescriptor that = (ReferenceDescriptor)o;
-
- if (offset != that.offset) return false;
- return file.equals(that.file);
- }
-
- @Override
- public int hashCode() {
- return 31 * file.hashCode() + offset;
- }
- }
-
- private static final Function MAPPER = new Function() {
- public ReferenceDescriptor fun(PsiReference psiReference) {
- final PsiElement element = psiReference.getElement();
- final PsiFile file = element.getContainingFile();
- return new ReferenceDescriptor(file, element.getTextRange().getStartOffset() + psiReference.getRangeInElement().getStartOffset());
- }
- };
-
private ReferencesSearch() {
}
@@ -116,6 +80,6 @@ public class ReferencesSearch extends ExtensibleQueryFactory search(@NotNull SearchParameters parameters) {
//noinspection unchecked
- return INSTANCE.createUniqueResultsQuery(parameters, TObjectHashingStrategy.CANONICAL, MAPPER);
+ return INSTANCE.createUniqueResultsQuery(parameters, TObjectHashingStrategy.CANONICAL, ReferenceDescriptor.MAPPER);
}
}
diff --git a/platform/lang-api/src/com/intellij/psi/util/PsiTreeUtil.java b/platform/lang-api/src/com/intellij/psi/util/PsiTreeUtil.java
index 217679658281..121d83dc1ade 100644
--- a/platform/lang-api/src/com/intellij/psi/util/PsiTreeUtil.java
+++ b/platform/lang-api/src/com/intellij/psi/util/PsiTreeUtil.java
@@ -22,6 +22,7 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.search.PsiElementProcessor;
+import com.intellij.psi.stubs.StubBase;
import com.intellij.util.ArrayUtil;
import com.intellij.util.SmartList;
import org.jetbrains.annotations.NotNull;
@@ -251,6 +252,19 @@ public class PsiTreeUtil {
return getParentOfType(element, aClass, true);
}
+ @Nullable
+ public static E getStubOrPsiParentOfType(@Nullable PsiElement element, final Class parentClass) {
+ if (element instanceof StubBasedPsiElement) {
+ StubBase stub = (StubBase)((StubBasedPsiElement) element).getStub();
+ if (stub != null) {
+ //noinspection unchecked
+ return (E)stub.getParentStubOfType(parentClass);
+ }
+
+ }
+ return getParentOfType(element, parentClass);
+ }
+
@Nullable public static T getContextOfType(@Nullable PsiElement element, @NotNull Class aClass, boolean strict) {
if (element == null) return null;
if (strict) {
diff --git a/platform/lang-api/src/com/intellij/refactoring/listeners/RefactoringElementListener.java b/platform/lang-api/src/com/intellij/refactoring/listeners/RefactoringElementListener.java
index a5b16f7f8056..50609a408e90 100644
--- a/platform/lang-api/src/com/intellij/refactoring/listeners/RefactoringElementListener.java
+++ b/platform/lang-api/src/com/intellij/refactoring/listeners/RefactoringElementListener.java
@@ -19,7 +19,7 @@ import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
/**
- * {@linkplain RefactoringElementListenerProvider} recieves a notifictaion of what happened
+ * {@linkplain RefactoringElementListenerProvider} receives a notification of what happened
* to element it have been observing during a refactoring.
* @author dsl
*/
diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleMainPanel.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleMainPanel.java
index aa63a59a86f2..af3a3b79fd87 100644
--- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleMainPanel.java
+++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/CodeStyleMainPanel.java
@@ -30,7 +30,7 @@ import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
-public class CodeStyleMainPanel extends JPanel {
+public class CodeStyleMainPanel extends JPanel implements LanguageSelectorListener {
private final CardLayout myLayout = new CardLayout();
private final JPanel mySettingsPanel = new JPanel(myLayout);
@@ -78,11 +78,7 @@ public class CodeStyleMainPanel extends JPanel {
}
});
- myLangSelector.addListener(new LanguageSelectorListener(){
- public void languageChanged(Language lang) {
- onLanguageChange(lang);
- }
- });
+ myLangSelector.addListener(this);
addWaitCard();
@@ -206,6 +202,7 @@ public class CodeStyleMainPanel extends JPanel {
public void disposeUIResources() {
myAlarm.cancelAllRequests();
clearPanels();
+ myLangSelector.removeListener(this);
}
public boolean isModified(final CodeStyleScheme scheme) {
@@ -216,7 +213,7 @@ public class CodeStyleMainPanel extends JPanel {
return mySettingsPanels.get(scheme.getName()).isModified();
}
- private void onLanguageChange(Language lang) {
+ public void languageChanged(Language lang) {
for (NewCodeStyleSettingsPanel panel : mySettingsPanels.values()) {
panel.setLanguage(lang);
}
diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/LanguageSelector.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/LanguageSelector.java
index db454e553d60..33341cc17fbd 100644
--- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/LanguageSelector.java
+++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/LanguageSelector.java
@@ -16,17 +16,16 @@
package com.intellij.application.options.codeStyle;
import com.intellij.lang.Language;
+import com.intellij.util.EventDispatcher;
import org.jetbrains.annotations.Nullable;
-import java.util.ArrayList;
-
/**
* Maintains programming language selection for code style panels.
*/
public class LanguageSelector {
private Language myLanguage;
- private ArrayList listeners = new ArrayList();
+ private final EventDispatcher myDispatcher = EventDispatcher.create(LanguageSelectorListener.class);
private Language[] myLanguages = LanguageCodeStyleSettingsProvider.getLanguagesWithCodeStyleSettings();
/**
@@ -54,12 +53,14 @@ public class LanguageSelector {
* @param l The listener to add.
*/
public void addListener(LanguageSelectorListener l) {
- listeners.add(l);
+ myDispatcher.addListener(l);
+ }
+
+ public void removeListener(LanguageSelectorListener l) {
+ myDispatcher.removeListener(l);
}
private void notifyListeners(Language lang) {
- for (LanguageSelectorListener l : listeners) {
- l.languageChanged(lang);
- }
+ myDispatcher.getMulticaster().languageChanged(lang);
}
}
diff --git a/platform/lang-impl/src/com/intellij/application/options/codeStyle/LanguageSelectorListener.java b/platform/lang-impl/src/com/intellij/application/options/codeStyle/LanguageSelectorListener.java
index 6ea024c1e3fe..53f9bc9425ae 100644
--- a/platform/lang-impl/src/com/intellij/application/options/codeStyle/LanguageSelectorListener.java
+++ b/platform/lang-impl/src/com/intellij/application/options/codeStyle/LanguageSelectorListener.java
@@ -17,11 +17,13 @@ package com.intellij.application.options.codeStyle;
import com.intellij.lang.Language;
+import java.util.EventListener;
+
/**
* Must be implemented by components willing to be notified on current code style language
* change.
*/
-public interface LanguageSelectorListener {
+public interface LanguageSelectorListener extends EventListener {
void languageChanged(Language lang);
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/generation/surroundWith/SurroundWithHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/generation/surroundWith/SurroundWithHandler.java
index 7efc9cee5cdb..9bb29ebcde0f 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/generation/surroundWith/SurroundWithHandler.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/generation/surroundWith/SurroundWithHandler.java
@@ -37,8 +37,8 @@ import com.intellij.psi.PsiFile;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
-import java.util.ArrayList;
-import java.util.List;
+import java.util.HashSet;
+import java.util.Set;
public class SurroundWithHandler implements CodeInsightActionHandler{
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.generation.surroundWith.SurroundWithHandler");
@@ -77,7 +77,7 @@ public class SurroundWithHandler implements CodeInsightActionHandler{
final Language baseLanguage = file.getViewProvider().getBaseLanguage();
final Language l = element1.getParent().getLanguage();
- List surroundDescriptors = new ArrayList();
+ final Set surroundDescriptors = new HashSet();
surroundDescriptors.addAll(LanguageSurrounders.INSTANCE.allForLanguage(l));
if (l != baseLanguage) surroundDescriptors.addAll(LanguageSurrounders.INSTANCE.allForLanguage(baseLanguage));
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java b/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java
index 0f1baeb1cdec..8d2503d63a00 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/hint/ImplementationViewComponent.java
@@ -128,7 +128,15 @@ public class ImplementationViewComponent extends JPanel {
myEditor = factory.createEditor(doc, project);
PsiFile psiFile = getContainingFile(myElements[myIndex]);
- EditorHighlighter highlighter = HighlighterFactory.createHighlighter(project, psiFile.getVirtualFile());
+ VirtualFile virtualFile = psiFile.getVirtualFile();
+ EditorHighlighter highlighter;
+ if (virtualFile != null)
+ highlighter = HighlighterFactory.createHighlighter(project, virtualFile);
+ else {
+ String fileName = psiFile.getName(); // some artificial psi file, lets do best we can
+ highlighter = HighlighterFactory.createHighlighter(project, fileName);
+ }
+
((EditorEx)myEditor).setHighlighter(highlighter);
((EditorEx)myEditor).setBackgroundColor(EditorFragmentComponent.getBackgroundColor(myEditor));
diff --git a/platform/lang-impl/src/com/intellij/extapi/psi/ASTDelegatePsiElement.java b/platform/lang-impl/src/com/intellij/extapi/psi/ASTDelegatePsiElement.java
index 308512ecd921..4c772793361e 100644
--- a/platform/lang-impl/src/com/intellij/extapi/psi/ASTDelegatePsiElement.java
+++ b/platform/lang-impl/src/com/intellij/extapi/psi/ASTDelegatePsiElement.java
@@ -293,7 +293,7 @@ public abstract class ASTDelegatePsiElement extends PsiElementBase {
getParent().deleteChildRange(this, this);
}
else {
- super.delete();
+ throw new UnsupportedOperationException(getClass().getName() + " under " + (getParent() == null ? "null" : getParent().getClass().getName()));
}
}
diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java
index 169a73bf03c4..6e0d6772fdcf 100644
--- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java
+++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesHandler.java
@@ -23,10 +23,9 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNamedElement;
import com.intellij.psi.PsiReference;
-import com.intellij.psi.util.PsiUtilBase;
-import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.search.SearchScope;
+import com.intellij.psi.search.*;
import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.util.PsiUtilBase;
import com.intellij.refactoring.util.TextOccurrencesUtil;
import com.intellij.usageView.UsageInfo;
import com.intellij.util.Processor;
@@ -90,18 +89,39 @@ public abstract class FindUsagesHandler {
return options;
}
- public void processElementUsages(@NotNull final PsiElement element, @NotNull final Processor processor, @NotNull FindUsagesOptions options) {
- if (options.isUsages) {
- ReferencesSearch.search(element, options.searchScope, false).forEach(new ReadActionProcessor() {
- public boolean processInReadAction(final PsiReference ref) {
- TextRange rangeInElement = ref.getRangeInElement();
- return processor.process(new UsageInfo(ref.getElement(), rangeInElement.getStartOffset(), rangeInElement.getEndOffset(), false));
- }
- });
+ public void processElementUsages(@NotNull final PsiElement element, @NotNull final Processor processor, @NotNull final FindUsagesOptions options) {
+ final ReadActionProcessor refProcessor = new ReadActionProcessor() {
+ public boolean processInReadAction(final PsiReference ref) {
+ TextRange rangeInElement = ref.getRangeInElement();
+ return processor
+ .process(new UsageInfo(ref.getElement(), rangeInElement.getStartOffset(), rangeInElement.getEndOffset(), false));
+ }
+ };
+
+ final SearchScope scope = options.searchScope;
+
+ final boolean searchText = options.isSearchForTextOccurences && scope instanceof GlobalSearchScope;
+ if (options.fastTrack != null) {
+ SearchRequestor.collectRequests(element, options, options.fastTrack);
+
+ if (searchText) {
+ options.fastTrack.searchCustom(new Processor>() {
+ public boolean process(Processor consumer) {
+ processUsagesInText(element, processor, (GlobalSearchScope)scope);
+ return true;
+ }
+ });
+ }
+
+ return;
}
- if (options.isSearchForTextOccurences && options.searchScope instanceof GlobalSearchScope) {
- processUsagesInText(element, processor, (GlobalSearchScope)options.searchScope);
+ if (options.isUsages) {
+ ReferencesSearch.search(element, scope, false).forEach(refProcessor);
+ }
+
+ if (searchText) {
+ processUsagesInText(element, processor, (GlobalSearchScope)scope);
}
}
diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java
index f1a7fb42c057..09fce5ad0ff3 100644
--- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java
+++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesManager.java
@@ -26,6 +26,7 @@ import com.intellij.openapi.actionSystem.ActionManager;
import com.intellij.openapi.actionSystem.AnAction;
import com.intellij.openapi.actionSystem.IdeActions;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ReadActionProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -44,6 +45,7 @@ import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.wm.StatusBar;
import com.intellij.psi.*;
import com.intellij.psi.search.LocalSearchScope;
+import com.intellij.psi.search.SearchRequestCollector;
import com.intellij.psi.search.SearchScope;
import com.intellij.ui.LightweightHint;
import com.intellij.ui.content.Content;
@@ -52,6 +54,7 @@ import com.intellij.usageView.UsageViewManager;
import com.intellij.usageView.UsageViewUtil;
import com.intellij.usages.*;
import com.intellij.usages.impl.UsageViewManagerImpl;
+import com.intellij.util.CommonProcessors;
import com.intellij.util.Processor;
import com.intellij.util.containers.ContainerUtil;
import org.jdom.Element;
@@ -338,29 +341,40 @@ public class FindUsagesManager implements JDOMExternalizable {
if (scopeFile != null) {
options.searchScope = new LocalSearchScope(scopeFile);
}
- final Processor usageInfoProcessorToUsageProcessorAdapter = new Processor() {
+ final Processor usageInfoProcessor = new CommonProcessors.UniqueProcessor(new Processor() {
public boolean process(UsageInfo usageInfo) {
return processor.process(UsageInfoToUsageConverter.convert(descriptor, usageInfo));
}
- };
+ });
List extends PsiElement> elements =
ApplicationManager.getApplication().runReadAction(new Computable>() {
public List extends PsiElement> compute() {
return descriptor.getAllElements();
}
});
+
+ options.fastTrack = new SearchRequestCollector();
+
for (final PsiElement element : elements) {
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
LOG.assertTrue(element.isValid());
}
});
- handler.processElementUsages(element, usageInfoProcessorToUsageProcessorAdapter, options);
+ handler.processElementUsages(element, usageInfoProcessor, options);
}
+
+ PsiManager.getInstance(handler.getProject()).getSearchHelper().processRequests(options.fastTrack, new ReadActionProcessor() {
+ public boolean processInReadAction(final PsiReference ref) {
+ TextRange rangeInElement = ref.getRangeInElement();
+ return usageInfoProcessor.process(new UsageInfo(ref.getElement(), rangeInElement.getStartOffset(), rangeInElement.getEndOffset(), false));
+ }
+ });
}
};
}
+
private static PsiElement2UsageTargetAdapter[] convertToUsageTargets(final List extends PsiElement> elementsToSearch) {
final ArrayList targets = new ArrayList(elementsToSearch.size());
for (PsiElement element : elementsToSearch) {
diff --git a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesOptions.java b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesOptions.java
index 7cf569e17e0a..376eaf6eb95f 100644
--- a/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesOptions.java
+++ b/platform/lang-impl/src/com/intellij/find/findUsages/FindUsagesOptions.java
@@ -23,6 +23,7 @@ import com.intellij.openapi.actionSystem.DataContext;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.psi.search.ProjectScope;
+import com.intellij.psi.search.SearchRequestCollector;
import com.intellij.psi.search.SearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -55,6 +56,7 @@ public class FindUsagesOptions extends UserDataHolderBase implements Cloneable {
public boolean isWriteAccess = false;
public boolean isIncludeOverloadUsages = false;
public boolean isThrowUsages = false;
+ public SearchRequestCollector fastTrack = null;
public FindUsagesOptions(@NotNull Project project, @Nullable final DataContext dataContext) {
String defaultScopeName = FindSettings.getInstance().getDefaultScopeName();
@@ -70,6 +72,10 @@ public class FindUsagesOptions extends UserDataHolderBase implements Cloneable {
}
}
+ public FindUsagesOptions(SearchScope searchScope) {
+ this.searchScope = searchScope;
+ }
+
public Object clone() {
return super.clone();
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/IndexCacheManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/IndexCacheManagerImpl.java
index 17c8b6dafdba..5273de0e288e 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/IndexCacheManagerImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/cache/impl/IndexCacheManagerImpl.java
@@ -19,12 +19,12 @@ package com.intellij.psi.impl.cache.impl;
import com.intellij.ide.caches.CacheUpdater;
import com.intellij.injected.editor.VirtualFileWindow;
import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ReadActionProcessor;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.ProjectFileIndex;
import com.intellij.openapi.roots.ProjectRootManager;
-import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
@@ -78,6 +78,10 @@ public class IndexCacheManagerImpl implements CacheManager{
return processor.getResults().isEmpty() ? PsiFile.EMPTY_ARRAY : processor.toArray(PsiFile.EMPTY_ARRAY);
}
+ public static boolean shouldBeFound(VirtualFile virtualFile, ProjectFileIndex index) {
+ return (index.isInContent(virtualFile) || index.isInLibrarySource(virtualFile)) && !virtualFile.getFileType().isBinary();
+ }
+
public boolean processFilesWithWord(@NotNull final Processor psiFileProcessor, @NotNull final String word, final short occurrenceMask, @NotNull final GlobalSearchScope scope, final boolean caseSensitively) {
final Set vFiles = new THashSet();
final GlobalSearchScope projectScope = GlobalSearchScope.allScope(myProject);
@@ -100,20 +104,15 @@ public class IndexCacheManagerImpl implements CacheManager{
final ProjectFileIndex index = ProjectRootManager.getInstance(myProject).getFileIndex();
- final Processor virtualFileProcessor = new Processor() {
- public boolean process(final VirtualFile virtualFile) {
+ final Processor virtualFileProcessor = new ReadActionProcessor() {
+ @Override
+ public boolean processInReadAction(VirtualFile virtualFile) {
LOG.assertTrue(virtualFile.isValid());
- return ApplicationManager.getApplication().runReadAction(new Computable() {
- public Boolean compute() {
- if (virtualFile.isValid() && scope.contains(virtualFile) && (index.isInContent(virtualFile) || index.isInLibrarySource(virtualFile))) {
- if (virtualFile.getFileType().isBinary()) return Boolean.TRUE;
-
- final PsiFile psiFile = myPsiManager.findFile(virtualFile);
- return psiFile == null || psiFileProcessor.process(psiFile);
- }
- return Boolean.TRUE;
- }
- }).booleanValue();
+ if (virtualFile.isValid() && scope.contains(virtualFile) && shouldBeFound(virtualFile, index)) {
+ final PsiFile psiFile = myPsiManager.findFile(virtualFile);
+ return psiFile == null || psiFileProcessor.process(psiFile);
+ }
+ return true;
}
};
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/CachesBasedRefSearcher.java b/platform/lang-impl/src/com/intellij/psi/impl/search/CachesBasedRefSearcher.java
index b7511856409a..3cad807eeb65 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/search/CachesBasedRefSearcher.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/search/CachesBasedRefSearcher.java
@@ -3,94 +3,110 @@
*/
package com.intellij.psi.impl.search;
+import com.intellij.find.findUsages.FindUsagesOptions;
import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.psi.*;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiNamedElement;
+import com.intellij.psi.PsiReference;
import com.intellij.psi.meta.PsiMetaData;
import com.intellij.psi.meta.PsiMetaOwner;
-import com.intellij.psi.search.*;
+import com.intellij.psi.search.SearchRequestCollector;
+import com.intellij.psi.search.SearchRequestor;
+import com.intellij.psi.search.SearchScope;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.util.Processor;
import com.intellij.util.QueryExecutor;
+import org.jetbrains.annotations.NotNull;
/**
* @author max
*/
-public class CachesBasedRefSearcher implements QueryExecutor {
- public static boolean DEBUG = false;
+public class CachesBasedRefSearcher extends SearchRequestor implements QueryExecutor {
public boolean execute(final ReferencesSearch.SearchParameters p, final Processor consumer) {
+ if (p instanceof MySearchParameters) {
+ return true;
+ }
+
final PsiElement refElement = p.getElementToSearch();
+ final SearchRequestCollector collector = new SearchRequestCollector();
- String text = ApplicationManager.getApplication().runReadAction(new Computable() {
- public String compute() {
- String text = null;
- if (refElement instanceof PsiFile) {
- final VirtualFile vFile = ((PsiFile)refElement).getVirtualFile();
- if (vFile != null) {
- text = vFile.getNameWithoutExtension();
- }
- }
- else if (refElement instanceof PsiNamedElement) {
- text = ((PsiNamedElement)refElement).getName();
- if (refElement instanceof PsiMetaOwner) {
- final PsiMetaData metaData = ((PsiMetaOwner)refElement).getMetaData();
- if (metaData != null) text = metaData.getName();
- }
- }
-
- if (text == null && refElement instanceof PsiMetaOwner) {
- final PsiMetaData metaData = ((PsiMetaOwner)refElement).getMetaData();
- if (metaData != null) text = metaData.getName();
- }
- return text;
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ public void run() {
+ final FindUsagesOptions options = new MyFindUsagesOptions(p);
+ options.isUsages = true;
+ contributeSearchTargets(refElement, options, collector, p.isIgnoreAccessScope(), options.searchScope);
+ SearchRequestor.collectRequests(refElement, options, collector);
}
});
- if (StringUtil.isEmpty(text)) return true;
- if (DEBUG) System.out.println("Searching for :" + text);
+ return refElement.getManager().getSearchHelper().processRequests(collector, consumer);
+ }
- SearchScope searchScope = ApplicationManager.getApplication().runReadAction(new Computable() {
- public SearchScope compute() {
- return p.getEffectiveSearchScope();
+ @Override
+ public void contributeRequests(@NotNull final PsiElement refElement,
+ @NotNull FindUsagesOptions options,
+ @NotNull SearchRequestCollector collector) {
+ if (options instanceof MyFindUsagesOptions) {
+ return;
+ }
+
+ final boolean ignoreAccessScope = false;
+ final SearchScope scope = options.searchScope;
+ contributeSearchTargets(refElement, options, collector, ignoreAccessScope, scope);
+ collector.searchCustom(new Processor>() {
+ public boolean process(Processor consumer) {
+ return ReferencesSearch.search(new MySearchParameters(refElement, scope, ignoreAccessScope)).forEach(consumer);
}
});
- final boolean ignoreInjectedPsi = searchScope instanceof LocalSearchScope && ((LocalSearchScope)searchScope).isIgnoreInjectedPsi();
+ }
- final TextOccurenceProcessor processor = new TextOccurenceProcessor() {
- public boolean execute(PsiElement element, int offsetInElement) {
- ProgressManager.checkCanceled();
- if (DEBUG) {
- System.out.println("!!! About to check " + element);
- }
- if (ignoreInjectedPsi && element instanceof PsiLanguageInjectionHost) return true;
- final PsiReference[] refs = element.getReferences();
- for (PsiReference ref : refs) {
- if (DEBUG) {
- System.out.println("!!!!!!!!!!!!!! Ref " + ref);
- }
- if (ReferenceRange.containsOffsetInElement(ref, offsetInElement)) {
- if (DEBUG) {
- System.out.println("!!!!!!!!!!!!!!!!!!!!! Ref " + ref + " contains");
- }
- if (ref.isReferenceTo(refElement)) {
- if (DEBUG) {
- System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Found ref " + ref);
- }
- return consumer.process(ref);
- }
- }
- }
- return true;
+ private static void contributeSearchTargets(@NotNull final PsiElement refElement,
+ @NotNull FindUsagesOptions options,
+ @NotNull SearchRequestCollector collector,
+ final boolean ignoreAccessScope,
+ final SearchScope scope) {
+ if (!options.isUsages) {
+ return;
+ }
+
+ String text = null;
+ if (refElement instanceof PsiFile) {
+ final VirtualFile vFile = ((PsiFile)refElement).getVirtualFile();
+ if (vFile != null) {
+ text = vFile.getNameWithoutExtension();
}
- };
+ }
+ else if (refElement instanceof PsiNamedElement) {
+ text = ((PsiNamedElement)refElement).getName();
+ if (refElement instanceof PsiMetaOwner) {
+ final PsiMetaData metaData = ((PsiMetaOwner)refElement).getMetaData();
+ if (metaData != null) text = metaData.getName();
+ }
+ }
- short searchContext = UsageSearchContext.IN_CODE | UsageSearchContext.IN_FOREIGN_LANGUAGES | UsageSearchContext.IN_COMMENTS;
+ if (text == null && refElement instanceof PsiMetaOwner) {
+ final PsiMetaData metaData = ((PsiMetaOwner)refElement).getMetaData();
+ if (metaData != null) text = metaData.getName();
+ }
+ if (StringUtil.isNotEmpty(text)) {
+ final SearchScope searchScope = ignoreAccessScope ? scope : refElement.getUseScope().intersectWith(scope);
+ assert text != null;
+ collector.searchWord(text, searchScope, refElement.getLanguage().isCaseSensitive(), refElement);
+ }
+ }
- final PsiSearchHelper helper = PsiManager.getInstance(refElement.getProject()).getSearchHelper();
- return helper.processElementsWithWord(processor, searchScope, text, searchContext,
- refElement.getLanguage().isCaseSensitive());
+ private static class MySearchParameters extends ReferencesSearch.SearchParameters {
+ public MySearchParameters(PsiElement refElement, SearchScope scope, boolean ignoreAccessScope) {
+ super(refElement, scope, ignoreAccessScope);
+ }
+ }
+
+ private static class MyFindUsagesOptions extends FindUsagesOptions {
+ public MyFindUsagesOptions(ReferencesSearch.SearchParameters p) {
+ super(p.getScope());
+ }
}
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/LowLevelSearchUtil.java b/platform/lang-impl/src/com/intellij/psi/impl/search/LowLevelSearchUtil.java
index 9b89e95838b6..eed20ecf37ce 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/search/LowLevelSearchUtil.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/search/LowLevelSearchUtil.java
@@ -108,9 +108,14 @@ public class LowLevelSearchUtil {
if (contains) {
if (!ignoreInjectedPsi) {
Boolean result = processInjectedFile(run, processor, searcher, progress);
- if (result != null) return result.booleanValue();
+ if (result != null) {
+ return result.booleanValue();
+ }
+ }
+ if (!processor.execute(run, start)) {
+ processor.execute(run, start);
+ return false;
}
- if (!processor.execute(run, start)) return false;
}
if (useTree) {
leafNode = leafNode.getTreeParent();
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java
index 91bc2f046286..ee9d8b5d3613 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java
@@ -25,16 +25,22 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.Ref;
-import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.impl.PsiManagerEx;
+import com.intellij.psi.impl.cache.impl.IndexCacheManagerImpl;
+import com.intellij.psi.impl.cache.impl.id.IdIndex;
+import com.intellij.psi.impl.cache.impl.id.IdIndexEntry;
import com.intellij.psi.search.*;
import com.intellij.psi.search.searches.IndexPatternSearch;
import com.intellij.util.CommonProcessors;
import com.intellij.util.Processor;
+import com.intellij.util.containers.MultiMap;
+import com.intellij.util.indexing.FileBasedIndex;
import com.intellij.util.text.StringSearcher;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
@@ -213,24 +219,39 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
progress.pushState();
progress.setText(PsiBundle.message("psi.scanning.files.progress"));
}
- myManager.startBatchFilesProcessingMode();
- try {
- String text = searcher.getPattern();
- List fileSet = getFilesWithText(scope, searchContext, caseSensitively, text, progress);
+ String text = searcher.getPattern();
+ List fileSet = getFilesWithText(scope, searchContext, caseSensitively, text, progress);
- if (progress != null) {
- progress.setText(PsiBundle.message("psi.search.for.word.progress", text));
+ if (progress != null) {
+ progress.setText(PsiBundle.message("psi.search.for.word.progress", text));
+ }
+
+ return processPsiFileRoots(progress, fileSet, new Processor() {
+ public boolean process(PsiElement psiRoot) {
+ return LowLevelSearchUtil.processElementsContainingWordInElement(processor, psiRoot, searcher, false, progress);
}
+ });
+ }
+ private boolean processPsiFileRoots(final ProgressIndicator progress,
+ List files,
+ final Processor psiRootProcessor) {
+ myManager.startBatchFilesProcessingMode();
+ try {
final AtomicInteger counter = new AtomicInteger(0);
final AtomicBoolean canceled = new AtomicBoolean(false);
final AtomicBoolean pceThrown = new AtomicBoolean(false);
- final int size = fileSet.size();
- boolean completed = JobUtil.invokeConcurrentlyUnderMyProgress(fileSet, new Processor() {
- public boolean process(final PsiFile file) {
- if (!(file instanceof PsiBinaryFile)) {
+ final int size = files.size();
+ boolean completed = JobUtil.invokeConcurrentlyUnderMyProgress(files, new Processor() {
+ public boolean process(final VirtualFile vfile) {
+ final PsiFile file = ApplicationManager.getApplication().runReadAction(new Computable() {
+ public PsiFile compute() {
+ return myManager.findFile(vfile);
+ }
+ });
+ if (file != null && !(file instanceof PsiBinaryFile)) {
file.getViewProvider().getContents(); // load contents outside readaction
ApplicationManager.getApplication().runReadAction(new Runnable() {
public void run() {
@@ -240,7 +261,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
for (PsiElement psiRoot : psiRoots) {
if (progress != null) progress.checkCanceled();
if (!processed.add(psiRoot)) continue;
- if (!LowLevelSearchUtil.processElementsContainingWordInElement(processor, psiRoot, searcher, false, progress)) {
+ if (!psiRootProcessor.process(psiRoot)) {
canceled.set(true);
return;
}
@@ -276,16 +297,27 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
}
}
- private List getFilesWithText(@NotNull GlobalSearchScope scope,
+ private List getFilesWithText(@NotNull GlobalSearchScope scope,
final short searchContext,
final boolean caseSensitively,
@NotNull String text,
ProgressIndicator progress) {
- List result = new ArrayList();
- if (!processFilesWithText(scope, searchContext, caseSensitively, text, new CommonProcessors.CollectProcessor(result), progress)) {
- return Collections.emptyList();
+ myManager.startBatchFilesProcessingMode();
+ try {
+ final List result = new ArrayList();
+ if (!processFilesWithText(scope, searchContext, caseSensitively, text, new Processor() {
+ public boolean process(PsiFile file) {
+ result.add(file.getViewProvider().getVirtualFile());
+ return true;
+ }
+ }, progress)) {
+ return Collections.emptyList();
+ }
+ return result;
+ }
+ finally {
+ myManager.finishBatchFilesProcessingMode();
}
- return result;
}
private boolean processFilesWithText(@NotNull final GlobalSearchScope scope,
@@ -447,6 +479,170 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
myManager.getCacheManager().processFilesWithWord(processor, word, UsageSearchContext.IN_STRINGS, scope, true);
}
+ public boolean processRequests(@NotNull SearchRequestCollector request, Processor processor) {
+ final MultiMap, PsiSearchRequest> singles = new MultiMap, PsiSearchRequest>();
+ final List>> customs = new ArrayList>>();
+ distributePrimitives(request, singles, customs);
+
+ if (!processRequestsOptimized(singles, processor)) {
+ return false;
+ }
+
+ for (Processor> custom : customs) {
+ if (!custom.process(processor)) {
+ return false;
+ }
+ }
+
+ return true;
+
+ }
+
+ private boolean processRequestsOptimized(MultiMap, PsiSearchRequest> singles, final Processor consumer) {
+ if (singles.isEmpty()) {
+ return true;
+ }
+
+ if (singles.size() == 1) {
+ final Collection requests = singles.get(singles.keySet().iterator().next());
+ if (requests.size() == 1) {
+ return processSingleRequest(requests.iterator().next(), consumer);
+ }
+ }
+
+ final ProgressIndicator progress = ProgressManager.getInstance().getProgressIndicator();
+ if (progress != null) {
+ progress.pushState();
+ progress.setText(PsiBundle.message("psi.scanning.files.progress"));
+ }
+
+ final MultiMap candidateFiles = collectFiles(singles);
+
+ final Map searchers = new HashMap();
+ final Set allWords = new TreeSet();
+ for (PsiSearchRequest singleRequest : candidateFiles.values()) {
+ searchers.put(singleRequest, new StringSearcher(singleRequest.word, singleRequest.caseSensitive, true));
+ allWords.add(singleRequest.word);
+ }
+
+ if (progress != null) {
+ progress.setText(PsiBundle.message("psi.search.for.word.progress", StringUtil.join(allWords, ", ")));
+ }
+
+ return processPsiFileRoots(progress, new ArrayList(candidateFiles.keySet()), new Processor() {
+ public boolean process(PsiElement psiRoot) {
+ final VirtualFile vfile = psiRoot.getContainingFile().getVirtualFile();
+ for (final PsiSearchRequest singleRequest : candidateFiles.get(vfile)) {
+ StringSearcher searcher = searchers.get(singleRequest);
+ if (!LowLevelSearchUtil.processElementsContainingWordInElement(adaptProcessor(singleRequest, consumer), psiRoot, searcher, false, progress)) {
+ return false;
+ }
+ }
+ return true;
+ }
+ });
+ }
+
+ private static TextOccurenceProcessor adaptProcessor(final PsiSearchRequest singleRequest,
+ final Processor consumer) {
+ final SearchScope searchScope = singleRequest.searchScope;
+ final boolean ignoreInjectedPsi = searchScope instanceof LocalSearchScope && ((LocalSearchScope)searchScope).isIgnoreInjectedPsi();
+ return new TextOccurenceProcessor() {
+ public boolean execute(PsiElement element, int offsetInElement) {
+ if (ignoreInjectedPsi && element instanceof PsiLanguageInjectionHost) return true;
+
+ return singleRequest.processor.execute(element, offsetInElement, consumer);
+ }
+ };
+ }
+
+ private MultiMap collectFiles(MultiMap, PsiSearchRequest> singles) {
+ final ProjectFileIndex index = ProjectRootManager.getInstance(myManager.getProject()).getFileIndex();
+ final MultiMap result = new MultiMap();
+ for (Set key : singles.keySet()) {
+ final Collection data = singles.get(key);
+ GlobalSearchScope commonScope = uniteScopes(data);
+
+ MultiMap intersection = null;
+
+ boolean first = true;
+ for (IdIndexEntry entry : key) {
+ final MultiMap local = findFilesWithIndexEntry(entry, index, data, commonScope);
+ if (first) {
+ intersection = local;
+ first = false;
+ } else {
+ for (VirtualFile file : local.keySet()) {
+ if (intersection.containsKey(file)) {
+ intersection.putValues(file, local.get(file));
+ }
+ }
+ }
+ }
+ result.putAllValues(intersection);
+ }
+ return result;
+ }
+
+ private static GlobalSearchScope uniteScopes(Collection requests) {
+ GlobalSearchScope commonScope = null;
+ for (PsiSearchRequest r : requests) {
+ final GlobalSearchScope scope = (GlobalSearchScope)r.searchScope;
+ commonScope = commonScope == null ? scope : commonScope.uniteWith(scope);
+ }
+ assert commonScope != null;
+ return commonScope;
+ }
+
+ private static MultiMap findFilesWithIndexEntry(IdIndexEntry entry,
+ final ProjectFileIndex index,
+ final Collection data,
+ GlobalSearchScope commonScope) {
+ final MultiMap local = new MultiMap();
+ FileBasedIndex.getInstance().processValues(IdIndex.NAME, entry, null, new FileBasedIndex.ValueProcessor() {
+ public boolean process(VirtualFile file, Integer value) {
+ if (!IndexCacheManagerImpl.shouldBeFound(file, index)) {
+ return true;
+ }
+ int mask = value.intValue();
+ for (PsiSearchRequest single : data) {
+ if ((mask & single.searchContext) != 0 && ((GlobalSearchScope)single.searchScope).contains(file)) {
+ local.putValue(file, single);
+ }
+ }
+ return true;
+ }
+ }, commonScope);
+ return local;
+ }
+
+ private void distributePrimitives(SearchRequestCollector request,
+ MultiMap, PsiSearchRequest> singles,
+ List>> customs) {
+ for (final PsiSearchRequest primitive : request.getSearchRequests()) {
+ final SearchScope scope = primitive.searchScope;
+ if (scope instanceof LocalSearchScope) {
+ customs.add(new Processor>() {
+ public boolean process(Processor processor) {
+ return processSingleRequest(primitive, processor);
+ }
+ });
+ } else {
+ final List words = StringUtil.getWordsIn(primitive.word);
+ final Set key = new HashSet(words.size());
+ for (String word : words) {
+ key.add(new IdIndexEntry(word, primitive.caseSensitive));
+ }
+ singles.putValue(key, primitive);
+ }
+ }
+ customs.addAll(request.getCustomSearchActions());
+ }
+
+ private boolean processSingleRequest(PsiSearchRequest single, Processor consumer) {
+ return processElementsWithWord(adaptProcessor(single, consumer), single.searchScope, single.word, single.searchContext, single.caseSensitive);
+ }
+
public SearchCostResult isCheapEnoughToSearch(@NotNull String name,
@NotNull GlobalSearchScope scope,
@Nullable final PsiFile fileToIgnoreOccurencesIn,
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceUtil.java b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceUtil.java
index 938d8bed9781..f401c935a18e 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceUtil.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/resolve/reference/impl/providers/FileReferenceUtil.java
@@ -15,6 +15,7 @@
*/
package com.intellij.psi.impl.source.resolve.reference.impl.providers;
+import com.intellij.openapi.paths.PsiDynaReference;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiReference;
@@ -52,7 +53,11 @@ public class FileReferenceUtil {
@Nullable
public static PsiFile findFile(PsiReference...references) {
for (int i = references.length - 1; i >= 0; i--) {
- if (references[i] instanceof FileReference) {
+ PsiReference ref = references[i];
+ if (ref instanceof PsiDynaReference) {
+ ref = ((PsiDynaReference)ref).getLastFileReference();
+ }
+ if (ref instanceof FileReference) {
final PsiElement file = references[i].resolve();
return file instanceof PsiFile ? (PsiFile)file : null;
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java
index b75cbe83a137..8783791a4a6c 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/CompositeElement.java
@@ -20,6 +20,7 @@ import com.intellij.extapi.psi.ASTDelegatePsiElement;
import com.intellij.lang.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProgressManager;
import com.intellij.pom.tree.events.ChangeInfo;
import com.intellij.pom.tree.events.TreeChangeEvent;
import com.intellij.pom.tree.events.impl.ChangeInfoImpl;
@@ -502,7 +503,9 @@ public class CompositeElement extends TreeElement {
}
}
- public PsiElement getPsi() {
+ public final PsiElement getPsi() {
+ ProgressManager.checkCanceled(); // We hope this method is being called often enough to cancel daemon processes smoothly
+
PsiElement wrapper = myWrapper;
if (wrapper != null) return wrapper;
@@ -510,18 +513,21 @@ public class CompositeElement extends TreeElement {
wrapper = myWrapper;
if (wrapper != null) return wrapper;
- final Language lang = getElementType().getLanguage();
- final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
- if (parserDefinition != null) {
- myWrapper = wrapper = parserDefinition.createElement(this);
- //noinspection ConstantConditions
- LOG.assertTrue(wrapper != null, "ParserDefinition.createElement() may not return null");
- }
-
- return wrapper;
+ return myWrapper = createPsiNoLock();
}
}
+ protected PsiElement createPsiNoLock() {
+ final Language lang = getElementType().getLanguage();
+ final ParserDefinition parserDefinition = LanguageParserDefinitions.INSTANCE.forLanguage(lang);
+ if (parserDefinition != null) {
+ return parserDefinition.createElement(this);
+ }
+
+ //noinspection ConstantConditions
+ return null;
+ }
+
public void setPsi(@NotNull PsiElement psi) {
myWrapper = psi;
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/CompositePsiElement.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/CompositePsiElement.java
index e20262e14965..be77e8b228ed 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/CompositePsiElement.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/CompositePsiElement.java
@@ -22,7 +22,6 @@ import com.intellij.lang.Language;
import com.intellij.navigation.ItemPresentation;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vcs.FileStatusManager;
@@ -278,8 +277,8 @@ public abstract class CompositePsiElement extends CompositeElement implements Ps
return this;
}
- public PsiElement getPsi() {
- ProgressManager.checkCanceled(); // We hope this method is being called often enough to cancel daemon processes smoothly
+ @Override
+ protected PsiElement createPsiNoLock() {
return this;
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/LazyParseableElement.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/LazyParseableElement.java
index 85e43cb63632..c77d34a7af46 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/LazyParseableElement.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/LazyParseableElement.java
@@ -21,7 +21,6 @@ package com.intellij.psi.impl.source.tree;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.psi.PsiLock;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.ILazyParseableElementType;
import com.intellij.util.text.CharArrayUtil;
@@ -30,10 +29,17 @@ import org.jetbrains.annotations.NotNull;
public class LazyParseableElement extends CompositeElement {
private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.tree.LazyParseableElement");
private static final RecursiveTreeElementWalkingVisitor CREATE_PSI = new RecursiveTreeElementWalkingVisitor(false) {
+
@Override
- protected void visitNode(TreeElement element) {
- element.getPsi();
+ public void visitLeaf(LeafElement leaf) {
}
+
+ @Override
+ public void visitComposite(CompositeElement composite) {
+ composite.createPsiNoLock();
+ super.visitComposite(composite);
+ }
+
};
private static class ChameleonLock {
@@ -169,14 +175,8 @@ public class LazyParseableElement extends CompositeElement {
rawAddChildren((TreeElement)parsedNode);
//ensure PSI is created all at once, to reduce contention of PsiLock in CompositeElement.getPsi()
- /*
- synchronized (PsiLock.LOCK) {
- while (parsedNode != null) {
- ((TreeElement)parsedNode).acceptTree(CREATE_PSI);
- parsedNode = parsedNode.getTreeNext();
- }
- }
- */
+ ((TreeElement)parsedNode).acceptTree(CREATE_PSI);
+ parsedNode = parsedNode.getTreeNext();
}
}
diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/LazyParseablePsiElement.java b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/LazyParseablePsiElement.java
index 54e74c316ac3..7f7ade51a517 100644
--- a/platform/lang-impl/src/com/intellij/psi/impl/source/tree/LazyParseablePsiElement.java
+++ b/platform/lang-impl/src/com/intellij/psi/impl/source/tree/LazyParseablePsiElement.java
@@ -25,7 +25,6 @@ import com.intellij.lang.Language;
import com.intellij.navigation.ItemPresentation;
import com.intellij.navigation.NavigationItem;
import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.FileStatus;
import com.intellij.openapi.vcs.FileStatusManager;
@@ -282,8 +281,8 @@ public class LazyParseablePsiElement extends LazyParseableElement implements Psi
return this;
}
- public PsiElement getPsi() {
- ProgressManager.checkCanceled(); // We hope this method is being called often enough to cancel daemon processes smoothly
+ @Override
+ protected PsiElement createPsiNoLock() {
return this;
}
diff --git a/platform/lang-impl/src/com/intellij/psi/search/SearchRequestor.java b/platform/lang-impl/src/com/intellij/psi/search/SearchRequestor.java
new file mode 100644
index 000000000000..495cf90aa670
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/psi/search/SearchRequestor.java
@@ -0,0 +1,27 @@
+package com.intellij.psi.search;
+
+import com.intellij.find.findUsages.FindUsagesOptions;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public abstract class SearchRequestor {
+ public static final ExtensionPointName EP_NAME = ExtensionPointName.create("com.intellij.searchRequestor");
+
+ public static void collectRequests(final PsiElement element, final FindUsagesOptions options, final SearchRequestCollector collector) {
+ ApplicationManager.getApplication().runReadAction(new Runnable() {
+ public void run() {
+ for (SearchRequestor searcher : EP_NAME.getExtensions()) {
+ searcher.contributeRequests(element, options, collector);
+ }
+ }
+ });
+ }
+
+ public abstract void contributeRequests(@NotNull PsiElement target, @NotNull FindUsagesOptions options, @NotNull SearchRequestCollector collector);
+
+}
diff --git a/platform/lang-impl/src/com/intellij/util/PatternValuesIndex.java b/platform/lang-impl/src/com/intellij/util/PatternValuesIndex.java
index b3758671f1ae..8a8f6dbc318f 100644
--- a/platform/lang-impl/src/com/intellij/util/PatternValuesIndex.java
+++ b/platform/lang-impl/src/com/intellij/util/PatternValuesIndex.java
@@ -15,10 +15,7 @@
*/
package com.intellij.util;
-import com.intellij.patterns.ElementPattern;
-import com.intellij.patterns.PatternCondition;
-import com.intellij.patterns.PatternConditionPlus;
-import com.intellij.patterns.ValuePatternCondition;
+import com.intellij.patterns.*;
import gnu.trove.THashSet;
import java.util.Collection;
@@ -51,7 +48,12 @@ public class PatternValuesIndex {
stack.add(next);
while (!stack.isEmpty()) {
final ElementPattern> pattern = stack.removeFirst();
- for (PatternCondition> condition : pattern.getCondition().getConditions()) {
+ final ElementPatternCondition> patternCondition = pattern.getCondition();
+ final InitialPatternCondition> initialCondition = patternCondition.getInitialCondition();
+ if (initialCondition instanceof InitialPatternConditionPlus) {
+ stack.addAll(((InitialPatternConditionPlus>)initialCondition).getPatterns());
+ }
+ for (PatternCondition> condition : patternCondition.getConditions()) {
if (condition instanceof PatternConditionPlus) {
stack.add(((PatternConditionPlus)condition).getValuePattern());
}
diff --git a/platform/platform-api/src/com/intellij/openapi/progress/BackgroundTaskQueue.java b/platform/platform-api/src/com/intellij/openapi/progress/BackgroundTaskQueue.java
index 611e93cf740b..231f5cee68be 100644
--- a/platform/platform-api/src/com/intellij/openapi/progress/BackgroundTaskQueue.java
+++ b/platform/platform-api/src/com/intellij/openapi/progress/BackgroundTaskQueue.java
@@ -16,6 +16,7 @@
package com.intellij.openapi.progress;
+import com.intellij.openapi.application.Application;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.project.Project;
@@ -33,6 +34,7 @@ public class BackgroundTaskQueue {
private final Queue myQueue = new LinkedList();
private boolean myHasActiveTask = false;
private Task.Backgroundable myRunnerTask;
+ private Boolean myForcedTestMode = null;
public BackgroundTaskQueue(String title) {
this(null, title);
@@ -74,7 +76,7 @@ public class BackgroundTaskQueue {
}
public void run(Task.Backgroundable task) {
- if (ApplicationManager.getApplication().isUnitTestMode()) {
+ if (isInTestMode()) {
task.run(new EmptyProgressIndicator());
task.onSuccess();
}
@@ -88,20 +90,43 @@ public class BackgroundTaskQueue {
myQueue.offer(task);
myHasActiveTask = true;
}
- if (!hadActiveTask) {
- if (ApplicationManager.getApplication().isDispatchThread()) {
- ProgressManager.getInstance().run(myRunnerTask);
- }
- else {
- ApplicationManager.getApplication().invokeLater(new Runnable() {
- public void run() {
- if (myProject == null || !myProject.isDisposed()) {
- ProgressManager.getInstance().run(myRunnerTask);
- }
- }
- });
- }
+ if (! hadActiveTask) {
+ runRunner();
}
}
}
+
+
+ private void runRunner() {
+ final Application application = ApplicationManager.getApplication();
+ if (application.isUnitTestMode()) {
+ application.executeOnPooledThread(new Runnable() {
+ public void run() {
+ myRunnerTask.run(new EmptyProgressIndicator());
+ }
+ });
+ } else {
+ if (application.isDispatchThread()) {
+ ProgressManager.getInstance().run(myRunnerTask);
+ }
+ else {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ public void run() {
+ if (myProject == null || !myProject.isDisposed()) {
+ ProgressManager.getInstance().run(myRunnerTask);
+ }
+ }
+ });
+ }
+ }
+ }
+
+ private boolean isInTestMode() {
+ if (myForcedTestMode != null) return myForcedTestMode.booleanValue();
+ return ApplicationManager.getApplication().isUnitTestMode();
+ }
+
+ public void setTestMode(boolean forcedTestMode) {
+ myForcedTestMode = forcedTestMode;
+ }
}
diff --git a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
index ec921fdc2814..bf1149306301 100644
--- a/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
+++ b/platform/platform-api/src/com/intellij/openapi/ui/DialogWrapper.java
@@ -40,7 +40,6 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
-import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
@@ -427,7 +426,7 @@ public abstract class DialogWrapper {
}
setMargin(button);
if (action.getValue(DEFAULT_ACTION) != null) {
- if (!myPeer.isHeadless()) {
+ if (myPeer != null && !myPeer.isHeadless()) {
getRootPane().setDefaultButton(button);
}
}
@@ -1340,4 +1339,4 @@ public abstract class DialogWrapper {
String getDoNotShowMessage();
}
-}
\ No newline at end of file
+}
diff --git a/platform/platform-api/src/com/intellij/patterns/InitialPatternConditionPlus.java b/platform/platform-api/src/com/intellij/patterns/InitialPatternConditionPlus.java
new file mode 100644
index 000000000000..f3697c02dcb4
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/patterns/InitialPatternConditionPlus.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2010 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.patterns;
+
+import java.util.List;
+
+/**
+ * @author peter
+*/
+public abstract class InitialPatternConditionPlus extends InitialPatternCondition {
+
+ protected InitialPatternConditionPlus(final Class aAcceptedClass) {
+ super(aAcceptedClass);
+ }
+
+ public abstract List> getPatterns();
+}
diff --git a/platform/platform-api/src/com/intellij/patterns/StandardPatterns.java b/platform/platform-api/src/com/intellij/patterns/StandardPatterns.java
index c06bdf05a2c2..c7bbe80d6800 100644
--- a/platform/platform-api/src/com/intellij/patterns/StandardPatterns.java
+++ b/platform/platform-api/src/com/intellij/patterns/StandardPatterns.java
@@ -22,6 +22,10 @@ import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
/**
* @author peter
*/
@@ -83,7 +87,7 @@ public class StandardPatterns {
}
public static ElementPattern or(final ElementPattern extends E>... patterns) {
- return new ObjectPattern.Capture(new InitialPatternCondition(Object.class) {
+ return new ObjectPattern.Capture(new InitialPatternConditionPlus(Object.class) {
public boolean accepts(@Nullable final Object o, final ProcessingContext context) {
for (final ElementPattern pattern : patterns) {
if (pattern.getCondition().accepts(o, context)) return true;
@@ -102,11 +106,15 @@ public class StandardPatterns {
}
}
+ @Override
+ public List> getPatterns() {
+ return Arrays.>asList(patterns);
+ }
});
}
public static ElementPattern and(final ElementPattern extends E>... patterns) {
- return new ObjectPattern.Capture(new InitialPatternCondition(Object.class) {
+ return new ObjectPattern.Capture(new InitialPatternConditionPlus(Object.class) {
public boolean accepts(@Nullable final Object o, final ProcessingContext context) {
for (final ElementPattern pattern : patterns) {
if (!pattern.getCondition().accepts(o, context)) return false;
@@ -124,11 +132,16 @@ public class StandardPatterns {
pattern.getCondition().append(builder, indent + " ");
}
}
+
+ @Override
+ public List> getPatterns() {
+ return Arrays.>asList(patterns);
+ }
});
}
public static ObjectPattern.Capture not(final ElementPattern pattern) {
- return new ObjectPattern.Capture(new InitialPatternCondition(Object.class) {
+ return new ObjectPattern.Capture(new InitialPatternConditionPlus(Object.class) {
public boolean accepts(@Nullable final Object o, final ProcessingContext context) {
return !pattern.getCondition().accepts(o, context);
}
@@ -137,6 +150,11 @@ public class StandardPatterns {
pattern.getCondition().append(builder.append("not("), indent + " ");
builder.append(")");
}
+
+ @Override
+ public List> getPatterns() {
+ return Collections.>singletonList(pattern);
+ }
});
}
diff --git a/platform/platform-api/src/com/intellij/util/Alarm.java b/platform/platform-api/src/com/intellij/util/Alarm.java
index 4aafb948aa95..9f4b1f78ddb6 100644
--- a/platform/platform-api/src/com/intellij/util/Alarm.java
+++ b/platform/platform-api/src/com/intellij/util/Alarm.java
@@ -43,8 +43,6 @@ public class Alarm implements Disposable {
private final List myRequests = new ArrayList();
private final List myPendingRequests = new ArrayList();
- private final ThreadPoolExecutor myExecutorService;
-
private static final ThreadPoolExecutor ourSharedExecutorService = ConcurrencyUtil.newSingleThreadExecutor("Alarm pool(shared)", Thread.NORM_PRIORITY - 2);
private final Object LOCK = new Object();
@@ -55,10 +53,6 @@ public class Alarm implements Disposable {
public void dispose() {
myDisposed = true;
cancelAllRequests();
- if (myThreadToUse == ThreadToUse.OWN_THREAD) {
- myExecutorService.getQueue().clear();
- myExecutorService.shutdown();
- }
}
public enum ThreadToUse {
@@ -84,7 +78,6 @@ public class Alarm implements Disposable {
}
public Alarm(@NotNull ThreadToUse threadToUse, Disposable parentDisposable) {
myThreadToUse = threadToUse;
- myExecutorService = threadToUse == ThreadToUse.OWN_THREAD ? ConcurrencyUtil.newSingleThreadExecutor("Alarm pool(own)", Thread.NORM_PRIORITY - 2) : ourSharedExecutorService;
if (parentDisposable != null) {
Disposer.register(parentDisposable, this);
@@ -243,7 +236,9 @@ public class Alarm implements Disposable {
}
}
else {
- myFuture = myExecutorService.submit(scheduledTask);
+ myFuture = (myThreadToUse == ThreadToUse.SHARED_THREAD)
+ ? ourSharedExecutorService.submit(scheduledTask)
+ : ApplicationManager.getApplication().executeOnPooledThread(scheduledTask);
}
}
}
diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
index 8e2d5bc46a12..1e156a0ec12c 100644
--- a/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
+++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/ApplicationImpl.java
@@ -107,7 +107,7 @@ public class ApplicationImpl extends ComponentManagerImpl implements Application
private final ExecutorService ourThreadExecutorsService = new ThreadPoolExecutor(
3,
Integer.MAX_VALUE,
- 30 * 60L,
+ 5 * 60L,
TimeUnit.SECONDS,
new SynchronousQueue(),
new ThreadFactory() {
diff --git a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml
index 1efa96bc041b..f705afae1875 100644
--- a/platform/platform-resources/src/META-INF/LangExtensionPoints.xml
+++ b/platform/platform-resources/src/META-INF/LangExtensionPoints.xml
@@ -128,6 +128,8 @@
+
+
+
diff --git a/platform/util/src/com/intellij/util/containers/MultiMap.java b/platform/util/src/com/intellij/util/containers/MultiMap.java
index 371c0f5f5304..d8e5dcd4b838 100644
--- a/platform/util/src/com/intellij/util/containers/MultiMap.java
+++ b/platform/util/src/com/intellij/util/containers/MultiMap.java
@@ -43,6 +43,22 @@ public class MultiMap {
return Collections.emptyList();
}
+ public void putAllValues(MultiMap extends K, ? extends V> from) {
+ for (K k : from.keySet()) {
+ //noinspection unchecked
+ putValues(k, ((MultiMap)from).get(k));
+ }
+ }
+
+ public void putValues(K key, Collection extends V> values) {
+ Collection list = myMap.get(key);
+ if (list == null) {
+ list = createCollection();
+ myMap.put(key, list);
+ }
+ list.addAll(values);
+ }
+
public void putValue(K key, V value) {
Collection list = myMap.get(key);
if (list == null) {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java
index b872e1241358..8e47b21bb77e 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListManagerImpl.java
@@ -294,6 +294,7 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
final boolean wasEverythingDirty = invalidated.isEverythingDirty();
final List scopes = invalidated.getScopes();
+ boolean somethingChangedInView = false;
try {
checkIfDisposed();
@@ -314,7 +315,6 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
if (wasEverythingDirty) {
changeListWorker.notifyStartProcessingChanges(null);
}
- myChangesViewManager.scheduleRefresh();
final ChangeListManagerGate gate = changeListWorker.createSelfGate();
@@ -380,11 +380,12 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
myModifier.clearQueue();
// update member from copy
if (takeChanges) {
- myWorker.takeData(changeListWorker);
+ somethingChangedInView |= myWorker.takeData(changeListWorker);
}
if (takeChanges && updateUnversionedFiles) {
boolean statusChanged = !myComposite.equals(composite);
+ somethingChangedInView |= statusChanged;
myComposite = composite;
if (statusChanged) {
myDelayedNotificator.getProxyDispatcher().unchangedFileStatusChanged();
@@ -396,7 +397,6 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
}
myShowLocalChangesInvalidated = false;
}
- myChangesViewManager.scheduleRefresh();
}
catch (DisposedException e) {
// OK, we're finishing all the stuff now.
@@ -415,6 +415,8 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec
synchronized (myDataLock) {
myDelayedNotificator.getProxyDispatcher().changeListUpdateDone();
+ }
+ if (somethingChangedInView) {
myChangesViewManager.scheduleRefresh();
}
}
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListWorker.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListWorker.java
index 8a5fb2a2e8c3..bda1c6658d01 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListWorker.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangeListWorker.java
@@ -94,20 +94,22 @@ public class ChangeListWorker implements ChangeListsWriteOperations {
myDefault = defaultList;
}
- public void takeData(@NotNull final ChangeListWorker worker) {
+ public boolean takeData(@NotNull final ChangeListWorker worker) {
myMap.clear();
myMap.putAll(worker.myMap);
myDefault = worker.myDefault;
myListsToDisappear.clear();
myListsToDisappear.addAll(worker.myListsToDisappear);
-
- myDelta.step(myIdx, worker.myIdx);
+
+ final boolean somethingChanged = myDelta.step(myIdx, worker.myIdx);
myIdx = new ChangeListsIndexes(worker.myIdx);
checkForMultipleCopiesNotMove();
- // todo +-
+
myLocallyDeleted.takeFrom(worker.myLocallyDeleted);
mySwitchedHolder.takeFrom(worker.mySwitchedHolder);
+
+ return somethingChanged;
}
private void checkForMultipleCopiesNotMove() {
diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesDelta.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesDelta.java
index 43a38faf00d4..be5e4611f6de 100644
--- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesDelta.java
+++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/ChangesDelta.java
@@ -36,12 +36,13 @@ public class ChangesDelta {
myVcsManager = ProjectLevelVcsManager.getInstance(project);
}
- public void step(final ChangeListsIndexes was, final ChangeListsIndexes became) {
+ // true -> something changed
+ public boolean step(final ChangeListsIndexes was, final ChangeListsIndexes became) {
List> wasAffected = was.getAffectedFilesUnderVcs();
if (! myInitialized) {
sendPlus(wasAffected);
myInitialized = true;
- return;
+ return true; //+-
}
final List> becameAffected = became.getAffectedFilesUnderVcs();
@@ -54,6 +55,7 @@ public class ChangesDelta {
}
}
sendPlus(toAdd);
+ return toRemove != null || toAdd != null;
}
private void sendPlus(final Collection> toAdd) {
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/Configuration.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/Configuration.java
index ad764c365c70..ef099cf3fbf1 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/Configuration.java
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/Configuration.java
@@ -16,7 +16,9 @@
package org.intellij.plugins.intelliLang;
import com.intellij.ide.plugins.IdeaPluginDescriptor;
+import com.intellij.ide.plugins.IdeaPluginDescriptorImpl;
import com.intellij.ide.plugins.PluginManager;
+import com.intellij.ide.plugins.cl.PluginClassLoader;
import com.intellij.openapi.command.UndoConfirmationPolicy;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.command.undo.DocumentReference;
@@ -199,14 +201,25 @@ public final class Configuration implements PersistentStateComponent, M
}
}
}
- final THashSet visitedUrls = new THashSet();
+ final THashSet