Merge remote-tracking branch 'origin/master'

This commit is contained in:
Ilya.Kazakevich
2014-06-25 19:55:39 +04:00
116 changed files with 1481 additions and 878 deletions
@@ -40,7 +40,7 @@ public class MethodsChainsCompletionContributor extends CompletionContributor {
private final static int FILTER_RATIO = 10;
@Override
public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) {
if (parameters.getInvocationCount() >= INVOCATIONS_THRESHOLD &&
ClassFilesIndexFeaturesHolder.getInstance(parameters.getPosition().getProject())
.enableFeatureIfNeed(ClassFilesIndexFeature.METHOD_CHAINS_COMPLETION)) {
@@ -116,8 +116,8 @@ public class JavaExecutionStack extends XExecutionStack {
@Override
protected void action() throws Exception {
boolean showLibraryStackframes = DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES;
List<JavaStackFrame> frames = new ArrayList<JavaStackFrame>();
if (!myThreadProxy.isCollected() && myDebugProcess.getSuspendManager().isSuspended(myThreadProxy)) {
List<JavaStackFrame> frames = new ArrayList<JavaStackFrame>();
int status = myThreadProxy.status();
if (!(status == ThreadReference.THREAD_STATUS_UNKNOWN) &&
!(status == ThreadReference.THREAD_STATUS_NOT_STARTED) &&
@@ -146,8 +146,11 @@ public class JavaExecutionStack extends XExecutionStack {
return;
}
}
container.addStackFrames(frames, true);
}
else {
container.errorOccurred(DebuggerBundle.message("frame.panel.frames.not.available"));
}
container.addStackFrames(frames, true);
}
});
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -43,7 +43,7 @@ import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VfsUtilCore;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
@@ -79,13 +79,14 @@ public class AttachSourcesNotificationProvider extends EditorNotifications.Provi
});
}
@NotNull
@Override
public Key<EditorNotificationPanel> getKey() {
return KEY;
}
@Override
public EditorNotificationPanel createNotificationPanel(final VirtualFile file, FileEditor fileEditor) {
public EditorNotificationPanel createNotificationPanel(@NotNull final VirtualFile file, @NotNull FileEditor fileEditor) {
if (file.getFileType() != JavaClassFileType.INSTANCE) return null;
final List<LibraryOrderEntry> libraries = findOrderEntriesContainingFile(file);
if (libraries == null) return null;
@@ -240,7 +241,7 @@ public class AttachSourcesNotificationProvider extends EditorNotifications.Provi
if (modelsToCommit.isEmpty()) return new ActionCallback.Rejected();
new WriteAction() {
@Override
protected void run(final Result result) {
protected void run(@NotNull final Result result) {
for (Library.ModifiableModel model : modelsToCommit) {
model.commit();
}
@@ -253,7 +254,7 @@ public class AttachSourcesNotificationProvider extends EditorNotifications.Provi
@Nullable
private VirtualFile findRoot(Library library) {
for (VirtualFile classesRoot : library.getFiles(OrderRootType.CLASSES)) {
if (VfsUtil.isAncestor(classesRoot, myClassFile, true)) {
if (VfsUtilCore.isAncestor(classesRoot, myClassFile, true)) {
return classesRoot;
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -53,13 +53,14 @@ public class SetupSDKNotificationProvider extends EditorNotifications.Provider<E
});
}
@NotNull
@Override
public Key<EditorNotificationPanel> getKey() {
return KEY;
}
@Override
public EditorNotificationPanel createNotificationPanel(VirtualFile file, FileEditor fileEditor) {
public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor) {
if (file.getFileType() == JavaClassFileType.INSTANCE) return null;
final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(file);
@@ -13,11 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* User: anna
* Date: 26-Dec-2007
*/
package com.intellij.openapi.roots.ui.configuration.libraryEditor;
import com.intellij.icons.AllIcons;
@@ -30,11 +25,15 @@ import com.intellij.openapi.roots.ui.OrderRootTypeUIFactory;
import javax.swing.*;
/**
* @author anna
* @since 26-Dec-2007
*/
public class ClassesOrderRootTypeUIFactory implements OrderRootTypeUIFactory {
@Override
public SdkPathEditor createPathEditor(Sdk sdk) {
return new SdkPathEditor(ProjectBundle.message("sdk.configure.classpath.tab"), OrderRootType.CLASSES, new FileChooserDescriptor(true, true, true, false, true, true));
FileChooserDescriptor descriptor = new FileChooserDescriptor(true, true, true, false, true, true);
return new SdkPathEditor(ProjectBundle.message("sdk.configure.classpath.tab"), OrderRootType.CLASSES, descriptor);
}
@Override
@@ -52,7 +52,7 @@ public class JavaClassNameCompletionContributor extends CompletionContributor {
psiElement(PsiReferenceList.class).withParent(PsiTypeParameter.class));
@Override
public void fillCompletionVariants(CompletionParameters parameters, final CompletionResultSet _result) {
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull final CompletionResultSet _result) {
if (parameters.getCompletionType() == CompletionType.CLASS_NAME ||
parameters.isExtendedCompletion() && mayContainClassName(parameters)) {
addAllClasses(parameters, _result);
@@ -41,7 +41,7 @@ public class JavaClassReferenceCompletionContributor extends CompletionContribut
}
@Override
public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
PsiElement position = parameters.getPosition();
JavaClassReference reference = findJavaClassReference(position.getContainingFile(), parameters.getOffset());
if (reference == null) {
@@ -196,7 +196,7 @@ public class JavaCompletionContributor extends CompletionContributor {
}
@Override
public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet _result) {
public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet _result) {
if (parameters.getCompletionType() != CompletionType.BASIC) {
return;
}
@@ -140,7 +140,7 @@ public class JavaDocCompletionContributor extends CompletionContributor {
}
@Override
public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) {
PsiElement position = parameters.getPosition();
if (PsiJavaPatterns.psiElement(JavaDocTokenType.DOC_COMMENT_DATA).accepts(position)) {
@@ -39,6 +39,7 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.PlatformIcons;
import com.intellij.util.containers.ContainerUtil;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
@@ -63,7 +64,7 @@ public class JavaMemberNameCompletionContributor extends CompletionContributor {
static final int MAX_SCOPE_SIZE_TO_SEARCH_UNRESOLVED = 50000;
@Override
public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
if (parameters.getCompletionType() != CompletionType.BASIC && parameters.getCompletionType() != CompletionType.SMART) {
return;
}
@@ -19,6 +19,7 @@ import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupItem;
import com.intellij.psi.PsiMethod;
import com.intellij.psi.ResolveResult;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -28,7 +29,7 @@ import java.util.ArrayList;
public class JavaMethodMergingContributor extends CompletionContributor {
@Override
public AutoCompletionDecision handleAutoCompletionPossibility(AutoCompletionContext context) {
public AutoCompletionDecision handleAutoCompletionPossibility(@NotNull AutoCompletionContext context) {
final CompletionParameters parameters = context.getParameters();
if (parameters.getCompletionType() != CompletionType.SMART && parameters.getCompletionType() != CompletionType.BASIC) {
return null;
@@ -27,6 +27,7 @@ import com.intellij.psi.filters.ElementFilter;
import com.intellij.psi.search.PsiShortNamesCache;
import com.intellij.util.CollectConsumer;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
@@ -42,7 +43,7 @@ import static com.intellij.patterns.PsiJavaPatterns.psiElement;
public class JavaNoVariantsDelegator extends CompletionContributor {
@Override
public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) {
public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull CompletionResultSet result) {
LinkedHashSet<CompletionResult> plainResults = result.runRemainingContributors(parameters, true);
final boolean empty = containsOnlyPackages(plainResults) || suggestMetaAnnotations(parameters);
@@ -352,7 +352,7 @@ public class JavaSmartCompletionContributor extends CompletionContributor {
}
@Override
public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
super.fillCompletionVariants(parameters, JavaCompletionSorting.addJavaSorting(parameters, result));
}
@@ -24,13 +24,14 @@ import com.intellij.openapi.module.ModuleUtil;
import com.intellij.psi.PsiClass;
import com.intellij.refactoring.ui.ClassNameReferenceEditor;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
/**
* @author peter
*/
public class RefactoringCompletionContributor extends CompletionContributor {
@Override
public void fillCompletionVariants(CompletionParameters parameters, final CompletionResultSet resultSet) {
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull final CompletionResultSet resultSet) {
if (parameters.getOriginalFile().getUserData(ClassNameReferenceEditor.CLASS_NAME_REFERENCE_FRAGMENT) == null) {
return;
}
@@ -21,6 +21,7 @@ import com.intellij.lang.StdLanguages;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
/**
* @author peter
@@ -28,7 +29,7 @@ import com.intellij.util.Consumer;
public class XmlBasicToClassNameDelegator extends CompletionContributor {
@Override
public void fillCompletionVariants(CompletionParameters parameters, final CompletionResultSet result) {
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull final CompletionResultSet result) {
PsiElement position = parameters.getPosition();
PsiFile file = position.getContainingFile();
if (parameters.getCompletionType() != CompletionType.BASIC ||
@@ -25,6 +25,7 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.Consumer;
import gnu.trove.THashSet;
import gnu.trove.TObjectHashingStrategy;
import org.jetbrains.annotations.NotNull;
import java.util.Arrays;
import java.util.List;
@@ -46,7 +47,7 @@ public class MagicCompletionContributor extends CompletionContributor {
private static final int PRIORITY = 100;
@Override
public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) {
//if (parameters.getCompletionType() != CompletionType.SMART) return;
PsiElement pos = parameters.getPosition();
MagicConstantInspection.AllowedValues allowedValues = null;
@@ -22,12 +22,11 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.HierarchicalMethodSignatureImpl;
import com.intellij.psi.impl.source.PsiClassImpl;
import com.intellij.psi.search.searches.DeepestSuperMethodsSearch;
import com.intellij.psi.search.searches.SuperMethodsSearch;
import com.intellij.psi.util.*;
import com.intellij.util.NotNullFunction;
import com.intellij.util.Processor;
import com.intellij.util.SmartList;
import com.intellij.util.*;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import gnu.trove.TObjectHashingStrategy;
@@ -143,7 +142,15 @@ public class PsiSuperMethodImplUtil {
}
});
for (PsiMethod method : aClass.getMethods()) {
PsiMethod[] methods = aClass.getMethods();
if (aClass instanceof PsiClassImpl) {
final PsiMethod valuesMethod = ((PsiClassImpl)aClass).getValuesMethod();
if (valuesMethod != null) {
methods = ArrayUtil.append(methods, valuesMethod);
}
}
for (PsiMethod method : methods) {
if (!method.isValid()) {
throw new PsiInvalidElementAccessException(method, "class.valid=" + aClass.isValid() + "; name=" + method.getName());
}
@@ -0,0 +1,25 @@
import java.util.function.Supplier;
class EnumValues {
{
Supplier<I<ABC>> supplier = () -> new C<>(ABC::values);
}
private static interface I<T> {
T get();
}
private static class C<E> implements I<E> {
C(Supplier<E[]> supplier) {}
@Override
public E get() {
return null;
}
}
private static enum ABC {
A, B, C
}
}
@@ -26,6 +26,8 @@ import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.testFramework.PsiTestUtil
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase
import org.jetbrains.annotations.NotNull
/**
* @author peter
*/
@@ -94,7 +96,7 @@ public class HeavyNormalCompletionTest extends JavaCodeInsightFixtureTestCase {
static class CacheVerifyingContributor extends CompletionContributor {
@Override
void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
PsiClass psiClass = PsiTreeUtil.getParentOfType(parameters.position, PsiClass)
for (ci in OverrideImplementExploreUtil.getMethodsToOverrideImplement(psiClass, true)) {
assert ci.element.valid
@@ -561,7 +561,7 @@ public interface Test {
static class LongContributor extends CompletionContributor {
@Override
void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
result.runRemainingContributors(parameters, true)
Thread.sleep 500
}
@@ -265,6 +265,10 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
doTest();
}
public void testEnumValuesMethod() throws Exception {
doTest();
}
private void doTest() {
doTest(false);
}
@@ -86,10 +86,8 @@ public class ClsMirrorBuildingTest extends LightIdeaTestCase {
private static void doTest(String clsPath, String txtPath) {
VirtualFileSystem fs = clsPath.contains("!/") ? JarFileSystem.getInstance() : LocalFileSystem.getInstance();
VirtualFile vFile = fs.findFileByPath(clsPath);
assertNotNull(clsPath, vFile);
PsiFile clsFile = getPsiManager().findFile(vFile);
assertNotNull(vFile.getPath(), clsFile);
VirtualFile file = fs.findFileByPath(clsPath);
assertNotNull(clsPath, file);
String expected;
try {
@@ -100,6 +98,6 @@ public class ClsMirrorBuildingTest extends LightIdeaTestCase {
return;
}
assertEquals(expected, ((ClsFileImpl)clsFile).getMirror().getText());
assertEquals(expected, ClsFileImpl.decompile(file).toString());
}
}
@@ -690,7 +690,6 @@ public class ClsRepositoryUseTest extends PsiTestCase {
final PsiType returnType = methodsWithReturnType.getReturnType();
assert returnType != null : methodsWithReturnType;
assertEquals("pack.Parametrized<? extends T>", returnType.getCanonicalText());
assertEquals("public pack.Parametrized<? extends T> method() { /* compiled code */ }", methodsWithReturnType.getText());
}
private static void checkEnumConstant(String name, PsiField field, PsiClassType type) {
@@ -740,19 +739,20 @@ public class ClsRepositoryUseTest extends PsiTestCase {
assertEquals(PsiWildcardType.createUnbounded(myPsiManager), substitution);
}
@SuppressWarnings("ConstantConditions")
public void testModifiers() throws Exception {
final PsiClass psiClass = myJavaFacade.findClass("pack.Modifiers", RESOLVE_SCOPE);
PsiClass psiClass = myJavaFacade.findClass("pack.Modifiers", RESOLVE_SCOPE);
assertNotNull(psiClass);
assertEquals("public class Modifiers {\n" +
" private transient int f1;\n" +
" private volatile int f2;\n" +
"\n" +
" public Modifiers() { /* compiled code */ }\n" +
"\n" +
" private void m1(int... i) { /* compiled code */ }\n" +
"\n" +
" private synchronized void m2() { /* compiled code */ }\n" +
"}",
psiClass.getText().trim());
PsiField f1 = psiClass.findFieldByName("f1", false);
assertEquals("private transient", f1.getModifierList().getText());
PsiField f2 = psiClass.findFieldByName("f2", false);
assertEquals("private volatile", f2.getModifierList().getText());
PsiMethod init = psiClass.findMethodsByName("Modifiers", false)[0];
assertEquals("public", init.getModifierList().getText());
PsiMethod m1 = psiClass.findMethodsByName("m1", false)[0];
assertEquals("private", m1.getModifierList().getText());
PsiMethod m2 = psiClass.findMethodsByName("m2", false)[0];
assertEquals("private synchronized", m2.getModifierList().getText());
}
}
@@ -20,12 +20,12 @@ import com.intellij.openapi.vfs.LocalFileSystem
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiManager
import com.intellij.psi.PsiMethod
import com.intellij.psi.impl.source.PsiFileImpl
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.searches.ClassInheritorsSearch
import com.intellij.psi.search.searches.OverridingMethodsSearch
import com.intellij.psi.stubs.StubTreeLoader
import com.intellij.testFramework.PsiTestUtil
import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase
/**
@@ -150,14 +150,12 @@ class ResolveInLibrariesTest extends JavaCodeInsightFixtureTestCase {
Collection<VirtualFile> pkgDirs = pkg.directories.collect { it.virtualFile }
Collection<VirtualFile> pkgChildren = pkgDirs.collect { it.children as List }.flatten()
PsiFile javaSrc = psiManager.findFile(pkgChildren.find { it.name == 'LibraryClass.java' })
assert !javaSrc.contentsLoaded
assert !javaSrc.stub
VirtualFile javaSrc = pkgChildren.find { it.name == 'LibraryClass.java' }
checkFileIsNotLoadedAndHasNoIndexedStub(javaSrc)
assert pkg.containsClassNamed('LibraryClass')
assert !javaSrc.contentsLoaded
assert !javaSrc.stub
assert !javaSrc.node.parsed
checkFileIsNotLoadedAndHasNoIndexedStub(javaSrc)
assert !((PsiFileImpl)psiManager.findFile(javaSrc)).treeElement
}
@Override
@@ -174,7 +172,7 @@ class ResolveInLibrariesTest extends JavaCodeInsightFixtureTestCase {
def localFile = myFixture.copyFileToProject(testDataPathForTest + File.separator + "Foo.java", 'Foo.java')
assert localFile != null
checkFileIsNotLoadedAndHasNoStub(localFile)
checkFileIsNotLoadedAndHasNoIndexedStub(localFile)
assert facade.findClasses('Foo', scope).size() == 0
PsiTestUtil.addLibrary(myModule, 'cas', lib.path, [] as String[], ["/classesAndSources.jar!/"] as String[])
@@ -187,14 +185,16 @@ class ResolveInLibrariesTest extends JavaCodeInsightFixtureTestCase {
assert facade.findClasses('LibraryClass', scope).size() == 0
checkFileIsNotLoadedAndHasNoStub(vfile)
checkFileIsNotLoadedAndHasNoIndexedStub(vfile)
}
private void checkFileIsNotLoadedAndHasNoStub(VirtualFile vfile) {
def file = PsiManager.getInstance(project).findFile(vfile);
private void checkFileIsNotLoadedAndHasNoIndexedStub(VirtualFile vfile) {
PsiFileImpl file = psiManager.findFile(vfile);
assert file != null
assert !file.contentsLoaded
assert !file.stub
assert !StubTreeLoader.instance.readFromVFile(project, vfile)
assert !StubTreeLoader.instance.canHaveStub(vfile)
assert file.stub // from text
}
}
@@ -23,6 +23,7 @@ import com.intellij.util.IncorrectOperationException;
import com.intellij.util.Processor;
import com.intellij.util.SmartList;
import com.intellij.util.WalkingState;
import com.intellij.util.concurrency.AtomicFieldUpdater;
import gnu.trove.TLongHashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
@@ -32,7 +33,6 @@ import java.lang.ref.WeakReference;
import java.util.ConcurrentModificationException;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -295,14 +295,14 @@ public abstract class IntervalTreeImpl<T extends MutableInterval> extends RedBla
}
/**
* packing/unpacking cachedDeltaUpToRoot field parts
* Bits layout:
* XXXXXXXXNMMMMMMMM where
* XXXXXXXX - 31bit int containing cached delta up to root
* N - 1bit flag. if set then all deltas up to root are null
* MMMMMMMM - 32bit int containing this node modification count
* packing/unpacking cachedDeltaUpToRoot field parts
* Bits layout:
* XXXXXXXXNMMMMMMMM where
* XXXXXXXX - 31bit int containing cached delta up to root
* N - 1bit flag. if set then all deltas up to root are null
* MMMMMMMM - 32bit int containing this node modification count
*/
private static final AtomicLongFieldUpdater<IntervalNode> cachedDeltaUpdater = AtomicLongFieldUpdater.newUpdater(IntervalNode.class, "cachedDeltaUpToRoot");
private static final AtomicFieldUpdater<IntervalNode, Long> cachedDeltaUpdater = AtomicFieldUpdater.forLongFieldIn(IntervalNode.class);
private void setCachedValues(int deltaUpToRoot, boolean allDeltaUpToRootAreNull, int modCount) {
cachedDeltaUpToRoot = packValues(deltaUpToRoot, allDeltaUpToRootAreNull, modCount);
@@ -316,7 +316,7 @@ public abstract class IntervalTreeImpl<T extends MutableInterval> extends RedBla
if (myIntervalTree.modCount != treeModCount) return false;
long newValue = packValues(deltaUpToRoot, allDeltasUpAreNull, treeModCount);
long oldValue = cachedDeltaUpToRoot;
return cachedDeltaUpdater.compareAndSet(this, oldValue, newValue);
return cachedDeltaUpdater.compareAndSetLong(this, oldValue, newValue);
}
private static boolean allDeltasUpAreNull(long packedOffsets) {
@@ -17,14 +17,19 @@ package com.intellij.openapi.module.impl.scopes;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.ProjectScope;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.containers.Queue;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
@@ -52,28 +57,49 @@ class ModuleWithDependentsScope extends GlobalSearchScope {
}
private void fillModules() {
ModuleIndex index = getModuleIndex(myModule.getProject());
Queue<Module> walkingQueue = new Queue<Module>(10);
walkingQueue.addLast(myModule);
Module[] allModules = ModuleManager.getInstance(myModule.getProject()).getModules();
Set<Module> processed = new THashSet<Module>();
while (!walkingQueue.isEmpty()) {
Module current = walkingQueue.pullFirst();
processed.add(current);
for (Module dependent : allModules) {
for (OrderEntry orderEntry : ModuleRootManager.getInstance(dependent).getOrderEntries()) {
if (orderEntry instanceof ModuleOrderEntry && current.equals(((ModuleOrderEntry)orderEntry).getModule())) {
myModules.add(dependent);
if (!processed.contains(dependent) && ((ModuleOrderEntry)orderEntry).isExported()) {
walkingQueue.addLast(dependent);
}
}
myModules.addAll(index.plainUsages.get(current));
for (Module dependent : index.exportingUsages.get(current)) {
if (myModules.add(dependent)) {
walkingQueue.addLast(dependent);
}
}
}
}
private static class ModuleIndex {
final MultiMap<Module, Module> plainUsages = MultiMap.create();
final MultiMap<Module, Module> exportingUsages = MultiMap.create();
}
private static ModuleIndex getModuleIndex(final Project project) {
return CachedValuesManager.getManager(project).getCachedValue(project, new CachedValueProvider<ModuleIndex>() {
@Nullable
@Override
public Result<ModuleIndex> compute() {
ModuleIndex index = new ModuleIndex();
for (Module module : ModuleManager.getInstance(project).getModules()) {
for (OrderEntry orderEntry : ModuleRootManager.getInstance(module).getOrderEntries()) {
if (orderEntry instanceof ModuleOrderEntry) {
Module referenced = ((ModuleOrderEntry)orderEntry).getModule();
if (referenced != null) {
MultiMap<Module, Module> map = ((ModuleOrderEntry)orderEntry).isExported() ? index.exportingUsages : index.plainUsages;
map.putValue(referenced, module);
}
}
}
}
return Result.create(index, ProjectRootManager.getInstance(project));
}
});
}
@Override
public boolean contains(@NotNull VirtualFile file) {
return contains(file, false);
@@ -128,7 +128,8 @@ public abstract class CompletionContributor {
private final MultiMap<CompletionType, Pair<ElementPattern<? extends PsiElement>, CompletionProvider<CompletionParameters>>> myMap =
new MultiMap<CompletionType, Pair<ElementPattern<? extends PsiElement>, CompletionProvider<CompletionParameters>>>();
public final void extend(@Nullable CompletionType type, final ElementPattern<? extends PsiElement> place, CompletionProvider<CompletionParameters> provider) {
public final void extend(@Nullable CompletionType type,
@NotNull final ElementPattern<? extends PsiElement> place, CompletionProvider<CompletionParameters> provider) {
myMap.putValue(type, new Pair<ElementPattern<? extends PsiElement>, CompletionProvider<CompletionParameters>>(place, provider));
}
@@ -144,11 +145,8 @@ public abstract class CompletionContributor {
* is of your favourite kind. This method is run inside a read action. If you do any long activity non-related to PSI in it, please
* ensure you call {@link com.intellij.openapi.progress.ProgressManager#checkCanceled()} often enough so that the completion process
* can be cancelled smoothly when the user begins to type in the editor.
*
* @param parameters
* @param result
*/
public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) {
public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull CompletionResultSet result) {
for (final Pair<ElementPattern<? extends PsiElement>, CompletionProvider<CompletionParameters>> pair : myMap.get(parameters.getCompletionType())) {
final ProcessingContext context = new ProcessingContext();
if (pair.first.accepts(parameters.getPosition(), context)) {
@@ -171,7 +169,6 @@ public abstract class CompletionContributor {
/**
* Invoked before completion is started. Is used mainly for determining custom offsets in editor, and to change default dummy identifier.
* @param context
*/
public void beforeCompletion(@NotNull CompletionInitializationContext context) {
}
@@ -188,8 +185,6 @@ public abstract class CompletionContributor {
/**
*
* @param parameters
* @param editor
* @return hint text to be shown if no variants are found, typically "No suggestions"
*/
@Nullable
@@ -201,7 +196,7 @@ public abstract class CompletionContributor {
* Called when the completion is finished quickly, lookup hasn't been shown and gives possibility to autoinsert some item (typically - the only one).
*/
@Nullable
public AutoCompletionDecision handleAutoCompletionPossibility(AutoCompletionContext context) {
public AutoCompletionDecision handleAutoCompletionPossibility(@NotNull AutoCompletionContext context) {
return null;
}
@@ -226,15 +221,16 @@ public abstract class CompletionContributor {
}
/**
* @param actionId
* @return String representation of action shortcut. Useful while advertising something
* @see #advertise(CompletionParameters)
*/
protected static String getActionShortcut(@NonNls final String actionId) {
@NotNull
protected static String getActionShortcut(@NonNls @NotNull final String actionId) {
return KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction(actionId));
}
public static List<CompletionContributor> forParameters(final CompletionParameters parameters) {
@NotNull
public static List<CompletionContributor> forParameters(@NotNull final CompletionParameters parameters) {
return ApplicationManager.getApplication().runReadAction(new Computable<List<CompletionContributor>>() {
@Override
public List<CompletionContributor> compute() {
@@ -243,6 +239,7 @@ public abstract class CompletionContributor {
});
}
@NotNull
public static List<CompletionContributor> forLanguage(@NotNull Language language) {
return MyExtensionPointManager.INSTANCE.forKey(language);
}
@@ -175,7 +175,7 @@ public class PathEditor {
requestDefaultFocus();
}
private VirtualFile[] doAdd() {
protected VirtualFile[] doAdd() {
VirtualFile baseDir = myAddBaseDir;
Project project = CommonDataKeys.PROJECT.getData(DataManager.getInstance().getDataContext(myPanel));
if (baseDir == null && project != null) {
@@ -13,11 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* User: anna
* Date: 26-Dec-2007
*/
package com.intellij.openapi.roots.ui;
import com.intellij.openapi.application.ApplicationManager;
@@ -31,16 +26,20 @@ import org.jetbrains.annotations.NotNull;
import javax.swing.*;
/**
* @author anna
* @since 26-Dec-2007
*/
public interface OrderRootTypeUIFactory {
ExtensionPointName<KeyedFactoryEPBean> EP_NAME = ExtensionPointName.create("com.intellij.OrderRootTypeUI");
KeyedExtensionFactory<OrderRootTypeUIFactory, OrderRootType> FACTORY = new KeyedExtensionFactory<OrderRootTypeUIFactory, OrderRootType>(OrderRootTypeUIFactory.class, EP_NAME,
ApplicationManager
.getApplication().getPicoContainer()) {
@Override
public String getKey(@NotNull final OrderRootType key) {
return key.name();
}
};
KeyedExtensionFactory<OrderRootTypeUIFactory, OrderRootType> FACTORY =
new KeyedExtensionFactory<OrderRootTypeUIFactory, OrderRootType>(OrderRootTypeUIFactory.class, EP_NAME, ApplicationManager.getApplication().getPicoContainer()) {
@Override
public String getKey(@NotNull final OrderRootType key) {
return key.name();
}
};
SdkPathEditor createPathEditor(Sdk sdk);
@@ -1,5 +1,6 @@
package com.intellij.codeInsight.completion;
import com.intellij.codeInsight.AutoPopupController;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.Editor;
@@ -11,7 +12,14 @@ import com.intellij.psi.PsiDocumentManager;
* @author zolotov
*/
public class AddSpaceInsertHandler implements InsertHandler<LookupElement> {
public final static InsertHandler<LookupElement> INSTANCE = new AddSpaceInsertHandler();
public final static InsertHandler<LookupElement> INSTANCE = new AddSpaceInsertHandler(false);
public final static InsertHandler<LookupElement> INSTANCE_WITH_AUTO_POPUP = new AddSpaceInsertHandler(true);
private final boolean myTriggerAutoPopup;
public AddSpaceInsertHandler(boolean triggerAutoPopup) {
myTriggerAutoPopup = triggerAutoPopup;
}
public void handleInsert(InsertionContext context, LookupElement item) {
Editor editor = context.getEditor();
@@ -25,6 +33,9 @@ public class AddSpaceInsertHandler implements InsertHandler<LookupElement> {
else {
editor.getCaretModel().moveToOffset(editor.getCaretModel().getOffset() + 1);
}
if (myTriggerAutoPopup) {
AutoPopupController.getInstance(project).autoPopupMemberLookup(editor, null);
}
}
}
@@ -21,6 +21,7 @@ import com.intellij.openapi.editor.Document;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.ui.StringComboboxEditor;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -30,7 +31,7 @@ import javax.swing.*;
public class ComboEditorCompletionContributor extends CompletionContributor{
@Override
public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) {
if (parameters.getInvocationCount() == 0) {
return;
}
@@ -66,7 +66,7 @@ public class DefaultCompletionContributor extends CompletionContributor {
}
@Override
public AutoCompletionDecision handleAutoCompletionPossibility(AutoCompletionContext context) {
public AutoCompletionDecision handleAutoCompletionPossibility(@NotNull AutoCompletionContext context) {
final LookupElement[] items = context.getItems();
if (items.length == 1) {
final LookupElement item = items[0];
@@ -26,6 +26,7 @@ import com.intellij.psi.PsiReference;
import com.intellij.psi.ReferenceRange;
import com.intellij.psi.impl.source.resolve.reference.impl.PsiMultiReference;
import com.intellij.util.PairConsumer;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.LinkedHashSet;
@@ -38,7 +39,7 @@ public class LegacyCompletionContributor extends CompletionContributor {
private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.completion.LegacyCompletionContributor");
@Override
public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet _result) {
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet _result) {
if (parameters.getCompletionType() != CompletionType.BASIC) {
return;
}
@@ -30,6 +30,7 @@ import com.intellij.psi.*;
import com.intellij.psi.impl.cache.impl.id.IdTableBuilding;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
@@ -45,7 +46,7 @@ import static com.intellij.patterns.PlatformPatterns.psiElement;
public class WordCompletionContributor extends CompletionContributor implements DumbAware {
@Override
public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull final CompletionResultSet result) {
if (parameters.getCompletionType() == CompletionType.BASIC && shouldPerformWordCompletion(parameters)) {
addWordCompletionVariants(result, parameters, Collections.<String>emptySet());
}
@@ -78,7 +78,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
private final Editor myEditor;
private final JBList myList = new JBList(new CollectionListModel<LookupElement>()) {
@Override
protected void processKeyEvent(final KeyEvent e) {
protected void processKeyEvent(@NotNull final KeyEvent e) {
final char keyChar = e.getKeyChar();
if (keyChar == KeyEvent.VK_ENTER || keyChar == KeyEvent.VK_TAB) {
IdeFocusManager.getInstance(myProject).requestFocus(myEditor.getContentComponent(), true).doWhenDone(new Runnable() {
@@ -590,7 +590,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
final String prefix = itemPattern(item);
final int length = prefix.length();
if (length == 0 || !StringUtil.startsWithIgnoreCase(lookupString, prefix)) return lookupString;
if (length == 0 || !itemMatcher(item).prefixMatches(prefix)) return lookupString;
boolean isAllLower = true;
boolean isAllUpper = true;
boolean sameCase = true;
@@ -771,7 +771,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable
private LookupElement oldItem = null;
@Override
public void valueChanged(ListSelectionEvent e){
public void valueChanged(@NotNull ListSelectionEvent e){
final LookupElement item = getCurrentItem();
if (oldItem != item && !myList.isEmpty()) { // do not update on temporary model wipe
fireCurrentItemChanged(item);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotificationPanel;
import com.intellij.ui.EditorNotifications;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
@@ -33,6 +34,7 @@ public class GeneratedFileEditingNotificationProvider extends EditorNotification
myChangeTracker = changeTracker;
}
@NotNull
@Override
public Key<EditorNotificationPanel> getKey() {
return KEY;
@@ -40,7 +42,7 @@ public class GeneratedFileEditingNotificationProvider extends EditorNotification
@Nullable
@Override
public EditorNotificationPanel createNotificationPanel(VirtualFile file, FileEditor fileEditor) {
public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor) {
if (!myChangeTracker.isEditedGeneratedFile(file)) return null;
EditorNotificationPanel panel = new EditorNotificationPanel();
@@ -437,7 +437,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
search.setText("");
search.getTextEditor().setForeground(UIUtil.getLabelForeground());
//myTitleIndexes = new TitleIndexes();
//titleIndex = new TitleIndexes();
editor.setColumns(SEARCH_FIELD_COLUMNS);
myFocusComponent = e.getOppositeComponent();
//noinspection SSBasedInspection
@@ -476,9 +476,9 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
final int index = myList.getSelectedIndex();
final SearchListModel model = getModel();
if (index >= 0) {
final int newIndex = forward ? model.myTitleIndexes.next(index) : model.myTitleIndexes.prev(index);
final int newIndex = forward ? model.next(index) : model.prev(index);
myList.setSelectedIndex(newIndex);
int more = model.myTitleIndexes.next(newIndex) - 1;
int more = model.next(newIndex) - 1;
if (more < newIndex) {
more = myList.getItemsCount() - 1;
}
@@ -529,38 +529,27 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
assert project != null;
final SearchListModel model = getModel();
if (isMoreItem(index)) {
String actionId = null;
if (index == model.myMoreIndexes.myMoreClassesIndex) {
final String pattern = myPopupField.getText();
final String pattern = myPopupField.getText();
WidgetID wid = null;
if (index == model.moreIndex.classes) wid = WidgetID.CLASSES;
else if (index == model.moreIndex.files) wid = WidgetID.FILES;
else if (index == model.moreIndex.settings) wid = WidgetID.SETTINGS;
else if (index == model.moreIndex.actions) wid = WidgetID.ACTIONS;
else if (index == model.moreIndex.symbols) wid = WidgetID.SYMBOLS;
else if (index == model.moreIndex.runConfigurations) wid = WidgetID.RUN_CONFIGURATIONS;
if (wid != null) {
final WidgetID widgetID = wid;
myCurrentWorker.doWhenProcessed(new Runnable() {
@Override
public void run() {
myCalcThread = new CalcThread(project, pattern, true);
myPopupActualWidth = 0;
myCurrentWorker = myCalcThread.insertClasses(index);
myCurrentWorker = myCalcThread.insert(index, widgetID);
}
});
return;
}
else if (index == model.myMoreIndexes.myMoreFilesIndex) actionId = "GotoFile";
else if (index == model.myMoreIndexes.myMoreSettingsIndex) actionId = "ShowSettings";
else if (index == model.myMoreIndexes.myMoreActionsIndex) actionId = "GotoAction";
else if (index == model.myMoreIndexes.myMoreSymbolsIndex) actionId = "GotoSymbol";
if (actionId != null) {
final AnAction action = ActionManager.getInstance().getAction(actionId);
GotoActionAction.openOptionOrPerformAction(action, getField().getText(), project, getField(), myActionEvent);
//noinspection SSBasedInspection
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
if (myPopup != null && myPopup.isVisible()) {
myPopup.cancel();
}
}
});
return;
}
}
final String pattern = getField().getText();
final Object value = myList.getSelectedValue();
@@ -630,11 +619,12 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
private boolean isMoreItem(int index) {
final SearchListModel model = getModel();
return index == model.myMoreIndexes.myMoreClassesIndex ||
index == model.myMoreIndexes.myMoreFilesIndex ||
index == model.myMoreIndexes.myMoreSettingsIndex ||
index == model.myMoreIndexes.myMoreActionsIndex ||
index == model.myMoreIndexes.myMoreSymbolsIndex;
return index == model.moreIndex.classes ||
index == model.moreIndex.files ||
index == model.moreIndex.settings ||
index == model.moreIndex.actions ||
index == model.moreIndex.symbols ||
index == model.moreIndex.runConfigurations;
}
private void rebuildList(final String pattern) {
@@ -1040,7 +1030,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
bg = cmp.getBackground();
}
myMainPanel.setBorder(new CustomLineBorder(bg, 0, 0, 2, 0));
String title = getModel().myTitleIndexes.getTitle(index);
String title = getModel().titleIndex.getTitle(index);
myMainPanel.removeAll();
if (title != null) {
myTitle.setText(title);
@@ -1149,7 +1139,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
myTitle.setFont(getTitleFont());
int index = 0;
while (index < model.getSize()) {
String title = getModel().myTitleIndexes.getTitle(index);
String title = getModel().titleIndex.getTitle(index);
if (title != null) {
myTitle.setText(title);
}
@@ -1208,6 +1198,8 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
return UIUtil.getLabelFont().deriveFont(UIUtil.getFontSize(UIUtil.FontSize.SMALL));
}
enum WidgetID {CLASSES, FILES, ACTIONS, SETTINGS, SYMBOLS, RUN_CONFIGURATIONS}
@SuppressWarnings("SSBasedInspection")
private class CalcThread implements Runnable {
private final Project project;
@@ -1239,8 +1231,6 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
//noinspection unchecked
myList.setModel(myListModel);
myAlreadyAddedFiles.clear();
myAlreadyAddedActions.clear();
}
});
@@ -1340,7 +1330,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
public void run() {
if (isCanceled()) return;
if (toolWindows.size() > 0) {
myListModel.myTitleIndexes.toolWindows = myListModel.size();
myListModel.titleIndex.toolWindows = myListModel.size();
for (Object toolWindow : toolWindows) {
myListModel.addElement(toolWindow);
}
@@ -1349,9 +1339,8 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
});
}
private synchronized void buildActionsAndSettings(String pattern) {
final Set<Object> actions = new HashSet<Object>();
final Set<Object> settings = new HashSet<Object>();
private SearchResult getActionsOrSettings(final String pattern, final int max, final boolean actions) {
final SearchResult result = new SearchResult();
final MinusculeMatcher matcher = new MinusculeMatcher("*" +pattern, NameUtil.MatchingCaseSensitivity.NONE);
if (myActions == null) {
if (myActionModel == null) {
@@ -1367,16 +1356,24 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
Object[] objects = myActionModel.getElementsByName(o.elementName, true, pattern);
for (Object object : objects) {
check();
if (isSetting(object) && settings.size() < MAX_SETTINGS) {
if (myListModel.contains(object)) continue;
if (!actions && isSetting(object)) {
if (matcher.matches(getSettingText((OptionDescription)object))) {
settings.add(object);
result.add(object);
}
} else if (actions && !isToolWindowAction(object) && isActionValue(object)) {
result.add(object);
}
else if (!isToolWindowAction(object) && isActionValue(object) && actions.size() < MAX_ACTIONS) {
actions.add(object);
}
if (result.size() == max) return result;
}
}
return result;
}
private synchronized void buildActionsAndSettings(String pattern) {
final SearchResult actions = getActionsOrSettings(pattern, MAX_ACTIONS, true);
final SearchResult settings = getActionsOrSettings(pattern, MAX_SETTINGS, false);
check();
@@ -1385,66 +1382,25 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
public void run() {
if (isCanceled()) return;
if (actions.size() > 0) {
myListModel.myTitleIndexes.actions = myListModel.size();
myListModel.titleIndex.actions = myListModel.size();
for (Object action : actions) {
myListModel.addElement(action);
}
}
myListModel.myMoreIndexes.myMoreActionsIndex = actions.size() >= MAX_ACTIONS ? myListModel.size() - 1 : -1;
myListModel.moreIndex.actions = actions.size() >= MAX_ACTIONS ? myListModel.size() - 1 : -1;
if (settings.size() > 0) {
myListModel.myTitleIndexes.settings = myListModel.size();
myListModel.titleIndex.settings = myListModel.size();
for (Object setting : settings) {
myListModel.addElement(setting);
}
}
myListModel.myMoreIndexes.myMoreSettingsIndex = settings.size() >= MAX_SETTINGS ? myListModel.size() - 1 : -1;
myListModel.moreIndex.settings = settings.size() >= MAX_SETTINGS ? myListModel.size() - 1 : -1;
}
});
}
private synchronized void buildFiles(final String pattern) {
int filesCounter = 0;
final Set<Object> elements = new LinkedHashSet<Object>();
final GlobalSearchScope scope = GlobalSearchScope.projectScope(project);
myFileChooseByName.getProvider().filterElements(myFileChooseByName, pattern, true,
myProgressIndicator, new Processor<Object>() {
@Override
public boolean process(Object o) {
VirtualFile file = null;
if (o instanceof VirtualFile) {
file = (VirtualFile)o;
} else if (o instanceof PsiFile) {
file = ((PsiFile)o).getVirtualFile();
} else if (o instanceof PsiDirectory) {
file = ((PsiDirectory)o).getVirtualFile();
}
if (file != null
&& !(pattern.indexOf(' ') != -1 && file.getName().indexOf(' ') == -1)
&& (showAll.get() || scope.accept(file))) {
elements.add(o);
}
return elements.size() < 30;
}
});
final List<Object> files = new ArrayList<Object>();
for (Object object : elements) {
if (filesCounter > MAX_FILES) break;
if (!myListModel.contains(object)) {
if (object instanceof PsiFile) {
object = ((PsiFile)object).getVirtualFile();
}
if ((object instanceof VirtualFile && !myAlreadyAddedFiles.contains(object))
|| object instanceof PsiDirectory) {
files.add(object);
if (object instanceof VirtualFile) {
myAlreadyAddedFiles.add((VirtualFile)object);
}
filesCounter++;
if (filesCounter > MAX_FILES) break;
}
}
}
final SearchResult files = getFiles(pattern, MAX_FILES);
check();
@@ -1453,45 +1409,21 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
@Override
public void run() {
if (isCanceled()) return;
myListModel.myTitleIndexes.files = myListModel.size();
myListModel.titleIndex.files = myListModel.size();
for (Object file : files) {
myListModel.addElement(file);
}
myListModel.myMoreIndexes.myMoreFilesIndex = files.size() >= MAX_FILES ? myListModel.size() - 1 : -1;
myListModel.moreIndex.files = files.needMore ? myListModel.size() - 1 : -1;
}
});
}
}
private synchronized void buildSymbols(final String pattern) {
check();
int symbolsCounter = 0;
final Set<Object> elements = new LinkedHashSet<Object>();
final GlobalSearchScope scope = GlobalSearchScope.projectScope(project);
mySymbolsChooseByName.getProvider().filterElements(mySymbolsChooseByName, pattern, false,
myProgressIndicator, new Processor<Object>() {
@Override
public boolean process(Object o) {
if (o instanceof PsiElement) {
final PsiElement element = (PsiElement)o;
final PsiFile file = element.getContainingFile();
if (file != null && file.getVirtualFile() != null && scope.accept(file.getVirtualFile())) {
elements.add(o);
}
}
return elements.size() < 30;
}
});
final List<Object> symbols = new ArrayList<Object>();
for (Object object : elements) {
if (symbolsCounter > MAX_SYMBOLS) break;
if (!myListModel.contains(object)) {
symbols.add(object);
symbolsCounter++;
if (symbolsCounter > MAX_SYMBOLS) break;
}
}
private synchronized void buildSymbols(final String pattern) {
final SearchResult symbols = getSymbols(pattern, MAX_SYMBOLS);
check();
if (symbols.size() > 0) {
@@ -1499,11 +1431,11 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
@Override
public void run() {
if (isCanceled()) return;
myListModel.myTitleIndexes.symbols = myListModel.size();
myListModel.titleIndex.symbols = myListModel.size();
for (Object file : symbols) {
myListModel.addElement(file);
}
myListModel.myMoreIndexes.myMoreSymbolsIndex = symbols.size() >= MAX_SYMBOLS ? myListModel.size() - 1 : -1;
myListModel.moreIndex.symbols = symbols.needMore ? myListModel.size() - 1 : -1;
}
});
}
@@ -1528,7 +1460,25 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
private synchronized void buildRunConfigurations(String pattern) {
final List<Object> runConfigurations = new ArrayList<Object>();
final SearchResult runConfigurations = getConfigurations(pattern, MAX_RUN_CONFIGURATION);
if (runConfigurations.size() > 0) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (isCanceled()) return;
myListModel.titleIndex.runConfigurations = myListModel.size();
for (Object runConfiguration : runConfigurations) {
myListModel.addElement(runConfiguration);
}
myListModel.moreIndex.runConfigurations = runConfigurations.needMore ? myListModel.getSize() - 1 : -1;
}
});
}
}
private SearchResult getConfigurations(String pattern, int max) {
SearchResult configurations = new SearchResult();
MinusculeMatcher matcher = new MinusculeMatcher(pattern, NameUtil.MatchingCaseSensitivity.NONE);
final ChooseRunConfigurationPopup.ItemWrapper[] wrappers =
ChooseRunConfigurationPopup.createSettingsList(project, new ExecutorProvider() {
@@ -1539,27 +1489,20 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}, false);
check();
for (ChooseRunConfigurationPopup.ItemWrapper wrapper : wrappers) {
if (matcher.matches(wrapper.getText())) {
runConfigurations.add(wrapper);
if (matcher.matches(wrapper.getText()) && !myListModel.contains(wrapper)) {
if (configurations.size() == max) {
configurations.needMore = true;
break;
}
configurations.add(wrapper);
}
check();
}
if (runConfigurations.size() > 0) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (isCanceled()) return;
myListModel.myTitleIndexes.runConfigurations = myListModel.size();
for (Object runConfiguration : runConfigurations) {
myListModel.addElement(runConfiguration);
}
}
});
}
return configurations;
}
private synchronized void buildClasses(final String pattern) {
if (pattern.indexOf('.') != -1) {
//todo[kb] it's not a mistake. If we search for "*.png" or "index.xml" in SearchEverywhere
@@ -1568,7 +1511,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
check();
final List<Object> classes = getClasses(pattern, showAll.get(), MAX_CLASSES);
final SearchResult classes = getClasses(pattern, showAll.get(), MAX_CLASSES);
check();
@@ -1577,47 +1520,97 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
@Override
public void run() {
if (isCanceled()) return;
myListModel.myTitleIndexes.classes = myListModel.size();
myListModel.titleIndex.classes = myListModel.size();
for (Object file : classes) {
myListModel.addElement(file);
}
myListModel.myMoreIndexes.myMoreClassesIndex = classes.size() >= MAX_CLASSES ? myListModel.size() - 1 : -1;
myListModel.moreIndex.classes = -1;
if (classes.needMore) {
myListModel.moreIndex.classes = myListModel.size() - 1;
}
}
});
}
}
private List<Object> getClasses(String pattern, boolean includeLibs, final int max) {
int counter = 0;
final Set<Object> elements = new LinkedHashSet<Object>();
private SearchResult getSymbols(String pattern, final int max) {
final SearchResult symbols = new SearchResult();
final GlobalSearchScope scope = GlobalSearchScope.projectScope(project);
mySymbolsChooseByName.getProvider().filterElements(mySymbolsChooseByName, pattern, false,
myProgressIndicator, new Processor<Object>() {
@Override
public boolean process(Object o) {
if (o instanceof PsiElement) {
final PsiElement element = (PsiElement)o;
final PsiFile file = element.getContainingFile();
if (!myListModel.contains(o) &&
//some elements are non-physical like DB columns
(file == null || (file.getVirtualFile() != null && scope.accept(file.getVirtualFile())))) {
symbols.add(o);
}
}
symbols.needMore = symbols.size() == max;
return !symbols.needMore;
}
});
return symbols;
}
private SearchResult getClasses(String pattern, boolean includeLibs, final int max) {
final SearchResult classes = new SearchResult();
myClassChooseByName.getProvider().filterElements(myClassChooseByName, pattern, includeLibs,
myProgressIndicator, new Processor<Object>() {
@Override
public boolean process(Object o) {
if (o instanceof PsiElement && !myListModel.contains(o)) {
elements.add(o);
if (o instanceof PsiElement && !myListModel.contains(o) && !classes.contains(o)) {
if (classes.size() == max) {
classes.needMore = true;
return false;
}
classes.add(o);
}
return elements.size() < max;
return true;
}
});
final List<Object> classes = new ArrayList<Object>();
for (Object object : elements) {
check();
if (counter > max) break;
if (!myListModel.contains(object)) {
if (object instanceof PsiElement) {
classes.add(object);
}
counter++;
if (counter > max) break;
}
}
if (!includeLibs && classes.isEmpty()) {
return getClasses(pattern, true, max);
}
return classes;
}
private SearchResult getFiles(final String pattern, final int max) {
final SearchResult files = new SearchResult();
final GlobalSearchScope scope = GlobalSearchScope.projectScope(project);
myFileChooseByName.getProvider().filterElements(myFileChooseByName, pattern, true,
myProgressIndicator, new Processor<Object>() {
@Override
public boolean process(Object o) {
VirtualFile file = null;
if (o instanceof VirtualFile) {
file = (VirtualFile)o;
} else if (o instanceof PsiFile) {
file = ((PsiFile)o).getVirtualFile();
} else if (o instanceof PsiDirectory) {
file = ((PsiDirectory)o).getVirtualFile();
}
if (file != null
&& !(pattern.indexOf(' ') != -1 && file.getName().indexOf(' ') == -1)
&& (showAll.get() || scope.accept(file)
&& !myListModel.contains(file)
&& !myAlreadyAddedFiles.contains(file))
&& !files.contains(file)) {
if (files.size() == max) {
files.needMore = true;
return false;
}
files.add(file);
}
return true;
}
});
return files;
}
private synchronized void buildRecentFiles(String pattern) {
final MinusculeMatcher matcher = new MinusculeMatcher("*" + pattern, NameUtil.MatchingCaseSensitivity.NONE);
final ArrayList<VirtualFile> files = new ArrayList<VirtualFile>();
@@ -1638,7 +1631,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
@Override
public void run() {
if (isCanceled()) return;
myListModel.myTitleIndexes.recentFiles = myListModel.size();
myListModel.titleIndex.recentFiles = myListModel.size();
for (Object file : files) {
myListModel.addElement(file);
}
@@ -1764,7 +1757,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
}
if (isCanceled() || elements.isEmpty()) return;
myListModel.myTitleIndexes.topHit = myListModel.size();
myListModel.titleIndex.topHit = myListModel.size();
for (Object element : elements) {
myListModel.addElement(element);
}
@@ -1933,32 +1926,48 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
return myDone;
}
public ActionCallback insertClasses(final int index) {
public ActionCallback insert(final int index, final WidgetID id) {
ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
public void run() {
runReadAction(new Runnable() {
@Override
public void run() {
try {
final List<Object> classes = getClasses(pattern, showAll.get(), DEFAULT_MORE_STEP_COUNT);
System.out.println(classes.size());
final SearchResult result
= id == WidgetID.CLASSES ? getClasses(pattern, showAll.get(), DEFAULT_MORE_STEP_COUNT)
: id == WidgetID.FILES ? getFiles(pattern, DEFAULT_MORE_STEP_COUNT)
: id == WidgetID.RUN_CONFIGURATIONS ? getConfigurations(pattern, DEFAULT_MORE_STEP_COUNT)
: id == WidgetID.SYMBOLS ? getSymbols(pattern, DEFAULT_MORE_STEP_COUNT)
: id == WidgetID.ACTIONS ? getActionsOrSettings(pattern, DEFAULT_MORE_STEP_COUNT, true)
: id == WidgetID.SETTINGS ? getActionsOrSettings(pattern, DEFAULT_MORE_STEP_COUNT, false)
: new SearchResult();
check();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
try {
int shift = 0;
int i = index;
for (Object aClass : classes) {
int i = index+1;
for (Object o : result) {
//noinspection unchecked
myListModel.insertElementAt(aClass, i);
myListModel.insertElementAt(o, i);
shift++;
i++;
}
myListModel.myTitleIndexes.shift(index, shift);
myListModel.myMoreIndexes.shift(index, shift);
if (classes.size() < DEFAULT_MORE_STEP_COUNT) {
myListModel.myMoreIndexes.myMoreClassesIndex = -1;
MoreIndex moreIndex = myListModel.moreIndex;
myListModel.titleIndex.shift(index, shift);
moreIndex.shift(index, shift);
if (!result.needMore) {
switch (id) {
case CLASSES: moreIndex.classes = -1; break;
case FILES: moreIndex.files = -1; break;
case ACTIONS: moreIndex.actions = -1; break;
case SETTINGS: moreIndex.settings = -1; break;
case SYMBOLS: moreIndex.symbols = -1; break;
case RUN_CONFIGURATIONS: moreIndex.runConfigurations = -1; break;
}
}
ListScrollingUtil.selectItem(myList, index);
myDone.setDone();
@@ -2128,23 +2137,25 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
}
static class MoreIndexes {
volatile int myMoreClassesIndex = -1;
volatile int myMoreFilesIndex = -1;
volatile int myMoreActionsIndex = -1;
volatile int myMoreSettingsIndex = -1;
volatile int myMoreSymbolsIndex = -1;
static class MoreIndex {
volatile int classes = -1;
volatile int files = -1;
volatile int actions = -1;
volatile int settings = -1;
volatile int symbols = -1;
volatile int runConfigurations = -1;
public void shift(int index, int shift) {
if (myMoreClassesIndex >= index) myMoreClassesIndex += shift;
if (myMoreFilesIndex >= index) myMoreFilesIndex += shift;
if (myMoreActionsIndex >= index) myMoreActionsIndex += shift;
if (myMoreSettingsIndex >= index) myMoreSettingsIndex += shift;
if (myMoreSymbolsIndex >= index) myMoreSymbolsIndex += shift;
if (runConfigurations >= index) runConfigurations += shift;
if (classes >= index) classes += shift;
if (files >= index) files += shift;
if (actions >= index) actions += shift;
if (settings >= index) settings += shift;
if (symbols >= index) symbols += shift;
}
}
static class TitleIndexes {
static class TitleIndex {
volatile int topHit = -1;
volatile int recentFiles = -1;
volatile int runConfigurations = -1;
@@ -2164,7 +2175,7 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
final String gotoSymbolTitle;
static final String toolWindowsTitle = "Tool Windows";
TitleIndexes() {
TitleIndex() {
String gotoClass = KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction("GotoClass"));
gotoClassTitle = StringUtil.isEmpty(gotoClass) ? "Classes" : "Classes (" + gotoClass + ")";
String gotoFile = KeymapUtil.getFirstKeyboardShortcutText(ActionManager.getInstance().getAction("GotoFile"));
@@ -2197,25 +2208,6 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
return null;
}
int next(int index) {
int[] all = new int[]{topHit, recentFiles, runConfigurations, classes, files, actions, settings, toolWindows, symbols};
Arrays.sort(all);
for (int next : all) {
if (next > index) return next;
}
return 0;
}
int prev(int index) {
int[] all = new int[]{topHit, recentFiles, runConfigurations, classes, files, actions, settings, toolWindows, symbols};
Arrays.sort(all);
for (int i = all.length-1; i >= 0; i--) {
if (all[i] != -1 && all[i] < index) return all[i];
}
return all[all.length - 1];
}
public void clear() {
topHit = -1;
runConfigurations = -1;
@@ -2238,13 +2230,17 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
}
}
static class SearchResult extends ArrayList<Object> {
boolean needMore;
}
@SuppressWarnings("unchecked")
private static class SearchListModel extends DefaultListModel {
@SuppressWarnings("UseOfObsoleteCollectionType")
Vector myDelegate;
volatile TitleIndexes myTitleIndexes = new TitleIndexes();
volatile MoreIndexes myMoreIndexes = new MoreIndexes();
volatile TitleIndex titleIndex = new TitleIndex();
volatile MoreIndex moreIndex = new MoreIndex();
private SearchListModel() {
super();
@@ -2257,6 +2253,44 @@ public class SearchEverywhereAction extends AnAction implements CustomComponentA
catch (IllegalAccessException ignore) {}
}
int next(int index) {
int[] all = getAll();
Arrays.sort(all);
for (int next : all) {
if (next > index) return next;
}
return 0;
}
int[] getAll() {
return new int[]{
titleIndex.topHit,
titleIndex.recentFiles,
titleIndex.runConfigurations,
titleIndex.classes,
titleIndex.files,
titleIndex.actions,
titleIndex.settings,
titleIndex.toolWindows,
titleIndex.symbols,
moreIndex.classes,
moreIndex.actions,
moreIndex.files,
moreIndex.settings,
moreIndex.symbols,
moreIndex.runConfigurations
};
}
int prev(int index) {
int[] all = getAll();
Arrays.sort(all);
for (int i = all.length-1; i >= 0; i--) {
if (all[i] != -1 && all[i] < index) return all[i];
}
return all[all.length - 1];
}
@Override
public void addElement(Object obj) {
myDelegate.add(obj);
@@ -21,6 +21,7 @@ import com.intellij.codeInsight.completion.CompletionResultSet;
import com.intellij.codeInsight.template.impl.TemplateManagerImpl;
import com.intellij.codeInsight.template.impl.TemplateState;
import com.intellij.openapi.editor.Editor;
import org.jetbrains.annotations.NotNull;
/**
* User: anna
@@ -29,7 +30,7 @@ import com.intellij.openapi.editor.Editor;
public class CompletionContributorForInplaceRename extends CompletionContributor {
@Override
public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
final Editor editor = parameters.getEditor();
final TemplateState state = TemplateManagerImpl.getTemplateState(editor);
if (state != null) {
@@ -29,6 +29,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
@@ -57,7 +58,7 @@ public class TextFieldWithAutoCompletionContributor<T> extends CompletionContrib
@Override
public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) {
public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull CompletionResultSet result) {
PsiFile file = parameters.getOriginalFile();
final TextFieldWithAutoCompletionListProvider<T> provider = file.getUserData(KEY);
@@ -7,6 +7,7 @@ import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.DumbService;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiPlainTextFile;
import org.jetbrains.annotations.NotNull;
/**
* @author sergey.evdokimov
@@ -14,7 +15,7 @@ import com.intellij.psi.PsiPlainTextFile;
public class CompletionContributorForTextField extends CompletionContributor implements DumbAware {
@Override
public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
PsiFile file = parameters.getOriginalFile();
if (!(file instanceof PsiPlainTextFile)) return;
@@ -48,6 +48,8 @@ public class FragmentContent extends DiffContent {
public FragmentContent(@NotNull DiffContent original, @NotNull TextRange range, Project project, FileType fileType) {
RangeMarker rangeMarker = original.getDocument().createRangeMarker(range.getStartOffset(), range.getEndOffset(), true);
rangeMarker.setGreedyToLeft(true);
rangeMarker.setGreedyToRight(true);
mySynchonizer = new MyDocumentsSynchronizer(project, rangeMarker);
myOriginal = original;
myType = fileType;
@@ -23,9 +23,10 @@ import com.intellij.openapi.util.TextRange;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
/**
* Created by IntelliJ IDEA.
@@ -34,7 +35,7 @@ import java.util.TreeMap;
* Time: 12:52 PM
*/
public class FragmentedEditorHighlighter implements EditorHighlighter {
private final TreeMap<Integer, Element> myPieces;
private final List<Element> myPieces;
private final Document myDocument;
private final int myAdditionalOffset;
private final boolean myMergeByTextAttributes;
@@ -49,52 +50,70 @@ public class FragmentedEditorHighlighter implements EditorHighlighter {
boolean mergeByTextAttributes) {
myMergeByTextAttributes = mergeByTextAttributes;
myDocument = sourceIterator.getDocument();
myPieces = new TreeMap<Integer, Element>();
myPieces = new ArrayList<Element>();
myAdditionalOffset = additionalOffset;
translate(sourceIterator, ranges);
}
private void translate(HighlighterIterator iterator, List<TextRange> ranges) {
if (iterator.atEnd()) return;
int offset = 0;
for (TextRange range : ranges) {
while (range.getStartOffset() > iterator.getStart()) {
int index = 0;
while (!iterator.atEnd() && index < ranges.size()) {
TextRange range = ranges.get(index);
if (range.getStartOffset() >= iterator.getEnd()) {
iterator.advance();
if (iterator.atEnd()) return;
continue;
}
while (range.getEndOffset() >= iterator.getEnd()) {
int relativeStart = iterator.getStart() - range.getStartOffset();
if (range.getEndOffset() >= iterator.getStart()) {
int relativeStart = Math.max(iterator.getStart() - range.getStartOffset(), 0);
int relativeEnd = Math.min(iterator.getEnd() - range.getStartOffset(), range.getLength());
boolean merged = false;
if (myMergeByTextAttributes && !myPieces.isEmpty()) {
Map.Entry<Integer, Element> entry = myPieces.lastEntry();
final Integer key = entry.getKey();
final Element element = entry.getValue();
Element element = myPieces.get(myPieces.size() - 1);
if (element.getEnd() >= offset + relativeStart &&
element.getAttributes().equals(iterator.getTextAttributes()) &&
element.getElementType().equals(iterator.getTokenType())) {
merged = true;
myPieces.put(key, new Element(key,
offset + (iterator.getEnd() - range.getStartOffset()), iterator.getTokenType(),
iterator.getTextAttributes()));
myPieces.add(new Element(element.getStart(),
offset + relativeEnd,
iterator.getTokenType(),
iterator.getTextAttributes()));
}
}
if (!merged) {
myPieces.put(offset + relativeStart, new Element(offset + relativeStart,
offset + (iterator.getEnd() - range.getStartOffset()), iterator.getTokenType(),
iterator.getTextAttributes()));
myPieces.add(new Element(offset + relativeStart,
offset + relativeEnd,
iterator.getTokenType(),
iterator.getTextAttributes()));
}
iterator.advance();
if (iterator.atEnd()) return;
}
offset += range.getLength() + 1 + myAdditionalOffset; // myAdditionalOffset because of extra line - for shoene separators
if (range.getEndOffset() < iterator.getEnd()) {
offset += range.getLength() + 1 + myAdditionalOffset; // myAdditionalOffset because of extra line - for shoene separators
index++;
continue;
}
iterator.advance();
}
}
@NotNull
@Override
public HighlighterIterator createIterator(int startOffset) {
Map.Entry<Integer, Element> entry = myPieces.ceilingEntry(startOffset);
return new ProxyIterator(myDocument, entry == null ? -1 : entry.getKey());
int offset = Collections.binarySearch(myPieces, new Element(startOffset, 0, null, null), new Comparator<Element>() {
@Override
public int compare(Element o1, Element o2) {
return o1.getStart() - o2.getStart();
}
});
// offset: (-insertion point - 1), where insertionPoint is the index of the first element greater than the key
// and we need offset of the first element that is less or equal (floorElement)
if (offset < 0) offset = Math.max(-offset - 2, 0);
return new ProxyIterator(myDocument, offset);
}
@Override
@@ -148,27 +167,21 @@ public class FragmentedEditorHighlighter implements EditorHighlighter {
@Override
public void advance() {
if (myIdx == myPieces.lastKey() || myIdx == -1) {
myIdx = -1;
return;
if (myIdx < myPieces.size()) {
myIdx++;
}
Map.Entry<Integer, Element> entry = myPieces.tailMap(myIdx, false).firstEntry();
myIdx = entry.getKey();
}
@Override
public void retreat() {
if (myIdx == myPieces.firstKey() || myIdx == -1) {
myIdx = -1;
return;
if (myIdx > -1) {
myIdx--;
}
Map.Entry<Integer, Element> entry = myPieces.headMap(myIdx, false).lastEntry();
myIdx = entry.getKey();
}
@Override
public boolean atEnd() {
return myIdx < 0;
return myIdx < 0 || myIdx >= myPieces.size();
}
@Override
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -21,6 +21,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.ProjectManager;
import com.intellij.openapi.util.Key;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
@@ -31,10 +32,11 @@ import javax.swing.*;
public abstract class EditorNotifications extends AbstractProjectComponent {
public abstract static class Provider<T extends JComponent> {
@NotNull
public abstract Key<T> getKey();
@Nullable
public abstract T createNotificationPanel(VirtualFile file, FileEditor fileEditor);
public abstract T createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor);
}
public static EditorNotifications getInstance(Project project) {
@@ -45,7 +47,7 @@ public abstract class EditorNotifications extends AbstractProjectComponent {
super(project);
}
public abstract void updateNotifications(final VirtualFile file);
public abstract void updateNotifications(@NotNull VirtualFile file);
public abstract void updateAllNotifications();
@@ -79,6 +79,7 @@ public class FileChangedNotificationProvider extends EditorNotifications.Provide
});
}
@NotNull
@Override
public Key<EditorNotificationPanel> getKey() {
return KEY;
@@ -20,70 +20,38 @@ import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.LightVirtualFile;
import org.jetbrains.annotations.NotNull;
import java.awt.datatransfer.StringSelection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
public class CopyPathsAction extends AnAction implements DumbAware {
public CopyPathsAction() {
setEnabledInModalContext(true);
}
@Override
public void actionPerformed(AnActionEvent e) {
final Collection<VirtualFile> files = getFiles(e);
if (files.isEmpty()) {
return;
VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(e.getDataContext());
if (files != null && files.length > 0) {
CopyPasteManager.getInstance().setContents(new StringSelection(getPaths(files)));
}
CopyPasteManager.getInstance().setContents(new StringSelection(getPaths(files)));
}
private static String getPaths(Collection<VirtualFile> files) {
final StringBuilder buf = new StringBuilder(files.size() * 64);
boolean first = true;
private static String getPaths(VirtualFile[] files) {
StringBuilder buf = new StringBuilder(files.length * 64);
for (VirtualFile file : files) {
if (first) {
first = false;
}
else {
buf.append("\n");
}
if (buf.length() > 0) buf.append('\n');
buf.append(file.getPresentableUrl());
}
return buf.toString();
}
@Override
public void update(AnActionEvent event) {
final Collection<VirtualFile> files = getFiles(event);
final Presentation presentation = event.getPresentation();
final boolean enabled = !files.isEmpty();
presentation.setEnabled(enabled);
if (ActionPlaces.isPopupPlace(event.getPlace())) {
presentation.setVisible(enabled);
}
else {
presentation.setVisible(true);
}
presentation.setText((files.size() == 1)
? IdeBundle.message("action.copy.path")
: IdeBundle.message("action.copy.paths"));
VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(event.getDataContext());
int num = files != null ? files.length : 0;
Presentation presentation = event.getPresentation();
presentation.setEnabled(num > 0);
presentation.setVisible(num > 0 || !ActionPlaces.isPopupPlace(event.getPlace()));
presentation.setText(IdeBundle.message(num == 1 ? "action.copy.path" : "action.copy.paths"));
}
@NotNull
private static Collection<VirtualFile> getFiles(AnActionEvent e) {
final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(e.getDataContext());
if (files == null || files.length == 0) return Collections.emptyList();
final ArrayList<VirtualFile> result = new ArrayList<VirtualFile>(files.length);
for (VirtualFile file : files) {
if (!(file instanceof LightVirtualFile)) {
result.add(file);
}
}
return result;
}
}
@@ -47,10 +47,11 @@ class RepositoryContentHandler extends DefaultHandler {
@NonNls public static final String CHNAGE_NOTES = "change-notes";
@NonNls private static final String DEPENDS = "depends";
@NonNls private static final String DOWNLOADS = "downloads";
@NonNls public static final String DOWNLOAD_URL = "downloadUrl";
@NonNls private static final String DOWNLOAD_URL = "downloadUrl";
@NonNls private static final String DOWNLOAD_URL_NEW_STYLE = "download-url";
@NonNls private static final String SIZE = "size";
@NonNls private static final String RATING = "rating";
@NonNls private static final String RATING = "rating";
@NonNls private static final String DATE = "date";
private PluginNode currentPlugin;
private final StringBuilder currentValue = new StringBuilder();
@@ -120,7 +121,7 @@ class RepositoryContentHandler extends DefaultHandler {
else if (qName.equals(RATING)) {
currentPlugin.setRating(currentValueString);
}
else if (qName.equals(DOWNLOAD_URL)) {
else if (qName.equals(DOWNLOAD_URL) || qName.equals(DOWNLOAD_URL_NEW_STYLE)) {
currentPlugin.setDownloadUrl(currentValueString);
}
}
@@ -41,7 +41,7 @@ public class DeleteLineAction extends TextComponentEditorAction {
}
@Override
public void executeWriteAction(Editor editor, DataContext dataContext) {
public void executeWriteAction(Editor editor, Caret caret, DataContext dataContext) {
CommandProcessor.getInstance().setCurrentCommandGroupId(EditorActionUtil.DELETE_COMMAND_GROUP);
CopyPasteManager.getInstance().stopKillRings();
SelectionModel selectionModel = editor.getSelectionModel();
@@ -76,7 +76,7 @@ public class DeleteLineAction extends TextComponentEditorAction {
selectionModel.selectLineAtCaret();
boolean removeLastSymbol = selectionModel.getSelectionEnd() == document.getTextLength() && document.getLineCount() > 1;
EditorModificationUtil.deleteSelectedText(editor);
if (removeLastSymbol) {
if (removeLastSymbol && document.getTextLength() > 0) {
document.deleteString(document.getTextLength() - 1, document.getTextLength());
position = new VisualPosition(position.line - 1, position.column);
}
@@ -2075,7 +2075,9 @@ public final class EditorImpl extends UserDataHolderBase implements EditorEx, Hi
}
private void paintComposedTextDecoration(@NotNull Graphics2D g) {
if (myInputMethodRequestsHandler != null && myInputMethodRequestsHandler.composedText != null) {
if (myInputMethodRequestsHandler != null
&& myInputMethodRequestsHandler.composedText != null
&& myInputMethodRequestsHandler.composedTextRange != null) {
VisualPosition visStart =
offsetToVisualPosition(Math.min(myInputMethodRequestsHandler.composedTextRange.getStartOffset(), myDocument.getTextLength()));
int y = visibleLineToY(visStart.line) + getAscent() + 1;
@@ -18,11 +18,8 @@ package com.intellij.openapi.updateSettings.impl;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.plugins.*;
import com.intellij.ide.startup.StartupActionScriptManager;
import com.intellij.ide.util.PropertiesComponent;
import com.intellij.openapi.application.ApplicationInfo;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.PluginId;
import com.intellij.openapi.progress.ProgressIndicator;
@@ -47,9 +44,7 @@ import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.List;
import java.util.UUID;
/**
* @author anna
@@ -98,6 +93,10 @@ public class PluginDownloader {
}
public boolean prepareToInstall(@Nullable ProgressIndicator pi, @Nullable BuildNumber forBuildNumber) throws IOException {
if (myFile != null) {
return true;
}
IdeaPluginDescriptor descriptor = null;
if (!Boolean.getBoolean(StartupActionScriptManager.STARTUP_WIZARD_MODE) && PluginManager.isPluginInstalled(PluginId.getId(myPluginId))) {
//store old plugins file
@@ -386,22 +385,9 @@ public class PluginDownloader {
}
public static PluginDownloader createDownloader(IdeaPluginDescriptor descriptor) throws UnsupportedEncodingException {
String url = null;
if (descriptor instanceof PluginNode) {
url = ((PluginNode)descriptor).getDownloadUrl();
}
if (url == null) {
String uuid = ApplicationManager.getApplication() == null ?
UUID.randomUUID().toString() :
UpdateChecker.getInstallationUID(PropertiesComponent.getInstance());
String buildNumber = ApplicationManager.getApplication() != null
? ApplicationInfo.getInstance().getApiVersion()
: ApplicationInfoImpl.getShadowInstance().getBuild().asString();
url = RepositoryHelper.getDownloadUrl() + URLEncoder.encode(descriptor.getPluginId().getIdString(), "UTF8") +
"&build=" + buildNumber + "&uuid=" + URLEncoder.encode(uuid, "UTF8");
}
PluginDownloader downloader = new PluginDownloader(descriptor.getPluginId().getIdString(), url, descriptor.getVersion(), null, descriptor.getName());
PluginDownloader downloader = new PluginDownloader(descriptor.getPluginId().getIdString(),
UpdateChecker.getDownloadUrl(descriptor),
descriptor.getVersion(), null, descriptor.getName());
downloader.setDescriptor(descriptor);
return downloader;
}
@@ -16,9 +16,13 @@
package com.intellij.openapi.updateSettings.impl;
import com.intellij.ide.IdeBundle;
import com.intellij.ide.plugins.PluginManagerConfigurable;
import com.intellij.openapi.ui.Messages;
import com.intellij.ide.plugins.PluginManagerMain;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.util.Ref;
import com.intellij.ui.TableUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -61,20 +65,46 @@ class PluginUpdateInfoDialog extends AbstractUpdateDialog {
@Override
protected void doOKAction() {
if (downloadPlugins() && toRestart()) {
restart();
}
super.doOKAction();
final Ref<Boolean> result = new Ref<Boolean>();
final Runnable runnable = new Runnable() {
public void run() {
UpdateChecker.saveDisabledToUpdatePlugins();
result.set(UpdateChecker.install(myUploadedPlugins));
}
};
final String progressTitle = "Download plugins...";
if (downloadModal()) {
ProgressManager.getInstance().runProcessWithProgressSynchronously(runnable, progressTitle, true, null);
} else {
ProgressManager.getInstance().run(new Task.Backgroundable(null, progressTitle, true) {
@Override
public void run(@NotNull ProgressIndicator indicator) {
runnable.run();
}
@Override
public void onSuccess() {
final Boolean installed = result.get();
if (installed != null && installed.booleanValue()) {
final String pluginName;
if (myUploadedPlugins.size() == 1) {
final PluginDownloader firstItem = ContainerUtil.getFirstItem(myUploadedPlugins);
pluginName = firstItem != null ? firstItem.getPluginName() : null;
}
else {
pluginName = null;
}
PluginManagerMain.notifyPluginsWereInstalled(pluginName, null);
}
}
});
}
}
protected boolean toRestart() {
return PluginManagerConfigurable.showRestartIDEADialog() == Messages.YES;
}
private boolean downloadPlugins() {
UpdateChecker.saveDisabledToUpdatePlugins();
return UpdateChecker.install(myUploadedPlugins);
protected boolean downloadModal() {
return false;
}
private class PluginUpdateInfoPanel {
@@ -26,6 +26,7 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ApplicationNamesInfo;
import com.intellij.openapi.application.PathManager;
import com.intellij.openapi.application.ex.ApplicationInfoEx;
import com.intellij.openapi.application.impl.ApplicationInfoImpl;
import com.intellij.openapi.diagnostic.IdeaLoggingEvent;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.extensions.PluginId;
@@ -74,7 +75,7 @@ import java.util.concurrent.TimeoutException;
public final class UpdateChecker {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.updateSettings.impl.UpdateChecker");
private static final Map<String, String> ourUpdatedPlugins = new HashMap<String, String>();
private static final Map<String, PluginDownloader> ourUpdatedPlugins = new HashMap<String, PluginDownloader>();
public enum DownloadPatchResult {
SUCCESS, FAILED, CANCELED
@@ -242,25 +243,12 @@ public final class UpdateChecker {
if (!toUpdate.isEmpty()) {
try {
final List<IdeaPluginDescriptor> process = RepositoryHelper.loadPluginsFromRepository(indicator);
final List<String> disabledPlugins = PluginManagerCore.getDisabledPlugins();
for (IdeaPluginDescriptor loadedPlugin : process) {
final PluginId pluginId = loadedPlugin.getPluginId();
final String idString = pluginId.getIdString();
if (!toUpdate.containsKey(idString)) continue;
final IdeaPluginDescriptor installedPlugin = toUpdate.get(idString);
if (installedPlugin == null) {
prepareToInstall(downloaded, loadedPlugin, indicator, buildNumber);
} else {
final String newVersion = loadedPlugin.getVersion();
if (PluginDownloader.compareVersionsSkipBroken(installedPlugin, newVersion) > 0) {
updateSettings.myOutdatedPlugins.add(idString);
if (isReadyToUpdate(idString, newVersion) && !disabledPlugins.contains(idString)) {
prepareToInstall(downloaded, loadedPlugin, indicator, buildNumber);
}
}
if (!downloaded.containsKey(pluginId)) {
collectIncompatible(incompatiblePlugins, buildNumber, installedPlugin);
}
if (!downloaded.containsKey(pluginId)) {
prepareToInstall(buildNumber, downloaded, incompatiblePlugins, PluginDownloader.createDownloader(loadedPlugin), indicator);
}
}
}
@@ -280,28 +268,52 @@ public final class UpdateChecker {
}
private static boolean isReadyToUpdate(String idString, String newVersion) {
return true;
final PluginDownloader oldPlugin = ourUpdatedPlugins.get(idString);
return oldPlugin == null || StringUtil.compareVersionNumbers(newVersion, oldPlugin.getPluginVersion()) > 0;
}
private static void prepareToInstall(Map<PluginId, PluginDownloader> downloaded,
IdeaPluginDescriptor loadedPlugin,
@Nullable ProgressIndicator indicator,
@Nullable BuildNumber buildNumber) throws IOException {
final PluginId pluginId = loadedPlugin.getPluginId();
//prefer plugins from plugin hosts
if (!downloaded.containsKey(pluginId)) {
final PluginDownloader downloader = PluginDownloader.createDownloader(loadedPlugin);
if (downloader.prepareToInstall(indicator, buildNumber)) {
downloaded.put(pluginId, downloader);
private static void prepareToInstall(BuildNumber buildNumber,
Map<PluginId, PluginDownloader> downloaded,
Collection<IdeaPluginDescriptor> incompatiblePlugins,
PluginDownloader downloader,
ProgressIndicator indicator) throws IOException {
final String pluginId = downloader.getPluginId();
final String pluginVersion = downloader.getPluginVersion();
final List<String> disabledPlugins = PluginManagerCore.getDisabledPlugins();
if (disabledPlugins.contains(pluginId)) return;
final IdeaPluginDescriptor installedPlugin = PluginManager.getPlugin(PluginId.getId(pluginId));
if (installedPlugin == null || pluginVersion == null ||
PluginDownloader.compareVersionsSkipBroken(installedPlugin, pluginVersion) > 0) {
IdeaPluginDescriptor descriptor = null;
if (isReadyToUpdate(pluginId, pluginVersion)) {
descriptor = downloader.getDescriptor();
if (descriptor == null) {
if (downloader.prepareToInstall(indicator, buildNumber)) {
descriptor = downloader.getDescriptor();
}
ourUpdatedPlugins.put(pluginId, downloader);
}
} else {
final PluginDownloader oldDownloader = ourUpdatedPlugins.get(pluginId);
if (oldDownloader != null) {
downloader = oldDownloader;
descriptor = oldDownloader.getDescriptor();
}
}
if (descriptor != null &&
!PluginManagerCore.isIncompatible(descriptor, buildNumber) &&
!InstalledPluginsTableModel.wasUpdated(descriptor.getPluginId())) {
downloaded.put(PluginId.getId(pluginId), downloader);
}
}
}
private static void collectIncompatible(Collection<IdeaPluginDescriptor> incompatiblePlugins,
BuildNumber buildNumber,
IdeaPluginDescriptor descriptor) {
if (incompatiblePlugins != null && descriptor != null && descriptor.isEnabled() && PluginManagerCore.isIncompatible(descriptor, buildNumber)) {
incompatiblePlugins.add(descriptor);
//collect plugins which were not updated and would be incompatible with new version
if (incompatiblePlugins != null &&
installedPlugin != null && installedPlugin.isEnabled() && !downloaded.containsKey(installedPlugin.getPluginId()) &&
PluginManagerCore.isIncompatible(installedPlugin, buildNumber)) {
incompatiblePlugins.add(installedPlugin);
}
}
@@ -354,7 +366,7 @@ public final class UpdateChecker {
final Map<PluginId, PluginDownloader> downloaded,
final @Nullable Collection<IdeaPluginDescriptor> incompatiblePlugins,
final boolean collectToUpdate,
@Nullable ProgressIndicator indicator,
final @Nullable ProgressIndicator indicator,
final BuildNumber buildNumber) throws Exception {
InputStream inputStream = loadVersionInfo(host);
if (inputStream == null) return false;
@@ -371,6 +383,7 @@ public final class UpdateChecker {
final List<IdeaPluginDescriptor> descriptors = RepositoryHelper.loadPluginsFromDescription(inputStream, indicator);
for (IdeaPluginDescriptor descriptor : descriptors) {
((PluginNode)descriptor).setRepositoryName(host);
prepareToInstall(buildNumber, downloaded, incompatiblePlugins, PluginDownloader.createDownloader(descriptor), indicator);
downloaded.put(descriptor.getPluginId(), PluginDownloader.createDownloader(descriptor));
}
@@ -418,17 +431,8 @@ public final class UpdateChecker {
if (progressIndicator != null) {
progressIndicator.setText2(finalPluginUrl);
}
final PluginDownloader downloader = new PluginDownloader(pluginId, finalPluginUrl, pluginVersion);
final IdeaPluginDescriptor loadedPlugin = PluginManager.getPlugin(PluginId.getId(pluginId));
if (loadedPlugin == null || pluginVersion == null ||
PluginDownloader.compareVersionsSkipBroken(loadedPlugin, pluginVersion) > 0) {
if (isReadyToUpdate(pluginId, pluginVersion) && downloader.prepareToInstall(progressIndicator, buildNumber)) {
downloaded.put(PluginId.getId(pluginId), downloader);
}
}
if (loadedPlugin != null && !downloaded.containsKey(loadedPlugin.getPluginId())) {
collectIncompatible(incompatiblePlugins, buildNumber, loadedPlugin);
}
final PluginDownloader downloader = new PluginDownloader(pluginId, finalPluginUrl, pluginVersion, null, null);
prepareToInstall(buildNumber, downloaded, incompatiblePlugins, downloader, indicator);
}
catch (IOException e) {
LOG.info(e);
@@ -708,17 +712,19 @@ public final class UpdateChecker {
boolean installed = false;
for (PluginDownloader downloader : downloaders) {
if (getDisabledToUpdatePlugins().contains(downloader.getPluginId())) continue;
final IdeaPluginDescriptor descriptor = downloader.getDescriptor();
if (descriptor != null) {
try {
InstalledPluginsTableModel.updateExistingPlugin(descriptor, PluginManager.getPlugin(descriptor.getPluginId()));
downloader.install();
installed = true;
}
catch (IOException e) {
LOG.info(e);
try {
if (downloader.prepareToInstall(ProgressManager.getInstance().getProgressIndicator())) {
final IdeaPluginDescriptor descriptor = downloader.getDescriptor();
if (descriptor != null) {
InstalledPluginsTableModel.updateExistingPlugin(descriptor, PluginManager.getPlugin(descriptor.getPluginId()));
downloader.install();
installed = true;
}
}
}
catch (IOException e) {
LOG.info(e);
}
}
return installed;
}
@@ -853,4 +859,23 @@ public final class UpdateChecker {
}
}
}
static String getDownloadUrl(IdeaPluginDescriptor descriptor) throws UnsupportedEncodingException {
String url = null;
if (descriptor instanceof PluginNode) {
url = ((PluginNode)descriptor).getDownloadUrl();
}
if (url == null) {
String uuid = ApplicationManager.getApplication() == null ?
UUID.randomUUID().toString() :
getInstallationUID(PropertiesComponent.getInstance());
String buildNumber = ApplicationManager.getApplication() != null
? ApplicationInfo.getInstance().getApiVersion()
: ApplicationInfoImpl.getShadowInstance().getBuild().asString();
url = RepositoryHelper.getDownloadUrl() + URLEncoder.encode(descriptor.getPluginId().getIdString(), "UTF8") +
"&build=" + buildNumber + "&uuid=" + URLEncoder.encode(uuid, "UTF8");
}
return url;
}
}
@@ -144,7 +144,7 @@ class UpdateInfoDialog extends AbstractUpdateDialog {
if (myUpdatedPlugins != null && !myUpdatedPlugins.isEmpty()) {
new PluginUpdateInfoDialog(getContentPanel(), myUpdatedPlugins, true){
@Override
protected boolean toRestart() {
protected boolean downloadModal() {
return true;
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -52,6 +52,7 @@ public class PluginAdvertiserEditorNotificationProvider extends EditorNotificati
myNotifications = notifications;
}
@NotNull
@Override
public Key<EditorNotificationPanel> getKey() {
return KEY;
@@ -59,7 +60,7 @@ public class PluginAdvertiserEditorNotificationProvider extends EditorNotificati
@Nullable
@Override
public EditorNotificationPanel createNotificationPanel(VirtualFile file, FileEditor fileEditor) {
public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor) {
if (file.getFileType() != PlainTextFileType.INSTANCE) return null;
final String extension = file.getExtension();
@@ -1,5 +1,6 @@
package com.intellij.remote;
import com.intellij.util.PathMappingSettings;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -97,6 +98,17 @@ public class RemoteSdkCredentialsHolder extends RemoteCredentialsHolder implemen
myRemoteSdkProperties.setRemoteRoots(remoteRoots);
}
@NotNull
@Override
public PathMappingSettings getPathMappings() {
return myRemoteSdkProperties.getPathMappings();
}
@Override
public void setPathMappings(@Nullable PathMappingSettings pathMappings) {
myRemoteSdkProperties.setPathMappings(pathMappings);
}
@Override
public boolean isHelpersVersionChecked() {
return myRemoteSdkProperties.isHelpersVersionChecked();
@@ -15,6 +15,10 @@
*/
package com.intellij.remote;
import com.intellij.util.PathMappingSettings;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
@@ -31,14 +35,47 @@ public interface RemoteSdkProperties {
String getDefaultHelpersName();
/**
* Use getPathMappings() instead
* To be removed in IDEA 15
*
* @deprecated
*/
@Deprecated
void addRemoteRoot(String remoteRoot);
/**
* Use getPathMappings() instead
* To be removed in IDEA 15
*
* @deprecated
*/
@Deprecated
void clearRemoteRoots();
/**
* Use getPathMappings() instead
* To be removed in IDEA 15
*
* @deprecated
*/
@Deprecated
List<String> getRemoteRoots();
/**
* Use setPathMappings() instead
* To be removed in IDEA 15
*
* @deprecated
*/
@Deprecated
void setRemoteRoots(List<String> remoteRoots);
@NotNull
PathMappingSettings getPathMappings();
void setPathMappings(@Nullable PathMappingSettings pathMappings);
boolean isHelpersVersionChecked();
void setHelpersVersionChecked(boolean helpersVersionChecked);
@@ -19,12 +19,13 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.intellij.openapi.util.JDOMExternalizer;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.PathMappingSettings;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
/**
* @author traff
@@ -35,6 +36,7 @@ public class RemoteSdkPropertiesHolder implements RemoteSdkProperties {
private static final String REMOTE_ROOTS = "REMOTE_ROOTS";
private static final String REMOTE_PATH = "REMOTE_PATH";
private static final String INITIALIZED = "INITIALIZED";
private static final String PATH_MAPPINGS = "PATH_MAPPINGS";
private String mySdkId;
@@ -49,6 +51,9 @@ public class RemoteSdkPropertiesHolder implements RemoteSdkProperties {
private boolean myInitialized = false;
@NotNull
private PathMappingSettings myPathMappings = new PathMappingSettings();
public RemoteSdkPropertiesHolder(String name) {
myHelpersDefaultDirName = name;
}
@@ -97,6 +102,20 @@ public class RemoteSdkPropertiesHolder implements RemoteSdkProperties {
myRemoteRoots = Sets.newTreeSet(remoteRoots);
}
@NotNull
@Override
public PathMappingSettings getPathMappings() {
return myPathMappings;
}
@Override
public void setPathMappings(@Nullable PathMappingSettings pathMappings) {
myPathMappings = new PathMappingSettings();
if (pathMappings != null) {
myPathMappings.addAll(pathMappings);
}
}
@Override
public boolean isHelpersVersionChecked() {
return myHelpersVersionChecked;
@@ -123,7 +142,6 @@ public class RemoteSdkPropertiesHolder implements RemoteSdkProperties {
@Override
public void setInitialized(boolean initialized) {
myInitialized = initialized;
}
public void copyTo(RemoteSdkProperties copy) {
@@ -142,6 +160,8 @@ public class RemoteSdkPropertiesHolder implements RemoteSdkProperties {
rootElement.setAttribute(INITIALIZED, Boolean.toString(isInitialized()));
PathMappingSettings.writeExternal(rootElement, myPathMappings);
for (String remoteRoot : getRemoteRoots()) {
final Element child = new Element(REMOTE_ROOTS);
child.setAttribute(REMOTE_PATH, remoteRoot);
@@ -156,5 +176,7 @@ public class RemoteSdkPropertiesHolder implements RemoteSdkProperties {
setRemoteRoots(JDOMExternalizer.loadStringsList(element, REMOTE_ROOTS, REMOTE_PATH));
setInitialized(StringUtil.parseBoolean(element.getAttributeValue(INITIALIZED), true));
setPathMappings(PathMappingSettings.readExternal(element));
}
}
@@ -90,6 +90,8 @@ public class EditorNotificationsImpl extends EditorNotifications {
myCurrentUpdates.put(file, indicator);
final ReadTask task = createTask(indicator, file);
if (task == null) return;
if (ApplicationManager.getApplication().isUnitTestMode()) {
task.computeInReadAction(indicator);
}
@@ -106,11 +108,25 @@ public class EditorNotificationsImpl extends EditorNotifications {
});
}
@Nullable
private ReadTask createTask(final ProgressIndicator indicator, final VirtualFile file) {
final FileEditor[] editors = FileEditorManager.getInstance(myProject).getAllEditors(file);
if (editors.length == 0) return null;
return new ReadTask() {
private boolean isOutdated() {
return myProject.isDisposed() || !file.isValid() || indicator != myCurrentUpdates.get(file);
if (myProject.isDisposed() || !file.isValid() || indicator != myCurrentUpdates.get(file)) {
return true;
}
for (FileEditor editor : editors) {
if (!editor.isValid()) {
return true;
}
}
return false;
}
@Override
@@ -118,7 +134,7 @@ public class EditorNotificationsImpl extends EditorNotifications {
if (isOutdated()) return;
final List<Runnable> updates = ContainerUtil.newArrayList();
for (final FileEditor editor : FileEditorManager.getInstance(myProject).getAllEditors(file)) {
for (final FileEditor editor : editors) {
for (final Provider<?> provider : Extensions.getExtensions(EXTENSION_POINT_NAME, myProject)) {
final JComponent component = provider.createNotificationPanel(file, editor);
updates.add(new Runnable() {
@@ -20,6 +20,8 @@ import com.intellij.openapi.editor.impl.AbstractEditorTest;
import com.intellij.testFramework.EditorTestUtil;
import com.intellij.testFramework.TestFileType;
import java.io.IOException;
public class EditorActionTest extends AbstractEditorTest {
public void testDownWithSelectionWhenCaretsAreAllowedInsideTabs() throws Exception {
init("<caret>text",
@@ -69,4 +71,35 @@ public class EditorActionTest extends AbstractEditorTest {
executeAction("EditorTab");
checkResultByText("some <caret>text");
}
public void testLineDeleteWithSelectionEndAtLineStart() throws IOException {
String text =
"line 1\n" +
"<selection>line 2\n" +
"</selection>line 3";
init(text, TestFileType.TEXT);
deleteLine();
checkResultByText(
"line 1\n" +
"line 3"
);
}
public void testDeleteLastLine() throws IOException {
String text =
"1\n" +
"2<caret>\n" +
"3";
init(text, TestFileType.TEXT);
deleteLine();
deleteLine();
checkResultByText("1");
}
public void testDeleteLastNonEmptyLine() throws IOException {
init("<caret>1\n", TestFileType.TEXT);
deleteLine();
checkResultByText("");
}
}
@@ -25,7 +25,8 @@ public interface ScriptManager {
*
* @param newSource new text of script
*/
AsyncResult<?> setSourceOnRemote(@NotNull Script script, @NotNull String newSource, boolean preview);
@NotNull
AsyncResult<?> setSourceOnRemote(@NotNull Script script, @NotNull CharSequence newSource, boolean preview);
void forEachScript(@NotNull Processor<Script> scriptProcessor);
@@ -5,6 +5,7 @@ import com.intellij.openapi.util.AsyncResult;
import com.intellij.util.Consumer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.debugger.values.Value;
import org.jetbrains.io.JsonUtil;
import java.util.Collections;
import java.util.List;
@@ -12,21 +13,6 @@ import java.util.regex.Pattern;
public final class ValueModifierUtil {
private static final Pattern KEY_NOTATION_PROPERTY_NAME_PATTERN = Pattern.compile("[\\p{L}_$]+[\\d\\p{L}_$]*");
private static final String[] REPLACEMENT_CHARS;
static {
REPLACEMENT_CHARS = new String[128];
for (int i = 0; i <= 31; i++) {
REPLACEMENT_CHARS[i] = String.format("\\u%04x", (int)i);
}
REPLACEMENT_CHARS['"'] = "\\\"";
REPLACEMENT_CHARS['\\'] = "\\\\";
REPLACEMENT_CHARS['\t'] = "\\t";
REPLACEMENT_CHARS['\b'] = "\\b";
REPLACEMENT_CHARS['\n'] = "\\n";
REPLACEMENT_CHARS['\r'] = "\\r";
REPLACEMENT_CHARS['\f'] = "\\f";
}
public static ActionCallback setValue(@NotNull final Variable variable, String newValue, @NotNull final EvaluateContext evaluateContext, @NotNull final ValueModifier modifier) {
final ActionCallback callback = new ActionCallback();
@@ -77,44 +63,9 @@ public final class ValueModifierUtil {
builder.append(name);
}
else {
escape(name, builder);
JsonUtil.escape(name, builder);
}
builder.append(']');
}
}
public static void escape(CharSequence value, StringBuilder sb) {
int length = value.length();
sb.ensureCapacity(sb.capacity() + length + 2);
sb.append('"');
int last = 0;
for (int i = 0; i < length; i++) {
char c = value.charAt(i);
String replacement;
if (c < 128) {
replacement = REPLACEMENT_CHARS[c];
if (replacement == null) {
continue;
}
}
else if (c == '\u2028') {
replacement = "\\u2028";
}
else if (c == '\u2029') {
replacement = "\\u2029";
}
else {
continue;
}
if (last < i) {
sb.append(value, last, i);
}
sb.append(replacement);
last = i + 1;
}
if (last < length) {
sb.append(value, last, length);
}
sb.append('"');
}
}
@@ -2,6 +2,7 @@ package org.jetbrains.io;
import com.intellij.util.SmartList;
import gnu.trove.THashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collections;
@@ -9,6 +10,57 @@ import java.util.List;
import java.util.Map;
public class JsonUtil {
private static final String[] REPLACEMENT_CHARS;
static {
REPLACEMENT_CHARS = new String[128];
for (int i = 0; i <= 31; i++) {
REPLACEMENT_CHARS[i] = String.format("\\u%04x", (int)i);
}
REPLACEMENT_CHARS['"'] = "\\\"";
REPLACEMENT_CHARS['\\'] = "\\\\";
REPLACEMENT_CHARS['\t'] = "\\t";
REPLACEMENT_CHARS['\b'] = "\\b";
REPLACEMENT_CHARS['\n'] = "\\n";
REPLACEMENT_CHARS['\r'] = "\\r";
REPLACEMENT_CHARS['\f'] = "\\f";
}
public static void escape(@NotNull CharSequence value, @NotNull StringBuilder sb) {
int length = value.length();
sb.ensureCapacity(sb.capacity() + length + 2);
sb.append('"');
int last = 0;
for (int i = 0; i < length; i++) {
char c = value.charAt(i);
String replacement;
if (c < 128) {
replacement = REPLACEMENT_CHARS[c];
if (replacement == null) {
continue;
}
}
else if (c == '\u2028') {
replacement = "\\u2028";
}
else if (c == '\u2029') {
replacement = "\\u2029";
}
else {
continue;
}
if (last < i) {
sb.append(value, last, i);
}
sb.append(replacement);
last = i + 1;
}
if (last < length) {
sb.append(value, last, length);
}
sb.append('"');
}
public static <T> List<T> nextList(JsonReaderEx reader) {
reader.beginArray();
if (!reader.hasNext()) {
@@ -5,13 +5,14 @@ import gnu.trove.TIntArrayList;
import gnu.trove.TIntHashSet;
import gnu.trove.TIntProcedure;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.io.JsonUtil;
import java.io.IOException;
import java.io.StringWriter;
import java.util.List;
import java.util.Map;
public abstract class OutMessage {
@SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
private final StringWriter stringWriter = new StringWriter();
public final JsonWriter writer = new JsonWriter(stringWriter);
@@ -149,7 +150,7 @@ public abstract class OutMessage {
}
}
protected final void writeSingletonIntArray(@NotNull String name, @NotNull int value) {
protected final void writeSingletonIntArray(@NotNull String name, int value) {
try {
beginArguments();
writer.name(name);
@@ -180,7 +181,7 @@ public abstract class OutMessage {
isNotFirst = true;
}
StringBuffer buffer = item.stringWriter.getBuffer();
StringBuilder buffer = item.stringWriter.getBuffer();
if (!item.finalized) {
item.finalized = true;
try {
@@ -217,7 +218,7 @@ public abstract class OutMessage {
public static void prepareWriteRaw(OutMessage message, String name) throws IOException {
message.writer.name(name).nullValue();
StringBuffer myBuffer = message.stringWriter.getBuffer();
StringBuilder myBuffer = message.stringWriter.getBuffer();
myBuffer.delete(myBuffer.length() - "null".length(), myBuffer.length());
}
@@ -230,7 +231,7 @@ public abstract class OutMessage {
beginArguments();
prepareWriteRaw(this, name);
StringBuffer buffer = value.stringWriter.getBuffer();
StringBuilder buffer = value.stringWriter.getBuffer();
if (!value.finalized) {
value.close();
}
@@ -284,6 +285,18 @@ public abstract class OutMessage {
}
}
protected final void writeString(String name, CharSequence value) {
if (value != null) {
try {
prepareWriteRaw(this, name);
JsonUtil.escape(value, stringWriter.getBuffer());
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
}
protected final void writeNullableString(String name, String value) {
try {
beginArguments();
@@ -0,0 +1,81 @@
package org.jetbrains.jsonProtocol;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import java.io.Writer;
public class StringWriter extends Writer {
private final StringBuilder builder;
public StringWriter() {
builder = new StringBuilder();
lock = builder;
}
public StringWriter(int initialSize) {
if (initialSize < 0) {
throw new IllegalArgumentException("Negative buffer size");
}
builder = new StringBuilder(initialSize);
lock = builder;
}
@Override
public void write(int c) {
builder.append((char)c);
}
@Override
public void write(@NotNull char[] chars, int off, int len) {
builder.append(chars, off, len);
}
@Override
public void write(@NotNull String string) {
builder.append(string);
}
@Override
public void write(@NotNull String str, int off, int length) {
builder.append(str, off, off + length);
}
@Override
public StringWriter append(CharSequence charSequence) {
builder.append(charSequence);
return this;
}
@Override
public StringWriter append(CharSequence charSequence, int start, int end) {
builder.append(charSequence, start, end);
return this;
}
@Override
public StringWriter append(char c) {
write(c);
return this;
}
public String toString() {
return builder.toString();
}
public StringBuilder getBuffer() {
return builder;
}
/**
* Flush the stream.
*/
@Override
public void flush() {
}
@Override
public void close() throws IOException {
}
}
@@ -128,10 +128,20 @@ public class PathMappingSettings implements Cloneable {
public void addMapping(String local, String remote) {
PathMapping mapping = new PathMapping(local, remote);
if (areBothEmpty(mapping.myLocalRoot, mapping.myRemoteRoot)) {
return;
add(mapping);
}
public void addMappingCheckUnique(String local, String remote) {
for (PathMapping mapping: myPathMappings) {
if (pathEquals(local, mapping.getLocalRoot()) && pathEquals(remote, mapping.getRemoteRoot())) {
return;
}
}
myPathMappings.add(mapping);
addMapping(local, remote);
}
private static boolean pathEquals(@NotNull String path1, @NotNull String path2) {
return norm(path1).equals(norm(path2));
}
public boolean canReplaceRemote(String remotePath) {
@@ -267,11 +277,11 @@ public class PathMappingSettings implements Cloneable {
return myRemoteRoot;
}
public int getLocalLen() {
private int getLocalLen() {
return myLocalRoot != null ? myLocalRoot.length() : -1;
}
public int getRemoteLen() {
private int getRemoteLen() {
return myRemoteRoot != null ? myRemoteRoot.length() : -1;
}
@@ -27,8 +27,6 @@ import sun.misc.Unsafe;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
import java.util.concurrent.atomic.AtomicLongFieldUpdater;
/**
* Utility class similar to {@link java.util.concurrent.atomic.AtomicReferenceFieldUpdater} except:
@@ -69,15 +67,13 @@ public class AtomicFieldUpdater<T,V> {
}
@NotNull
public static <T> AtomicLongFieldUpdater<T> forLongFieldIn(@NotNull Class<T> ownerClass) {
Field field = getTheOnlyVolatileFieldOfClass(ownerClass, long.class);
return AtomicLongFieldUpdater.newUpdater(ownerClass, field.getName());
public static <T> AtomicFieldUpdater<T, Long> forLongFieldIn(@NotNull Class<T> ownerClass) {
return new AtomicFieldUpdater<T, Long>(ownerClass, long.class);
}
@NotNull
public static <T> AtomicIntegerFieldUpdater<T> forIntFieldIn(@NotNull Class<T> ownerClass) {
Field field = getTheOnlyVolatileFieldOfClass(ownerClass, int.class);
return AtomicIntegerFieldUpdater.newUpdater(ownerClass, field.getName());
public static <T> AtomicFieldUpdater<T, Integer> forIntFieldIn(@NotNull Class<T> ownerClass) {
return new AtomicFieldUpdater<T, Integer>(ownerClass, int.class);
}
private AtomicFieldUpdater(@NotNull Class<T> ownerClass, @NotNull Class<V> fieldType) {
@@ -120,6 +116,10 @@ public class AtomicFieldUpdater<T,V> {
return unsafe.compareAndSwapLong(owner, offset, expected, newValue);
}
public boolean compareAndSetInt(@NotNull T owner, int expected, int newValue) {
return unsafe.compareAndSwapInt(owner, offset, expected, newValue);
}
public void set(@NotNull T owner, V newValue) {
unsafe.putObjectVolatile(owner, offset, newValue);
}
@@ -29,6 +29,7 @@ import com.intellij.openapi.vcs.ui.CommitMessage;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiFile;
import com.intellij.ui.TextFieldWithAutoCompletionListProvider;
import org.jetbrains.annotations.NotNull;
/**
* @author Dmitry Avdeev
@@ -36,7 +37,7 @@ import com.intellij.ui.TextFieldWithAutoCompletionListProvider;
public class CommitCompletionContributor extends CompletionContributor {
@Override
public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
PsiFile file = parameters.getOriginalFile();
Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
if (document != null) {
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2010 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -20,6 +20,7 @@ import com.intellij.openapi.util.Key;
import com.intellij.openapi.vcs.changes.ChangeListManagerImpl;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.ui.EditorNotifications;
import org.jetbrains.annotations.NotNull;
/**
* @author Dmitry Avdeev
@@ -34,11 +35,14 @@ public class ChangelistConflictNotificationProvider extends EditorNotifications.
myConflictTracker = changeListManager.getConflictTracker();
}
@Override
@NotNull
public Key<ChangelistConflictNotificationPanel> getKey() {
return KEY;
}
public ChangelistConflictNotificationPanel createNotificationPanel(VirtualFile file, FileEditor fileEditor) {
@Override
public ChangelistConflictNotificationPanel createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor) {
return myConflictTracker.hasConflict(file) ? ChangelistConflictNotificationPanel.create(myConflictTracker, file) : null;
}
}
@@ -25,6 +25,8 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.vcs.AbstractVcs;
import com.intellij.openapi.vcs.VcsActiveEnvironmentsProxy;
import com.intellij.util.xmlb.annotations.Attribute;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* @author yole
@@ -47,29 +49,43 @@ public class VcsEP extends AbstractExtensionPointBean {
public boolean crawlUpToCheckUnderVcs;
private AbstractVcs myVcs;
private final Object LOCK = new Object();
public AbstractVcs getVcs(Project project) {
if (myVcs == null) {
try {
final Class<? extends AbstractVcs> foundClass = findClass(vcsClass);
final Class<?>[] interfaces = foundClass.getInterfaces();
for (Class<?> anInterface : interfaces) {
if (BaseComponent.class.isAssignableFrom(anInterface)) {
myVcs = PeriodicalTasksCloser.getInstance().safeGetComponent(project, foundClass);
myVcs = VcsActiveEnvironmentsProxy.proxyVcs(myVcs);
return myVcs;
}
}
myVcs = VcsActiveEnvironmentsProxy.proxyVcs((AbstractVcs)instantiate(vcsClass, project.getPicoContainer()));
}
catch(Exception e) {
LOG.error(e);
return null;
@Nullable
public AbstractVcs getVcs(@NotNull Project project) {
synchronized (LOCK) {
if (myVcs != null) {
return myVcs;
}
}
return myVcs;
AbstractVcs vcs = getInstance(project, vcsClass);
synchronized (LOCK) {
if (myVcs == null) {
myVcs = VcsActiveEnvironmentsProxy.proxyVcs(vcs);
}
return myVcs;
}
}
@Nullable
private AbstractVcs getInstance(@NotNull Project project, @NotNull String vcsClass) {
try {
final Class<? extends AbstractVcs> foundClass = findClass(vcsClass);
final Class<?>[] interfaces = foundClass.getInterfaces();
for (Class<?> anInterface : interfaces) {
if (BaseComponent.class.isAssignableFrom(anInterface)) {
return PeriodicalTasksCloser.getInstance().safeGetComponent(project, foundClass);
}
}
return instantiate(vcsClass, project.getPicoContainer());
}
catch(Exception e) {
LOG.error(e);
return null;
}
}
@NotNull
public VcsDescriptor createDescriptor() {
return new VcsDescriptor(administrativeAreaName, displayName, name, crawlUpToCheckUnderVcs);
}
@@ -91,15 +91,24 @@ public class AllVcses implements AllVcsesI, Disposable {
if (vcs != null) {
return vcs;
}
final VcsEP ep = myExtensions.get(name);
if (ep != null) {
final AbstractVcs vcs1 = ep.getVcs(myProject);
LOG.assertTrue(vcs1 != null, name);
addVcs(vcs1);
return vcs1;
}
}
// unmodifiable map => no sync needed
final VcsEP ep = myExtensions.get(name);
if (ep == null) {
return null;
}
// VcsEP guarantees to always return the same vcs value
final AbstractVcs vcs1 = ep.getVcs(myProject);
LOG.assertTrue(vcs1 != null, name);
synchronized (myLock) {
if (!myVcses.containsKey(name)) {
addVcs(vcs1);
}
return vcs1;
}
}
@Nullable
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -85,13 +85,14 @@ public class UseDistributionWithSourcesNotificationProvider extends EditorNotifi
});
}
@NotNull
@Override
public Key<EditorNotificationPanel> getKey() {
return KEY;
}
@Override
public EditorNotificationPanel createNotificationPanel(VirtualFile file, FileEditor fileEditor) {
public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor) {
try {
if (GradleConstants.DEFAULT_SCRIPT_NAME.equals(file.getName()) ||
GradleConstants.SETTINGS_FILE_NAME.equals(file.getName())) {
@@ -19,6 +19,7 @@
<root url="jar://$MODULE_DIR$/../lib/gradle-messaging-1.12.jar!/" />
<root url="jar://$MODULE_DIR$/../lib/gradle-wrapper-1.12.jar!/" />
<root url="jar://$MODULE_DIR$/../lib/gradle-base-services-1.12.jar!/" />
<root url="jar://$MODULE_DIR$/../lib/gradle-base-services-groovy-1.12.jar!/" />
<root url="jar://$MODULE_DIR$/../lib/gradle-native-1.12.jar!/" />
</CLASSES>
<JAVADOC />
@@ -0,0 +1,140 @@
/*
* Copyright 2000-2014 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 org.jetbrains.plugins.gradle.tooling.builder
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.file.FileVisitDetails
import org.gradle.api.file.FileVisitor
import org.gradle.api.java.archives.Manifest
import org.gradle.api.plugins.WarPlugin
import org.gradle.api.tasks.bundling.War
import org.gradle.util.GradleVersion
import org.jetbrains.annotations.NotNull
import org.jetbrains.annotations.Nullable
import org.jetbrains.plugins.gradle.model.web.WebConfiguration
import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder
import org.jetbrains.plugins.gradle.tooling.ModelBuilderService
import org.jetbrains.plugins.gradle.tooling.internal.web.WarModelImpl
import org.jetbrains.plugins.gradle.tooling.internal.web.WebConfigurationImpl
import org.jetbrains.plugins.gradle.tooling.internal.web.WebResourceImpl
/**
* @author Vladislav.Soroka
* @since 6/25/2014
*/
class WarModelBuilderImpl implements ModelBuilderService {
private static final String WEB_APP_DIR_PROPERTY = "webAppDir"
private static final String WEB_APP_DIR_NAME_PROPERTY = "webAppDirName"
@Override
public boolean canBuild(String modelName) {
return WebConfiguration.name.equals(modelName)
}
@Nullable
@Override
public Object buildAll(String modelName, Project project) {
final WarPlugin warPlugin = project.plugins.findPlugin(WarPlugin)
if (warPlugin == null) return null
final String webAppDirName = !project.hasProperty(WEB_APP_DIR_NAME_PROPERTY) ?
"src/main/webapp" : String.valueOf(project.property(WEB_APP_DIR_NAME_PROPERTY))
final File webAppDir = !project.hasProperty(WEB_APP_DIR_PROPERTY) ? new File(project.projectDir, webAppDirName) :
(File)project.property(WEB_APP_DIR_PROPERTY)
def warModels = []
project.tasks.each { Task task ->
if (task instanceof War) {
final WarModelImpl warModel =
new WarModelImpl((task as War).archiveName, webAppDirName, webAppDir)
final List<WebConfiguration.WebResource> webResources = []
final War warTask = task as War
warModel.webXml = warTask.webXml
warTask.rootSpec.walk({ def resolver ->
// def resolver ->
// in Gradle v1.x - org.gradle.api.internal.file.copy.CopySpecInternal
// in Gradle v2.x - org.gradle.api.internal.file.copy.CopySpecResolver
if (resolver.metaClass.respondsTo(resolver, 'setIncludeEmptyDirs', boolean)) {
resolver.setIncludeEmptyDirs(true)
}
if (!resolver.metaClass.respondsTo(resolver, 'getDestPath') ||
!resolver.metaClass.respondsTo(resolver, 'getSource')) {
throw new RuntimeException("${GradleVersion.current()} is not supported by web artifact importer")
}
final String relativePath = resolver.destPath.pathString
resolver.source.visit(new FileVisitor() {
@Override
public void visitDir(FileVisitDetails dirDetails) {
try {
addPath(webResources, relativePath, dirDetails.path, dirDetails.file)
}
catch (Exception ignore) {
}
}
@Override
public void visitFile(FileVisitDetails fileDetails) {
try {
if (warTask.webXml == null ||
!fileDetails.file.canonicalPath.equals(warTask.webXml.canonicalPath)) {
addPath(webResources, relativePath, fileDetails.path, fileDetails.file)
}
}
catch (Exception ignore) {
}
}
})
})
warModel.webResources = webResources
warModel.classpath = warTask.classpath.files
Manifest manifest = warTask.manifest
if (manifest != null) {
def writer = new StringWriter()
manifest.writeTo(writer)
warModel.manifestContent = writer.toString()
}
warModels.add(warModel)
}
}
new WebConfigurationImpl(warModels)
}
@NotNull
@Override
public ErrorMessageBuilder getErrorMessageBuilder(@NotNull Project project, @NotNull Exception e) {
ErrorMessageBuilder.create(
project, e, "Web project import errors"
).withDescription("Web Facets/Artifacts will not be configured")
}
private static addPath(List<WebConfiguration.WebResource> webResources, String warRelativePath, String fileRelativePath, File file) {
warRelativePath = warRelativePath == null ? "" : warRelativePath
WebConfiguration.WebResource webResource = new WebResourceImpl(warRelativePath, fileRelativePath, file)
webResources.add(webResource)
}
}
@@ -1,140 +0,0 @@
/*
* Copyright 2000-2014 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 org.jetbrains.plugins.gradle.tooling.builder;
import org.gradle.api.Action;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.file.FileVisitDetails;
import org.gradle.api.file.FileVisitor;
import org.gradle.api.internal.file.copy.CopySpecInternal;
import org.gradle.api.java.archives.Manifest;
import org.gradle.api.plugins.WarPlugin;
import org.gradle.api.tasks.bundling.War;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.gradle.model.web.WebConfiguration;
import org.jetbrains.plugins.gradle.tooling.ErrorMessageBuilder;
import org.jetbrains.plugins.gradle.tooling.ModelBuilderService;
import org.jetbrains.plugins.gradle.tooling.internal.web.WarModelImpl;
import org.jetbrains.plugins.gradle.tooling.internal.web.WebConfigurationImpl;
import org.jetbrains.plugins.gradle.tooling.internal.web.WebResourceImpl;
import java.io.File;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
/**
* @author Vladislav.Soroka
* @since 11/5/13
*/
public class WarModelBuilderImpl implements ModelBuilderService {
private static final String WEB_APP_DIR_PROPERTY = "webAppDir";
private static final String WEB_APP_DIR_NAME_PROPERTY = "webAppDirName";
@Override
public boolean canBuild(String modelName) {
return WebConfiguration.class.getName().equals(modelName);
}
@Nullable
@Override
public Object buildAll(String modelName, Project project) {
final WarPlugin warPlugin = project.getPlugins().findPlugin(WarPlugin.class);
if (warPlugin == null) return null;
final String webAppDirName = !project.hasProperty(WEB_APP_DIR_NAME_PROPERTY) ?
"src/main/webapp" : String.valueOf(project.property(WEB_APP_DIR_NAME_PROPERTY));
final File webAppDir = !project.hasProperty(WEB_APP_DIR_PROPERTY)
? new File(project.getProjectDir(), webAppDirName)
: (File)project.property(WEB_APP_DIR_PROPERTY);
List<WebConfiguration.WarModel> warModels = new ArrayList<WebConfiguration.WarModel>();
for (Task task : project.getTasks()) {
if (task instanceof War) {
final WarModelImpl warModel =
new WarModelImpl(((War)task).getArchiveName(), webAppDirName, webAppDir);
final List<WebConfiguration.WebResource> webResources = new ArrayList<WebConfiguration.WebResource>();
final War warTask = (War)task;
warModel.setWebXml(warTask.getWebXml());
warTask.getRootSpec().walk(new Action<CopySpecInternal>() {
@Override
public void execute(CopySpecInternal internal) {
final String relativePath = internal.getDestPath().getPathString();
internal.getSource().visit(new FileVisitor() {
@Override
public void visitDir(FileVisitDetails dirDetails) {
try {
addPath(webResources, relativePath, dirDetails.getPath(), dirDetails.getFile());
}
catch (Exception ignore) {
}
}
@Override
public void visitFile(FileVisitDetails fileDetails) {
try {
if (warTask.getWebXml() == null ||
!fileDetails.getFile().getCanonicalPath().equals(warTask.getWebXml().getCanonicalPath())) {
addPath(webResources, relativePath, fileDetails.getPath(), fileDetails.getFile());
}
}
catch (Exception ignore) {
}
}
});
}
});
warModel.setWebResources(webResources);
warModel.setClasspath(warTask.getClasspath().getFiles());
Manifest manifest = warTask.getManifest();
if (manifest != null) {
StringWriter writer = new StringWriter();
manifest.writeTo(writer);
warModel.setManifestContent(writer.toString());
}
warModels.add(warModel);
}
}
return new WebConfigurationImpl(warModels);
}
@NotNull
@Override
public ErrorMessageBuilder getErrorMessageBuilder(@NotNull Project project, @NotNull Exception e) {
return ErrorMessageBuilder.create(
project, e, "Web project import errors"
).withDescription("Web Facets/Artifacts will not be configured");
}
private static void addPath(List<WebConfiguration.WebResource> webResources, String warRelativePath, String fileRelativePath, File file) {
warRelativePath = warRelativePath == null ? "" : warRelativePath;
WebConfiguration.WebResource webResource = new WebResourceImpl(warRelativePath, fileRelativePath, file);
webResources.add(webResource);
}
}
@@ -20,7 +20,7 @@ allprojects {
idea {
module {
scopes.PROVIDED.plus += configurations.provided
scopes.PROVIDED.plus += [configurations.provided]
}
}
}
@@ -65,6 +65,7 @@ public abstract class AbstractModelBuilderTest {
public static final String GRADLE_v1_10 = "1.10";
public static final String GRADLE_v1_11 = "1.11";
public static final String GRADLE_v1_12 = "1.12";
public static final String GRADLE_v2_0 = "2.0-rc-2";
public static final Pattern TEST_METHOD_NAME_PATTERN = Pattern.compile("(.*)\\[(\\d*)\\]");
@@ -84,10 +85,11 @@ public abstract class AbstractModelBuilderTest {
@Parameterized.Parameters
public static Collection<Object[]> data() {
Object[][] data = {
{AbstractModelBuilderTest.GRADLE_v1_9},
{AbstractModelBuilderTest.GRADLE_v1_10},
{AbstractModelBuilderTest.GRADLE_v1_11},
{AbstractModelBuilderTest.GRADLE_v1_12}
{GRADLE_v1_9},
{GRADLE_v1_10},
{GRADLE_v1_11},
{GRADLE_v1_12},
{GRADLE_v2_0}
};
return Arrays.asList(data);
}
@@ -21,6 +21,7 @@ import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
@@ -67,13 +68,14 @@ public class ConfigureGroovyLibraryNotificationProvider extends EditorNotificati
}
}
@NotNull
@Override
public Key<EditorNotificationPanel> getKey() {
return KEY;
}
@Override
public EditorNotificationPanel createNotificationPanel(VirtualFile file, FileEditor fileEditor) {
public EditorNotificationPanel createNotificationPanel(@NotNull VirtualFile file, @NotNull FileEditor fileEditor) {
try {
if (!supportedFileTypes.contains(file.getFileType())) return null;
// do not show the panel for Gradle build scripts
@@ -81,7 +83,7 @@ public class ConfigureGroovyLibraryNotificationProvider extends EditorNotificati
if (StringUtil.endsWith(file.getName(), ".gradle")) return null;
if (CompilerManager.getInstance(myProject).isExcludedFromCompilation(file)) return null;
final Module module = ModuleUtil.findModuleForFile(file, myProject);
final Module module = ModuleUtilCore.findModuleForFile(file, myProject);
if (module == null) return null;
if (isMavenModule(module)) return null;
@@ -34,7 +34,7 @@ import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
*/
public class GroovyShellCompletionContributor extends CompletionContributor {
@Override
public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
PsiFile file = parameters.getOriginalFile();
if (!(file instanceof GroovyShellCodeFragment)) return;
@@ -22,6 +22,7 @@ import com.intellij.psi.PsiMethod;
import com.intellij.psi.PsiParameter;
import com.intellij.psi.PsiType;
import com.intellij.psi.ResolveResult;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.plugins.groovy.lang.psi.impl.statements.expressions.TypesUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
@@ -32,7 +33,7 @@ import java.util.ArrayList;
*/
public class GrMethodMergingContributor extends CompletionContributor {
@Override
public AutoCompletionDecision handleAutoCompletionPossibility(AutoCompletionContext context) {
public AutoCompletionDecision handleAutoCompletionPossibility(@NotNull AutoCompletionContext context) {
final CompletionParameters parameters = context.getParameters();
if (parameters.getCompletionType() != CompletionType.SMART && parameters.getCompletionType() != CompletionType.BASIC) {
@@ -73,7 +73,7 @@ public class GroovyCompletionContributor extends CompletionContributor {
}
@Override
public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
if (!AFTER_NUMBER_LITERAL.accepts(parameters.getPosition())) {
super.fillCompletionVariants(parameters, result);
}
@@ -48,7 +48,7 @@ public class GroovyNoVariantsDelegator extends CompletionContributor {
}
@Override
public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) {
public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull CompletionResultSet result) {
LinkedHashSet<CompletionResult> plainResults = result.runRemainingContributors(parameters, true);
final boolean empty = JavaNoVariantsDelegator.containsOnlyPackages(plainResults) || suggestMetaAnnotations(parameters);
@@ -377,7 +377,7 @@ public class GroovySmartCompletionContributor extends CompletionContributor {
}
@Override
public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
super.fillCompletionVariants(parameters, result);
}
@@ -171,7 +171,6 @@ public class RenameGrFieldProcessor extends RenameJavaVariableProcessor {
return GrTraitUtil.getTraitFieldPrefix(prototype.getContainingClass()) + newPrototypeName;
}
LOG.error(element);
return null;
}
@@ -202,7 +201,6 @@ public class RenameGrFieldProcessor extends RenameJavaVariableProcessor {
return getNewElement(prototype);
}
LOG.error(element);
return null;
}
}
Binary file not shown.
@@ -55,6 +55,7 @@ public class IdeaDecompilerTest extends LightCodeInsightFixtureTestCase {
public void testExtendsList() { doTestDecompiler(); }
public void testParameters() { doTestDecompiler(); }
public void testConstants() { doTestDecompiler(); }
public void testAnonymous() { doTestDecompiler(); }
private void doTestDecompiler() {
String name = PluginPathManager.getPluginHomePath("java-decompiler") + "/testData/" + getName().substring(4);
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,13 @@
public class Anonymous {
private int count = 0;
public Object produce() {
final int id = count++;
return new Object() {
@Override
public String toString() {
return "anonymous_" + id;
}
};
}
}
@@ -0,0 +1,24 @@
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
public class Anonymous {
private int count = 0;
public Anonymous() {
}
public Object produce() {
++this.count;
final int var1 = this.count;
return new Object() {
public String toString() {
return "anonymous_" + var1;
}
};
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2014 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.
@@ -19,17 +19,12 @@ package com.intellij.execution;
import com.intellij.execution.junit.JUnitUtil;
import com.intellij.execution.junit.TestClassFilter;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.IndexNotReadyException;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.search.PsiElementProcessorAdapter;
import com.intellij.psi.search.PsiShortNamesCache;
import com.intellij.psi.search.*;
import com.intellij.psi.search.searches.AnnotatedMembersSearch;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.util.PsiUtilCore;
@@ -47,7 +42,7 @@ public class ConfigurationUtil {
final Project project = manager.getProject();
GlobalSearchScope projectScopeWithoutLibraries = GlobalSearchScope.projectScope(project);
final GlobalSearchScope scope = projectScopeWithoutLibraries.intersectWith(testClassFilter.getScope());
ClassInheritorsSearch.search(testClassFilter.getBase(), scope, true).forEach(new PsiElementProcessorAdapter<PsiClass>(new PsiElementProcessor<PsiClass>() {
ClassInheritorsSearch.search(testClassFilter.getBase(), scope, true, true, false).forEach(new PsiElementProcessorAdapter<PsiClass>(new PsiElementProcessor<PsiClass>() {
public boolean execute(@NotNull final PsiClass aClass) {
if (testClassFilter.isAccepted(aClass)) found.add(aClass);
return true;
@@ -113,7 +108,7 @@ public class ConfigurationUtil {
found.add(containingClass);
isJUnit4.set(Boolean.TRUE);
}
ClassInheritorsSearch.search(containingClass, scope, true)
ClassInheritorsSearch.search(containingClass, scope, true, true, false)
.forEach(new PsiElementProcessorAdapter<PsiClass>(new PsiElementProcessor<PsiClass>() {
public boolean execute(@NotNull final PsiClass aClass) {
if (testClassFilter.isAccepted(aClass)) {
@@ -17,6 +17,7 @@ import com.intellij.psi.xml.XmlTokenType;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomFileElement;
import com.intellij.util.xml.DomManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.dom.converters.MavenDependencyCompletionUtil;
import org.jetbrains.idea.maven.dom.model.MavenDomDependency;
import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
@@ -28,7 +29,7 @@ import org.jetbrains.idea.maven.indices.MavenProjectIndicesManager;
public class MavenDependenciesCompletionProvider extends CompletionContributor {
@Override
public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
PsiElement xmlText = parameters.getPosition().getParent();
if (!(xmlText instanceof XmlText)) return;
@@ -16,6 +16,7 @@ import com.intellij.util.Consumer;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomFileDescription;
import com.intellij.util.xml.DomManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.dom.MavenDomProjectModelDescription;
import org.jetbrains.idea.maven.dom.MavenDomUtil;
import org.jetbrains.idea.maven.dom.converters.MavenDependencyCompletionUtil;
@@ -31,7 +32,7 @@ public class MavenPomXmlCompletionTagListenerContributor extends CompletionContr
private final Set<String> myHandledTags = ImmutableSet.of("dependency");
@Override
public void fillCompletionVariants(CompletionParameters parameters, final CompletionResultSet result) {
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull final CompletionResultSet result) {
if (TemplateManager.getInstance(parameters.getOriginalFile().getProject()).getActiveTemplate(parameters.getEditor()) != null) {
return; // Don't brake the template.
}
@@ -39,7 +39,7 @@ import java.util.Collections;
public class MavenSmartCompletionContributor extends CompletionContributor {
@Override
public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) {
public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull CompletionResultSet result) {
if (parameters.getCompletionType() != CompletionType.SMART) return;
Collection<?> variants = getVariants(parameters);
@@ -46,7 +46,7 @@ import java.util.Set;
public class MavenVersionCompletionContributor extends CompletionContributor {
@Override
public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
if (parameters.getCompletionType() != CompletionType.BASIC) return;
PsiElement element = parameters.getPosition();
@@ -24,6 +24,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiNamedElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.dom.MavenDomUtil;
import org.jetbrains.idea.maven.project.MavenProject;
import org.jetbrains.idea.maven.project.MavenProjectsManager;
@@ -33,7 +34,7 @@ import java.util.Collection;
public class MavenPropertyCompletionContributor extends CompletionContributor {
@Override
public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
PsiFile psiFile = parameters.getOriginalFile();
Project project = psiFile.getProject();
@@ -177,7 +177,7 @@ public class JqlCompletionContributor extends CompletionContributor {
}
@Override
public void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
public void fillCompletionVariants(@NotNull CompletionParameters parameters, @NotNull CompletionResultSet result) {
LOG.debug(DebugUtil.psiToString(parameters.getOriginalFile(), true));
super.fillCompletionVariants(parameters, result);
}
@@ -20,8 +20,6 @@ import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicReference;
import static com.intellij.tasks.actions.TaskSearchSupport.getRepositoriesTasks;
/**
* @author Mikhail Golubev
*/
@@ -88,7 +86,15 @@ class TaskItemProvider implements ChooseByNameItemProvider, Disposable {
try {
List<Task> tasks = future.get();
myFutureReference.compareAndSet(future, null);
tasks.removeAll(cachedAndLocalTasks);
// Exclude *all* cached and local issues, not only those returned by TaskSearchSupport.getLocalAndCachedTasks().
// Previously used approach might lead to the following strange behavior. Local task excluded by getLocalAndCachedTasks()
// as "locally closed" (i.e. having no associated change list) was indeed *included* in popup because it
// was contained in server response (as not remotely closed). Moreover on next request with pagination when the
// same issues was not returned again by server it was *excluded* from popup (thus subsequent update reduced total
// number of items shown).
tasks.removeAll(TaskManager.getManager(myProject).getLocalTasks());
tasks.removeAll(TaskManager.getManager(myProject).getCachedIssues());
return processTasks(tasks, consumer, cancelled);
}
catch (InterruptedException interrupted) {
@@ -138,7 +144,8 @@ class TaskItemProvider implements ChooseByNameItemProvider, Disposable {
limit = GotoTaskAction.PAGE_SIZE;
myCurrentOffset += GotoTaskAction.PAGE_SIZE;
}
List<Task> tasks = getRepositoriesTasks(TaskManager.getManager(myProject), pattern, offset, limit, true, everywhere, cancelled);
List<Task> tasks = TaskSearchSupport.getRepositoriesTasks(TaskManager.getManager(myProject),
pattern, offset, limit, true, everywhere, cancelled);
myOldEverywhere = everywhere;
myOldPattern = pattern;
return tasks;
@@ -108,7 +108,11 @@ public class RedmineRepository extends NewBaseRepositoryImpl {
// /users/current.json. Unfortunately this endpoint may be unavailable on some old servers (see IDEA-122845)
// and in this case we have to come back to requesting issues in this case to test anything at all.
HttpClient client = getHttpClient();
HttpResponse response = client.execute(new HttpGet(getRestApiUrl("users", "current.json")));
URIBuilder uriBuilder = new URIBuilder(getRestApiUrl("users", "current.json"));
if (isUseApiKeyAuthentication()) {
uriBuilder.addParameter("key", getAPIKey());
}
HttpResponse response = client.execute(new HttpGet(uriBuilder.build()));
//TaskUtil.prettyFormatResponseToLog(LOG, response);
int code = response.getStatusLine().getStatusCode();
if (code == HttpStatus.SC_NOT_FOUND) {
@@ -189,7 +193,7 @@ public class RedmineRepository extends NewBaseRepositoryImpl {
}
private boolean isUseApiKeyAuthentication() {
return !StringUtil.isEmptyOrSpaces(myAPIKey) && !isUseHttpAuthentication();
return !isUseHttpAuthentication() && StringUtil.isNotEmpty(myAPIKey);
}
@Override
@@ -203,11 +207,11 @@ public class RedmineRepository extends NewBaseRepositoryImpl {
@Override
public boolean isConfigured() {
if (!super.isConfigured() || StringUtil.isEmpty(myUsername)) return false;
if (!super.isConfigured()) return false;
if (isUseHttpAuthentication()) {
return StringUtil.isNotEmpty(myPassword);
return StringUtil.isNotEmpty(myPassword) && StringUtil.isNotEmpty(myUsername);
}
return !StringUtil.isEmptyOrSpaces(myAPIKey);
return StringUtil.isNotEmpty(myAPIKey);
}
@Nullable
@@ -35,6 +35,8 @@ public class RedmineRepositoryEditor extends BaseRepositoryEditor<RedmineReposit
installListener(myProjectCombo);
installListener(myAPIKey);
toggleCredentialsVisibility();
UIUtil.invokeLaterIfNeeded(new Runnable() {
@Override
public void run() {
@@ -47,6 +49,8 @@ public class RedmineRepositoryEditor extends BaseRepositoryEditor<RedmineReposit
protected void afterTestConnection(boolean connectionSuccessful) {
if (connectionSuccessful) {
new FetchProjectsTask().queue();
} else {
myProjectCombo.removeAllItems();
}
}
@@ -63,6 +67,19 @@ public class RedmineRepositoryEditor extends BaseRepositoryEditor<RedmineReposit
myRepository.setCurrentProject((RedmineProject)myProjectCombo.getSelectedItem());
myRepository.setAPIKey(myAPIKey.getText().trim());
myTestButton.setEnabled(myRepository.isConfigured());
toggleCredentialsVisibility();
}
private void toggleCredentialsVisibility() {
myPasswordLabel.setVisible(myRepository.isUseHttpAuthentication());
myPasswordText.setVisible(myRepository.isUseHttpAuthentication());
myUsernameLabel.setVisible(myRepository.isUseHttpAuthentication());
myUserNameText.setVisible(myRepository.isUseHttpAuthentication());
myAPIKeyLabel.setVisible(!myRepository.isUseHttpAuthentication());
myAPIKey.setVisible(!myRepository.isUseHttpAuthentication());
}
@Nullable
@@ -72,7 +89,7 @@ public class RedmineRepositoryEditor extends BaseRepositoryEditor<RedmineReposit
myProjectCombo = new ComboBox(300);
myProjectCombo.setRenderer(new TaskUiUtil.SimpleComboBoxRenderer("Set URL and password/token first"));
myAPIKeyLabel = new JBLabel("API Token:", SwingConstants.RIGHT);
myAPIKey = new JTextField();
myAPIKey = new JPasswordField();
return FormBuilder.createFormBuilder()
.addLabeledComponent(myAPIKeyLabel, myAPIKey)
.addLabeledComponent(myProjectLabel, myProjectCombo)
@@ -34,7 +34,7 @@ public class YouTrackCompletionContributor extends CompletionContributor {
private static final InsertHandler<LookupElement> INSERT_HANDLER = new MyInsertHandler();
@Override
public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) {
public void fillCompletionVariants(@NotNull final CompletionParameters parameters, @NotNull CompletionResultSet result) {
if (LOG.isDebugEnabled()) {
LOG.debug(DebugUtil.psiToString(parameters.getOriginalFile(), true));
}

Some files were not shown because too many files have changed in this diff Show More