diff --git a/build/scripts/layouts.gant b/build/scripts/layouts.gant index e23b893019c4..fb0427ec800e 100644 --- a/build/scripts/layouts.gant +++ b/build/scripts/layouts.gant @@ -77,7 +77,6 @@ def layoutFull(String home, String targetDirectory, String patchedDescriptorDir "java-indexing-impl", "java-impl", "java-psi-impl", - "js-analysis-impl", "jsp-spi", "manifest", "platform-main", diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/NewLibraryEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/NewLibraryEditor.java index e94b4f5ca876..6183b8a27bd0 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/NewLibraryEditor.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/NewLibraryEditor.java @@ -30,10 +30,7 @@ import com.intellij.util.containers.MultiMap; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.List; +import java.util.*; /** * @author nik @@ -41,7 +38,7 @@ import java.util.List; public class NewLibraryEditor extends LibraryEditorBase { private String myLibraryName; private final MultiMap myRoots; - private final List myExcludedRoots; + private final Set myExcludedRoots; private final JarDirectories myJarDirectories = new JarDirectories(); private LibraryType myType; private LibraryProperties myProperties; @@ -54,7 +51,7 @@ public class NewLibraryEditor extends LibraryEditorBase { myType = type; myProperties = properties; myRoots = new MultiMap(); - myExcludedRoots = new ArrayList(); + myExcludedRoots = new LinkedHashSet(); } @Override @@ -94,7 +91,7 @@ public class NewLibraryEditor extends LibraryEditorBase { } private static String[] pointersToUrls(Collection pointers) { - List urls = new ArrayList(); + List urls = new ArrayList(pointers.size()); for (LightFilePointer pointer : pointers) { urls.add(pointer.getUrl()); } diff --git a/java/java-analysis-api/src/com/intellij/codeInspection/reference/RefClass.java b/java/java-analysis-api/src/com/intellij/codeInspection/reference/RefClass.java index da8a04fe7b7f..3e9044ec5eaf 100644 --- a/java/java-analysis-api/src/com/intellij/codeInspection/reference/RefClass.java +++ b/java/java-analysis-api/src/com/intellij/codeInspection/reference/RefClass.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 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. @@ -17,6 +17,7 @@ package com.intellij.codeInspection.reference; import com.intellij.psi.PsiClass; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.Set; @@ -65,6 +66,7 @@ public interface RefClass extends RefJavaElement { boolean isSelfInheritor(PsiClass psiClass); + @Nullable @Override PsiClass getElement(); } diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefClassImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefClassImpl.java index 17416a0b99de..1e2aee542e7f 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefClassImpl.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/reference/RefClassImpl.java @@ -211,6 +211,7 @@ public class RefClassImpl extends RefJavaElementImpl implements RefClass { return isSelfInheritor(psiClass, new ArrayList()); } + @Nullable @Override public PsiClass getElement() { return (PsiClass)super.getElement(); diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateClassOrPackageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateClassOrPackageFix.java index f29f21b42633..d3c4858ffc34 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateClassOrPackageFix.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/quickFix/CreateClassOrPackageFix.java @@ -246,7 +246,9 @@ public class CreateClassOrPackageFix extends LocalQuickFixAndIntentionActionOnPs if (LOG.isDebugEnabled()) { LOG.debug("Package directory: " + directory); } - if (directory.isWritable() && scope.contains(directory.getVirtualFile())) { + VirtualFile virtualFile = directory.getVirtualFile(); + if (directory.isWritable() && scope.contains(virtualFile) + && !JavaProjectRootsUtil.isInGeneratedCode(virtualFile, psiManager.getProject())) { writableDirectoryList.add(directory); } } diff --git a/java/java-tests/testSrc/com/intellij/concurrency/JobUtilTest.java b/java/java-tests/testSrc/com/intellij/concurrency/JobUtilTest.java index 5df9119932da..fd68abd89066 100644 --- a/java/java-tests/testSrc/com/intellij/concurrency/JobUtilTest.java +++ b/java/java-tests/testSrc/com/intellij/concurrency/JobUtilTest.java @@ -20,6 +20,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; +import com.intellij.openapi.progress.util.AbstractProgressIndicatorBase; import com.intellij.openapi.progress.util.ProgressIndicatorBase; import com.intellij.testFramework.PlatformTestCase; import com.intellij.util.Processor; @@ -177,7 +178,7 @@ public class JobUtilTest extends PlatformTestCase { ProgressIndicator actualIndicator = ProgressManager.getInstance().getProgressIndicator(); if (progress == null) { assertNotNull(actualIndicator); - assertTrue(actualIndicator instanceof ProgressIndicatorBase); + assertTrue(actualIndicator instanceof AbstractProgressIndicatorBase); } else { assertTrue(actualIndicator instanceof SensitiveProgressWrapper); diff --git a/java/java-tests/testSrc/com/intellij/roots/libraries/LibraryTest.java b/java/java-tests/testSrc/com/intellij/roots/libraries/LibraryTest.java index 82e91fee8e33..e78308b4ae92 100644 --- a/java/java-tests/testSrc/com/intellij/roots/libraries/LibraryTest.java +++ b/java/java-tests/testSrc/com/intellij/roots/libraries/LibraryTest.java @@ -3,17 +3,19 @@ package com.intellij.roots.libraries; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.RootProvider; +import com.intellij.openapi.roots.impl.libraries.LibraryEx; import com.intellij.openapi.roots.libraries.Library; import com.intellij.openapi.roots.libraries.LibraryTable; import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar; -import com.intellij.testFramework.IdeaTestCase; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.roots.ModuleRootManagerTestCase; import org.jdom.Element; import org.jdom.output.XMLOutputter; /** * @author dsl */ -public class LibraryTest extends IdeaTestCase { +public class LibraryTest extends ModuleRootManagerTestCase { public void testModification() throws Exception { final LibraryTable libraryTable = LibraryTablesRegistrar.getInstance().getLibraryTable(); final Library library = libraryTable.createLibrary("NewLibrary"); @@ -25,27 +27,17 @@ public class LibraryTest extends IdeaTestCase { } }); - final Library.ModifiableModel modifyableModel = library.getModifiableModel(); - modifyableModel.addRoot("file://x.jar", OrderRootType.CLASSES); - modifyableModel.addRoot("file://x-src.jar", OrderRootType.SOURCES); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - modifyableModel.commit(); - } - }); + final Library.ModifiableModel model1 = library.getModifiableModel(); + model1.addRoot("file://x.jar", OrderRootType.CLASSES); + model1.addRoot("file://x-src.jar", OrderRootType.SOURCES); + commit(model1); assertTrue(listenerNotifiedOnChange[0]); listenerNotifiedOnChange[0] = false; - final Library.ModifiableModel modifyableModel1 = library.getModifiableModel(); - modifyableModel1.setName("library"); - ApplicationManager.getApplication().runWriteAction(new Runnable() { - @Override - public void run() { - modifyableModel1.commit(); - } - }); + final Library.ModifiableModel model2 = library.getModifiableModel(); + model2.setName("library"); + commit(model2); assertFalse(listenerNotifiedOnChange[0]); final Element element = new Element("root"); @@ -60,4 +52,47 @@ public class LibraryTest extends IdeaTestCase { } }); } + + public void testAddRemoveExcludedRoot() { + VirtualFile jar = getJDomJar(); + LibraryEx library = (LibraryEx)createLibrary("junit", jar, null); + assertEmpty(library.getExcludedRoots()); + + LibraryEx.ModifiableModelEx model = library.getModifiableModel(); + model.addExcludedRoot(jar.getUrl()); + commit(model); + assertOrderedEquals(library.getExcludedRoots(), jar); + + LibraryEx.ModifiableModelEx model2 = library.getModifiableModel(); + model2.removeExcludedRoot(jar.getUrl()); + commit(model2); + assertEmpty(library.getExcludedRoots()); + } + + public void testRemoveExcludedRootWhenParentRootIsRemoved() { + VirtualFile jar = getJDomJar(); + LibraryEx library = (LibraryEx)createLibrary("junit", jar, null); + + LibraryEx.ModifiableModelEx model = library.getModifiableModel(); + VirtualFile excluded = jar.findChild("org"); + assertNotNull(excluded); + model.addExcludedRoot(excluded.getUrl()); + commit(model); + + assertOrderedEquals(library.getExcludedRoots(), excluded); + LibraryEx.ModifiableModelEx model2 = library.getModifiableModel(); + model2.removeRoot(jar.getUrl(), OrderRootType.CLASSES); + commit(model2); + + assertEmpty(library.getExcludedRoots()); + } + + private static void commit(final Library.ModifiableModel modifyableModel1) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + modifyableModel1.commit(); + } + }); + } } diff --git a/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java b/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java index 68a9393f9d75..d594b7d993fb 100644 --- a/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java +++ b/platform/core-api/src/com/intellij/openapi/vfs/VfsUtilCore.java @@ -88,7 +88,13 @@ public class VfsUtilCore { } public static boolean isEqualOrAncestor(@NotNull String ancestorUrl, @NotNull String fileUrl) { - return ancestorUrl.equals(fileUrl) || StringUtil.startsWithConcatenation(fileUrl, ancestorUrl, "/"); + if (ancestorUrl.equals(fileUrl)) return true; + if (StringUtil.endsWithChar(ancestorUrl, '/')) { + return fileUrl.startsWith(ancestorUrl); + } + else { + return StringUtil.startsWithConcatenation(fileUrl, ancestorUrl, "/"); + } } public static boolean isAncestor(@NotNull File ancestor, @NotNull File file, boolean strict) { diff --git a/platform/core-api/src/com/intellij/concurrency/JobLauncher.java b/platform/core-impl/src/com/intellij/concurrency/JobLauncher.java similarity index 94% rename from platform/core-api/src/com/intellij/concurrency/JobLauncher.java rename to platform/core-impl/src/com/intellij/concurrency/JobLauncher.java index 2822832af85b..c5f6671ac126 100644 --- a/platform/core-api/src/com/intellij/concurrency/JobLauncher.java +++ b/platform/core-impl/src/com/intellij/concurrency/JobLauncher.java @@ -26,6 +26,10 @@ import org.jetbrains.annotations.Nullable; import java.util.List; import java.util.concurrent.Future; +/** + * Invitation-only service for running short-lived computing-intensive IO-free tasks on all available CPU cores. + * DO NOT USE for your tasks, IO-bound or long tasks, there is Application#executeOnPooledThread() for that. + */ public abstract class JobLauncher { public static JobLauncher getInstance() { return ServiceManager.getService(JobLauncher.class); diff --git a/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java b/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java index fed68c5688bc..60560a349f95 100644 --- a/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java +++ b/platform/core-impl/src/com/intellij/core/CoreApplicationEnvironment.java @@ -19,6 +19,7 @@ import com.intellij.concurrency.*; import com.intellij.lang.*; import com.intellij.lang.impl.PsiBuilderFactoryImpl; import com.intellij.mock.MockApplication; +import com.intellij.mock.MockApplicationEx; import com.intellij.mock.MockFileDocumentManagerImpl; import com.intellij.mock.MockReferenceProvidersRegistry; import com.intellij.openapi.Disposable; @@ -135,7 +136,7 @@ public class CoreApplicationEnvironment { } protected MockApplication createApplication(Disposable parentDisposable) { - return new MockApplication(parentDisposable); + return new MockApplicationEx(parentDisposable); } protected JobLauncher createJobLauncher() { diff --git a/platform/testFramework/src/com/intellij/mock/MockApplicationEx.java b/platform/core-impl/src/com/intellij/mock/MockApplicationEx.java similarity index 98% rename from platform/testFramework/src/com/intellij/mock/MockApplicationEx.java rename to platform/core-impl/src/com/intellij/mock/MockApplicationEx.java index b33427096827..2636faeec21e 100644 --- a/platform/testFramework/src/com/intellij/mock/MockApplicationEx.java +++ b/platform/core-impl/src/com/intellij/mock/MockApplicationEx.java @@ -118,6 +118,7 @@ public class MockApplicationEx extends MockApplication implements ApplicationEx @Override public boolean tryRunReadAction(@NotNull Runnable runnable) { - return false; + runReadAction(runnable); + return true; } } diff --git a/platform/platform-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java b/platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java similarity index 100% rename from platform/platform-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java rename to platform/core-impl/src/com/intellij/openapi/application/ex/ApplicationEx.java diff --git a/platform/indexing-api/src/com/intellij/psi/search/SearchRequestCollector.java b/platform/indexing-api/src/com/intellij/psi/search/SearchRequestCollector.java index f11b5fbf9b65..fef43be72ba5 100644 --- a/platform/indexing-api/src/com/intellij/psi/search/SearchRequestCollector.java +++ b/platform/indexing-api/src/com/intellij/psi/search/SearchRequestCollector.java @@ -16,6 +16,8 @@ package com.intellij.psi.search; import com.intellij.codeInsight.ContainerProvider; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFileSystemItem; @@ -82,9 +84,14 @@ public class SearchRequestCollector { searchWord(word, searchScope, searchContext, caseSensitive, getContainerName(searchTarget), processor); } - private static String getContainerName(@NotNull PsiElement target) { - PsiElement container = getContainer(target); - return container instanceof PsiNamedElement ? ((PsiNamedElement)container).getName() : null; + private static String getContainerName(@NotNull final PsiElement target) { + return ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public String compute() { + PsiElement container = getContainer(target); + return container instanceof PsiNamedElement ? ((PsiNamedElement)container).getName() : null; + } + }); } private static PsiElement getContainer(@NotNull PsiElement refElement) { diff --git a/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java b/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java index 27c595afa0b7..bc0fb118071a 100644 --- a/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java +++ b/platform/indexing-impl/src/com/intellij/psi/impl/search/PsiSearchHelperImpl.java @@ -20,6 +20,7 @@ import com.intellij.concurrency.*; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ReadAction; import com.intellij.openapi.application.Result; +import com.intellij.openapi.application.ex.ApplicationEx; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; @@ -27,10 +28,7 @@ import com.intellij.openapi.progress.ProgressIndicatorProvider; import com.intellij.openapi.progress.util.TooManyUsagesStatus; import com.intellij.openapi.project.Project; import com.intellij.openapi.roots.FileIndexFacade; -import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.Computable; -import com.intellij.openapi.util.Condition; -import com.intellij.openapi.util.Ref; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; @@ -60,7 +58,6 @@ import java.util.concurrent.atomic.AtomicInteger; public class PsiSearchHelperImpl implements PsiSearchHelper { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.search.PsiSearchHelperImpl"); - private final PsiManagerEx myManager; @Override @@ -76,8 +73,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { return scope; } - - public PsiSearchHelperImpl(PsiManagerEx manager) { + public PsiSearchHelperImpl(@NotNull PsiManagerEx manager) { myManager = manager; } @@ -172,10 +168,22 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { PsiElement[] scopeElements = scope.getScope(); final StringSearcher searcher = new StringSearcher(text, caseSensitively, true, searchContext == UsageSearchContext.IN_STRINGS); Processor localProcessor = localProcessor(processor, progress, processInjectedPsi, searcher); - return JobLauncher.getInstance().invokeConcurrentlyUnderProgressAsync(Arrays.asList(scopeElements), progress, false, localProcessor); + return wrapInFuture(Arrays.asList(scopeElements), progress, localProcessor); } - private boolean shouldProcessInjectedPsi(SearchScope scope) { + private static AsyncFuture wrapInFuture(@NotNull List files, final ProgressIndicator progress, @NotNull Processor processor) { + AsyncFutureResult asyncFutureResult = AsyncFutureFactory.getInstance().createAsyncFutureResult(); + try { + boolean result = JobLauncher.getInstance().invokeConcurrentlyUnderProgress(files, progress, true, true, processor); + asyncFutureResult.set(result); + } + catch (Throwable t) { + asyncFutureResult.setException(t); + } + return asyncFutureResult; + } + + private static boolean shouldProcessInjectedPsi(SearchScope scope) { return scope instanceof LocalSearchScope ? !((LocalSearchScope)scope).isIgnoreInjectedPsi() : true; } @@ -265,7 +273,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { } AsyncFuture result = fileSet.isEmpty() - ? AsyncFutureFactory.wrap(true) + ? AsyncFutureFactory.wrap(Boolean.TRUE) : processPsiFileRootsAsync(new ArrayList(fileSet), fileSet.size(), 0, progress, localProcessor); return popStateAfter(result, progress); } @@ -299,32 +307,25 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { return totalResult; } - // splits mainList into 2 lists: outIntersection containing elements from both mainList and list2 and outRest with all the rest elements from mainList - private static void splitSortedLists(@NotNull List mainList, - @NotNull List list2, - @NotNull Comparator comparator, - @NotNull List outIntersection, - @NotNull List outRest) { - int index1 = 0; - int index2 = 0; - while (index1 != mainList.size()) { - T element1 = mainList.get(index1); - T element2 = index2 == list2.size() ? null : list2.get(index2); - int c = element2 == null ? -1 : comparator.compare(element1, element2); - if (c == 0) { - outIntersection.add(element1); - index1++; - index2++; - } - else if (c < 0) { - index1++; - outRest.add(element1); - } - else { - index2++; - } + private static class CannotRunReadActionException extends RuntimeException{ + @Override + public Throwable fillInStackTrace() { + return this; } } + // throws exception if can't grab read action right now + private static T tryRead(final Computable computable) throws CannotRunReadActionException { + final Ref result = new Ref(); + if (((ApplicationEx)ApplicationManager.getApplication()).tryRunReadAction(new Runnable() { + @Override + public void run() { + result.set(computable.compute()); + } + })) { + return result.get(); + } + throw new CannotRunReadActionException(); + } /** * @param files to scan for references in this pass. @@ -337,64 +338,95 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { final int totalSize, int alreadyProcessedFiles, final ProgressIndicator progress, - @NotNull final Processor psiRootProcessor) { + @NotNull final Processor localProcessor) { myManager.startBatchFilesProcessingMode(); final AtomicInteger counter = new AtomicInteger(alreadyProcessedFiles); final AtomicBoolean canceled = new AtomicBoolean(false); - AsyncFuture - completed = JobLauncher.getInstance().invokeConcurrentlyUnderProgressAsync(files, progress, false, new Processor() { - @Override - public boolean process(final VirtualFile vfile) { - final PsiFile file = ApplicationManager.getApplication().runReadAction(new Computable() { + AsyncFutureResult asyncFutureResult = AsyncFutureFactory.getInstance().createAsyncFutureResult(); + final List failedFiles = new ArrayList(); + try { + boolean completed = + JobLauncher.getInstance().invokeConcurrentlyUnderProgress(files, progress, false, false, new Processor() { @Override - public PsiFile compute() { - return vfile.isValid() ? myManager.findFile(vfile) : null; + public boolean process(final VirtualFile vfile) { + try { + processVirtualFile(vfile, progress, localProcessor, canceled, counter, totalSize); + } + catch (CannotRunReadActionException action) { + failedFiles.add(vfile); + } + return !canceled.get(); } }); - if (file != null && !(file instanceof PsiBinaryFile)) { - file.getViewProvider().getContents(); // load contents outside read action - if (myManager.getProject().isDisposed()) throw new ProcessCanceledException(); - List psiRoots = ApplicationManager.getApplication().runReadAction(new Computable>() { + if (!failedFiles.isEmpty()) { + for (final VirtualFile vfile : failedFiles) { + // we failed to run read action in job launcher thread + // run read action in our thread instead + ApplicationManager.getApplication().runReadAction(new Runnable() { @Override - public List compute() { - return file.getViewProvider().getAllFiles(); + public void run() { + processVirtualFile(vfile, progress, localProcessor, canceled, counter, totalSize); } }); - Set processed = new THashSet(psiRoots.size() * 2, (float)0.5); + } + } + asyncFutureResult.set(completed); + myManager.finishBatchFilesProcessingMode(); + } + catch (Throwable t) { + asyncFutureResult.setException(t); + } + + return asyncFutureResult; + } + + private void processVirtualFile(final VirtualFile vfile, + final ProgressIndicator progress, + final Processor localProcessor, + final AtomicBoolean canceled, AtomicInteger counter, int totalSize) { + final PsiFile file = tryRead(new Computable() { + @Override + public PsiFile compute() { + return vfile.isValid() ? myManager.findFile(vfile) : null; + } + }); + if (file != null && !(file instanceof PsiBinaryFile)) { + file.getViewProvider().getContents(); // load contents outside read action + if (myManager.getProject().isDisposed()) throw new ProcessCanceledException(); + final List psiRoots = tryRead(new Computable>() { + @Override + public List compute() { + return file.getViewProvider().getAllFiles(); + } + }); + final Set processed = new THashSet(psiRoots.size() * 2, (float)0.5); + TooManyUsagesStatus.getFrom(progress).pauseProcessingIfTooManyUsages(); + tryRead(new Computable() { + @Override + public Void compute() { for (final PsiFile psiRoot : psiRoots) { checkCanceled(progress); assert psiRoot != null : "One of the roots of file " + file + " is null. All roots: " + psiRoots + "; ViewProvider: " + file.getViewProvider() + "; Virtual file: " + file.getViewProvider().getVirtualFile(); if (!processed.add(psiRoot)) continue; - if (!ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public Boolean compute() { - return psiRoot.isValid(); - } - })) { + if (!psiRoot.isValid()) { continue; } - if (!psiRootProcessor.process(psiRoot)) { + + if (!localProcessor.process(psiRoot)) { canceled.set(true); break; } } + return null; } - if (progress != null && progress.isRunning()) { - double fraction = (double)counter.incrementAndGet() / totalSize; - progress.setFraction(fraction); - } - return !canceled.get(); - } - }); - - return new FinallyFuture(completed, new Runnable() { - @Override - public void run() { - myManager.finishBatchFilesProcessingMode(); - } - }); + }); + } + if (progress != null && progress.isRunning()) { + double fraction = (double)counter.incrementAndGet() / totalSize; + progress.setFraction(fraction); + } } private static void checkCanceled(ProgressIndicator progress) { @@ -769,6 +801,7 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { return popStateAfter(result, progress); } + @NotNull private AsyncFuture processCandidatesAsync(final ProgressIndicator progress, @NotNull final Map> localProcessors, @NotNull final MultiMap candidateFiles, @@ -779,20 +812,19 @@ public class PsiSearchHelperImpl implements PsiSearchHelper { return processPsiFileRootsAsync(files, totalSize, alreadyProcessedFiles, progress, new Processor() { @Override public boolean process(final PsiFile psiRoot) { - final VirtualFile vfile = ApplicationManager.getApplication().runReadAction(new Computable() { + return tryRead(new Computable() { @Override - public VirtualFile compute() { - return psiRoot.getVirtualFile(); + public Boolean compute() { + final VirtualFile vfile = psiRoot.getVirtualFile(); + for (final RequestWithProcessor singleRequest : candidateFiles.get(vfile)) { + Processor localProcessor = localProcessors.get(singleRequest); + if (!localProcessor.process(psiRoot)) { + return false; + } + } + return true; } }); - for (final RequestWithProcessor singleRequest : candidateFiles.get(vfile)) { - Processor localProcessor = localProcessors.get(singleRequest); - TooManyUsagesStatus.getFrom(progress).pauseProcessingIfTooManyUsages(); - if (!localProcessor.process(psiRoot)) { - return false; - } - } - return true; } }); } diff --git a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java index d66de2d8abb0..5817e1ab10af 100644 --- a/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java +++ b/platform/lang-impl/src/com/intellij/execution/console/LanguageConsoleImpl.java @@ -404,8 +404,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { Document history = myHistoryViewer.getDocument(); MarkupModel markupModel = DocumentMarkupModel.forDocument(history, myProject, true); - int offset = history.getTextLength(); - appendToHistoryDocument(history, text); + int offset = appendToHistoryDocument(history, text); if (attributes == null) return; markupModel.addRangeHighlighter(offset, offset + text.length(), HighlighterLayer.SYNTAX, attributes, HighlighterTargetArea.EXACT_RANGE); } @@ -482,8 +481,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { highlighter = consoleEditor.getHighlighter(); } //offset can be changed after text trimming after insert due to buffer constraints - appendToHistoryDocument(history, text); - int offset = history.getTextLength() - text.length(); + int offset = appendToHistoryDocument(history, text); final HighlighterIterator iterator = highlighter.createIterator(localStartOffset); final int localEndOffset = textRange.getEndOffset(); @@ -514,9 +512,11 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider { addTextToHistory(myPrompt, ConsoleViewContentType.USER_INPUT.getAttributes()); } - protected void appendToHistoryDocument(@NotNull Document history, @NotNull CharSequence text) { + // returns the real (cyclic-buffer-aware) start offset of the inserted text + protected int appendToHistoryDocument(@NotNull Document history, @NotNull CharSequence text) { ApplicationManager.getApplication().assertIsDispatchThread(); history.insertString(history.getTextLength(), text); + return history.getTextLength() - text.length(); } private static void duplicateHighlighters(@NotNull MarkupModel to, @NotNull MarkupModel from, int offset, @NotNull TextRange textRange) { diff --git a/platform/lang-impl/src/com/intellij/find/impl/FindResultUsageInfo.java b/platform/lang-impl/src/com/intellij/find/impl/FindResultUsageInfo.java index 138af2cbb285..2c372795ea85 100644 --- a/platform/lang-impl/src/com/intellij/find/impl/FindResultUsageInfo.java +++ b/platform/lang-impl/src/com/intellij/find/impl/FindResultUsageInfo.java @@ -1,3 +1,18 @@ +/* + * Copyright 2000-2013 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.find.impl; import com.intellij.find.FindManager; @@ -16,14 +31,14 @@ import com.intellij.usageView.UsageInfo; import org.jetbrains.annotations.NotNull; public class FindResultUsageInfo extends UsageInfo { - private FindManager myFindManager; - private FindModel myFindModel; + private final FindManager myFindManager; + private final FindModel myFindModel; private SmartPsiFileRange myAnchor; private Boolean myCachedResult; private long myTimestamp = 0; - private static Key ourDocumentTimestampKey = Key.create("com.intellij.find.impl.FindResultUsageInfo.documentTimestamp"); + private static final Key ourDocumentTimestampKey = Key.create("com.intellij.find.impl.FindResultUsageInfo.documentTimestamp"); @Override public boolean isValid() { @@ -35,40 +50,52 @@ public class FindResultUsageInfo extends UsageInfo { return false; } - if (document.getModificationStamp() == myTimestamp && myCachedResult != null) { - return myCachedResult; - } else { - myTimestamp = document.getModificationStamp(); + Boolean cachedResult = myCachedResult; + if (document.getModificationStamp() == myTimestamp && cachedResult != null) { + return cachedResult; } + myTimestamp = document.getModificationStamp(); - Segment segment = super.getSegment(); - if (segment == null) return myCachedResult = false; + Segment segment = getSegment(); + if (segment == null) { + myCachedResult = false; + return false; + } VirtualFile file = getPsiFile().getVirtualFile(); Segment searchOffset; if (myAnchor != null) { searchOffset = myAnchor.getRange(); - if (searchOffset == null) return myCachedResult = false; - } else { + if (searchOffset == null) { + myCachedResult = false; + return false; + } + } + else { searchOffset = segment; } int offset = searchOffset.getStartOffset(); - FindResult result; Long data = myFindModel.getUserData(ourDocumentTimestampKey); if (data == null || data != myTimestamp) { data = myTimestamp; myFindModel.putUserData(FindManagerImpl.ourCommentsLiteralsSearchDataKey, null); } myFindModel.putUserData(ourDocumentTimestampKey, data); + FindResult result; do { result = myFindManager.findString(document.getCharsSequence(), offset, myFindModel, file); offset = result.getEndOffset() == offset ? offset + 1 : result.getEndOffset(); - if (!result.isStringFound()) return myCachedResult = false; + if (!result.isStringFound()) { + myCachedResult = false; + return false; + } } while (result.getStartOffset() < segment.getStartOffset()); - return myCachedResult = (segment.getStartOffset() == result.getStartOffset() && segment.getEndOffset() == result.getEndOffset()); + boolean ret = segment.getStartOffset() == result.getStartOffset() && segment.getEndOffset() == result.getEndOffset(); + myCachedResult = ret; + return ret; } private PsiFile getPsiFile() { diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkSourceRootAction.java b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkSourceRootAction.java index 08eabbb101f8..dca6d0599309 100644 --- a/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkSourceRootAction.java +++ b/platform/lang-impl/src/com/intellij/ide/projectView/actions/MarkSourceRootAction.java @@ -17,6 +17,7 @@ package com.intellij.ide.projectView.actions; import com.intellij.openapi.actionSystem.Presentation; import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.project.ProjectBundle; import com.intellij.openapi.roots.ContentEntry; import com.intellij.openapi.roots.SourceFolder; @@ -46,7 +47,7 @@ public class MarkSourceRootAction extends MarkRootActionBase { @Override protected boolean isEnabled(@NotNull RootsSelection selection, @NotNull Module module) { - if (selection.myHaveSelectedFilesUnderSourceRoots) { + if (!ModuleType.get(module).isSupportedRootType(myRootType) || selection.myHaveSelectedFilesUnderSourceRoots) { return false; } diff --git a/platform/platform-impl/src/com/intellij/concurrency/ApplierCompleter.java b/platform/platform-impl/src/com/intellij/concurrency/ApplierCompleter.java index 1644e54df8b1..4db4b3c67407 100644 --- a/platform/platform-impl/src/com/intellij/concurrency/ApplierCompleter.java +++ b/platform/platform-impl/src/com/intellij/concurrency/ApplierCompleter.java @@ -219,7 +219,7 @@ public class ApplierCompleter extends CountedCompleter { } } }); - assert task.failedSubTasks == null; + assert task.failedSubTasks == null : task.failedSubTasks; } return result[0]; } diff --git a/platform/platform-impl/src/com/intellij/concurrency/JobLauncherImpl.java b/platform/platform-impl/src/com/intellij/concurrency/JobLauncherImpl.java index d87b9aeb0449..4e9a9b948d5b 100644 --- a/platform/platform-impl/src/com/intellij/concurrency/JobLauncherImpl.java +++ b/platform/platform-impl/src/com/intellij/concurrency/JobLauncherImpl.java @@ -19,7 +19,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.progress.ProgressIndicator; import com.intellij.openapi.progress.ProgressManager; -import com.intellij.openapi.progress.util.ProgressIndicatorBase; +import com.intellij.openapi.progress.util.AbstractProgressIndicatorBase; import com.intellij.util.Consumer; import com.intellij.util.IncorrectOperationException; import com.intellij.util.Processor; @@ -120,7 +120,7 @@ public class JobLauncherImpl extends JobLauncher { @NotNull final Processor thingProcessor) throws ProcessCanceledException { if (things.isEmpty()) return true; // supply our own indicator even if we haven't given one - to support cancellation - final ProgressIndicator wrapper = progress == null ? new ProgressIndicatorBase() : new SensitiveProgressWrapper(progress); + final ProgressIndicator wrapper = progress == null ? new AbstractProgressIndicatorBase() : new SensitiveProgressWrapper(progress); if (things.size() <= 1 || JobSchedulerImpl.CORES_COUNT <= CORES_FORK_THRESHOLD) { final AtomicBoolean result = new AtomicBoolean(true); diff --git a/platform/platform-impl/src/com/intellij/designer/propertyTable/PropertyTable.java b/platform/platform-impl/src/com/intellij/designer/propertyTable/PropertyTable.java index 3470d77047f1..7b3b22b6c756 100644 --- a/platform/platform-impl/src/com/intellij/designer/propertyTable/PropertyTable.java +++ b/platform/platform-impl/src/com/intellij/designer/propertyTable/PropertyTable.java @@ -308,7 +308,13 @@ public abstract class PropertyTable extends JBTable { } public void update(@NotNull List containers, @Nullable Property initialSelection) { - finishEditing(); + update(containers, initialSelection, true); + } + + private void update(@NotNull List containers, @Nullable Property initialSelection, boolean finishEditing) { + if (finishEditing) { + finishEditing(); + } if (mySkipUpdate) { return; @@ -316,7 +322,7 @@ public abstract class PropertyTable extends JBTable { mySkipUpdate = true; try { - if (isEditing()) { + if (finishEditing && isEditing()) { cellEditor.stopCellEditing(); } @@ -841,7 +847,7 @@ public abstract class PropertyTable extends JBTable { if (isSetValue) { if (property.needRefreshPropertyList() || needRefresh[0]) { - update(); + update(myContainers, null, false); } else { myModel.fireTableRowsUpdated(row, row); @@ -1107,7 +1113,9 @@ public abstract class PropertyTable extends JBTable { if (setValueAtRow(editingRow, value)) { if (!continueEditing) { - tableCellEditor.stopCellEditing(); + PropertyEditor editor = myProperties.get(editingRow).getEditor(); + editor.removePropertyEditorListener(myPropertyEditorListener); + removeEditor(); } } else if (closeEditorOnError) { diff --git a/platform/platform-impl/src/com/intellij/designer/propertyTable/editors/BooleanEditor.java b/platform/platform-impl/src/com/intellij/designer/propertyTable/editors/BooleanEditor.java index 984eb245e62f..145f2a9e9b7d 100644 --- a/platform/platform-impl/src/com/intellij/designer/propertyTable/editors/BooleanEditor.java +++ b/platform/platform-impl/src/com/intellij/designer/propertyTable/editors/BooleanEditor.java @@ -40,7 +40,7 @@ public class BooleanEditor extends PropertyEditor { myCheckBox.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { if (!myInsideChange) { - fireValueCommitted(true, false); + fireValueCommitted(false, true); } } }); diff --git a/platform/platform-impl/src/com/intellij/designer/propertyTable/editors/TextEditor.java b/platform/platform-impl/src/com/intellij/designer/propertyTable/editors/TextEditor.java index 6dbe4057bc81..c6ddc0ae484a 100644 --- a/platform/platform-impl/src/com/intellij/designer/propertyTable/editors/TextEditor.java +++ b/platform/platform-impl/src/com/intellij/designer/propertyTable/editors/TextEditor.java @@ -40,7 +40,7 @@ public class TextEditor extends PropertyEditor { myTextField.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - fireValueCommitted(true, false); + fireValueCommitted(true, true); } }); myTextField.getDocument().addDocumentListener( diff --git a/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java b/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java index 149c11e37749..cfc84f4224d3 100644 --- a/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java +++ b/platform/platform-impl/src/com/intellij/execution/DelayedDocumentWatcher.java @@ -16,17 +16,26 @@ package com.intellij.execution; import com.google.common.collect.ImmutableSet; +import com.intellij.AppTopics; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.EditorFactory; import com.intellij.openapi.editor.event.DocumentAdapter; import com.intellij.openapi.editor.event.DocumentEvent; import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.fileEditor.FileDocumentManagerAdapter; import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Computable; import com.intellij.openapi.util.Condition; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.problems.WolfTheProblemSolver; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.Alarm; import com.intellij.util.Consumer; +import com.intellij.util.messages.MessageBusConnection; import gnu.trove.THashSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -43,7 +52,8 @@ public class DelayedDocumentWatcher { private final Runnable myAlarmRunnable; private final Set myChangedFiles = new THashSet(); - + private boolean myDocumentSavingInProgress = false; + private MessageBusConnection myConnection; public DelayedDocumentWatcher(@NotNull Project project, int delayMillis, @@ -65,15 +75,41 @@ public class DelayedDocumentWatcher { public void activate() { EditorFactory.getInstance().getEventMulticaster().addDocumentListener(myListener, myProject); + if (myConnection == null) { + myConnection = ApplicationManager.getApplication().getMessageBus().connect(myProject); + myConnection.subscribe(AppTopics.FILE_DOCUMENT_SYNC, new FileDocumentManagerAdapter() { + @Override + public void beforeAllDocumentsSaving() { + myDocumentSavingInProgress = true; + ApplicationManager.getApplication().invokeLater(new Runnable() { + @Override + public void run() { + myDocumentSavingInProgress = false; + } + }, ModalityState.any()); + } + }); + } } public void deactivate() { EditorFactory.getInstance().getEventMulticaster().removeDocumentListener(myListener); + if (myConnection != null) { + myConnection.disconnect(); + myConnection = null; + } } private class MyDocumentAdapter extends DocumentAdapter { @Override public void documentChanged(DocumentEvent event) { + if (myDocumentSavingInProgress) { + /** When {@link FileDocumentManager#saveAllDocuments} is called, + * {@link com.intellij.openapi.fileEditor.impl.TrailingSpacesStripper} can change a document. + * These needless 'documentChanged' events should be filtered out. + */ + return; + } final Document document = event.getDocument(); final VirtualFile file = FileDocumentManager.getInstance().getFile(document); if (file == null) { @@ -96,9 +132,9 @@ public class DelayedDocumentWatcher { private class MyRunnable implements Runnable { @Override public void run() { - WolfTheProblemSolver problemSolver = WolfTheProblemSolver.getInstance(myProject); for (VirtualFile file : myChangedFiles) { - if (problemSolver.hasSyntaxErrors(file)) { + boolean hasErrors = hasErrors(file); + if (hasErrors) { // Do nothing, if some changed file has syntax errors. // This method will be invoked subsequently, when syntax errors are fixed. return; @@ -110,4 +146,21 @@ public class DelayedDocumentWatcher { } } + private boolean hasErrors(@NotNull VirtualFile file) { + // don't use 'WolfTheProblemSolver.hasSyntaxErrors(file)' if possible + Document document = FileDocumentManager.getInstance().getDocument(file); + if (document != null) { + final PsiFile psiFile = PsiDocumentManager.getInstance(myProject).getPsiFile(document); + if (psiFile != null) { + return ApplicationManager.getApplication().runWriteAction(new Computable() { + @Override + public Boolean compute() { + return PsiTreeUtil.hasErrorElements(psiFile); + } + }); + } + } + return WolfTheProblemSolver.getInstance(myProject).hasSyntaxErrors(file); + } + } diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java index 87a260d3688e..39fcc8f76445 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java @@ -20,6 +20,7 @@ import com.intellij.openapi.ui.GraphicsConfig; import com.intellij.ui.Gray; import com.intellij.ui.JBColor; import com.intellij.util.ui.UIUtil; +import sun.swing.DefaultLookup; import javax.swing.*; import javax.swing.border.Border; @@ -27,7 +28,6 @@ import javax.swing.plaf.ComponentUI; import javax.swing.plaf.DimensionUIResource; import javax.swing.plaf.InsetsUIResource; import javax.swing.plaf.basic.BasicArrowButton; -import javax.swing.plaf.basic.BasicComboBoxRenderer; import javax.swing.plaf.basic.BasicComboBoxUI; import java.awt.*; import java.awt.event.FocusAdapter; @@ -66,25 +66,6 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border { myPadding = UIManager.getInsets("ComboBox.padding"); } - @Override - protected ListCellRenderer createRenderer() { - return new BasicComboBoxRenderer.UIResource() { - @Override - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - final Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - if (c instanceof JComponent) { - final JComponent jc = (JComponent)c; - if (index == -1) { - jc.setOpaque(false); - jc.setForeground(list.getForeground()); - } else { - jc.setOpaque(true); - } - } - return c; - } - }; - } protected JButton createArrowButton() { final Color bg = myComboBox.getBackground(); @@ -144,10 +125,6 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border { } protected Dimension getDisplaySize() { - if (!myDisplaySizeDirty) { - return new Dimension(myDisplaySizeCache); - } - Dimension display = new Dimension(); ListCellRenderer renderer = comboBox.getRenderer(); @@ -214,7 +191,6 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border { return d; } - @Override public void paint(Graphics g, JComponent c) { final Container parent = c.getParent(); @@ -229,6 +205,51 @@ public class DarculaComboBoxUI extends BasicComboBoxUI implements Border { paintCurrentValue(g, r, hasFocus); } + public void paintCurrentValue(Graphics g, Rectangle bounds, boolean hasFocus) { + ListCellRenderer renderer = comboBox.getRenderer(); + Component c; + + if (hasFocus && !isPopupVisible(comboBox)) { + c = renderer.getListCellRendererComponent(listBox, comboBox.getSelectedItem(), -1, false, false); + } + else { + c = renderer.getListCellRendererComponent(listBox, comboBox.getSelectedItem(), -1, false, false); + c.setBackground(UIManager.getColor("ComboBox.background")); + } + c.setFont(comboBox.getFont()); + if (hasFocus && !isPopupVisible(comboBox)) { + c.setForeground(listBox.getForeground()); + c.setBackground(listBox.getBackground()); + } + else { + if (comboBox.isEnabled()) { + c.setForeground(comboBox.getForeground()); + c.setBackground(comboBox.getBackground()); + } + else { + c.setForeground(DefaultLookup.getColor( + comboBox, this, "ComboBox.disabledForeground", null)); + c.setBackground(DefaultLookup.getColor( + comboBox, this, "ComboBox.disabledBackground", null)); + } + } + + boolean shouldValidate = false; + if (c instanceof JPanel) { + shouldValidate = true; + } + + Rectangle r = new Rectangle(bounds); + if (myPadding != null) { + r.x += myPadding.left; + r.y += myPadding.top; + r.width -= myPadding.left + myPadding.right; + r.height -= myPadding.top + myPadding.bottom; + } + + currentValuePane.paintComponent(g, c, comboBox, r.x-2, r.y, r.width, r.height, shouldValidate); + } + @Override protected void installKeyboardActions() { super.installKeyboardActions(); diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaRadioButtonUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaRadioButtonUI.java index f2a2efd511fd..e6674a643331 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaRadioButtonUI.java +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaRadioButtonUI.java @@ -17,7 +17,6 @@ package com.intellij.ide.ui.laf.darcula.ui; import com.intellij.ide.ui.laf.darcula.DarculaUIUtil; import com.intellij.openapi.ui.GraphicsConfig; -import com.intellij.openapi.util.SystemInfo; import com.intellij.ui.ColorUtil; import com.intellij.ui.Gray; import com.intellij.util.ui.EmptyIcon; @@ -88,14 +87,21 @@ public class DarculaRadioButtonUI extends MetalRadioButtonUI { //setup AA for lines final GraphicsConfig config = GraphicsUtil.setupAAPainting(g); - g.setPaint( - UIUtil.getGradientPaint(0, 0, ColorUtil.shift(c.getBackground(), 1.5), 0, c.getHeight(), ColorUtil.shift(c.getBackground(), 1.2))); - g.fillOval(0, 1, w - 1, h - 1); + final boolean focus = b.hasFocus(); + g.setPaint(UIUtil.getGradientPaint(0, 0, ColorUtil.shift(c.getBackground(), 1.5), + 0, c.getHeight(), ColorUtil.shift(c.getBackground(), 1.2))); + if (focus) { + g.fillOval(0, 1, w, h); + } else { + g.fillOval(0, 1, w - 1, h - 1); + } - if (b.hasFocus()) { - int sysOffX = SystemInfo.isMac ? 0 : 1; - int sysOffY = SystemInfo.isMac ? 0 : -1; - DarculaUIUtil.paintFocusOval(g, w/2 - rad - sysOffX, y- (rad + 1)/2 + sysOffY, w-2, h-2); + if (focus) { + if (UIUtil.isRetina()) { + DarculaUIUtil.paintFocusOval(g, 1, 2, w-2, h-2); + } else { + DarculaUIUtil.paintFocusOval(g, 0, 1, w, h); + } } else { if (UIUtil.isUnderDarcula()) { g.setPaint(UIUtil.getGradientPaint(w / 2, 1, Gray._160.withAlpha(90), w / 2, h, Gray._100.withAlpha(90))); diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties index 7128c5c3c85d..773bd46e5ddd 100644 --- a/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties +++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/intellijlaf.properties @@ -26,7 +26,7 @@ Menu.border=com.intellij.ide.ui.laf.darcula.ui.DarculaMenuItemBorder EditorPaneUI=com.intellij.ide.ui.laf.darcula.ui.DarculaEditorPaneUI -control=cccccc +control=e0e0e0 link.foreground=589df6 ScrollBarUI=com.intellij.ide.ui.laf.darcula.ui.DarculaScrollBarUI diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java index 0178a8168347..6dfe3082fd57 100644 --- a/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java +++ b/platform/platform-impl/src/com/intellij/openapi/vfs/newvfs/persistent/RefreshWorker.java @@ -32,6 +32,8 @@ import com.intellij.openapi.vfs.newvfs.impl.VirtualDirectoryImpl; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.OpenTHashSet; import com.intellij.util.containers.Queue; +import com.intellij.util.text.FilePathHashingStrategy; +import gnu.trove.TObjectHashingStrategy; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -92,6 +94,8 @@ public class RefreshWorker { } private void processQueue(NewVirtualFileSystem fs, PersistentFS persistence) throws RefreshCancelledException { + TObjectHashingStrategy strategy = FilePathHashingStrategy.create(fs.isCaseSensitive()); + while (!myRefreshQueue.isEmpty()) { checkCancelled(); @@ -120,13 +124,13 @@ public class RefreshWorker { if (fullSync) { String[] currentNames = persistence.list(file); String[] upToDateNames = VfsUtil.filterNames(fs.list(file)); - Set newNames = newTroveSet(FileUtil.PATH_HASHING_STRATEGY, upToDateNames); + Set newNames = newTroveSet(strategy, upToDateNames); ContainerUtil.removeAll(newNames, currentNames); - Set deletedNames = newTroveSet(FileUtil.PATH_HASHING_STRATEGY, currentNames); + Set deletedNames = newTroveSet(strategy, currentNames); ContainerUtil.removeAll(deletedNames, upToDateNames); OpenTHashSet actualNames = null; - if (!SystemInfo.isFileSystemCaseSensitive) { - actualNames = new OpenTHashSet(FileUtil.PATH_HASHING_STRATEGY, upToDateNames); + if (!fs.isCaseSensitive()) { + actualNames = new OpenTHashSet(strategy, upToDateNames); } debug(LOG, "current=%s +%s -%s", currentNames, newNames, deletedNames); @@ -163,8 +167,8 @@ public class RefreshWorker { else { Collection cachedChildren = file.getCachedChildren(); OpenTHashSet actualNames = null; - if (!SystemInfo.isFileSystemCaseSensitive) { - actualNames = new OpenTHashSet(FileUtil.PATH_HASHING_STRATEGY, VfsUtil.filterNames(fs.list(file))); + if (!fs.isCaseSensitive()) { + actualNames = new OpenTHashSet(strategy, VfsUtil.filterNames(fs.list(file))); } debug(LOG, "cached=%s actual=%s", cachedChildren, actualNames); diff --git a/platform/platform-resources-en/src/inspectionDescriptions/Annotator.html b/platform/platform-resources-en/src/inspectionDescriptions/Annotator.html index ce63baf76ae2..5003474700c6 100644 --- a/platform/platform-resources-en/src/inspectionDescriptions/Annotator.html +++ b/platform/platform-resources-en/src/inspectionDescriptions/Annotator.html @@ -1,5 +1,5 @@ -Allows to see problems reported by language annotators in the results of batch code inspection. +Allows you to see problems reported by language annotators in the results of batch code inspection. \ No newline at end of file diff --git a/platform/platform-resources-en/src/inspectionDescriptions/SyntaxError.html b/platform/platform-resources-en/src/inspectionDescriptions/SyntaxError.html index 398a7b8a0e03..d60b5db0e39e 100644 --- a/platform/platform-resources-en/src/inspectionDescriptions/SyntaxError.html +++ b/platform/platform-resources-en/src/inspectionDescriptions/SyntaxError.html @@ -1,5 +1,5 @@ -Allows to see syntax errors in the results of batch code inspection. +Allows you to see syntax errors in the results of batch code inspection. \ No newline at end of file diff --git a/platform/platform-resources-en/src/messages/ApplicationBundle.properties b/platform/platform-resources-en/src/messages/ApplicationBundle.properties index 577a0766460c..0b45e230e88a 100644 --- a/platform/platform-resources-en/src/messages/ApplicationBundle.properties +++ b/platform/platform-resources-en/src/messages/ApplicationBundle.properties @@ -505,7 +505,7 @@ title.colors.and.fonts=Colors \\& Fonts progress.analysing.font=Analysing font: {0} button.edit.scopes=Edit Scopes... group.editor.font=Editor Font -label.fallback.fonts.list.description=If primary font fails IDE tries to use the secondary one +label.fallback.fonts.list.description=If primary font fails, IDE tries to use the secondary one quickdoc.tooltip.font.size.by.wheel=Slider or Ctrl+Wheel change font size label.font.size=Font size: label.font.name=Name: diff --git a/platform/platform-resources/src/codeStyle/preview/preview.xml.template b/platform/platform-resources/src/codeStyle/preview/preview.xml.template index 6edd0817d215..ca848fe23595 100644 --- a/platform/platform-resources/src/codeStyle/preview/preview.xml.template +++ b/platform/platform-resources/src/codeStyle/preview/preview.xml.template @@ -10,7 +10,7 @@ Our product makes development a real pleasure. It decreases the time you spend on routine, repetitive handwork, giving you more time to focus on the task at hand. Its robust set of features for automatic error-checking and code correction cuts development time and increases your efficiency. You'll find that our product quickly - pays back it's cost in increased developer productivity and improved code quality. + pays back its cost in increased developer productivity and improved code quality. diff --git a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java index 954b254ae402..5bcb04f89955 100644 --- a/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java +++ b/platform/projectModel-impl/src/com/intellij/openapi/roots/impl/libraries/LibraryImpl.java @@ -379,7 +379,10 @@ public class LibraryImpl extends TraceableDisposable implements LibraryEx.Modifi @Override public void addExcludedRoot(@NotNull String url) { - getOrCreateExcludedRoots().add(url); + VirtualFilePointerContainer roots = getOrCreateExcludedRoots(); + if (roots.findByUrl(url) == null) { + roots.add(url); + } } @Override @@ -492,7 +495,7 @@ public class LibraryImpl extends TraceableDisposable implements LibraryEx.Modifi if (myExcludedRoots != null) { for (String excludedRoot : myExcludedRoots.getUrls()) { if (!isUnderRoots(excludedRoot)) { - VirtualFilePointer pointer = myExcludedRoots.findByUrl(url); + VirtualFilePointer pointer = myExcludedRoots.findByUrl(excludedRoot); if (pointer != null) { myExcludedRoots.remove(pointer); } diff --git a/platform/util/src/com/intellij/util/text/FilePathHashingStrategy.java b/platform/util/src/com/intellij/util/text/FilePathHashingStrategy.java index b91b718295eb..bad768477e58 100644 --- a/platform/util/src/com/intellij/util/text/FilePathHashingStrategy.java +++ b/platform/util/src/com/intellij/util/text/FilePathHashingStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2013 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.util.text; import com.intellij.openapi.util.SystemInfo; @@ -25,11 +24,15 @@ import org.jetbrains.annotations.NotNull; * @author max */ public class FilePathHashingStrategy { - private FilePathHashingStrategy() { - } + private FilePathHashingStrategy() { } @NotNull public static TObjectHashingStrategy create() { - return SystemInfo.isFileSystemCaseSensitive ? ContainerUtil.canonicalStrategy() : new CaseInsensitiveStringHashingStrategy(); + return create(SystemInfo.isFileSystemCaseSensitive); + } + + @NotNull + public static TObjectHashingStrategy create(boolean caseSensitive) { + return caseSensitive ? ContainerUtil.canonicalStrategy() : new CaseInsensitiveStringHashingStrategy(); } } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dependency/CyclicClassDependencyInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dependency/CyclicClassDependencyInspection.java index 51a5a1a01d7a..355d5933d511 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dependency/CyclicClassDependencyInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/dependency/CyclicClassDependencyInspection.java @@ -1,5 +1,5 @@ /* - * Copyright 2006-2011 Dave Griffith, Bas Leijdekkers + * Copyright 2006-2013 Dave Griffith, Bas Leijdekkers * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -51,7 +51,7 @@ public class CyclicClassDependencyInspection extends BaseGlobalInspection { } final RefClass refClass = (RefClass)refEntity; final PsiClass aClass = refClass.getElement(); - if (aClass.getContainingClass() != null) { + if (aClass == null || aClass.getContainingClass() != null) { return null; } final Set dependencies = @@ -67,7 +67,7 @@ public class CyclicClassDependencyInspection extends BaseGlobalInspection { } final String errorString = InspectionGadgetsBundle.message( "cyclic.class.dependency.problem.descriptor", - refEntity.getName(), numMutualDependents - 1); + refEntity.getName(), Integer.valueOf(numMutualDependents - 1)); return new CommonProblemDescriptor[]{ inspectionManager.createProblemDescriptor(errorString) }; diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/ErrorRethrownInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/ErrorRethrownInspection.java index 793ad82b4e2f..2310d5380405 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/ErrorRethrownInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/ErrorRethrownInspection.java @@ -51,20 +51,13 @@ public class ErrorRethrownInspection extends BaseInspection { private static class ErrorRethrownVisitor extends BaseInspectionVisitor { @Override - public void visitTryStatement(@NotNull PsiTryStatement statement) { - super.visitTryStatement(statement); - final PsiCatchSection[] catchSections = statement.getCatchSections(); - for (PsiCatchSection catchSection : catchSections) { - checkCatchSection(catchSection); - } - } - - private void checkCatchSection(PsiCatchSection catchSection) { - final PsiParameter parameter = catchSection.getParameter(); + public void visitCatchSection(PsiCatchSection section) { + super.visitCatchSection(section); + final PsiParameter parameter = section.getParameter(); if (parameter == null) { return; } - final PsiCodeBlock catchBlock = catchSection.getCatchBlock(); + final PsiCodeBlock catchBlock = section.getCatchBlock(); if (catchBlock == null) { return; } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/ThreadDeathRethrownInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/ThreadDeathRethrownInspection.java index a79b5b2f9e73..130ace79f489 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/ThreadDeathRethrownInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/errorhandling/ThreadDeathRethrownInspection.java @@ -51,20 +51,13 @@ public class ThreadDeathRethrownInspection extends BaseInspection { private static class ThreadDeathRethrownVisitor extends BaseInspectionVisitor { @Override - public void visitTryStatement(@NotNull PsiTryStatement statement) { - super.visitTryStatement(statement); - final PsiCatchSection[] catchSections = statement.getCatchSections(); - for (PsiCatchSection catchSection : catchSections) { - checkCatchSection(catchSection); - } - } - - private void checkCatchSection(PsiCatchSection catchSection) { - final PsiParameter parameter = catchSection.getParameter(); + public void visitCatchSection(PsiCatchSection section) { + super.visitCatchSection(section); + final PsiParameter parameter = section.getParameter(); if (parameter == null) { return; } - final PsiCodeBlock catchBlock = catchSection.getCatchBlock(); + final PsiCodeBlock catchBlock = section.getCatchBlock(); if (catchBlock == null) { return; } diff --git a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspection.java b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspection.java index d6282386f5b4..7777d874c4ea 100644 --- a/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspection.java +++ b/plugins/InspectionGadgets/InspectionGadgetsAnalysis/src/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspection.java @@ -39,9 +39,6 @@ public class MethodCanBeVariableArityMethodInspection extends BaseInspection { @SuppressWarnings("PublicField") public boolean ignoreOverridingMethods = false; - @SuppressWarnings("PublicField") - public boolean ignoreNullableParameters = true; - @Nls @NotNull @Override @@ -61,7 +58,6 @@ public class MethodCanBeVariableArityMethodInspection extends BaseInspection { panel.addCheckbox(InspectionGadgetsBundle.message("method.can.be.variable.arity.method.ignore.byte.short.option"), "ignoreByteAndShortArrayParameters"); panel.addCheckbox(InspectionGadgetsBundle.message("ignore.methods.overriding.super.method"), "ignoreOverridingMethods"); - panel.addCheckbox(InspectionGadgetsBundle.message("ignore.nullable.parameters.option"), "ignoreNullableParameters"); return panel; } @@ -89,7 +85,7 @@ public class MethodCanBeVariableArityMethodInspection extends BaseInspection { } final PsiParameter[] parameters = parameterList.getParameters(); final PsiParameter lastParameter = parameters[parameters.length - 1]; - if (ignoreNullableParameters && NullableNotNullManager.isNullable(lastParameter)) { + if (NullableNotNullManager.isNullable(lastParameter)) { return; } final PsiType type = lastParameter.getType(); diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspectionTest.java index d6fbed29e2e9..a54bd64d3b47 100644 --- a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspectionTest.java +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/migration/MethodCanBeVariableArityMethodInspectionTest.java @@ -8,7 +8,6 @@ public class MethodCanBeVariableArityMethodInspectionTest extends IGInspectionTe final MethodCanBeVariableArityMethodInspection tool = new MethodCanBeVariableArityMethodInspection(); tool.ignoreByteAndShortArrayParameters = true; tool.ignoreOverridingMethods = true; - tool.ignoreNullableParameters = true; doTest("com/siyeh/igtest/migration/method_can_be_variable_arity_method", tool); } } \ No newline at end of file diff --git a/python/src/com/jetbrains/python/testing/PythonTestCommandLineStateBase.java b/python/src/com/jetbrains/python/testing/PythonTestCommandLineStateBase.java index ef16a65a7658..39e4e96b836b 100644 --- a/python/src/com/jetbrains/python/testing/PythonTestCommandLineStateBase.java +++ b/python/src/com/jetbrains/python/testing/PythonTestCommandLineStateBase.java @@ -106,9 +106,10 @@ public abstract class PythonTestCommandLineStateBase extends PythonCommandLineSt return cmd; } - private void setWorkingDirectory(@NotNull final GeneralCommandLine cmd) { - if (!StringUtil.isEmptyOrSpaces(myConfiguration.getWorkingDirectory())) { - cmd.setWorkDirectory(myConfiguration.getWorkingDirectory()); + protected void setWorkingDirectory(@NotNull final GeneralCommandLine cmd) { + final String workingDirectory = myConfiguration.getWorkingDirectory(); + if (!StringUtil.isEmptyOrSpaces(workingDirectory)) { + cmd.setWorkDirectory(workingDirectory); } else if (myConfiguration instanceof AbstractPythonTestRunConfiguration) { final String folderName = ((AbstractPythonTestRunConfiguration)myConfiguration).getFolderName(); diff --git a/xml/impl/resources/inspectionDescriptions/HtmlFormInputWithoutLabel.html b/xml/impl/resources/inspectionDescriptions/HtmlFormInputWithoutLabel.html index 680c983342d4..52947834a6ae 100644 --- a/xml/impl/resources/inspectionDescriptions/HtmlFormInputWithoutLabel.html +++ b/xml/impl/resources/inspectionDescriptions/HtmlFormInputWithoutLabel.html @@ -1,6 +1,6 @@ -This inspection highlights form elements without required associated label and provides ability to create a new label.
+This inspection highlights form elements without required associated label and provides the ability to create a new label.
\ No newline at end of file diff --git a/xml/impl/resources/inspectionDescriptions/HtmlPresentationalElement.html b/xml/impl/resources/inspectionDescriptions/HtmlPresentationalElement.html index 3a0609aa95fc..46257d041b1b 100644 --- a/xml/impl/resources/inspectionDescriptions/HtmlPresentationalElement.html +++ b/xml/impl/resources/inspectionDescriptions/HtmlPresentationalElement.html @@ -1,6 +1,6 @@ -This inspection highlights pure presentational HTML tags and provides ability to replace them with CSS or with other tags.
+This inspection highlights pure presentational HTML tags and provides the ability to replace them with CSS or with other tags.
\ No newline at end of file diff --git a/xml/impl/resources/inspectionDescriptions/XmlUnboundNsPrefix.html b/xml/impl/resources/inspectionDescriptions/XmlUnboundNsPrefix.html index 2821e9fe15b0..c2d3c150ad28 100644 --- a/xml/impl/resources/inspectionDescriptions/XmlUnboundNsPrefix.html +++ b/xml/impl/resources/inspectionDescriptions/XmlUnboundNsPrefix.html @@ -1,6 +1,6 @@ -This inspection checks for unbound namespace prefixes in XML +This inspection checks for unbound namespace prefixes in XML. \ No newline at end of file diff --git a/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsForm.form b/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsForm.form index 4dd9851442ca..dca1e251f80e 100644 --- a/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsForm.form +++ b/xml/impl/src/com/intellij/application/options/editor/WebEditorOptionsForm.form @@ -65,7 +65,7 @@ - +
diff --git a/xml/relaxng/src/inspectionDescriptions/UnusedDefine.html b/xml/relaxng/src/inspectionDescriptions/UnusedDefine.html index 1a59a9063112..8c22875b4e81 100644 --- a/xml/relaxng/src/inspectionDescriptions/UnusedDefine.html +++ b/xml/relaxng/src/inspectionDescriptions/UnusedDefine.html @@ -18,7 +18,7 @@

This inspections checks for any unused named patterns ("define") in a RELAX-NG file (XML or Compact Syntax) and highlights them as unused symbols. This is done with respect to includes from other files, i.e. a define is not - marked as unused if is is used through an include in another file. + marked as unused if it is used through an include in another file.