diff --git a/java/compiler/impl/src/com/intellij/compiler/classFilesIndex/chainsSearch/completion/MethodsChainsCompletionContributor.java b/java/compiler/impl/src/com/intellij/compiler/classFilesIndex/chainsSearch/completion/MethodsChainsCompletionContributor.java index 5a8539629fb5..d96d6dfe0f83 100644 --- a/java/compiler/impl/src/com/intellij/compiler/classFilesIndex/chainsSearch/completion/MethodsChainsCompletionContributor.java +++ b/java/compiler/impl/src/com/intellij/compiler/classFilesIndex/chainsSearch/completion/MethodsChainsCompletionContributor.java @@ -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)) { diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java b/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java index e52236dca5a2..2eb2ca8e78a8 100644 --- a/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java +++ b/java/debugger/impl/src/com/intellij/debugger/engine/JavaExecutionStack.java @@ -116,8 +116,8 @@ public class JavaExecutionStack extends XExecutionStack { @Override protected void action() throws Exception { boolean showLibraryStackframes = DebuggerSettings.getInstance().SHOW_LIBRARY_STACKFRAMES; - List frames = new ArrayList(); if (!myThreadProxy.isCollected() && myDebugProcess.getSuspendManager().isSuspended(myThreadProxy)) { + List frames = new ArrayList(); 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); } }); } diff --git a/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java b/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java index 5f6f18def730..8a4c380a669a 100644 --- a/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java +++ b/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/AttachSourcesNotificationProvider.java @@ -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 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 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; } } diff --git a/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/SetupSDKNotificationProvider.java b/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/SetupSDKNotificationProvider.java index 178c85584ae2..668f2cc97577 100644 --- a/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/SetupSDKNotificationProvider.java +++ b/java/idea-ui/src/com/intellij/codeInsight/daemon/impl/SetupSDKNotificationProvider.java @@ -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 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); diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/ClassesOrderRootTypeUIFactory.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/ClassesOrderRootTypeUIFactory.java index 92b110caef43..c2d3d801a211 100644 --- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/ClassesOrderRootTypeUIFactory.java +++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/libraryEditor/ClassesOrderRootTypeUIFactory.java @@ -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 diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java index 66dbe098e5ce..2fc06a2dabd5 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassNameCompletionContributor.java @@ -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); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java index e84eb2646ec0..f6871faea16e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaClassReferenceCompletionContributor.java @@ -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) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java index 20615a027a42..47cf86819c0f 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java @@ -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; } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java index 7e7e0955b560..49379c2c4f3e 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaDocCompletionContributor.java @@ -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)) { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java index a484e4b1f4f9..a1d4a6f8ac81 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMemberNameCompletionContributor.java @@ -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; } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java index 74bdc7ccc0a5..b409014c1fe8 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaMethodMergingContributor.java @@ -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; diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java index a174ef437acf..f36f567199a0 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java @@ -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 plainResults = result.runRemainingContributors(parameters, true); final boolean empty = containsOnlyPackages(plainResults) || suggestMetaAnnotations(parameters); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java index 37dc0829f969..61d8abe18368 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java @@ -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)); } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/RefactoringCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/RefactoringCompletionContributor.java index 62dbd0df8f79..9264599a4e1b 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/RefactoringCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/RefactoringCompletionContributor.java @@ -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; } diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java b/java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java index a57303044485..310cf1444e88 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/XmlBasicToClassNameDelegator.java @@ -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 || diff --git a/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicCompletionContributor.java b/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicCompletionContributor.java index 4f9fa882be6e..8150b618f8dc 100644 --- a/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInspection/magicConstant/MagicCompletionContributor.java @@ -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; diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java index ac3e7a6fd455..f1d847cb24c2 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSuperMethodImplUtil.java @@ -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()); } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/EnumValuesMethod.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/EnumValuesMethod.java new file mode 100644 index 000000000000..14ad192c8823 --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/newMethodRef/EnumValuesMethod.java @@ -0,0 +1,25 @@ +import java.util.function.Supplier; + +class EnumValues { + + { + Supplier> supplier = () -> new C<>(ABC::values); + } + + private static interface I { + T get(); + } + + private static class C implements I { + C(Supplier supplier) {} + + @Override + public E get() { + return null; + } + } + + private static enum ABC { + A, B, C + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavyNormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavyNormalCompletionTest.groovy index 45a3f818df3f..5d0bcd4eaa8c 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavyNormalCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/HeavyNormalCompletionTest.groovy @@ -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 diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy index 32dfc92200a8..8a54c9594144 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy @@ -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 } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java index 0c61b63bfc8d..3cfdaa4071cc 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/NewMethodRefHighlightingTest.java @@ -265,6 +265,10 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase { doTest(); } + public void testEnumValuesMethod() throws Exception { + doTest(); + } + private void doTest() { doTest(false); } diff --git a/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java b/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java index b832e65c7675..3cde353eded2 100644 --- a/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java @@ -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()); } } diff --git a/java/java-tests/testSrc/com/intellij/psi/ClsRepositoryUseTest.java b/java/java-tests/testSrc/com/intellij/psi/ClsRepositoryUseTest.java index 16392eb601d5..e8317415d8b3 100644 --- a/java/java-tests/testSrc/com/intellij/psi/ClsRepositoryUseTest.java +++ b/java/java-tests/testSrc/com/intellij/psi/ClsRepositoryUseTest.java @@ -690,7 +690,6 @@ public class ClsRepositoryUseTest extends PsiTestCase { final PsiType returnType = methodsWithReturnType.getReturnType(); assert returnType != null : methodsWithReturnType; assertEquals("pack.Parametrized", returnType.getCanonicalText()); - assertEquals("public pack.Parametrized 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()); } } diff --git a/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveInLibrariesTest.groovy b/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveInLibrariesTest.groovy index 5e6adfdb4f55..ce04dd0ba20c 100644 --- a/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveInLibrariesTest.groovy +++ b/java/java-tests/testSrc/com/intellij/psi/resolve/ResolveInLibrariesTest.groovy @@ -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 pkgDirs = pkg.directories.collect { it.virtualFile } Collection 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 } } diff --git a/platform/core-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java b/platform/core-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java index b8ecfc3dc017..68e8d2500314 100644 --- a/platform/core-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java +++ b/platform/core-impl/src/com/intellij/openapi/editor/impl/IntervalTreeImpl.java @@ -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 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 cachedDeltaUpdater = AtomicLongFieldUpdater.newUpdater(IntervalNode.class, "cachedDeltaUpToRoot"); + private static final AtomicFieldUpdater 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 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) { diff --git a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java index 5f64932abb35..0a575acdc550 100644 --- a/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java +++ b/platform/indexing-impl/src/com/intellij/openapi/module/impl/scopes/ModuleWithDependentsScope.java @@ -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 walkingQueue = new Queue(10); walkingQueue.addLast(myModule); - Module[] allModules = ModuleManager.getInstance(myModule.getProject()).getModules(); - Set processed = new THashSet(); - 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 plainUsages = MultiMap.create(); + final MultiMap exportingUsages = MultiMap.create(); + } + + private static ModuleIndex getModuleIndex(final Project project) { + return CachedValuesManager.getManager(project).getCachedValue(project, new CachedValueProvider() { + @Nullable + @Override + public Result 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 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); diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java index 831e056e7efb..06edc72a06f8 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/CompletionContributor.java @@ -128,7 +128,8 @@ public abstract class CompletionContributor { private final MultiMap, CompletionProvider>> myMap = new MultiMap, CompletionProvider>>(); - public final void extend(@Nullable CompletionType type, final ElementPattern place, CompletionProvider provider) { + public final void extend(@Nullable CompletionType type, + @NotNull final ElementPattern place, CompletionProvider provider) { myMap.putValue(type, new Pair, CompletionProvider>(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, CompletionProvider> 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 forParameters(final CompletionParameters parameters) { + @NotNull + public static List forParameters(@NotNull final CompletionParameters parameters) { return ApplicationManager.getApplication().runReadAction(new Computable>() { @Override public List compute() { @@ -243,6 +239,7 @@ public abstract class CompletionContributor { }); } + @NotNull public static List forLanguage(@NotNull Language language) { return MyExtensionPointManager.INSTANCE.forKey(language); } diff --git a/platform/lang-api/src/com/intellij/openapi/projectRoots/ui/PathEditor.java b/platform/lang-api/src/com/intellij/openapi/projectRoots/ui/PathEditor.java index 33f1cced24bf..ecebb9db73f3 100644 --- a/platform/lang-api/src/com/intellij/openapi/projectRoots/ui/PathEditor.java +++ b/platform/lang-api/src/com/intellij/openapi/projectRoots/ui/PathEditor.java @@ -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) { diff --git a/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java b/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java index ee36676ec5fc..021c055dd70f 100644 --- a/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java +++ b/platform/lang-api/src/com/intellij/openapi/roots/ui/OrderRootTypeUIFactory.java @@ -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 EP_NAME = ExtensionPointName.create("com.intellij.OrderRootTypeUI"); - KeyedExtensionFactory FACTORY = new KeyedExtensionFactory(OrderRootTypeUIFactory.class, EP_NAME, - ApplicationManager - .getApplication().getPicoContainer()) { - @Override - public String getKey(@NotNull final OrderRootType key) { - return key.name(); - } - }; + + KeyedExtensionFactory FACTORY = + new KeyedExtensionFactory(OrderRootTypeUIFactory.class, EP_NAME, ApplicationManager.getApplication().getPicoContainer()) { + @Override + public String getKey(@NotNull final OrderRootType key) { + return key.name(); + } + }; SdkPathEditor createPathEditor(Sdk sdk); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/AddSpaceInsertHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/AddSpaceInsertHandler.java index d0e990654f3d..d3cfedaf6a1a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/AddSpaceInsertHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/AddSpaceInsertHandler.java @@ -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 { - public final static InsertHandler INSTANCE = new AddSpaceInsertHandler(); + public final static InsertHandler INSTANCE = new AddSpaceInsertHandler(false); + public final static InsertHandler 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 { else { editor.getCaretModel().moveToOffset(editor.getCaretModel().getOffset() + 1); } + if (myTriggerAutoPopup) { + AutoPopupController.getInstance(project).autoPopupMemberLookup(editor, null); + } } } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/ComboEditorCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/ComboEditorCompletionContributor.java index ac685230486b..cd309b722d6a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/ComboEditorCompletionContributor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/ComboEditorCompletionContributor.java @@ -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; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/DefaultCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/DefaultCompletionContributor.java index cc69a9aeb611..fe495d3e6f3a 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/DefaultCompletionContributor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/DefaultCompletionContributor.java @@ -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]; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/LegacyCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/LegacyCompletionContributor.java index 1104bb83d826..b8b58bf5bd1f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/LegacyCompletionContributor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/LegacyCompletionContributor.java @@ -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; } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/WordCompletionContributor.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/WordCompletionContributor.java index 5d1ef95ffb4c..7dc1cd40dfad 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/WordCompletionContributor.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/WordCompletionContributor.java @@ -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.emptySet()); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java index e776b30b7f98..ae9ba979e771 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/impl/LookupImpl.java @@ -78,7 +78,7 @@ public class LookupImpl extends LightweightHint implements LookupEx, Disposable private final Editor myEditor; private final JBList myList = new JBList(new CollectionListModel()) { @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); diff --git a/platform/lang-impl/src/com/intellij/ide/GeneratedFileEditingNotificationProvider.java b/platform/lang-impl/src/com/intellij/ide/GeneratedFileEditingNotificationProvider.java index 5a6606be1c77..5b9e9a663b3f 100644 --- a/platform/lang-impl/src/com/intellij/ide/GeneratedFileEditingNotificationProvider.java +++ b/platform/lang-impl/src/com/intellij/ide/GeneratedFileEditingNotificationProvider.java @@ -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 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(); diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java index 688d69fdd467..657fc6b9eda7 100644 --- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java +++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java @@ -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 actions = new HashSet(); - final Set settings = new HashSet(); + 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 elements = new LinkedHashSet(); - final GlobalSearchScope scope = GlobalSearchScope.projectScope(project); - myFileChooseByName.getProvider().filterElements(myFileChooseByName, pattern, true, - myProgressIndicator, new Processor() { - @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 files = new ArrayList(); - 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 elements = new LinkedHashSet(); - final GlobalSearchScope scope = GlobalSearchScope.projectScope(project); - mySymbolsChooseByName.getProvider().filterElements(mySymbolsChooseByName, pattern, false, - myProgressIndicator, new Processor() { - @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 symbols = new ArrayList(); - 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 runConfigurations = new ArrayList(); + 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 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 getClasses(String pattern, boolean includeLibs, final int max) { - int counter = 0; - final Set elements = new LinkedHashSet(); + 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() { + @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() { @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 classes = new ArrayList(); - 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() { + @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 files = new ArrayList(); @@ -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 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 { + 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); diff --git a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/CompletionContributorForInplaceRename.java b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/CompletionContributorForInplaceRename.java index 2c59c10fb486..04bfd2a4a06f 100644 --- a/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/CompletionContributorForInplaceRename.java +++ b/platform/lang-impl/src/com/intellij/refactoring/rename/inplace/CompletionContributorForInplaceRename.java @@ -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) { diff --git a/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletionContributor.java b/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletionContributor.java index 2debdbe82fe6..27ddc4e1b1b2 100644 --- a/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletionContributor.java +++ b/platform/lang-impl/src/com/intellij/ui/TextFieldWithAutoCompletionContributor.java @@ -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 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 provider = file.getUserData(KEY); diff --git a/platform/lang-impl/src/com/intellij/util/CompletionContributorForTextField.java b/platform/lang-impl/src/com/intellij/util/CompletionContributorForTextField.java index d220e1fd7cdf..50eadaa0a2c4 100644 --- a/platform/lang-impl/src/com/intellij/util/CompletionContributorForTextField.java +++ b/platform/lang-impl/src/com/intellij/util/CompletionContributorForTextField.java @@ -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; diff --git a/platform/platform-api/src/com/intellij/openapi/diff/FragmentContent.java b/platform/platform-api/src/com/intellij/openapi/diff/FragmentContent.java index 9a176e37aaf4..26537316b4e9 100644 --- a/platform/platform-api/src/com/intellij/openapi/diff/FragmentContent.java +++ b/platform/platform-api/src/com/intellij/openapi/diff/FragmentContent.java @@ -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; diff --git a/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java b/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java index 8d26ee44031d..eed6946c86ff 100644 --- a/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java +++ b/platform/platform-api/src/com/intellij/openapi/editor/highlighter/FragmentedEditorHighlighter.java @@ -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 myPieces; + private final List 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(); + myPieces = new ArrayList(); myAdditionalOffset = additionalOffset; translate(sourceIterator, ranges); } private void translate(HighlighterIterator iterator, List 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 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 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() { + @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 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 entry = myPieces.headMap(myIdx, false).lastEntry(); - myIdx = entry.getKey(); } @Override public boolean atEnd() { - return myIdx < 0; + return myIdx < 0 || myIdx >= myPieces.size(); } @Override diff --git a/platform/platform-api/src/com/intellij/ui/EditorNotifications.java b/platform/platform-api/src/com/intellij/ui/EditorNotifications.java index 4db32d94dd30..6805266e57ad 100644 --- a/platform/platform-api/src/com/intellij/ui/EditorNotifications.java +++ b/platform/platform-api/src/com/intellij/ui/EditorNotifications.java @@ -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 { + @NotNull public abstract Key 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(); diff --git a/platform/platform-impl/src/com/intellij/ide/FileChangedNotificationProvider.java b/platform/platform-impl/src/com/intellij/ide/FileChangedNotificationProvider.java index cce510c0233d..fa975283d921 100644 --- a/platform/platform-impl/src/com/intellij/ide/FileChangedNotificationProvider.java +++ b/platform/platform-impl/src/com/intellij/ide/FileChangedNotificationProvider.java @@ -79,6 +79,7 @@ public class FileChangedNotificationProvider extends EditorNotifications.Provide }); } + @NotNull @Override public Key getKey() { return KEY; diff --git a/platform/platform-impl/src/com/intellij/ide/actions/CopyPathsAction.java b/platform/platform-impl/src/com/intellij/ide/actions/CopyPathsAction.java index 388a446d991c..0bc0a50e1df8 100644 --- a/platform/platform-impl/src/com/intellij/ide/actions/CopyPathsAction.java +++ b/platform/platform-impl/src/com/intellij/ide/actions/CopyPathsAction.java @@ -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 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 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 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 getFiles(AnActionEvent e) { - final VirtualFile[] files = CommonDataKeys.VIRTUAL_FILE_ARRAY.getData(e.getDataContext()); - if (files == null || files.length == 0) return Collections.emptyList(); - final ArrayList result = new ArrayList(files.length); - for (VirtualFile file : files) { - if (!(file instanceof LightVirtualFile)) { - result.add(file); - } - } - return result; - } - } diff --git a/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryContentHandler.java b/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryContentHandler.java index 6092139d3e0f..af6adfcbe599 100644 --- a/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryContentHandler.java +++ b/platform/platform-impl/src/com/intellij/ide/plugins/RepositoryContentHandler.java @@ -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); } } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/actions/DeleteLineAction.java b/platform/platform-impl/src/com/intellij/openapi/editor/actions/DeleteLineAction.java index 4b5201e2c9ea..2143a176bd46 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/actions/DeleteLineAction.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/actions/DeleteLineAction.java @@ -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); } diff --git a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java index 83bb738ca263..109fe6b75d27 100644 --- a/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java +++ b/platform/platform-impl/src/com/intellij/openapi/editor/impl/EditorImpl.java @@ -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; diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java index a6641bb0cea4..9739d75be7e7 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginDownloader.java @@ -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; } diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoDialog.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoDialog.java index 162c91a50ff7..02e9af1b4118 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoDialog.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/PluginUpdateInfoDialog.java @@ -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 result = new Ref(); + 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 { diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java index fa29a714061d..1bae513aefbf 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateChecker.java @@ -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 ourUpdatedPlugins = new HashMap(); + private static final Map ourUpdatedPlugins = new HashMap(); public enum DownloadPatchResult { SUCCESS, FAILED, CANCELED @@ -242,25 +243,12 @@ public final class UpdateChecker { if (!toUpdate.isEmpty()) { try { final List process = RepositoryHelper.loadPluginsFromRepository(indicator); - final List 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 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 downloaded, + Collection incompatiblePlugins, + PluginDownloader downloader, + ProgressIndicator indicator) throws IOException { + final String pluginId = downloader.getPluginId(); + final String pluginVersion = downloader.getPluginVersion(); + final List 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 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 downloaded, final @Nullable Collection 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 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; + } + } diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java index cbace7534322..e3ee04111e95 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/UpdateInfoDialog.java @@ -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; } diff --git a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.java b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.java index 18c5f76b670a..394dec20f4ef 100644 --- a/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.java +++ b/platform/platform-impl/src/com/intellij/openapi/updateSettings/impl/pluginsAdvertisement/PluginAdvertiserEditorNotificationProvider.java @@ -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 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(); diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsHolder.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsHolder.java index 8069f8c0336a..d92839e212b8 100644 --- a/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsHolder.java +++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkCredentialsHolder.java @@ -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(); diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteSdkProperties.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkProperties.java index 7d132578a6d4..a690afd96afc 100644 --- a/platform/platform-impl/src/com/intellij/remote/RemoteSdkProperties.java +++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkProperties.java @@ -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 getRemoteRoots(); + /** + * Use setPathMappings() instead + * To be removed in IDEA 15 + * + * @deprecated + */ + @Deprecated void setRemoteRoots(List remoteRoots); + @NotNull + PathMappingSettings getPathMappings(); + + void setPathMappings(@Nullable PathMappingSettings pathMappings); + boolean isHelpersVersionChecked(); void setHelpersVersionChecked(boolean helpersVersionChecked); diff --git a/platform/platform-impl/src/com/intellij/remote/RemoteSdkPropertiesHolder.java b/platform/platform-impl/src/com/intellij/remote/RemoteSdkPropertiesHolder.java index 71bf44ba3cb7..a0407d27f7e9 100644 --- a/platform/platform-impl/src/com/intellij/remote/RemoteSdkPropertiesHolder.java +++ b/platform/platform-impl/src/com/intellij/remote/RemoteSdkPropertiesHolder.java @@ -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)); } } diff --git a/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java b/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java index 24660c6674ab..800d8bd1dc63 100644 --- a/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java +++ b/platform/platform-impl/src/com/intellij/ui/EditorNotificationsImpl.java @@ -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 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() { diff --git a/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/EditorActionTest.java b/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/EditorActionTest.java index 63e040def381..deb63c13abf8 100644 --- a/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/EditorActionTest.java +++ b/platform/platform-tests/testSrc/com/intellij/openapi/editor/actions/EditorActionTest.java @@ -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("text", @@ -69,4 +71,35 @@ public class EditorActionTest extends AbstractEditorTest { executeAction("EditorTab"); checkResultByText("some text"); } + + public void testLineDeleteWithSelectionEndAtLineStart() throws IOException { + String text = + "line 1\n" + + "line 2\n" + + "line 3"; + init(text, TestFileType.TEXT); + deleteLine(); + checkResultByText( + "line 1\n" + + "line 3" + ); + } + + public void testDeleteLastLine() throws IOException { + String text = + "1\n" + + "2\n" + + "3"; + init(text, TestFileType.TEXT); + + deleteLine(); + deleteLine(); + checkResultByText("1"); + } + + public void testDeleteLastNonEmptyLine() throws IOException { + init("1\n", TestFileType.TEXT); + deleteLine(); + checkResultByText(""); + } } \ No newline at end of file diff --git a/platform/script-debugger/backend/src/org/jetbrains/debugger/ScriptManager.java b/platform/script-debugger/backend/src/org/jetbrains/debugger/ScriptManager.java index 76157af7b808..019d8da6271b 100644 --- a/platform/script-debugger/backend/src/org/jetbrains/debugger/ScriptManager.java +++ b/platform/script-debugger/backend/src/org/jetbrains/debugger/ScriptManager.java @@ -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