diff --git a/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java b/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java index d53091584ec9..3ff8f0164d22 100644 --- a/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java +++ b/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java @@ -550,6 +550,9 @@ public class CompilerTask extends Task.Backgroundable { public boolean canCloseProject(final Project project) { assert project != null; + if (!project.equals(myProject)) { + return true; + } if (shouldAskUser()) { int result = Messages.showOkCancelDialog( myProject, @@ -627,13 +630,15 @@ public class CompilerTask extends Task.Backgroundable { } public void projectClosed(Project project) { - if (myContent != null) { + if (project.equals(myProject) && myContent != null) { myContentManager.removeContent(myContent, true); } } public void projectClosing(Project project) { - myIsApplicationExitingOrProjectClosing = true; + if (project.equals(myProject)) { + myIsApplicationExitingOrProjectClosing = true; + } } } } diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/ExportDialog.java b/java/debugger/impl/src/com/intellij/debugger/ui/ExportDialog.java index 914146fc772a..95fbd8b07366 100644 --- a/java/debugger/impl/src/com/intellij/debugger/ui/ExportDialog.java +++ b/java/debugger/impl/src/com/intellij/debugger/ui/ExportDialog.java @@ -143,10 +143,14 @@ public class ExportDialog extends DialogWrapper { } public static String getExportThreadsText(VirtualMachineProxyImpl vmProxy) { - StringBuffer buffer = new StringBuffer(512); + final StringBuffer buffer = new StringBuffer(512); List threads = vmProxy.getVirtualMachine().allThreads(); for (ThreadReference threadReference : threads) { - buffer.append(threadName(threadReference)); + final String name = threadName(threadReference); + if (name == null) { + continue; + } + buffer.append(name); ReferenceType referenceType = threadReference.referenceType(); if (referenceType != null) { //noinspection HardCodedStringLiteral @@ -181,7 +185,10 @@ public class ExportDialog extends DialogWrapper { for (ObjectReference reference : list) { final List waiting = reference.waitingThreads(); for (ThreadReference thread : waiting) { - buffer.append("\n\t ").append(DebuggerBundle.message("threads.export.attribute.label.blocks.thread", threadName(thread))); + final String waitingThreadName = threadName(thread); + if (waitingThreadName != null) { + buffer.append("\n\t ").append(DebuggerBundle.message("threads.export.attribute.label.blocks.thread", waitingThreadName)); + } } } } @@ -191,8 +198,10 @@ public class ExportDialog extends DialogWrapper { if (vmProxy.canGetMonitorInfo()) { ThreadReference waitedThread = waitedMonitor.owningThread(); if (waitedThread != null) { - buffer.append("\n\t ") - .append(DebuggerBundle.message("threads.export.attribute.label.waiting.for.thread", threadName(waitedThread))); + final String waitedThreadName = threadName(waitedThread); + if (waitedThreadName != null) { + buffer.append("\n\t ").append(DebuggerBundle.message("threads.export.attribute.label.waiting.for.thread", waitedThreadName)); + } } } } @@ -228,7 +237,12 @@ public class ExportDialog extends DialogWrapper { } private static String threadName(ThreadReference threadReference) { - return threadReference.name() + "@" + threadReference.uniqueID(); + try { + return threadReference.name() + "@" + threadReference.uniqueID(); + } + catch (ObjectCollectedException e) { + return null; + } } private class CopyToClipboardAction extends AbstractAction { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavadocAutoLookupHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavadocAutoLookupHandler.java deleted file mode 100644 index ad38c47ef0a3..000000000000 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavadocAutoLookupHandler.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.codeInsight.completion; - -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.editor.Editor; - -/** - * - */ -public class JavadocAutoLookupHandler extends CodeCompletionHandlerBase { - public JavadocAutoLookupHandler() { - super(CompletionType.BASIC, false, false); - } - - protected void doComplete(final int offset1, final int offset2, final CompletionContext context, final FileCopyPatcher dummyIdentifier, - final Editor editor, final int invocationCount) { - PsiFile file = context.file; - int offset = context.getStartOffset(); - - PsiElement lastElement = file.findElementAt(offset - 1); - if (lastElement == null || !StringUtil.endsWithChar(lastElement.getText(), '@')) return; - - super.doComplete(offset1, offset2, context, dummyIdentifier, editor, invocationCount); - } -} diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java index 9d4bbf20e271..a99e67f228c3 100644 --- a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaTypedHandler.java @@ -17,10 +17,6 @@ package com.intellij.codeInsight.editorActions; import com.intellij.codeInsight.AutoPopupController; import com.intellij.codeInsight.CodeInsightSettings; -import com.intellij.codeInsight.completion.JavadocAutoLookupHandler; -import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.command.CommandProcessor; -import com.intellij.openapi.command.UndoConfirmationPolicy; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.EditorModificationUtil; import com.intellij.openapi.editor.ScrollType; @@ -30,6 +26,7 @@ import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.fileTypes.StdFileTypes; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.filters.ClassFilter; @@ -39,7 +36,6 @@ import com.intellij.psi.jsp.JspFile; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; -import com.intellij.psi.util.PsiUtilBase; import org.jetbrains.annotations.Nullable; /** @@ -54,13 +50,45 @@ public class JavaTypedHandler extends TypedHandlerDelegate { return Result.STOP; } if (charTyped == '#' || charTyped == '.') { - AutoPopupController.getInstance(project).autoPopupMemberLookup(editor, new MemberAutoLookupCondition()); + autoPopupMemberLookup(project, editor); return Result.STOP; } return Result.CONTINUE; } + private static void autoPopupMemberLookup(Project project, final Editor editor) { + AutoPopupController.getInstance(project).autoPopupMemberLookup(editor, new Condition() { + public boolean value(final PsiFile file) { + int offset = editor.getCaretModel().getOffset(); + + PsiElement lastElement = file.findElementAt(offset - 1); + if (lastElement == null) { + return false; + } + + //do not show lookup when typing varargs ellipsis + final PsiElement prevSibling = lastElement.getPrevSibling(); + if (prevSibling == null || ".".equals(prevSibling.getText())) return false; + PsiElement parent = prevSibling; + do { + parent = parent.getParent(); + } while(parent instanceof PsiJavaCodeReferenceElement || parent instanceof PsiTypeElement); + if (parent instanceof PsiParameterList) return false; + + if (!".".equals(lastElement.getText()) && !"#".equals(lastElement.getText())) { + return false; + } + else{ + final PsiElement element = file.findElementAt(offset); + return element == null || + !"#".equals(lastElement.getText()) || + new SuperParentFilter(new ClassFilter(PsiDocComment.class)).isAcceptable(element, element.getParent()); + } + } + }); + } + public Result beforeCharTyped(final char c, final Project project, final Editor editor, final PsiFile file, final FileType fileType) { final FileType originalFileType = getOriginalFileType(file); @@ -217,27 +245,15 @@ public class JavaTypedHandler extends TypedHandlerDelegate { } private static void autoPopupJavadocLookup(final Project project, final Editor editor) { - if (ApplicationManager.getApplication().isUnitTestMode()) return; + AutoPopupController.getInstance(project).autoPopupMemberLookup(editor, new Condition() { + @Override + public boolean value(PsiFile file) { + int offset = editor.getCaretModel().getOffset(); - final CodeInsightSettings settings = CodeInsightSettings.getInstance(); - if (settings.AUTO_POPUP_COMPLETION_LOOKUP) { - final PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, project); - if (file == null) return; - final Runnable request = new Runnable(){ - public void run(){ - PsiDocumentManager.getInstance(project).commitAllDocuments(); - CommandProcessor.getInstance().executeCommand(project, new Runnable() { - public void run(){ - new JavadocAutoLookupHandler().invoke(project, editor, file); - } - }, - "", - null, UndoConfirmationPolicy.DEFAULT, editor.getDocument() - ); - } - }; - AutoPopupController.getInstance(project).invokeAutoPopupRunnable(request, settings.AUTO_LOOKUP_DELAY); - } + PsiElement lastElement = file.findElementAt(offset - 1); + return lastElement != null && StringUtil.endsWithChar(lastElement.getText(), '@'); + } + }); } public static boolean isAfterClassLikeIdentifierOrDot(final int offset, final Editor editor) { @@ -259,38 +275,4 @@ public class JavaTypedHandler extends TypedHandlerDelegate { return false; } - - private static class MemberAutoLookupCondition implements Condition { - public boolean value(final Editor editor) { - final Project project = editor.getProject(); - if (project == null) return false; - PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); - if (file == null) return false; - int offset = editor.getCaretModel().getOffset(); - - PsiElement lastElement = file.findElementAt(offset - 1); - if (lastElement == null) { - return false; - } - - //do not show lookup when typing varargs ellipsis - final PsiElement prevSibling = lastElement.getPrevSibling(); - if (prevSibling == null || ".".equals(prevSibling.getText())) return false; - PsiElement parent = prevSibling; - do { - parent = parent.getParent(); - } while(parent instanceof PsiJavaCodeReferenceElement || parent instanceof PsiTypeElement); - if (parent instanceof PsiParameterList) return false; - - if (!".".equals(lastElement.getText()) && !"#".equals(lastElement.getText())) { - return false; - } - else{ - final PsiElement element = file.findElementAt(offset); - return element == null || - !"#".equals(lastElement.getText()) || - new SuperParentFilter(new ClassFilter(PsiDocComment.class)).isAcceptable(element, element.getParent()); - } - } - } } diff --git a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java index ab2b60d30939..e8de23e4e3cc 100644 --- a/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java +++ b/java/java-impl/src/com/intellij/psi/formatter/java/JavaSpacePropertyProcessor.java @@ -185,6 +185,9 @@ public class JavaSpacePropertyProcessor extends JavaElementVisitor { else if (myRole2 == ChildRole.ARGUMENT_LIST) { createSpaceInCode(mySettings.SPACE_BEFORE_METHOD_CALL_PARENTHESES); } + else if (myRole1 == ChildRole.LBRACKET || myRole2 == ChildRole.RBRACKET) { + createSpaceInCode(mySettings.SPACE_WITHIN_BRACKETS); + } } @Override public void visitArrayInitializerExpression(PsiArrayInitializerExpression expression) { diff --git a/java/java-impl/src/com/intellij/refactoring/rename/RenameAliasingPomTargetProcessor.java b/java/java-impl/src/com/intellij/refactoring/rename/RenameAliasingPomTargetProcessor.java index 328e1800f188..b9ec190bb82b 100644 --- a/java/java-impl/src/com/intellij/refactoring/rename/RenameAliasingPomTargetProcessor.java +++ b/java/java-impl/src/com/intellij/refactoring/rename/RenameAliasingPomTargetProcessor.java @@ -20,7 +20,6 @@ import com.intellij.pom.PomTarget; import com.intellij.pom.PomTargetPsiElement; import com.intellij.pom.references.PomService; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiTarget; import com.intellij.psi.targets.AliasingPsiTarget; import com.intellij.psi.targets.AliasingPsiTargetMapper; import org.jetbrains.annotations.Nullable; @@ -31,15 +30,32 @@ public class RenameAliasingPomTargetProcessor extends RenamePsiElementProcessor @Override public boolean canProcessElement(@Nullable PsiElement element) { - return element instanceof PomTargetPsiElement; + return element instanceof PomTarget || element instanceof PomTargetPsiElement; } @Override public void prepareRenaming(PsiElement element, String newName, Map allRenames) { + PomTarget target = null; if (element instanceof PomTargetPsiElement) { + target = ((PomTargetPsiElement)element).getTarget(); + } + else if (element instanceof PomTarget) { + target = (PomTarget)element; + } + + if (target != null) { for (AliasingPsiTargetMapper mapper : Extensions.getExtensions(AliasingPsiTargetMapper.EP_NAME)) { - for (AliasingPsiTarget psiTarget : mapper.getTargets(((PomTargetPsiElement)element).getTarget())) { - allRenames.put(PomService.convertToPsi(psiTarget), psiTarget.getNameAlias(newName)); + for (AliasingPsiTarget psiTarget : mapper.getTargets(target)) { + PsiElement psiElement = PomService.convertToPsi(psiTarget); + String name = psiTarget.getNameAlias(newName); + + String definedName = allRenames.put(psiElement, name); + if (definedName != null) { + assert definedName.equals(name); + } + else { + prepareRenaming(psiElement, name, allRenames); + } } } } diff --git a/java/java-impl/src/com/intellij/testIntegration/TestIntegrationUtils.java b/java/java-impl/src/com/intellij/testIntegration/TestIntegrationUtils.java index 164fa4148b46..0ae830a98b67 100644 --- a/java/java-impl/src/com/intellij/testIntegration/TestIntegrationUtils.java +++ b/java/java-impl/src/com/intellij/testIntegration/TestIntegrationUtils.java @@ -81,8 +81,16 @@ public class TestIntegrationUtils { public static PsiClass findOuterClass(PsiElement element) { PsiClass result = PsiTreeUtil.getParentOfType(element, PsiClass.class, false); + if (result == null) { + final PsiFile containingFile = element.getContainingFile(); + if (containingFile instanceof PsiClassOwner){ + final PsiClass[] classes = ((PsiClassOwner)containingFile).getClasses(); + if (classes.length == 1) { + result = classes[0]; + } + } + } if (result == null) return null; - do { PsiClass nextParent = PsiTreeUtil.getParentOfType(result, PsiClass.class, true); if (nextParent == null) return result; diff --git a/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestAction.java b/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestAction.java index 1bc558717162..b9d23e17c5f4 100644 --- a/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestAction.java +++ b/java/java-impl/src/com/intellij/testIntegration/createTest/CreateTestAction.java @@ -39,6 +39,7 @@ import com.intellij.testIntegration.TestFramework; import com.intellij.testIntegration.TestIntegrationUtils; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.Collection; @@ -60,17 +61,18 @@ public class CreateTestAction extends PsiElementBaseIntentionAction { PsiClass psiClass = getContainingClass(element); + assert psiClass != null; PsiJavaToken leftBrace = psiClass.getLBrace(); if (leftBrace == null) return false; if (element.getTextOffset() >= leftBrace.getTextOffset()) return false; - TextRange declarationRange = HighlightNamesUtil.getClassDeclarationTextRange(psiClass); - if (!declarationRange.contains(element.getTextRange())) return false; + //TextRange declarationRange = HighlightNamesUtil.getClassDeclarationTextRange(psiClass); + //if (!declarationRange.contains(element.getTextRange())) return false; return true; } - public boolean isAvailableForElement(PsiElement element) { + public static boolean isAvailableForElement(PsiElement element) { if (element == null) return false; PsiClass psiClass = getContainingClass(element); @@ -91,7 +93,7 @@ public class CreateTestAction extends PsiElementBaseIntentionAction { return true; } - private boolean isUnderTestSources(PsiClass c) { + private static boolean isUnderTestSources(PsiClass c) { ProjectRootManager rm = ProjectRootManager.getInstance(c.getProject()); VirtualFile f = c.getContainingFile().getVirtualFile(); if (f == null) return false; @@ -144,7 +146,7 @@ public class CreateTestAction extends PsiElementBaseIntentionAction { }); } - private void showErrorLater(final Project project, final String targetClassName) { + private static void showErrorLater(final Project project, final String targetClassName) { ApplicationManager.getApplication().invokeLater(new Runnable() { public void run() { Messages.showErrorDialog(project, @@ -154,7 +156,7 @@ public class CreateTestAction extends PsiElementBaseIntentionAction { }); } - private void addSuperClass(PsiClass targetClass, Project project, String superClassName) throws IncorrectOperationException { + private static void addSuperClass(PsiClass targetClass, Project project, String superClassName) throws IncorrectOperationException { if (superClassName == null) return; PsiElementFactory ef = JavaPsiFacade.getInstance(project).getElementFactory(); @@ -170,12 +172,13 @@ public class CreateTestAction extends PsiElementBaseIntentionAction { targetClass.getExtendsList().add(superClassRef); } - private PsiClass findClass(Project project, String fqName) { + @Nullable + private static PsiClass findClass(Project project, String fqName) { GlobalSearchScope scope = GlobalSearchScope.allScope(project); return JavaPsiFacade.getInstance(project).findClass(fqName, scope); } - private void addTestMethods(Editor editor, + private static void addTestMethods(Editor editor, PsiClass targetClass, TestFramework descriptor, Collection methods, @@ -192,14 +195,25 @@ public class CreateTestAction extends PsiElementBaseIntentionAction { } } - private void generateMethod(TestIntegrationUtils.MethodKind methodKind, TestFramework descriptor, PsiClass targetClass, Editor editor, String name) { + private static void generateMethod(TestIntegrationUtils.MethodKind methodKind, TestFramework descriptor, PsiClass targetClass, Editor editor, String name) { PsiMethod method = (PsiMethod)targetClass.add(TestIntegrationUtils.createDummyMethod(targetClass.getProject())); PsiDocumentManager.getInstance(targetClass.getProject()).doPostponedOperationsAndUnblockDocument(editor.getDocument()); TestIntegrationUtils.runTestMethodTemplate(methodKind, descriptor, editor, targetClass, method, name, true); } - private PsiClass getContainingClass(PsiElement element) { - return PsiTreeUtil.getParentOfType(element, PsiClass.class, false); + @Nullable + private static PsiClass getContainingClass(PsiElement element) { + final PsiClass psiClass = PsiTreeUtil.getParentOfType(element, PsiClass.class, false); + if (psiClass == null) { + final PsiFile containingFile = element.getContainingFile(); + if (containingFile instanceof PsiClassOwner){ + final PsiClass[] classes = ((PsiClassOwner)containingFile).getClasses(); + if (classes.length == 1) { + return classes[0]; + } + } + } + return psiClass; } public boolean startInWriteAction() { diff --git a/java/java-tests/testSrc/com/intellij/psi/PsiConcurrencyStressTest.java b/java/java-tests/testSrc/com/intellij/psi/PsiConcurrencyStressTest.java index 73e7b86be0e9..1a58f4b1d6a9 100644 --- a/java/java-tests/testSrc/com/intellij/psi/PsiConcurrencyStressTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/PsiConcurrencyStressTest.java @@ -3,10 +3,12 @@ */ package com.intellij.psi; +import com.intellij.codeInsight.daemon.impl.HighlightInfoFilter; +import com.intellij.codeInsight.daemon.impl.analysis.HighlightInfoHolder; +import com.intellij.codeInsight.daemon.impl.analysis.HighlightVisitorImpl; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.Result; import com.intellij.openapi.application.ex.PathManagerEx; -import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.editor.Document; import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; @@ -16,10 +18,10 @@ import com.intellij.psi.search.GlobalSearchScope; import com.intellij.testFramework.PsiTestCase; import com.intellij.testFramework.PsiTestUtil; import com.intellij.util.IncorrectOperationException; -import com.intellij.util.indexing.StorageException; import java.util.Random; import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; public class PsiConcurrencyStressTest extends PsiTestCase { @@ -47,9 +49,10 @@ public class PsiConcurrencyStressTest extends PsiTestCase { } private PsiJavaFile myFile; + private volatile boolean writeActionInProgress; public void testStress() throws Exception { int numOfThreads = 10; - final int readIterations = 50000; + final int readIterations = 100; final int writeIterations = 30; synchronized (this) { @@ -71,12 +74,8 @@ public class PsiConcurrencyStressTest extends PsiTestCase { ApplicationManager.getApplication().runReadAction(new Runnable() { @Override public void run() { - try { - readStep(random); - } - catch (StorageException e) { - LOG.error(e); - } + assertFalse(writeActionInProgress); + readStep(random); } }); } @@ -93,15 +92,17 @@ public class PsiConcurrencyStressTest extends PsiTestCase { new WriteCommandAction(myProject, myFile) { @Override protected void run(final Result result) throws Throwable { + writeActionInProgress = true; documentManager.commitAllDocuments(); writeStep(random); documentManager.commitAllDocuments(); assertEquals(document.getText(), myFile.getText()); + writeActionInProgress = false; } }.execute(); } - reads.await(); + reads.await(5, TimeUnit.MINUTES); } private static void mark(final String s) { @@ -132,62 +133,46 @@ public class PsiConcurrencyStressTest extends PsiTestCase { } } - private void readStep(final Random random) throws StorageException { + private void readStep(final Random random) { PsiClass aClass = getPsiClass(); - switch (random.nextInt(5)) { - case 0 : + switch (random.nextInt(4)) { + case 0: mark("v"); - aClass.getContainingFile().accept(new PsiRecursiveElementVisitor() {}); break; + aClass.getContainingFile().accept(new PsiRecursiveElementVisitor() { + }); + break; - case 1 : + case 1: mark("m"); - aClass.getMethods(); + for (int offset=0; offset condition){ + public void autoPopupMemberLookup(final Editor editor, @Nullable final Condition condition){ if (ApplicationManager.getApplication().isUnitTestMode()) return; final CodeInsightSettings settings = CodeInsightSettings.getInstance(); @@ -92,7 +92,9 @@ public class AutoPopupController implements Disposable { if (editor.isDisposed()) return; PsiDocumentManager.getInstance(myProject).commitAllDocuments(); - if (condition != null && !condition.value(editor)) return; + if (!file.isValid()) return; + + if (condition != null && !condition.value(file)) return; new CodeCompletionHandlerBase(CompletionType.BASIC, false, false).invoke(myProject, editor, file); } }; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/ComboEditorCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/ComboEditorCompletionContributor.java index 9e3510b03442..fdbc741cf588 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/ComboEditorCompletionContributor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/ComboEditorCompletionContributor.java @@ -31,6 +31,11 @@ public class ComboEditorCompletionContributor extends CompletionContributor{ @Override public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) { + final CompletionProcess process = CompletionService.getCompletionService().getCurrentCompletion(); + if (process != null && process.isAutopopupCompletion()) { + return; + } + final PsiFile file = parameters.getOriginalFile(); final Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file); if (document != null) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java index c05c356bb554..6576c47cf6f1 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/LocalInspectionsPass.java @@ -42,6 +42,7 @@ import com.intellij.openapi.keymap.KeymapUtil; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.util.ProgressWrapper; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.util.Pair; @@ -49,6 +50,7 @@ import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.Trinity; import com.intellij.openapi.util.text.StringUtil; import com.intellij.profile.codeInspection.InspectionProjectProfileManager; +import com.intellij.profile.codeInspection.SeverityProvider; import com.intellij.psi.*; import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.util.ConcurrencyUtil; @@ -101,9 +103,9 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass else { myShortcutText = ""; } - mySeverityRegistrar = SeverityRegistrar.getInstance(myProject); InspectionProfileWrapper customProfile = file.getUserData(InspectionProfileWrapper.KEY); myProfileWrapper = customProfile == null ? InspectionProjectProfileManager.getInstance(myProject).getProfileWrapper() : customProfile; + mySeverityRegistrar = ((SeverityProvider)myProfileWrapper.getInspectionProfile().getProfileManager()).getSeverityRegistrar(); // initial guess setProgressLimit(300 * 2); @@ -324,16 +326,17 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass return highlights; } - private static HighlightInfo highlightInfoFromDescriptor(final ProblemDescriptor problemDescriptor, - final HighlightInfoType highlightInfoType, - final String message, - final String toolTip) { + private HighlightInfo highlightInfoFromDescriptor(final ProblemDescriptor problemDescriptor, + final HighlightInfoType highlightInfoType, + final String message, + final String toolTip) { TextRange textRange = ((ProblemDescriptorImpl)problemDescriptor).getTextRange(); PsiElement element = problemDescriptor.getPsiElement(); boolean isFileLevel = element instanceof PsiFile && textRange.equals(element.getTextRange()); - return new HighlightInfo(null, highlightInfoType, textRange.getStartOffset(), textRange.getEndOffset(), message, toolTip, - highlightInfoType.getSeverity(element), problemDescriptor.isAfterEndOfLine(), null, isFileLevel); + final HighlightSeverity severity = highlightInfoType.getSeverity(element); + return new HighlightInfo(mySeverityRegistrar.getTextAttributesBySeverity(severity), highlightInfoType, textRange.getStartOffset(), textRange.getEndOffset(), message, toolTip, + severity, problemDescriptor.isAfterEndOfLine(), null, isFileLevel); } private final AtomicBoolean haveInfosToProcess = new AtomicBoolean(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/AutoHardWrapHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/AutoHardWrapHandler.java index b23803abd1dd..25f2e8669a9e 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/AutoHardWrapHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/AutoHardWrapHandler.java @@ -158,9 +158,15 @@ public class AutoHardWrapHandler { } final int[] wrapIntroducedSymbolsNumber = new int[1]; + final int[] caretOffsetDiff = new int[1]; + final int baseCaretOffset = caretModel.getOffset(); DocumentListener listener = new DocumentListener() { @Override public void beforeDocumentChange(DocumentEvent event) { + if (event.getOffset() <= baseCaretOffset + caretOffsetDiff[0]) { + caretOffsetDiff[0] += event.getNewLength() - event.getOldLength(); + } + if (event.getNewLength() <= 0) { // There is a possible case that document fragment is removed because of auto-formatting. We don't want to process such events. return; @@ -188,12 +194,7 @@ public class AutoHardWrapHandler { change.change.setStart(wrapOffset); change.change.setEnd(wrapOffset + wrapIntroducedSymbolsNumber[0]); - int newCaretOffset = caretOffset; - if (wrapOffset <= caretOffset && newCaretOffset + wrapIntroducedSymbolsNumber[0] < document.getTextLength()) { - newCaretOffset += wrapIntroducedSymbolsNumber[0]; - } - newCaretOffset = Math.min(document.getLineEndOffset(line + 1), newCaretOffset); - caretModel.moveToOffset(newCaretOffset); + caretModel.moveToOffset(baseCaretOffset + caretOffsetDiff[0]); } private static class AutoWrapChange { diff --git a/platform/lang-impl/src/com/intellij/execution/OutputListener.java b/platform/lang-impl/src/com/intellij/execution/OutputListener.java index cba904e34f8e..a10658238d6b 100644 --- a/platform/lang-impl/src/com/intellij/execution/OutputListener.java +++ b/platform/lang-impl/src/com/intellij/execution/OutputListener.java @@ -4,6 +4,7 @@ import com.intellij.execution.process.ProcessAdapter; import com.intellij.execution.process.ProcessEvent; import com.intellij.execution.process.ProcessOutputTypes; import com.intellij.openapi.util.Key; +import org.apache.commons.lang.text.StrBuilder; import org.jetbrains.annotations.NotNull; /** @@ -13,6 +14,11 @@ public class OutputListener extends ProcessAdapter { private final StringBuilder out; private final StringBuilder err; + public OutputListener() { + out = new StringBuilder(); + err = new StringBuilder(); + } + public OutputListener(@NotNull final StringBuilder out, @NotNull final StringBuilder err) { this.out = out; this.err = err; @@ -26,4 +32,8 @@ public class OutputListener extends ProcessAdapter { err.append(event.getText()); } } + + public Output getOutput() { + return new Output(out.toString(), err.toString()); + } } diff --git a/platform/lang-impl/src/com/intellij/ide/actions/CreateFileFromTemplateDialog.java b/platform/lang-impl/src/com/intellij/ide/actions/CreateFileFromTemplateDialog.java index d285dea2b374..547fb508ce3d 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/CreateFileFromTemplateDialog.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/CreateFileFromTemplateDialog.java @@ -16,26 +16,17 @@ package com.intellij.ide.actions; -import com.intellij.ide.ui.UISettings; -import com.intellij.openapi.actionSystem.AnAction; -import com.intellij.openapi.actionSystem.AnActionEvent; -import com.intellij.openapi.actionSystem.CustomShortcutSet; -import com.intellij.openapi.actionSystem.KeyboardShortcut; -import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.DialogWrapper; import com.intellij.openapi.util.Ref; -import com.intellij.openapi.util.Trinity; import com.intellij.psi.PsiElement; -import com.intellij.ui.ComboboxSpeedSearch; import com.intellij.util.Icons; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; -import java.awt.*; -import java.awt.event.KeyEvent; +import java.util.Map; /** * @author peter @@ -49,7 +40,7 @@ public class CreateFileFromTemplateDialog extends DialogWrapper { private ElementCreator myCreator; - private CreateFileFromTemplateDialog(@NotNull Project project) { + protected CreateFileFromTemplateDialog(@NotNull Project project) { super(project, true); myKindLabel.setLabelFor(myKindCombo); @@ -58,8 +49,16 @@ public class CreateFileFromTemplateDialog extends DialogWrapper { init(); } + protected JTextField getNameField() { + return myNameField; + } + + protected TemplateKindCombo getKindCombo() { + return myKindCombo; + } + private String getEnteredName() { - return myNameField.getText(); + return getNameField().getText(); } @Override @@ -77,57 +76,72 @@ public class CreateFileFromTemplateDialog extends DialogWrapper { @Override public JComponent getPreferredFocusedComponent() { - return myNameField; + return getNameField(); } - public static Builder createDialog(@NotNull final Project project) { + public static Builder createDialog(@NotNull final Project project) { final CreateFileFromTemplateDialog dialog = new CreateFileFromTemplateDialog(project); + return new BuilderImpl(dialog, project); + } - return new Builder() { + protected static class BuilderImpl implements Builder { - @Override - public Builder setTitle(String title) { - dialog.setTitle(title); - return this; - } + private final CreateFileFromTemplateDialog myDialog; + private final Project myProject; - public Builder addKind(@NotNull String name, @Nullable Icon icon, @NotNull String templateName) { - dialog.myKindCombo.addItem(name, icon, templateName); - return this; - } + public BuilderImpl(CreateFileFromTemplateDialog dialog, Project project) { + myDialog = dialog; + myProject = project; + } - public T show(@NotNull String errorTitle, @Nullable String selectedTemplateName, - @NotNull final FileCreator creator) { - final Ref created = Ref.create(null); - dialog.myKindCombo.setSelectedName(selectedTemplateName); - dialog.myCreator = new ElementCreator(project, errorTitle) { - @Override - protected void checkBeforeCreate(String newName) throws IncorrectOperationException { - creator.checkBeforeCreate(newName, dialog.myKindCombo.getSelectedName()); - } + @Override + public Builder setTitle(String title) { + myDialog.setTitle(title); + return this; + } - @Override - protected PsiElement[] create(String newName) throws Exception { - final T element = creator.createFile(dialog.getEnteredName(), dialog.myKindCombo.getSelectedName()); - created.set(element); - if (element != null) { - return new PsiElement[]{element}; - } - return PsiElement.EMPTY_ARRAY; - } + public Builder addKind(@NotNull String name, @Nullable Icon icon, @NotNull String templateName) { + myDialog.getKindCombo().addItem(name, icon, templateName); + return this; + } - @Override - protected String getActionName(String newName) { - return creator.getActionName(newName, dialog.myKindCombo.getSelectedName()); - } - }; - dialog.show(); - if (dialog.getExitCode() == OK_EXIT_CODE) { - return created.get(); + public T show(@NotNull String errorTitle, @Nullable String selectedTemplateName, + @NotNull final FileCreator creator) { + final Ref created = Ref.create(null); + myDialog.getKindCombo().setSelectedName(selectedTemplateName); + myDialog.myCreator = new ElementCreator(myProject, errorTitle) { + @Override + protected void checkBeforeCreate(String newName) throws IncorrectOperationException { + creator.checkBeforeCreate(newName, myDialog.getKindCombo().getSelectedName()); } - return null; + + @Override + protected PsiElement[] create(String newName) throws Exception { + final T element = creator.createFile(myDialog.getEnteredName(), myDialog.getKindCombo().getSelectedName()); + created.set(element); + if (element != null) { + return new PsiElement[]{element}; + } + return PsiElement.EMPTY_ARRAY; + } + + @Override + protected String getActionName(String newName) { + return creator.getActionName(newName, myDialog.getKindCombo().getSelectedName()); + } + }; + myDialog.show(); + if (myDialog.getExitCode() == OK_EXIT_CODE) { + return created.get(); } - }; + return null; + } + + @Nullable + @Override + public Map getCustomProperties() { + return null; + } } public interface Builder { @@ -135,6 +149,8 @@ public class CreateFileFromTemplateDialog extends DialogWrapper { Builder addKind(@NotNull String kind, @Nullable Icon icon, @NotNull String templateName); @Nullable T show(@NotNull String errorTitle, @Nullable String selectedItem, @NotNull FileCreator creator); + @Nullable + Map getCustomProperties(); } public interface FileCreator { diff --git a/platform/lang-impl/src/com/intellij/ide/actions/CreateFromTemplateAction.java b/platform/lang-impl/src/com/intellij/ide/actions/CreateFromTemplateAction.java index 34928e5d968b..2ddc1cb56a1e 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/CreateFromTemplateAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/CreateFromTemplateAction.java @@ -28,6 +28,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.util.Map; /** * @author Eugene.Kudelevsky @@ -74,11 +75,11 @@ public abstract class CreateFromTemplateAction extends AnA }); if (createdElement != null) { view.selectElement(createdElement); - postProcess(createdElement, selectedTemplateName.get()); + postProcess(createdElement, selectedTemplateName.get(), builder.getCustomProperties()); } } - protected void postProcess(T createdElement, String templateName) { + protected void postProcess(T createdElement, String templateName, Map customProperties) { } @Nullable diff --git a/platform/lang-impl/src/com/intellij/ide/actions/TemplateKindCombo.java b/platform/lang-impl/src/com/intellij/ide/actions/TemplateKindCombo.java index 59ac1694d9e9..1abe1c1ef7db 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/TemplateKindCombo.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/TemplateKindCombo.java @@ -24,18 +24,18 @@ import com.intellij.openapi.actionSystem.KeyboardShortcut; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.util.Trinity; import com.intellij.ui.ComboboxSpeedSearch; +import com.intellij.ui.ComboboxWithBrowseButton; import org.jetbrains.annotations.Nullable; import javax.swing.*; +import java.awt.event.ActionListener; import java.awt.event.KeyEvent; -public class TemplateKindCombo extends JComboBox { +public class TemplateKindCombo extends ComboboxWithBrowseButton { private static final Logger LOG = Logger.getInstance("#com.intellij.ide.actions.TemplateKindCombo"); public TemplateKindCombo() { - super(); - - setRenderer(new ListCellRendererWrapper(getRenderer()) { + getComboBox().setRenderer(new ListCellRendererWrapper(getComboBox().getRenderer()) { @Override public void customize(final JList list, final Object value, final int index, final boolean selected, final boolean cellHasFocus) { if (value instanceof Trinity) { @@ -45,7 +45,7 @@ public class TemplateKindCombo extends JComboBox { } }); - new ComboboxSpeedSearch(this) { + new ComboboxSpeedSearch(getComboBox()) { @Override protected String getElementText(Object element) { if (element instanceof Trinity) { @@ -54,28 +54,30 @@ public class TemplateKindCombo extends JComboBox { return null; } }; + setButtonListener(null); } public void addItem(String presentableName, Icon icon, String templateName) { - addItem(new Trinity(presentableName, icon, templateName)); + getComboBox().addItem(new Trinity(presentableName, icon, templateName)); } public String getSelectedName() { //noinspection unchecked - final Trinity trinity = (Trinity)getSelectedItem(); + final Trinity trinity = (Trinity)getComboBox().getSelectedItem(); if (trinity == null) { - LOG.error("Model: " + getModel()); + // design time + return null; } return trinity.third; } public void setSelectedName(@Nullable String name) { if (name == null) return; - ComboBoxModel model = getModel(); + ComboBoxModel model = getComboBox().getModel(); for (int i = 0, n = model.getSize(); i < n; i++) { Trinity trinity = (Trinity)model.getElementAt(i); if (name.equals(trinity.third)) { - setSelectedItem(trinity); + getComboBox().setSelectedItem(trinity); return; } } @@ -97,15 +99,29 @@ public class TemplateKindCombo extends JComboBox { } private void scrollBy(int delta) { - final int size = getModel().getSize(); - int next = getSelectedIndex() + delta; + if (delta == 0) return; + final int size = getComboBox().getModel().getSize(); + int next = getComboBox().getSelectedIndex() + delta; if (next < 0 || next >= size) { if (!UISettings.getInstance().CYCLE_SCROLLING) { return; } next = (next + size) % size; } - setSelectedIndex(next); + getComboBox().setSelectedIndex(next); } + /** + * @param listener pass null to hide browse button + */ + public void setButtonListener(@Nullable ActionListener listener) { + getButton().setVisible(listener != null); + if (listener != null) { + addActionListener(listener); + } + } + + public void clear() { + getComboBox().removeAllItems(); + } } diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java index f9ca00a2875a..195522df5a41 100644 --- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java +++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/NavBarRootPaneExtension.java @@ -21,12 +21,14 @@ package com.intellij.ide.navigationToolbar; import com.intellij.ide.ui.UISettings; +import com.intellij.ide.ui.UISettingsListener; +import com.intellij.openapi.actionSystem.*; +import com.intellij.openapi.actionSystem.ex.ComboBoxAction; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.IconLoader; import com.intellij.openapi.wm.impl.IdeRootPaneNorthExtension; import com.intellij.ui.ScrollPaneFactory; import com.intellij.ui.components.panels.OpaquePanel; -import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NonNls; import javax.swing.*; @@ -37,51 +39,100 @@ import java.awt.event.MouseEvent; public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension { private static final Icon CROSS_ICON = IconLoader.getIcon("/actions/cross.png"); - private JComponent myPanel; + private JComponent myWrapperPanel; @NonNls public static final String NAV_BAR = "NavBar"; private final Project myProject; private NavBarPanel myNavigationBar; + private JPanel myRunPanel; public NavBarRootPaneExtension(Project project) { myProject = project; + + UISettings.getInstance().addUISettingsListener(new UISettingsListener() { + @Override + public void uiSettingsChanged(UISettings source) { + toggleRunPanel(!source.SHOW_MAIN_TOOLBAR); + } + }, project); } public JComponent getComponent() { - if (myPanel == null) { - myPanel = new OpaquePanel.List(new BorderLayout()); - - myNavigationBar = new NavBarPanel(myProject); - - JScrollPane scroller = ScrollPaneFactory.createScrollPane(myNavigationBar); - scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); - scroller.setHorizontalScrollBar(null); - scroller.setBorder(null); - - myPanel.add(scroller, BorderLayout.CENTER); - - JLabel closeLabel = new JLabel(CROSS_ICON); - - closeLabel.addMouseListener(new MouseAdapter() { - public void mouseClicked(final MouseEvent e) { - UISettings.getInstance().SHOW_NAVIGATION_BAR = false; - uiSettingsChanged(UISettings.getInstance()); - } - }); - myPanel.add(closeLabel, BorderLayout.EAST); - - myPanel.putClientProperty("NavBarPanel", myNavigationBar); - myNavigationBar.installBorder(0, true); - myPanel.setBorder(myNavigationBar.getBorder()); - myNavigationBar.setBorder(null); + if (myWrapperPanel == null) { + myWrapperPanel = new JPanel(new BorderLayout()); + myWrapperPanel.add(buildNavBarPanel(), BorderLayout.CENTER); + myWrapperPanel.putClientProperty("NavBarPanel", myNavigationBar); + toggleRunPanel(!UISettings.getInstance().SHOW_MAIN_TOOLBAR); } - return myPanel; + return myWrapperPanel; + } + + private void toggleRunPanel(final boolean show) { + if (show && myRunPanel == null) { + final ActionManager manager = ActionManager.getInstance(); + final AnAction toolbarRunGroup = manager.getAction("ToolbarRunGroup"); + if (toolbarRunGroup instanceof DefaultActionGroup) { + final DefaultActionGroup group = (DefaultActionGroup)toolbarRunGroup; + boolean needsGap = false; + int i = 0; + for (final AnAction action : group.getChildActionsOrStubs()) { + if (action instanceof ComboBoxAction) { + needsGap = i == 0; + break; + } else if (!(action instanceof Separator)) { + i++; + } + } + + final ActionToolbar actionToolbar = manager.createActionToolbar(ActionPlaces.UNKNOWN, group, true); + final JComponent component = actionToolbar.getComponent(); + component.setBackground(Color.WHITE); + myRunPanel = new JPanel(new BorderLayout()); + final Color color = myRunPanel.getBackground() != null ? myRunPanel.getBackground().darker() : Color.darkGray; + myRunPanel.setBackground(Color.WHITE); + myRunPanel.add(component); + myRunPanel.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createMatteBorder(0, 1, 1, 0, color), + BorderFactory.createEmptyBorder(1, needsGap ? 5 : 1, 0, 0))); + myWrapperPanel.add(myRunPanel, BorderLayout.EAST); + } + } + else if (!show && myRunPanel != null) { + myWrapperPanel.remove(myRunPanel); + myRunPanel = null; + } + } + + private JComponent buildNavBarPanel() { + final JComponent result = new OpaquePanel.List(new BorderLayout()); + myNavigationBar = new NavBarPanel(myProject); + + JScrollPane scroller = ScrollPaneFactory.createScrollPane(myNavigationBar); + scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); + scroller.setHorizontalScrollBar(null); + scroller.setBorder(null); + + result.add(scroller, BorderLayout.CENTER); + + JLabel closeLabel = new JLabel(CROSS_ICON); + + closeLabel.addMouseListener(new MouseAdapter() { + public void mouseClicked(final MouseEvent e) { + UISettings.getInstance().SHOW_NAVIGATION_BAR = false; + uiSettingsChanged(UISettings.getInstance()); + } + }); + result.add(closeLabel, BorderLayout.EAST); + + myNavigationBar.installBorder(0, true); + result.setBorder(myNavigationBar.getBorder()); + myNavigationBar.setBorder(null); + return result; } public void uiSettingsChanged(final UISettings settings) { if (myNavigationBar != null) { myNavigationBar.updateState(settings.SHOW_NAVIGATION_BAR); - myPanel.setVisible(settings.SHOW_NAVIGATION_BAR); + myWrapperPanel.setVisible(settings.SHOW_NAVIGATION_BAR); } } @@ -90,9 +141,11 @@ public class NavBarRootPaneExtension extends IdeRootPaneNorthExtension { return NAV_BAR; } + public void dispose() { - myPanel.setVisible(false); - myPanel = null; + myWrapperPanel.setVisible(false); + myWrapperPanel = null; + myRunPanel = null; myNavigationBar = null; } } diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/LangScriptingContextConfigurable.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/LangScriptingContextConfigurable.java index 9dc58225f6a3..350547a5a967 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/LangScriptingContextConfigurable.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/LangScriptingContextConfigurable.java @@ -33,14 +33,13 @@ import javax.swing.*; public class LangScriptingContextConfigurable implements Configurable { private ScriptingLibrariesPanel myPanel; private LangScriptingContextProvider myProvider; - private ModifiableRootModel myRootModel; + private ScriptingLibraryManager myLibManager; - public LangScriptingContextConfigurable(ModifiableRootModel rootModel, LangScriptingContextProvider provider) { - LibraryTable libTable = rootModel != null ? - rootModel.getModuleLibraryTable() : null; + public LangScriptingContextConfigurable(ScriptingLibraryManager libManager, LangScriptingContextProvider provider) { + LibraryTable libTable = libManager.getLibraryTable(); myPanel = new ScriptingLibrariesPanel(libTable); myProvider = provider; - myRootModel = rootModel; + myLibManager = libManager; } @Nls @@ -71,19 +70,19 @@ public class LangScriptingContextConfigurable implements Configurable { @Override public void apply() throws ConfigurationException { - if (myRootModel != null) { - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - myRootModel.commit(); - } - }); - } + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + myLibManager.commitModel(); + myPanel.resetTable(myLibManager.getLibraryTable()); + } + }); } @Override public void reset() { - //To change body of implemented methods use File | Settings | File Templates. + myLibManager.resetModel(); + myPanel.resetTable(myLibManager.getLibraryTable()); } @Override diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingContextsConfigurable.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingContextsConfigurable.java index c04705b24006..a81190614687 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingContextsConfigurable.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingContextsConfigurable.java @@ -33,14 +33,12 @@ public class ScriptingContextsConfigurable implements Configurable, Configurable private MainScriptingContextsPanel myPanel; private String myLangNames; - private Project myProject; - private ModifiableRootModel myRootModel; + private ScriptingLibraryManager myLibManager; public ScriptingContextsConfigurable(Project project) { myPanel = new MainScriptingContextsPanel(); myLangNames = getLangNames(); - myProject = project; - myRootModel = ScriptingLibraryManager.getRootModel(project); + myLibManager = new ScriptingLibraryManager(project); } @Nls @@ -71,9 +69,7 @@ public class ScriptingContextsConfigurable implements Configurable, Configurable @Override public void apply() throws ConfigurationException { - if (myRootModel != null) { - myRootModel.commit(); - } + myLibManager.commitModel(); } @Override @@ -83,14 +79,14 @@ public class ScriptingContextsConfigurable implements Configurable, Configurable @Override public void disposeUIResources() { - disposeModel(); + myLibManager.disposeModel(); } @Override public Configurable[] getConfigurables() { ArrayList configurables = new ArrayList(); for (LangScriptingContextProvider provider : LangScriptingContextProvider.getProviders()) { - configurables.add(new LangScriptingContextConfigurable(myRootModel, provider)); + configurables.add(new LangScriptingContextConfigurable(myLibManager, provider)); } return configurables.toArray(new LangScriptingContextConfigurable[configurables.size()]); } @@ -104,9 +100,4 @@ public class ScriptingContextsConfigurable implements Configurable, Configurable return result.substring(0, result.length() - 1); } - public void disposeModel() { - if (myRootModel != null && !myRootModel.isDisposed()) { - myRootModel.dispose(); - } - } } diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryManager.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryManager.java index 558314a9c0f6..9a3a9ec9d5bc 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryManager.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ScriptingLibraryManager.java @@ -32,8 +32,16 @@ public class ScriptingLibraryManager { public static final String WEB_MODULE_TYPE = "WEB_MODULE"; + private ModifiableRootModel myRootModel; + private Project myProject; + + public ScriptingLibraryManager(Project project) { + myProject = project; + myRootModel = getRootModel(project); + } + @Nullable - public static ModifiableRootModel getRootModel(Project project) { + private static ModifiableRootModel getRootModel(Project project) { for (Module module : ModuleManager.getInstance(project).getModules()) { if (WEB_MODULE_TYPE.equals(module.getModuleType().getId())) { return ModuleRootManager.getInstance(module).getModifiableModel(); @@ -41,4 +49,30 @@ public class ScriptingLibraryManager { } return null; } + + public void disposeModel() { + if (myRootModel != null && !myRootModel.isDisposed()) { + myRootModel.dispose(); + myRootModel = null; + } + } + + public void commitModel() { + if (myRootModel != null && !myRootModel.isDisposed()) { + myRootModel.commit(); + } + } + + public void resetModel() { + disposeModel(); + myRootModel = getRootModel(myProject); + } + + @Nullable + public LibraryTable getLibraryTable() { + if (myRootModel != null) { + return myRootModel.getModuleLibraryTable(); + } + return null; + } } diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/ScriptingLibrariesPanel.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/ScriptingLibrariesPanel.java index dd5957d05115..67391b1ecfb3 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/ScriptingLibrariesPanel.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/ScriptingLibrariesPanel.java @@ -74,4 +74,10 @@ public class ScriptingLibrariesPanel { return myModified; } + public void resetTable(LibraryTable libTable) { + myLibTableModel.resetTable(libTable); + myModified = false; + myLibraryTable.repaint(); + } + } diff --git a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/ScriptingLibraryTableModel.java b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/ScriptingLibraryTableModel.java index 0a298b429c39..b5d66ee5f39a 100644 --- a/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/ScriptingLibraryTableModel.java +++ b/platform/lang-impl/src/com/intellij/ide/scriptingContext/ui/ScriptingLibraryTableModel.java @@ -36,6 +36,10 @@ public class ScriptingLibraryTableModel extends AbstractTableModel { myLibTable = libTable; } + public void resetTable(LibraryTable libTable) { + myLibTable = libTable; + } + @Override public int getRowCount() { if (myLibTable != null) { diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameDialog.java b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameDialog.java index 9c32630b7933..95c17948c896 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/RenameDialog.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/RenameDialog.java @@ -16,8 +16,6 @@ package com.intellij.refactoring.rename; -import com.intellij.codeInsight.lookup.LookupElement; -import com.intellij.codeInsight.lookup.LookupManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.extensions.Extensions; @@ -45,11 +43,9 @@ import org.jetbrains.annotations.TestOnly; import javax.swing.*; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.InputEvent; -import java.awt.event.KeyEvent; -import java.util.*; +import java.util.HashMap; +import java.util.LinkedHashSet; +import java.util.Map; public class RenameDialog extends RefactoringDialog { private static final Logger LOG = Logger.getInstance("#com.intellij.refactoring.rename.RenameDialog"); @@ -126,11 +122,6 @@ public class RenameDialog extends RefactoringDialog { }; myNameSuggestionsField.addDataChangedListener(myNameChangedListener); - myNameSuggestionsField.getComponent().registerKeyboardAction(new ActionListener() { - public void actionPerformed(ActionEvent e) { - completeVariable(myNameSuggestionsField.getEditor()); - } - }, KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.CTRL_MASK), JComponent.WHEN_IN_FOCUSED_WINDOW); } public String[] getSuggestedNames() { @@ -146,21 +137,6 @@ public class RenameDialog extends RefactoringDialog { return ArrayUtil.toStringArray(result); } - private void completeVariable(Editor editor) { - final String prefix = myNameSuggestionsField.getEnteredName(); - Collection items = null; - for(NameSuggestionProvider provider: Extensions.getExtensions(NameSuggestionProvider.EP_NAME)) { - items = provider.completeName(myPsiElement, myNameSuggestionContext, prefix); - if (items != null) break; - } - - if (items != null) { - final LookupElement[] lookupItems = items.toArray(new LookupElement[items.size()]); - editor.getCaretModel().moveToOffset(prefix.length()); - editor.getSelectionModel().removeSelection(); - LookupManager.getInstance(myProject).showLookup(editor, lookupItems, prefix); - } - } public String getNewName() { return myNameSuggestionsField.getEnteredName().trim(); diff --git a/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java b/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java index e7e2a0bf83f0..0328885ae07f 100644 --- a/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java +++ b/platform/platform-impl/src/com/intellij/codeInsight/hint/HintManagerImpl.java @@ -210,18 +210,29 @@ public class HintManagerImpl extends HintManager implements Disposable { ((ScrollAwareHint)hint.getComponent()).editorScrolled(); } + if (!hint.isVisible()) { + return; + } + Editor editor = e.getEditor(); if (!editor.getComponent().isShowing() || editor.isOneLineMode()) return; Rectangle newRectangle = e.getOldRectangle(); Rectangle oldRectangle = e.getNewRectangle(); Rectangle bounds = hint.getBounds(); - Point location = bounds.getLocation(); + Point location; - location = SwingUtilities.convertPoint( - editor.getComponent().getRootPane().getLayeredPane(), - location, - editor.getContentComponent() - ); + final Window window = SwingUtilities.getWindowAncestor(hint.getComponent()); + final boolean realPopup = window != null && window != SwingUtilities.getWindowAncestor(editor.getComponent()); + if (realPopup) { + location = window.getLocationOnScreen(); + SwingUtilities.convertPointFromScreen(location, editor.getContentComponent()); + } else { + location = SwingUtilities.convertPoint( + editor.getComponent().getRootPane().getLayeredPane(), + bounds.getLocation(), + editor.getContentComponent() + ); + } int xOffset = location.x - oldRectangle.x; @@ -232,13 +243,18 @@ public class HintManagerImpl extends HintManager implements Disposable { final boolean valid = hideIfOutOfEditor ? oldRectangle.contains(newBounds) : oldRectangle.intersects(newBounds); if (valid) { - location = SwingUtilities.convertPoint( - editor.getContentComponent(), - location, - editor.getComponent().getRootPane().getLayeredPane() - ); + if (!realPopup) { + location = SwingUtilities.convertPoint( + editor.getContentComponent(), + location, + editor.getComponent().getRootPane().getLayeredPane() + ); + hint.updateBounds(location.x, location.y); + } else { + SwingUtilities.convertPointToScreen(location, editor.getContentComponent()); + window.setLocation(location); + } - hint.updateBounds(location.x, location.y); } else { hint.hide(); diff --git a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java index 0d66b46bb2af..1c341ab07bcb 100644 --- a/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/actionSystem/impl/ActionToolbarImpl.java @@ -363,11 +363,14 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar { if (myOrientation == SwingConstants.HORIZONTAL) { int eachX = 0; int eachY = 0; + int maxHeight = 0; for (int i = 0; i < componentCount; i++) { final Component eachComp = getComponent(i); final boolean isLast = i == componentCount - 1; final Rectangle eachBound = new Rectangle(eachComp.getPreferredSize()); + maxHeight = Math.max(eachBound.height, maxHeight); + if (!full) { boolean inside; if (isLast) { @@ -408,6 +411,13 @@ public class ActionToolbarImpl extends JPanel implements ActionToolbar { bounds.get(i).setBounds(eachBound); } + + for (final Rectangle r : bounds) { + if (r.height < maxHeight && r.y == 0) { + r.y = (maxHeight - r.height) / 2; + } + } + } else { int eachX = 0; diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java index 336c1a561a1d..5c5c5ffbbe09 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/DocumentImpl.java @@ -468,7 +468,9 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx { return null; // suppress events in shutdown hook } DocumentEvent event = new DocumentEventImpl(this, offset, oldString, newString, myModificationStamp, wholeTextReplaced); - + //System.out.printf("%nbefore change: offset=%d, old text='%s', new text='%s', document modification stamp=%d%nDocument:'%s'%n", + // event.getOffset(), event.getOldFragment(), event.getNewFragment(), event.getDocument().getModificationStamp(), + // event.getDocument().getText()); for (int i = myDocumentListeners.size() - 1; i >= 0; i--) { try { myDocumentListeners.get(i).beforeDocumentChange(event); @@ -484,6 +486,8 @@ public class DocumentImpl extends UserDataHolderBase implements DocumentEx { @SuppressWarnings({"ForLoopReplaceableByForEach"}) private void changedUpdate(DocumentEvent event, long newModificationStamp) { + //System.out.printf("after change: new modification stamp=%d%ndocument='%s'%n", event.getDocument().getModificationStamp(), + // event.getDocument().getText()); if (ShutDownTracker.isShutdownHookRunning()) { return; // suppress events in shutdown hook } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java index 29a34a6ce8a2..3c6c4560bc37 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/SoftWrapModelImpl.java @@ -116,11 +116,7 @@ public class SoftWrapModelImpl implements SoftWrapModelEx, PrioritizedDocumentLi } Rectangle visibleArea = myEditor.getScrollingModel().getVisibleArea(); - if (visibleArea.width <= 0 || visibleArea.height <= 0) { - return false; - } - - if (!ApplicationManager.getApplication().isUnitTestMode() && myEditor.getScrollingModel().getVisibleArea().width <= 0) { + if (!ApplicationManager.getApplication().isUnitTestMode() && (visibleArea.width <= 0 || visibleArea.height <= 0)) { return false; } diff --git a/platform/util/src/com/intellij/openapi/util/ShutDownTracker.java b/platform/util/src/com/intellij/openapi/util/ShutDownTracker.java index 36ed9dbcec22..35cacacd5065 100644 --- a/platform/util/src/com/intellij/openapi/util/ShutDownTracker.java +++ b/platform/util/src/com/intellij/openapi/util/ShutDownTracker.java @@ -25,7 +25,7 @@ public class ShutDownTracker implements Runnable { private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.util.ShutDownTracker"); private static ShutDownTracker ourInstance; private final List myThreads = new ArrayList(); - private final List myShutdownThreads = new ArrayList(); + private final LinkedList myShutdownThreads = new LinkedList(); private final LinkedList myShutdownTasks = new LinkedList(); private volatile boolean myIsShutdownHookRunning = false; @@ -48,17 +48,6 @@ public class ShutDownTracker implements Runnable { public void run() { myIsShutdownHookRunning = true; - while (!myShutdownTasks.isEmpty()) { - // task can change myShutdownTasks - final Runnable task = myShutdownTasks.removeLast(); - try { - task.run(); - } - catch (Throwable e) { - LOG.error(e); - } - } - Thread[] threads = getStopperThreads(); while (threads.length > 0) { Thread thread = threads[0]; @@ -77,14 +66,27 @@ public class ShutDownTracker implements Runnable { } threads = getStopperThreads(); } - - for (int idx = myShutdownThreads.size() - 1; idx >= 0; idx--) { - final Thread thread = myShutdownThreads.remove(idx); - thread.start(); + + while (!myShutdownTasks.isEmpty()) { + // task can change myShutdownTasks + final Runnable task = myShutdownTasks.removeLast(); try { - thread.join(); + task.run(); + } + catch (Throwable e) { + LOG.error(e); + } + } + + if (!myShutdownThreads.isEmpty()) { + for (Thread thread = myShutdownThreads.removeLast(); thread != null; thread = myShutdownThreads.removeLast()) { + thread.start(); + try { + thread.join(); + } + catch (InterruptedException ignored) { + } } - catch (InterruptedException e) { } } } @@ -105,7 +107,7 @@ public class ShutDownTracker implements Runnable { } public void registerShutdownThread(final Thread thread) { - myShutdownThreads.add(thread); + myShutdownThreads.addLast(thread); } public void registerShutdownThread(int index, final Thread thread) { diff --git a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java index 25f26f933a6f..c6c1220ae681 100644 --- a/platform/util/src/com/intellij/openapi/util/io/FileUtil.java +++ b/platform/util/src/com/intellij/openapi/util/io/FileUtil.java @@ -19,7 +19,6 @@ package com.intellij.openapi.util.io; import com.intellij.CommonBundle; import com.intellij.Patches; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.util.ShutDownTracker; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.Processor; @@ -429,14 +428,14 @@ public class FileUtil { public void run() { final Thread currentThread = Thread.currentThread(); currentThread.setPriority(Thread.MIN_PRIORITY); - ShutDownTracker.getInstance().registerStopperThread(currentThread); + //ShutDownTracker.getInstance().registerStopperThread(currentThread); try { for (File tempFile : tempFiles) { delete(tempFile); } } finally { - ShutDownTracker.getInstance().unregisterStopperThread(currentThread); + //ShutDownTracker.getInstance().unregisterStopperThread(currentThread); currentThread.setPriority(Thread.NORM_PRIORITY); } } diff --git a/platform/util/src/com/intellij/util/containers/StripedLockConcurrentHashMap.java b/platform/util/src/com/intellij/util/containers/StripedLockConcurrentHashMap.java index ccfcf4ef1d02..13feab624273 100644 --- a/platform/util/src/com/intellij/util/containers/StripedLockConcurrentHashMap.java +++ b/platform/util/src/com/intellij/util/containers/StripedLockConcurrentHashMap.java @@ -18,6 +18,7 @@ package com.intellij.util.containers; import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.*; import java.util.concurrent.ConcurrentMap; @@ -69,7 +70,7 @@ public class StripedLockConcurrentHashMap extends _CHMSegment implem /* ---------------- Public operations -------------- */ - public StripedLockConcurrentHashMap(TObjectHashingStrategy hashingStrategy) { + public StripedLockConcurrentHashMap(@Nullable TObjectHashingStrategy hashingStrategy) { this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR, hashingStrategy); } @@ -90,7 +91,7 @@ public class StripedLockConcurrentHashMap extends _CHMSegment implem this(initialCapacity, loadFactor, null); } - public StripedLockConcurrentHashMap(int initialCapacity, float loadFactor, TObjectHashingStrategy hashingStrategy) { + public StripedLockConcurrentHashMap(int initialCapacity, float loadFactor, @Nullable TObjectHashingStrategy hashingStrategy) { super(getInitCap(initialCapacity, loadFactor), loadFactor, hashingStrategy); } @@ -138,7 +139,7 @@ public class StripedLockConcurrentHashMap extends _CHMSegment implem * * @param t the map */ - public StripedLockConcurrentHashMap(Map t) { + public StripedLockConcurrentHashMap(@NotNull Map t) { this(Math.max((int)(t.size() / DEFAULT_LOAD_FACTOR) + 1, 11), DEFAULT_LOAD_FACTOR); putAll(t); } @@ -166,7 +167,7 @@ public class StripedLockConcurrentHashMap extends _CHMSegment implem * @throws NullPointerException if the key is * null. */ - public V get(Object key) { + public V get(@NotNull Object key) { K kKey = (K)key; int hash = myHashingStrategy.computeHashCode(kKey); // throws NullPointerException if key null return get(kKey, hash); @@ -182,7 +183,7 @@ public class StripedLockConcurrentHashMap extends _CHMSegment implem * @throws NullPointerException if the key is * null. */ - public boolean containsKey(Object key) { + public boolean containsKey(@NotNull Object key) { K kKey = (K)key; int hash = myHashingStrategy.computeHashCode(kKey); // throws NullPointerException if key null return containsKey(kKey, hash); @@ -203,7 +204,7 @@ public class StripedLockConcurrentHashMap extends _CHMSegment implem * false otherwise. * @throws NullPointerException if the value is null. */ - public boolean contains(Object value) { + public boolean contains(@NotNull Object value) { return containsValue(value); } @@ -262,7 +263,10 @@ public class StripedLockConcurrentHashMap extends _CHMSegment implem */ public void putAll(@NotNull Map t) { for (Entry e : t.entrySet()) { - put(e.getKey(), e.getValue()); + V value = e.getValue(); + if (value != null) { // null is possible if the entry has just been removed + put(e.getKey(), value); + } } } @@ -507,20 +511,24 @@ public class StripedLockConcurrentHashMap extends _CHMSegment implem } final class KeyIterator extends HashIterator implements Iterator, Enumeration { + @NotNull public K next() { return nextEntry().key; } + @NotNull public K nextElement() { return nextEntry().key; } } final class ValueIterator extends HashIterator implements Iterator, Enumeration { + @NotNull public V next() { return nextEntry().value; } + @NotNull public V nextElement() { return nextEntry().value; } @@ -534,11 +542,13 @@ public class StripedLockConcurrentHashMap extends _CHMSegment implem * itself acts as a forwarding pseudo-entry. */ final class EntryIterator extends HashIterator implements Entry, Iterator> { + @NotNull public Entry next() { nextEntry(); return this; } + @NotNull public K getKey() { if (lastReturned == null) { throw new IllegalStateException("Entry was removed"); @@ -546,6 +556,7 @@ public class StripedLockConcurrentHashMap extends _CHMSegment implem return lastReturned.key; } + @Nullable("null means the entry has just been removed") public V getValue() { if (lastReturned == null) { throw new IllegalStateException("Entry was removed"); @@ -553,7 +564,7 @@ public class StripedLockConcurrentHashMap extends _CHMSegment implem return get(lastReturned.key); } - public V setValue(V value) { + public V setValue(@NotNull V value) { if (lastReturned == null) { throw new IllegalStateException("Entry was removed"); } @@ -571,7 +582,7 @@ public class StripedLockConcurrentHashMap extends _CHMSegment implem Entry e = (Entry)o; K o1 = getKey(); K o2 = (K)e.getKey(); - return (o1 == null ? o2 == null : myHashingStrategy.equals(o1, o2)) && eq(getValue(), e.getValue()); + return myHashingStrategy.equals(o1, o2) && getValue().equals(e.getValue()); } public int hashCode() { @@ -582,8 +593,7 @@ public class StripedLockConcurrentHashMap extends _CHMSegment implem Object k = getKey(); Object v = getValue(); - return (k == null ? 0 : k.hashCode()) ^ - (v == null ? 0 : v.hashCode()); + return k.hashCode() ^ v.hashCode(); } public String toString() { @@ -591,15 +601,8 @@ public class StripedLockConcurrentHashMap extends _CHMSegment implem if (lastReturned == null) { return super.toString(); } - else { - return getKey() + "=" + getValue(); - } + return getKey() + "=" + getValue(); } - - boolean eq(Object o1, Object o2) { - return o1 == null ? o2 == null : o1.equals(o2); - } - } final class KeySet extends AbstractSet { @@ -728,23 +731,25 @@ public class StripedLockConcurrentHashMap extends _CHMSegment implem * is made accessible. */ final class SimpleEntry implements Entry { - K key; + final K key; V value; - public SimpleEntry(Entry e) { + public SimpleEntry(@NotNull Entry e) { key = e.getKey(); value = e.getValue(); } + @NotNull public K getKey() { return key; } + @NotNull public V getValue() { return value; } - public V setValue(V value) { + public V setValue(@NotNull V value) { V oldValue = this.value; this.value = value; return oldValue; @@ -756,21 +761,16 @@ public class StripedLockConcurrentHashMap extends _CHMSegment implem } Entry e = (Entry)o; K o2 = (K)e.getKey(); - return (key == null ? o2 == null : myHashingStrategy.equals(key, o2)) && eq(value, e.getValue()); + return myHashingStrategy.equals(key, o2) && value.equals(e.getValue()); } public int hashCode() { - return (key == null ? 0 : key.hashCode()) ^ - (value == null ? 0 : value.hashCode()); + return key.hashCode() ^ value.hashCode(); } public String toString() { return key + "=" + value; } - - boolean eq(Object o1, Object o2) { - return o1 == null ? o2 == null : o1.equals(o2); - } } static class CanonicalHashingStrategy implements TObjectHashingStrategy { @@ -790,7 +790,7 @@ public class StripedLockConcurrentHashMap extends _CHMSegment implem return h; } - public boolean equals(final K o1, final K o2) { + public boolean equals(@NotNull K o1, @NotNull K o2) { return o1.equals(o2); } } @@ -964,9 +964,7 @@ class _CHMSegment { HashEntry[] tab = table; int len = tab.length; for (int i = 0; i < len; i++) { - for (HashEntry e = tab[i]; - e != null; - e = e.next) { + for (HashEntry e = tab[i]; e != null; e = e.next) { V v = e.value; if (v == null) // recheck { @@ -1124,7 +1122,7 @@ class _CHMSegment { /* * Remove; match on key only if value null, else match both. */ - V remove(K key, int hash, Object value) { + V remove(@NotNull K key, int hash, @Nullable("null means don't care") Object value) { try { lock(); int c = count - 1; @@ -1188,9 +1186,9 @@ class _CHMSegment { * an unsynchronized access method. */ static final class HashEntry { - final K key; + @NotNull final K key; final int hash; - volatile V value; + @NotNull volatile V value; final HashEntry next; HashEntry(@NotNull K key, int hash, HashEntry next, @NotNull V value) { 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 1253c07886b3..fb3eea4db205 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 @@ -276,24 +276,29 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec } } + private VcsDirtyScopeManagerImpl getVcsManager() { + try { + return ((VcsDirtyScopeManagerImpl) VcsDirtyScopeManager.getInstance(myProject)); + } + catch(ProcessCanceledException ex) { + return null; + } + catch(Exception ex) { + LOG.error(ex); + return null; + } + } + private void updateImmediately(final AtomicSectionsAware atomicSectionsAware) { - FileHolderComposite composite; - ChangeListWorker changeListWorker; + final FileHolderComposite composite; + final ChangeListWorker changeListWorker; final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(myProject); if (! vcsManager.hasActiveVcss()) return; - final VcsDirtyScopeManagerImpl dirtyScopeManager; - try { - dirtyScopeManager = ((VcsDirtyScopeManagerImpl) VcsDirtyScopeManager.getInstanceChecked(myProject)); - } - catch(ProcessCanceledException ex) { - return; - } - catch(Exception ex) { - LOG.error(ex); - return; - } + final VcsDirtyScopeManagerImpl dirtyScopeManager = getVcsManager(); + if (dirtyScopeManager == null) return; + final VcsInvalidated invalidated = dirtyScopeManager.retrieveScopes(); if (invalidated == null || invalidated.isEmpty()) { // a hack here; but otherwise everything here should be refactored ;) @@ -305,6 +310,8 @@ public class ChangeListManagerImpl extends ChangeListManagerEx implements Projec final boolean wasEverythingDirty = invalidated.isEverythingDirty(); final List scopes = invalidated.getScopes(); + + try { checkIfDisposed(); diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeVfsListener.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeVfsListener.java index dd653c55f792..be64be80935e 100644 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeVfsListener.java +++ b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/VcsDirtyScopeVfsListener.java @@ -22,7 +22,8 @@ import com.intellij.openapi.project.ProjectLocator; import com.intellij.openapi.util.Pair; import com.intellij.openapi.vcs.FilePath; import com.intellij.openapi.vcs.FilePathImpl; -import com.intellij.openapi.vfs.*; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.openapi.vfs.newvfs.BulkFileListener; import com.intellij.openapi.vfs.newvfs.events.*; import com.intellij.util.containers.HashMap; @@ -71,13 +72,15 @@ public class VcsDirtyScopeVfsListener implements ApplicationComponent, BulkFileL // collect files and directories - sources of events for (VFileEvent event : events) { final VirtualFile file = getFileForEvent(event); - if (file == null) { continue; } + if (file == null) { + continue; + } if (event instanceof VFileDeleteEvent) { if (!file.isInLocalFileSystem()) { continue; } - dirtyFilesAndDirs.add(file); + dirtyFilesAndDirs.add(file, true); } else if (event instanceof VFileMoveEvent || event instanceof VFilePropertyChangeEvent) { - dirtyFilesAndDirs.addToFiles(file); + dirtyFilesAndDirs.addToFiles(file, false); // todo ? } } // and notify VCSDirtyScopeManager @@ -90,20 +93,22 @@ public class VcsDirtyScopeVfsListener implements ApplicationComponent, BulkFileL // collect files and directories - sources of events for (VFileEvent event : events) { final VirtualFile file = getFileForEvent(event); - if (file == null) { continue; } + if (file == null) { + continue; + } if (event instanceof VFileContentChangeEvent || event instanceof VFileCopyEvent || event instanceof VFileCreateEvent) { - dirtyFilesAndDirs.addToFiles(file); + dirtyFilesAndDirs.add(file, false); } else if (event instanceof VFilePropertyChangeEvent) { final VFilePropertyChangeEvent pce = (VFilePropertyChangeEvent) event; if (pce.getPropertyName().equals(VirtualFile.PROP_NAME)) { // if a file was renamed, then the file is dirty and its parent directory is dirty too; // if a directory was renamed, all its children are recursively dirty, the parent dir is also dirty but not recursively. - dirtyFilesAndDirs.add(file); // the file is dirty recursively - dirtyFilesAndDirs.addToFiles(file.getParent()); // directory is dirty alone. if parent is null - is checked in the method + dirtyFilesAndDirs.add(file, false); // the file is dirty recursively + dirtyFilesAndDirs.addToFiles(file.getParent(), false); // directory is dirty alone. if parent is null - is checked in the method } else { - dirtyFilesAndDirs.addToFiles(file); + dirtyFilesAndDirs.addToFiles(file, false); } } } @@ -133,11 +138,12 @@ public class VcsDirtyScopeVfsListener implements ApplicationComponent, BulkFileL * @param file file which path is to be added. * @param addToFiles If true, then add to dirty files even if it is a directory. Otherwise add to the proper set. */ - private void add(VirtualFile file, boolean addToFiles) { + public void add(VirtualFile file, boolean addToFiles, final boolean forDelete) { if (file == null) { return; } final boolean isDirectory = file.isDirectory(); // need to create FilePath explicitly without referring to VirtualFile because the path of VirtualFile may change - final FilePathImpl path = new FilePathImpl(new File(file.getPath()), isDirectory); + final FilePathImpl path = forDelete ? new FilePathImpl(new File(file.getPath()), isDirectory) : + new FilePathImpl(file); final Collection managers = getManagers(file); for (VcsDirtyScopeManager manager : managers) { @@ -158,16 +164,16 @@ public class VcsDirtyScopeVfsListener implements ApplicationComponent, BulkFileL /** * Adds files to the collection of files and directories - to the collection of directories (which are handled recursively). */ - void add(VirtualFile file) { - add(file, false); + void add(VirtualFile file, final boolean forDelete) { + add(file, false, forDelete); } /** * Adds to the collection of files. A file (even if it is a directory) is marked dirty alone (not recursively). * Use this method, when you want directory not to be marked dirty recursively. */ - void addToFiles(VirtualFile file) { - add(file, true); + void addToFiles(VirtualFile file, final boolean forDelete) { + add(file, true, forDelete); } void markDirty() { diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java index 0a3410af3b17..05d32ba2e114 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/util/PsiUtil.java @@ -562,11 +562,15 @@ public class PsiUtil { @Nullable public static PsiClass getContextClass(PsiElement context) { - GroovyPsiElement parent = PsiTreeUtil.getParentOfType(context, GrTypeDefinition.class, GroovyFileBase.class); - if (parent instanceof GrTypeDefinition) { - return (PsiClass)parent; - } else if (parent instanceof GroovyFileBase) { - return ((GroovyFileBase)parent).getScriptClass(); + while (context != null) { + if (context instanceof GrTypeDefinition) { + return (PsiClass)context; + } + else if (context instanceof GroovyFileBase) { + return ((GroovyFileBase)context).getScriptClass(); + } + + context = context.getContext(); } return null; } diff --git a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/IgnoredFilesTest.java b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/IgnoredFilesTest.java index 7ba9d18a01b3..7057c621a889 100644 --- a/plugins/svn4idea/testSource/org/jetbrains/idea/svn/IgnoredFilesTest.java +++ b/plugins/svn4idea/testSource/org/jetbrains/idea/svn/IgnoredFilesTest.java @@ -4,16 +4,22 @@ import com.intellij.ide.startup.impl.StartupManagerImpl; import com.intellij.openapi.components.ProjectComponent; import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.vcs.FileStatus; import com.intellij.openapi.vcs.ProjectLevelVcsManager; import com.intellij.openapi.vcs.changes.ChangeListManager; +import com.intellij.openapi.vcs.changes.IgnoredBeanFactory; +import com.intellij.openapi.vcs.changes.IgnoredFileBean; import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager; import com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl; import com.intellij.openapi.vfs.LocalFileSystem; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.testFramework.AbstractVcsTestCase; import com.intellij.testFramework.fixtures.IdeaTestFixtureFactory; import com.intellij.testFramework.fixtures.TempDirTestFixture; import org.junit.After; +import org.junit.Assert; import org.junit.Before; +import org.junit.Test; import java.io.File; @@ -46,7 +52,7 @@ public class IgnoredFilesTest extends AbstractVcsTestCase { myVcs = SvnVcs.getInstance(myProject); myVcsManager = (ProjectLevelVcsManagerImpl) ProjectLevelVcsManager.getInstance(myProject); myVcsManager.registerVcs(myVcs); - myVcsManager.setDirectoryMapping("", myVcs.getName()); + myVcsManager.setDirectoryMapping(myWorkingCopyDir.getPath(), myVcs.getName()); ((ProjectComponent) myChangeListManager).projectOpened(); myVcsDirtyScopeManager = VcsDirtyScopeManager.getInstance(myProject); @@ -72,7 +78,7 @@ public class IgnoredFilesTest extends AbstractVcsTestCase { } // they all blink now - /* + @Test public void testFileIsIgnored() throws Exception { final String filePath1 = myClientRoot.getPath() + "/a"; @@ -97,8 +103,8 @@ public class IgnoredFilesTest extends AbstractVcsTestCase { @Test public void testDirIsIgnored() throws Exception { - final String dirPath1 = myClientRoot.getPath() + "/a"; - final File dir = new File(dirPath1); + //final String dirPath1 = myClientRoot.getPath() + "/a"; + final File dir = new File(myClientRoot, "a"); dir.mkdir(); final File innerDir = new File(dir, "innerDir"); innerDir.mkdir(); @@ -111,7 +117,7 @@ public class IgnoredFilesTest extends AbstractVcsTestCase { final VirtualFile vf1 = myLocalFileSystem.refreshAndFindFileByIoFile(file1); final VirtualFile vf2 = myLocalFileSystem.refreshAndFindFileByIoFile(file2); - final IgnoredFileBean ignoredFileBean = IgnoredBeanFactory.ignoreUnderDirectory(dirPath1, myProject); + final IgnoredFileBean ignoredFileBean = IgnoredBeanFactory.ignoreUnderDirectory(FileUtil.toSystemIndependentName(dir.getPath()), myProject); myChangeListManager.addFilesToIgnore(ignoredFileBean); dirty(); @@ -124,7 +130,7 @@ public class IgnoredFilesTest extends AbstractVcsTestCase { @Test public void testPatternIsIgnored() throws Exception { final String dirPath1 = myClientRoot.getPath() + "/a"; - final File dir = new File(dirPath1); + final File dir = new File(myClientRoot, "a"); dir.mkdir(); final File innerDir = new File(dir, "innerDir"); innerDir.mkdir(); @@ -155,5 +161,5 @@ public class IgnoredFilesTest extends AbstractVcsTestCase { Assert.assertNotNull(vf); Assert.assertTrue(myChangeListManager.isIgnoredFile(vf)); Assert.assertEquals(FileStatus.IGNORED, myChangeListManager.getStatus(vf)); - } */ + } } diff --git a/xml/impl/src/com/intellij/codeInsight/completion/XmlAutoLookupHandler.java b/xml/impl/src/com/intellij/codeInsight/completion/XmlAutoLookupHandler.java deleted file mode 100644 index 90766757a1ee..000000000000 --- a/xml/impl/src/com/intellij/codeInsight/completion/XmlAutoLookupHandler.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2000-2009 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.intellij.codeInsight.completion; - -import com.intellij.lang.Language; -import com.intellij.lang.xml.XMLLanguage; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.util.Ref; -import com.intellij.psi.FileViewProvider; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiWhiteSpace; -import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; -import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider; -import com.intellij.xml.util.XmlUtil; - -/** - * - */ -public class XmlAutoLookupHandler extends CodeCompletionHandlerBase { - public XmlAutoLookupHandler() { - super(CompletionType.BASIC, false, false); - } - - protected void doComplete(final int offset1, final int offset2, final CompletionContext context, final FileCopyPatcher dummyIdentifier, Editor editor, - final int invocationCount) { - PsiFile file = context.file; - int offset = context.getStartOffset(); - - PsiElement lastElement = InjectedLanguageUtil.findElementAtNoCommit(file, offset - 1); - if (lastElement instanceof PsiFile) { //the very end of an injected file - lastElement = file.findElementAt(offset - 1); - } - if (lastElement == null) return; - - if(!doCompleteIfNeeded(offset1, offset2, context, dummyIdentifier, editor, invocationCount, file, lastElement)) { - // In template language based file we need to check element from template data language tree, not from base language - FileViewProvider fileViewProvider = file.getViewProvider(); - Language templateDataLanguage; - - final PsiElement parent = lastElement.getParent(); - if (fileViewProvider instanceof TemplateLanguageFileViewProvider && - (templateDataLanguage = ((TemplateLanguageFileViewProvider)fileViewProvider).getTemplateDataLanguage()) != parent.getLanguage()) { - lastElement = fileViewProvider.findElementAt(offset - 1, templateDataLanguage); - if (lastElement == null) return; - doCompleteIfNeeded(offset1, offset2, context, dummyIdentifier, editor, invocationCount, file, lastElement); - } - } - } - - private boolean doCompleteIfNeeded(int offset1, - int offset2, - CompletionContext context, - FileCopyPatcher dummyIdentifier, - Editor editor, - int invocationCount, PsiFile file, PsiElement lastElement) { - final Ref isRelevantLanguage = new Ref(); - final Ref isAnt = new Ref(); - String text = lastElement.getText(); - final int len = context.getStartOffset() - lastElement.getTextRange().getStartOffset(); - if (len < text.length()) { - text = text.substring(0, len); - } - if (text.equals("<") && isLanguageRelevant(lastElement, file, isRelevantLanguage, isAnt) || - text.equals(" ") && isLanguageRelevant(lastElement, file, isRelevantLanguage, isAnt) || - text.endsWith("${") && isLanguageRelevant(lastElement, file, isRelevantLanguage, isAnt) && isAnt.get().booleanValue() || - text.endsWith("@{") && isLanguageRelevant(lastElement, file, isRelevantLanguage, isAnt) && isAnt.get().booleanValue() || - text.endsWith(" isRelevantLanguage, - final Ref isAnt) { - Boolean isAntFile = isAnt.get(); - if (isAntFile == null) { - isAntFile = XmlUtil.isAntFile(file); - isAnt.set(isAntFile); - } - Boolean result = isRelevantLanguage.get(); - if (result == null) { - Language language = element.getLanguage(); - if (element instanceof PsiWhiteSpace) language = element.getParent().getLanguage(); - result = language instanceof XMLLanguage || isAntFile.booleanValue(); - isRelevantLanguage.set(result); - } - return result.booleanValue(); - } -} diff --git a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlAutoPopupHandler.java b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlAutoPopupHandler.java index cbcc831b4d7b..a0f5406fc740 100644 --- a/xml/impl/src/com/intellij/codeInsight/editorActions/XmlAutoPopupHandler.java +++ b/xml/impl/src/com/intellij/codeInsight/editorActions/XmlAutoPopupHandler.java @@ -16,17 +16,20 @@ package com.intellij.codeInsight.editorActions; import com.intellij.codeInsight.AutoPopupController; -import com.intellij.codeInsight.CodeInsightSettings; -import com.intellij.codeInsight.completion.XmlAutoLookupHandler; +import com.intellij.lang.Language; import com.intellij.lang.xml.XMLLanguage; -import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiDocumentManager; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Ref; +import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import com.intellij.psi.util.PsiUtilBase; +import com.intellij.psi.PsiWhiteSpace; +import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; +import com.intellij.psi.templateLanguages.TemplateLanguageFileViewProvider; import com.intellij.psi.xml.XmlTag; +import com.intellij.xml.util.XmlUtil; public class XmlAutoPopupHandler extends TypedHandlerDelegate { public Result checkAutoPopup(final char charTyped, final Project project, final Editor editor, final PsiFile file) { @@ -53,24 +56,73 @@ public class XmlAutoPopupHandler extends TypedHandlerDelegate { } public static void autoPopupXmlLookup(final Project project, final Editor editor){ - final CodeInsightSettings settings = CodeInsightSettings.getInstance(); - if (settings.AUTO_POPUP_COMPLETION_LOOKUP) { - final Runnable request = new Runnable(){ - public void run(){ - PsiDocumentManager.getInstance(project).commitAllDocuments(); + AutoPopupController.getInstance(project).autoPopupMemberLookup(editor, new Condition() { + @Override + public boolean value(PsiFile file) { + int offset = editor.getCaretModel().getOffset(); - final PsiFile file = PsiUtilBase.getPsiFileInEditor(editor, project); - if (file == null) return; - - CommandProcessor.getInstance().executeCommand(project, new Runnable() { - public void run() { - new XmlAutoLookupHandler().invoke(project, editor, file); - } - }, null, null); + PsiElement lastElement = InjectedLanguageUtil.findElementAtNoCommit(file, offset - 1); + if (lastElement instanceof PsiFile) { //the very end of an injected file + lastElement = file.findElementAt(offset - 1); } - }; - AutoPopupController.getInstance(project).invokeAutoPopupRunnable(request, settings.AUTO_LOOKUP_DELAY); - } + if (lastElement == null) return false; + + if (doCompleteIfNeeded(offset, file, lastElement)) { + return true; + } + + FileViewProvider fileViewProvider = file.getViewProvider(); + Language templateDataLanguage; + + final PsiElement parent = lastElement.getParent(); + if (fileViewProvider instanceof TemplateLanguageFileViewProvider && + (templateDataLanguage = ((TemplateLanguageFileViewProvider)fileViewProvider).getTemplateDataLanguage()) != parent.getLanguage()) { + lastElement = fileViewProvider.findElementAt(offset - 1, templateDataLanguage); + if (lastElement == null) return false; + return doCompleteIfNeeded(offset, file, lastElement); + } + return false; + } + }); } + private static boolean doCompleteIfNeeded(int offset, PsiFile file, PsiElement lastElement) { + final Ref isRelevantLanguage = new Ref(); + final Ref isAnt = new Ref(); + String text = lastElement.getText(); + final int len = offset - lastElement.getTextRange().getStartOffset(); + if (len < text.length()) { + text = text.substring(0, len); + } + if (text.equals("<") && isLanguageRelevant(lastElement, file, isRelevantLanguage, isAnt) || + text.equals(" ") && isLanguageRelevant(lastElement, file, isRelevantLanguage, isAnt) || + text.endsWith("${") && isLanguageRelevant(lastElement, file, isRelevantLanguage, isAnt) && isAnt.get().booleanValue() || + text.endsWith("@{") && isLanguageRelevant(lastElement, file, isRelevantLanguage, isAnt) && isAnt.get().booleanValue() || + text.endsWith(" isRelevantLanguage, + final Ref isAnt) { + Boolean isAntFile = isAnt.get(); + if (isAntFile == null) { + isAntFile = XmlUtil.isAntFile(file); + isAnt.set(isAntFile); + } + Boolean result = isRelevantLanguage.get(); + if (result == null) { + Language language = element.getLanguage(); + if (element instanceof PsiWhiteSpace) language = element.getParent().getLanguage(); + result = language instanceof XMLLanguage || isAntFile.booleanValue(); + isRelevantLanguage.set(result); + } + return result.booleanValue(); + } + + } \ No newline at end of file