mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-01 13:11:39 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -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",
|
||||
|
||||
+4
-7
@@ -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<OrderRootType, LightFilePointer> myRoots;
|
||||
private final List<LightFilePointer> myExcludedRoots;
|
||||
private final Set<LightFilePointer> 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<OrderRootType, LightFilePointer>();
|
||||
myExcludedRoots = new ArrayList<LightFilePointer>();
|
||||
myExcludedRoots = new LinkedHashSet<LightFilePointer>();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -94,7 +91,7 @@ public class NewLibraryEditor extends LibraryEditorBase {
|
||||
}
|
||||
|
||||
private static String[] pointersToUrls(Collection<LightFilePointer> pointers) {
|
||||
List<String> urls = new ArrayList<String>();
|
||||
List<String> urls = new ArrayList<String>(pointers.size());
|
||||
for (LightFilePointer pointer : pointers) {
|
||||
urls.add(pointer.getUrl());
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -211,6 +211,7 @@ public class RefClassImpl extends RefJavaElementImpl implements RefClass {
|
||||
return isSelfInheritor(psiClass, new ArrayList<PsiClass>());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiClass getElement() {
|
||||
return (PsiClass)super.getElement();
|
||||
|
||||
+3
-1
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
+4
@@ -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);
|
||||
@@ -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() {
|
||||
|
||||
+2
-1
@@ -118,6 +118,7 @@ public class MockApplicationEx extends MockApplication implements ApplicationEx
|
||||
|
||||
@Override
|
||||
public boolean tryRunReadAction(@NotNull Runnable runnable) {
|
||||
return false;
|
||||
runReadAction(runnable);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -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<String>() {
|
||||
@Override
|
||||
public String compute() {
|
||||
PsiElement container = getContainer(target);
|
||||
return container instanceof PsiNamedElement ? ((PsiNamedElement)container).getName() : null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static PsiElement getContainer(@NotNull PsiElement refElement) {
|
||||
|
||||
@@ -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<PsiElement> 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 <T> AsyncFuture<Boolean> wrapInFuture(@NotNull List<T> files, final ProgressIndicator progress, @NotNull Processor<T> processor) {
|
||||
AsyncFutureResult<Boolean> 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<Boolean> result = fileSet.isEmpty()
|
||||
? AsyncFutureFactory.wrap(true)
|
||||
? AsyncFutureFactory.wrap(Boolean.TRUE)
|
||||
: processPsiFileRootsAsync(new ArrayList<VirtualFile>(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 <T> void splitSortedLists(@NotNull List<T> mainList,
|
||||
@NotNull List<T> list2,
|
||||
@NotNull Comparator<? super T> comparator,
|
||||
@NotNull List<T> outIntersection,
|
||||
@NotNull List<T> 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> T tryRead(final Computable<T> computable) throws CannotRunReadActionException {
|
||||
final Ref<T> result = new Ref<T>();
|
||||
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<? super PsiFile> psiRootProcessor) {
|
||||
@NotNull final Processor<? super PsiFile> localProcessor) {
|
||||
myManager.startBatchFilesProcessingMode();
|
||||
final AtomicInteger counter = new AtomicInteger(alreadyProcessedFiles);
|
||||
final AtomicBoolean canceled = new AtomicBoolean(false);
|
||||
|
||||
AsyncFuture<Boolean>
|
||||
completed = JobLauncher.getInstance().invokeConcurrentlyUnderProgressAsync(files, progress, false, new Processor<VirtualFile>() {
|
||||
@Override
|
||||
public boolean process(final VirtualFile vfile) {
|
||||
final PsiFile file = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() {
|
||||
AsyncFutureResult<Boolean> asyncFutureResult = AsyncFutureFactory.getInstance().createAsyncFutureResult();
|
||||
final List<VirtualFile> failedFiles = new ArrayList<VirtualFile>();
|
||||
try {
|
||||
boolean completed =
|
||||
JobLauncher.getInstance().invokeConcurrentlyUnderProgress(files, progress, false, false, new Processor<VirtualFile>() {
|
||||
@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<PsiFile> psiRoots = ApplicationManager.getApplication().runReadAction(new Computable<List<PsiFile>>() {
|
||||
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<PsiFile> compute() {
|
||||
return file.getViewProvider().getAllFiles();
|
||||
public void run() {
|
||||
processVirtualFile(vfile, progress, localProcessor, canceled, counter, totalSize);
|
||||
}
|
||||
});
|
||||
Set<PsiElement> processed = new THashSet<PsiElement>(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<? super PsiFile> localProcessor,
|
||||
final AtomicBoolean canceled, AtomicInteger counter, int totalSize) {
|
||||
final PsiFile file = tryRead(new Computable<PsiFile>() {
|
||||
@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<PsiFile> psiRoots = tryRead(new Computable<List<PsiFile>>() {
|
||||
@Override
|
||||
public List<PsiFile> compute() {
|
||||
return file.getViewProvider().getAllFiles();
|
||||
}
|
||||
});
|
||||
final Set<PsiElement> processed = new THashSet<PsiElement>(psiRoots.size() * 2, (float)0.5);
|
||||
TooManyUsagesStatus.getFrom(progress).pauseProcessingIfTooManyUsages();
|
||||
tryRead(new Computable<Void>() {
|
||||
@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<Boolean>() {
|
||||
@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<Boolean>(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<Boolean> processCandidatesAsync(final ProgressIndicator progress,
|
||||
@NotNull final Map<RequestWithProcessor, Processor<PsiElement>> localProcessors,
|
||||
@NotNull final MultiMap<VirtualFile, RequestWithProcessor> candidateFiles,
|
||||
@@ -779,20 +812,19 @@ public class PsiSearchHelperImpl implements PsiSearchHelper {
|
||||
return processPsiFileRootsAsync(files, totalSize, alreadyProcessedFiles, progress, new Processor<PsiFile>() {
|
||||
@Override
|
||||
public boolean process(final PsiFile psiRoot) {
|
||||
final VirtualFile vfile = ApplicationManager.getApplication().runReadAction(new Computable<VirtualFile>() {
|
||||
return tryRead(new Computable<Boolean>() {
|
||||
@Override
|
||||
public VirtualFile compute() {
|
||||
return psiRoot.getVirtualFile();
|
||||
public Boolean compute() {
|
||||
final VirtualFile vfile = psiRoot.getVirtualFile();
|
||||
for (final RequestWithProcessor singleRequest : candidateFiles.get(vfile)) {
|
||||
Processor<PsiElement> localProcessor = localProcessors.get(singleRequest);
|
||||
if (!localProcessor.process(psiRoot)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
for (final RequestWithProcessor singleRequest : candidateFiles.get(vfile)) {
|
||||
Processor<PsiElement> localProcessor = localProcessors.get(singleRequest);
|
||||
TooManyUsagesStatus.getFrom(progress).pauseProcessingIfTooManyUsages();
|
||||
if (!localProcessor.process(psiRoot)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<Long> ourDocumentTimestampKey = Key.create("com.intellij.find.impl.FindResultUsageInfo.documentTimestamp");
|
||||
private static final Key<Long> 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() {
|
||||
|
||||
+2
-1
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -219,7 +219,7 @@ public class ApplierCompleter extends CountedCompleter<Void> {
|
||||
}
|
||||
}
|
||||
});
|
||||
assert task.failedSubTasks == null;
|
||||
assert task.failedSubTasks == null : task.failedSubTasks;
|
||||
}
|
||||
return result[0];
|
||||
}
|
||||
|
||||
@@ -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<T> 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);
|
||||
|
||||
@@ -308,7 +308,13 @@ public abstract class PropertyTable extends JBTable {
|
||||
}
|
||||
|
||||
public void update(@NotNull List<? extends PropertiesContainer> containers, @Nullable Property initialSelection) {
|
||||
finishEditing();
|
||||
update(containers, initialSelection, true);
|
||||
}
|
||||
|
||||
private void update(@NotNull List<? extends PropertiesContainer> 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) {
|
||||
|
||||
+1
-1
@@ -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);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
+1
-1
@@ -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(
|
||||
|
||||
@@ -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<VirtualFile> myChangedFiles = new THashSet<VirtualFile>();
|
||||
|
||||
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<Boolean>() {
|
||||
@Override
|
||||
public Boolean compute() {
|
||||
return PsiTreeUtil.hasErrorElements(psiFile);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return WolfTheProblemSolver.getInstance(myProject).hasSyntaxErrors(file);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+46
-25
@@ -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();
|
||||
|
||||
+14
-8
@@ -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)));
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
+10
-6
@@ -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<String> 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<String> newNames = newTroveSet(FileUtil.PATH_HASHING_STRATEGY, upToDateNames);
|
||||
Set<String> newNames = newTroveSet(strategy, upToDateNames);
|
||||
ContainerUtil.removeAll(newNames, currentNames);
|
||||
Set<String> deletedNames = newTroveSet(FileUtil.PATH_HASHING_STRATEGY, currentNames);
|
||||
Set<String> deletedNames = newTroveSet(strategy, currentNames);
|
||||
ContainerUtil.removeAll(deletedNames, upToDateNames);
|
||||
OpenTHashSet<String> actualNames = null;
|
||||
if (!SystemInfo.isFileSystemCaseSensitive) {
|
||||
actualNames = new OpenTHashSet<String>(FileUtil.PATH_HASHING_STRATEGY, upToDateNames);
|
||||
if (!fs.isCaseSensitive()) {
|
||||
actualNames = new OpenTHashSet<String>(strategy, upToDateNames);
|
||||
}
|
||||
debug(LOG, "current=%s +%s -%s", currentNames, newNames, deletedNames);
|
||||
|
||||
@@ -163,8 +167,8 @@ public class RefreshWorker {
|
||||
else {
|
||||
Collection<VirtualFile> cachedChildren = file.getCachedChildren();
|
||||
OpenTHashSet<String> actualNames = null;
|
||||
if (!SystemInfo.isFileSystemCaseSensitive) {
|
||||
actualNames = new OpenTHashSet<String>(FileUtil.PATH_HASHING_STRATEGY, VfsUtil.filterNames(fs.list(file)));
|
||||
if (!fs.isCaseSensitive()) {
|
||||
actualNames = new OpenTHashSet<String>(strategy, VfsUtil.filterNames(fs.list(file)));
|
||||
}
|
||||
debug(LOG, "cached=%s actual=%s", cachedChildren, actualNames);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
<font face="verdana" size="-1">Allows to see problems reported by language annotators in the results of batch code inspection.
|
||||
<font face="verdana" size="-1">Allows you to see problems reported by language annotators in the results of batch code inspection.
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,5 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
<font face="verdana" size="-1">Allows to see syntax errors in the results of batch code inspection.
|
||||
<font face="verdana" size="-1">Allows you to see syntax errors in the results of batch code inspection.
|
||||
</body>
|
||||
</html>
|
||||
@@ -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:
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<description>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.
|
||||
</description>
|
||||
|
||||
<component>
|
||||
|
||||
+5
-2
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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<String> create() {
|
||||
return SystemInfo.isFileSystemCaseSensitive ? ContainerUtil.<String>canonicalStrategy() : new CaseInsensitiveStringHashingStrategy();
|
||||
return create(SystemInfo.isFileSystemCaseSensitive);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static TObjectHashingStrategy<String> create(boolean caseSensitive) {
|
||||
return caseSensitive ? ContainerUtil.<String>canonicalStrategy() : new CaseInsensitiveStringHashingStrategy();
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -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<RefClass> 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)
|
||||
};
|
||||
|
||||
+4
-11
@@ -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;
|
||||
}
|
||||
|
||||
+4
-11
@@ -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;
|
||||
}
|
||||
|
||||
+1
-5
@@ -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();
|
||||
|
||||
-1
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<html>
|
||||
<body>
|
||||
<font face="verdana" size="-1">This inspection highlights form elements without required associated label and provides ability to create a new label.<br>
|
||||
<font face="verdana" size="-1">This inspection highlights form elements without required associated label and provides the ability to create a new label.<br>
|
||||
</font>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,6 +1,6 @@
|
||||
<html>
|
||||
<body>
|
||||
<font face="verdana" size="-1">This inspection highlights pure presentational HTML tags and provides ability to replace them with CSS or with other tags.<br>
|
||||
<font face="verdana" size="-1">This inspection highlights pure presentational HTML tags and provides the ability to replace them with CSS or with other tags.<br>
|
||||
</font>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,6 +1,6 @@
|
||||
<html>
|
||||
<body>
|
||||
<font face="verdana" size="-1">This inspection checks for unbound namespace prefixes in XML
|
||||
<font face="verdana" size="-1">This inspection checks for unbound namespace prefixes in XML.
|
||||
</font>
|
||||
</body>
|
||||
</html>
|
||||
@@ -65,7 +65,7 @@
|
||||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="Automatically add quotas for attribute value"/>
|
||||
<text value="Automatically add quotes for attribute value"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<p>
|
||||
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.
|
||||
</p>
|
||||
|
||||
<p id="footer">Powered by RELAX-NG Support</p>
|
||||
|
||||
Reference in New Issue
Block a user