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 f8664fd307ed..96d916ba499c 100644 --- a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java +++ b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java @@ -1517,13 +1517,14 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { } private void markOutputPathForDeletion(final int projectId, final String outputPath, final String classname, final String srcUrl) { - synchronized (myOutputsToDelete) { + final SourceUrlClassNamePair pair = new SourceUrlClassNamePair(srcUrl, classname); + synchronized (myDataLock) { Map map = myOutputsToDelete.get(projectId); if (map == null) { map = new HashMap(); myOutputsToDelete.put(projectId, map); } - map.put(outputPath, new SourceUrlClassNamePair(srcUrl, classname)); + map.put(outputPath, pair); if (LOG.isDebugEnabled() || ourDebugMode) { final String message = "ADD path to delete: " + outputPath + "; source: " + srcUrl; LOG.debug(message); @@ -1535,7 +1536,7 @@ public class TranslatingCompilerFilesMonitor implements ApplicationComponent { } private void unmarkOutputPathForDeletion(String outputPath) { - synchronized (myOutputsToDelete) { + synchronized (myDataLock) { for (int projectId : myOutputsToDelete.keys()) { final Map map = myOutputsToDelete.get(projectId); if (map != null) { diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/ValueHint.java b/java/debugger/impl/src/com/intellij/debugger/ui/ValueHint.java index 6604fcd58802..f825e83d06e3 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/ValueHint.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/ValueHint.java @@ -245,7 +245,9 @@ public class ValueHint extends AbstractValueHint { PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); - if(psiFile == null || !psiFile.isValid()) return; + if(psiFile == null || !psiFile.isValid()) { + return; + } int selectionStart = editor.getSelectionModel().getSelectionStart(); int selectionEnd = editor.getSelectionModel().getSelectionEnd(); @@ -255,11 +257,16 @@ public class ValueHint extends AbstractValueHint { try { String text = editor.getSelectionModel().getSelectedText(); if(text != null && ctx != null) { - selectedExpression.set(JVMElementFactories.getFactory(ctx.getLanguage(), project).createExpressionFromText(text, ctx)); + final JVMElementFactory factory = JVMElementFactories.getFactory(ctx.getLanguage(), project); + if (factory == null) { + return; + } + selectedExpression.set(factory.createExpressionFromText(text, ctx)); currentRange.set(new TextRange(editor.getSelectionModel().getSelectionStart(), editor.getSelectionModel().getSelectionEnd())); } } - catch (IncorrectOperationException ignored) { } + catch (IncorrectOperationException ignored) { + } } if(currentRange.get() == null) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java index 0955e86123ce..a9aa7041e34e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java @@ -197,9 +197,13 @@ public class JavaSmartCompletionContributor extends CompletionContributor { }; THashSet mergedInfos = new THashSet(_infos, EXPECTED_TYPE_INFO_STRATEGY); + List chainedEtc = new ArrayList(); for (final ExpectedTypeInfo info : mergedInfos) { - ReferenceExpressionCompletionContributor.fillCompletionVariants(new JavaSmartCompletionParameters(params, info), noTypeCheck); + Runnable slowContinuation = + ReferenceExpressionCompletionContributor.fillCompletionVariants(new JavaSmartCompletionParameters(params, info), noTypeCheck); + ContainerUtil.addIfNotNull(chainedEtc, slowContinuation); } + addExpectedTypeMembers(params, mergedInfos, true, noTypeCheck); for (final ExpectedTypeInfo info : mergedInfos) { BasicExpressionCompletionContributor.fillCompletionVariants(new JavaSmartCompletionParameters(params, info), new Consumer() { @@ -216,19 +220,15 @@ public class JavaSmartCompletionContributor extends CompletionContributor { }, result.getPrefixMatcher()); } - - PsiElement position = params.getPosition(); - final PsiElement parent = position.getParent(); - if (!BasicExpressionCompletionContributor.AFTER_DOT.accepts(position) && - parent != null && - !(parent.getParent() instanceof PsiSwitchLabelStatement)) { - for (ExpectedTypeInfo info : mergedInfos) { - final boolean searchInheritors = params.getInvocationCount() > 1; - new JavaMembersGetter(info.getType(), position).addMembers(position, searchInheritors, noTypeCheck); - if (!info.getDefaultType().equals(info.getType())) { - new JavaMembersGetter(info.getDefaultType(), position).addMembers(position, searchInheritors, noTypeCheck); - } - } + + for (Runnable runnable : chainedEtc) { + runnable.run(); + } + + + final boolean searchInheritors = params.getInvocationCount() > 1; + if (searchInheritors) { + addExpectedTypeMembers(params, mergedInfos, false, noTypeCheck); } } }); @@ -349,6 +349,24 @@ public class JavaSmartCompletionContributor extends CompletionContributor { extend(CompletionType.SMART, AFTER_NEW, new JavaInheritorsGetter(ConstructorInsertHandler.SMART_INSTANCE)); } + private static void addExpectedTypeMembers(CompletionParameters params, + THashSet mergedInfos, + boolean quick, + Consumer consumer) { + PsiElement position = params.getPosition(); + final PsiElement parent = position.getParent(); + if (!BasicExpressionCompletionContributor.AFTER_DOT.accepts(position) && + parent != null && + !(parent.getParent() instanceof PsiSwitchLabelStatement)) { + for (ExpectedTypeInfo info : mergedInfos) { + new JavaMembersGetter(info.getType(), position).addMembers(position, !quick, consumer); + if (!info.getDefaultType().equals(info.getType())) { + new JavaMembersGetter(info.getDefaultType(), position).addMembers(position, !quick, consumer); + } + } + } + } + @Override public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) { super.fillCompletionVariants(parameters, JavaCompletionSorting.addJavaSorting(parameters, result)); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java index c432f2ab811e..279c8e58b912 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ReferenceExpressionCompletionContributor.java @@ -104,32 +104,35 @@ public class ReferenceExpressionCompletionContributor { return TrueFilter.INSTANCE; } - public static void fillCompletionVariants(final JavaSmartCompletionParameters parameters, final Consumer result) { - ApplicationManager.getApplication().runReadAction(new Runnable() { - public void run() { - final PsiElement element = parameters.getPosition(); - if (JavaSmartCompletionContributor.INSIDE_TYPECAST_EXPRESSION.accepts(element)) return; - if (JavaCompletionData.isAfterPrimitiveOrArrayType(element)) return; + @Nullable + public static Runnable fillCompletionVariants(final JavaSmartCompletionParameters parameters, final Consumer result) { + final PsiElement element = parameters.getPosition(); + if (JavaSmartCompletionContributor.INSIDE_TYPECAST_EXPRESSION.accepts(element)) return null; + if (JavaCompletionData.isAfterPrimitiveOrArrayType(element)) return null; - final int offset = parameters.getParameters().getOffset(); - final PsiReference reference = element.getContainingFile().findReferenceAt(offset); - if (reference != null) { - final ElementFilter filter = getReferenceFilter(element, false); - for (final LookupElement item : completeFinalReference(element, reference, filter, parameters)) { - result.consume(item); - } + final int offset = parameters.getParameters().getOffset(); + final PsiReference reference = element.getContainingFile().findReferenceAt(offset); + if (reference != null) { + final ElementFilter filter = getReferenceFilter(element, false); + for (final LookupElement item : completeFinalReference(element, reference, filter, parameters)) { + result.consume(item); + } - final boolean secondTime = parameters.getParameters().getInvocationCount() >= 2; + final boolean secondTime = parameters.getParameters().getInvocationCount() >= 2; - for (final LookupElement item : JavaSmartCompletionContributor.completeReference(element, reference, filter, false, parameters.getParameters())) { - addSingleArrayElementAccess(element, item, parameters, result); - - if (secondTime) { + final Set base = + JavaSmartCompletionContributor.completeReference(element, reference, filter, false, parameters.getParameters()); + for (final LookupElement item : base) { + addSingleArrayElementAccess(element, item, parameters, result); + } + + if (secondTime) { + return new Runnable() { + @Override + public void run() { + for (final LookupElement item : base) { addSecondCompletionVariants(element, reference, item, parameters, result); } - } - - if (secondTime) { if (!psiElement().afterLeaf(".").accepts(element)) { BasicExpressionCompletionContributor.processDataflowExpressionTypes(element, null, TRUE_MATCHER, new Consumer() { public void consume(LookupElement baseItem) { @@ -138,9 +141,10 @@ public class ReferenceExpressionCompletionContributor { }); } } - } + }; } - }); + } + return null; } private static Set completeFinalReference(final PsiElement element, PsiReference reference, ElementFilter filter, diff --git a/java/java-psi-api/src/com/intellij/psi/JVMElementFactories.java b/java/java-psi-api/src/com/intellij/psi/JVMElementFactories.java index 54cdd810fb10..29768641fdd7 100644 --- a/java/java-psi-api/src/com/intellij/psi/JVMElementFactories.java +++ b/java/java-psi-api/src/com/intellij/psi/JVMElementFactories.java @@ -18,6 +18,7 @@ package com.intellij.psi; import com.intellij.lang.Language; import com.intellij.lang.LanguageExtension; import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.Nullable; /** * @author Medvedev Max @@ -29,8 +30,9 @@ public class JVMElementFactories extends LanguageExtension rangesToHighlight, - Collection> stringUsages, - EditorColorsManager colorsManager) { - } - @Override protected void addHighlights(@NotNull Map ranges, @NotNull Editor editor, diff --git a/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/InplaceVariableIntroducer.java b/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/InplaceVariableIntroducer.java index 17aed8f83dd3..c57894747d03 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/InplaceVariableIntroducer.java +++ b/platform/lang-impl/src/com/intellij/refactoring/introduce/inplace/InplaceVariableIntroducer.java @@ -218,4 +218,10 @@ public class InplaceVariableIntroducer extends VariableInp protected TextRange preserveSelectedRange(SelectionModel selectionModel) { return null; } + + @Override + protected void performOnInvalidIdentifier(String newName, LinkedHashSet nameSuggestions) { + //move logic to performRefactoring + } + } diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenamer.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenamer.java index bad2b38d93ff..95e58024e488 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenamer.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/MemberInplaceRenamer.java @@ -15,15 +15,11 @@ */ package com.intellij.refactoring.rename.inplace; -import com.intellij.codeInsight.template.impl.TemplateManagerImpl; -import com.intellij.codeInsight.template.impl.TemplateState; import com.intellij.lang.LanguageNamesValidation; import com.intellij.lang.refactoring.NamesValidator; -import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.command.impl.FinishMarkAction; import com.intellij.openapi.command.impl.StartMarkAction; -import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.extensions.Extensions; @@ -31,7 +27,6 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; -import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.search.LocalSearchScope; import com.intellij.psi.search.ProjectScope; import com.intellij.psi.search.SearchScope; @@ -55,13 +50,14 @@ import java.util.List; * Date: 11/9/11 */ public class MemberInplaceRenamer extends VariableInplaceRenamer { - protected final String myOldName; private final PsiElement mySubstituted; private RangeMarker mySubstitutedRange; - public MemberInplaceRenamer(@NotNull PsiNameIdentifierOwner elementToRename, PsiElement substituted, Editor editor) { - super(elementToRename, editor); - myOldName = elementToRename.getName(); + this(elementToRename, substituted, editor, elementToRename.getName(), elementToRename.getName()); + } + + public MemberInplaceRenamer(@NotNull PsiNameIdentifierOwner elementToRename, PsiElement substituted, Editor editor, String initialName, String oldName) { + super(elementToRename, editor, elementToRename.getProject(), initialName, oldName); mySubstituted = substituted; if (mySubstituted != null && mySubstituted != myElementToRename && mySubstituted.getTextRange() != null) { final PsiFile containingFile = mySubstituted.getContainingFile(); @@ -76,6 +72,11 @@ public class MemberInplaceRenamer extends VariableInplaceRenamer { showDialogAdvertisement("RenameElement"); } + @Override + protected VariableInplaceRenamer createInplaceRenamerToRestart(PsiNamedElement variable, Editor editor, String initialName) { + return new MemberInplaceRenamer((PsiNameIdentifierOwner)variable, getSubstituted(), editor, initialName, myOldName); + } + @Override protected PsiElement checkLocalScope() { PsiElement scope = super.checkLocalScope(); @@ -181,7 +182,7 @@ public class MemberInplaceRenamer extends VariableInplaceRenamer { if (substituted == null) { return; } - + final String commandName = RefactoringBundle .message("renaming.0.1.to.2", UsageViewUtil.getType(variable), UsageViewUtil.getDescriptiveName(variable), newName); CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { @@ -218,23 +219,7 @@ public class MemberInplaceRenamer extends VariableInplaceRenamer { @Override protected void restoreStateBeforeTemplateIsFinished() { - CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { - public void run() { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - public void run() { - final Editor editor = InjectedLanguageUtil.getTopLevelEditor(myEditor); - final TemplateState state = TemplateManagerImpl.getTemplateState(editor); - assert state != null; - final int segmentsCount = state.getSegmentsCount(); - final Document document = editor.getDocument(); - for (int i = 0; i < segmentsCount; i++) { - final TextRange segmentRange = state.getSegmentRange(i); - document.replaceString(segmentRange.getStartOffset(), segmentRange.getEndOffset(), myOldName); - } - } - }); - } - }, RENAME_TITLE, null); + revertState(); } @Override diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java index 27a46867dd8a..b70eae8df922 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/VariableInplaceRenamer.java @@ -18,7 +18,6 @@ package com.intellij.refactoring.rename.inplace; import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl; import com.intellij.codeInsight.highlighting.HighlightManager; -import com.intellij.codeInsight.highlighting.ReadWriteAccessDetector; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.codeInsight.lookup.LookupManager; @@ -29,7 +28,6 @@ import com.intellij.codeInsight.template.impl.TemplateState; import com.intellij.injected.editor.VirtualFileWindow; import com.intellij.lang.LanguageExtension; import com.intellij.lang.LanguageNamesValidation; -import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.actionSystem.Shortcut; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; @@ -88,7 +86,6 @@ import com.intellij.usageView.UsageViewUtil; import com.intellij.util.PairProcessor; import com.intellij.util.containers.MultiMap; import com.intellij.util.containers.Stack; -import gnu.trove.THashMap; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -117,6 +114,8 @@ public class VariableInplaceRenamer { protected final Editor myEditor; protected final Project myProject; private RangeMarker myRenameOffset; + private String myInitialName; + protected final String myOldName; public void setAdvertisementText(String advertisementText) { myAdvertisementText = advertisementText; @@ -133,10 +132,20 @@ public class VariableInplaceRenamer { public VariableInplaceRenamer(PsiNamedElement elementToRename, Editor editor, Project project) { + this(elementToRename, editor, project, elementToRename != null ? elementToRename.getName() : null, elementToRename != null ? elementToRename.getName() : null); + } + + public VariableInplaceRenamer(PsiNamedElement elementToRename, + Editor editor, + Project project, + final String initialName, + final String oldName) { myElementToRename = elementToRename; myEditor = /*(editor instanceof EditorWindow)? ((EditorWindow)editor).getDelegate() : */editor; myProject = project; + myOldName = oldName; if (myElementToRename != null) { + myInitialName = initialName; final PsiFile containingFile = myElementToRename.getContainingFile(); if (!notSameFile(containingFile.getVirtualFile(), containingFile)) { myRenameOffset = myElementToRename != null && myElementToRename.getTextRange() != null ? myEditor.getDocument().createRangeMarker(myElementToRename.getTextRange()) : null; @@ -243,7 +252,7 @@ public class VariableInplaceRenamer { } } - private boolean runRenameTemplate(LinkedHashSet nameSuggestions, + private boolean runRenameTemplate(final LinkedHashSet nameSuggestions, Collection refs, final Collection> stringUsages, PsiElement scope, @@ -253,10 +262,6 @@ public class VariableInplaceRenamer { scope = context.getContainingFile(); } - final Map rangesToHighlight = new THashMap(); - //it is crucial to highlight AFTER the template is started, so we collect ranges first - collectElementsToHighlight(rangesToHighlight, refs, stringUsages); - final HighlightManager highlightManager = HighlightManager.getInstance(myProject); ResolveSnapshotProvider resolveSnapshotProvider = INSTANCE.forLanguage(scope.getLanguage()); final ResolveSnapshotProvider.ResolveSnapshot snapshot = resolveSnapshotProvider != null ? @@ -329,7 +334,10 @@ public class VariableInplaceRenamer { TextResult value = templateState.getVariableValue(PRIMARY_VARIABLE_NAME); myNewName = getNewName(value != null ? value.toString() : null, snapshot); - + if (!LanguageNamesValidation.INSTANCE.forLanguage(scope1.getLanguage()).isIdentifier(myNewName, myProject)) { + performOnInvalidIdentifier(myNewName, nameSuggestions); + return; + } if (snapshot != null && performAutomaticRename()) { if (LanguageNamesValidation.INSTANCE.forLanguage(scope1.getLanguage()).isIdentifier(myNewName, myProject)) { ApplicationManager.getApplication().runWriteAction(new Runnable() { @@ -410,6 +418,23 @@ public class VariableInplaceRenamer { //add highlights if (myHighlighters != null) { // can be null if finish is called during testing + Map rangesToHighlight = new HashMap(); + final TemplateState templateState = TemplateManagerImpl.getTemplateState(topLevelEditor); + if (templateState != null) { + EditorColorsManager colorsManager = EditorColorsManager.getInstance(); + for (int i = 0; i < templateState.getSegmentsCount(); i++) { + final TextRange segmentOffset = templateState.getSegmentRange(i); + final String name = template.getSegmentName(i); + TextAttributes attributes = null; + if (name.equals(PRIMARY_VARIABLE_NAME)) { + attributes = colorsManager.getGlobalScheme().getAttributes(EditorColors.WRITE_SEARCH_RESULT_ATTRIBUTES); + } else if (name.equals(OTHER_VARIABLE_NAME)) { + attributes = colorsManager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); + } + if (attributes == null) continue; + rangesToHighlight.put(segmentOffset, attributes); + } + } addHighlights(rangesToHighlight, topLevelEditor, myHighlighters, highlightManager); } } @@ -446,8 +471,24 @@ public class VariableInplaceRenamer { } } } + + protected VariableInplaceRenamer createInplaceRenamerToRestart(PsiNamedElement variable, Editor editor, String initialName) { + return new VariableInplaceRenamer(variable, editor, myProject, initialName, myOldName); + } + + protected void performOnInvalidIdentifier(final String newName, final LinkedHashSet nameSuggestions) { + revertState(); + JBPopupFactory.getInstance() + .createConfirmation("Inserted identifier is not valid", "Continue editing", "Cancel", new Runnable() { + @Override + public void run() { + createInplaceRenamerToRestart(getVariable(), myEditor, newName).performInplaceRename(true, nameSuggestions); + } + }, 0).showInBestPositionFor(myEditor); + } + + protected void restoreStateBeforeTemplateIsFinished(){} - protected void restoreStateBeforeTemplateIsFinished() {} @Nullable protected PsiElement getNameIdentifier() { @@ -600,6 +641,36 @@ public class VariableInplaceRenamer { } } + public String getInitialName() { + if (myInitialName == null) { + final PsiNamedElement variable = getVariable(); + if (variable != null) { + return variable.getName(); + } + } + return myInitialName; + } + + protected void revertState() { + CommandProcessor.getInstance().executeCommand(myProject, new Runnable() { + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + public void run() { + final Editor topLevelEditor = InjectedLanguageUtil.getTopLevelEditor(myEditor); + final TemplateState state = TemplateManagerImpl.getTemplateState(topLevelEditor); + assert state != null; + final int segmentsCount = state.getSegmentsCount(); + final Document document = topLevelEditor.getDocument(); + for (int i = 0; i < segmentsCount; i++) { + final TextRange segmentRange = state.getSegmentRange(i); + document.replaceString(segmentRange.getStartOffset(), segmentRange.getEndOffset(), myOldName); + } + } + }); + } + }, RENAME_TITLE, null); + } + private static VirtualFile getTopLevelVirtualFile(final FileViewProvider fileViewProvider) { VirtualFile file = fileViewProvider.getVirtualFile(); if (file instanceof VirtualFileWindow) file = ((VirtualFileWindow)file).getDelegate(); @@ -633,46 +704,6 @@ public class VariableInplaceRenamer { } } - private void collectElementsToHighlight(Map rangesToHighlight, - Collection refs, - Collection> stringUsages) { - EditorColorsManager colorsManager = EditorColorsManager.getInstance(); - PsiElement nameIdentifier = getNameIdentifier(); - if (nameIdentifier != null) { - final TextRange textRange = nameIdentifier.getTextRange(); - LOG.assertTrue(textRange != null, nameIdentifier); - TextRange range = InjectedLanguageManager.getInstance(myProject).injectedToHost(nameIdentifier, textRange); - rangesToHighlight.put(range, colorsManager.getGlobalScheme().getAttributes(EditorColors.WRITE_SEARCH_RESULT_ATTRIBUTES)); - } - - for (PsiReference ref : refs) { - final PsiElement element = ref.getElement(); - TextRange range = ref.getRangeInElement().shiftRight( - InjectedLanguageManager.getInstance(element.getProject()).injectedToHost(element, element.getTextRange().getStartOffset())); - - ReadWriteAccessDetector writeAccessDetector = ReadWriteAccessDetector.findDetector(element); - // TODO: read / write usages - boolean isForWrite = writeAccessDetector != null && - ReadWriteAccessDetector.Access.Write == writeAccessDetector.getExpressionAccess(element); - TextAttributes attributes = colorsManager.getGlobalScheme().getAttributes(isForWrite ? - EditorColors.WRITE_SEARCH_RESULT_ATTRIBUTES : - EditorColors.SEARCH_RESULT_ATTRIBUTES); - rangesToHighlight.put(range, attributes); - } - - collectAdditionalRangesToHighlight(rangesToHighlight, stringUsages, colorsManager); - } - - protected void collectAdditionalRangesToHighlight(Map rangesToHighlight, - Collection> stringUsages, - EditorColorsManager colorsManager) { - for (Pair usage : stringUsages) { - final TextRange range = usage.second.shiftRight(usage.first.getTextOffset()); - final TextAttributes attributes = colorsManager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES); - rangesToHighlight.put(range, attributes); - } - } - protected void addHighlights(@NotNull Map ranges, @NotNull Editor editor, @NotNull Collection highlighters, @NotNull HighlightManager highlightManager) { for (Map.Entry entry : ranges.entrySet()) { TextRange range = entry.getKey(); @@ -720,7 +751,7 @@ public class VariableInplaceRenamer { final LinkedHashSet names) { if (reference.getElement() == selectedElement && contains(reference.getRangeInElement().shiftRight(selectedElement.getTextRange().getStartOffset()), offset)) { - Expression expression = new MyExpression(myElementToRename.getName(), names); + Expression expression = new MyExpression(getInitialName(), names); builder.replaceElement(reference, PRIMARY_VARIABLE_NAME, expression, true); } else { @@ -741,7 +772,7 @@ public class VariableInplaceRenamer { final TemplateBuilderImpl builder, final LinkedHashSet names) { if (element == selectedElement) { - Expression expression = new MyExpression(myElementToRename.getName(), names); + Expression expression = new MyExpression(getInitialName(), names); builder.replaceElement(element, PRIMARY_VARIABLE_NAME, expression, true); } else if (textRange != null) { builder.replaceElement(element, textRange, OTHER_VARIABLE_NAME, PRIMARY_VARIABLE_NAME, false); diff --git a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java index 0a3d2786a186..a52461998d74 100644 --- a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java +++ b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java @@ -585,8 +585,11 @@ public class IdeEventQueue extends EventQueue { if (focusOwner == null || !focusOwner.isShowing() || focusOwner instanceof JFrame || focusOwner instanceof JDialog) { boolean mouseEventsAhead = isMouseEventAhead(e); + boolean focusTransferred = IdeFocusManager.getGlobalInstance().isFocusBeingTransferred(); - if (!mouseEventsAhead) { + boolean okToFixFocus = !mouseEventsAhead && (!focusTransferred || !Registry.is("actionSystem.fixLostTyping")); + + if (okToFixFocus) { Window showingWindow = mgr.getActiveWindow(); if (showingWindow == null) { Method getNativeFocusOwner = ReflectionUtil.getDeclaredMethod(KeyboardFocusManager.class, "getNativeFocusOwner"); diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java index 91c3465066e3..1c24a21f184d 100644 --- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/FocusManagerImpl.java @@ -734,32 +734,43 @@ public class FocusManagerImpl extends IdeFocusManager implements Disposable { } private int getCurrentModalityCount() { - int modalDialogs = 0; + int modalityCount = 0; Window[] windows = Window.getWindows(); for (Window each : windows) { + if (!each.isShowing()) continue; + if (each instanceof Dialog) { Dialog eachDialog = (Dialog)each; - if (eachDialog.isModal() && eachDialog.isShowing()) { - modalDialogs++; + if (eachDialog.isModal()) { + modalityCount++; + } else if (each instanceof JDialog) { + if (isModalContextPopup(((JDialog)each).getRootPane())) { + modalityCount++; + } } } else if (each instanceof JWindow) { - final JBPopup popup = (JBPopup)((JWindow)each).getRootPane().getClientProperty(JBPopup.KEY); - if (popup != null && popup.isModalContext()) { - modalDialogs++; + JRootPane rootPane = ((JWindow)each).getRootPane(); + if (isModalContextPopup(rootPane)) { + modalityCount++; } } } Iterator modalityCounts = myModalityCount2FlushCount.keySet().iterator(); while (modalityCounts.hasNext()) { Integer eachModalityCount = modalityCounts.next(); - if (eachModalityCount > modalDialogs) { + if (eachModalityCount > modalityCount) { modalityCounts.remove(); } } - return modalDialogs; + return modalityCount; } + private boolean isModalContextPopup(JRootPane rootPane) { + final JBPopup popup = (JBPopup)rootPane.getClientProperty(JBPopup.KEY); + return popup != null && popup.isModalContext(); + } + public void suspendKeyProcessingUntil(@NotNull final ActionCallback done) { typeAheadUntil(done); } diff --git a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java index 0726090febb8..46eb4bcc4a1c 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/AbstractPopup.java @@ -696,7 +696,7 @@ public class AbstractPopup implements JBPopup { PopupComponent.Factory factory = getFactory(myForcedHeavyweight || myResizable, forcedDialog); myNativePopup = factory.isNativePopup(); - myPopup = factory.getPopup(myOwner, myContent, targetBounds.x, targetBounds.y); + myPopup = factory.getPopup(myOwner, myContent, targetBounds.x, targetBounds.y, this); if (myResizable) { final JRootPane root = myContent.getRootPane(); @@ -751,9 +751,6 @@ public class AbstractPopup implements JBPopup { myWindow = updateMaskAndAlpha(window); - if (myWindow instanceof JWindow) { - ((JWindow)myWindow).getRootPane().putClientProperty(KEY, this); - } if (myWindow != null) { // dialogwrapper-based popups do this internally through peer, diff --git a/platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java b/platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java index 86d63554f72c..fb4d29d1b814 100644 --- a/platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java +++ b/platform/platform-impl/src/com/intellij/ui/popup/PopupComponent.java @@ -16,6 +16,7 @@ package com.intellij.ui.popup; import com.intellij.openapi.diagnostic.Logger; +import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.util.PopupUtil; import com.intellij.openapi.util.SystemInfo; import com.intellij.util.ReflectionUtil; @@ -38,15 +39,15 @@ public interface PopupComponent { boolean isPopupWindow(Window window); interface Factory { - PopupComponent getPopup(Component owner, Component content, int x, int y); + PopupComponent getPopup(Component owner, Component content, int x, int y, JBPopup jbPopup); boolean isNativePopup(); class AwtDefault implements Factory { - public PopupComponent getPopup(Component owner, Component content, int x, int y) { + public PopupComponent getPopup(Component owner, Component content, int x, int y, JBPopup jbPopup) { final PopupFactory factory = PopupFactory.getSharedInstance(); final Popup popup = factory.getPopup(owner, content, x, y); - return new AwtPopupWrapper(popup); + return new AwtPopupWrapper(popup, jbPopup); } public boolean isNativePopup() { @@ -55,7 +56,7 @@ public interface PopupComponent { } class AwtHeavyweight implements Factory { - public PopupComponent getPopup(Component owner, Component content, int x, int y) { + public PopupComponent getPopup(Component owner, Component content, int x, int y, JBPopup jbPopup) { final PopupFactory factory = PopupFactory.getSharedInstance(); final int oldType = PopupUtil.getPopupType(factory); @@ -63,7 +64,7 @@ public interface PopupComponent { final Popup popup = factory.getPopup(owner, content, x, y); if (oldType >= 0) PopupUtil.setPopupType(factory, oldType); - return new AwtPopupWrapper(popup); + return new AwtPopupWrapper(popup, jbPopup); } public boolean isNativePopup() { @@ -72,8 +73,8 @@ public interface PopupComponent { } class Dialog implements Factory { - public PopupComponent getPopup(Component owner, Component content, int x, int y) { - return new DialogPopupWrapper(owner, content, x, y); + public PopupComponent getPopup(Component owner, Component content, int x, int y, JBPopup jbPopup) { + return new DialogPopupWrapper(owner, content, x, y, jbPopup); } public boolean isNativePopup() { @@ -95,7 +96,7 @@ public interface PopupComponent { return myDialog != null && myDialog == window; } - public DialogPopupWrapper(Component owner, Component content, int x, int y) { + public DialogPopupWrapper(Component owner, Component content, int x, int y, JBPopup jbPopup) { if (!owner.isShowing()) { throw new IllegalArgumentException("Popup owner must be showing"); } @@ -109,6 +110,7 @@ public interface PopupComponent { myDialog.getContentPane().setLayout(new BorderLayout()); myDialog.getContentPane().add(content, BorderLayout.CENTER); + myDialog.getRootPane().putClientProperty(JBPopup.KEY, jbPopup); myDialog.setUndecorated(true); myDialog.pack(); @@ -123,6 +125,7 @@ public interface PopupComponent { myDialog.setVisible(false); if (dispose) { myDialog.dispose(); + myDialog.getRootPane().putClientProperty(JBPopup.KEY, null); } } @@ -142,9 +145,11 @@ public interface PopupComponent { class AwtPopupWrapper implements PopupComponent { private final Popup myPopup; + private JBPopup myJBPopup; - public AwtPopupWrapper(Popup popup) { + public AwtPopupWrapper(Popup popup, JBPopup jbPopup) { myPopup = popup; + myJBPopup = jbPopup; if (SystemInfo.isMac && UIUtil.isUnderAquaLookAndFeel()) { final Component c = (Component)ReflectionUtil.getField(Popup.class, myPopup, Component.class, "component"); @@ -176,6 +181,10 @@ public interface PopupComponent { public void show() { myPopup.show(); + Window wnd = getWindow(); + if (wnd instanceof JWindow) { + ((JWindow)wnd).getRootPane().putClientProperty(JBPopup.KEY, myJBPopup); + } } public Window getWindow() { diff --git a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java index 8d013ef5e41f..d09084f50f4e 100644 --- a/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java +++ b/platform/xdebugger-impl/src/com/intellij/xdebugger/impl/ui/DebuggerSessionTabBase.java @@ -205,7 +205,7 @@ public abstract class DebuggerSessionTabBase implements DebuggerLogConsoleManage } public void removeAdditionalTabComponent(AdditionalTabComponent component) { - component.dispose(); + Disposer.dispose(component); final Content content = myAdditionalContent.remove(component); getUi().removeContent(content, true); }